Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicClassificationSolutionSimplifierViewBase.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicClassificationSolutionSimplifierViewBase.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicClassificationSolutionSimplifierViewBase.cs	(revision 15406)
@@ -20,7 +20,4 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -29,6 +26,4 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views {
   public abstract partial class InteractiveSymbolicClassificationSolutionSimplifierViewBase : InteractiveSymbolicDataAnalysisSolutionSimplifierView {
-    private readonly SymbolicClassificationSolutionImpactValuesCalculator calculator;
-
     public new ISymbolicClassificationSolution Content {
       get { return (ISymbolicClassificationSolution)base.Content; }
@@ -36,10 +31,8 @@
     }
 
-    public InteractiveSymbolicClassificationSolutionSimplifierViewBase()
-      : base() {
+    protected InteractiveSymbolicClassificationSolutionSimplifierViewBase()
+      : base(new SymbolicClassificationSolutionImpactValuesCalculator()) {
       InitializeComponent();
       this.Caption = "Interactive Classification Solution Simplifier";
-
-      calculator = new SymbolicClassificationSolutionImpactValuesCalculator();
     }
 
@@ -59,18 +52,4 @@
       return 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);
-        impactAndReplacementValues.Add(node, new Tuple<double, double>(impactValue, replacementValue));
-      }
-      return impactAndReplacementValues;
-    }
-
-    protected override void btnOptimizeConstants_Click(object sender, EventArgs e) {
-
-    }
   }
 }
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolutionImpactValuesCalculator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolutionImpactValuesCalculator.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolutionImpactValuesCalculator.cs	(revision 15406)
@@ -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: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 15406)
@@ -21,13 +21,10 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.MainForm;
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Views;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views {
   public partial class InteractiveSymbolicRegressionSolutionSimplifierView : InteractiveSymbolicDataAnalysisSolutionSimplifierView {
-    private readonly SymbolicRegressionSolutionImpactValuesCalculator calculator;
-
     public new SymbolicRegressionSolution Content {
       get { return (SymbolicRegressionSolution)base.Content; }
@@ -36,8 +33,7 @@
 
     public InteractiveSymbolicRegressionSolutionSimplifierView()
-      : base() {
+      : base(new SymbolicRegressionSolutionImpactValuesCalculator()) {
       InitializeComponent();
       this.Caption = "Interactive Regression Solution Simplifier";
-      calculator = new SymbolicRegressionSolutionImpactValuesCalculator();
     }
 
@@ -48,20 +44,15 @@
     }
 
-
-    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) {
+    protected override ISymbolicExpressionTree OptimizeConstants(ISymbolicExpressionTree tree, IProgress progress) {
+      const int constOptIterations = 50;
+      var regressionProblemData = Content.ProblemData;
       var model = Content.Model;
-      SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(model.Interpreter, model.SymbolicExpressionTree, Content.ProblemData, Content.ProblemData.TrainingIndices,
-        applyLinearScaling: true, maxIterations: 50, updateVariableWeights: true, lowerEstimationLimit: model.LowerEstimationLimit, upperEstimationLimit: model.UpperEstimationLimit);
-      UpdateModel(Content.Model.SymbolicExpressionTree);
+      SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(model.Interpreter, tree, regressionProblemData, regressionProblemData.TrainingIndices,
+        applyLinearScaling: true, maxIterations: constOptIterations, updateVariableWeights: true, lowerEstimationLimit: model.LowerEstimationLimit, upperEstimationLimit: model.UpperEstimationLimit,
+        iterationCallback: (args, func, obj) => {
+          double newProgressValue = progress.ProgressValue + 1.0 / (constOptIterations + 2); // (maxIterations + 2) iterations are reported
+          progress.ProgressValue = Math.Min(newProgressValue, 1.0);
+        });
+      return tree;
     }
   }
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs	(revision 15406)
@@ -51,6 +51,6 @@
     private void btn_SimplifyModel_Click(object sender, EventArgs e) {
       var view = new InteractiveSymbolicRegressionSolutionSimplifierView();
+      view.Show(); // open view first that a progress can be displayed when setting the content
       view.Content = (SymbolicRegressionSolution)this.Content.Clone();
-      view.Show();
     }
 
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 15406)
@@ -156,5 +156,5 @@
       int maxIterations, bool updateVariableWeights = true,
       double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue,
-      bool updateConstantsInTree = true) {
+      bool updateConstantsInTree = true, Action<double[], double, object> iterationCallback = null) {
 
       // numeric constants in the tree become variables for constant opt
@@ -210,10 +210,12 @@
       alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(func);
       alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(func_grad);
+      alglib.ndimensional_rep xrep = (p, f, obj) => iterationCallback(p, f, obj);
 
       try {
         alglib.lsfitcreatefg(x, y, c, n, m, k, false, out state);
         alglib.lsfitsetcond(state, 0.0, 0.0, maxIterations);
+        alglib.lsfitsetxrep(state, iterationCallback != null);
         //alglib.lsfitsetgradientcheck(state, 0.001);
-        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null);
+        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, xrep, null);
         alglib.lsfitresults(state, out retVal, out c, out rep);
       }
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs	(revision 15406)
@@ -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: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 15406)
@@ -20,16 +20,10 @@
 #endregion
 
-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;
-
     public new SymbolicTimeSeriesPrognosisSolution Content {
       get { return (SymbolicTimeSeriesPrognosisSolution)base.Content; }
@@ -38,46 +32,7 @@
 
     public InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView()
-      : base() {
+      : base(new SymbolicRegressionSolutionImpactValuesCalculator()) {
       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;
     }
 
@@ -87,36 +42,4 @@
       Content.Model = model;
     }
-
-    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);
-
-      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: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Plugin.cs.frame
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Plugin.cs.frame	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Plugin.cs.frame	(revision 15406)
@@ -28,5 +28,4 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views", "Provides views for symbolic time-series prognosis problem classes.", "3.4.10.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.Common", "3.3")]
   [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
   [PluginDependency("HeuristicLab.Core", "3.3")]
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 15406)
@@ -24,8 +24,10 @@
 using System.Drawing;
 using System.Linq;
+using System.Threading.Tasks;
 using System.Windows.Forms;
 using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
+using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
 
@@ -36,8 +38,12 @@
     private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
 
+    private readonly ISymbolicDataAnalysisSolutionImpactValuesCalculator impactCalculator;
+
+    private readonly IProgress progress = new Progress();
+
     private enum TreeState { Valid, Invalid }
     private TreeState treeState;
 
-    protected InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
+    protected InteractiveSymbolicDataAnalysisSolutionSimplifierView(ISymbolicDataAnalysisSolutionImpactValuesCalculator impactCalculator) {
       InitializeComponent();
       foldedNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
@@ -45,4 +51,5 @@
       nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
       this.Caption = "Interactive Solution Simplifier";
+      this.impactCalculator = impactCalculator;
 
       // initialize the tree modifier that will be used to perform edit operations over the tree
@@ -145,4 +152,5 @@
       Content.ProblemDataChanged += Content_Changed;
       treeChart.Repainted += treeChart_Repainted;
+      MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>().AddOperationProgressToView(grpSimplify, progress);
     }
     protected override void DeregisterContentEvents() {
@@ -151,4 +159,5 @@
       Content.ProblemDataChanged -= Content_Changed;
       treeChart.Repainted -= treeChart_Repainted;
+      MainFormManager.GetMainForm<MainForm.WindowsForms.MainForm>().RemoveOperationProgressFromView(grpSimplify, false);
     }
 
@@ -169,10 +178,12 @@
     }
 
-    private void UpdateView() {
+    private async void UpdateView() {
       if (Content == null || Content.Model == null || Content.ProblemData == null) return;
       var tree = Content.Model.SymbolicExpressionTree;
       treeChart.Tree = tree.Root.SubtreeCount > 1 ? new SymbolicExpressionTree(tree.Root) : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
 
-      var impactAndReplacementValues = CalculateImpactAndReplacementValues(tree);
+      progress.Start("Calculate Impact and Replacement Values ...");
+      var impactAndReplacementValues = await Task.Run(() => CalculateImpactAndReplacementValues(tree));
+      await Task.Delay(500); // wait for progressbar to finish animation
       var replacementValues = impactAndReplacementValues.ToDictionary(x => x.Key, x => x.Value.Item2);
       foreach (var pair in replacementValues.Where(pair => !(pair.Key is ConstantTreeNode))) {
@@ -180,9 +191,25 @@
       }
       nodeImpacts = impactAndReplacementValues.ToDictionary(x => x.Key, x => x.Value.Item1);
+      progress.Finish();
       PaintNodeImpacts();
     }
 
-    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);
+        double newProgressValue = progress.ProgressValue + 1.0 / (tree.Length - 2);
+        progress.ProgressValue = Math.Min(newProgressValue, 1);
+        impactAndReplacementValues.Add(node, new Tuple<double, double>(impactValue, replacementValue));
+      }
+      return impactAndReplacementValues;
+    }
+
     protected abstract void UpdateModel(ISymbolicExpressionTree tree);
+
+    protected virtual ISymbolicExpressionTree OptimizeConstants(ISymbolicExpressionTree tree, IProgress progress) {
+      return tree;
+    }
 
     private static ConstantTreeNode MakeConstantTreeNode(double value) {
@@ -270,5 +297,11 @@
     }
 
-    protected abstract void btnOptimizeConstants_Click(object sender, EventArgs e);
+    private async void btnOptimizeConstants_Click(object sender, EventArgs e) {
+      progress.Start("Optimizing Constants ...");
+      var tree = (ISymbolicExpressionTree)Content.Model.SymbolicExpressionTree.Clone();
+      var newTree = await Task.Run(() => OptimizeConstants(tree, progress));
+      await Task.Delay(500); // wait for progressbar to finish animation
+      UpdateModel(newTree); // UpdateModel calls Progress.Finish (via Content_Changed)
+    }
   }
 }
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 15406)
@@ -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,
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 15393)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 15406)
@@ -469,4 +469,5 @@
       <Project>{2E782078-FA81-4B70-B56F-74CE38DAC6C8}</Project>
       <Name>HeuristicLab.Algorithms.DataAnalysis-3.4</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj">
@@ -558,8 +559,10 @@
       <Project>{5AC82412-911B-4FA2-A013-EDC5E3F3FCC2}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
       <Project>{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis.Symbolic-3.4</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
Index: stable/HeuristicLab.Problems.Instances.DataAnalysis.Views/3.3/RegressionInstanceProviderView.cs
===================================================================
--- stable/HeuristicLab.Problems.Instances.DataAnalysis.Views/3.3/RegressionInstanceProviderView.cs	(revision 15393)
+++ stable/HeuristicLab.Problems.Instances.DataAnalysis.Views/3.3/RegressionInstanceProviderView.cs	(revision 15406)
@@ -21,5 +21,4 @@
 
 using System;
-using System.IO;
 using System.Threading.Tasks;
 using System.Windows.Forms;
@@ -73,5 +72,4 @@
           } finally {
             Invoke((Action)(() => instancesComboBox.SelectedIndex = -1));
-            mainForm.RemoveOperationProgressFromContent(activeView.Content);
           }
         });
