Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 14720)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 14721)
@@ -35,13 +35,13 @@
   [Item("SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic data analysis solution for single objective symbolic data analysis problems.")]
   [StorableClass]
-  public abstract class SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<T> : SymbolicDataAnalysisSingleObjectiveAnalyzer, IIterationBasedOperator
-
-    where T : class, ISymbolicDataAnalysisSolution {
+  public abstract class SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<T> : SymbolicDataAnalysisSingleObjectiveAnalyzer, IIterationBasedOperator where T : class, ISymbolicDataAnalysisSolution {
     private const string TrainingBestSolutionParameterName = "Best training solution";
     private const string TrainingBestSolutionQualityParameterName = "Best training solution quality";
     private const string TrainingBestSolutionGenerationParameterName = "Best training solution generation";
+    private const string TrainingBestSolutionsHistoryParameterName = "Best training solutions history";
     private const string UpdateAlwaysParameterName = "Always update best solution";
     private const string IterationsParameterName = "Iterations";
     private const string MaximumIterationsParameterName = "Maximum Iterations";
+    private const string StoreHistoryParameterName = "Store History";
 
     #region parameter properties
@@ -55,4 +55,7 @@
       get { return (ILookupParameter<IntValue>)Parameters[TrainingBestSolutionGenerationParameterName]; }
     }
+    public ILookupParameter<ItemList<T>> TrainingBestSolutionsHistoryParameter {
+      get { return (ILookupParameter<ItemList<T>>)Parameters[TrainingBestSolutionsHistoryParameterName]; }
+    }
     public IFixedValueParameter<BoolValue> UpdateAlwaysParameter {
       get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateAlwaysParameterName]; }
@@ -63,4 +66,8 @@
     public IValueLookupParameter<IntValue> MaximumIterationsParameter {
       get { return (IValueLookupParameter<IntValue>)Parameters[MaximumIterationsParameterName]; }
+    }
+
+    public IFixedValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[StoreHistoryParameterName]; }
     }
     #endregion
@@ -74,8 +81,15 @@
       set { TrainingBestSolutionQualityParameter.ActualValue = value; }
     }
-    public BoolValue UpdateAlways {
-      get { return UpdateAlwaysParameter.Value; }
+    public bool UpdateAlways {
+      get { return UpdateAlwaysParameter.Value.Value; }
+      set { UpdateAlwaysParameter.Value.Value = value; }
+    }
+
+    public bool StoreHistory {
+      get { return StoreHistoryParameter.Value.Value; }
+      set { StoreHistoryParameter.Value.Value = value; }
     }
     #endregion
+
 
     [StorableConstructor]
@@ -84,5 +98,5 @@
     public SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer()
       : base() {
-      Parameters.Add(new LookupParameter<T>(TrainingBestSolutionParameterName, "The training best symbolic data analyis solution."));
+      Parameters.Add(new LookupParameter<T>(TrainingBestSolutionParameterName, "The best training symbolic data analyis solution."));
       Parameters.Add(new LookupParameter<DoubleValue>(TrainingBestSolutionQualityParameterName, "The quality of the training best symbolic data analysis solution."));
       Parameters.Add(new LookupParameter<IntValue>(TrainingBestSolutionGenerationParameterName, "The generation in which the best training solution was found."));
@@ -90,4 +104,6 @@
       Parameters.Add(new LookupParameter<IntValue>(IterationsParameterName, "The number of performed iterations."));
       Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsParameterName, "The maximum number of performed iterations.") { Hidden = true });
+      Parameters.Add(new FixedValueParameter<BoolValue>(StoreHistoryParameterName, "Flag that determines whether all encountered best solutions should be stored as results.", new BoolValue(false)));
+      Parameters.Add(new LookupParameter<ItemList<T>>(TrainingBestSolutionsHistoryParameterName, "The history of the best training symbolic data analysis solutions."));
       UpdateAlwaysParameter.Hidden = true;
     }
@@ -105,7 +121,27 @@
       if (!Parameters.ContainsKey(MaximumIterationsParameterName))
         Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsParameterName, "The maximum number of performed iterations.") { Hidden = true });
+      if (!Parameters.ContainsKey(StoreHistoryParameterName))
+        Parameters.Add(new FixedValueParameter<BoolValue>(StoreHistoryParameterName, "Flag that determines whether all encountered best solutions should be stored as results.", new BoolValue(false)));
+      if (!Parameters.ContainsKey(TrainingBestSolutionsHistoryParameterName))
+        Parameters.Add(new LookupParameter<ItemList<T>>(TrainingBestSolutionsHistoryParameterName, "The history of the best training symbolic data analysis solutions."));
     }
 
     public override IOperation Apply() {
+      var results = ResultCollection;
+      #region create results
+      if (!results.ContainsKey(TrainingBestSolutionParameter.Name))
+        results.Add(new Result(TrainingBestSolutionParameter.Name, TrainingBestSolutionParameter.Description, typeof(T)));
+      if (!results.ContainsKey(TrainingBestSolutionQualityParameter.Name))
+        results.Add(new Result(TrainingBestSolutionQualityParameter.Name, TrainingBestSolutionQualityParameter.Description, typeof(DoubleValue)));
+      if (!results.ContainsKey(TrainingBestSolutionGenerationParameter.Name) && IterationsParameter.ActualValue != null)
+        results.Add(new Result(TrainingBestSolutionGenerationParameter.Name, TrainingBestSolutionGenerationParameter.Description, typeof(IntValue)));
+      if (StoreHistory && !results.ContainsKey(TrainingBestSolutionsHistoryParameter.Name)) {
+
+        results.Add(new Result(TrainingBestSolutionsHistoryParameter.Name, TrainingBestSolutionsHistoryParameter.Description, typeof(ItemList<T>)));
+        TrainingBestSolutionsHistoryParameter.ActualValue = new ItemList<T>();
+        results[TrainingBestSolutionsHistoryParameter.Name].Value = TrainingBestSolutionsHistoryParameter.ActualValue;
+      }
+      #endregion
+
       #region find best tree
       double bestQuality = Maximization.Value ? double.NegativeInfinity : double.PositiveInfinity;
@@ -121,6 +157,5 @@
       #endregion
 
-      var results = ResultCollection;
-      if (bestTree != null && (UpdateAlways.Value || TrainingBestSolutionQuality == null ||
+      if (bestTree != null && (UpdateAlways || TrainingBestSolutionQuality == null ||
         IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value))) {
         TrainingBestSolution = CreateSolution(bestTree, bestQuality);
@@ -129,15 +164,11 @@
           TrainingBestSolutionGenerationParameter.ActualValue = new IntValue(IterationsParameter.ActualValue.Value);
 
-        if (!results.ContainsKey(TrainingBestSolutionParameter.Name)) {
-          results.Add(new Result(TrainingBestSolutionParameter.Name, TrainingBestSolutionParameter.Description, TrainingBestSolution));
-          results.Add(new Result(TrainingBestSolutionQualityParameter.Name, TrainingBestSolutionQualityParameter.Description, TrainingBestSolutionQuality));
-          if (TrainingBestSolutionGenerationParameter.ActualValue != null)
-            results.Add(new Result(TrainingBestSolutionGenerationParameter.Name, TrainingBestSolutionGenerationParameter.Description, TrainingBestSolutionGenerationParameter.ActualValue));
-        } else {
-          results[TrainingBestSolutionParameter.Name].Value = TrainingBestSolution;
-          results[TrainingBestSolutionQualityParameter.Name].Value = TrainingBestSolutionQuality;
-          if (TrainingBestSolutionGenerationParameter.ActualValue != null)
-            results[TrainingBestSolutionGenerationParameter.Name].Value = TrainingBestSolutionGenerationParameter.ActualValue;
+        results[TrainingBestSolutionParameter.Name].Value = TrainingBestSolution;
+        results[TrainingBestSolutionQualityParameter.Name].Value = TrainingBestSolutionQuality;
+        if (TrainingBestSolutionGenerationParameter.ActualValue != null)
+          results[TrainingBestSolutionGenerationParameter.Name].Value = TrainingBestSolutionGenerationParameter.ActualValue;
 
+        if (StoreHistory) {
+          TrainingBestSolutionsHistoryParameter.ActualValue.Add(TrainingBestSolution);
         }
       }
