/**
   * Parse a single entry in a jar file
   *
   * @param jar
   * @param entry
   * @param resolver
   * @throws Exception
   */
  protected void parseJarEntry(URI jar, JarEntry entry, final ClassNameResolver resolver)
      throws Exception {
    if (jar == null || entry == null) return;

    // skip directories
    if (entry.isDirectory()) return;

    String name = entry.getName();

    // check file is a valid class file name
    if (isValidClassFileName(name) && isValidClassFilePath(name)) {
      String shortName = name.replace('/', '.').substring(0, name.length() - 6);

      if ((resolver == null)
          || (!resolver.isExcluded(shortName)
              && (!isParsed(shortName) || resolver.shouldOverride(shortName)))) {
        Resource clazz = Resource.newResource("jar:" + jar + "!/" + name);
        if (LOG.isDebugEnabled()) {
          LOG.debug("Scanning class from jar {}", clazz);
        }
        ;
        scanClass(clazz.getInputStream());
      }
    }
  }
 /**
  * Parse the given classes
  *
  * @param classNames
  * @param resolver
  * @throws Exception
  */
 public void parse(List<String> classNames, ClassNameResolver resolver) throws Exception {
   for (String s : classNames) {
     if ((resolver == null)
         || (!resolver.isExcluded(s) && (!isParsed(s) || resolver.shouldOverride(s)))) {
       s = s.replace('.', '/') + ".class";
       URL resource = Loader.getResource(this.getClass(), s, false);
       if (resource != null) {
         Resource r = Resource.newResource(resource);
         scanClass(r.getInputStream());
       }
     }
   }
 }
  /**
   * Parse a given class
   *
   * @param className
   * @param resolver
   * @throws Exception
   */
  public void parse(String className, ClassNameResolver resolver) throws Exception {
    if (className == null) return;

    if (!resolver.isExcluded(className)) {
      if (!isParsed(className) || resolver.shouldOverride(className)) {
        className = className.replace('.', '/') + ".class";
        URL resource = Loader.getResource(this.getClass(), className, false);
        if (resource != null) {
          Resource r = Resource.newResource(resource);
          scanClass(r.getInputStream());
        }
      }
    }
  }
 /**
  * Parse the given class, optionally walking its inheritance hierarchy
  *
  * @param clazz
  * @param resolver
  * @param visitSuperClasses
  * @throws Exception
  */
 public void parse(Class<?> clazz, ClassNameResolver resolver, boolean visitSuperClasses)
     throws Exception {
   Class<?> cz = clazz;
   while (cz != null) {
     if (!resolver.isExcluded(cz.getName())) {
       if (!isParsed(cz.getName()) || resolver.shouldOverride(cz.getName())) {
         String nameAsResource = cz.getName().replace('.', '/') + ".class";
         URL resource = Loader.getResource(this.getClass(), nameAsResource, false);
         if (resource != null) {
           Resource r = Resource.newResource(resource);
           scanClass(r.getInputStream());
         }
       }
     }
     if (visitSuperClasses) cz = cz.getSuperclass();
     else cz = null;
   }
 }
  /**
   * Uses the resolver provided in the constructor with the given pattern to get matching classes.
   * By default uses {@link DefaultClassNameResolver} to resolve {@link Resource} objects to class
   * names.
   */
  public Class[] getClasses(String pattern) {
    Resource[] resources = findResources(pattern);
    List classes = new ArrayList();

    for (int i = 0; i < resources.length; i++) {
      String className =
          classNameResolver.resolveClassName(resources[i], determinePackageRoot(pattern));
      classes.add(loadClass(className));
    }

    return (Class[]) classes.toArray(new Class[0]);
  }
  /**
   * Parse all classes in a directory
   *
   * @param dir
   * @param resolver
   * @throws Exception
   */
  public void parseDir(Resource dir, ClassNameResolver resolver) throws Exception {
    // skip dirs whose name start with . (ie hidden)
    if (!dir.isDirectory() || !dir.exists() || dir.getName().startsWith(".")) return;

    if (LOG.isDebugEnabled()) {
      LOG.debug("Scanning dir {}", dir);
    }
    ;

    String[] files = dir.list();
    for (int f = 0; files != null && f < files.length; f++) {
      try {
        Resource res = dir.addPath(files[f]);
        if (res.isDirectory()) parseDir(res, resolver);
        else {
          // we've already verified the directories, so just verify the class file name
          String filename = res.getFile().getName();
          if (isValidClassFileName(filename)) {
            String name = res.getName();
            if ((resolver == null)
                || (!resolver.isExcluded(name)
                    && (!isParsed(name) || resolver.shouldOverride(name)))) {
              Resource r = Resource.newResource(res.getURL());
              if (LOG.isDebugEnabled()) {
                LOG.debug("Scanning class {}", r);
              }
              ;
              scanClass(r.getInputStream());
            }
          }
        }
      } catch (Exception ex) {
        LOG.warn(Log.EXCEPTION, ex);
      }
    }
  }