/* Class.java -- Representation of a Java class.
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
   Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.lang;

import gnu.classpath.VMStackWalker;
import gnu.java.lang.reflect.ClassSignatureParser;

import java.io.InputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.net.URL;
import java.security.AccessController;
import java.security.AllPermission;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;


/**
 * A Class represents a Java type.  There will never be multiple Class
 * objects with identical names and ClassLoaders. Primitive types, array
 * types, and void also have a Class object.
 *
 * <p>Arrays with identical type and number of dimensions share the same class.
 * The array class ClassLoader is the same as the ClassLoader of the element
 * type of the array (which can be null to indicate the bootstrap classloader).
 * The name of an array class is <code>[&lt;signature format&gt;;</code>.
 * <p> For example,
 * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte,
 * short, char, int, long, float and double have the "type name" of
 * Z,B,S,C,I,J,F,D for the purposes of array classes.  If it's a
 * multidimensioned array, the same principle applies:
 * <code>int[][][]</code> == <code>[[[I</code>.
 *
 * <p>There is no public constructor - Class objects are obtained only through
 * the virtual machine, as defined in ClassLoaders.
 *
 * @serialData Class objects serialize specially:
 * <code>TC_CLASS ClassDescriptor</code>. For more serialization information,
 * see {@link ObjectStreamClass}.
 *
 * @author John Keiser
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Tom Tromey (tromey@redhat.com)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.0
 * @see ClassLoader
 */
public final class Class<T>
  implements Serializable, Type, AnnotatedElement, GenericDeclaration
{
  /**
   * Compatible with JDK 1.0+.
   */
  private static final long serialVersionUID = 3206093459760846163L;

  /**
   * Flag indicating a synthetic member.
   * Note that this duplicates a constant in Modifier.
   */
  private static final int SYNTHETIC = 0x1000;

  /**
   * Flag indiciating an annotation class.
   */
  private static final int ANNOTATION = 0x2000;

  /**
   * Flag indicating an enum constant or an enum class.
   * Note that this duplicates a constant in Modifier.
   */
  private static final int ENUM = 0x4000;

  /** The class signers. */
  private Object[] signers = null;
  /** The class protection domain. */
  private final transient ProtectionDomain pd;

  /* We use an inner class, so that Class doesn't have a static initializer */
  private static final class StaticData
  {
    static final ProtectionDomain unknownProtectionDomain;

    static
    {
      Permissions permissions = new Permissions();
      permissions.add(new AllPermission());
      unknownProtectionDomain = new ProtectionDomain(null, permissions);
    }
  }

  final transient Object vmdata;

  /** newInstance() caches the default constructor */
  private transient Constructor<T> constructor;

  /**
   * Class is non-instantiable from Java code; only the VM can create
   * instances of this class.
   */
  Class(Object vmdata)
  {
    this(vmdata, null);
  }

  Class(Object vmdata, ProtectionDomain pd)
  {
    this.vmdata = vmdata;
    // If the VM didn't supply a protection domain and the class is an array,
    // we "inherit" the protection domain from the component type class. This
    // saves the VM from having to worry about protection domains for array
    // classes.
    if (pd == null && isArray())
      this.pd = getComponentType().pd;
    else
      this.pd = pd;
  }

  /**
   * Use the classloader of the current class to load, link, and initialize
   * a class. This is equivalent to your code calling
   * <code>Class.forName(name, true, getClass().getClassLoader())</code>.
   *
   * @param name the name of the class to find
   * @return the Class object representing the class
   * @throws ClassNotFoundException if the class was not found by the
   *         classloader
   * @throws LinkageError if linking the class fails
   * @throws ExceptionInInitializerError if the class loads, but an exception
   *         occurs during initialization
   */
  public static Class<?> forName(String name) throws ClassNotFoundException
  {
    return VMClass.forName(name, true, VMStackWalker.getCallingClassLoader());
  }

  /**
   * Use the specified classloader to load and link a class. If the loader
   * is null, this uses the bootstrap class loader (provide the security
   * check succeeds). Unfortunately, this method cannot be used to obtain
   * the Class objects for primitive types or for void, you have to use
   * the fields in the appropriate java.lang wrapper classes.
   *
   * <p>Calls <code>classloader.loadclass(name, initialize)</code>.
   *
   * @param name the name of the class to find
   * @param initialize whether or not to initialize the class at this time
   * @param classloader the classloader to use to find the class; null means
   *        to use the bootstrap class loader
   *
   * @return the class object for the given class
   *
   * @throws ClassNotFoundException if the class was not found by the
   *         classloader
   * @throws LinkageError if linking the class fails
   * @throws ExceptionInInitializerError if the class loads, but an exception
   *         occurs during initialization
   * @throws SecurityException if the <code>classloader</code> argument
   *         is <code>null</code> and the caller does not have the
   *         <code>RuntimePermission("getClassLoader")</code> permission
   * @see ClassLoader
   * @since 1.2
   */
  public static Class<?> forName(String name, boolean initialize,
                                 ClassLoader classloader)
    throws ClassNotFoundException
  {
    if (classloader == null)
      {
        // Check if we may access the bootstrap classloader
        SecurityManager sm = SecurityManager.current;
        if (sm != null)
          {
            // Get the calling classloader
            ClassLoader cl = VMStackWalker.getCallingClassLoader();
            if (cl != null)
              sm.checkPermission(new RuntimePermission("getClassLoader"));
          }
      }
    return (Class<?>) VMClass.forName(name, initialize, classloader);
  }

  /**
   * Get all the public member classes and interfaces declared in this
   * class or inherited from superclasses. This returns an array of length
   * 0 if there are no member classes, including for primitive types. A
   * security check may be performed, with
   * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all public member classes in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Class<?>[] getClasses()
  {
    memberAccessCheck(Member.PUBLIC);
    return internalGetClasses();
  }

  /**
   * Like <code>getClasses()</code> but without the security checks.
   */
  private Class<?>[] internalGetClasses()
  {
    ArrayList<Class> list = new ArrayList<Class>();
    list.addAll(Arrays.asList(getDeclaredClasses(true)));
    Class superClass = getSuperclass();
    if (superClass != null)
      list.addAll(Arrays.asList(superClass.internalGetClasses()));
    return list.toArray(new Class<?>[list.size()]);
  }

  /**
   * Get the ClassLoader that loaded this class.  If the class was loaded
   * by the bootstrap classloader, this method will return null.
   * If there is a security manager, and the caller's class loader is not
   * an ancestor of the requested one, a security check of
   * <code>RuntimePermission("getClassLoader")</code>
   * must first succeed. Primitive types and void return null.
   *
   * @return the ClassLoader that loaded this class
   * @throws SecurityException if the security check fails
   * @see ClassLoader
   * @see RuntimePermission
   */
  public ClassLoader getClassLoader()
  {
    if (isPrimitive())
      return null;

    ClassLoader loader = VMClass.getClassLoader(this);
    // Check if we may get the classloader
    SecurityManager sm = SecurityManager.current;
    if (loader != null && sm != null)
      {
        // Get the calling classloader
        ClassLoader cl = VMStackWalker.getCallingClassLoader();
        if (cl != null && !cl.isAncestorOf(loader))
          sm.checkPermission(new RuntimePermission("getClassLoader"));
      }
    return loader;
  }

  /**
   * If this is an array, get the Class representing the type of array.
   * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
   * calling getComponentType on that would give "java.lang.String".  If
   * this is not an array, returns null.
   *
   * @return the array type of this class, or null
   * @see Array
   * @since 1.1
   */
  public Class<?> getComponentType()
  {
    return VMClass.getComponentType (this);
  }

  /**
   * Get a public constructor declared in this class. If the constructor takes
   * no argument, an array of zero elements and null are equivalent for the
   * types argument. A security check may be performed, with
   * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @param types the type of each parameter
   * @return the constructor
   * @throws NoSuchMethodException if the constructor does not exist
   * @throws SecurityException if the security check fails
   * @see #getConstructors()
   * @since 1.1
   */
  public Constructor<T> getConstructor(Class<?>... types)
    throws NoSuchMethodException
  {
    memberAccessCheck(Member.PUBLIC);
    Constructor[] constructors = getDeclaredConstructors(true);
    for (int i = 0; i < constructors.length; i++)
      {
        Constructor constructor = constructors[i];
        if (matchParameters(types, constructor.getParameterTypes()))
          return constructor;
      }
    throw new NoSuchMethodException();
  }

  /**
   * Get all the public constructors of this class. This returns an array of
   * length 0 if there are no constructors, including for primitive types,
   * arrays, and interfaces. It does, however, include the default
   * constructor if one was supplied by the compiler. A security check may
   * be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code>
   * as well as <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all public constructors in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Constructor<?>[] getConstructors()
  {
    memberAccessCheck(Member.PUBLIC);
    return getDeclaredConstructors(true);
  }

  /**
   * Get a constructor declared in this class. If the constructor takes no
   * argument, an array of zero elements and null are equivalent for the
   * types argument. A security check may be performed, with
   * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @param types the type of each parameter
   * @return the constructor
   * @throws NoSuchMethodException if the constructor does not exist
   * @throws SecurityException if the security check fails
   * @see #getDeclaredConstructors()
   * @since 1.1
   */
  public Constructor<T> getDeclaredConstructor(Class<?>... types)
    throws NoSuchMethodException
  {
    memberAccessCheck(Member.DECLARED);
    Constructor[] constructors = getDeclaredConstructors(false);
    for (int i = 0; i < constructors.length; i++)
      {
        Constructor constructor = constructors[i];
        if (matchParameters(types, constructor.getParameterTypes()))
          return constructor;
      }
    throw new NoSuchMethodException();
  }

  /**
   * Get all the declared member classes and interfaces in this class, but
   * not those inherited from superclasses. This returns an array of length
   * 0 if there are no member classes, including for primitive types. A
   * security check may be performed, with
   * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all declared member classes in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Class<?>[] getDeclaredClasses()
  {
    memberAccessCheck(Member.DECLARED);
    return getDeclaredClasses(false);
  }

  Class<?>[] getDeclaredClasses (boolean publicOnly)
  {
    return VMClass.getDeclaredClasses (this, publicOnly);
  }

  /**
   * Get all the declared constructors of this class. This returns an array of
   * length 0 if there are no constructors, including for primitive types,
   * arrays, and interfaces. It does, however, include the default
   * constructor if one was supplied by the compiler. A security check may
   * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code>
   * as well as <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all constructors in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Constructor<?>[] getDeclaredConstructors()
  {
    memberAccessCheck(Member.DECLARED);
    return getDeclaredConstructors(false);
  }

  Constructor<?>[] getDeclaredConstructors (boolean publicOnly)
  {
    return VMClass.getDeclaredConstructors (this, publicOnly);
  }

  /**
   * Get a field declared in this class, where name is its simple name. The
   * implicit length field of arrays is not available. A security check may
   * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code>
   * as well as <code>checkPackageAccess</code> both having to succeed.
   *
   * @param name the name of the field
   * @return the field
   * @throws NoSuchFieldException if the field does not exist
   * @throws SecurityException if the security check fails
   * @throws NullPointerException if <code>fieldName</code> is null
   * @see #getDeclaredFields()
   * @since 1.1
   */
  public Field getDeclaredField(String name) throws NoSuchFieldException
  {
    if (name == null)
      throw new NullPointerException();
    memberAccessCheck(Member.DECLARED);
    Field[] fields = getDeclaredFields(false);
    for (int i = 0; i < fields.length; i++)
      {
        if (fields[i].getName().equals(name))
          return fields[i];
      }
    throw new NoSuchFieldException();
  }

  /**
   * Get all the declared fields in this class, but not those inherited from
   * superclasses. This returns an array of length 0 if there are no fields,
   * including for primitive types. This does not return the implicit length
   * field of arrays. A security check may be performed, with
   * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all declared fields in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Field[] getDeclaredFields()
  {
    memberAccessCheck(Member.DECLARED);
    return getDeclaredFields(false);
  }

  Field[] getDeclaredFields (boolean publicOnly)
  {
    return VMClass.getDeclaredFields (this, publicOnly);
  }

  /**
   * Get a method declared in this class, where name is its simple name. The
   * implicit methods of Object are not available from arrays or interfaces.
   * Constructors (named "&lt;init&gt;" in the class file) and class initializers
   * (name "&lt;clinit&gt;") are not available.  The Virtual Machine allows
   * multiple methods with the same signature but differing return types; in
   * such a case the most specific return types are favored, then the final
   * choice is arbitrary. If the method takes no argument, an array of zero
   * elements and null are equivalent for the types argument. A security
   * check may be performed, with
   * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @param methodName the name of the method
   * @param types the type of each parameter
   * @return the method
   * @throws NoSuchMethodException if the method does not exist
   * @throws SecurityException if the security check fails
   * @throws NullPointerException if <code>methodName</code> is null
   * @see #getDeclaredMethods()
   * @since 1.1
   */
  public Method getDeclaredMethod(String methodName, Class<?>... types)
    throws NoSuchMethodException
  {
    if (methodName == null)
      throw new NullPointerException();
    memberAccessCheck(Member.DECLARED);
    Method match = matchMethod(getDeclaredMethods(false), methodName, types);
    if (match == null)
      throw new NoSuchMethodException(methodName);
    return match;
  }

  /**
   * Get all the declared methods in this class, but not those inherited from
   * superclasses. This returns an array of length 0 if there are no methods,
   * including for primitive types. This does include the implicit methods of
   * arrays and interfaces which mirror methods of Object, nor does it
   * include constructors or the class initialization methods. The Virtual
   * Machine allows multiple methods with the same signature but differing
   * return types; all such methods are in the returned array. A security
   * check may be performed, with
   * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all declared methods in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Method[] getDeclaredMethods()
  {
    memberAccessCheck(Member.DECLARED);
    return getDeclaredMethods(false);
  }

  Method[] getDeclaredMethods (boolean publicOnly)
  {
    return VMClass.getDeclaredMethods (this, publicOnly);
  }

  /**
   * If this is a nested or inner class, return the class that declared it.
   * If not, return null.
   *
   * @return the declaring class of this class
   * @since 1.1
   */
  public Class<?> getDeclaringClass()
  {
    return VMClass.getDeclaringClass (this);
  }

  /**
   * Get a public field declared or inherited in this class, where name is
   * its simple name. If the class contains multiple accessible fields by
   * that name, an arbitrary one is returned. The implicit length field of
   * arrays is not available. A security check may be performed, with
   * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @param fieldName the name of the field
   * @return the field
   * @throws NoSuchFieldException if the field does not exist
   * @throws SecurityException if the security check fails
   * @throws NullPointerException if <code>fieldName</code> is null
   * @see #getFields()
   * @since 1.1
   */
  public Field getField(String fieldName)
    throws NoSuchFieldException
  {
    if (fieldName == null)
      throw new NullPointerException();
    memberAccessCheck(Member.PUBLIC);
    Field field = internalGetField(fieldName);
    if (field == null)
      throw new NoSuchFieldException(fieldName);
    return field;
  }

  /**
   * Get all the public fields declared in this class or inherited from
   * superclasses. This returns an array of length 0 if there are no fields,
   * including for primitive types. This does not return the implicit length
   * field of arrays. A security check may be performed, with
   * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all public fields in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Field[] getFields()
  {
    memberAccessCheck(Member.PUBLIC);
    return internalGetFields();
  }

  /**
   * Like <code>getFields()</code> but without the security checks.
   */
  private Field[] internalGetFields()
  {
    LinkedHashSet<Field> set = new LinkedHashSet<Field>();
    set.addAll(Arrays.asList(getDeclaredFields(true)));
    Class[] interfaces = getInterfaces();
    for (int i = 0; i < interfaces.length; i++)
      set.addAll(Arrays.asList(interfaces[i].internalGetFields()));
    Class superClass = getSuperclass();
    if (superClass != null)
      set.addAll(Arrays.asList(superClass.internalGetFields()));
    return set.toArray(new Field[set.size()]);
  }

  /**
   * Returns the <code>Package</code> in which this class is defined
   * Returns null when this information is not available from the
   * classloader of this class.
   *
   * @return the package for this class, if it is available
   * @since 1.2
   */
  public Package getPackage()
  {
    ClassLoader cl = getClassLoader();
    if (cl != null)
      return cl.getPackage(getPackagePortion(getName()));
    else
      return VMClassLoader.getPackage(getPackagePortion(getName()));
  }

  /**
   * Get the interfaces this class <em>directly</em> implements, in the
   * order that they were declared. This returns an empty array, not null,
   * for Object, primitives, void, and classes or interfaces with no direct
   * superinterface. Array types return Cloneable and Serializable.
   *
   * @return the interfaces this class directly implements
   */
  public Class<?>[] getInterfaces()
  {
    return VMClass.getInterfaces (this);
  }

  private static final class MethodKey
  {
    private String name;
    private Class[] params;
    private Class returnType;
    private int hash;

    MethodKey(Method m)
    {
      name = m.getName();
      params = m.getParameterTypes();
      returnType = m.getReturnType();
      hash = name.hashCode() ^ returnType.hashCode();
      for(int i = 0; i < params.length; i++)
        {
          hash ^= params[i].hashCode();
        }
    }

    public boolean equals(Object o)
    {
      if (o instanceof MethodKey)
        {
          MethodKey m = (MethodKey) o;
          if (m.name.equals(name) && m.params.length == params.length
              && m.returnType == returnType)
            {
              for (int i = 0; i < params.length; i++)
                {
                  if (m.params[i] != params[i])
                    return false;
                }
              return true;
            }
        }
      return false;
    }

    public int hashCode()
    {
      return hash;
    }
  }

  /**
   * Get a public method declared or inherited in this class, where name is
   * its simple name. The implicit methods of Object are not available from
   * interfaces.  Constructors (named "&lt;init&gt;" in the class file) and class
   * initializers (name "&lt;clinit&gt;") are not available.  The Virtual
   * Machine allows multiple methods with the same signature but differing
   * return types, and the class can inherit multiple methods of the same
   * return type; in such a case the most specific return types are favored,
   * then the final choice is arbitrary. If the method takes no argument, an
   * array of zero elements and null are equivalent for the types argument.
   * A security check may be performed, with
   * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @param methodName the name of the method
   * @param types the type of each parameter
   * @return the method
   * @throws NoSuchMethodException if the method does not exist
   * @throws SecurityException if the security check fails
   * @throws NullPointerException if <code>methodName</code> is null
   * @see #getMethods()
   * @since 1.1
   */
  public Method getMethod(String methodName, Class<?>... types)
    throws NoSuchMethodException
  {
    if (methodName == null)
      throw new NullPointerException();
    memberAccessCheck(Member.PUBLIC);
    Method method = internalGetMethod(methodName, types);
    if (method == null)
      throw new NoSuchMethodException(methodName);
    return method;
  }

  /**
   * Like <code>getMethod(String,Class[])</code> but without the security
   * checks and returns null instead of throwing NoSuchMethodException.
   */
  private Method internalGetMethod(String methodName, Class[] args)
  {
    Method match = matchMethod(getDeclaredMethods(true), methodName, args);
    if (match != null)
      return match;
    Class superClass = getSuperclass();
    if (superClass != null)
      {
        match = superClass.internalGetMethod(methodName, args);
        if(match != null)
          return match;
      }
    Class[] interfaces = getInterfaces();
    for (int i = 0; i < interfaces.length; i++)
      {
        match = interfaces[i].internalGetMethod(methodName, args);
        if (match != null)
          return match;
      }
    return null;
  }

  /**
   * Find the best matching method in <code>list</code> according to
   * the definition of ``best matching'' used by <code>getMethod()</code>
   *
   * <p>
   * Returns the method if any, otherwise <code>null</code>.
   *
   * @param list List of methods to search
   * @param name Name of method
   * @param args Method parameter types
   * @see #getMethod(String, Class[])
   */
  private static Method matchMethod(Method[] list, String name, Class[] args)
  {
    Method match = null;
    for (int i = 0; i < list.length; i++)
      {
        Method method = list[i];
        if (!method.getName().equals(name))
          continue;
        if (!matchParameters(args, method.getParameterTypes()))
          continue;
        if (match == null
            || match.getReturnType().isAssignableFrom(method.getReturnType()))
          match = method;
      }
    return match;
  }

  /**
   * Check for an exact match between parameter type lists.
   * Either list may be <code>null</code> to mean a list of
   * length zero.
   */
  private static boolean matchParameters(Class[] types1, Class[] types2)
  {
    if (types1 == null)
      return types2 == null || types2.length == 0;
    if (types2 == null)
      return types1 == null || types1.length == 0;
    if (types1.length != types2.length)
      return false;
    for (int i = 0; i < types1.length; i++)
      {
        if (types1[i] != types2[i])
          return false;
      }
    return true;
  }

  /**
   * Get all the public methods declared in this class or inherited from
   * superclasses. This returns an array of length 0 if there are no methods,
   * including for primitive types. This does not include the implicit
   * methods of interfaces which mirror methods of Object, nor does it
   * include constructors or the class initialization methods. The Virtual
   * Machine allows multiple methods with the same signature but differing
   * return types; all such methods are in the returned array. A security
   * check may be performed, with
   * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
   * <code>checkPackageAccess</code> both having to succeed.
   *
   * @return all public methods in this class
   * @throws SecurityException if the security check fails
   * @since 1.1
   */
  public Method[] getMethods()
  {
    memberAccessCheck(Member.PUBLIC);
    // NOTE the API docs claim that no methods are returned for arrays,
    // but Sun's implementation *does* return the public methods of Object
    // (as would be expected), so we follow their implementation instead
    // of their documentation.
    return internalGetMethods();
  }

  /**
   * Like <code>getMethods()</code> but without the security checks.
   */
  private Method[] internalGetMethods()
  {
    HashMap<MethodKey,Method> map = new HashMap<MethodKey,Method>();
    Method[] methods;
    Class[] interfaces = getInterfaces();
    for(int i = 0; i < interfaces.length; i++)
      {
        methods = interfaces[i].internalGetMethods();
        for(int j = 0; j < methods.length; j++)
          {
            map.put(new MethodKey(methods[j]), methods[j]);
          }
      }
    Class superClass = getSuperclass();
    if(superClass != null)
      {
        methods = superClass.internalGetMethods();
        for(int i = 0; i < methods.length; i++)
          {
            map.put(new MethodKey(methods[i]), methods[i]);
          }
      }
    methods = getDeclaredMethods(true);
    for(int i = 0; i < methods.length; i++)
      {
        map.put(new MethodKey(methods[i]), methods[i]);
      }
    return map.values().toArray(new Method[map.size()]);
  }

  /**
   * Get the modifiers of this class.  These can be decoded using Modifier,
   * and is limited to one of public, protected, or private, and any of
   * final, static, abstract, or interface. An array class has the same
   * public, protected, or private modifier as its component type, and is
   * marked final but not an interface. Primitive types and void are marked
   * public and final, but not an interface.
   *
   * @return the modifiers of this class
   * @see Modifier
   * @since 1.1
   */
  public int getModifiers()
  {
    int mod = VMClass.getModifiers (this, false);
    return (mod & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
          Modifier.FINAL | Modifier.STATIC | Modifier.ABSTRACT |
          Modifier.INTERFACE));
  }

  /**
   * Get the name of this class, separated by dots for package separators.
   * If the class represents a primitive type, or void, then the
   * name of the type as it appears in the Java programming language
   * is returned.  For instance, <code>Byte.TYPE.getName()</code>
   * returns "byte".
   *
   * Arrays are specially encoded as shown on this table.
   * <pre>
   * array type          [<em>element type</em>
   *                     (note that the element type is encoded per
   *                      this table)
   * boolean             Z
   * byte                B
   * char                C
   * short               S
   * int                 I
   * long                J
   * float               F
   * double              D
   * void                V
   * class or interface, alone: &lt;dotted name&gt;
   * class or interface, as element type: L&lt;dotted name&gt;;
   * </pre>
   *
   * @return the name of this class
   */
  public String getName()
  {
    return VMClass.getName (this);
  }

  /**
   * Get a resource URL using this class's package using the
   * getClassLoader().getResource() method.  If this class was loaded using
   * the system classloader, ClassLoader.getSystemResource() is used instead.
   *
   * <p>If the name you supply is absolute (it starts with a <code>/</code>),
   * then the leading <code>/</code> is removed and it is passed on to
   * getResource(). If it is relative, the package name is prepended, and
   * <code>.</code>'s are replaced with <code>/</code>.
   *
   * <p>The URL returned is system- and classloader-dependent, and could
   * change across implementations.
   *
   * @param resourceName the name of the resource, generally a path
   * @return the URL to the resource
   * @throws NullPointerException if name is null
   * @since 1.1
   */
  public URL getResource(String resourceName)
  {
    String name = resourcePath(resourceName);
    ClassLoader loader = getClassLoader();
    if (loader == null)
      return ClassLoader.getSystemResource(name);
    return loader.getResource(name);
  }

  /**
   * Get a resource using this class's package using the
   * getClassLoader().getResourceAsStream() method.  If this class was loaded
   * using the system classloader, ClassLoader.getSystemResource() is used
   * instead.
   *
   * <p>If the name you supply is absolute (it starts with a <code>/</code>),
   * then the leading <code>/</code> is removed and it is passed on to
   * getResource(). If it is relative, the package name is prepended, and
   * <code>.</code>'s are replaced with <code>/</code>.
   *
   * <p>The URL returned is system- and classloader-dependent, and could
   * change across implementations.
   *
   * @param resourceName the name of the resource, generally a path
   * @return an InputStream with the contents of the resource in it, or null
   * @throws NullPointerException if name is null
   * @since 1.1
   */
  public InputStream getResourceAsStream(String resourceName)
  {
    String name = resourcePath(resourceName);
    ClassLoader loader = getClassLoader();
    if (loader == null)
      return ClassLoader.getSystemResourceAsStream(name);
    return loader.getResourceAsStream(name);
  }

  private String resourcePath(String resourceName)
  {
    if (resourceName.length() > 0)
      {
        if (resourceName.charAt(0) != '/')
          {
            String pkg = getPackagePortion(getName());
            if (pkg.length() > 0)
              resourceName = pkg.replace('.','/') + '/' + resourceName;
          }
        else
          {
            resourceName = resourceName.substring(1);
          }
      }
    return resourceName;
  }

  /**
   * Get the signers of this class. This returns null if there are no signers,
   * such as for primitive types or void.
   *
   * @return the signers of this class
   * @since 1.1
   */
  public Object[] getSigners()
  {
    return signers == null ? null : (Object[]) signers.clone ();
  }

  /**
   * Set the signers of this class.
   *
   * @param signers the signers of this class
   */
  void setSigners(Object[] signers)
  {
    this.signers = signers;
  }

  /**
   * Get the direct superclass of this class.  If this is an interface,
   * Object, a primitive type, or void, it will return null. If this is an
   * array type, it will return Object.
   *
   * @return the direct superclass of this class
   */
  public Class<? super T> getSuperclass()
  {
    return VMClass.getSuperclass (this);
  }

  /**
   * Return whether this class is an array type.
   *
   * @return whether this class is an array type
   * @since 1.1
   */
  public boolean isArray()
  {
    return VMClass.isArray (this);
  }

  /**
   * Discover whether an instance of the Class parameter would be an
   * instance of this Class as well.  Think of doing
   * <code>isInstance(c.newInstance())</code> or even
   * <code>c.newInstance() instanceof (this class)</code>. While this
   * checks widening conversions for objects, it must be exact for primitive
   * types.
   *
   * @param c the class to check
   * @return whether an instance of c would be an instance of this class
   *         as well
   * @throws NullPointerException if c is null
   * @since 1.1
   */
  public boolean isAssignableFrom(Class<?> c)
  {
    return VMClass.isAssignableFrom (this, c);
  }

  /**
   * Discover whether an Object is an instance of this Class.  Think of it
   * as almost like <code>o instanceof (this class)</code>.
   *
   * @param o the Object to check
   * @return whether o is an instance of this class
   * @since 1.1
   */
  public boolean isInstance(Object o)
  {
    return VMClass.isInstance (this, o);
  }

  /**
   * Check whether this class is an interface or not.  Array types are not
   * interfaces.
   *
   * @return whether this class is an interface or not
   */
  public boolean isInterface()
  {
    return VMClass.isInterface (this);
  }

  /**
   * Return whether this class is a primitive type.  A primitive type class
   * is a class representing a kind of "placeholder" for the various
   * primitive types, or void.  You can access the various primitive type
   * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
   * or through boolean.class, int.class, etc.
   *
   * @return whether this class is a primitive type
   * @see Boolean#TYPE
   * @see Byte#TYPE
   * @see Character#TYPE
   * @see Short#TYPE
   * @see Integer#TYPE
   * @see Long#TYPE
   * @see Float#TYPE
   * @see Double#TYPE
   * @see Void#TYPE
   * @since 1.1
   */
  public boolean isPrimitive()
  {
    return VMClass.isPrimitive (this);
  }

  /**
   * Get a new instance of this class by calling the no-argument constructor.
   * The class is initialized if it has not been already. A security check
   * may be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code>
   * as well as <code>checkPackageAccess</code> both having to succeed.
   *
   * @return a new instance of this class
   * @throws InstantiationException if there is not a no-arg constructor
   *         for this class, including interfaces, abstract classes, arrays,
   *         primitive types, and void; or if an exception occurred during
   *         the constructor
   * @throws IllegalAccessException if you are not allowed to access the
   *         no-arg constructor because of scoping reasons
   * @throws SecurityException if the security check fails
   * @throws ExceptionInInitializerError if class initialization caused by
   *         this call fails with an exception
   */
  public T newInstance()
    throws InstantiationException, IllegalAccessException
  {
    memberAccessCheck(Member.PUBLIC);
    Constructor<T> constructor;
    synchronized(this)
      {
        constructor = this.constructor;
      }
    if (constructor == null)
      {
        Constructor[] constructors = getDeclaredConstructors(false);
        for (int i = 0; i < constructors.length; i++)
          {
            if (constructors[i].getParameterTypes().length == 0)
              {
                constructor = constructors[i];
                break;
              }
          }
        if (constructor == null)
          throw new InstantiationException(getName());
        if (!Modifier.isPublic(constructor.getModifiers())
            || !Modifier.isPublic(VMClass.getModifiers(this, true)))
          {
            setAccessible(constructor);
          }
        synchronized(this)
          {
            if (this.constructor == null)
              this.constructor = constructor;
          }
      }
    int modifiers = constructor.getModifiers();
    if (!Modifier.isPublic(modifiers)
        || !Modifier.isPublic(VMClass.getModifiers(this, true)))
      {
        Class caller = VMStackWalker.getCallingClass();
        if (caller != null &&
            caller != this &&
            (Modifier.isPrivate(modifiers)
             || getClassLoader() != caller.getClassLoader()
             || !getPackagePortion(getName())
             .equals(getPackagePortion(caller.getName()))))
          throw new IllegalAccessException(getName()
                                           + " has an inaccessible constructor");
      }
    try
      {
        return constructor.newInstance();
      }
    catch (InvocationTargetException e)
      {
        VMClass.throwException(e.getTargetException());
        throw (InternalError) new InternalError
          ("VMClass.throwException returned").initCause(e);
      }
  }

  /**
   * Returns the protection domain of this class. If the classloader did not
   * record the protection domain when creating this class the unknown
   * protection domain is returned which has a <code>null</code> code source
   * and all permissions. A security check may be performed, with
   * <code>RuntimePermission("getProtectionDomain")</code>.
   *
   * @return the protection domain
   * @throws SecurityException if the security manager exists and the caller
   * does not have <code>RuntimePermission("getProtectionDomain")</code>.
   * @see RuntimePermission
   * @since 1.2
   */
  public ProtectionDomain getProtectionDomain()
  {
    SecurityManager sm = SecurityManager.current;
    if (sm != null)
      sm.checkPermission(new RuntimePermission("getProtectionDomain"));

    return pd == null ? StaticData.unknownProtectionDomain : pd;
  }

  /**
   * Return the human-readable form of this Object.  For an object, this
   * is either "interface " or "class " followed by <code>getName()</code>,
   * for primitive types and void it is just <code>getName()</code>.
   *
   * @return the human-readable form of this Object
   */
  public String toString()
  {
    if (isPrimitive())
      return getName();
    return (isInterface() ? "interface " : "class ") + getName();
  }

  /**
   * Returns the desired assertion status of this class, if it were to be
   * initialized at this moment. The class assertion status, if set, is
   * returned; the backup is the default package status; then if there is
   * a class loader, that default is returned; and finally the system default
   * is returned. This method seldom needs calling in user code, but exists
   * for compilers to implement the assert statement. Note that there is no
   * guarantee that the result of this method matches the class's actual
   * assertion status.
   *
   * @return the desired assertion status
   * @see ClassLoader#setClassAssertionStatus(String, boolean)
   * @see ClassLoader#setPackageAssertionStatus(String, boolean)
   * @see ClassLoader#setDefaultAssertionStatus(boolean)
   * @since 1.4
   */
  public boolean desiredAssertionStatus()
  {
    ClassLoader c = getClassLoader();
    Object status;
    if (c == null)
      return VMClassLoader.defaultAssertionStatus();
    if (c.classAssertionStatus != null)
      synchronized (c)
        {
          status = c.classAssertionStatus.get(getName());
          if (status != null)
            return status.equals(Boolean.TRUE);
        }
    else
      {
        status = ClassLoader.StaticData.
                    systemClassAssertionStatus.get(getName());
        if (status != null)
          return status.equals(Boolean.TRUE);
      }
    if (c.packageAssertionStatus != null)
      synchronized (c)
        {
          String name = getPackagePortion(getName());
          if ("".equals(name))
            status = c.packageAssertionStatus.get(null);
          else
            do
              {
                status = c.packageAssertionStatus.get(name);
                name = getPackagePortion(name);
              }
            while (! "".equals(name) && status == null);
          if (status != null)
            return status.equals(Boolean.TRUE);
        }
    else
      {
        String name = getPackagePortion(getName());
        if ("".equals(name))
          status = ClassLoader.StaticData.
                    systemPackageAssertionStatus.get(null);
        else
          do
            {
              status = ClassLoader.StaticData.
                        systemPackageAssertionStatus.get(name);
              name = getPackagePortion(name);
            }
          while (! "".equals(name) && status == null);
        if (status != null)
          return status.equals(Boolean.TRUE);
      }
    return c.defaultAssertionStatus;
  }

  /**
   * <p>
   * Casts this class to represent a subclass of the specified class.
   * This method is useful for `narrowing' the type of a class so that
   * the class object, and instances of that class, can match the contract
   * of a more restrictive method.  For example, if this class has the
   * static type of <code>Class&lt;Object&gt;</code>, and a dynamic type of
   * <code>Class&lt;Rectangle&gt;</code>, then, assuming <code>Shape</code> is
   * a superclass of <code>Rectangle</code>, this method can be used on
   * this class with the parameter, <code>Class&lt;Shape&gt;</code>, to retain
   * the same instance but with the type
   * <code>Class&lt;? extends Shape&gt;</code>.
   * </p>
   * <p>
   * If this class can be converted to an instance which is parameterised
   * over a subtype of the supplied type, <code>U</code>, then this method
   * returns an appropriately cast reference to this object.  Otherwise,
   * a <code>ClassCastException</code> is thrown.
   * </p>
   *
   * @param klass the class object, the parameterized type (<code>U</code>) of
   *              which should be a superclass of the parameterized type of
   *              this instance.
   * @return a reference to this object, appropriately cast.
   * @throws ClassCastException if this class can not be converted to one
   *                            which represents a subclass of the specified
   *                            type, <code>U</code>.
   * @since 1.5
   */
  public <U> Class<? extends U> asSubclass(Class<U> klass)
  {
    if (! klass.isAssignableFrom(this))
      throw new ClassCastException();
    return (Class<? extends U>) this;
  }

  /**
   * Returns the specified object, cast to this <code>Class</code>' type.
   *
   * @param obj the object to cast
   * @throws ClassCastException  if obj is not an instance of this class
   * @since 1.5
   */
  public T cast(Object obj)
  {
    if (obj != null && ! isInstance(obj))
      throw new ClassCastException();
    return (T) obj;
  }

  /**
   * Like <code>getField(String)</code> but without the security checks and
   * returns null instead of throwing NoSuchFieldException.
   */
  private Field internalGetField(String name)
  {
    Field[] fields = getDeclaredFields(true);
    for (int i = 0; i < fields.length; i++)
      {
        Field field = fields[i];
        if (field.getName().equals(name))
          return field;
      }
    Class[] interfaces = getInterfaces();
    for (int i = 0; i < interfaces.length; i++)
      {
        Field field = interfaces[i].internalGetField(name);
        if(field != null)
          return field;
      }
    Class superClass = getSuperclass();
    if (superClass != null)
      return superClass.internalGetField(name);
    return null;
  }

  /**
   * Strip the last portion of the name (after the last dot).
   *
   * @param name the name to get package of
   * @return the package name, or "" if no package
   */
  private static String getPackagePortion(String name)
  {
    int lastInd = name.lastIndexOf('.');
    if (lastInd == -1)
      return "";
    return name.substring(0, lastInd);
  }

  /**
   * Perform security checks common to all of the methods that
   * get members of this Class.
   */
  private void memberAccessCheck(int which)
  {
    SecurityManager sm = SecurityManager.current;
    if (sm != null)
      {
        sm.checkMemberAccess(this, which);
        Package pkg = getPackage();
        if (pkg != null)
          sm.checkPackageAccess(pkg.getName());
      }
  }

  /**
   * Returns the enumeration constants of this class, or
   * null if this class is not an <code>Enum</code>.
   *
   * @return an array of <code>Enum</code> constants
   *         associated with this class, or null if this
   *         class is not an <code>enum</code>.
   * @since 1.5
   */
  public T[] getEnumConstants()
  {
    if (isEnum())
      {
        try
          {
            Method m = getMethod("values");
            setAccessible(m);
            return (T[]) m.invoke(null);
          }
        catch (NoSuchMethodException exception)
          {
            throw new Error("Enum lacks values() method");
          }
        catch (IllegalAccessException exception)
          {
            throw new Error("Unable to access Enum class");
          }
        catch (InvocationTargetException exception)
          {
            throw new
              RuntimeException("The values method threw an exception",
                               exception);
          }
      }
    else
      {
        return null;
      }
  }

  /**
   * Returns true if this class is an <code>Enum</code>.
   *
   * @return true if this is an enumeration class.
   * @since 1.5
   */
  public boolean isEnum()
  {
    int mod = VMClass.getModifiers (this, true);
    return (mod & ENUM) != 0;
  }

  /**
   * Returns true if this class is a synthetic class, generated by
   * the compiler.
   *
   * @return true if this is a synthetic class.
   * @since 1.5
   */
  public boolean isSynthetic()
  {
    int mod = VMClass.getModifiers (this, true);
    return (mod & SYNTHETIC) != 0;
  }

  /**
   * Returns true if this class is an <code>Annotation</code>.
   *
   * @return true if this is an annotation class.
   * @since 1.5
   */
  public boolean isAnnotation()
  {
    int mod = VMClass.getModifiers (this, true);
    return (mod & ANNOTATION) != 0;
  }

  /**
   * Returns the simple name for this class, as used in the source
   * code.  For normal classes, this is the content returned by
   * <code>getName()</code> which follows the last ".".  Anonymous
   * classes have no name, and so the result of calling this method is
   * "".  The simple name of an array consists of the simple name of
   * its component type, followed by "[]".  Thus, an array with the
   * component type of an anonymous class has a simple name of simply
   * "[]".
   *
   * @return the simple name for this class.
   * @since 1.5
   */
  public String getSimpleName()
  {
    return VMClass.getSimpleName(this);
  }

  /**
   * Returns this class' annotation for the specified annotation type,
   * or <code>null</code> if no such annotation exists.
   *
   * @param annotationClass the type of annotation to look for.
   * @return this class' annotation for the specified type, or
   *         <code>null</code> if no such annotation exists.
   * @since 1.5
   */
  public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
  {
    A foundAnnotation = null;
    Annotation[] annotations = getAnnotations();
    for (Annotation annotation : annotations)
      if (annotation.annotationType() == annotationClass)
        foundAnnotation = (A) annotation;
    return foundAnnotation;
  }

  /**
   * Returns all annotations associated with this class.  If there are
   * no annotations associated with this class, then a zero-length array
   * will be returned.  The returned array may be modified by the client
   * code, but this will have no effect on the annotation content of this
   * class, and hence no effect on the return value of this method for
   * future callers.
   *
   * @return this class' annotations.
   * @since 1.5
   */
  public Annotation[] getAnnotations()
  {
    HashMap<Class, Annotation> map = new HashMap<Class, Annotation>();
    for (Annotation a : getDeclaredAnnotations())
      map.put((Class) a.annotationType(), a);
    for (Class<? super T> s = getSuperclass();
         s != null;
         s = s.getSuperclass())
      {
        for (Annotation a : s.getDeclaredAnnotations())
          {
            Class k = (Class) a.annotationType();
            if (! map.containsKey(k) && k.isAnnotationPresent(Inherited.class))
              map.put(k, a);
          }
      }
    Collection<Annotation> v = map.values();
    return v.toArray(new Annotation[v.size()]);
  }

  /**
   * <p>
   * Returns the canonical name of this class, as defined by section
   * 6.7 of the Java language specification.  Each package, top-level class,
   * top-level interface and primitive type has a canonical name.  A member
   * class has a canonical name, if its parent class has one.  Likewise,
   * an array type has a canonical name, if its component type does.
   * Local or anonymous classes do not have canonical names.
   * </p>
   * <p>
   * The canonical name for top-level classes, top-level interfaces and
   * primitive types is always the same as the fully-qualified name.
   * For array types, the canonical name is the canonical name of its
   * component type with `[]' appended.
   * </p>
   * <p>
   * The canonical name of a member class always refers to the place where
   * the class was defined, and is composed of the canonical name of the
   * defining class and the simple name of the member class, joined by `.'.
   *  For example, if a <code>Person</code> class has an inner class,
   * <code>M</code>, then both its fully-qualified name and canonical name
   * is <code>Person.M</code>.  A subclass, <code>Staff</code>, of
   * <code>Person</code> refers to the same inner class by the fully-qualified
   * name of <code>Staff.M</code>, but its canonical name is still
   * <code>Person.M</code>.
   * </p>
   * <p>
   * Where no canonical name is present, <code>null</code> is returned.
   * </p>
   *
   * @return the canonical name of the class, or <code>null</code> if the
   *         class doesn't have a canonical name.
   * @since 1.5
   */
  public String getCanonicalName()
  {
    return VMClass.getCanonicalName(this);
  }

  /**
   * Returns all annotations directly defined by this class.  If there are
   * no annotations associated with this class, then a zero-length array
   * will be returned.  The returned array may be modified by the client
   * code, but this will have no effect on the annotation content of this
   * class, and hence no effect on the return value of this method for
   * future callers.
   *
   * @return the annotations directly defined by this class.
   * @since 1.5
   */
  public Annotation[] getDeclaredAnnotations()
  {
    return VMClass.getDeclaredAnnotations(this);
  }

  /**
   * Returns the class which immediately encloses this class.  If this class
   * is a top-level class, this method returns <code>null</code>.
   *
   * @return the immediate enclosing class, or <code>null</code> if this is
   *         a top-level class.
   * @since 1.5
   */
  public Class<?> getEnclosingClass()
  {
    return VMClass.getEnclosingClass(this);
  }

  /**
   * Returns the constructor which immediately encloses this class.  If
   * this class is a top-level class, or a local or anonymous class
   * immediately enclosed by a type definition, instance initializer
   * or static initializer, then <code>null</code> is returned.
   *
   * @return the immediate enclosing constructor if this class is
   *         declared within a constructor.  Otherwise, <code>null</code>
   *         is returned.
   * @since 1.5
   */
  public Constructor<?> getEnclosingConstructor()
  {
    return VMClass.getEnclosingConstructor(this);
  }

  /**
   * Returns the method which immediately encloses this class.  If
   * this class is a top-level class, or a local or anonymous class
   * immediately enclosed by a type definition, instance initializer
   * or static initializer, then <code>null</code> is returned.
   *
   * @return the immediate enclosing method if this class is
   *         declared within a method.  Otherwise, <code>null</code>
   *         is returned.
   * @since 1.5
   */
  public Method getEnclosingMethod()
  {
    return VMClass.getEnclosingMethod(this);
  }

  /**
   * <p>
   * Returns an array of <code>Type</code> objects which represent the
   * interfaces directly implemented by this class or extended by this
   * interface.
   * </p>
   * <p>
   * If one of the superinterfaces is a parameterized type, then the
   * object returned for this interface reflects the actual type
   * parameters used in the source code.  Type parameters are created
   * using the semantics specified by the <code>ParameterizedType</code>
   * interface, and only if an instance has not already been created.
   * </p>
   * <p>
   * The order of the interfaces in the array matches the order in which
   * the interfaces are declared.  For classes which represent an array,
   * an array of two interfaces, <code>Cloneable</code> and
   * <code>Serializable</code>, is always returned, with the objects in
   * that order.  A class representing a primitive type or void always
   * returns an array of zero size.
   * </p>
   *
   * @return an array of interfaces implemented or extended by this class.
   * @throws GenericSignatureFormatError if the generic signature of one
   *         of the interfaces does not comply with that specified by the Java
   *         Virtual Machine specification, 3rd edition.
   * @throws TypeNotPresentException if any of the superinterfaces refers
   *         to a non-existant type.
   * @throws MalformedParameterizedTypeException if any of the interfaces
   *         refer to a parameterized type that can not be instantiated for
   *         some reason.
   * @since 1.5
   * @see java.lang.reflect.ParameterizedType
   */
  public Type[] getGenericInterfaces()
  {
    if (isPrimitive())
      return new Type[0];

    String sig = VMClass.getClassSignature(this);
    if (sig == null)
      return getInterfaces();

    ClassSignatureParser p = new ClassSignatureParser(this, sig);
    return p.getInterfaceTypes();
  }

  /**
   * <p>
   * Returns a <code>Type</code> object representing the direct superclass,
   * whether class, interface, primitive type or void, of this class.
   * If this class is an array class, then a class instance representing
   * the <code>Object</code> class is returned.  If this class is primitive,
   * an interface, or a representation of either the <code>Object</code>
   * class or void, then <code>null</code> is returned.
   * </p>
   * <p>
   * If the superclass is a parameterized type, then the
   * object returned for this interface reflects the actual type
   * parameters used in the source code.  Type parameters are created
   * using the semantics specified by the <code>ParameterizedType</code>
   * interface, and only if an instance has not already been created.
   * </p>
   *
   * @return the superclass of this class.
   * @throws GenericSignatureFormatError if the generic signature of the
   *         class does not comply with that specified by the Java
   *         Virtual Machine specification, 3rd edition.
   * @throws TypeNotPresentException if the superclass refers
   *         to a non-existant type.
   * @throws MalformedParameterizedTypeException if the superclass
   *         refers to a parameterized type that can not be instantiated for
   *         some reason.
   * @since 1.5
   * @see java.lang.reflect.ParameterizedType
   */
  public Type getGenericSuperclass()
  {
    if (isArray())
      return Object.class;

    if (isPrimitive() || isInterface() || this == Object.class)
      return null;

    String sig = VMClass.getClassSignature(this);
    if (sig == null)
      return getSuperclass();

    ClassSignatureParser p = new ClassSignatureParser(this, sig);
    return p.getSuperclassType();
  }

  /**
   * Returns an array of <code>TypeVariable</code> objects that represents
   * the type variables declared by this class, in declaration order.
   * An array of size zero is returned if this class has no type
   * variables.
   *
   * @return the type variables associated with this class.
   * @throws GenericSignatureFormatError if the generic signature does
   *         not conform to the format specified in the Virtual Machine
   *         specification, version 3.
   * @since 1.5
   */
  public TypeVariable<Class<T>>[] getTypeParameters()
  {
    String sig = VMClass.getClassSignature(this);
    if (sig == null)
      return (TypeVariable<Class<T>>[])new TypeVariable[0];

    ClassSignatureParser p = new ClassSignatureParser(this, sig);
    return p.getTypeParameters();
  }

  /**
   * Returns true if an annotation for the specified type is associated
   * with this class.  This is primarily a short-hand for using marker
   * annotations.
   *
   * @param annotationClass the type of annotation to look for.
   * @return true if an annotation exists for the specified type.
   * @since 1.5
   */
  public boolean isAnnotationPresent(Class<? extends Annotation>
                                     annotationClass)
  {
    return getAnnotation(annotationClass) != null;
  }

  /**
   * Returns true if this object represents an anonymous class.
   *
   * @return true if this object represents an anonymous class.
   * @since 1.5
   */
  public boolean isAnonymousClass()
  {
    return VMClass.isAnonymousClass(this);
  }

  /**
   * Returns true if this object represents an local class.
   *
   * @return true if this object represents an local class.
   * @since 1.5
   */
  public boolean isLocalClass()
  {
    return VMClass.isLocalClass(this);
  }

  /**
   * Returns true if this object represents an member class.
   *
   * @return true if this object represents an member class.
   * @since 1.5
   */
  public boolean isMemberClass()
  {
    return VMClass.isMemberClass(this);
  }

  /**
   * Utility method for use by classes in this package.
   */
  static void setAccessible(final AccessibleObject obj)
  {
    AccessController.doPrivileged(new PrivilegedAction()
      {
        public Object run()
          {
            obj.setAccessible(true);
            return null;
          }
      });
  }
}
