/**
  * Adds all API super types of the given type to the given list in top down order.
  *
  * @param superTypes list to add to
  * @param type type being processed
  */
 private void gatherAPISuperTypes(List<IApiType> superTypes, IApiType type) throws CoreException {
   if (type != null) {
     if (isAPIType(type)) {
       superTypes.add(0, type);
     }
     gatherAPISuperTypes(superTypes, type.getSuperclass());
     IApiType[] interfaces = type.getSuperInterfaces();
     if (interfaces != null) {
       for (int i = 0; i < interfaces.length; i++) {
         if (isAPIType(interfaces[i])) {
           superTypes.add(interfaces[i]);
           gatherAPISuperTypes(superTypes, interfaces[i]);
         }
       }
     }
   }
 }
 /*
  * (non-Javadoc)
  * @see
  * org.eclipse.pde.api.tools.internal.search.AbstractTypeLeakDetector#isProblem
  * (org.eclipse.pde.api.tools.internal.provisional.model.IReference)
  */
 @Override
 public boolean isProblem(IReference reference) {
   if (super.isProblem(reference)) {
     // check the use restrictions on the API type (can be extended or
     // not)
     IApiType type = (IApiType) reference.getMember();
     IApiComponent component = type.getApiComponent();
     try {
       if (type.isClass()) {
         int modifiers = 0;
         IApiAnnotations annotations =
             component.getApiDescription().resolveAnnotations(type.getHandle());
         if (annotations != null) {
           // if annotations are null, the reference should not
           // have been retained
           // as it indicates a reference from a top level non
           // public type
           if (RestrictionModifiers.isExtendRestriction(annotations.getRestrictions())) {
             // The no extend restriction means only public
             // members can be seen
             modifiers = Flags.AccPublic;
           } else {
             if (Flags.isFinal(type.getModifiers())) {
               // if final then only public members can be seen
               modifiers = Flags.AccPublic;
             } else {
               // public and protected members can be seen
               modifiers = Flags.AccPublic | Flags.AccProtected;
             }
           }
           IApiType nonApiSuper = type.getSuperclass();
           // collect all visible methods in non-API types
           Set<MethodKey> methods = new HashSet<MethodKey>();
           while (!isAPIType(nonApiSuper)) {
             if (hasVisibleField(nonApiSuper, modifiers)) {
               // a visible field in a non-API type is a
               // definite leak
               return true;
             }
             gatherVisibleMethods(nonApiSuper, methods, modifiers);
             nonApiSuper = nonApiSuper.getSuperclass();
           }
           if (methods.size() > 0) {
             // check if the visible members are part of an API
             // interface/class
             List<IApiType> apiTypes = new LinkedList<IApiType>();
             apiTypes.add(type);
             gatherAPISuperTypes(apiTypes, type);
             for (IApiType t2 : apiTypes) {
               Set<MethodKey> apiMembers = new HashSet<MethodKey>();
               gatherVisibleMethods(t2, apiMembers, modifiers);
               methods.removeAll(apiMembers);
               if (methods.size() == 0) {
                 // there are no visible methods left that
                 // are not part of an API type/interface
                 return false;
               }
             }
             if (methods.size() > 0) {
               // there are visible members that are not part
               // of an API type/interface
               return true;
             }
           }
         }
       } else {
         // don't process interfaces, enums, annotations
         return true;
       }
     } catch (CoreException ce) {
       if (ApiPlugin.DEBUG_PROBLEM_DETECTOR) {
         ApiPlugin.log(ce);
       }
       return true;
     }
   }
   return false;
 }