Index: branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs
===================================================================
--- branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs	(revision 11011)
+++ branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs	(revision 11064)
@@ -1,3 +1,26 @@
-﻿using System;
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Linq;
 using HeuristicLab.Analysis;
@@ -27,5 +50,7 @@
     private const string PruningOperatorParameterName = "PruningOperator";
     private const string ResultsParameterName = "Results";
-    #endregion
+    private const string PopulationSizeParameterName = "PopulationSize";
+    #endregion
+
     #region private members
     private DataReducer prunedSubtreesReducer;
@@ -33,6 +58,6 @@
     private DataTableValuesCollector valuesCollector;
     private ResultsCollector resultsCollector;
-    private EmptyOperator emptyOp;
-    #endregion
+    #endregion
+
     #region parameter properties
     public IValueParameter<SymbolicDataAnalysisExpressionPruningOperator> PruningOperatorParameter {
@@ -48,39 +73,63 @@
       get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
     }
-    private ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter {
-      get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
-    }
-    public IValueParameter<IntValue> UpdateIntervalParameter {
-      get { return (IValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
-    }
-    public IValueParameter<IntValue> UpdateCounterParameter {
-      get { return (IValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
-    }
-    public IValueParameter<DoubleRange> PopulationSliceParameter {
-      get { return (IValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; }
-    }
-    public IValueParameter<DoubleValue> PruningProbabilityParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; }
-    }
-    #endregion
+    public IFixedValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> UpdateCounterParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
+    }
+    public IFixedValueParameter<DoubleRange> PopulationSliceParameter {
+      get { return (IFixedValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; }
+    }
+    public IFixedValueParameter<DoubleValue> PruningProbabilityParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; }
+    }
+    public ILookupParameter<IntValue> PopulationSizeParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[PopulationSizeParameterName]; }
+    }
+    #endregion
+
     #region properties
     protected SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get { return PruningOperatorParameter.Value; } }
-    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
-    protected IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
-    protected IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
-    protected DoubleRange PopulationSlice { get { return PopulationSliceParameter.Value; } }
-    protected DoubleValue PruningProbability { get { return PruningProbabilityParameter.Value; } }
-    protected IRandom Random { get { return RandomParameter.ActualValue; } }
-    protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
-    protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
-    #endregion
+    protected int UpdateInterval { get { return UpdateIntervalParameter.Value.Value; } }
+
+    protected int UpdateCounter {
+      get { return UpdateCounterParameter.Value.Value; }
+      set { UpdateCounterParameter.Value.Value = value; }
+    }
+
+    protected double PopulationSliceStart {
+      get { return PopulationSliceParameter.Value.Start; }
+      set { PopulationSliceParameter.Value.Start = value; }
+    }
+
+    protected double PopulationSliceEnd {
+      get { return PopulationSliceParameter.Value.End; }
+      set { PopulationSliceParameter.Value.End = value; }
+    }
+
+    protected double PruningProbability {
+      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
+
     #region IStatefulItem members
     public override void InitializeState() {
       base.InitializeState();
-      UpdateCounter.Value = 0;
+      UpdateCounter = 0;
     }
     public override void ClearState() {
       base.ClearState();
-      UpdateCounter.Value = 0;
+      UpdateCounter = 0;
     }
     #endregion
@@ -88,4 +137,5 @@
     [StorableConstructor]
     protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(bool deserializing) : base(deserializing) { }
+
     protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
       : base(original, cloner) {
@@ -99,15 +149,114 @@
         this.resultsCollector = (ResultsCollector)original.resultsCollector.Clone();
     }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(PopulationSizeParameterName)) {
+        Parameters.Add(new LookupParameter<IntValue>(PopulationSizeParameterName, "The population of individuals."));
+      }
+      if (Parameters.ContainsKey(UpdateCounterParameterName)) {
+        var fixedValueParameter = Parameters[UpdateCounterParameterName] as FixedValueParameter<IntValue>;
+        if (fixedValueParameter == null) {
+          var valueParameter = (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName];
+          Parameters.Remove(UpdateCounterParameterName);
+          Parameters.Add(new FixedValueParameter<IntValue>(UpdateCounterParameterName, valueParameter.Value));
+        }
+      }
+      if (Parameters.ContainsKey(UpdateIntervalParameterName)) {
+        var fixedValueParameter = Parameters[UpdateIntervalParameterName] as FixedValueParameter<IntValue>;
+        if (fixedValueParameter == null) {
+          var valueParameter = (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName];
+          Parameters.Remove(UpdateIntervalParameterName);
+          Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, valueParameter.Value));
+        }
+      }
+      if (Parameters.ContainsKey(PopulationSliceParameterName)) {
+        var fixedValueParameter = Parameters[PopulationSliceParameterName] as FixedValueParameter<DoubleRange>;
+        if (fixedValueParameter == null) {
+          var valueParameter = (ValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName];
+          Parameters.Remove(PopulationSliceParameterName);
+          Parameters.Add(new FixedValueParameter<DoubleRange>(PopulationSliceParameterName, valueParameter.Value));
+        }
+      }
+      if (Parameters.ContainsKey(PruningProbabilityParameterName)) {
+        var fixedValueParameter = Parameters[PruningProbabilityParameterName] as FixedValueParameter<DoubleValue>;
+        if (fixedValueParameter == null) {
+          var valueParameter = (ValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName];
+          Parameters.Remove(PruningProbabilityParameterName);
+          Parameters.Add(new FixedValueParameter<DoubleValue>(PruningProbabilityParameterName, valueParameter.Value));
+        }
+      }
+    }
+
     protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer() {
       #region add parameters
-      Parameters.Add(new ValueParameter<DoubleRange>(PopulationSliceParameterName, new DoubleRange(0.75, 1)));
-      Parameters.Add(new ValueParameter<DoubleValue>(PruningProbabilityParameterName, new DoubleValue(0.5)));
-      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
-      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
-      Parameters.Add(new LookupParameter<IRandom>(RandomParameterName));
-      Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName));
-      Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, new DoubleValue(0.0)));
-      Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<DoubleRange>(PopulationSliceParameterName, "The slice of the population where pruning should be applied.", new DoubleRange(0.75, 1)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(PruningProbabilityParameterName, "The probability for pruning an individual.", new DoubleValue(0.5)));
+      Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
+      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
+    }
+
+    // 
+    /// <summary>
+    /// Computes the closed interval bounding the portion of the population that is to be pruned. 
+    /// </summary>
+    /// <returns>Returns an int range [start, end]</returns>
+    private IntRange GetSliceBounds() {
+      if (PopulationSliceStart < 0 || PopulationSliceEnd < 0) throw new ArgumentOutOfRangeException("The slice bounds cannot be negative.");
+      if (PopulationSliceStart > 1 || PopulationSliceEnd > 1) throw new ArgumentOutOfRangeException("The slice bounds should be expressed as unit percentages.");
+      var count = PopulationSizeParameter.ActualValue.Value;
+      var start = (int)Math.Round(PopulationSliceStart * count);
+      var end = (int)Math.Round(PopulationSliceEnd * count);
+      if (end > count) end = count;
+
+      if (start >= end) throw new ArgumentOutOfRangeException("Invalid PopulationSlice bounds.");
+      return new IntRange(start, end);
+    }
+
+    private IOperation CreatePruningOperation() {
+      var operations = new OperationCollection { Parallel = true };
+      var range = GetSliceBounds();
+      var qualities = Quality.Select(x => x.Value).ToArray();
+      var indices = Enumerable.Range(0, qualities.Length).ToArray();
+      Array.Sort(qualities, indices);
+      if (!Maximization.Value) Array.Reverse(indices);
+
+      var subscopes = ExecutionContext.Scope.SubScopes;
+      var random = RandomParameter.ActualValue;
+
+      var empty = new EmptyOperator();
+
+      for (int i = 0; i < subscopes.Count; ++i) {
+        IOperator @operator;
+        if (range.Start <= i && i < range.End && random.NextDouble() <= PruningProbability)
+          @operator = PruningOperator;
+        else @operator = empty;
+        var index = indices[i];
+        var subscope = subscopes[index];
+        operations.Add(ExecutionContext.CreateChildOperation(@operator, subscope));
+      }
+      return operations;
+    }
+
+    public override IOperation Apply() {
+      UpdateCounter++;
+      if (UpdateCounter != UpdateInterval) return base.Apply();
+      UpdateCounter = 0;
+
+      if (prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
+
+      var prune = CreatePruningOperation();
+      var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer);
+      var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer);
+      var collectValues = ExecutionContext.CreateChildOperation(valuesCollector);
+      var collectResults = ExecutionContext.CreateChildOperation(resultsCollector);
+
+      return new OperationCollection { prune, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
     }
 
@@ -133,60 +282,4 @@
       resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>("Population pruning"));
       resultsCollector.ResultsParameter.ActualName = ResultsParameterName;
-
-      emptyOp = new EmptyOperator();
-    }
-
-    // 
-    /// <summary>
-    /// Computes the closed interval bounding the portion of the population that is to be pruned. 
-    /// </summary>
-    /// <returns>Returns an int range [start, end]</returns>
-    private IntRange GetSliceBounds() {
-      var count = ExecutionContext.Scope.SubScopes.Count;
-      var start = (int)Math.Round(PopulationSlice.Start * count);
-      var end = (int)Math.Round(PopulationSlice.End * count);
-      if (end > count) end = count;
-
-      if (PopulationSlice.Start > 1 || PopulationSlice.End > 1) throw new ArgumentOutOfRangeException("The slice bounds should be expressed as unit percentages.");
-      if (start >= end) throw new ArgumentOutOfRangeException("Invalid PopulationSlice bounds.");
-      return new IntRange(start, end);
-    }
-
-    private IOperation CreatePruningOperation() {
-      var oc = new OperationCollection { Parallel = true };
-      var range = GetSliceBounds();
-      var qualities = Quality.Select(x => x.Value).ToArray();
-      var indices = Enumerable.Range(0, qualities.Length).ToArray();
-      Array.Sort(qualities, indices);
-      if (!Maximization.Value) Array.Reverse(indices);
-
-      var subscopes = ExecutionContext.Scope.SubScopes;
-
-      for (int i = 0; i < subscopes.Count; ++i) {
-        IOperator op;
-        if (range.Start <= i && i < range.End && Random.NextDouble() <= PruningProbability.Value)
-          op = PruningOperator;
-        else op = emptyOp;
-        var index = indices[i];
-        var subscope = subscopes[index];
-        oc.Add(ExecutionContext.CreateChildOperation(op, subscope));
-      }
-      return oc;
-    }
-
-    public override IOperation Apply() {
-      UpdateCounter.Value++;
-      if (UpdateCounter.Value != UpdateInterval.Value) return base.Apply();
-      UpdateCounter.Value = 0;
-
-      if (prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
-
-      var prune = CreatePruningOperation();
-      var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer);
-      var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer);
-      var collectValues = ExecutionContext.CreateChildOperation(valuesCollector);
-      var collectResults = ExecutionContext.CreateChildOperation(resultsCollector);
-
-      return new OperationCollection { prune, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
     }
   }
Index: branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs
===================================================================
--- branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 11011)
+++ branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 11064)
@@ -85,10 +85,17 @@
     }
     #endregion
+
     #region properties
     protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
     protected ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactValuesCalculator { get { return ImpactValuesCalculatorParameter.Value; } }
     protected IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } }
-    protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
-    protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.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; }
+    }
     protected ISymbolicExpressionTree SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } }
     protected DoubleValue Quality { get { return QualityParameter.ActualValue; } }
@@ -117,9 +124,13 @@
       #endregion
     }
+
+    protected abstract ISymbolicDataAnalysisModel CreateModel();
+
+    protected abstract double Evaluate(IDataAnalysisModel model);
+
     public override IOperation Apply() {
       var model = CreateModel();
       var nodes = SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
-      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size).ToList();
-
+      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size);
       var prunedSubtrees = 0;
       var prunedTrees = 0;
@@ -134,8 +145,13 @@
         ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, ProblemData, rows, out impactValue, out replacementValue, quality);
 
-        if (PruneOnlyZeroImpactNodes.Value && (!impactValue.IsAlmost(0.0))) continue;
-        else if (NodeImpactThreshold.Value < impactValue) continue;
+        if (PruneOnlyZeroImpactNodes) {
+          if (!impactValue.IsAlmost(0.0)) continue;
+        } else if (NodeImpactThreshold < impactValue) {
+          continue;
+        }
 
-        var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue };
+        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
@@ -152,4 +168,5 @@
       return base.Apply();
     }
+
     private static void ReplaceWithConstant(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement) {
       var parent = original.Parent;
@@ -158,6 +175,4 @@
       parent.InsertSubtree(i, replacement);
     }
-    protected abstract ISymbolicDataAnalysisModel CreateModel();
-    protected abstract double Evaluate(IDataAnalysisModel model);
   }
 }
