class BlockingClassLoader extends URLClassLoader {

  @Override protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException  {

    if (!m_shared.matches(name, false)) {

      if (m_respectGrandparents) {
        try {
          // We always have a grandparent classloader.
          return Class.forName(name, resolve, getParent().getParent());
        }
        catch (ClassNotFoundException e) {
          // Grandparent knows nothing.
        }
      }

      if (m_blocked.matches(name, false)) {
        throw new ClassNotFoundException();
      }

      if (m_isolated.matches(name, false)) {
        synchronized (this) {
          Class<?> c = findLoadedClass(name);

          if (c == null) {
            c = findClass(name);
          }

          if (resolve) {
            resolveClass(c);
          }

          return c;
        }
      }
    }

    return super.loadClass(name, resolve);
  }

  public  BlockingClassLoader(URLClassLoader parent,
                             List<URL> additionalClassPath,
                             Set<String> blocked,
                             Set<String> isolated,
                             Set<String> shared,
                             boolean respectGrandparents);
  public  BlockingClassLoader(List<URL> additionalClassPath,
                             Set<String> blocked,
                             Set<String> isolated,
                             Set<String> shared,
                             boolean respectGrandparents);
  public  BlockingClassLoader(Set<String> blocked,
                             Set<String> isolated,
                             Set<String> shared,
                             boolean respectGrandparents);

}