private static LinkedList<TemplateContextType> buildOrderedContextTypes() {
   final TemplateContextType[] typeCollection = getAllContextTypes();
   LinkedList<TemplateContextType> userDefinedExtensionsFirst =
       new LinkedList<TemplateContextType>();
   for (TemplateContextType contextType : typeCollection) {
     if (contextType.getClass().getName().startsWith(Template.class.getPackage().getName())) {
       userDefinedExtensionsFirst.addLast(contextType);
     } else {
       userDefinedExtensionsFirst.addFirst(contextType);
     }
   }
   return userDefinedExtensionsFirst;
 }
 private static List<TemplateContextType> getBases(TemplateContextType type) {
   ArrayList<TemplateContextType> list = new ArrayList<TemplateContextType>();
   while (true) {
     type = type.getBaseContextType();
     if (type == null) return list;
     list.add(type);
   }
 }
  private static Set<TemplateContextType> getDirectlyApplicableContextTypes(
      @NotNull PsiFile file, int offset) {
    LinkedHashSet<TemplateContextType> set = new LinkedHashSet<TemplateContextType>();
    LinkedList<TemplateContextType> contexts = buildOrderedContextTypes();
    for (TemplateContextType contextType : contexts) {
      if (contextType.isInContext(file, offset)) {
        set.add(contextType);
      }
    }

    removeBases:
    while (true) {
      for (TemplateContextType type : set) {
        if (set.removeAll(getBases(type))) {
          continue removeBases;
        }
      }

      return set;
    }
  }