Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj	(revision 5681)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj	(revision 5685)
@@ -109,4 +109,6 @@
   <ItemGroup>
     <Compile Include="Interfaces\ISymbolicDiscriminantFunctionClassificationModel.cs" />
+    <Compile Include="MultiObjective\SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs" />
+    <Compile Include="SingleObjective\SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs" />
     <Compile Include="SymbolicDiscriminantFunctionClassificationModel.cs" />
     <Compile Include="SymbolicDiscriminantFunctionClassificationSolution.cs" />
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveProblem.cs	(revision 5681)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveProblem.cs	(revision 5685)
@@ -24,4 +24,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Parameters;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
@@ -31,5 +32,27 @@
   public class SymbolicClassificationMultiObjectiveProblem : SymbolicDataAnalysisMultiObjectiveProblem<IClassificationProblemData, ISymbolicClassificationMultiObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator> {
     private const double PunishmentFactor = 10;
+    private const int InitialMaximumTreeDepth = 8;
+    private const int InitialMaximumTreeLength = 25;
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterDescription = "The lower limit for the estimated value that can be returned by the symbolic classification model.";
+    private const string UpperEstimationLimitParameterDescription = "The upper limit for the estimated value that can be returned by the symbolic classification model.";
 
+    #region parameter properties
+    public IFixedValueParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+    public IFixedValueParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    #endregion
+    #region properties
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.Value; }
+    }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.Value; }
+    }
+    #endregion
     [StorableConstructor]
     protected SymbolicClassificationMultiObjectiveProblem(bool deserializing) : base(deserializing) { }
@@ -39,10 +62,21 @@
     public SymbolicClassificationMultiObjectiveProblem()
       : base(new ClassificationProblemData(), new SymbolicClassificationMultiObjectiveMeanSquaredErrorTreeSizeEvaluator(), new SymbolicDataAnalysisExpressionTreeCreator()) {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(LowerEstimationLimitParameterName, LowerEstimationLimitParameterDescription, new DoubleValue()));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(UpperEstimationLimitParameterName, UpperEstimationLimitParameterDescription, new DoubleValue()));
+
       Maximization = new BoolArray(new bool[] { false, false });
-      MaximumSymbolicExpressionTreeDepth.Value = 8;
-      MaximumSymbolicExpressionTreeLength.Value = 25;
+      MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
+      MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
+
+      InitializeOperators();
     }
 
-    protected override void UpdateEstimationLimits() {
+    private void InitializeOperators() {
+      Operators.Add(new SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer());
+      Operators.Add(new SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer());
+      ParameterizeOperators();
+    }
+
+    private void UpdateEstimationLimits() {
       if (ProblemData.TrainingPartitionStart.Value < ProblemData.TrainingPartitionEnd.Value) {
         var targetValues = ProblemData.Dataset.GetVariableValues(ProblemData.TargetVariable, ProblemData.TrainingPartitionStart.Value, ProblemData.TrainingPartitionEnd.Value);
@@ -54,4 +88,18 @@
     }
 
+    protected override void OnProblemDataChanged() {
+      base.OnProblemDataChanged();
+      UpdateEstimationLimits();
+    }
+
+    protected new void ParameterizeOperators() {
+      base.ParameterizeOperators();
+      var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators);
+      foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedEvaluator<IClassificationProblemData>>()) {
+        op.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameterName;
+        op.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameterName;
+      }
+    }
+
     public override void ImportProblemDataFromFile(string fileName) {
       ClassificationProblemData problemData = ClassificationProblemData.ImportFromFile(fileName);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 5681)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 5685)
@@ -63,4 +63,5 @@
       : base() {
       Parameters.Add(new LookupParameter<IClassificationProblemData>(ProblemDataParameterName, "The problem data for the symbolic classification solution."));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -77,5 +78,5 @@
       var model = new SymbolicDiscriminantFunctionClassificationModel(bestTree, SymbolicDataAnalysisTreeInterpreter, classValues, thresholds);
       return new SymbolicDiscriminantFunctionClassificationSolution(model, ProblemData);
-    }  
+    }
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 5685)
@@ -0,0 +1,61 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  /// <summary>
+  /// An operator that analyzes the validation best symbolic classification solution for multi objective symbolic classification problems.
+  /// </summary>
+  [Item("SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic classification solution for multi objective symbolic classification problems.")]
+  [StorableClass]
+  public sealed class SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer<ISymbolicClassificationSolution, ISymbolicClassificationMultiObjectiveEvaluator, IClassificationProblemData> {
+    [StorableConstructor]
+    private SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer(SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer()
+      : base() {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer(this, cloner);
+    }
+
+    protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQualities) {
+      double[] classValues;
+      double[] thresholds;
+      // calculate thresholds on the whole training set even for the validation best solution
+      var estimatedValues = SymbolicDataAnalysisTreeInterpreter.GetSymbolicExpressionTreeValues(bestTree, ProblemData.Dataset, ProblemData.TrainingIndizes);
+      var targetClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      AccuracyMaximizationThresholdCalculator.CalculateThresholds(ProblemData, estimatedValues, targetClassValues, out classValues, out thresholds);
+      var model = new SymbolicDiscriminantFunctionClassificationModel(bestTree, SymbolicDataAnalysisTreeInterpreter, classValues, thresholds);
+      return new SymbolicDiscriminantFunctionClassificationSolution(model, ProblemData);
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs	(revision 5681)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs	(revision 5685)
@@ -23,4 +23,6 @@
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
@@ -30,5 +32,27 @@
   public class SymbolicClassificationSingleObjectiveProblem : SymbolicDataAnalysisSingleObjectiveProblem<IClassificationProblemData, ISymbolicClassificationSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator> {
     private const double PunishmentFactor = 10;
+    private const int InitialMaximumTreeDepth = 8;
+    private const int InitialMaximumTreeLength = 25;
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterDescription = "The lower limit for the estimated value that can be returned by the symbolic classification model.";
+    private const string UpperEstimationLimitParameterDescription = "The upper limit for the estimated value that can be returned by the symbolic classification model.";
 
+    #region parameter properties
+    public IFixedValueParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+    public IFixedValueParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    #endregion
+    #region properties
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.Value; }
+    }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.Value; }
+    }
+    #endregion
     [StorableConstructor]
     protected SymbolicClassificationSingleObjectiveProblem(bool deserializing) : base(deserializing) { }
@@ -38,9 +62,20 @@
     public SymbolicClassificationSingleObjectiveProblem()
       : base(new ClassificationProblemData(), new SymbolicClassificationSingleObjectiveMeanSquaredErrorEvaluator(), new SymbolicDataAnalysisExpressionTreeCreator()) {
-      MaximumSymbolicExpressionTreeDepth.Value = 8;
-      MaximumSymbolicExpressionTreeLength.Value = 25;
+      Parameters.Add(new FixedValueParameter<DoubleValue>(LowerEstimationLimitParameterName, LowerEstimationLimitParameterDescription, new DoubleValue()));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(UpperEstimationLimitParameterName, UpperEstimationLimitParameterDescription, new DoubleValue()));
+
+      MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
+      MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
+
+      InitializeOperators();
     }
 
-    protected override void UpdateEstimationLimits() {
+    private void InitializeOperators() {
+      Operators.Add(new SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer());
+      Operators.Add(new SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer());
+      ParameterizeOperators();
+    }
+
+    private void UpdateEstimationLimits() {
       if (ProblemData.TrainingPartitionStart.Value < ProblemData.TrainingPartitionEnd.Value) {
         var targetValues = ProblemData.Dataset.GetVariableValues(ProblemData.TargetVariable, ProblemData.TrainingPartitionStart.Value, ProblemData.TrainingPartitionEnd.Value);
@@ -52,4 +87,18 @@
     }
 
+    protected override void OnProblemDataChanged() {
+      base.OnProblemDataChanged();
+      UpdateEstimationLimits();
+    }
+
+    protected override void ParameterizeOperators() {
+      base.ParameterizeOperators();
+      var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators);
+      foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedEvaluator<IClassificationProblemData>>()) {
+        op.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameterName;
+        op.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameterName;
+      }
+    }
+
     public override void ImportProblemDataFromFile(string fileName) {
       ClassificationProblemData problemData = ClassificationProblemData.ImportFromFile(fileName);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 5681)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 5685)
@@ -62,4 +62,6 @@
     public SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer()
       : base() {
+      Parameters.Add(new LookupParameter<IClassificationProblemData>(ProblemDataParameterName, "The problem data for the symbolic classification solution."));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 5685)
@@ -0,0 +1,61 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  /// <summary>
+  /// An operator that analyzes the validation best symbolic classification solution for single objective symbolic classification problems.
+  /// </summary>
+  [Item("SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic classification solution for single objective symbolic classification problems.")]
+  [StorableClass]
+  public sealed class SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer<ISymbolicClassificationSolution, ISymbolicClassificationSingleObjectiveEvaluator, IClassificationProblemData> {
+    [StorableConstructor]
+    private SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer(SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer()
+      : base() {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer(this, cloner);
+    }
+
+    protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
+      double[] classValues;
+      double[] thresholds;
+      // calculate thresholds on the whole training set even for the validation best solution
+      var estimatedValues = SymbolicDataAnalysisTreeInterpreter.GetSymbolicExpressionTreeValues(bestTree, ProblemData.Dataset, ProblemData.TrainingIndizes);
+      var targetClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      AccuracyMaximizationThresholdCalculator.CalculateThresholds(ProblemData, estimatedValues, targetClassValues, out classValues, out thresholds);
+      var model = new SymbolicDiscriminantFunctionClassificationModel(bestTree, SymbolicDataAnalysisTreeInterpreter, classValues, thresholds);
+      return new SymbolicDiscriminantFunctionClassificationSolution(model, ProblemData);
+    }
+  }
+}
