/* Copyright (c) 2008-2009, Avian Contributors

   Permission to use, copy, modify, and/or distribute this software
   for any purpose with or without fee is hereby granted, provided
   that the above copyright notice and this permission notice appear
   in all copies.

   There is NO WARRANTY for this software.  See license.txt for
   details. */

package java.lang;

import java.io.InputStream;
import java.io.IOException;
import java.net.URL;

public abstract class ClassLoader {
  private final ClassLoader parent;

  protected ClassLoader(ClassLoader parent) {
    if (parent == null) {
      this.parent = getSystemClassLoader();
    } else {
      this.parent = parent;
    }
  }

  protected ClassLoader() {
    this(getSystemClassLoader());
  }

  public static ClassLoader getSystemClassLoader() {
    return ClassLoader.class.getClassLoader();
  }

  protected Class defineClass(String name, byte[] b, int offset, int length) {
    if (b == null) {
      throw new NullPointerException();
    }

    if (offset < 0 || offset > length || offset + length > b.length) {
      throw new IndexOutOfBoundsException();
    }

    return avian.SystemClassLoader.defineClass(this, b, offset, length);
  }

  protected Class findClass(String name) throws ClassNotFoundException {
    throw new ClassNotFoundException();
  }

  protected abstract Class reallyFindLoadedClass(String name);

  protected final Class findLoadedClass(String name) {
    return reallyFindLoadedClass(name);
  }

  public Class loadClass(String name) throws ClassNotFoundException {
    return loadClass(name, false);
  }

  protected Class loadClass(String name, boolean resolve)
    throws ClassNotFoundException
  {
    Class c = findLoadedClass(name);
    if (c == null) {
      if (parent != null) {
        try {
          c = parent.loadClass(name);
        } catch (ClassNotFoundException ok) { }
      }

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

    if (resolve) {
      resolveClass(c);
    }

    return c;
  }

  protected void resolveClass(Class c) {
    avian.SystemClassLoader.link(c, this);
  }

  private ClassLoader getParent() {
    return parent;
  }
  
  protected URL findResource(String path) {
    return null;
  }

  public URL getResource(String path) {
    URL url = null;
    if (parent != null) {
      url = parent.getResource(path);
    }

    if (url == null) {
      url = findResource(path);
    }

    return url;
  }

  public InputStream getResourceAsStream(String path) {
    URL url = getResource(path);
    try {
      return (url == null ? null : url.openStream());
    } catch (IOException e) {
      return null;
    }
  }

  public static URL getSystemResource(String path) {
    return getSystemClassLoader().getResource(path);
  }

  public static InputStream getSystemResourceAsStream(String path) {
    return getSystemClassLoader().getResourceAsStream(path);
  }
}

@@ -440,16 +440,133 @@
 net.URL;
+%0Aimport java.util.ArrayList;%0Aimport java.util.Collection;%0Aimport java.util.Collections;%0Aimport java.util.Enumeration;
 %0A%0Apublic
@@ -3027,10 +3027,610 @@
 h);%0A  %7D%0A
+  %0A  public static Enumeration%3CURL%3E getSystemResources(String name) throws IOException %7B%0A    return getSystemClassLoader().getResources(name);%0A  %7D%0A  %0A  public Enumeration%3CURL%3E getResources(String name)%0A    throws IOException %7B%0A    Collection%3CURL%3E resources = collectResources(name);%0A    return Collections.enumeration(resources);%0A  %7D%0A%0A  private Collection%3CURL%3E collectResources(String name) %7B%0A    Collection%3CURL%3E urls = parent != null ? parent.collectResources(name) : new ArrayList%3CURL%3E(5);%0A    URL url = findResource(name);%0A    if (url != null) %7B%0A      urls.add(url);%0A    %7D%0A    return urls;%0A  %7D%0A  %0A
 %7D%0A

add ClassLoader.getResources calls