Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 14185)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 14826)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -36,25 +37,35 @@
     [StorableConstructor]
     protected SymbolicDataAnalysisSolutionImpactValuesCalculator(bool deserializing) : base(deserializing) { }
-    public abstract double CalculateReplacementValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows);
-    public abstract double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double qualityForImpactsCalculation = double.NaN);
     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);
 
-    protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+    protected IEnumerable<double> CalculateReplacementValues(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
       IDataset dataset, IEnumerable<int> rows) {
       //optimization: constant nodes return always the same value
       ConstantTreeNode constantNode = node as ConstantTreeNode;
-      if (constantNode != null) return constantNode.Value;
+      BinaryFactorVariableTreeNode binaryFactorNode = node as BinaryFactorVariableTreeNode;
+      FactorVariableTreeNode factorNode = node as FactorVariableTreeNode;
+      if (constantNode != null) {
+        yield return constantNode.Value;
+      } else if (binaryFactorNode != null) {
+        // valid replacements are either all off or all on
+        yield return 0;
+        yield return 1;
+      } else if (factorNode != null) {
+        foreach (var w in factorNode.Weights) yield return w;
+        yield return 0.0;
+      } else {
+        var rootSymbol = new ProgramRootSymbol().CreateTreeNode();
+        var startSymbol = new StartSymbol().CreateTreeNode();
+        rootSymbol.AddSubtree(startSymbol);
+        startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());
 
-      var rootSymbol = new ProgramRootSymbol().CreateTreeNode();
-      var startSymbol = new StartSymbol().CreateTreeNode();
-      rootSymbol.AddSubtree(startSymbol);
-      startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());
-
-      var tempTree = new SymbolicExpressionTree(rootSymbol);
-      // clone ADFs of source tree
-      for (int i = 1; i < sourceTree.Root.SubtreeCount; i++) {
-        tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
+        var tempTree = new SymbolicExpressionTree(rootSymbol);
+        // clone ADFs of source tree
+        for (int i = 1; i < sourceTree.Root.SubtreeCount; i++) {
+          tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
+        }
+        yield return interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median();
+        yield return interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Average(); // TODO perf
       }
-      return interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median();
     }
   }
