Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 10859)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 10985)
@@ -323,14 +323,19 @@
       if (cachedIsAllowedChildSymbol.TryGetValue(key, out result)) return result;
 
-      List<string> temp;
-      if (allowedChildSymbols.TryGetValue(parent.Name, out temp)) {
-        //if (temp.Contains(child.Name)) return true;
-        if (temp.SelectMany(s => GetSymbol(s).Flatten()).Any(s => s.Name == child.Name)) {
-          cachedIsAllowedChildSymbol.Add(key, true);
-          return true;
+      // value has to be calculated and cached make sure this is done in only one thread
+      lock (cachedIsAllowedChildSymbol) {
+        // in case the value has been calculated on another thread in the meanwhile
+        if (cachedIsAllowedChildSymbol.TryGetValue(key, out result)) return result;
+
+        List<string> temp;
+        if (allowedChildSymbols.TryGetValue(parent.Name, out temp)) {
+          if (temp.SelectMany(s => GetSymbol(s).Flatten()).Any(s => s.Name == child.Name)) {
+            cachedIsAllowedChildSymbol.Add(key, true);
+            return true;
+          }
         }
-      }
-      cachedIsAllowedChildSymbol.Add(key, false);
-      return false;
+        cachedIsAllowedChildSymbol.Add(key, false);
+        return false;
+      }
     }
 
@@ -345,13 +350,19 @@
       if (cachedIsAllowedChildSymbolIndex.TryGetValue(key, out result)) return result;
 
-      List<string> temp;
-      if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, argumentIndex), out temp)) {
-        if (temp.SelectMany(s => GetSymbol(s).Flatten()).Any(s => s.Name == child.Name)) {
-          cachedIsAllowedChildSymbolIndex.Add(key, true);
-          return true;
+      // value has to be calculated and cached make sure this is done in only one thread
+      lock (cachedIsAllowedChildSymbolIndex) {
+        // in case the value has been calculated on another thread in the meanwhile
+        if (cachedIsAllowedChildSymbolIndex.TryGetValue(key, out result)) return result;
+
+        List<string> temp;
+        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, argumentIndex), out temp)) {
+          if (temp.SelectMany(s => GetSymbol(s).Flatten()).Any(s => s.Name == child.Name)) {
+            cachedIsAllowedChildSymbolIndex.Add(key, true);
+            return true;
+          }
         }
-      }
-      cachedIsAllowedChildSymbolIndex.Add(key, false);
-      return false;
+        cachedIsAllowedChildSymbolIndex.Add(key, false);
+        return false;
+      }
     }
 
@@ -391,9 +402,15 @@
         return res;
 
-      res = GetMinimumExpressionLengthRec(symbol);
-      foreach (var entry in cachedMinExpressionLength.Where(e => e.Value >= int.MaxValue).ToList()) {
-        if (entry.Key != symbol.Name) cachedMinExpressionLength.Remove(entry.Key);
-      }
-      return res;
+      // value has to be calculated and cached make sure this is done in only one thread
+      lock (cachedMinExpressionLength) {
+        // in case the value has been calculated on another thread in the meanwhile
+        if (cachedMinExpressionLength.TryGetValue(symbol.Name, out res)) return res;
+
+        res = GetMinimumExpressionLengthRec(symbol);
+        foreach (var entry in cachedMinExpressionLength.Where(e => e.Value >= int.MaxValue).ToList()) {
+          if (entry.Key != symbol.Name) cachedMinExpressionLength.Remove(entry.Key);
+        }
+        return res;
+      }
     }
 
@@ -418,5 +435,10 @@
       int temp;
       var key = Tuple.Create(symbol.Name, maxDepth);
-      if (!cachedMaxExpressionLength.TryGetValue(key, out temp)) {
+      if (cachedMaxExpressionLength.TryGetValue(key, out temp)) return temp;
+      // value has to be calculated and cached make sure this is done in only one thread
+      lock (cachedMaxExpressionLength) {
+        // in case the value has been calculated on another thread in the meanwhile
+        if (cachedMaxExpressionLength.TryGetValue(key, out temp)) return temp;
+
         cachedMaxExpressionLength[key] = int.MaxValue; // prevent infinite recursion
         long sumOfMaxTrees = 1 + (from argIndex in Enumerable.Range(0, GetMaximumSubtreeCount(symbol))
@@ -429,5 +451,4 @@
         return cachedMaxExpressionLength[key];
       }
-      return temp;
     }
 
@@ -438,9 +459,15 @@
         return res;
 
-      res = GetMinimumExpressionDepthRec(symbol);
-      foreach (var entry in cachedMinExpressionDepth.Where(e => e.Value >= int.MaxValue).ToList()) {
-        if (entry.Key != symbol.Name) cachedMinExpressionDepth.Remove(entry.Key);
-      }
-      return res;
+      // value has to be calculated and cached make sure this is done in only one thread
+      lock (cachedMinExpressionDepth) {
+        // in case the value has been calculated on another thread in the meanwhile
+        if (cachedMinExpressionDepth.TryGetValue(symbol.Name, out res)) return res;
+
+        res = GetMinimumExpressionDepthRec(symbol);
+        foreach (var entry in cachedMinExpressionDepth.Where(e => e.Value >= int.MaxValue).ToList()) {
+          if (entry.Key != symbol.Name) cachedMinExpressionDepth.Remove(entry.Key);
+        }
+        return res;
+      }
     }
     private int GetMinimumExpressionDepthRec(ISymbol symbol) {
@@ -462,5 +489,10 @@
     public int GetMaximumExpressionDepth(ISymbol symbol) {
       int temp;
-      if (!cachedMaxExpressionDepth.TryGetValue(symbol.Name, out temp)) {
+      if (cachedMaxExpressionDepth.TryGetValue(symbol.Name, out temp)) return temp;
+      // value has to be calculated and cached make sure this is done in only one thread
+      lock (cachedMaxExpressionDepth) {
+        // in case the value has been calculated on another thread in the meanwhile
+        if (cachedMaxExpressionDepth.TryGetValue(symbol.Name, out temp)) return temp;
+
         cachedMaxExpressionDepth[symbol.Name] = int.MaxValue;
         long maxDepth = 1 + (from argIndex in Enumerable.Range(0, GetMaximumSubtreeCount(symbol))
@@ -472,5 +504,4 @@
         return cachedMaxExpressionDepth[symbol.Name];
       }
-      return temp;
     }
 
