Performance optimization for hierarchy cache invalidation.
diff --git a/org.eclipse.scout.sdk.ui/src/org/eclipse/scout/sdk/ui/internal/view/outline/pages/project/client/form/field/FormFieldTemplateTablePage.java b/org.eclipse.scout.sdk.ui/src/org/eclipse/scout/sdk/ui/internal/view/outline/pages/project/client/form/field/FormFieldTemplateTablePage.java
index 1eec301..d15e90b 100644
--- a/org.eclipse.scout.sdk.ui/src/org/eclipse/scout/sdk/ui/internal/view/outline/pages/project/client/form/field/FormFieldTemplateTablePage.java
+++ b/org.eclipse.scout.sdk.ui/src/org/eclipse/scout/sdk/ui/internal/view/outline/pages/project/client/form/field/FormFieldTemplateTablePage.java
@@ -66,8 +66,10 @@
   protected void loadChildrenImpl() {
     for (IType fieldTemplate : resolveFormFieldTemplates()) {
       ITypePage nodePage = (ITypePage) FormFieldExtensionPoint.createNodePage(fieldTemplate, m_formFieldHierarchy);
-      nodePage.setParent(this);
-      nodePage.setType(fieldTemplate);
+      if (nodePage != null) {
+        nodePage.setParent(this);
+        nodePage.setType(fieldTemplate);
+      }
     }
   }
 
diff --git a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/HierarchyCache.java b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/HierarchyCache.java
index 33acc30..c29649a 100644
--- a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/HierarchyCache.java
+++ b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/HierarchyCache.java
@@ -125,6 +125,15 @@
     }
   }
 
+  private static boolean areTypesInHierarchy(CachedTypeHierarchy h, IType[] types) {
+    for (IType t : types) {
+      if (h.contains(t)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   private void handleTypeChange(IType t, ITypeHierarchy superTypeHierarchy) {
     try {
       ArrayList<CachedTypeHierarchy> hierarchies = new ArrayList<CachedTypeHierarchy>(m_cachedPrimaryTypeHierarchies.size());
@@ -135,12 +144,13 @@
       }
 
       if (hierarchies.size() > 0) {
+        IType[] superTypes = superTypeHierarchy.getSupertypes(t);
+
         for (CachedTypeHierarchy h : hierarchies) {
           if (h.isCreated()) {
-            IType[] superTypes = superTypeHierarchy.getSupertypes(t);
 
             if (h.contains(t)) {
-              if (!h.containsInSubHierarchy(h.getType(), superTypes)) {
+              if (!areTypesInHierarchy(h, superTypes)) {
                 // remove
                 h.invalidate();
               }
@@ -153,7 +163,7 @@
               }
             }
             else {
-              if (h.containsInSubHierarchy(h.getType(), superTypes)) {
+              if (areTypesInHierarchy(h, superTypes)) {
                 // add
                 h.invalidate();
               }
diff --git a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/TypeHierarchy.java b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/TypeHierarchy.java
index 83677b2..7e4cb1f 100644
--- a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/TypeHierarchy.java
+++ b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/internal/typecache/TypeHierarchy.java
@@ -10,7 +10,7 @@
  ******************************************************************************/
 package org.eclipse.scout.sdk.util.internal.typecache;
 
-import java.util.Arrays;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Set;
@@ -19,6 +19,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.scout.commons.CompareUtility;
 import org.eclipse.scout.sdk.util.type.ITypeFilter;
 import org.eclipse.scout.sdk.util.type.TypeUtility;
 
@@ -107,21 +108,13 @@
 
   @Override
   public boolean isSubtype(IType type, IType potentialSubtype) {
-    HashSet<IType> allSubTypes = new HashSet<IType>(Arrays.asList(getAllSubtypes(type)));
-    allSubTypes.add(type);
-    return allSubTypes.contains(potentialSubtype);
+    if (CompareUtility.equals(type, potentialSubtype)) {
+      return true;
   }
 
-  @Override
-  public boolean containsInSubHierarchy(IType type, IType[] potentialSubtypes) {
-    HashSet<IType> allSubTypes = new HashSet<IType>(Arrays.asList(getAllSubtypes(type)));
-    allSubTypes.add(type);
-    for (IType pt : potentialSubtypes) {
-      if (allSubTypes.contains(pt)) {
-        return true;
-      }
-    }
-    return false;
+    revalidate(null);
+    HashSet<IType> allSubTypes = (HashSet<IType>) getTypesFilteredAndSortedImpl(m_hierarchy.getAllSubtypes(type), null, null);
+    return allSubTypes.contains(potentialSubtype);
   }
 
   @Override
@@ -312,6 +305,11 @@
   }
 
   private static IType[] getTypesFilteredAndSorted(IType[] types, ITypeFilter filter, Comparator<IType> comparator) {
+    Collection<IType> result = getTypesFilteredAndSortedImpl(types, filter, comparator);
+    return result.toArray(new IType[result.size()]);
+  }
+
+  private static Collection<IType> getTypesFilteredAndSortedImpl(IType[] types, ITypeFilter filter, Comparator<IType> comparator) {
     Set<IType> result = null;
     if (comparator == null) {
       result = new HashSet<IType>();
@@ -327,6 +325,6 @@
         }
       }
     }
-    return result.toArray(new IType[result.size()]);
+    return result;
   }
 }
diff --git a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/typecache/ITypeHierarchy.java b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/typecache/ITypeHierarchy.java
index b25e844..984bddb 100644
--- a/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/typecache/ITypeHierarchy.java
+++ b/org.eclipse.scout.sdk.util/src/org/eclipse/scout/sdk/util/typecache/ITypeHierarchy.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
  * Contributors:
  *     BSI Business Systems Integration AG - initial API and implementation
  ******************************************************************************/
@@ -100,13 +100,6 @@
   boolean isSubtype(IType type, IType potentialSubtype);
 
   /**
-   * @param type
-   * @param potentialSubtypes
-   * @return true if one of the potentialSubtypes is a subtype of the given type
-   */
-  boolean containsInSubHierarchy(IType type, IType[] potentialSubtypes);
-
-  /**
    * @see ITypeHierarchy#getAllSuperclasses(IType, ITypeFilter, Comparator)
    */
   IType[] getAllSuperclasses(IType type);