/* Class.java -- Representation of a Java class.
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
   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.ObjectStreamClass;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.GenericSignatureFormatError;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.MalformedParameterizedTypeException;
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.HashMap;
import java.util.HashSet;


/**
 * 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)
 * @author Tom Tromey (tromey@cygnus.com)
 * @since 1.0
 * @see ClassLoader
 */
public final class Class 
  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 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 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 list = new ArrayList();
    list.addAll(Arrays.asList(getDeclaredClasses(true)));
    Class superClass = getSuperclass();
    if (superClass != null)
      list.addAll(Arrays.asList(superClass.internalGetClasses()));
    return (Class[])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 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 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
   * @see #getDeclaredFields()
   * @since 1.1
   */
  public Field getDeclaredField(String name) throws NoSuchFieldException
  {
    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
   * @see #getDeclaredMethods()
   * @since 1.1
   */
  public Method getDeclaredMethod(String methodName, Class[] types)
    throws NoSuchMethodException
  {
    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
   * @see #getFields()
   * @since 1.1
   */
  public Field getField(String fieldName)
    throws NoSuchFieldException
  {
    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()
  {
    HashSet set = new HashSet();
    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 (Field[])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
   * @see #getMethods()
   * @since 1.1
   */
  public Method getMethod(String methodName, Class[] types)
    throws NoSuchMethodException
  {
    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 map = new HashMap();
    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 (Method[])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 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 Object newInstance()
    throws InstantiationException, IllegalAccessException
  {
    memberAccessCheck(Member.PUBLIC);
    Constructor 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)))
	  {
	    final Constructor finalConstructor = constructor;
	    AccessController.doPrivileged(new PrivilegedAction()
	      {
		public Object run()
	        {
		  finalConstructor.setAccessible(true);
		  return null;
		}
	      });
	  }
	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(null);
      }
    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
   */
   /* FIXME[GENERICS]: Should be <U> Class<? extends U> asSubClass(Class<U> klass */
  public Class asSubclass(Class klass)
  {
    if (! klass.isAssignableFrom(this))
      throw new ClassCastException();
    return this; /* FIXME[GENERICS]: Should cast to Class<? extends U> */ 
  }

  /**
   * 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
   */
  /* FIXME[GENERICS]: Should be T cast(Object obj) */
  public Object cast(Object obj)
  {
    if (obj != null && ! isInstance(obj))
      throw new ClassCastException();
    return obj; /* FIXME[GENERICS]: Should be cast to T */
  }

  /**
   * 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
   */
  /* FIXME[GENERICS]: T[] getEnumConstants() */
  public Object[] getEnumConstants()
  {
    if (isEnum())
      {
	try
	  {
	    return (Object[])
	      getMethod("values", new Class[0]).invoke(null, new Object[0]);
	  }
	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
   */
  /* FIXME[GENERICS]: <T extends Annotation> T getAnnotation(Class <T>) */
  public Annotation getAnnotation(Class annotationClass)
  {
    Annotation foundAnnotation = null;
    Annotation[] annotations = getAnnotations();
    for (int i = 0; i < annotations.length; i++)
      if (annotations[i].annotationType() == annotationClass)
	foundAnnotation = annotations[i];
    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()
  {
    HashSet set = new HashSet();
    set.addAll(Arrays.asList(getDeclaredAnnotations()));
    Class[] interfaces = getInterfaces();
    for (int i = 0; i < interfaces.length; i++)
      set.addAll(Arrays.asList(interfaces[i].getAnnotations()));
    Class superClass = getSuperclass();
    if (superClass != null)
      set.addAll(Arrays.asList(superClass.getAnnotations()));
    return (Annotation[]) set.toArray(new Annotation[set.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
   */
   /* FIXME[GENERICS]: Should return Class<?> */
  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
   */
   /* FIXME[GENERICS]: Should return Constructor<?> */
  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
   */
   /* FIXME[GENERICS]: Should return TypeVariable<Class<T>> */
  public TypeVariable[] getTypeParameters()
  {
    String sig = VMClass.getClassSignature(this);
    if (sig == null)
      return 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
   */
  /* FIXME[GENERICS]: Should be Class<? extends Annotation> */
  public boolean isAnnotationPresent(Class
				     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);
  }


}
