Index: branches/SymbolicExpressionTreeDiversityAnalyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationPhenotypicDiversityAnalyzer.cs
===================================================================
--- branches/SymbolicExpressionTreeDiversityAnalyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationPhenotypicDiversityAnalyzer.cs	(revision 12068)
+++ branches/SymbolicExpressionTreeDiversityAnalyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationPhenotypicDiversityAnalyzer.cs	(revision 12075)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Analysis;
@@ -26,4 +27,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -32,5 +34,5 @@
   [Item("SymbolicClassificationPhenotypicDiversityAnalyzer", "An analyzer which calculates diversity based on the phenotypic distance between trees")]
   [StorableClass]
-  public class SymbolicClassificationPhenotypicDiversityAnalyzer : SingleObjectivePopulationDiversityAnalyzer {
+  public class SymbolicClassificationPhenotypicDiversityAnalyzer : PopulationSimilarityAnalyzer {
     #region parameter names
     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
@@ -74,6 +76,6 @@
     #endregion
 
-    public SymbolicClassificationPhenotypicDiversityAnalyzer() {
-      SimilarityCalculator = new SymbolicExpressionTreePhenotypicSimilarityCalculator() { SolutionVariableName = "SymbolicExpressionTree", QualityVariableName = "Quality" };
+    public SymbolicClassificationPhenotypicDiversityAnalyzer(IEnumerable<ISingleObjectiveSolutionSimilarityCalculator> validSimilarityCalculators)
+      : base(validSimilarityCalculators) {
       #region add parameters
       Parameters.Add(new ScopeTreeLookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees."));
@@ -85,4 +87,6 @@
       Parameters.Add(new FixedValueParameter<BoolValue>(UseClassValuesParameterName, "Specifies whether the raw estimated values of the tree or the corresponding class values should be used for similarity calculation.", new BoolValue(false)));
       #endregion
+
+      UpdateCounterParameter.ActualName = "PhenotypicDiversityAnalyzerUpdateCounter";
     }
 
@@ -101,19 +105,32 @@
 
     public override IOperation Apply() {
-      var trees = SymbolicExpressionTreeParameter.ActualValue;
-      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
-      var problemData = ProblemDataParameter.ActualValue;
-      var ds = ProblemDataParameter.ActualValue.Dataset;
-      var rows = ProblemDataParameter.ActualValue.TrainingIndices;
-      var modelCreator = ModelCreatorParameter.ActualValue;
-      var estimationLimits = EstimationLimitsParameter.ActualValue;
-      var evaluatedValues = new ItemArray<DoubleArray>(trees.Length);
-      for (int i = 0; i < trees.Length; ++i) {
-        var model = (IDiscriminantFunctionClassificationModel)modelCreator.CreateSymbolicDiscriminantFunctionClassificationModel(trees[i], interpreter, estimationLimits.Lower, estimationLimits.Upper);
-        model.RecalculateModelParameters(problemData, rows);
-        var values = UseClassValues ? model.GetEstimatedClassValues(ds, rows) : model.GetEstimatedValues(ds, rows);
-        evaluatedValues[i] = new DoubleArray(values.ToArray());
+      int updateInterval = UpdateIntervalParameter.Value.Value;
+      IntValue updateCounter = UpdateCounterParameter.ActualValue;
+
+      if (updateCounter == null) {
+        updateCounter = new IntValue(updateInterval);
+        UpdateCounterParameter.ActualValue = updateCounter;
       }
-      EvaluatedValuesParameter.ActualValue = evaluatedValues;
+
+      if (updateCounter.Value == updateInterval) {
+        var trees = SymbolicExpressionTreeParameter.ActualValue;
+        var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+        var problemData = ProblemDataParameter.ActualValue;
+        var ds = ProblemDataParameter.ActualValue.Dataset;
+        var rows = ProblemDataParameter.ActualValue.TrainingIndices;
+        var modelCreator = ModelCreatorParameter.ActualValue;
+        var estimationLimits = EstimationLimitsParameter.ActualValue;
+        var evaluatedValues = new ItemArray<DoubleArray>(trees.Length);
+        for (int i = 0; i < trees.Length; ++i) {
+          var model =
+            (IDiscriminantFunctionClassificationModel)
+              modelCreator.CreateSymbolicDiscriminantFunctionClassificationModel(trees[i], interpreter,
+                estimationLimits.Lower, estimationLimits.Upper);
+          model.RecalculateModelParameters(problemData, rows);
+          var values = UseClassValues ? model.GetEstimatedClassValues(ds, rows) : model.GetEstimatedValues(ds, rows);
+          evaluatedValues[i] = new DoubleArray(values.ToArray());
+        }
+        EvaluatedValuesParameter.ActualValue = evaluatedValues;
+      }
       return base.Apply();
     }
Index: branches/SymbolicExpressionTreeDiversityAnalyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs
===================================================================
--- branches/SymbolicExpressionTreeDiversityAnalyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs	(revision 12068)
+++ branches/SymbolicExpressionTreeDiversityAnalyzers/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs	(revision 12075)
@@ -22,4 +22,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -115,6 +116,6 @@
       Operators.Add(new SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer());
       Operators.Add(new SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer());
-      Operators.Add(new SymbolicClassificationPhenotypicDiversityAnalyzer());
       Operators.Add(new SymbolicExpressionTreePhenotypicSimilarityCalculator());
+      Operators.Add(new SymbolicClassificationPhenotypicDiversityAnalyzer(Operators.OfType<SymbolicExpressionTreePhenotypicSimilarityCalculator>()) { DiversityResultName = "Phenotypic Similarity" });
       ParameterizeOperators();
     }
@@ -148,14 +149,13 @@
       }
 
-      foreach (var op in Operators.OfType<SymbolicExpressionTreePhenotypicSimilarityCalculator>()) {
+      foreach (var op in Operators.OfType<ISingleObjectiveSolutionSimilarityCalculator>()) {
         op.SolutionVariableName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
-        op.ProblemData = ProblemData;
-        op.Interpreter = SymbolicExpressionTreeInterpreter;
-      }
+        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
 
-      foreach (var op in Operators.OfType<SymbolicClassificationPhenotypicDiversityAnalyzer>()) {
-        var sim = Operators.OfType<SymbolicExpressionTreePhenotypicSimilarityCalculator>().FirstOrDefault();
-        if (sim != null)
-          op.SimilarityCalculator = sim;
+        if (op is SymbolicExpressionTreePhenotypicSimilarityCalculator) {
+          var phenotypicSimilarityCalculator = (SymbolicExpressionTreePhenotypicSimilarityCalculator)op;
+          phenotypicSimilarityCalculator.ProblemData = ProblemData;
+          phenotypicSimilarityCalculator.Interpreter = SymbolicExpressionTreeInterpreter;
+        }
       }
     }
