Index: /trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/FunctionLibraryInjectors/SimpleFunctionLibraryInjector.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/FunctionLibraryInjectors/SimpleFunctionLibraryInjector.cs	(revision 2674)
+++ /trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/FunctionLibraryInjectors/SimpleFunctionLibraryInjector.cs	(revision 2675)
@@ -67,4 +67,11 @@
 
     protected override FunctionLibrary CreateFunctionLibrary() {
+      return Create(
+        GetVariableValue<BoolData>(DIFFERENTIALS_ALLOWED, null, false).Data,
+        minTimeOffset,
+        maxTimeOffset);
+    }
+
+    public static FunctionLibrary Create(bool differentialAllowed, int minTimeOffset, int maxTimeOffset) {
       FunctionLibrary functionLibrary = new FunctionLibrary();
 
@@ -85,5 +92,5 @@
 
       List<IFunction> valueNodes = new List<IFunction>();
-      ConditionalAddFunction(DIFFERENTIALS_ALLOWED, differential, valueNodes);
+      if (differentialAllowed) valueNodes.Add(differential);
       valueNodes.Add(variable);
       valueNodes.Add(constant);
@@ -122,5 +129,5 @@
       SetAllowedSubOperators(tangens, valueNodes);
 
-      ConditionalAddOperator(DIFFERENTIALS_ALLOWED, functionLibrary, differential);
+      if (differentialAllowed) functionLibrary.AddFunction(differential);
 
       allFunctions.ForEach(x => functionLibrary.AddFunction(x));
@@ -131,12 +138,4 @@
       return functionLibrary;
     }
-
-    private void ConditionalAddFunction(string condName, IFunction fun, List<IFunction> list) {
-      if (GetVariableValue<BoolData>(condName, null, false).Data) list.Add(fun);
-    }
-
-    private void ConditionalAddOperator(string condName, FunctionLibrary functionLib, IFunction op) {
-      if (GetVariableValue<BoolData>(condName, null, false).Data) functionLib.AddFunction(op);
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.GP.Tests/HeuristicLab.GP.Tests.csproj
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/HeuristicLab.GP.Tests.csproj	(revision 2674)
+++ /trunk/sources/HeuristicLab.GP.Tests/HeuristicLab.GP.Tests.csproj	(revision 2675)
@@ -63,4 +63,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="SimpleFunctionLibraryTest.cs" />
     <Compile Include="NetworkFunctionLibraryTest.cs" />
     <Compile Include="HL3TreeEvaluatorTest.cs" />
Index: /trunk/sources/HeuristicLab.GP.Tests/SimpleFunctionLibraryTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/SimpleFunctionLibraryTest.cs	(revision 2675)
+++ /trunk/sources/HeuristicLab.GP.Tests/SimpleFunctionLibraryTest.cs	(revision 2675)
@@ -0,0 +1,144 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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 HeuristicLab.GP.StructureIdentification;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.DataAnalysis;
+using System;
+using HeuristicLab.GP.Interfaces;
+using HeuristicLab.Random;
+using HeuristicLab.GP.Operators;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+namespace HeuristicLab.GP.Test {
+
+
+  [TestClass()]
+  public class SimpleFunctionLibraryTest {
+    private const int N = 1000;
+    private TestContext testContextInstance;
+    private static IFunctionTree[] randomTrees;
+
+    /// <summary>
+    ///Gets or sets the test context which provides
+    ///information about and functionality for the current test run.
+    ///</summary>
+    public TestContext TestContext {
+      get {
+        return testContextInstance;
+      }
+      set {
+        testContextInstance = value;
+      }
+    }
+
+    [ClassInitialize()]
+    public static void CreateRandomNetworks(TestContext testContext) {
+      MersenneTwister twister = new MersenneTwister();
+      Dataset ds = Util.CreateRandomDataset(twister, 1, 20);
+      randomTrees = Util.CreateRandomTrees(twister, ds, SimpleFunctionLibraryInjector.Create(true, -3, 0), N, 1, 100);
+    }
+
+    [TestMethod()]
+    public void SimpleFunctionLibrarySizeDistributionTest() {
+      int[] histogram = new int[105 / 5];
+      for (int i = 0; i < randomTrees.Length; i++) {
+        histogram[randomTrees[i].GetSize() / 5]++;
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      for (int i = 0; i < histogram.Length; i++) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append("< "); strBuilder.Append((i + 1) * 5);
+        strBuilder.Append(": "); strBuilder.AppendFormat("{0:#0.00%}", histogram[i] / (double)randomTrees.Length);
+      }
+      Assert.Inconclusive("Size distribution of ProbabilisticTreeCreator: " + strBuilder);
+    }
+
+    [TestMethod()]
+    public void SimpleFunctionLibraryFunctionDistributionTest() {
+      Dictionary<IFunction, int> occurances = new Dictionary<IFunction, int>();
+      double n = 0.0;
+      for (int i = 0; i < randomTrees.Length; i++) {
+        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
+          if (node.SubTrees.Count > 0) {
+            if (!occurances.ContainsKey(node.Function))
+              occurances[node.Function] = 0;
+            occurances[node.Function]++;
+            n++;
+          }
+        }
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      foreach (var function in occurances.Keys) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append(function.Name); strBuilder.Append(": ");
+        strBuilder.AppendFormat("{0:#0.00%}", occurances[function] / n);
+      }
+      Assert.Inconclusive("Function distribution of ProbabilisticTreeCreator: " + strBuilder);
+    }
+
+    [TestMethod()]
+    public void SimpleFunctionLibraryNumberOfSubTreesDistributionTest() {
+      Dictionary<int, int> occurances = new Dictionary<int, int>();
+      double n = 0.0;
+      for (int i = 0; i < randomTrees.Length; i++) {
+        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
+          if (!occurances.ContainsKey(node.SubTrees.Count))
+            occurances[node.SubTrees.Count] = 0;
+          occurances[node.SubTrees.Count]++;
+          n++;
+        }
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      foreach (var arity in occurances.Keys) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append(arity); strBuilder.Append(": ");
+        strBuilder.AppendFormat("{0:#0.00%}", occurances[arity] / n);
+      }
+      Assert.Inconclusive("Distribution of function arities of ProbabilisticTreeCreator: " + strBuilder);
+    }
+
+
+    [TestMethod()]
+    public void SimpleFunctionLibraryTerminalDistributionTest() {
+      Dictionary<IFunction, int> occurances = new Dictionary<IFunction, int>();
+      double n = 0.0;
+      for (int i = 0; i < randomTrees.Length; i++) {
+        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
+          if (node.SubTrees.Count == 0) {
+            if (!occurances.ContainsKey(node.Function))
+              occurances[node.Function] = 0;
+            occurances[node.Function]++;
+            n++;
+          }
+        }
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      foreach (var function in occurances.Keys) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append(function.Name); strBuilder.Append(": ");
+        strBuilder.AppendFormat("{0:#0.00%}", occurances[function] / n);
+      }
+      Assert.Inconclusive("Terminal distribution of ProbabilisticTreeCreator: " + strBuilder);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.GP/3.3/BaseClasses/FunctionBase.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP/3.3/BaseClasses/FunctionBase.cs	(revision 2674)
+++ /trunk/sources/HeuristicLab.GP/3.3/BaseClasses/FunctionBase.cs	(revision 2675)
@@ -27,4 +27,5 @@
 using System.Diagnostics;
 using HeuristicLab.GP.Interfaces;
+using System.Linq;
 
 namespace HeuristicLab.GP {
@@ -72,4 +73,5 @@
       get {
         if (minTreeSize <= 0) RecalculateMinimalTreeSize();
+        Debug.Assert(minTreeSize > 0);
         return minTreeSize;
       }
@@ -79,4 +81,5 @@
       get {
         if (minTreeHeight <= 0) RecalculateMinimalTreeHeight();
+        Debug.Assert(minTreeHeight > 0);
         return minTreeHeight;
       }
@@ -130,27 +133,25 @@
 
     private void RecalculateMinimalTreeSize() {
-      minTreeSize = int.MaxValue;
-      int sum = 1;
-      int minSize = int.MaxValue;
-      for (int i = 0; i < MinSubTrees; i++) {
-        foreach (IFunction subFun in GetAllowedSubFunctions(i)) {
-          minSize = Math.Min(minSize, subFun.MinTreeSize);
-        }
-        sum += minSize;
-      }
-      minTreeSize = sum;
+      if (MinSubTrees == 0) minTreeSize = 1;
+      else {
+        minTreeSize = int.MaxValue; // prevent infinite recursion
+        minTreeSize = 1 + (from slot in Enumerable.Range(0, MinSubTrees)
+                           let minForSlot = (from function in GetAllowedSubFunctions(slot)
+                                             where function != this
+                                             select function.MinTreeSize).Min()
+                           select minForSlot).Sum();
+      }
     }
 
     private void RecalculateMinimalTreeHeight() {
-      minTreeHeight = int.MaxValue;
-      int height = 0;
-      int minHeight = int.MaxValue;
-      for (int i = 0; i < MinSubTrees; i++) {
-        foreach (IFunction subFun in GetAllowedSubFunctions(i)) {
-          minHeight = Math.Min(minHeight, subFun.MinTreeHeight);
-        }
-        height = Math.Max(height, minHeight);
-      }
-      minTreeHeight = height + 1;
+      if (MinSubTrees == 0) minTreeHeight = 1;
+      else {
+        minTreeHeight = int.MaxValue;
+        minTreeHeight = 1 + (from slot in Enumerable.Range(0, MinSubTrees)
+                             let minForSlot = (from function in GetAllowedSubFunctions(slot)
+                                               where function != this
+                                               select function.MinTreeHeight).Min()
+                             select minForSlot).Max();
+      }
     }
 
Index: /trunk/sources/HeuristicLab.GP/3.3/TreeGardener.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP/3.3/TreeGardener.cs	(revision 2674)
+++ /trunk/sources/HeuristicLab.GP/3.3/TreeGardener.cs	(revision 2675)
@@ -120,5 +120,5 @@
           int a = (int)nextExtension[1];
           int d = (int)nextExtension[2];
-          if (d == maxDepth) {
+          if (d + parent.Function.MinTreeHeight >= maxDepth) {
             parent.RemoveSubTree(a);
             IFunctionTree branch = CreateRandomTree(GetAllowedSubFunctions(parent.Function, a), 1, 1);
@@ -127,6 +127,11 @@
             totalListMinSize -= branch.GetSize();
           } else {
-            IFunction selectedFunction = TreeGardener.RandomSelect(random, GetAllowedSubFunctions(parent.Function, a).Where(
-              f => IsRecursiveExpansionPossible(f) && f.MinTreeHeight + (d - 1) <= maxDepth).ToArray());
+            var allowedSubFunctions = from f in GetAllowedSubFunctions(parent.Function, a)
+                                      where f.MinTreeHeight + (d - 1) < maxDepth
+                                      where IsRecursiveExpansionPossible(f) ||
+                                            totalListMinSize + currentSize >= size * 0.9 // if the necessary size is almost reached then also allow
+                                                                                         // terminals or terminal-branches
+                                      select f;
+            IFunction selectedFunction = TreeGardener.RandomSelect(random, allowedSubFunctions.ToList());
             IFunctionTree newTree = selectedFunction.GetTreeNode();
             parent.RemoveSubTree(a);
@@ -146,5 +151,5 @@
               list.Add(new object[] { newTree, i, d + 1 });
             }
-            totalListMinSize += newTree.Function.MinTreeSize - 1;
+            totalListMinSize += newTree.Function.MinTreeSize;
           }
         }
@@ -164,30 +169,30 @@
     }
 
-    private bool IsRecursiveExpansionPossible(IFunction parent) {
-      return FindCycle(parent, new Stack<IFunction>());
+    private bool IsRecursiveExpansionPossible(IFunction function) {
+      return FindCycle(function, new Stack<IFunction>());
     }
 
     private Dictionary<IFunction, bool> inCycle = new Dictionary<IFunction, bool>();
-    private bool FindCycle(IFunction parent, Stack<IFunction> parentChain) {
-      if (inCycle.ContainsKey(parent)) {
-        return inCycle[parent];
-      } else if (IsTerminal(parent)) {
-        inCycle[parent] = false;
+    private bool FindCycle(IFunction function, Stack<IFunction> functionChain) {
+      if (inCycle.ContainsKey(function)) {
+        return inCycle[function];
+      } else if (IsTerminal(function)) {
+        inCycle[function] = false;
         return false;
-      } else if (parentChain.Contains(parent)) {
-        inCycle[parent] = true;
+      } else if (functionChain.Contains(function)) {
+        inCycle[function] = true;
         return true;
       } else {
-        parentChain.Push(parent);
+        functionChain.Push(function);
         bool result = false;
         // all slot indexes
-        for (int i = 0; i < parent.MaxSubTrees; i++) {
-          foreach (IFunction subFunction in GetAllowedSubFunctions(parent, i)) {
-            result |= FindCycle(subFunction, parentChain);
+        for (int i = 0; i < function.MaxSubTrees; i++) {
+          foreach (IFunction subFunction in GetAllowedSubFunctions(function, i)) {
+            result |= FindCycle(subFunction, functionChain);
           }
         }
 
-        parentChain.Pop();
-        inCycle[parent] = result;
+        functionChain.Pop();
+        inCycle[function] = result;
         return result;
       }
