Index: anches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisModelComplexityAnalyzer.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisModelComplexityAnalyzer.cs	(revision 13219)
+++ 	(revision )
@@ -1,127 +1,0 @@
-﻿#region License Information
-
-/* HeuristicLab
- * Copyright (C) 2002-2015 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;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public class SymbolicDataAnalysisModelComplexityAnalyzer {
-    public static double CalculateComplexity(ISymbolicExpressionTreeNode node) {
-      switch (OpCodes.MapSymbolToOpCode(node)) {
-        case OpCodes.Constant: {
-            return 1;
-          }
-        case OpCodes.Variable: {
-            return 2;
-          }
-        case OpCodes.Add: {
-            double complexity = 0;
-            for (int i = 0; i < node.SubtreeCount; i++) {
-              complexity += CalculateComplexity(node.GetSubtree(i));
-            }
-            return complexity;
-          }
-        case OpCodes.Sub: {
-            double complexity = 0;
-            for (int i = 0; i < node.SubtreeCount; i++) {
-              complexity += CalculateComplexity(node.GetSubtree(i));
-            }
-            return complexity;
-          }
-        case OpCodes.Mul: {
-            double complexity = 1;
-            for (int i = 0; i < node.SubtreeCount; i++) {
-              var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
-              complexity *= nodeComplexity + 1;
-            }
-            return complexity;
-          }
-        case OpCodes.Div: {
-            double complexity = 1;
-            for (int i = 0; i < node.SubtreeCount; i++) {
-              var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
-              complexity *= nodeComplexity +1;
-            }
-            return complexity;
-          }
-        case OpCodes.Sin: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return Math.Pow(2.0, complexity);
-          }
-        case OpCodes.Cos: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return Math.Pow(2.0, complexity);
-          }
-        case OpCodes.Tan: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return Math.Pow(2.0, complexity);
-          }
-        case OpCodes.Exp: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return Math.Pow(2.0, complexity);
-          }
-        case OpCodes.Log: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return Math.Pow(2.0, complexity);
-          }
-        case OpCodes.Square: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return complexity * complexity;
-          }
-        case OpCodes.SquareRoot: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            return complexity * complexity * complexity;
-          }
-        case OpCodes.Power: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            var exponentNode = node.GetSubtree(1) as ConstantTreeNode;
-            if (exponentNode != null) {
-              double exponent = exponentNode.Value;
-              if (exponent < 0) exponent = Math.Abs(exponent);
-              if (exponent < 1) exponent = 1 / exponent;
-              return Math.Pow(complexity, Math.Round(exponent));
-            }
-
-            double exponentComplexity = CalculateComplexity(node.GetSubtree(1));
-            return Math.Pow(complexity, 2 * exponentComplexity);
-          }
-        case OpCodes.Root: {
-            double complexity = CalculateComplexity(node.GetSubtree(0));
-            var rootNode = node.GetSubtree(1) as ConstantTreeNode;
-            if (rootNode != null) {
-              double root = rootNode.Value;
-              if (root < 0) root = Math.Abs(root);
-              if (root < 1) root = 1 / root;
-              return Math.Pow(complexity, Math.Round(root));
-            }
-
-            double rootComplexity = CalculateComplexity(node.GetSubtree(1));
-            return Math.Pow(complexity, 2 * rootComplexity);
-          }
-
-        default:
-          throw new NotSupportedException();
-      }
-    }
-  }
-}
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 13219)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 13220)
@@ -41,8 +41,5 @@
     private const string TrainingBestSolutionQualitiesParameterName = "Best training solution qualities";
     private const string UpdateAlwaysParameterName = "Always update best solutions";
-
     private const string TrainingBestSolutionParameterName = "Best training solution";
-    private const string TrainingBestSolutionQualityParameterName = "Best training solution quality";
-    private const string TrainingBestSolutionGenerationParameterName = "Best training solution generation";
 
     #region parameter properties
@@ -58,14 +55,15 @@
     #endregion
     #region properties
-    public ItemList<T> TrainingBestSolutions {
+    private ItemList<T> TrainingBestSolutions {
       get { return TrainingBestSolutionsParameter.ActualValue; }
       set { TrainingBestSolutionsParameter.ActualValue = value; }
     }
-    public ItemList<DoubleArray> TrainingBestSolutionQualities {
+    private ItemList<DoubleArray> TrainingBestSolutionQualities {
       get { return TrainingBestSolutionQualitiesParameter.ActualValue; }
       set { TrainingBestSolutionQualitiesParameter.ActualValue = value; }
     }
-    public BoolValue UpdateAlways {
-      get { return UpdateAlwaysParameter.Value; }
+    public bool UpdateAlways {
+      get { return UpdateAlwaysParameter.Value.Value; }
+      set { UpdateAlwaysParameter.Value.Value = value; }
     }
     #endregion
@@ -106,5 +104,5 @@
       //if the pareto front of best solutions shall be updated regardless of the quality, the list initialized empty to discard old solutions
       List<double[]> trainingBestQualities;
-      if (UpdateAlways.Value) {
+      if (UpdateAlways) {
         trainingBestQualities = new List<double[]>();
       } else {
@@ -144,5 +142,8 @@
         }
 
-        var sortedNonDominatedSolutions = nonDominatedSolutions.OrderByDescending(x => x.Qualities[0]);
+        //assumes the the first objective is always the accuracy
+        var sortedNonDominatedSolutions = maximization[0]
+          ? nonDominatedSolutions.OrderByDescending(x => x.Qualities[0])
+          : nonDominatedSolutions.OrderBy(x => x.Qualities[0]);
         var trainingBestSolution = sortedNonDominatedSolutions.Select(s => s.Solution).First();
         results[TrainingBestSolutionParameterName].Value = trainingBestSolution;
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 13219)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 13220)
@@ -182,5 +182,6 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Analyzers\SymbolicDataAnalysisModelComplexityAnalyzer.cs" />
+    <Compile Include="SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs" />
+    <Compile Include="SymbolicDataAnalysisModelComplexityCalculator.cs" />
     <Compile Include="Analyzers\SymbolicDataAnalysisBottomUpDiversityAnalyzer.cs" />
     <Compile Include="Analyzers\SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs" />
@@ -249,5 +250,4 @@
     <Compile Include="SymbolicDataAnalysisProblem.cs" />
     <Compile Include="SymbolicDataAnalysisSolutionImpactValuesCalculator.cs" />
-    <Compile Include="SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs" />
     <Compile Include="Symbols\Addition.cs" />
     <Compile Include="Symbols\And.cs" />
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs	(revision 13219)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs	(revision 13220)
@@ -28,5 +28,7 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public class SymbolicDataAnalysisExpressionTreeSimplificationOperator : SingleSuccessorOperator {
+  [Item("SymbolicExpressionTreeSimplificationOperator", "Simplfies symbolic expression trees encoding a mathematical formula.")]
+  [StorableClass]
+  public class SymbolicDataAnalysisExpressionTreeSimplificationOperator : SingleSuccessorOperator, ISymbolicExpressionTreeOperator {
     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
 
@@ -46,5 +48,5 @@
 
     public SymbolicDataAnalysisExpressionTreeSimplificationOperator() {
-      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree to be simplified."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree to simplify."));
     }
 
Index: /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModelComplexityCalculator.cs
===================================================================
--- /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModelComplexityCalculator.cs	(revision 13220)
+++ /branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModelComplexityCalculator.cs	(revision 13220)
@@ -0,0 +1,134 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public static class SymbolicDataAnalysisModelComplexityCalculator {
+    public static double CalculateComplexity(ISymbolicExpressionTree tree) {
+      return CalculateComplexity(tree.Root);
+    }
+    public static double CalculateComplexity(ISymbolicExpressionTreeNode treeNode) {
+      var node = treeNode;
+      if (node.Symbol is ProgramRootSymbol) node = node.GetSubtree(0);
+      if (node.Symbol is StartSymbol) node = node.GetSubtree(0);
+
+      switch (OpCodes.MapSymbolToOpCode(node)) {
+        case OpCodes.Constant: {
+            return 1;
+          }
+        case OpCodes.Variable: {
+            return 2;
+          }
+        case OpCodes.Add: {
+            double complexity = 0;
+            for (int i = 0; i < node.SubtreeCount; i++) {
+              complexity += CalculateComplexity(node.GetSubtree(i));
+            }
+            return complexity;
+          }
+        case OpCodes.Sub: {
+            double complexity = 0;
+            for (int i = 0; i < node.SubtreeCount; i++) {
+              complexity += CalculateComplexity(node.GetSubtree(i));
+            }
+            return complexity;
+          }
+        case OpCodes.Mul: {
+            double complexity = 1;
+            for (int i = 0; i < node.SubtreeCount; i++) {
+              var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
+              complexity *= nodeComplexity + 1;
+            }
+            return complexity;
+          }
+        case OpCodes.Div: {
+            double complexity = 1;
+            for (int i = 0; i < node.SubtreeCount; i++) {
+              var nodeComplexity = CalculateComplexity(node.GetSubtree(i));
+              complexity *= nodeComplexity + 1;
+            }
+            return complexity;
+          }
+        case OpCodes.Sin: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return Math.Pow(2.0, complexity);
+          }
+        case OpCodes.Cos: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return Math.Pow(2.0, complexity);
+          }
+        case OpCodes.Tan: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return Math.Pow(2.0, complexity);
+          }
+        case OpCodes.Exp: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return Math.Pow(2.0, complexity);
+          }
+        case OpCodes.Log: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return Math.Pow(2.0, complexity);
+          }
+        case OpCodes.Square: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return complexity * complexity;
+          }
+        case OpCodes.SquareRoot: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            return complexity * complexity * complexity;
+          }
+        case OpCodes.Power: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            var exponentNode = node.GetSubtree(1) as ConstantTreeNode;
+            if (exponentNode != null) {
+              double exponent = exponentNode.Value;
+              if (exponent < 0) exponent = Math.Abs(exponent);
+              if (exponent < 1) exponent = 1 / exponent;
+              return Math.Pow(complexity, Math.Round(exponent));
+            }
+
+            double exponentComplexity = CalculateComplexity(node.GetSubtree(1));
+            return Math.Pow(complexity, 2 * exponentComplexity);
+          }
+        case OpCodes.Root: {
+            double complexity = CalculateComplexity(node.GetSubtree(0));
+            var rootNode = node.GetSubtree(1) as ConstantTreeNode;
+            if (rootNode != null) {
+              double root = rootNode.Value;
+              if (root < 0) root = Math.Abs(root);
+              if (root < 1) root = 1 / root;
+              return Math.Pow(complexity, Math.Round(root));
+            }
+
+            double rootComplexity = CalculateComplexity(node.GetSubtree(1));
+            return Math.Pow(complexity, 2 * rootComplexity);
+          }
+
+        default:
+          throw new NotSupportedException();
+      }
+    }
+  }
+}
