/** Loads all existing repository infos from persisent storage. */
  private void preload() {
    try {
      File[] files = getWorkingDir().listFiles(new ExtensionFilter(EXT_REPOSITORY));
      long now = System.currentTimeMillis();

      /** @todo make user configurable */
      long delta = 1000 * 60 * 60 * 24 * 15;

      for (int i = 0; i < files.length; i++) {
        ClassRepositoryEntry.Info info = loadInfo(files[i]);
        _infos.add(info);

        if ((files[i].lastModified() + delta) < now) {
          // remove repository file not used for a long time
          if (!files[i].delete()) {
            Object[] args = {files[i]};
            Loggers.IO.l7dlog(Level.INFO, "IMPORT_DELETE_UNUSED_ERR", args, null);
          }
        }
      }
    } catch (Throwable ex) {
      _infos.clear();
      Loggers.IO.warn("Error preloading the class repository, no import optimizaton available", ex);
    }
  }
  /**
   * Creates a new entry.
   *
   * @param location location of the package to add.
   * @param path path to add.
   * @param types the package types.
   * @param verify if <code>true</code> the package root check will be performed.
   * @return if <code>verify == true</code> returns <code>true</code> when the given location could
   *     be verified, <code>false</code> if the given location is no package root; otherwise always
   *     returns <code>true</code>.
   */
  private static boolean createEntryImpl(
      File location, String path, final Set types, boolean verify) {
    // strip extension
    path = path.substring(0, path.lastIndexOf('.'));

    int pos = path.lastIndexOf('$');

    // is this an inner class?
    if (pos > -1) {
      String className = path.substring(pos + 1);

      // skip anonymous inner classes
      if (StringHelper.isNumber(className)) {
        return true;
      }

      path = path.replace('$', '.');
    } else if (verify) {
      try {
        // we setup a classloader with the given location and check
        // whether the location is indeed a package root
        URL[] url = new URL[] {location.toURL()};
        ClassLoader loader = new URLClassLoader(url, ClassRepository.class.getClassLoader());
        loader.loadClass(path.replace(File.separatorChar, '.'));
      } catch (ClassNotFoundException ex) {
        Object[] args = {path, location};
        Loggers.IO.l7dlog(Level.WARN, "REPOSITORY_NOT_PACKAGE_ROOT", args, null);

        return false;
      } catch (Throwable ex) {
        return false;
      }
    }

    String typeName = StringHelper.getClassName(path);

    // HACK skip obfuscated classes
    // this is necessary to make our import declaration expanding working
    // as it could easily be, that an identifier reported by the parser
    // would be wrongly taken as a type name:
    //
    //      Database d = new Database();
    //      d.shutdown();
    //      ^
    // 'd' would be reported as an identifier which is perfect but
    // lead to wrong results as there could be a class 'd.class' for
    // obfuscated librarys
    if ((typeName.length() == 1) && Character.isLowerCase(typeName.charAt(0))) {
      return true;
    }

    String packageName = StringHelper.getPackageName(path);

    // we place this marker in front of every subpackage so we know
    // where a package starts (purely for the searching facility in
    // ImportTransformation.java)
    if (!EMPTY_STRING.equals(packageName)) {
      types.add(packageName + '#');
    }

    types.add(path);

    return true;
  }