Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicClassificationSolutionSimplifierViewBase.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicClassificationSolutionSimplifierViewBase.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicClassificationSolutionSimplifierViewBase.cs	(revision 15321)
@@ -21,6 +21,4 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -34,4 +32,8 @@
       get { return (ISymbolicClassificationSolution)base.Content; }
       set { base.Content = value; }
+    }
+
+    protected override ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactCalculator {
+      get { return calculator; }
     }
 
@@ -60,14 +62,4 @@
     }
 
-    protected override Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) {
-      var impactAndReplacementValues = new Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>>();
-      foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix()) {
-        double impactValue, replacementValue, newQualityForImpactsCalculation;
-        calculator.CalculateImpactAndReplacementValues(Content.Model, node, Content.ProblemData, Content.ProblemData.TrainingIndices, out impactValue, out replacementValue, out newQualityForImpactsCalculation);
-        impactAndReplacementValues.Add(node, new Tuple<double, double>(impactValue, replacementValue));
-      }
-      return impactAndReplacementValues;
-    }
-
     protected override void btnOptimizeConstants_Click(object sender, EventArgs e) {
 
Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolutionImpactValuesCalculator.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolutionImpactValuesCalculator.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolutionImpactValuesCalculator.cs	(revision 15321)
@@ -20,9 +20,7 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -40,59 +38,13 @@
     protected SymbolicClassificationSolutionImpactValuesCalculator(bool deserializing) : base(deserializing) { }
 
-    public override void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model,
-      ISymbolicExpressionTreeNode node,
-      IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue,
-      out double newQualityForImpactsCalculation,
-      double qualityForImpactsCalculation = Double.NaN) {
+    protected override double CalculateQualityForImpacts(ISymbolicDataAnalysisModel model, IDataAnalysisProblemData problemData, IEnumerable<int> rows) {
       var classificationModel = (ISymbolicClassificationModel)model;
       var classificationProblemData = (IClassificationProblemData)problemData;
-
-      if (double.IsNaN(qualityForImpactsCalculation))
-        qualityForImpactsCalculation = CalculateQualityForImpacts(classificationModel, classificationProblemData, rows);
-
-
-      var cloner = new Cloner();
-      var tempModel = cloner.Clone(classificationModel);
-      var tempModelNode = (ISymbolicExpressionTreeNode)cloner.GetClone(node);
-
-      var tempModelParentNode = tempModelNode.Parent;
-      int i = tempModelParentNode.IndexOfSubtree(tempModelNode);
-      double bestReplacementValue = 0.0;
-      double bestImpactValue = double.PositiveInfinity;
-      newQualityForImpactsCalculation = qualityForImpactsCalculation; // initialize
-      // try the potentially reasonable replacement values and use the best one
-      foreach (var repValue in CalculateReplacementValues(node, classificationModel.SymbolicExpressionTree, classificationModel.Interpreter, classificationProblemData.Dataset, classificationProblemData.TrainingIndices)) {
-        tempModelParentNode.RemoveSubtree(i);
-
-        var constantNode = new ConstantTreeNode(new Constant()) { Value = repValue };
-        tempModelParentNode.InsertSubtree(i, constantNode);
-
-        var dataset = classificationProblemData.Dataset;
-        var targetClassValues = dataset.GetDoubleValues(classificationProblemData.TargetVariable, rows);
-        var estimatedClassValues = tempModel.GetEstimatedClassValues(dataset, rows);
-        OnlineCalculatorError errorState;
-        newQualityForImpactsCalculation = OnlineAccuracyCalculator.Calculate(targetClassValues, estimatedClassValues,
-          out errorState);
-        if (errorState != OnlineCalculatorError.None) newQualityForImpactsCalculation = 0.0;
-
-        impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
-
-        if (impactValue < bestImpactValue) {
-          bestImpactValue = impactValue;
-          bestReplacementValue = repValue;
-        }
-      }
-      replacementValue = bestReplacementValue;
-      impactValue = bestImpactValue;
-    }
-
-    public static double CalculateQualityForImpacts(ISymbolicClassificationModel model, IClassificationProblemData problemData, IEnumerable<int> rows) {
       OnlineCalculatorError errorState;
       var dataset = problemData.Dataset;
-      var targetClassValues = dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      var originalClassValues = model.GetEstimatedClassValues(dataset, rows);
+      var targetClassValues = dataset.GetDoubleValues(classificationProblemData.TargetVariable, rows);
+      var originalClassValues = classificationModel.GetEstimatedClassValues(dataset, rows);
       var qualityForImpactsCalculation = OnlineAccuracyCalculator.Calculate(targetClassValues, originalClassValues, out errorState);
       if (errorState != OnlineCalculatorError.None) qualityForImpactsCalculation = 0.0;
-
       return qualityForImpactsCalculation;
     }
Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 15321)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using System.Threading.Tasks;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -35,4 +34,8 @@
     }
 
+    protected override ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactCalculator {
+      get { return calculator; }
+    }
+
     public InteractiveSymbolicRegressionSolutionSimplifierView()
       : base() {
@@ -46,16 +49,4 @@
       model.Scale(Content.ProblemData);
       Content.Model = model;
-    }
-
-
-    protected override Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) {
-      var impactAndReplacementValues = new Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>>();
-      foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix()) {
-        double impactValue, replacementValue, newQualityForImpactsCalculation;
-        calculator.CalculateImpactAndReplacementValues(Content.Model, node, Content.ProblemData, Content.ProblemData.TrainingIndices, out impactValue, out replacementValue, out newQualityForImpactsCalculation);
-        Progress.ProgressValue += 1.0 / (tree.Length - 2);
-        impactAndReplacementValues.Add(node, new Tuple<double, double>(impactValue, replacementValue));
-      }
-      return impactAndReplacementValues;
     }
 
Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs	(revision 15321)
@@ -20,9 +20,7 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -32,5 +30,4 @@
   public class SymbolicRegressionSolutionImpactValuesCalculator : SymbolicDataAnalysisSolutionImpactValuesCalculator {
     public SymbolicRegressionSolutionImpactValuesCalculator() { }
-
     protected SymbolicRegressionSolutionImpactValuesCalculator(SymbolicRegressionSolutionImpactValuesCalculator original, Cloner cloner)
       : base(original, cloner) { }
@@ -38,58 +35,12 @@
       return new SymbolicRegressionSolutionImpactValuesCalculator(this, cloner);
     }
-
     [StorableConstructor]
     protected SymbolicRegressionSolutionImpactValuesCalculator(bool deserializing) : base(deserializing) { }
 
-    public override void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node,
-      IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation,
-      double qualityForImpactsCalculation = double.NaN) {
+    protected override double CalculateQualityForImpacts(ISymbolicDataAnalysisModel model, IDataAnalysisProblemData problemData, IEnumerable<int> rows) {
       var regressionModel = (ISymbolicRegressionModel)model;
       var regressionProblemData = (IRegressionProblemData)problemData;
-
-      var dataset = regressionProblemData.Dataset;
-      var targetValues = dataset.GetDoubleValues(regressionProblemData.TargetVariable, rows);
-
-      if (double.IsNaN(qualityForImpactsCalculation))
-        qualityForImpactsCalculation = CalculateQualityForImpacts(regressionModel, regressionProblemData, rows);
-
-      var cloner = new Cloner();
-      var tempModel = cloner.Clone(regressionModel);
-      var tempModelNode = (ISymbolicExpressionTreeNode)cloner.GetClone(node);
-
-      var tempModelParentNode = tempModelNode.Parent;
-      int i = tempModelParentNode.IndexOfSubtree(tempModelNode);
-
-      double bestReplacementValue = 0.0;
-      double bestImpactValue = double.PositiveInfinity;
-      newQualityForImpactsCalculation = qualityForImpactsCalculation; // initialize
-      // try the potentially reasonable replacement values and use the best one
-      foreach (var repValue in CalculateReplacementValues(node, regressionModel.SymbolicExpressionTree, regressionModel.Interpreter, regressionProblemData.Dataset, regressionProblemData.TrainingIndices)) {
-
-        tempModelParentNode.RemoveSubtree(i);
-
-        var constantNode = new ConstantTreeNode(new Constant()) { Value = repValue };
-
-        tempModelParentNode.InsertSubtree(i, constantNode);
-
-        var estimatedValues = tempModel.GetEstimatedValues(dataset, rows);
-        OnlineCalculatorError errorState;
-        double r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
-        if (errorState != OnlineCalculatorError.None) r = 0.0;
-        newQualityForImpactsCalculation = r * r;
-
-        impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
-        if (impactValue < bestImpactValue) {
-          bestImpactValue = impactValue;
-          bestReplacementValue = repValue;
-        }
-      }
-      replacementValue = bestReplacementValue;
-      impactValue = bestImpactValue;
-    }
-
-    public static double CalculateQualityForImpacts(ISymbolicRegressionModel model, IRegressionProblemData problemData, IEnumerable<int> rows) {
-      var estimatedValues = model.GetEstimatedValues(problemData.Dataset, rows); // also bounds the values
-      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var estimatedValues = regressionModel.GetEstimatedValues(problemData.Dataset, rows); // also bounds the values
+      var targetValues = problemData.Dataset.GetDoubleValues(regressionProblemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
       var r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 15321)
@@ -21,14 +21,11 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Views;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
   public partial class InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView : InteractiveSymbolicDataAnalysisSolutionSimplifierView {
-    private readonly ConstantTreeNode constantNode;
-    private readonly SymbolicExpressionTree tempTree;
+    private readonly SymbolicRegressionSolutionImpactValuesCalculator calculator;
 
     public new SymbolicTimeSeriesPrognosisSolution Content {
@@ -37,47 +34,13 @@
     }
 
+    protected override ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactCalculator {
+      get { return calculator; }
+    }
+
     public InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView()
       : base() {
       InitializeComponent();
       this.Caption = "Interactive Time-Series Prognosis Solution Simplifier";
-
-      constantNode = ((ConstantTreeNode)new Constant().CreateTreeNode());
-      ISymbolicExpressionTreeNode root = new ProgramRootSymbol().CreateTreeNode();
-      ISymbolicExpressionTreeNode start = new StartSymbol().CreateTreeNode();
-      root.AddSubtree(start);
-      tempTree = new SymbolicExpressionTree(root);
-    }
-
-    protected override Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) {
-      var interpreter = Content.Model.Interpreter;
-      var rows = Content.ProblemData.TrainingIndices;
-      var dataset = Content.ProblemData.Dataset;
-      var targetVariable = Content.ProblemData.TargetVariable;
-      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
-      var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToArray();
-
-      var impactAndReplacementValues = new Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>>();
-      List<ISymbolicExpressionTreeNode> nodes = tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPostfix().ToList();
-      OnlineCalculatorError errorState;
-      double originalR = OnlinePearsonsRCalculator.Calculate(targetValues, originalOutput, out errorState);
-      if (errorState != OnlineCalculatorError.None) originalR = 0.0;
-
-      foreach (ISymbolicExpressionTreeNode node in nodes) {
-        var parent = node.Parent;
-        constantNode.Value = CalculateReplacementValue(node, tree);
-        ISymbolicExpressionTreeNode replacementNode = constantNode;
-        SwitchNode(parent, node, replacementNode);
-        var newOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows);
-        double newR = OnlinePearsonsRCalculator.Calculate(targetValues, newOutput, out errorState);
-        if (errorState != OnlineCalculatorError.None) newR = 0.0;
-
-        // impact = 0 if no change
-        // impact < 0 if new solution is better
-        // impact > 0 if new solution is worse
-        double impact = (originalR * originalR) - (newR * newR);
-        impactAndReplacementValues[node] = new Tuple<double, double>(impact, constantNode.Value);
-        SwitchNode(parent, replacementNode, node);
-      }
-      return impactAndReplacementValues;
+      calculator = new SymbolicRegressionSolutionImpactValuesCalculator();
     }
 
@@ -88,34 +51,6 @@
     }
 
-    private double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree) {
-      // remove old ADFs
-      while (tempTree.Root.SubtreeCount > 1) tempTree.Root.RemoveSubtree(1);
-      // clone ADFs of source tree
-      for (int i = 1; i < sourceTree.Root.SubtreeCount; i++) {
-        tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
-      }
-      var start = tempTree.Root.GetSubtree(0);
-      while (start.SubtreeCount > 0) start.RemoveSubtree(0);
-      start.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());
-      var interpreter = Content.Model.Interpreter;
-      var rows = Content.ProblemData.TrainingIndices;
-      var allPrognosedValues = interpreter.GetSymbolicExpressionTreeValues(tempTree, Content.ProblemData.Dataset, rows);
+    protected override void btnOptimizeConstants_Click(object sender, EventArgs e) {
 
-      return allPrognosedValues.Median();
-    }
-
-
-    private void SwitchNode(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode oldBranch, ISymbolicExpressionTreeNode newBranch) {
-      for (int i = 0; i < root.SubtreeCount; i++) {
-        if (root.GetSubtree(i) == oldBranch) {
-          root.RemoveSubtree(i);
-          root.InsertSubtree(i, newBranch);
-          return;
-        }
-      }
-    }
-
-    protected override void btnOptimizeConstants_Click(object sender, EventArgs e) {
-      throw new NotImplementedException();
     }
   }
Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 15321)
@@ -191,6 +191,18 @@
     }
 
-    protected abstract Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree);
+    protected virtual Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>> CalculateImpactAndReplacementValues(ISymbolicExpressionTree tree) {
+      var impactAndReplacementValues = new Dictionary<ISymbolicExpressionTreeNode, Tuple<double, double>>();
+      foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix()) {
+        double impactValue, replacementValue, newQualityForImpactsCalculation;
+        ImpactCalculator.CalculateImpactAndReplacementValues(Content.Model, node, Content.ProblemData, Content.ProblemData.TrainingIndices, out impactValue, out replacementValue, out newQualityForImpactsCalculation);
+        Progress.ProgressValue += 1.0 / (tree.Length - 2);
+        impactAndReplacementValues.Add(node, new Tuple<double, double>(impactValue, replacementValue));
+      }
+      return impactAndReplacementValues;
+    }
+
     protected abstract void UpdateModel(ISymbolicExpressionTree tree);
+
+    protected abstract ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactCalculator { get; }
 
     private static ConstantTreeNode MakeConstantTreeNode(double value) {
Index: branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
===================================================================
--- branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 15320)
+++ branches/SimplifierViewsProgress/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 15321)
@@ -32,10 +32,46 @@
   public abstract class SymbolicDataAnalysisSolutionImpactValuesCalculator : Item, ISymbolicDataAnalysisSolutionImpactValuesCalculator {
     protected SymbolicDataAnalysisSolutionImpactValuesCalculator() { }
-
     protected SymbolicDataAnalysisSolutionImpactValuesCalculator(SymbolicDataAnalysisSolutionImpactValuesCalculator original, Cloner cloner)
       : base(original, cloner) { }
     [StorableConstructor]
     protected SymbolicDataAnalysisSolutionImpactValuesCalculator(bool deserializing) : base(deserializing) { }
-    public abstract void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation, double qualityForImpactsCalculation = double.NaN);
+
+    public virtual void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows,
+        out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation,
+        double qualityForImpactsCalculation = double.NaN) {
+      if (double.IsNaN(qualityForImpactsCalculation))
+        qualityForImpactsCalculation = CalculateQualityForImpacts(model, problemData, rows);
+
+      var cloner = new Cloner();
+      var tempModel = cloner.Clone(model);
+      var tempModelNode = (ISymbolicExpressionTreeNode)cloner.GetClone(node);
+
+      var tempModelParentNode = tempModelNode.Parent;
+      int i = tempModelParentNode.IndexOfSubtree(tempModelNode);
+
+      double bestReplacementValue = 0.0;
+      double bestImpactValue = double.PositiveInfinity;
+      newQualityForImpactsCalculation = qualityForImpactsCalculation; // initialize
+      // try the potentially reasonable replacement values and use the best one
+      foreach (var repValue in CalculateReplacementValues(node, model.SymbolicExpressionTree, model.Interpreter, problemData.Dataset, problemData.TrainingIndices)) {
+        tempModelParentNode.RemoveSubtree(i);
+
+        var constantNode = new ConstantTreeNode(new Constant()) { Value = repValue };
+        tempModelParentNode.InsertSubtree(i, constantNode);
+
+        newQualityForImpactsCalculation = CalculateQualityForImpacts(tempModel, problemData, rows);
+
+        impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
+        if (impactValue < bestImpactValue) {
+          bestImpactValue = impactValue;
+          bestReplacementValue = repValue;
+        }
+      }
+
+      replacementValue = bestReplacementValue;
+      impactValue = bestImpactValue;
+    }
+
+    protected abstract double CalculateQualityForImpacts(ISymbolicDataAnalysisModel model, IDataAnalysisProblemData problemData, IEnumerable<int> rows);
 
     protected IEnumerable<double> CalculateReplacementValues(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
