Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveProblem.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveProblem.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveProblem.cs	(revision 12547)
@@ -29,7 +29,7 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Item("Symbolic Regression Problem (multi objective)", "Represents a multi objective symbolic regression problem.")]
+  [Item("Symbolic Regression Problem (multi-objective)", "Represents a multi objective symbolic regression problem.")]
   [StorableClass]
-  [Creatable("Problems")]
+  [Creatable(CreatableAttribute.Categories.GeneticProgrammingProblems, Priority = 110)]
   public class SymbolicRegressionMultiObjectiveProblem : SymbolicDataAnalysisMultiObjectiveProblem<IRegressionProblemData, ISymbolicRegressionMultiObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, IRegressionProblem {
     private const double PunishmentFactor = 10;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 12547)
@@ -202,5 +202,5 @@
       int info;
 
-      Dataset ds = problemData.Dataset;
+      IDataset ds = problemData.Dataset;
       double[,] x = new double[rows.Count(), variableNames.Count];
       int row = 0;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 12547)
@@ -28,7 +28,7 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Item("Symbolic Regression Problem (single objective)", "Represents a single objective symbolic regression problem.")]
+  [Item("Symbolic Regression Problem (single-objective)", "Represents a single objective symbolic regression problem.")]
   [StorableClass]
-  [Creatable("Problems")]
+  [Creatable(CreatableAttribute.Categories.GeneticProgrammingProblems, Priority = 100)]
   public class SymbolicRegressionSingleObjectiveProblem : SymbolicDataAnalysisSingleObjectiveProblem<IRegressionProblemData, ISymbolicRegressionSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, IRegressionProblem {
     private const double PunishmentFactor = 10;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs	(revision 12547)
@@ -47,5 +47,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows)
         .LimitToRange(LowerEstimationLimit, UpperEstimationLimit);
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPhenotypicDiversityAnalyzer.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPhenotypicDiversityAnalyzer.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPhenotypicDiversityAnalyzer.cs	(revision 12547)
@@ -35,5 +35,5 @@
   [StorableClass]
   public class SymbolicRegressionPhenotypicDiversityAnalyzer : PopulationSimilarityAnalyzer,
-    ISymbolicDataAnalysisBoundedOperator, ISymbolicDataAnalysisInterpreterOperator, ISymbolicExpressionTreeOperator {
+    ISymbolicDataAnalysisBoundedOperator, ISymbolicDataAnalysisInterpreterOperator, ISymbolicExpressionTreeAnalyzer {
     #region parameter names
     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs	(revision 12547)
@@ -31,12 +31,15 @@
   [StorableClass]
   public sealed class SymbolicRegressionPruningAnalyzer : SymbolicDataAnalysisSingleObjectivePruningAnalyzer {
-    private const string ImpactValuesCalculatorParameterName = "ImpactValuesCalculator";
     private const string PruningOperatorParameterName = "PruningOperator";
-    private SymbolicRegressionPruningAnalyzer(SymbolicRegressionPruningAnalyzer original, Cloner cloner)
-      : base(original, cloner) {
+    public IValueParameter<SymbolicRegressionPruningOperator> PruningOperatorParameter {
+      get { return (IValueParameter<SymbolicRegressionPruningOperator>)Parameters[PruningOperatorParameterName]; }
     }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicRegressionPruningAnalyzer(this, cloner);
+
+    protected override SymbolicDataAnalysisExpressionPruningOperator PruningOperator {
+      get { return PruningOperatorParameter.Value; }
     }
+
+    private SymbolicRegressionPruningAnalyzer(SymbolicRegressionPruningAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicRegressionPruningAnalyzer(this, cloner); }
 
     [StorableConstructor]
@@ -44,6 +47,5 @@
 
     public SymbolicRegressionPruningAnalyzer() {
-      Parameters.Add(new ValueParameter<SymbolicDataAnalysisSolutionImpactValuesCalculator>(ImpactValuesCalculatorParameterName, "The impact values calculator", new SymbolicRegressionSolutionImpactValuesCalculator()));
-      Parameters.Add(new ValueParameter<SymbolicDataAnalysisExpressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
+      Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
     }
   }
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 12547)
@@ -53,6 +53,6 @@
     protected override double Evaluate(IDataAnalysisModel model) {
       var regressionModel = (IRegressionModel)model;
-      var regressionProblemData = (IRegressionProblemData)ProblemData;
-      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size);
+      var regressionProblemData = (IRegressionProblemData)ProblemDataParameter.ActualValue;
+      var rows = Enumerable.Range(FitnessCalculationPartitionParameter.ActualValue.Start, FitnessCalculationPartitionParameter.ActualValue.Size);
       return Evaluate(regressionModel, regressionProblemData, rows);
     }
@@ -71,5 +71,5 @@
       var clonedTree = (ISymbolicExpressionTree)tree.Clone();
       var model = new SymbolicRegressionModel(clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
-      var nodes = clonedTree.IterateNodesPrefix().ToList();
+      var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
       double quality = Evaluate(model, problemData, rows);
 
@@ -81,9 +81,6 @@
         impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, quality);
 
-        if (pruneOnlyZeroImpactNodes) {
-          if (!impactValue.IsAlmost(0.0)) continue;
-        } else if (nodeImpactThreshold < impactValue) {
-          continue;
-        }
+        if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
+        if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold) continue;
 
         var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisModelComplexityAnalyzer.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisModelComplexityAnalyzer.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisModelComplexityAnalyzer.cs	(revision 12547)
@@ -53,5 +53,5 @@
             for (int i = 0; i < node.SubtreeCount; i++) {
               var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
-              complexity *= nodeComplexity > 2 ? nodeComplexity : 2;
+              complexity *= nodeComplexity + 1;
             }
             return complexity;
@@ -61,5 +61,5 @@
             for (int i = 0; i < node.SubtreeCount; i++) {
               var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
-              complexity *= nodeComplexity > 2 ? nodeComplexity : 2;
+              complexity *= nodeComplexity +1;
             }
             return complexity;
@@ -75,5 +75,5 @@
         case OpCodes.Tan: {
             double complexity = CalculateComplexity(node.GetSubtree(0));
-            return Math.Pow(2.0, complexity); ;
+            return Math.Pow(2.0, complexity);
           }
         case OpCodes.Exp: {
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs	(revision 12547)
@@ -45,8 +45,6 @@
     private const string TotalNumberOfPrunedSubtreesParameterName = "Number of pruned subtrees";
     private const string TotalNumberOfPrunedTreesParameterName = "Number of pruned trees";
+    private const string TotalNumberOfPrunedNodesParameterName = "Number of pruned nodes";
     private const string RandomParameterName = "Random";
-    private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes";
-    private const string NodeImpactThresholdParameterName = "ImpactThreshold";
-    private const string PruningOperatorParameterName = "PruningOperator";
     private const string ResultsParameterName = "Results";
     private const string PopulationSizeParameterName = "PopulationSize";
@@ -54,4 +52,5 @@
 
     #region private members
+    private DataReducer prunedNodesReducer;
     private DataReducer prunedSubtreesReducer;
     private DataReducer prunedTreesReducer;
@@ -61,13 +60,4 @@
 
     #region parameter properties
-    public IValueParameter<SymbolicDataAnalysisExpressionPruningOperator> PruningOperatorParameter {
-      get { return (IValueParameter<SymbolicDataAnalysisExpressionPruningOperator>)Parameters[PruningOperatorParameterName]; }
-    }
-    public IFixedValueParameter<BoolValue> PruneOnlyZeroImpactNodesParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[PruneOnlyZeroImpactNodesParameterName]; }
-    }
-    public IFixedValueParameter<DoubleValue> NodeImpactThresholdParameter {
-      get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; }
-    }
     public ILookupParameter<IRandom> RandomParameter {
       get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
@@ -91,5 +81,5 @@
 
     #region properties
-    protected SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get { return PruningOperatorParameter.Value; } }
+    protected abstract SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get; }
     protected int UpdateInterval { get { return UpdateIntervalParameter.Value.Value; } }
 
@@ -112,13 +102,4 @@
       get { return PruningProbabilityParameter.Value.Value; }
       set { PruningProbabilityParameter.Value.Value = value; }
-    }
-
-    protected bool PruneOnlyZeroImpactNodes {
-      get { return PruneOnlyZeroImpactNodesParameter.Value.Value; }
-      set { PruneOnlyZeroImpactNodesParameter.Value.Value = value; }
-    }
-    protected double NodeImpactThreshold {
-      get { return NodeImpactThresholdParameter.Value.Value; }
-      set { NodeImpactThresholdParameter.Value.Value = value; }
     }
     #endregion
@@ -140,4 +121,6 @@
     protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
       : base(original, cloner) {
+      if (original.prunedNodesReducer != null)
+        this.prunedNodesReducer = (DataReducer)original.prunedNodesReducer.Clone();
       if (original.prunedSubtreesReducer != null)
         this.prunedSubtreesReducer = (DataReducer)original.prunedSubtreesReducer.Clone();
@@ -197,6 +180,4 @@
       Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "The random number generator."));
       Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName, "The problem data."));
-      Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, "The impact threshold  below which an individual should be pruned.", new DoubleValue(0.0)));
-      Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, "Switch to determine of only zero impact individuals should be pruned.", new BoolValue(false)));
       Parameters.Add(new LookupParameter<IntValue>(PopulationSizeParameterName, "The population of individuals."));
       #endregion
@@ -250,7 +231,8 @@
       UpdateCounter = 0;
 
-      if (prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
+      if (prunedNodesReducer == null || prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
 
       var prune = CreatePruningOperation();
+      var reducePrunedNodes = ExecutionContext.CreateChildOperation(prunedNodesReducer);
       var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer);
       var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer);
@@ -258,8 +240,14 @@
       var collectResults = ExecutionContext.CreateChildOperation(resultsCollector);
 
-      return new OperationCollection { prune, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
+      return new OperationCollection { prune, reducePrunedNodes, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
     }
 
     private void InitializeOperators() {
+      prunedNodesReducer = new DataReducer();
+      prunedNodesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedNodesParameter.ActualName;
+      prunedNodesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum); // sum all the pruned subtrees parameter values
+      prunedNodesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign); // asign the sum to the target parameter
+      prunedNodesReducer.TargetParameter.ActualName = TotalNumberOfPrunedNodesParameterName;
+
       prunedSubtreesReducer = new DataReducer();
       prunedSubtreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedSubtreesParameter.ActualName;
@@ -275,4 +263,5 @@
 
       valuesCollector = new DataTableValuesCollector();
+      valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedNodesParameterName));
       valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedSubtreesParameterName));
       valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedTreesParameterName));
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/MultiSymbolicDataAnalysisExpressionCrossover.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/MultiSymbolicDataAnalysisExpressionCrossover.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/MultiSymbolicDataAnalysisExpressionCrossover.cs	(revision 12547)
@@ -35,8 +35,9 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [Item("MultiSymbolicDataAnalysisExpressionCrossover", "Randomly selects and applies one of its crossovers every time it is called.")]
+  [StorableClass]
   public class MultiSymbolicDataAnalysisExpressionCrossover<T> : StochasticMultiBranch<ISymbolicExpressionTreeCrossover>,
     ISymbolicDataAnalysisExpressionCrossover<T> where T : class, IDataAnalysisProblemData {
     private const string ParentsParameterName = "Parents";
-    private const string ChildParameterName = "Child";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
     private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
     private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
@@ -62,6 +63,6 @@
       get { return (ScopeTreeLookupParameter<ISymbolicExpressionTree>)Parameters[ParentsParameterName]; }
     }
-    public ILookupParameter<ISymbolicExpressionTree> ChildParameter {
-      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[ChildParameterName]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
     }
     public IValueLookupParameter<IntValue> MaximumSymbolicExpressionTreeLengthParameter {
@@ -99,5 +100,5 @@
       Parameters.Add(new ValueLookupParameter<IntRange>(SymbolicDataAnalysisEvaluationPartitionParameterName, "The start index of the dataset partition on which the symbolic data analysis solution should be evaluated."));
       Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(ParentsParameterName, "The parent symbolic expression trees which should be crossed."));
-      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(ChildParameterName, "The child symbolic expression tree resulting from the crossover."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The child symbolic expression tree resulting from the crossover."));
 
       EvaluatorParameter.Hidden = true;
@@ -111,4 +112,13 @@
 
       SelectedOperatorParameter.ActualName = "SelectedCrossoverOperator";
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(SymbolicExpressionTreeParameterName))
+        Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
+      #endregion
     }
 
@@ -155,5 +165,5 @@
     private void ParameterizeCrossovers() {
       foreach (ISymbolicExpressionTreeCrossover op in Operators) {
-        op.ChildParameter.ActualName = ChildParameter.Name;
+        op.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
         op.ParentsParameter.ActualName = ParentsParameter.Name;
       }
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionContextAwareCrossover.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionContextAwareCrossover.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionContextAwareCrossover.cs	(revision 12547)
@@ -27,4 +27,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -68,5 +69,6 @@
           possibleChildren.Add(n);
       });
-      var selectedChild = possibleChildren.SelectRandom(random);
+
+      var selectedChild = possibleChildren.SampleRandom(random);
       var crossoverPoints = new List<CutPoint>();
       var qualities = new List<Tuple<CutPoint, double>>();
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionDepthConstrainedCrossover.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionDepthConstrainedCrossover.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionDepthConstrainedCrossover.cs	(revision 12547)
@@ -29,4 +29,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -115,6 +116,5 @@
         throw new Exception("No crossover points available in the first parent");
 
-      var crossoverPoint0 = crossoverPoints0.SelectRandom(random);
-
+      var crossoverPoint0 = crossoverPoints0.SampleRandom(random);
       int level = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
       int length = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();
@@ -126,5 +126,6 @@
                              select s).ToList();
       if (allowedBranches.Count == 0) return parent0;
-      var selectedBranch = allowedBranches.SelectRandom(random);
+
+      var selectedBranch = allowedBranches.SampleRandom(random);
       Swap(crossoverPoint0, selectedBranch);
       return parent0;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionDeterministicBestCrossover.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionDeterministicBestCrossover.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionDeterministicBestCrossover.cs	(revision 12547)
@@ -27,4 +27,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -67,5 +68,6 @@
           crossoverPoints0.Add(new CutPoint(n.Parent, n));
       });
-      CutPoint crossoverPoint0 = crossoverPoints0.SelectRandom(random);
+
+      CutPoint crossoverPoint0 = crossoverPoints0.SampleRandom(random);
       int level = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
       int length = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionProbabilisticFunctionalCrossover.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionProbabilisticFunctionalCrossover.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionProbabilisticFunctionalCrossover.cs	(revision 12547)
@@ -27,4 +27,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -69,5 +70,6 @@
         }
       });
-      var crossoverPoint0 = crossoverPoints0.SelectRandom(random);
+
+      var crossoverPoint0 = crossoverPoints0.SampleRandom(random);
       int level = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
       int length = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();
@@ -137,5 +139,7 @@
           weights[i] /= sum;
 
+#pragma warning disable 612, 618
         selectedBranch = allowedBranches.SelectRandom(weights, random);
+#pragma warning restore 612, 618
       }
       Swap(crossoverPoint0, selectedBranch);
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionSemanticSimilarityCrossover.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionSemanticSimilarityCrossover.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Crossovers/SymbolicDataAnalysisExpressionSemanticSimilarityCrossover.cs	(revision 12547)
@@ -28,4 +28,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -81,5 +82,6 @@
           crossoverPoints0.Add(new CutPoint(n.Parent, n));
       });
-      var crossoverPoint0 = crossoverPoints0.SelectRandom(random);
+
+      var crossoverPoint0 = crossoverPoints0.SampleRandom(random);
       int level = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
       int length = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs	(revision 12547)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs	(revision 12547)
@@ -0,0 +1,208 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Globalization;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("C# Symbolic Expression Tree Formatter", "A string formatter that converts symbolic expression trees to C# code.")]
+  [StorableClass]
+  public sealed class CSharpSymbolicExpressionTreeStringFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
+    [StorableConstructor]
+    private CSharpSymbolicExpressionTreeStringFormatter(bool deserializing) : base(deserializing) { }
+    private CSharpSymbolicExpressionTreeStringFormatter(CSharpSymbolicExpressionTreeStringFormatter original, Cloner cloner) : base(original, cloner) { }
+    public CSharpSymbolicExpressionTreeStringFormatter()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CSharpSymbolicExpressionTreeStringFormatter(this, cloner);
+    }
+
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
+      // skip root and start symbols
+      StringBuilder strBuilder = new StringBuilder();
+      GenerateHeader(strBuilder, symbolicExpressionTree);
+      FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), strBuilder);
+      GenerateFooter(strBuilder);
+      return strBuilder.ToString();
+    }
+
+    private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      if (node.Subtrees.Any()) {
+        if (node.Symbol is Addition) {
+          FormatOperator(node, "+", strBuilder);
+        } else if (node.Symbol is And) {
+          FormatOperator(node, "&&", strBuilder);
+        } else if (node.Symbol is Average) {
+          FormatFunction(node, "Average", strBuilder);
+        } else if (node.Symbol is Cosine) {
+          FormatFunction(node, "Math.Cos", strBuilder);
+        } else if (node.Symbol is Division) {
+          FormatDivision(node, strBuilder);
+        } else if (node.Symbol is Exponential) {
+          FormatFunction(node, "Math.Exp", strBuilder);
+        } else if (node.Symbol is GreaterThan) {
+          FormatOperator(node, ">", strBuilder);
+        } else if (node.Symbol is IfThenElse) {
+          FormatFunction(node, "EvaluateIf", strBuilder);
+        } else if (node.Symbol is LessThan) {
+          FormatOperator(node, "<", strBuilder);
+        } else if (node.Symbol is Logarithm) {
+          FormatFunction(node, "Math.Log", strBuilder);
+        } else if (node.Symbol is Multiplication) {
+          FormatOperator(node, "*", strBuilder);
+        } else if (node.Symbol is Not) {
+          FormatOperator(node, "!", strBuilder);
+        } else if (node.Symbol is Or) {
+          FormatOperator(node, "||", strBuilder);
+        } else if (node.Symbol is Sine) {
+          FormatFunction(node, "Math.Sin", strBuilder);
+        } else if (node.Symbol is Subtraction) {
+          FormatOperator(node, "-", strBuilder);
+        } else if (node.Symbol is Tangent) {
+          FormatFunction(node, "Math.Tan", strBuilder);
+        } else if (node.Symbol is Square) {
+          FormatSquare(node, strBuilder);
+        } else if (node.Symbol is SquareRoot) {
+          FormatFunction(node, "Math.Sqrt", strBuilder);
+        } else if (node.Symbol is Power) {
+          FormatFunction(node, "Math.Pow", strBuilder);
+        } else if (node.Symbol is Root) {
+          FormatRoot(node, strBuilder);
+        } else {
+          throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter.");
+        }
+      } else {
+        if (node is VariableTreeNode) {
+          var varNode = node as VariableTreeNode;
+          strBuilder.AppendFormat("{0} * {1}", varNode.VariableName, varNode.Weight.ToString("g17", CultureInfo.InvariantCulture));
+        } else if (node is ConstantTreeNode) {
+          var constNode = node as ConstantTreeNode;
+          strBuilder.Append(constNode.Value.ToString("g17", CultureInfo.InvariantCulture));
+        } else {
+          throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter.");
+        }
+      }
+    }
+
+    private void FormatSquare(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      strBuilder.Append("Math.Pow(");
+      FormatRecursively(node.GetSubtree(0), strBuilder);
+      strBuilder.Append(", 2)");
+    }
+
+    private void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      strBuilder.Append("Math.Pow(");
+      FormatRecursively(node.GetSubtree(0), strBuilder);
+      strBuilder.Append(", 1.0 / (");
+      FormatRecursively(node.GetSubtree(1), strBuilder);
+      strBuilder.Append("))");
+    }
+
+    private void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      if (node.SubtreeCount == 1) {
+        strBuilder.Append("1.0 / ");
+        FormatRecursively(node.GetSubtree(0), strBuilder);
+      } else {
+        FormatRecursively(node.GetSubtree(0), strBuilder);
+        strBuilder.Append("/ (");
+        for (int i = 1; i < node.SubtreeCount; i++) {
+          if (i > 1) strBuilder.Append(" * ");
+          FormatRecursively(node.GetSubtree(i), strBuilder);
+        }
+        strBuilder.Append(")");
+      }
+    }
+
+    private void FormatOperator(ISymbolicExpressionTreeNode node, string symbol, StringBuilder strBuilder) {
+      strBuilder.Append("(");
+      foreach (var child in node.Subtrees) {
+        FormatRecursively(child, strBuilder);
+        if (child != node.Subtrees.Last())
+          strBuilder.Append(" " + symbol + " ");
+      }
+      strBuilder.Append(")");
+    }
+
+    private void FormatFunction(ISymbolicExpressionTreeNode node, string function, StringBuilder strBuilder) {
+      strBuilder.Append(function + "(");
+      foreach (var child in node.Subtrees) {
+        FormatRecursively(child, strBuilder);
+        if (child != node.Subtrees.Last())
+          strBuilder.Append(", ");
+      }
+      strBuilder.Append(")");
+    }
+
+    private void GenerateHeader(StringBuilder strBuilder, ISymbolicExpressionTree symbolicExpressionTree) {
+      strBuilder.AppendLine("using System;");
+      strBuilder.AppendLine("using System.Linq;" + Environment.NewLine);
+      strBuilder.AppendLine("namespace HeuristicLab.Models {");
+      strBuilder.AppendLine("public static class Model {");
+      GenerateAverageSource(strBuilder);
+      GenerateIfThenElseSource(strBuilder);
+      strBuilder.Append(Environment.NewLine + "public static double Evaluate (");
+
+      HashSet<string> varNames = new HashSet<string>();
+      foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is VariableTreeNode)) {
+        varNames.Add(((VariableTreeNode)node).VariableName);
+      }
+      foreach (var varName in varNames) {
+        strBuilder.Append("double " + varName);
+        if (varName != varNames.Last()) {
+          strBuilder.Append(", ");
+        }
+      }
+
+      strBuilder.AppendLine(") {");
+      strBuilder.Append("double result = ");
+    }
+
+    private void GenerateFooter(StringBuilder strBuilder) {
+      strBuilder.AppendLine(";");
+      strBuilder.AppendLine("return result;");
+      strBuilder.AppendLine("}");
+      strBuilder.AppendLine("}");
+      strBuilder.AppendLine("}");
+    }
+
+    private void GenerateAverageSource(StringBuilder strBuilder) {
+      strBuilder.AppendLine("private static double Average(params double[] values) {");
+      strBuilder.AppendLine("  return values.Average();");
+      strBuilder.AppendLine("}");
+    }
+
+    private void GenerateIfThenElseSource(StringBuilder strBuilder) {
+      strBuilder.AppendLine("private static double EvaluateIf(bool condition, double then, double @else) {");
+      strBuilder.AppendLine("   return condition ? then : @else;");
+      strBuilder.AppendLine("}");
+    }
+  }
+}
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs	(revision 12547)
@@ -71,5 +71,5 @@
     }
 
-    public string Format(ISymbolicExpressionTree symbolicExpressionTree, Dataset dataset) {
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree, IDataset dataset) {
       var stringBuilder = new StringBuilder();
       if (dataset != null) CalculateVariableMapping(symbolicExpressionTree, dataset);
@@ -85,5 +85,5 @@
     }
 
-    private void CalculateVariableMapping(ISymbolicExpressionTree tree, Dataset dataset) {
+    private void CalculateVariableMapping(ISymbolicExpressionTree tree, IDataset dataset) {
       int columnIndex = 0;
       int inputIndex = 0;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 12547)
@@ -198,4 +198,5 @@
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" />
     <Compile Include="Importer\SymbolicExpressionImporter.cs" />
     <Compile Include="Importer\Token.cs" />
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 12547)
@@ -27,5 +27,5 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   public interface ISymbolicDataAnalysisExpressionTreeInterpreter : INamedItem, IStatefulItem {
-    IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows);
+    IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows);
     IntValue EvaluatedSolutions { get; set; }
   }
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 12547)
@@ -138,5 +138,5 @@
     #endregion
 
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -161,5 +161,5 @@
     }
 
-    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, IDataset dataset) {
       Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
       Dictionary<string, int> doubleVariableNames = dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i);
@@ -182,5 +182,5 @@
     }
 
-    private void CompileInstructions(ILGenerator il, InterpreterState state, Dataset ds) {
+    private void CompileInstructions(ILGenerator il, InterpreterState state, IDataset ds) {
       Instruction currentInstr = state.NextInstruction();
       int nArgs = currentInstr.nArguments;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 12547)
@@ -95,5 +95,5 @@
     #endregion
 
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -111,5 +111,5 @@
     }
 
-    private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
+    private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, IDataset dataset) {
       Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
       int necessaryArgStackSize = 0;
@@ -132,5 +132,5 @@
 
 
-    public virtual double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
+    public virtual double Evaluate(IDataset dataset, ref int row, InterpreterState state) {
       Instruction currentInstr = state.NextInstruction();
       switch (currentInstr.opCode) {
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 12547)
@@ -102,5 +102,5 @@
     #endregion
 
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -115,5 +115,5 @@
     }
 
-    private double Evaluate(Dataset dataset, int row, LinearInstruction[] code) {
+    private double Evaluate(IDataset dataset, int row, LinearInstruction[] code) {
       for (int i = code.Length - 1; i >= 0; --i) {
         if (code[i].skip) continue;
@@ -352,5 +352,5 @@
     }
 
-    public static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) {
+    public static void PrepareInstructions(LinearInstruction[] code, IDataset dataset) {
       for (int i = 0; i != code.Length; ++i) {
         var instr = code[i];
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 12547)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("SymbolicExpressionTreePruningOperator", "An operator that replaces introns with constant values in a symbolic expression tree.")]
-  public abstract class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator {
+  public abstract class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator, ISymbolicExpressionTreeOperator {
     #region parameter names
     private const string ProblemDataParameterName = "ProblemData";
@@ -41,4 +41,5 @@
     private const string PrunedSubtreesParameterName = "PrunedSubtrees";
     private const string PrunedTreesParameterName = "PrunedTrees";
+    private const string PrunedNodesParameterName = "PrunedNodes";
     private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition";
     private const string NodeImpactThresholdParameterName = "ImpactThreshold";
@@ -72,4 +73,7 @@
       get { return (ILookupParameter<IntValue>)Parameters[PrunedTreesParameterName]; }
     }
+    public ILookupParameter<IntValue> PrunedNodesParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[PrunedNodesParameterName]; }
+    }
     public IFixedValueParameter<DoubleValue> NodeImpactThresholdParameter {
       get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; }
@@ -87,19 +91,16 @@
 
     #region properties
-    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
-    protected ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactValuesCalculator { get { return ImpactValuesCalculatorParameter.Value; } }
-    protected IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } }
-    protected bool PruneOnlyZeroImpactNodes {
+    public ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactValuesCalculator {
+      get { return ImpactValuesCalculatorParameter.Value; }
+      set { ImpactValuesCalculatorParameter.Value = value; }
+    }
+    public bool PruneOnlyZeroImpactNodes {
       get { return PruneOnlyZeroImpactNodesParameter.Value.Value; }
       set { PruneOnlyZeroImpactNodesParameter.Value.Value = value; }
     }
-    protected double NodeImpactThreshold {
+    public double NodeImpactThreshold {
       get { return NodeImpactThresholdParameter.Value.Value; }
       set { NodeImpactThresholdParameter.Value.Value = value; }
     }
-    protected ISymbolicExpressionTree SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } }
-    protected DoubleValue Quality { get { return QualityParameter.ActualValue; } }
-    protected DoubleLimit EstimationLimits { get { return EstimationLimitsParameter.ActualValue; } }
-    protected ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get { return InterpreterParameter.ActualValue; } }
     #endregion
 
@@ -114,4 +115,5 @@
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisModel>(SymbolicDataAnalysisModelParameterName));
       Parameters.Add(new LookupParameter<IntRange>(FitnessCalculationPartitionParameterName));
+      Parameters.Add(new LookupParameter<IntValue>(PrunedNodesParameterName, "A counter of how many nodes were pruned."));
       Parameters.Add(new LookupParameter<IntValue>(PrunedSubtreesParameterName, "A counter of how many subtrees were replaced."));
       Parameters.Add(new LookupParameter<IntValue>(PrunedTreesParameterName, "A counter of how many trees were pruned."));
@@ -131,9 +133,16 @@
 
     public override IOperation Apply() {
-      var model = CreateModel(SymbolicExpressionTree, Interpreter, ProblemData, EstimationLimits);
-      var nodes = SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
-      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size);
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+      var fitnessCalculationPartition = FitnessCalculationPartitionParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var interpreter = InterpreterParameter.ActualValue;
+
+      var model = CreateModel(tree, interpreter, problemData, estimationLimits);
+      var nodes = tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
+      var rows = Enumerable.Range(fitnessCalculationPartition.Start, fitnessCalculationPartition.Size);
       var prunedSubtrees = 0;
       var prunedTrees = 0;
+      var prunedNodes = 0;
 
       double quality = Evaluate(model);
@@ -144,21 +153,19 @@
 
         double impactValue, replacementValue;
-        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, ProblemData, rows, out impactValue, out replacementValue, quality);
+        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, quality);
 
-        if (PruneOnlyZeroImpactNodes) {
-          if (!impactValue.IsAlmost(0.0)) continue;
-        } else if (NodeImpactThreshold < impactValue) {
-          continue;
-        }
+        if (PruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
+        if (!PruneOnlyZeroImpactNodes && impactValue > NodeImpactThreshold) continue;
 
         var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
         constantNode.Value = replacementValue;
 
+        var length = node.GetLength();
         ReplaceWithConstant(node, constantNode);
-        i += node.GetLength() - 1; // skip subtrees under the node that was folded
+        i += length - 1; // skip subtrees under the node that was folded
 
         quality -= impactValue;
-
         prunedSubtrees++;
+        prunedNodes += length;
       }
 
@@ -166,37 +173,8 @@
       PrunedSubtreesParameter.ActualValue = new IntValue(prunedSubtrees);
       PrunedTreesParameter.ActualValue = new IntValue(prunedTrees);
+      PrunedNodesParameter.ActualValue = new IntValue(prunedNodes);
+      QualityParameter.ActualValue.Value = quality;
 
       return base.Apply();
-    }
-
-    public ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) {
-      var model = CreateModel((ISymbolicExpressionTree)tree.Clone(), Interpreter, ProblemData, EstimationLimits);
-      var nodes = SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
-      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size);
-
-      double quality = Evaluate(model);
-
-      for (int i = 0; i < nodes.Count; ++i) {
-        var node = nodes[i];
-        if (node is ConstantTreeNode) continue;
-
-        double impactValue, replacementValue;
-        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, ProblemData, rows, out impactValue, out replacementValue, quality);
-
-        if (PruneOnlyZeroImpactNodes) {
-          if (!impactValue.IsAlmost(0.0)) continue;
-        } else if (NodeImpactThreshold < impactValue) {
-          continue;
-        }
-
-        var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
-        constantNode.Value = replacementValue;
-
-        ReplaceWithConstant(node, constantNode);
-        i += node.GetLength() - 1; // skip subtrees under the node that was folded
-
-        quality -= impactValue;
-      }
-      return model.SymbolicExpressionTree;
     }
 
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 12547)
@@ -287,6 +287,6 @@
         // make sum(x0..xn) / n
         var sum = original.Subtrees
-          .Select(x => GetSimplifiedTree(x))
-          .Aggregate((a, b) => MakeSum(a, b));
+          .Select(GetSimplifiedTree)
+          .Aggregate(MakeSum);
         return MakeFraction(sum, MakeConstant(original.Subtrees.Count()));
       }
@@ -299,7 +299,9 @@
         // simplify expressions x0..xn
         // make multiplication (x0 * 1/(x1 * x1 * .. * xn))
-        var simplifiedTrees = original.Subtrees.Select(GetSimplifiedTree).ToArray();
+        var first = original.GetSubtree(0);
+        var second = original.GetSubtree(1);
+        var remaining = original.Subtrees.Skip(2);
         return
-          MakeProduct(simplifiedTrees.First(), Invert(simplifiedTrees.Skip(1).Aggregate(MakeProduct)));
+          MakeProduct(GetSimplifiedTree(first), Invert(remaining.Aggregate(GetSimplifiedTree(second), (a, b) => MakeProduct(a, GetSimplifiedTree(b)))));
       }
     }
@@ -310,5 +312,5 @@
       } else {
         return original.Subtrees
-          .Select(GetSimplifiedTree).ToArray()
+          .Select(GetSimplifiedTree)
           .Aggregate(MakeProduct);
       }
@@ -321,8 +323,7 @@
         // simplify expressions x0..xn
         // make addition (x0,-x1..-xn)
-        var simplifiedTrees = original.Subtrees.Select(GetSimplifiedTree).ToArray();
-        return simplifiedTrees.Take(1)
-          .Concat(simplifiedTrees.Skip(1).Select(Negate))
-          .Aggregate(MakeSum);
+        var first = original.Subtrees.First();
+        var remaining = original.Subtrees.Skip(1);
+        return remaining.Aggregate(GetSimplifiedTree(first), (a, b) => MakeSum(a, Negate(GetSimplifiedTree(b))));
       }
     }
@@ -335,5 +336,5 @@
         // make addition (x0..xn)
         return original.Subtrees
-          .Select(GetSimplifiedTree).ToArray()
+          .Select(GetSimplifiedTree)
           .Aggregate(MakeSum);
       }
@@ -345,11 +346,11 @@
     private ISymbolicExpressionTreeNode SimplifyOr(ISymbolicExpressionTreeNode original) {
       return original.Subtrees
-        .Select(x => GetSimplifiedTree(x))
-        .Aggregate((a, b) => MakeOr(a, b));
+        .Select(GetSimplifiedTree)
+        .Aggregate(MakeOr);
     }
     private ISymbolicExpressionTreeNode SimplifyAnd(ISymbolicExpressionTreeNode original) {
       return original.Subtrees
-        .Select(x => GetSimplifiedTree(x))
-        .Aggregate((a, b) => MakeAnd(a, b));
+        .Select(GetSimplifiedTree)
+        .Aggregate(MakeAnd);
     }
     private ISymbolicExpressionTreeNode SimplifyLessThan(ISymbolicExpressionTreeNode original) {
@@ -831,5 +832,5 @@
     private void MergeVariablesInSum(ISymbolicExpressionTreeNode sum) {
       var subtrees = new List<ISymbolicExpressionTreeNode>(sum.Subtrees);
-      while (sum.Subtrees.Count() > 0) sum.RemoveSubtree(0);
+      while (sum.Subtrees.Any()) sum.RemoveSubtree(0);
       var groupedVarNodes = from node in subtrees.OfType<VariableTreeNode>()
                             let lag = (node is LaggedVariableTreeNode) ? ((LaggedVariableTreeNode)node).Lag : 0
@@ -949,5 +950,5 @@
     private void MergeVariablesAndConstantsInProduct(ISymbolicExpressionTreeNode prod) {
       var subtrees = new List<ISymbolicExpressionTreeNode>(prod.Subtrees);
-      while (prod.Subtrees.Count() > 0) prod.RemoveSubtree(0);
+      while (prod.Subtrees.Any()) prod.RemoveSubtree(0);
       var groupedVarNodes = from node in subtrees.OfType<VariableTreeNode>()
                             let lag = (node is LaggedVariableTreeNode) ? ((LaggedVariableTreeNode)node).Lag : 0
@@ -1004,6 +1005,6 @@
       } else if (IsAddition(x)) {
         // (x0 + x1 + .. + xn) * -1 => (-x0 + -x1 + .. + -xn)        
-        List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(x.Subtrees);
-        while (x.Subtrees.Count() > 0) x.RemoveSubtree(0);
+        var subtrees = new List<ISymbolicExpressionTreeNode>(x.Subtrees);
+        while (x.Subtrees.Any()) x.RemoveSubtree(0);
         foreach (var subtree in subtrees) {
           x.AddSubtree(Negate(subtree));
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 12547)
@@ -321,5 +321,5 @@
       foreach (var op in operators.OfType<ISymbolicExpressionTreeCrossover>()) {
         op.ParentsParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
-        op.ChildParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+        op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeManipulator>()) {
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 12547)
@@ -41,5 +41,5 @@
 
     protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
-      Dataset dataset, IEnumerable<int> rows) {
+      IDataset dataset, IEnumerable<int> rows) {
       //optimization: constant nodes return always the same value
       ConstantTreeNode constantNode = node as ConstantTreeNode;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs	(revision 12547)
@@ -74,5 +74,9 @@
       base.ResetLocalParameters(random);
       threshold = NormalDistributedRandom.NextDouble(random, Symbol.ThresholdInitializerMu, Symbol.ThresholdInitializerSigma);
+
+#pragma warning disable 612, 618
       variableName = Symbol.VariableNames.SelectRandom(random);
+#pragma warning restore 612, 618
+
       slope = NormalDistributedRandom.NextDouble(random, Symbol.SlopeInitializerMu, Symbol.SlopeInitializerSigma);
     }
@@ -82,5 +86,9 @@
       double x = NormalDistributedRandom.NextDouble(random, Symbol.ThresholdManipulatorMu, Symbol.ThresholdManipulatorSigma);
       threshold = threshold + x * shakingFactor;
+
+#pragma warning disable 612, 618
       variableName = Symbol.VariableNames.SelectRandom(random);
+#pragma warning restore 612, 618
+
       x = NormalDistributedRandom.NextDouble(random, Symbol.SlopeManipulatorMu, Symbol.SlopeManipulatorSigma);
       slope = slope + x * shakingFactor;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableTreeNode.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableTreeNode.cs	(revision 12546)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableTreeNode.cs	(revision 12547)
@@ -61,5 +61,8 @@
       base.ResetLocalParameters(random);
       weight = NormalDistributedRandom.NextDouble(random, Symbol.WeightMu, Symbol.WeightSigma);
+
+#pragma warning disable 612, 618
       variableName = Symbol.VariableNames.SelectRandom(random);
+#pragma warning restore 612, 618
     }
 
@@ -70,9 +73,11 @@
         double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu, Symbol.WeightManipulatorSigma);
         weight = weight + x * shakingFactor;
-      } else {        
+      } else {
         double x = NormalDistributedRandom.NextDouble(random, 1.0, Symbol.MultiplicativeWeightManipulatorSigma);
         weight = weight * x;
       }
+#pragma warning disable 612, 618
       variableName = Symbol.VariableNames.SelectRandom(random);
+#pragma warning restore 612, 618
     }
 
