Index: libraryInterface/Common/src/java/lang/reflect/VMMethod.java
===================================================================
--- libraryInterface/Common/src/java/lang/reflect/VMMethod.java	(revision 14213)
+++ libraryInterface/Common/src/java/lang/reflect/VMMethod.java	(working copy)
@@ -20,6 +20,7 @@
 import org.jikesrvm.runtime.VM_Runtime;
 import org.vmmagic.pragma.Inline;
 import org.vmmagic.pragma.NoInline;
+import org.vmmagic.pragma.Pure;
 
 /**
  * Implementation of java.lang.reflect.Field for JikesRVM.
@@ -27,9 +28,8 @@
  * By convention, order methods in the same order
  * as they appear in the method summary list of Sun's 1.4 Javadoc API.
  */
-final class VMMethod {
+final class VMMethod extends VMMember {
   final VM_Method method;
-  Method m;
 
    // Prevent this class from being instantiated.
   @SuppressWarnings("unused")
@@ -39,74 +39,47 @@
 
   // For use by JikesRVMSupport
   VMMethod(VM_Method m) {
+    super(m);
     method = m;
   }
 
-  public boolean equals(Object other) {
-    if (other instanceof Method) {
-      return method == ((Method)other).m.method;
-    } else {
-      return false;
-    }
+  @Override
+  VM_Member getMember() {
+    return method;
   }
 
-  public Class<?> getDeclaringClass() {
-    return method.getDeclaringClass().getClassForType();
-  }
-
-  Class<?>[] getExceptionTypes() {
-    VM_TypeReference[] exceptionTypes = method.getExceptionTypes();
-    if (exceptionTypes == null) {
-      return new Class[0];
-    } else {
-      return JikesRVMSupport.typesToClasses(exceptionTypes);
-    }
-  }
-
-  int getModifiersInternal() {
-    return method.getModifiers();
-  }
-
-  public String getName() {
-    return method.getName().toString();
-  }
-
-  Class<?>[] getParameterTypes() {
-    return JikesRVMSupport.typesToClasses(method.getParameterTypes());
-  }
-
   Class<?> getReturnType() {
     return method.getReturnType().resolve().getClassForType();
   }
 
   @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
-  Object invoke(Object receiver, Object[] args)
+  Object invoke(Object receiver, Object[] args, Method m)
       throws IllegalAccessException, IllegalArgumentException,
       ExceptionInInitializerError, InvocationTargetException {
     // validate number and types of arguments
     if (checkArguments(args)) {
       if (method.isStatic()) {
-        return invokeStatic(receiver, args);
+        return invokeStatic(receiver, args, m);
       } else {
-        return invokeVirtual(receiver, args);
+        return invokeVirtual(receiver, args, m);
       }
     } else {
       if (method.isStatic()) {
-        return invokeStatic(receiver, makeArgumentsCompatible(args));
+        return invokeStatic(receiver, makeArgumentsCompatible(args), m);
       } else {
-        return invokeVirtual(receiver, makeArgumentsCompatible(args));
+        return invokeVirtual(receiver, makeArgumentsCompatible(args), m);
       }
     }
   }
 
   @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
-  private Object invokeStatic(Object receiver, Object[] args)
+  private Object invokeStatic(Object receiver, Object[] args, Method m)
       throws IllegalAccessException, IllegalArgumentException,
       ExceptionInInitializerError, InvocationTargetException {
     // Accessibility checks
     VM_Method method = this.method;
     if (!method.isPublic() && !m.isAccessible()) {
-      checkAccess();
+      checkAccess(VM_Class.getClassFromStackFrame(3));
     }
 
     // Forces initialization of declaring class
@@ -116,15 +89,11 @@
     }
 
     // Invoke method
-    try {
-      return VM_Reflection.invoke(method, receiver, args);
-    } catch (Throwable t) {
-      throw new InvocationTargetException(t);
-    }
+    return performInvoke(method, receiver, args, eagerInvoker);
   }
 
   @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
-  private Object invokeVirtual(Object receiver, Object[] args)
+  private Object invokeVirtual(Object receiver, Object[] args, Method m)
       throws IllegalAccessException, IllegalArgumentException,
       ExceptionInInitializerError, InvocationTargetException {
     // validate "this" argument
@@ -133,13 +102,13 @@
     }
     VM_Method method = this.method;
     VM_Class declaringClass = method.getDeclaringClass();
-    if (!JikesRVMSupport.isArgumentCompatible(declaringClass, receiver)) {
+    if (!isArgumentCompatible(declaringClass, receiver)) {
       throw new IllegalArgumentException();
     }
 
     // Accessibility checks
     if (!method.isPublic() && !m.isAccessible()) {
-      checkAccess();
+      checkAccess(VM_Class.getClassFromStackFrame(3));
     }
 
     // find the right method to call
@@ -147,118 +116,12 @@
     method = C.findVirtualMethod(method.getName(), method.getDescriptor());
 
     // Invoke method
-    try {
-      return VM_Reflection.invoke(method, receiver, args);
-    } catch (Throwable t) {
-      throw new InvocationTargetException(t);
-    }
+    return performInvoke(method, receiver, args, eagerInvoker);
   }
 
-  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
-  private boolean checkArguments(Object[] args) throws IllegalArgumentException {
-    VM_TypeReference[] parameterTypes = method.getParameterTypes();
-    if (((args == null) && (parameterTypes.length != 0)) ||
-        ((args != null) && (args.length != parameterTypes.length))) {
-      throw new IllegalArgumentException("argument count mismatch");
-    }
-    switch (parameterTypes.length) {
-    case 6:
-      if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[5].resolve(), args[5])) {
-        return false;
-      }
-    case 5:
-      if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[4].resolve(), args[4])) {
-        return false;
-      }
-    case 4:
-      if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[3].resolve(), args[3])) {
-        return false;
-      }
-    case 3:
-      if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[2].resolve(), args[2])) {
-        return false;
-      }
-    case 2:
-      if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[1].resolve(), args[1])) {
-        return false;
-      }
-    case 1:
-      if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[0].resolve(), args[0])) {
-        return false;
-      }
-    case 0:
-      return true;
-    default:
-      for (int i=0, n = parameterTypes.length; i < n; ++i) {
-        if (!JikesRVMSupport.isArgumentCompatible(parameterTypes[i].resolve(), args[i])) {
-          return false;
-        }
-      }
-      return true;
-    }
-  }
-
-  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
-  private  Object[] makeArgumentsCompatible(Object[] args) {
-    VM_TypeReference[] parameterTypes = method.getParameterTypes();
-    int length = parameterTypes.length;
-    Object[] newArgs = new Object[length];
-    switch(length) {
-    case 6: newArgs[5] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[5].peekType(), args[5]);
-    case 5: newArgs[4] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[4].peekType(), args[4]);
-    case 4: newArgs[3] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[3].peekType(), args[3]);
-    case 3: newArgs[2] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[2].peekType(), args[2]);
-    case 2: newArgs[1] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[1].peekType(), args[1]);
-    case 1: newArgs[0] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[0].peekType(), args[0]);
-    case 0: break;
-    default: {
-      for (int i = 0; i < length; ++i) {
-        newArgs[i] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[i].peekType(), args[i]);
-      }
-      break;
-    }
-    }
-    return newArgs;
-  }
-
-  @NoInline
-  private static void runClassInitializer(VM_Class declaringClass) throws ExceptionInInitializerError {
-    try {
-      VM_Runtime.initializeClassForDynamicLink(declaringClass);
-    } catch (Throwable e) {
-      ExceptionInInitializerError ex = new ExceptionInInitializerError();
-      ex.initCause(e);
-      throw ex;
-    }
-  }
-
-  @NoInline
-  private void checkAccess() throws IllegalAccessException {
-    VM_Class accessingClass = VM_Class.getClassFromStackFrame(4);
-    JikesRVMSupport.checkAccess(method, accessingClass);
-  }
-
   // AnnotatedElement interface
-
-  Annotation[] getDeclaredAnnotations() {
-    return method.getDeclaredAnnotations();
-  }
-
-  <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return method.getAnnotation(annotationClass);
-  }
-
+  @Pure
   Object getDefaultValue() {
-    /* FIXME: This should handle the case where this is an annotation method */
-    return null;
+    return method.getAnnotationDefault();
   }
-
-  String getSignature() {
-    return method.getSignature().toString();
-  }
-
-  Annotation[][] getParameterAnnotations() {
-    return method.getDeclaredParameterAnnotations();
-  }
-
 }
Index: libraryInterface/Common/src/java/lang/reflect/VMField.java
===================================================================
--- libraryInterface/Common/src/java/lang/reflect/VMField.java	(revision 14213)
+++ libraryInterface/Common/src/java/lang/reflect/VMField.java	(working copy)
@@ -16,12 +16,15 @@
 
 import org.jikesrvm.classloader.VM_Class;
 import org.jikesrvm.classloader.VM_Field;
+import org.jikesrvm.classloader.VM_Member;
 import org.jikesrvm.classloader.VM_TypeReference;
 import org.jikesrvm.classloader.VM_Type;
-
 import org.jikesrvm.objectmodel.VM_ObjectModel;
 import org.jikesrvm.VM;
 import org.jikesrvm.runtime.VM_Runtime;
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.NoInline;
+import org.vmmagic.pragma.Pure;
 
 /**
  * Implementation of java.lang.reflect.Field for JikesRVM.
@@ -29,10 +32,9 @@
  * By convention, order methods in the same order
  * as they appear in the method summary list of Sun's 1.4 Javadoc API.
  */
-public final class VMField {
+public final class VMField extends VMMember {
 
   final VM_Field field;
-  Field f;
 
   // Prevent this class from being instantiated.
   @SuppressWarnings("unused")
@@ -45,16 +47,13 @@
     field = f;
   }
 
-  public boolean equals(Object object) {
-    if (object instanceof Field) {
-      return field == ((Field)object).f.field;
-    } else {
-      return false;
-    }
+  @Override
+  VM_Member getMember() {
+    return field;
   }
 
-  Object get(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  Object get(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
 
     if (field.isReferenceType()) {
       return field.getObjectValueUnchecked(object);
@@ -80,78 +79,67 @@
     }
   }
 
-  boolean getBoolean(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  boolean getBoolean(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getBooleanInternal(object);
   }
 
-  byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  byte getByte(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getByteInternal(object);
   }
 
-  char getChar(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  char getChar(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getCharInternal(object);
   }
 
-  public Class<?> getDeclaringClass() {
-    return field.getDeclaringClass().getClassForType();
-  }
-
-  double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  double getDouble(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getDoubleInternal(object);
   }
 
-  float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  float getFloat(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getFloatInternal(object);
   }
 
-  int getInt(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  int getInt(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getIntInternal(object);
   }
 
-  long getLong(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  long getLong(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getLongInternal(object);
   }
 
-  int getModifiersInternal() {
-    return field.getModifiers();
-  }
-
-  public String getName() {
-    return field.getName().toString();
-  }
-
-  public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException {
-    checkReadAccess(object);
+  public short getShort(Object object, Field f) throws IllegalAccessException, IllegalArgumentException {
+    checkReadAccess(object, f);
     return getShortInternal(object);
   }
 
+  @Pure
   Class<?> getType() {
     return field.getType().resolve().getClassForType();
   }
 
-  void set(Object object, Object value)
+  void set(Object object, Object value, Field f)
     throws IllegalAccessException, IllegalArgumentException     {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
 
     if (field.isReferenceType()) {
       if (value != null) {
         VM_Type valueType = VM_ObjectModel.getObjectType(value);
-        VM_Type fieldType;
+        VM_Type fieldType = null;
         try {
           fieldType = field.getType().resolve();
         } catch (NoClassDefFoundError e) {
-          throw new IllegalArgumentException("field type mismatch");
+          throwIllegalArgumentException("field type mismatch");
         }
         if (fieldType != valueType &&
             !VM_Runtime.isAssignableWith(fieldType, valueType)) {
-          throw new IllegalArgumentException("field type mismatch");
+          throwIllegalArgumentException("field type mismatch");
         }
       }
       field.setObjectValueUnchecked(object, value);
@@ -172,140 +160,181 @@
     } else if (value instanceof Boolean) {
       setBooleanInternal(object, (Boolean) value);
     } else {
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
     }
   }
 
-  void setBoolean(Object object, boolean value)
+  void setBoolean(Object object, boolean value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setBooleanInternal(object, value);
   }
 
-   void setByte(Object object, byte value)
+   void setByte(Object object, byte value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setByteInternal(object, value);
   }
 
-  void setChar(Object object, char value)
+  void setChar(Object object, char value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setCharInternal(object, value);
   }
 
-  void setDouble(Object object, double value)
+  void setDouble(Object object, double value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setDoubleInternal(object, value);
   }
 
-  void setFloat(Object object, float value)
+  void setFloat(Object object, float value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setFloatInternal(object, value);
   }
 
-  void setInt(Object object, int value)
+  void setInt(Object object, int value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setIntInternal(object, value);
   }
 
-  void setLong(Object object, long value)
+  void setLong(Object object, long value, Field f)
     throws IllegalAccessException, IllegalArgumentException    {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setLongInternal(object, value);
   }
 
-  void setShort(Object object, short value)
+  void setShort(Object object, short value, Field f)
     throws IllegalAccessException, IllegalArgumentException   {
-    checkWriteAccess(object);
+    checkWriteAccess(object, f);
     setShortInternal(object, value);
   }
 
-  private void checkReadAccess(Object obj) throws IllegalAccessException,
+  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
+  private void checkReadAccess(Object obj, Field f) throws IllegalAccessException,
                                                   IllegalArgumentException,
                                                   ExceptionInInitializerError {
+    if (field.isStatic()) {
+      checkStaticReadAccess(obj, f);
+    } else {
+      checkInstanceReadAccess(obj, f);
+    }
+  }
 
+
+  private void checkStaticReadAccess(Object obj, Field f) throws IllegalAccessException,
+                                                  IllegalArgumentException,
+                                                  ExceptionInInitializerError {
+    if (!field.isPublic() && !f.isAccessible()) {
+      VM_Class accessingClass = VM_Class.getClassFromStackFrame(4);
+      checkAccess(accessingClass);
+    }
     VM_Class declaringClass = field.getDeclaringClass();
-    if (!field.isStatic()) {
-      if (obj == null) {
-        throw new NullPointerException();
-      }
+    if (!declaringClass.isInitialized()) {
+      runClassInitializer(declaringClass);
+    }
+  }
 
-      VM_Type objType = VM_ObjectModel.getObjectType(obj);
-      if (objType != declaringClass && !VM_Runtime.isAssignableWith(declaringClass, objType)) {
-        throw new IllegalArgumentException();
-      }
+  private void checkInstanceReadAccess(Object obj, Field f) throws IllegalAccessException,
+                                                  IllegalArgumentException,
+                                                  ExceptionInInitializerError {
+    if (obj == null) {
+      throw new NullPointerException();
     }
+    VM_Class declaringClass = field.getDeclaringClass();
+    VM_Type objType = VM_ObjectModel.getObjectType(obj);
+    if (objType != declaringClass && !VM_Runtime.isAssignableWith(declaringClass, objType)) {
+      throwIllegalArgumentException();
+    }
 
     if (!field.isPublic() && !f.isAccessible()) {
-      VM_Class accessingClass = VM_Class.getClassFromStackFrame(3);
-      JikesRVMSupport.checkAccess(field, accessingClass);
+      VM_Class accessingClass = VM_Class.getClassFromStackFrame(4);
+      checkAccess(accessingClass);
     }
+  }
 
-    if (field.isStatic() && !declaringClass.isInitialized()) {
-      try {
-        VM_Runtime.initializeClassForDynamicLink(declaringClass);
-      } catch (Throwable e) {
-        ExceptionInInitializerError ex = new ExceptionInInitializerError();
-        ex.initCause(e);
-        throw ex;
-      }
+  private void checkWriteAccess(Object obj, Field f) throws IllegalAccessException,
+                                                   IllegalArgumentException,
+                                                   ExceptionInInitializerError {
+    if (field.isStatic()) {
+      checkStaticWriteAccess(obj, f);
+    } else {
+      checkInstanceWriteAccess(obj, f);
     }
   }
 
-  private void checkWriteAccess(Object obj) throws IllegalAccessException,
+
+  private void checkStaticWriteAccess(Object obj, Field f) throws IllegalAccessException,
                                                    IllegalArgumentException,
                                                    ExceptionInInitializerError {
+    if (!field.isPublic() && !f.isAccessible()) {
+      VM_Class accessingClass = VM_Class.getClassFromStackFrame(4);
+      checkAccess(accessingClass);
+    }
 
+    if (field.isFinal())
+      throwIllegalAccessException();
+
     VM_Class declaringClass = field.getDeclaringClass();
-    if (!field.isStatic()) {
-      if (obj == null) {
-        throw new NullPointerException();
-      }
+    if (field.isStatic() && !declaringClass.isInitialized()) {
+      runClassInitializer(declaringClass);
+    }
+  }
 
-      VM_Type objType = VM_ObjectModel.getObjectType(obj);
-      if (objType != declaringClass && !VM_Runtime.isAssignableWith(declaringClass, objType)) {
-        throw new IllegalArgumentException();
-      }
+  private void checkInstanceWriteAccess(Object obj, Field f) throws IllegalAccessException,
+                                                   IllegalArgumentException,
+                                                   ExceptionInInitializerError {
+    if (obj == null) {
+      throw new NullPointerException();
     }
 
+    VM_Class declaringClass = field.getDeclaringClass();
+    VM_Type objType = VM_ObjectModel.getObjectType(obj);
+    if (objType != declaringClass && !VM_Runtime.isAssignableWith(declaringClass, objType)) {
+      throwIllegalArgumentException();
+    }
+
     if (!field.isPublic() && !f.isAccessible()) {
-      VM_Class accessingClass = VM_Class.getClassFromStackFrame(3);
-      JikesRVMSupport.checkAccess(field, accessingClass);
+      VM_Class accessingClass = VM_Class.getClassFromStackFrame(4);
+      checkAccess(accessingClass);
     }
 
     if (field.isFinal())
-      throw new IllegalAccessException();
+      throwIllegalAccessException();
+  }
 
-    if (field.isStatic() && !declaringClass.isInitialized()) {
-      try {
-        VM_Runtime.initializeClassForDynamicLink(declaringClass);
-      } catch (Throwable e) {
-        ExceptionInInitializerError ex = new ExceptionInInitializerError();
-        ex.initCause(e);
-        throw ex;
-      }
-    }
+  @NoInline
+  private void throwIllegalAccessException() throws IllegalAccessException {
+    throw new IllegalAccessException();
   }
 
+  @NoInline
+  private void throwIllegalArgumentException() throws IllegalArgumentException {
+    throw new IllegalArgumentException();
+  }
+
+  @NoInline
+  private void throwIllegalArgumentException(String s) throws IllegalArgumentException {
+    throw new IllegalArgumentException(s);
+  }
+
   public boolean getBooleanInternal(Object object) throws IllegalArgumentException {
     VM_TypeReference type = field.getType();
-    if (!type.isBooleanType()) throw new IllegalArgumentException("field type mismatch");
+    if (!type.isBooleanType()) throwIllegalArgumentException("field type mismatch");
     return field.getBooleanValueUnchecked(object);
   }
 
   private byte getByteInternal(Object object) throws IllegalArgumentException {
     VM_TypeReference type = field.getType();
-    if (!type.isByteType()) throw new IllegalArgumentException("field type mismatch");
+    if (!type.isByteType()) throwIllegalArgumentException("field type mismatch");
     return field.getByteValueUnchecked(object);
   }
 
   private char getCharInternal(Object object) throws IllegalArgumentException {
     VM_TypeReference type = field.getType();
-    if (!type.isCharType()) throw new IllegalArgumentException("field type mismatch");
+    if (!type.isCharType()) throwIllegalArgumentException("field type mismatch");
     return field.getCharValueUnchecked(object);
   }
 
@@ -326,7 +355,8 @@
     } else if (type.isByteType()) {
       return (double)field.getByteValueUnchecked(object);
     } else {
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
+      return 0.0d;
     }
   }
 
@@ -345,7 +375,8 @@
     } else if (type.isByteType()) {
       return (float)field.getByteValueUnchecked(object);
     } else {
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
+      return 0.0f;
     }
   }
 
@@ -360,7 +391,8 @@
     } else if (type.isByteType()) {
       return (int)field.getByteValueUnchecked(object);
     } else {
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
+      return 0;
     }
   }
 
@@ -377,7 +409,8 @@
     } else if (type.isByteType()) {
       return (long)field.getByteValueUnchecked(object);
     } else {
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
+      return 0L;
     }
   }
 
@@ -388,7 +421,8 @@
     } else if (type.isByteType()) {
       return (short)field.getByteValueUnchecked(object);
     } else {
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
+      return 0;
     }
   }
 
@@ -398,7 +432,7 @@
     if (type.isBooleanType())
       field.setBooleanValueUnchecked(object, value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setByteInternal(Object object, byte value) throws IllegalArgumentException {
@@ -418,7 +452,7 @@
     else if (type.isFloatType())
       field.setFloatValueUnchecked(object, (float)value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setCharInternal(Object object, char value) throws IllegalArgumentException {
@@ -436,7 +470,7 @@
     else if (type.isFloatType())
       field.setFloatValueUnchecked(object, (float)value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setDoubleInternal(Object object, double value) throws IllegalArgumentException {
@@ -444,7 +478,7 @@
     if (type.isDoubleType())
       field.setDoubleValueUnchecked(object, value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setFloatInternal(Object object, float value) throws IllegalArgumentException {
@@ -454,7 +488,7 @@
     else if (type.isDoubleType())
       field.setDoubleValueUnchecked(object, (double)value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setIntInternal(Object object, int value) throws IllegalArgumentException {
@@ -468,7 +502,7 @@
     else if (type.isFloatType())
       field.setFloatValueUnchecked(object, (float)value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setLongInternal(Object object, long value) throws IllegalArgumentException {
@@ -480,7 +514,7 @@
     else if (type.isFloatType())
       field.setFloatValueUnchecked(object, (float)value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
 
   private void setShortInternal(Object object, short value) throws IllegalArgumentException {
@@ -496,21 +530,6 @@
     else if (type.isFloatType())
       field.setFloatValueUnchecked(object, (float)value);
     else
-      throw new IllegalArgumentException("field type mismatch");
+      throwIllegalArgumentException("field type mismatch");
   }
-
-  // AnnotatedElement interface
-
-  Annotation[] getDeclaredAnnotations() {
-    return field.getDeclaredAnnotations();
-  }
-
-  <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return field.getAnnotation(annotationClass);
-  }
-
-  String getSignature() {
-    return field.getSignature().toString();
-  }
-
 }
Index: libraryInterface/Common/src/java/lang/reflect/JikesRVMSupport.java
===================================================================
--- libraryInterface/Common/src/java/lang/reflect/JikesRVMSupport.java	(revision 14213)
+++ libraryInterface/Common/src/java/lang/reflect/JikesRVMSupport.java	(working copy)
@@ -24,110 +24,6 @@
  */
 public class JikesRVMSupport {
 
-  /**
-   * Convert from "vm" type system to "jdk" type system.
-   */
-  static Class<?>[] typesToClasses(VM_TypeReference[] types) {
-    Class<?>[] classes = new Class[types.length];
-    for (int i = 0; i < types.length; i++) {
-      classes[i] = types[i].resolve().getClassForType();
-    }
-    return classes;
-  }
-
-  /**
-   * Make possibly wrapped method argument compatible with expected type
-   */
-  @SuppressWarnings({"UnnecessaryBoxing","PMD.IntegerInstantiation"})
-  @NoInline
-  @Pure
-  static Object makeArgumentCompatible(VM_Type expectedType, Object arg) {
-    if (expectedType.isPrimitiveType()) {
-      if (arg instanceof java.lang.Byte) {
-        if (expectedType.isByteType()) return arg;
-        if (expectedType.isShortType()) return Short.valueOf((Byte) arg);
-        if (expectedType.isIntType()) return Integer.valueOf((Byte) arg);
-        if (expectedType.isLongType()) return Long.valueOf((Byte) arg);
-      } else if (arg instanceof java.lang.Short) {
-        if (expectedType.isShortType()) return arg;
-        if (expectedType.isIntType()) return Integer.valueOf((Short) arg);
-        if (expectedType.isLongType()) return Long.valueOf((Short) arg);
-      } else if (arg instanceof java.lang.Character) {
-        if (expectedType.isCharType()) return arg;
-        if (expectedType.isIntType()) return Integer.valueOf((Character) arg);
-        if (expectedType.isLongType()) return Long.valueOf((Character) arg);
-      } else if (arg instanceof java.lang.Integer) {
-        if (expectedType.isIntType()) return arg;
-        if (expectedType.isLongType()) return Long.valueOf((Integer) arg);
-      } else if (arg instanceof java.lang.Float) {
-        if (expectedType.isDoubleType()) return Double.valueOf((Float) arg);
-      }
-    }
-    return arg;
-  }
-
-  /**
-   * Are the 2 arguments compatible? Throw IllegalArgumentException if they
-   * can't be made compatible.
-   */
-  @Pure
-  @Inline
-  static boolean isArgumentCompatible(VM_Type expectedType, Object arg) {
-    if (expectedType.isPrimitiveType()) {
-      return isPrimitiveArgumentCompatible(expectedType, arg);
-    } else {
-      if (arg == null) return true; // null is always ok
-      VM_Type actualType = VM_ObjectModel.getObjectType(arg);
-      if (expectedType == actualType ||
-          expectedType == VM_Type.JavaLangObjectType ||
-          VM_Runtime.isAssignableWith(expectedType, actualType)) {
-        return true;
-      } else {
-        throwNewIllegalArgumentException();
-        return false;
-      }
-    }
-  }
-
-  @NoInline
-  private static void throwNewIllegalArgumentException() {
-    throw new IllegalArgumentException();
-  }
-  @Pure
-  @Inline
-  private static boolean isPrimitiveArgumentCompatible(VM_Type expectedType, Object arg) {
-    if (arg instanceof java.lang.Void) {
-      if (expectedType.isVoidType()) return true;
-    } else if (arg instanceof java.lang.Boolean) {
-      if (expectedType.isBooleanType()) return true;
-    } else if (arg instanceof java.lang.Byte) {
-      if (expectedType.isByteType()) return true;
-      if (expectedType.isShortType()) return false;
-      if (expectedType.isIntType()) return false;
-      if (expectedType.isLongType()) return false;
-    } else if (arg instanceof java.lang.Short) {
-      if (expectedType.isShortType()) return true;
-      if (expectedType.isIntType()) return false;
-      if (expectedType.isLongType()) return false;
-    } else if (arg instanceof java.lang.Character) {
-      if (expectedType.isCharType()) return true;
-      if (expectedType.isIntType()) return false;
-      if (expectedType.isLongType()) return false;
-    } else if (arg instanceof java.lang.Integer) {
-      if (expectedType.isIntType()) return true;
-      if (expectedType.isLongType()) return false;
-    } else if (arg instanceof java.lang.Long) {
-      if (expectedType.isLongType()) return true;
-    } else if (arg instanceof java.lang.Float) {
-      if (expectedType.isFloatType()) return true;
-      if (expectedType.isDoubleType()) return false;
-    } else if (arg instanceof java.lang.Double) {
-      if (expectedType.isDoubleType()) return true;
-    }
-    throwNewIllegalArgumentException();
-    return false;
-  }
-
   public static Field createField(VM_Field f) {
     return new Field(new VMField(f));
   }
@@ -168,33 +64,4 @@
   public static VM_Method getMethodOf(VMConstructor cons) {
     return cons.constructor;
   }
-
-
-  /**
-   * Check to see if a method declared by the accessingClass
-   * should be allowed to access the argument VM_Member.
-   * Assumption: member is not public.  This trivial case should
-   * be approved by the caller without needing to call this method.
-   */
-  public static void checkAccess(VM_Member member, VM_Class accessingClass) throws IllegalAccessException {
-    VM_Class declaringClass = member.getDeclaringClass();
-    if (member.isPrivate()) {
-      // access from the declaringClass is allowed
-      if (accessingClass == declaringClass) return;
-    } else if (member.isProtected()) {
-      // access within the package is allowed.
-      if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return;
-
-      // access by subclasses is allowed.
-      for (VM_Class cls = accessingClass; cls != null; cls = cls.getSuperClass()) {
-        if (accessingClass == declaringClass) return;
-      }
-    } else {
-      // default: access within package is allowed
-      if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return;
-    }
-
-    throw new IllegalAccessException("Access to "+member+" is denied to "+accessingClass);
-  }
-
 }
Index: libraryInterface/Common/src/java/lang/reflect/VMConstructor.java
===================================================================
--- libraryInterface/Common/src/java/lang/reflect/VMConstructor.java	(revision 14213)
+++ libraryInterface/Common/src/java/lang/reflect/VMConstructor.java	(working copy)
@@ -17,6 +17,8 @@
 import org.jikesrvm.classloader.*;
 import org.jikesrvm.runtime.VM_Reflection;
 import org.jikesrvm.runtime.VM_Runtime;
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.NoInline;
 
 /**
  * Implementation of java.lang.reflect.VMConstructor for JikesRVM.
@@ -24,9 +26,8 @@
  * By convention, order methods in the same order
  * as they appear in the method summary list of Sun's 1.4 Javadoc API.
  */
-final class VMConstructor {
+final class VMConstructor extends VMMember {
   final VM_Method constructor;
-  Constructor cons;
 
   // Prevent this class from being instantiated.
   @SuppressWarnings("unused")
@@ -36,109 +37,56 @@
 
   // For use by JikesRVMSupport
   VMConstructor(VM_Method m) {
+    super(m);
     constructor = m;
   }
 
-  public boolean equals(Object other) {
-    if (other instanceof Constructor) {
-      return constructor == ((Constructor)other).cons.constructor;
-    } else {
-      return false;
-    }
+  @Override
+  VM_Member getMember() {
+    return constructor;
   }
 
-  Class getDeclaringClass() {
-    return constructor.getDeclaringClass().getClassForType();
-  }
-
-  Class[] getExceptionTypes() {
-    VM_TypeReference[] exceptionTypes = constructor.getExceptionTypes();
-    if (exceptionTypes == null) {
-      return new Class[0];
+  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
+  Object construct(Object[] args, Constructor cons) throws InstantiationException,
+                IllegalAccessException,
+                IllegalArgumentException,
+                InvocationTargetException {
+    if (checkArguments(args)) {
+      return invokeConstructor(args, cons);
     } else {
-      return JikesRVMSupport.typesToClasses(exceptionTypes);
+      return invokeConstructor(makeArgumentsCompatible(args), cons);
     }
   }
 
-  int getModifiersInternal() {
-    return constructor.getModifiers();
-  }
-
-  String getName() {
-    return getDeclaringClass().getName();
-  }
-
-  Class[] getParameterTypes() {
-    return JikesRVMSupport.typesToClasses(constructor.getParameterTypes());
-  }
-
-  Object construct(Object[] args) throws InstantiationException,
+  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
+  private Object invokeConstructor(Object[] args, Constructor c) throws InstantiationException,
                 IllegalAccessException,
                 IllegalArgumentException,
                 InvocationTargetException {
-    // Check accessibility
-    if (!constructor.isPublic() && !cons.isAccessible()) {
-      VM_Class accessingClass = VM_Class.getClassFromStackFrame(2);
-      JikesRVMSupport.checkAccess(constructor, accessingClass);
+    // Accessibility checks
+    VM_Method method = this.constructor;
+    if (!method.isPublic() && !c.isAccessible()) {
+      checkAccess(VM_Class.getClassFromStackFrame(3));
     }
-
-    // validate number and types of arguments to constructor
-    VM_TypeReference[] parameterTypes = constructor.getParameterTypes();
-    if (args == null) {
-      if (parameterTypes.length != 0) {
-        throw new IllegalArgumentException("argument count mismatch");
-      }
-    } else {
-      if (args.length != parameterTypes.length) {
-        throw new IllegalArgumentException("argument count mismatch");
-      }
-      for (int i = 0; i < parameterTypes.length; i++) {
-        args[i] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[i].resolve(), args[i]);
-      }
+    // Ensure class isn't abstract
+    VM_Class declaringClass = method.getDeclaringClass();
+    if (declaringClass.isAbstract()) {
+      throwNewAbstractInstantiationException();
     }
-
-    VM_Class cls = constructor.getDeclaringClass();
-    if (cls.isAbstract()) {
-      throw new InstantiationException("Abstract class");
+    // Forces initialization of declaring class
+    if (!declaringClass.isInitialized()) {
+      runClassInitializer(declaringClass);
     }
-
-    // Ensure that the class is initialized
-    if (!cls.isInitialized()) {
-      try {
-        VM_Runtime.initializeClassForDynamicLink(cls);
-      } catch (Throwable e) {
-        ExceptionInInitializerError ex = new ExceptionInInitializerError();
-        ex.initCause(e);
-        throw ex;
-      }
-    }
-
     // Allocate an uninitialized instance;
-    Object obj = VM_Runtime.resolvedNewScalar(cls);
-
-    // Run the constructor on the instance.
-    try {
-      VM_Reflection.invoke(constructor, obj, args);
-    } catch (Throwable e) {
-      throw new InvocationTargetException(e);
-    }
+    Object obj = VM_Runtime.resolvedNewScalar(declaringClass);
+    // Invoke method
+    performInvoke(method, obj, args, eagerInvoker);
+    // Return instance
     return obj;
   }
 
-  String getSignature() {
-    return constructor.getSignature().toString();
+  @NoInline
+  private void throwNewAbstractInstantiationException() throws InstantiationException{
+    throw new InstantiationException("Class " + constructor.getDeclaringClass() + " is abstract");
   }
-
-  Annotation[][] getParameterAnnotations() {
-    return constructor.getDeclaredParameterAnnotations();
-  }
-
-  Annotation[] getDeclaredAnnotations() {
-    return constructor.getDeclaredAnnotations();
-  }
-
-  <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-    return constructor.getAnnotation(annotationClass);
-  }
-
 }
Index: libraryInterface/Common/src/java/lang/reflect/VMMember.java
===================================================================
--- libraryInterface/Common/src/java/lang/reflect/VMMember.java	(revision 0)
+++ libraryInterface/Common/src/java/lang/reflect/VMMember.java	(revision 0)
@@ -0,0 +1,392 @@
+/*
+ *  This file is part of the Jikes RVM project (http://jikesrvm.org).
+ *
+ *  This file is licensed to You under the Common Public License (CPL);
+ *  You may not use this file except in compliance with the License. You
+ *  may obtain a copy of the License at
+ *
+ *      http://www.opensource.org/licenses/cpl1.0.php
+ *
+ *  See the COPYRIGHT.txt file distributed with this work for information
+ *  regarding copyright ownership.
+ */
+package java.lang.reflect;
+
+import java.lang.annotation.Annotation;
+
+import org.jikesrvm.classloader.*;
+import org.jikesrvm.objectmodel.VM_ObjectModel;
+import org.jikesrvm.runtime.VM_Reflection;
+import org.jikesrvm.runtime.VM_Magic;
+import org.jikesrvm.runtime.VM_Runtime;
+import org.jikesrvm.util.VM_HashMap;
+import org.jikesrvm.VM;
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.NoInline;
+import org.vmmagic.pragma.Pure;
+
+/**
+ * Based implementation of java.lang.reflect.Constructor/Field/Method for
+ * JikesRVM.
+ */
+public abstract class VMMember {
+
+  public static final int OUT_OF_LINE_MACHINE_CODE = 0;
+
+  public static final int OUT_OF_LINE_MACHINE_CODE_SIMPLIFY = 1;
+
+  public static final int BYTECODE_EAGER_CREATE = 2;
+
+  public static final int BYTECODE_LAZY_CREATE = 3;
+
+    public static final int INVOKE_POLICY = BYTECODE_LAZY_CREATE;
+
+  protected final ReflectionBase eagerInvoker;
+
+  VMMember() {
+    eagerInvoker = null;
+  }
+
+  VMMember(VM_Method method) {
+    if (INVOKE_POLICY == BYTECODE_EAGER_CREATE && VM.runningVM)
+      eagerInvoker = getInvoker(method);
+    else
+      eagerInvoker = null;
+  }
+
+  abstract VM_Member getMember();
+
+  @Pure
+  public final boolean equals(Object o) {
+    return (o instanceof VMMember) && ((VMMember)o).getMember() == getMember();
+  }
+
+  @Pure
+  final Class<?> getDeclaringClass() {
+    return getMember().getDeclaringClass().getClassForType();
+  }
+
+  @Pure
+  final int getModifiersInternal() {
+    return getMember().getModifiers();
+  }
+
+  @Pure
+  final String getName() {
+    return getMember().getName().toString();
+  }
+
+  final Class<?>[] getParameterTypes() {
+    VM_TypeReference[] types = ((VM_Method)getMember()).getParameterTypes();
+    Class<?>[] classes = new Class[types.length];
+    for (int i = 0; i < types.length; i++) {
+      classes[i] = types[i].resolve().getClassForType();
+    }
+    return classes;
+  }
+
+  final Class[] getExceptionTypes() {
+    VM_TypeReference[] types = ((VM_Method)getMember()).getExceptionTypes();
+    if (types == null) {
+      return new Class[0];
+    } else {
+      Class<?>[] classes = new Class[types.length];
+      for (int i = 0; i < types.length; i++) {
+        classes[i] = types[i].resolve().getClassForType();
+      }
+      return classes;
+    }
+  }
+
+  final Annotation[] getDeclaredAnnotations() {
+    return getMember().getDeclaredAnnotations();
+  }
+
+  final <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+    return getMember().getAnnotation(annotationClass);
+  }
+
+  final Annotation[][] getParameterAnnotations() {
+    return ((VM_Method)getMember()).getDeclaredParameterAnnotations();
+  }
+
+  @Pure
+  final String getSignature() {
+    return getMember().getSignature().toString();
+  }
+
+  /**
+   * Check to see if a method declared by the accessingClass
+   * should be allowed to access the VMMember.
+   * Assumption: member is not public.  This trivial case should
+   * be approved by the caller without needing to call this method.
+   */
+  @Inline
+  final void checkAccess(VM_Class accessingClass) throws IllegalAccessException {
+    if(!checkAccess2(accessingClass)) throwIllegalAccessException(accessingClass);
+  }
+
+  @NoInline
+  private void throwIllegalAccessException(VM_Class accessingClass) throws IllegalAccessException {
+    throw new IllegalAccessException("Access to "+getMember()+" is denied to "+accessingClass); 
+  }
+
+  @Pure
+  private boolean checkAccess2(VM_Class accessingClass) {
+    VM_Member member = getMember();
+    VM_Class declaringClass = member.getDeclaringClass();
+    if (member.isPrivate()) {
+      // access from the declaringClass is allowed
+      return accessingClass == declaringClass;
+    } else if (member.isProtected()) {
+      // access within the package is allowed.
+      if (declaringClass.getClassLoader() == accessingClass.getClassLoader() &&
+          declaringClass.getPackageName().equals(accessingClass.getPackageName()))
+        return true;
+      // access by subclasses is allowed.
+      for (VM_Class cls = accessingClass; cls != null; cls = cls.getSuperClass()) {
+        if (accessingClass == declaringClass) return true;
+      }
+      return false;
+    } else {
+      // default: access within package is allowed
+      return declaringClass.getClassLoader() == accessingClass.getClassLoader() &&
+        declaringClass.getPackageName().equals(accessingClass.getPackageName());
+    }
+  }
+
+
+  @NoInline
+  static void runClassInitializer(VM_Class declaringClass) throws ExceptionInInitializerError {
+    try {
+      VM_Runtime.initializeClassForDynamicLink(declaringClass);
+    } catch (Throwable e) {
+      ExceptionInInitializerError ex = new ExceptionInInitializerError();
+      ex.initCause(e);
+      throw ex;
+    }
+  }
+
+  private static final VM_HashMap<VM_Method, ReflectionBase> invokeMethods = new VM_HashMap<VM_Method, ReflectionBase>();
+
+  @Pure
+  private static ReflectionBase getInvoker(VM_Method method) {
+    ReflectionBase invoker = invokeMethods.get(method);
+    if (invoker == null) {
+      Class<ReflectionBase> reflectionClass = VM_Class.createReflectionClass(method);
+      try {
+        invoker = reflectionClass.newInstance();
+      } catch (Throwable e) {
+        throw new Error(e);
+      }
+      invokeMethods.put(method, invoker);
+    }
+    return invoker;
+  }
+
+  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
+    private static Object performBytecodeInvoke(VM_Method method, Object receiver, Object[] args, ReflectionBase eagerInvoker)
+      throws IllegalAccessException, IllegalArgumentException, ExceptionInInitializerError,
+      InvocationTargetException {
+    ReflectionBase invoker;
+    if (INVOKE_POLICY == BYTECODE_EAGER_CREATE && eagerInvoker != null) {
+      invoker = eagerInvoker;
+    } else {
+      invoker = getInvoker(method);
+    }
+    try {
+      return invoker.invoke(receiver, args);
+    } catch (IllegalArgumentException e) {
+      throw e;
+    } catch (ExceptionInInitializerError e) {
+      throw e;
+    } catch (Throwable t) {
+      throwInvocationTargetException(t, receiver);
+    }
+    return null; // never reached
+  }
+
+  @NoInline
+  private static void throwInvocationTargetException(Throwable t, Object receiver) throws InvocationTargetException {
+    throw new InvocationTargetException(t,
+                                        "While invoking the method:\n\t\"" + // toString() + "\"\n" +
+                                        " on the object:\n\t\"" + receiver + "\"\n" +
+                                        " it threw the exception:\n\t\"" + t + "\"");
+  }
+
+  @Inline
+    public static Object performInvoke(VM_Method method, Object receiver, Object[] args, ReflectionBase eagerInvoker)
+      throws IllegalAccessException, IllegalArgumentException, ExceptionInInitializerError,
+      InvocationTargetException {
+    if (INVOKE_POLICY == BYTECODE_EAGER_CREATE || INVOKE_POLICY == BYTECODE_LAZY_CREATE) {
+      return performBytecodeInvoke(method, receiver, args, eagerInvoker);
+    } else {
+      try {
+        return VM_Reflection.invoke(method, receiver, args);
+      } catch (Throwable t) {
+        throwInvocationTargetException(t, receiver);
+        return null; // never reached
+      }
+    }
+  }
+
+  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
+  final boolean checkArguments(Object[] args) throws IllegalArgumentException {
+    VM_TypeReference[] parameterTypes = ((VM_Method)getMember()).getParameterTypes();
+    if (((args == null) && (parameterTypes.length != 0)) ||
+        ((args != null) && (args.length != parameterTypes.length))) {
+      throw new IllegalArgumentException("argument count mismatch");
+    }
+    switch (parameterTypes.length) {
+    case 6:
+      if (!isArgumentCompatible(parameterTypes[5].resolve(), args[5])) {
+        return false;
+      }
+    case 5:
+      if (!isArgumentCompatible(parameterTypes[4].resolve(), args[4])) {
+        return false;
+      }
+    case 4:
+      if (!isArgumentCompatible(parameterTypes[3].resolve(), args[3])) {
+        return false;
+      }
+    case 3:
+      if (!isArgumentCompatible(parameterTypes[2].resolve(), args[2])) {
+        return false;
+      }
+    case 2:
+      if (!isArgumentCompatible(parameterTypes[1].resolve(), args[1])) {
+        return false;
+      }
+    case 1:
+      if (!isArgumentCompatible(parameterTypes[0].resolve(), args[0])) {
+        return false;
+      }
+    case 0:
+      return true;
+    default:
+      for (int i=0, n = parameterTypes.length; i < n; ++i) {
+        if (!isArgumentCompatible(parameterTypes[i].resolve(), args[i])) {
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+
+  @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0})
+  final Object[] makeArgumentsCompatible(Object[] args) {
+    VM_TypeReference[] parameterTypes = ((VM_Method)getMember()).getParameterTypes();
+    int length = parameterTypes.length;
+    Object[] newArgs = new Object[length];
+    switch(length) {
+    case 6: newArgs[5] = makeArgumentCompatible(parameterTypes[5].peekType(), args[5]);
+    case 5: newArgs[4] = makeArgumentCompatible(parameterTypes[4].peekType(), args[4]);
+    case 4: newArgs[3] = makeArgumentCompatible(parameterTypes[3].peekType(), args[3]);
+    case 3: newArgs[2] = makeArgumentCompatible(parameterTypes[2].peekType(), args[2]);
+    case 2: newArgs[1] = makeArgumentCompatible(parameterTypes[1].peekType(), args[1]);
+    case 1: newArgs[0] = makeArgumentCompatible(parameterTypes[0].peekType(), args[0]);
+    case 0: break;
+    default: {
+      for (int i = 0; i < length; ++i) {
+        newArgs[i] = makeArgumentCompatible(parameterTypes[i].peekType(), args[i]);
+      }
+      break;
+    }
+    }
+    return newArgs;
+  }
+
+  /**
+   * Make possibly wrapped method argument compatible with expected type
+   */
+  @SuppressWarnings({"UnnecessaryBoxing","PMD.IntegerInstantiation"})
+  @Pure
+  private static Object makeArgumentCompatible(VM_Type expectedType, Object arg) {
+    if (expectedType.isPrimitiveType()) {
+      if (arg instanceof java.lang.Byte) {
+        if (expectedType.isByteType()) return arg;
+        if (expectedType.isShortType()) return Short.valueOf((Byte) arg);
+        if (expectedType.isIntType()) return Integer.valueOf((Byte) arg);
+        if (expectedType.isLongType()) return Long.valueOf((Byte) arg);
+      } else if (arg instanceof java.lang.Short) {
+        if (expectedType.isShortType()) return arg;
+        if (expectedType.isIntType()) return Integer.valueOf((Short) arg);
+        if (expectedType.isLongType()) return Long.valueOf((Short) arg);
+      } else if (arg instanceof java.lang.Character) {
+        if (expectedType.isCharType()) return arg;
+        if (expectedType.isIntType()) return Integer.valueOf((Character) arg);
+        if (expectedType.isLongType()) return Long.valueOf((Character) arg);
+      } else if (arg instanceof java.lang.Integer) {
+        if (expectedType.isIntType()) return arg;
+        if (expectedType.isLongType()) return Long.valueOf((Integer) arg);
+      } else if (arg instanceof java.lang.Float) {
+        if (expectedType.isDoubleType()) return Double.valueOf((Float) arg);
+      }
+    }
+    return arg;
+  }
+
+  /**
+   * Are the 2 arguments compatible? Throw IllegalArgumentException if they
+   * can't be made compatible.
+   */
+  @Pure
+  @Inline
+  static boolean isArgumentCompatible(VM_Type expectedType, Object arg) {
+    if (expectedType.isPrimitiveType()) {
+      return isPrimitiveArgumentCompatible(expectedType, arg);
+    } else {
+      if (arg == null) return true; // null is always ok
+      VM_Type actualType = VM_ObjectModel.getObjectType(arg);
+      if (expectedType == actualType ||
+          expectedType == VM_Type.JavaLangObjectType ||
+          VM_Runtime.isAssignableWith(expectedType, actualType)) {
+        return true;
+      } else {
+        throwNewIllegalArgumentException();
+        return false;
+      }
+    }
+  }
+
+  @Pure
+  @Inline
+  private static boolean isPrimitiveArgumentCompatible(VM_Type expectedType, Object arg) {
+    if (arg instanceof java.lang.Void) {
+      if (expectedType.isVoidType()) return true;
+    } else if (arg instanceof java.lang.Boolean) {
+      if (expectedType.isBooleanType()) return true;
+    } else if (arg instanceof java.lang.Byte) {
+      if (expectedType.isByteType()) return true;
+      if (expectedType.isShortType()) return false;
+      if (expectedType.isIntType()) return false;
+      if (expectedType.isLongType()) return false;
+    } else if (arg instanceof java.lang.Short) {
+      if (expectedType.isShortType()) return true;
+      if (expectedType.isIntType()) return false;
+      if (expectedType.isLongType()) return false;
+    } else if (arg instanceof java.lang.Character) {
+      if (expectedType.isCharType()) return true;
+      if (expectedType.isIntType()) return false;
+      if (expectedType.isLongType()) return false;
+    } else if (arg instanceof java.lang.Integer) {
+      if (expectedType.isIntType()) return true;
+      if (expectedType.isLongType()) return false;
+    } else if (arg instanceof java.lang.Long) {
+      if (expectedType.isLongType()) return true;
+    } else if (arg instanceof java.lang.Float) {
+      if (expectedType.isFloatType()) return true;
+      if (expectedType.isDoubleType()) return false;
+    } else if (arg instanceof java.lang.Double) {
+      if (expectedType.isDoubleType()) return true;
+    }
+    throwNewIllegalArgumentException();
+    return false;
+  }
+
+  @NoInline
+  private static void throwNewIllegalArgumentException() {
+    throw new IllegalArgumentException();
+  }
+}
Index: libraryInterface/Common/src/java/lang/Class.java
===================================================================
--- libraryInterface/Common/src/java/lang/Class.java	(revision 14213)
+++ libraryInterface/Common/src/java/lang/Class.java	(working copy)
@@ -46,6 +46,9 @@
 import org.jikesrvm.runtime.VM_Runtime;
 import org.jikesrvm.VM_UnimplementedError;
 
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.NoInline;
+import org.vmmagic.pragma.Pure;
 /**
  * Implementation of java.lang.Class for JikesRVM.
  *
@@ -609,7 +612,7 @@
     // Check that caller is allowed to access it
     if (!defaultConstructor.isPublic()) {
       VM_Class accessingClass = VM_Class.getClassFromStackFrame(1);
-      JikesRVMSupport.checkAccess(defaultConstructor, accessingClass);
+      checkAccess(defaultConstructor, accessingClass);
     }
 
     // Ensure that the class is initialized
@@ -1024,4 +1027,44 @@
       throw new ClassCastException();
     return (Class<? extends U>) this;
   }
+
+
+  /**
+   * Check to see if a method declared by the accessingClass
+   * should be allowed to access the argument VM_Member.
+   * Assumption: member is not public.  This trivial case should
+   * be approved by the caller without needing to call this method.
+   */
+  @Inline
+  private static void checkAccess(VM_Member member, VM_Class accessingClass) throws IllegalAccessException {
+    if(!checkAccess2(member, accessingClass)) throwIllegalAccessException(member, accessingClass);
+  }
+
+  @NoInline
+  private static void throwIllegalAccessException(VM_Member member, VM_Class accessingClass) throws IllegalAccessException {
+    throw new IllegalAccessException("Access to "+member+" is denied to "+accessingClass);
+  }
+
+  @Pure
+  private static boolean checkAccess2(VM_Member member, VM_Class accessingClass) {
+    VM_Class declaringClass = member.getDeclaringClass();
+    if (member.isPrivate()) {
+      // access from the declaringClass is allowed
+      return accessingClass == declaringClass;
+    } else if (member.isProtected()) {
+      // access within the package is allowed.
+      if (declaringClass.getClassLoader() == accessingClass.getClassLoader() &&
+          declaringClass.getPackageName().equals(accessingClass.getPackageName()))
+        return true;
+      // access by subclasses is allowed.
+      for (VM_Class cls = accessingClass; cls != null; cls = cls.getSuperClass()) {
+        if (accessingClass == declaringClass) return true;
+      }
+      return false;
+    } else {
+      // default: access within package is allowed
+      return declaringClass.getClassLoader() == accessingClass.getClassLoader() &&
+        declaringClass.getPackageName().equals(accessingClass.getPackageName());
+    }
+  }
 }
Index: libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Method.java
===================================================================
--- libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Method.java	(revision 0)
+++ libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Method.java	(revision 0)
@@ -0,0 +1,498 @@
+/* java.lang.reflect.Method - reflection of Java methods
+   Copyright (C) 1998, 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
+
+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.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Method class represents a member method of a class. It also allows
+ * dynamic invocation, via reflection. This works for both static and
+ * instance methods. Invocation on Method objects knows how to do
+ * widening conversions, but throws {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Method regardless of location, but invocation access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @see java.lang.Class#getMethods()
+ * @see java.lang.Class#getDeclaredMethods()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Method
+extends AccessibleObject implements Member, GenericDeclaration
+{
+  private static final int METHOD_MODIFIERS
+    = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+      | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+      | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+  private MethodSignatureParser p;
+
+  final VMMethod m;
+
+  /**
+   * This class is uninstantiable outside this package.
+   */
+  Method(VMMethod m)
+  {
+    this.m = m;
+  }
+
+  /**
+   * Gets the class that declared this method, or the class where this method
+   * is a non-inherited member.
+   * @return the class that declared this member
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?> getDeclaringClass()
+  {
+    return (Class<?>) m.getDeclaringClass();
+  }
+
+  /**
+   * Gets the name of this method.
+   * @return the name of this method
+   */
+  public String getName()
+  {
+    return m.getName();
+  }
+
+  /**
+   * Gets the modifiers this method uses.  Use the <code>Modifier</code>
+   * class to interpret the values.  A method can only have a subset of the
+   * following modifiers: public, private, protected, abstract, static,
+   * final, synchronized, native, and strictfp.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public int getModifiers()
+  {
+    return m.getModifiersInternal() & METHOD_MODIFIERS;
+  }
+
+  /**
+   * Return true if this method is a bridge method.  A bridge method
+   * is generated by the compiler in some situations involving
+   * generics and inheritance.
+   * @since 1.5
+   */
+  public boolean isBridge()
+  {
+    return (m.getModifiersInternal() & Modifier.BRIDGE) != 0;
+  }
+
+  /**
+   * Return true if this method is synthetic, false otherwise.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (m.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this is a varargs method, that is if
+   * the method takes a variable number of arguments.
+   * @since 1.5
+   */
+  public boolean isVarArgs()
+  {
+    return (m.getModifiersInternal() & Modifier.VARARGS) != 0;
+  }
+
+  /**
+   * Gets the return type of this method.
+   * @return the type of this method
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?> getReturnType()
+  {
+    return (Class<?>) m.getReturnType();
+  }
+
+  /**
+   * Get the parameter list for this method, in declaration order. If the
+   * method takes no parameters, returns a 0-length array (not null).
+   *
+   * @return a list of the types of the method's parameters
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getParameterTypes()
+  {
+    return (Class<?>[]) m.getParameterTypes();
+  }
+
+  /**
+   * Get the exception types this method says it throws, in no particular
+   * order. If the method has no throws clause, returns a 0-length array
+   * (not null).
+   *
+   * @return a list of the types in the method's throws clause
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getExceptionTypes()
+  {
+    return (Class<?>[]) m.getExceptionTypes();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Methods are semantically equivalent if they have the same declaring
+   * class, name, parameter list, and return type.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals(Object o)
+  {
+    return m.equals(o);
+  }
+
+  /**
+   * Get the hash code for the Method. The Method hash code is the hash code
+   * of its name XOR'd with the hash code of its class name.
+   *
+   * @return the hash code for the object
+   */
+  public int hashCode()
+  {
+    return m.getDeclaringClass().getName().hashCode() ^ m.getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Method. A Method's String
+   * representation is "&lt;modifiers&gt; &lt;returntype&gt;
+   * &lt;methodname&gt;(&lt;paramtypes&gt;) throws &lt;exceptions&gt;", where
+   * everything after ')' is omitted if there are no exceptions.<br> Example:
+   * <code>public static int run(java.lang.Runnable,int)</code>
+   *
+   * @return the String representation of the Method
+   */
+  public String toString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(ClassHelper.getUserName(getReturnType())).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName()).append('(');
+    Class[] c = getParameterTypes();
+    if (c.length > 0)
+      {
+        sb.append(ClassHelper.getUserName(c[0]));
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(ClassHelper.getUserName(c[i]));
+      }
+    sb.append(')');
+    c = getExceptionTypes();
+    if (c.length > 0)
+      {
+        sb.append(" throws ").append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    return sb.toString();
+  }
+
+  public String toGenericString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    Constructor.addTypeParameters(sb, getTypeParameters());
+    sb.append(getGenericReturnType()).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName()).append('(');
+    Type[] types = getGenericParameterTypes();
+    if (types.length > 0)
+      {
+        sb.append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    sb.append(')');
+    types = getGenericExceptionTypes();
+    if (types.length > 0)
+      {
+        sb.append(" throws ").append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    return sb.toString();
+  }
+
+  /**
+   * Invoke the method. Arguments are automatically unwrapped and widened,
+   * and the result is automatically wrapped, if needed.<p>
+   *
+   * If the method is static, <code>o</code> will be ignored. Otherwise,
+   * the method uses dynamic lookup as described in JLS 15.12.4.4. You cannot
+   * mimic the behavior of nonvirtual lookup (as in super.foo()). This means
+   * you will get a <code>NullPointerException</code> if <code>o</code> is
+   * null, and an <code>IllegalArgumentException</code> if it is incompatible
+   * with the declaring class of the method. If the method takes 0 arguments,
+   * you may use null or a 0-length array for <code>args</code>.<p>
+   *
+   * Next, if this Method enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not acces this method in similar compiled code. If the method
+   * is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the method is invoked. If it completes normally, the return value
+   * will be null for a void method, a wrapped object for a primitive return
+   * method, or the actual return of an Object method. If it completes
+   * abruptly, the exception is wrapped in an
+   * <code>InvocationTargetException</code>.
+   *
+   * @param o the object to invoke the method on
+   * @param args the arguments to the method
+   * @return the return value of the method, wrapped in the appropriate
+   *         wrapper if it is primitive
+   * @throws IllegalAccessException if the method could not normally be called
+   *         by the Java code (i.e. it is not public)
+   * @throws IllegalArgumentException if the number of arguments is incorrect;
+   *         if the arguments types are wrong even with a widening conversion;
+   *         or if <code>o</code> is not an instance of the class or interface
+   *         declaring this method
+   * @throws InvocationTargetException if the method throws an exception
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static method triggered
+   *         class initialization, which then failed
+   */
+  public Object invoke(Object o, Object... args)
+    throws IllegalAccessException, InvocationTargetException
+  {
+    return m.invoke(o, args, this);
+  }
+
+  /**
+   * Returns an array of <code>TypeVariable</code> objects that represents
+   * the type variables declared by this constructor, 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<Method>[] getTypeParameters()
+  {
+    if (p == null)
+      {
+	String sig = m.getSignature();
+	if (sig == null)
+	  return (TypeVariable<Method>[]) new TypeVariable[0];
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getTypeParameters();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the exception types declared by this method, in declaration order.
+   * An array of size zero is returned if this method declares no
+   * exceptions.
+   *
+   * @return the exception types declared by this method. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericExceptionTypes()
+  {
+    if (p == null)
+      {
+	String sig = m.getSignature();
+	if (sig == null)
+	  return getExceptionTypes();
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericExceptionTypes();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the parameter list for this method, in declaration order.
+   * An array of size zero is returned if this method takes no
+   * parameters.
+   *
+   * @return a list of the types of the method's parameters
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericParameterTypes()
+  {
+    if (p == null)
+      {
+	String sig = m.getSignature();
+	if (sig == null)
+	  return getParameterTypes();
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericParameterTypes();
+  }
+
+  /**
+   * Returns the return type of this method.
+   *
+   * @return the return type of this method
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type getGenericReturnType()
+  {
+    if (p == null)
+      {
+	String sig = m.getSignature();
+	if (sig == null)
+	  return getReturnType();
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericReturnType();
+  }
+
+  /**
+   * If this method is an annotation method, returns the default
+   * value for the method.  If there is no default value, or if the
+   * method is not a member of an annotation type, returns null.
+   * Primitive types are wrapped.
+   *
+   * @throws TypeNotPresentException if the method returns a Class,
+   * and the class cannot be found
+   *
+   * @since 1.5
+   */
+  public Object getDefaultValue()
+  {
+    return m.getDefaultValue();
+  }
+
+  /**
+   * <p>
+   * Return an array of arrays representing the annotations on each
+   * of the method's parameters.  The outer array is aligned against
+   * the parameters of the method and is thus equal in length to
+   * the number of parameters (thus having a length zero if there are none).
+   * Each array element in the outer array contains an inner array which
+   * holds the annotations.  This array has a length of zero if the parameter
+   * has no annotations.
+   * </p>
+   * <p>
+   * The returned annotations are serialized.  Changing the annotations has
+   * no affect on the return value of future calls to this method.
+   * </p>
+   * 
+   * @return an array of arrays which represents the annotations used on the
+   *         parameters of this method.  The order of the array elements
+   *         matches the declaration order of the parameters.
+   * @since 1.5
+   */
+  public Annotation[][] getParameterAnnotations()
+  {
+    return m.getParameterAnnotations();
+  }
+
+  /**
+   * Returns the element's 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 element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+  {
+    return (T) m.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, 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 the element.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    return m.getDeclaredAnnotations();
+  }
+
+}
Index: libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Field.java
===================================================================
--- libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Field.java	(revision 0)
+++ libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Field.java	(revision 0)
@@ -0,0 +1,734 @@
+/* java.lang.reflect.Field - reflection of Java fields
+   Copyright (C) 1998, 2001, 2005, 2008 Free Software Foundation, Inc.
+
+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.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Field class represents a member variable of a class. It also allows
+ * dynamic access to a member, via reflection. This works for both
+ * static and instance fields. Operations on Field objects know how to
+ * do widening conversions, but throw {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Field regardless of location, but get and set access may be limited
+ * by Java language access controls. If you can't do it in the compiler, you
+ * can't normally do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Field
+extends AccessibleObject implements Member
+{
+  static final int FIELD_MODIFIERS
+    = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+      | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+      | Modifier.VOLATILE;
+
+  private FieldSignatureParser p;
+
+  final VMField f;
+
+  /**
+   * This class is uninstantiable outside the package.
+   */
+  Field(VMField f)
+  {
+    this.f = f;
+  }
+
+  /**
+   * Gets the class that declared this field, or the class where this field
+   * is a non-inherited member.
+   * @return the class that declared this member
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?> getDeclaringClass()
+  {
+    return (Class<?>) f.getDeclaringClass();
+  }
+
+  /**
+   * Gets the name of this field.
+   * @return the name of this field
+   */
+  public String getName()
+  {
+    return f.getName();
+  }
+
+  /**
+   * Gets the modifiers this field uses.  Use the <code>Modifier</code>
+   * class to interpret the values.  A field can only have a subset of the
+   * following modifiers: public, private, protected, static, final,
+   * transient, and volatile.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public int getModifiers()
+  {
+    return f.getModifiersInternal() & FIELD_MODIFIERS;
+  }
+
+  /**
+   * Return true if this field is synthetic, false otherwise.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (f.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this field represents an enum constant,
+   * false otherwise.
+   * @since 1.5
+   */
+  public boolean isEnumConstant()
+  {
+    return (f.getModifiersInternal() & Modifier.ENUM) != 0;
+  }
+
+  /**
+   * Gets the type of this field.
+   * @return the type of this field
+   */
+  public Class<?> getType()
+  {
+    return f.getType();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Fields are semantically equivalent if they have the same declaring
+   * class, name, and type. Since you can't creat a Field except through
+   * the VM, this is just the == relation.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not
+   */
+  public boolean equals(Object o)
+  {
+    return (o instanceof Field) && f.equals(((Field)o).f);
+  }
+
+  /**
+   * Get the hash code for the Field. The Field hash code is the hash code
+   * of its name XOR'd with the hash code of its class name.
+   *
+   * @return the hash code for the object.
+   */
+  public int hashCode()
+  {
+    return f.getDeclaringClass().getName().hashCode() ^ f.getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Field. A Field's String
+   * representation is "&lt;modifiers&gt; &lt;type&gt;
+   * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+   * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+   *
+   * @return the String representation of the Field
+   */
+  public String toString()
+  {
+    // 64 is a reasonable buffer initial size for field
+    CPStringBuilder sb = new CPStringBuilder(64);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(ClassHelper.getUserName(getType())).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  public String toGenericString()
+  {
+    CPStringBuilder sb = new CPStringBuilder(64);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getGenericType()).append(' ');
+    sb.append(getDeclaringClass().getName()).append('.');
+    sb.append(getName());
+    return sb.toString();
+  }
+
+  /**
+   * Get the value of this Field.  If it is primitive, it will be wrapped
+   * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+   *
+   * If the field is static, <code>o</code> will be ignored. Otherwise, if
+   * <code>o</code> is null, you get a <code>NullPointerException</code>,
+   * and if it is incompatible with the declaring class of the field, you
+   * get an <code>IllegalArgumentException</code>.<p>
+   *
+   * Next, if this Field enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not access this field in similar compiled code. If the field
+   * is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the field is accessed, and primitives are wrapped (but not
+   * necessarily in new objects). This method accesses the field of the
+   * declaring class, even if the instance passed in belongs to a subclass
+   * which declares another field to hide this one.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if <code>o</code> is not an instance of
+   *         the class or interface declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #getBoolean(Object)
+   * @see #getByte(Object)
+   * @see #getChar(Object)
+   * @see #getShort(Object)
+   * @see #getInt(Object)
+   * @see #getLong(Object)
+   * @see #getFloat(Object)
+   * @see #getDouble(Object)
+   */
+  public Object get(Object o)
+    throws IllegalAccessException
+  {
+    return f.get(o, this);
+  }
+
+  /**
+   * Get the value of this boolean Field. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a boolean field of
+   *         <code>o</code>, or if <code>o</code> is not an instance of the
+   *         declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public boolean getBoolean(Object o)
+    throws IllegalAccessException
+  {
+    return f.getBoolean(o, this);
+  }
+
+  /**
+   * Get the value of this byte Field. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte field of
+   *         <code>o</code>, or if <code>o</code> is not an instance of the
+   *         declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public byte getByte(Object o)
+    throws IllegalAccessException
+  {
+    return f.getByte(o, this);
+  }
+
+  /**
+   * Get the value of this Field as a char. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a char field of
+   *         <code>o</code>, or if <code>o</code> is not an instance
+   *         of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public char getChar(Object o)
+    throws IllegalAccessException
+  {
+    return f.getChar(o, this);
+  }
+
+  /**
+   * Get the value of this Field as a short. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte or short
+   *         field of <code>o</code>, or if <code>o</code> is not an instance
+   *         of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public short getShort(Object o)
+    throws IllegalAccessException
+  {
+    return f.getShort(o, this);
+  }
+
+  /**
+   * Get the value of this Field as an int. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, or
+   *         int field of <code>o</code>, or if <code>o</code> is not an
+   *         instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public int getInt(Object o)
+    throws IllegalAccessException
+  {
+    return f.getInt(o, this);
+  }
+
+  /**
+   * Get the value of this Field as a long. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         or long field of <code>o</code>, or if <code>o</code> is not an
+   *         instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public long getLong(Object o)
+    throws IllegalAccessException
+  {
+    return f.getLong(o, this);
+  }
+
+  /**
+   * Get the value of this Field as a float. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         long, or float field of <code>o</code>, or if <code>o</code> is
+   *         not an instance of the declaring class of this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public float getFloat(Object o)
+    throws IllegalAccessException
+  {
+    return f.getFloat(o, this);
+  }
+
+  /**
+   * Get the value of this Field as a double. If the field is static,
+   * <code>o</code> will be ignored.
+   *
+   * @param o the object to get the value of this Field from
+   * @return the value of the Field
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, char, int,
+   *         long, float, or double field of <code>o</code>, or if
+   *         <code>o</code> is not an instance of the declaring class of this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #get(Object)
+   */
+  public double getDouble(Object o)
+    throws IllegalAccessException
+  {
+    return f.getDouble(o, this);
+  }
+
+  /**
+   * Set the value of this Field.  If it is a primitive field, the value
+   * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+   *
+   * If the field is static, <code>o</code> will be ignored. Otherwise, if
+   * <code>o</code> is null, you get a <code>NullPointerException</code>,
+   * and if it is incompatible with the declaring class of the field, you
+   * get an <code>IllegalArgumentException</code>.<p>
+   *
+   * Next, if this Field enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not access this field in similar compiled code. This also
+   * occurs whether or not there is access control if the field is final.
+   * If the field is primitive, and unwrapping your argument fails, you will
+   * get an <code>IllegalArgumentException</code>; likewise, this error
+   * happens if <code>value</code> cannot be cast to the correct object type.
+   * If the field is static, and its class is uninitialized, you trigger class
+   * initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Finally, the field is set with the widened value. This method accesses
+   * the field of the declaring class, even if the instance passed in belongs
+   * to a subclass which declares another field to hide this one.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if <code>value</code> cannot be
+   *         converted by a widening conversion to the underlying type of
+   *         the Field, or if <code>o</code> is not an instance of the class
+   *         declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #setBoolean(Object, boolean)
+   * @see #setByte(Object, byte)
+   * @see #setChar(Object, char)
+   * @see #setShort(Object, short)
+   * @see #setInt(Object, int)
+   * @see #setLong(Object, long)
+   * @see #setFloat(Object, float)
+   * @see #setDouble(Object, double)
+   */
+  public void set(Object o, Object value)
+    throws IllegalAccessException
+  {
+    f.set(o, value, this);
+  }
+
+  /**
+   * Set this boolean Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a boolean field, or if
+   *         <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setBoolean(Object o, boolean value)
+    throws IllegalAccessException
+  {
+    f.setBoolean(o, value, this);
+  }
+
+  /**
+   * Set this byte Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a byte, short, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setByte(Object o, byte value)
+    throws IllegalAccessException
+  {
+    f.setByte(o, value, this);
+  }
+
+  /**
+   * Set this char Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a char, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setChar(Object o, char value)
+    throws IllegalAccessException
+  {
+    f.setChar(o, value, this);
+  }
+
+  /**
+   * Set this short Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a short, int, long,
+   *         float, or double field, or if <code>o</code> is not an instance
+   *         of the class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setShort(Object o, short value)
+    throws IllegalAccessException
+  {
+    f.setShort(o, value, this);
+  }
+
+  /**
+   * Set this int Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not an int, long, float, or
+   *         double field, or if <code>o</code> is not an instance of the
+   *         class declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setInt(Object o, int value)
+    throws IllegalAccessException
+  {
+    f.setInt(o, value, this);
+  }
+
+  /**
+   * Set this long Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a long, float, or double
+   *         field, or if <code>o</code> is not an instance of the class
+   *         declaring this field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setLong(Object o, long value)
+    throws IllegalAccessException
+  {
+    f.setLong(o, value, this);
+  }
+
+  /**
+   * Set this float Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a float or long field, or
+   *         if <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setFloat(Object o, float value)
+    throws IllegalAccessException
+  {
+    f.setFloat(o, value, this);
+  }
+
+  /**
+   * Set this double Field. If the field is static, <code>o</code> will be
+   * ignored.
+   *
+   * @param o the object to set this Field on
+   * @param value the value to set this Field to
+   * @throws IllegalAccessException if you could not normally access this field
+   *         (i.e. it is not public)
+   * @throws IllegalArgumentException if this is not a double field, or if
+   *         <code>o</code> is not an instance of the class declaring this
+   *         field
+   * @throws NullPointerException if <code>o</code> is null and this field
+   *         requires an instance
+   * @throws ExceptionInInitializerError if accessing a static field triggered
+   *         class initialization, which then failed
+   * @see #set(Object, Object)
+   */
+  public void setDouble(Object o, double value)
+    throws IllegalAccessException
+  {
+    f.setDouble(o, value, this);
+  }
+
+  /**
+   * Return the generic type of the field. If the field type is not a generic
+   * type, the method returns the same as <code>getType()</code>.
+   *
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type getGenericType()
+  {
+    if (p == null)
+      {
+	String signature = f.getSignature();
+	if (signature == null)
+	  return getType();
+	p = new FieldSignatureParser(getDeclaringClass(),
+				     signature);
+      }
+    return p.getFieldType();
+  }
+
+  /**
+   * Returns the element's 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 element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+  {
+    return (T) f.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, 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 the element.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    return f.getDeclaredAnnotations();
+  }
+
+}
Index: libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Constructor.java
===================================================================
--- libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Constructor.java	(revision 0)
+++ libraryInterface/GNUClasspath/LGPL/src/java/lang/reflect/Constructor.java	(revision 0)
@@ -0,0 +1,449 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+   Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+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.reflect;
+
+import gnu.java.lang.ClassHelper;
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type.  They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc.  These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class.  It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor<T>
+  extends AccessibleObject
+  implements GenericDeclaration, Member
+{  
+  private static final int CONSTRUCTOR_MODIFIERS
+    = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+  private MethodSignatureParser p;
+
+  final VMConstructor cons;
+
+  /**
+   * This class is uninstantiable outside this package.
+   */
+  Constructor(VMConstructor cons)
+  {
+    this.cons = cons;
+  }
+
+  private Constructor()
+  {
+    this.cons = null;
+  }
+
+  /**
+   * Gets the class that declared this constructor.
+   * @return the class that declared this member
+   */
+  @SuppressWarnings("unchecked")
+  public Class<T> getDeclaringClass()
+  {
+    return (Class<T>) cons.getDeclaringClass();
+  }
+
+  /**
+   * Gets the name of this constructor (the non-qualified name of the class
+   * it was declared in).
+   * @return the name of this constructor
+   */
+  public String getName()
+  {
+    return cons.getDeclaringClass().getName();
+  }
+
+  /**
+   * Gets the modifiers this constructor uses.  Use the <code>Modifier</code>
+   * class to interpret the values. A constructor can only have a subset of the
+   * following modifiers: public, private, protected.
+   *
+   * @return an integer representing the modifiers to this Member
+   * @see Modifier
+   */
+  public int getModifiers()
+  {
+    return cons.getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+  }
+
+  /**
+   * Return true if this constructor is synthetic, false otherwise.
+   * A synthetic member is one which is created by the compiler,
+   * and which does not appear in the user's source code.
+   * @since 1.5
+   */
+  public boolean isSynthetic()
+  {
+    return (cons.getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+  }
+
+  /**
+   * Return true if this is a varargs constructor, that is if
+   * the constructor takes a variable number of arguments.
+   * @since 1.5
+   */
+  public boolean isVarArgs()
+  {
+    return (cons.getModifiersInternal() & Modifier.VARARGS) != 0;
+  }
+
+  /**
+   * Get the parameter list for this constructor, in declaration order. If the
+   * constructor takes no parameters, returns a 0-length array (not null).
+   *
+   * @return a list of the types of the constructor's parameters
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getParameterTypes()
+  {
+    return (Class<?>[]) cons.getParameterTypes();
+  }
+
+  /**
+   * Get the exception types this constructor says it throws, in no particular
+   * order. If the constructor has no throws clause, returns a 0-length array
+   * (not null).
+   *
+   * @return a list of the types in the constructor's throws clause
+   */
+  @SuppressWarnings("unchecked")
+  public Class<?>[] getExceptionTypes()
+  {
+    return (Class<?>[]) cons.getExceptionTypes();
+  }
+
+  /**
+   * Compare two objects to see if they are semantically equivalent.
+   * Two Constructors are semantically equivalent if they have the same
+   * declaring class and the same parameter list.  This ignores different
+   * exception clauses, but since you can't create a Method except through the
+   * VM, this is just the == relation.
+   *
+   * @param o the object to compare to
+   * @return <code>true</code> if they are equal; <code>false</code> if not.
+   */
+  public boolean equals(Object o)
+  {
+    return cons.equals(o);
+  }
+
+  /**
+   * Get the hash code for the Constructor. The Constructor hash code is the
+   * hash code of the declaring class's name.
+   *
+   * @return the hash code for the object
+   */
+  public int hashCode()
+  {
+    return getName().hashCode();
+  }
+
+  /**
+   * Get a String representation of the Constructor. A Constructor's String
+   * representation is "&lt;modifier&gt; &lt;classname&gt;(&lt;paramtypes&gt;)
+   * throws &lt;exceptions&gt;", where everything after ')' is omitted if
+   * there are no exceptions.<br> Example:
+   * <code>public java.io.FileInputStream(java.lang.Runnable)
+   * throws java.io.FileNotFoundException</code>
+   *
+   * @return the String representation of the Constructor
+   */
+  public String toString()
+  {
+    // 128 is a reasonable buffer initial size for constructor
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    sb.append(getDeclaringClass().getName()).append('(');
+    Class[] c = getParameterTypes();
+    if (c.length > 0)
+      {
+        sb.append(ClassHelper.getUserName(c[0]));
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(ClassHelper.getUserName(c[i]));
+      }
+    sb.append(')');
+    c = getExceptionTypes();
+    if (c.length > 0)
+      {
+        sb.append(" throws ").append(c[0].getName());
+        for (int i = 1; i < c.length; i++)
+          sb.append(',').append(c[i].getName());
+      }
+    return sb.toString();
+  }
+
+  static <X extends GenericDeclaration>
+  void addTypeParameters(CPStringBuilder sb, TypeVariable<X>[] typeArgs)
+  {
+    if (typeArgs.length == 0)
+      return;
+    sb.append('<');
+    for (int i = 0; i < typeArgs.length; ++i)
+      {
+        if (i > 0)
+          sb.append(',');
+        sb.append(typeArgs[i]);
+      }
+    sb.append("> ");
+  }
+
+  public String toGenericString()
+  {
+    CPStringBuilder sb = new CPStringBuilder(128);
+    Modifier.toString(getModifiers(), sb).append(' ');
+    addTypeParameters(sb, getTypeParameters());
+    sb.append(getDeclaringClass().getName()).append('(');
+    Type[] types = getGenericParameterTypes();
+    if (types.length > 0)
+      {
+        sb.append(types[0]);
+        for (int i = 1; i < types.length; ++i)
+          sb.append(',').append(types[i]);
+      }
+    sb.append(')');
+    types = getGenericExceptionTypes();
+    if (types.length > 0)
+      {
+        sb.append(" throws ").append(types[0]);
+        for (int i = 1; i < types.length; i++)
+          sb.append(',').append(types[i]);
+      }
+    return sb.toString();
+  }
+
+  /**
+   * Create a new instance by invoking the constructor. Arguments are
+   * automatically unwrapped and widened, if needed.<p>
+   *
+   * If this class is abstract, you will get an
+   * <code>InstantiationException</code>. If the constructor takes 0
+   * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+   *
+   * If this Constructor enforces access control, your runtime context is
+   * evaluated, and you may have an <code>IllegalAccessException</code> if
+   * you could not create this object in similar compiled code. If the class
+   * is uninitialized, you trigger class initialization, which may end in a
+   * <code>ExceptionInInitializerError</code>.<p>
+   *
+   * Then, the constructor is invoked. If it completes normally, the return
+   * value will be the new object. If it completes abruptly, the exception is
+   * wrapped in an <code>InvocationTargetException</code>.
+   *
+   * @param args the arguments to the constructor
+   * @return the newly created object
+   * @throws IllegalAccessException if the constructor could not normally be
+   *         called by the Java code (i.e. it is not public)
+   * @throws IllegalArgumentException if the number of arguments is incorrect;
+   *         or if the arguments types are wrong even with a widening
+   *         conversion
+   * @throws InstantiationException if the class is abstract
+   * @throws InvocationTargetException if the constructor throws an exception
+   * @throws ExceptionInInitializerError if construction triggered class
+   *         initialization, which then failed
+   */
+  @SuppressWarnings("unchecked")
+  public T newInstance(Object... args)
+    throws InstantiationException, IllegalAccessException,
+           InvocationTargetException
+  {
+    return (T) cons.construct(args, this);
+  }
+
+  /**
+   * Returns an array of <code>TypeVariable</code> objects that represents
+   * the type variables declared by this constructor, in declaration order.
+   * An array of size zero is returned if this constructor has no type
+   * variables.
+   *
+   * @return the type variables associated with this constructor.
+   * @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<Constructor<T>>[] getTypeParameters()
+  {
+    if (p == null)
+      {
+	String sig = cons.getSignature();
+	if (sig == null)
+	  return new TypeVariable[0];
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getTypeParameters();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the exception types declared by this constructor, in declaration order.
+   * An array of size zero is returned if this constructor declares no
+   * exceptions.
+   *
+   * @return the exception types declared by this constructor. 
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericExceptionTypes()
+  {
+    if (p == null)
+      {
+	String sig = cons.getSignature();
+	if (sig == null)
+	  return getExceptionTypes();
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericExceptionTypes();
+  }
+
+  /**
+   * Returns an array of <code>Type</code> objects that represents
+   * the parameter list for this constructor, in declaration order.
+   * An array of size zero is returned if this constructor takes no
+   * parameters.
+   *
+   * @return a list of the types of the constructor's parameters
+   * @throws GenericSignatureFormatError if the generic signature does
+   *         not conform to the format specified in the Virtual Machine
+   *         specification, version 3.
+   * @since 1.5
+   */
+  public Type[] getGenericParameterTypes()
+  {
+    if (p == null)
+      {
+	String sig = cons.getSignature();
+	if (sig == null)
+	  return getParameterTypes();
+	p = new MethodSignatureParser(this, sig);
+      }
+    return p.getGenericParameterTypes();
+  }
+
+  /**
+   * <p>
+   * Return an array of arrays representing the annotations on each
+   * of the constructor's parameters.  The outer array is aligned against
+   * the parameters of the constructors and is thus equal in length to
+   * the number of parameters (thus having a length zero if there are none).
+   * Each array element in the outer array contains an inner array which
+   * holds the annotations.  This array has a length of zero if the parameter
+   * has no annotations.
+   * </p>
+   * <p>
+   * The returned annotations are serialized.  Changing the annotations has
+   * no affect on the return value of future calls to this method.
+   * </p>
+   * 
+   * @return an array of arrays which represents the annotations used on the
+   *         parameters of this constructor.  The order of the array elements
+   *         matches the declaration order of the parameters.
+   * @since 1.5
+   */
+  public Annotation[][] getParameterAnnotations()
+  {
+    return cons.getParameterAnnotations();
+  }
+
+  /**
+   * Returns the element's 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 element's annotation for the specified type, or
+   *         <code>null</code> if no such annotation exists.
+   * @throws NullPointerException if the annotation class is <code>null</code>.
+   */
+  @SuppressWarnings("unchecked")
+  public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+  {
+    return (T) cons.getAnnotation(annotationClass);
+  }
+
+  /**
+   * Returns all annotations directly defined by the element.  If there are
+   * no annotations directly associated with the element, 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 the element.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    return cons.getDeclaredAnnotations();
+  }
+
+}
Index: build.xml
===================================================================
--- build.xml	(revision 14213)
+++ build.xml	(working copy)
@@ -925,7 +925,7 @@
     </javac>
 
     <mkdir dir="${build.base}/syscall/java"/>
-    <exec executable="apt" failonerror="true">
+    <exec executable="/tmp/jdk1.6.0_05/bin/apt" failonerror="true">
       <arg value="-factorypath"/>
       <arg value="${tasks.classes}"/>
       <arg value="-nocompile"/>
Index: rvm/src-generated/opt-ir/InstructionFormatList.dat
===================================================================
--- rvm/src-generated/opt-ir/InstructionFormatList.dat	(revision 14213)
+++ rvm/src-generated/opt-ir/InstructionFormatList.dat	(working copy)
@@ -308,6 +308,12 @@
 "U InlinedTypeInfo InlinedOsrTypeInfoOperand"
 "Element Operand"
 
+ReflectiveCall
+1 0 5
+"D Result RegisterOperand" \
+"U Method Operand" "U ThisArg Operand" "U OtherArgs Operand" " U IsNonVirtual Operand" "U Guard Operand opt"
+
+
 # Bogus instruction format only used by template generation code.
 ARCH_INDEPENDENT_INSTR_FORMAT_END
 0 0 0 0 0
Index: rvm/src-generated/opt-ir/OperatorList.dat
===================================================================
--- rvm/src-generated/opt-ir/OperatorList.dat	(revision 14213)
+++ rvm/src-generated/opt-ir/OperatorList.dat	(working copy)
@@ -1486,6 +1486,13 @@
 callDefs
 callUses
 
+# HIR for a reflective method call
+REFLECTIVE_CALL
+ReflectiveCall
+call
+callDefs
+callUses
+
 # A call instruction.  Used for special system calls.
 # Is marked as a memory model load/store, but does not directly load/store any values itself.
 SYSCALL
Index: rvm/src/org/jikesrvm/jni/ia32/VM_JNIHelpers.java
===================================================================
--- rvm/src/org/jikesrvm/jni/ia32/VM_JNIHelpers.java	(revision 14213)
+++ rvm/src/org/jikesrvm/jni/ia32/VM_JNIHelpers.java	(working copy)
@@ -290,7 +290,7 @@
     }
 
     // now invoke the method
-    return VM_Reflection.invoke(targetMethod, obj, argObjectArray, skip4Args);
+    return java.lang.reflect.VMMember.performInvoke(targetMethod, obj, argObjectArray, null);//VM_Reflection.invoke(targetMethod, obj, argObjectArray, skip4Args);
   }
 
   /**
Index: rvm/src/org/jikesrvm/runtime/VM_Entrypoints.java
===================================================================
--- rvm/src/org/jikesrvm/runtime/VM_Entrypoints.java	(revision 14213)
+++ rvm/src/org/jikesrvm/runtime/VM_Entrypoints.java	(working copy)
@@ -39,6 +39,13 @@
   public static final VM_Method java_lang_reflect_Method_invokeMethod =
       getMethod(java.lang.reflect.Method.class, "invoke",
           "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
+  public static final VM_Method org_jikesrvm_runtime_VM_Reflection_invokeMethod =
+      getMethod(org.jikesrvm.runtime.VM_Reflection.class, "invoke",
+          "(Lorg/jikesrvm/classloader/VM_Method;Ljava/lang/Object;[Ljava/lang/Object;Z)Ljava/lang/Object;");
+  public static final VM_Method getClassFromStackFrame =
+    getMethod(org.jikesrvm.classloader.VM_Class.class, "getClassFromStackFrame", "(I)Lorg/jikesrvm/classloader/VM_Class;");
+  public static final VM_Method getClassLoaderFromStackFrame =
+    getMethod(org.jikesrvm.classloader.VM_Class.class, "getClassLoaderFromStackFrame", "(I)Ljava/lang/ClassLoader;");
 
   public static final VM_Field magicObjectRemapperField =
       getField(org.jikesrvm.runtime.VM_Magic.class,
Index: rvm/src/org/jikesrvm/runtime/VM_Reflection.java
===================================================================
--- rvm/src/org/jikesrvm/runtime/VM_Reflection.java	(revision 14213)
+++ rvm/src/org/jikesrvm/runtime/VM_Reflection.java	(working copy)
@@ -30,6 +30,9 @@
  */
 public class VM_Reflection implements VM_Constants {
 
+  /** Have unwrapper dynamic link sites been resolved?  */
+  private static boolean firstUse = true;
+
   /**
    * Call a method.
    * @param method method to be called
@@ -45,7 +48,10 @@
     return invoke(method, thisArg, otherArgs, false);
   }
 
-  public static Object invoke(VM_Method method, Object thisArg, Object[] otherArgs, boolean isNonvirtual) {
+  public static Object invoke(VM_Method method, Object thisArg, Object[] otherArgs, boolean isNonvirtual) {    
+    if (firstUse) {
+      forceUnwrapResolution();
+    }
 
     // the class must be initialized before we can invoke a method
     //
@@ -72,34 +78,20 @@
 
     int spillCount = triple >> (REFLECTION_GPRS_BITS + REFLECTION_FPRS_BITS);
 
-    WordArray Spills = WordArray.create(spillCount);
+    WordArray Spills = WordArray.create(spillCount); 
 
-    if (firstUse) {
-      // force dynamic link sites in unwrappers to get resolved,
-      // before disabling gc.
-      // this is a bit silly, but I can't think of another way to do it [--DL]
-      unwrapBoolean(wrapBoolean(0));
-      unwrapByte(wrapByte((byte) 0));
-      unwrapChar(wrapChar((char) 0));
-      unwrapShort(wrapShort((short) 0));
-      unwrapInt(wrapInt(0));
-      unwrapLong(wrapLong((long) 0));
-      unwrapFloat(wrapFloat((float) 0));
-      unwrapDouble(wrapDouble((double) 0));
-      firstUse = false;
-    }
 
     // choose actual method to be called
     //
     VM_Method targetMethod;
-    if (method.isStatic() || method.isObjectInitializer() || isNonvirtual) {
+    if (isNonvirtual || method.isStatic() || method.isObjectInitializer()) {
       targetMethod = method;
     } else {
       int tibIndex = method.getOffset().toInt() >>> LOG_BYTES_IN_ADDRESS;
       targetMethod =
           VM_Magic.getObjectType(thisArg).asClass().getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX];
     }
-
+ 
     // getCurrentCompiledMethod is synchronized but Unpreemptible.
     // Therefore there are no possible yieldpoints from the time
     // the compiledMethod is loaded in getCurrentCompiledMethod
@@ -173,6 +165,23 @@
     return null;
   }
 
+  /**
+   * Force dynamic link sites in unwrappers to get resolved, before disabling
+   * gc. this is a bit silly, but I can't think of another way to do it [--DL]
+   */
+  @NoInline
+  private static void forceUnwrapResolution() {
+    unwrapBoolean(wrapBoolean(0));
+    unwrapByte(wrapByte((byte) 0));
+    unwrapChar(wrapChar((char) 0));
+    unwrapShort(wrapShort((short) 0));
+    unwrapInt(wrapInt(0));
+    unwrapLong(wrapLong((long) 0));
+    unwrapFloat(wrapFloat((float) 0));
+    unwrapDouble(wrapDouble((double) 0));
+    firstUse = false;
+  }
+
   // Method parameter wrappers.
   //
   @NoInline
@@ -236,6 +245,4 @@
 
   @NoInline
   public static Address unwrapObject(Object o) { return VM_Magic.objectAsAddress(o); }
-
-  private static boolean firstUse = true;
 }
Index: rvm/src/org/jikesrvm/classloader/VM_TypeReference.java
===================================================================
--- rvm/src/org/jikesrvm/classloader/VM_TypeReference.java	(revision 14213)
+++ rvm/src/org/jikesrvm/classloader/VM_TypeReference.java	(working copy)
@@ -123,6 +123,15 @@
 
   public static final VM_TypeReference JavaLangObjectArray = findOrCreate(java.lang.Object[].class);
 
+  public static final VM_TypeReference JavaLangBoolean = findOrCreate(java.lang.Boolean.class);
+  public static final VM_TypeReference JavaLangByte = findOrCreate(java.lang.Byte.class);
+  public static final VM_TypeReference JavaLangShort = findOrCreate(java.lang.Short.class);
+  public static final VM_TypeReference JavaLangCharacter = findOrCreate(java.lang.Character.class);
+  public static final VM_TypeReference JavaLangInteger = findOrCreate(java.lang.Integer.class);
+  public static final VM_TypeReference JavaLangLong = findOrCreate(java.lang.Long.class);
+  public static final VM_TypeReference JavaLangFloat = findOrCreate(java.lang.Float.class);
+  public static final VM_TypeReference JavaLangDouble = findOrCreate(java.lang.Double.class);
+
   public static final VM_TypeReference JavaLangThrowable = findOrCreate(java.lang.Throwable.class);
   public static final VM_TypeReference JavaLangError = findOrCreate(java.lang.Error.class);
   public static final VM_TypeReference JavaLangNullPointerException =
Index: rvm/src/org/jikesrvm/classloader/VM_Class.java
===================================================================
--- rvm/src/org/jikesrvm/classloader/VM_Class.java	(revision 14213)
+++ rvm/src/org/jikesrvm/classloader/VM_Class.java	(working copy)
@@ -614,7 +614,7 @@
   //
 
   @Uninterruptible
-  private static int packCPEntry(byte type, int value) {
+  static int packCPEntry(byte type, int value) {
     return (type << 29) | (value & 0x1fffffff);
   }
 
@@ -2475,6 +2475,36 @@
     }
   }
 
+
+  private static int numberOfReflectionClasses = 0;
+  
+  public static Class createReflectionClass(VM_Method methodToCall) {
+    int[] constantPool = new int[methodToCall.getParameterTypes().length+3];
+    VM_TypeReference reflectionClass = VM_TypeReference.findOrCreate("Lorg/jikesrvm/classloader/ReflectionBase$$Reflect"+numberOfReflectionClasses+";");
+    numberOfReflectionClasses++;
+    VM_MethodReference reflectionMethodRef = VM_MethodReference.findOrCreate(reflectionClass,
+                                                                             VM_Atom.findOrCreateUnicodeAtom("invoke"),
+                                                                             VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")
+                                                                             ).asMethodReference();
+    VM_MethodReference constructorMethodRef = VM_MethodReference.findOrCreate(reflectionClass,
+                                                                              VM_Atom.findOrCreateUnicodeAtom("<init>"),
+                                                                              VM_Atom.findOrCreateUnicodeAtom("()V")
+                                                                             ).asMethodReference();
+    
+    VM_Method[] reflectionMethods = new VM_Method[]{methodToCall.createReflectionMethod(reflectionClass,
+                                                                                        constantPool,
+                                                                                        reflectionMethodRef),
+                                                    VM_Method.createDefaultConstructor(reflectionClass, constructorMethodRef)};
+    VM_Class klass =
+      new VM_Class(reflectionClass, constantPool, (short) (ACC_SYNTHETIC | ACC_PUBLIC | ACC_FINAL), // modifiers
+                   VM_Method.baseReflectionClass.resolve().asClass(), // superClass
+                   emptyVMClass, // declaredInterfaces
+                   emptyVMField, reflectionMethods,
+                   null, null, null, null, null, null, null, null);
+    reflectionClass.setType(klass);
+    return klass.getClassForType();
+  }
+
   /**
    * Number of [ in descriptor for arrays; -1 for primitives; 0 for
    * classes
Index: rvm/src/org/jikesrvm/classloader/VM_Method.java
===================================================================
--- rvm/src/org/jikesrvm/classloader/VM_Method.java	(revision 14213)
+++ rvm/src/org/jikesrvm/classloader/VM_Method.java	(working copy)
@@ -15,6 +15,8 @@
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import org.jikesrvm.ArchitectureSpecific.VM_CodeArray;
 import org.jikesrvm.ArchitectureSpecific.VM_LazyCompilationTrampoline;
 import org.jikesrvm.VM;
@@ -23,6 +25,8 @@
 import org.jikesrvm.runtime.VM_Entrypoints;
 import org.jikesrvm.runtime.VM_Statics;
 import org.jikesrvm.util.VM_HashMap;
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.NoInline;
 import org.vmmagic.pragma.Pure;
 import org.vmmagic.pragma.Uninterruptible;
 import org.vmmagic.pragma.Unpreemptible;
@@ -115,7 +119,7 @@
    * Get the annotation default value for an annotation method
    */
   @Pure
-  Object getAnnotationDefault() {
+  public Object getAnnotationDefault() {
     synchronized(annotationDefaults) {
       return annotationDefaults.get(this);
     }
@@ -345,7 +349,194 @@
                                null);
   }
 
+  static VM_Method createDefaultConstructor(VM_TypeReference klass, VM_MemberReference memRef) {
+    return new VM_NormalMethod(klass,
+                               memRef,
+                               (short) (ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC),
+                               null,
+                               (short) 1,
+                               (short) 0,
+                               new byte[]{(byte)JBC_return},
+                               null,
+                               null,
+                               new int[0],
+                               null,
+                               null,
+                               null,
+                               null);
+  }
+
+  static final VM_TypeReference baseReflectionClass = VM_TypeReference.findOrCreate(ReflectionBase.class);
+  
   /**
+   * Create a method for reflectively invoking this method
+   *
+   * @param reflectionClass the class this method will belong to
+   * @param constantPool for the class
+   * @param memRef the member reference corresponding to this method
+   * @param interfaceMethod the interface method that will copied to
+   * produce the annotation method
+   * @param constantPoolIndex the index of the field that will be
+   * returned by this method
+   * @return the created method
+   */
+  VM_Method createReflectionMethod(VM_TypeReference reflectionClass, int[] constantPool,
+                                   VM_MethodReference memRef) {
+    VM_TypeReference[] parameters = getParameterTypes();
+    int numParams = parameters.length;
+    byte[] bytecodes;
+    int curBC = 0;
+    if (!isStatic()) {
+      bytecodes = new byte[8 * numParams + 8];
+      bytecodes[curBC] = JBC_aload_1;
+      curBC++;
+    } else {
+      bytecodes = new byte[8 * numParams + 7];
+    }
+    for (int i=0; i < numParams; i++) {
+      if (parameters[i].isVoidType()) {
+        bytecodes[curBC+1] = 
+          bytecodes[curBC+2] = 
+          bytecodes[curBC+3] = 
+          bytecodes[curBC+4] =
+          bytecodes[curBC+5] =
+          bytecodes[curBC+6] =
+          bytecodes[curBC+7] =
+            (byte)JBC_nop;
+        continue;
+      }
+      bytecodes[curBC] = (byte)JBC_aload_2;
+      bytecodes[curBC+1] = (byte)JBC_sipush;
+      bytecodes[curBC+2] = (byte)(i >>> 8);
+      bytecodes[curBC+3] = (byte)i;
+      bytecodes[curBC+4] = (byte)JBC_aaload;
+      if (!parameters[i].isPrimitiveType()) {
+        bytecodes[curBC+5] = (byte)JBC_checkcast;
+        if (VM.VerifyAssertions) VM._assert(parameters[i].getId() != 0);
+        constantPool[i+1] = VM_Class.packCPEntry(VM_Class.CP_CLASS, parameters[i].getId());
+        bytecodes[curBC+6] = (byte)((i+1) >>> 8);
+        bytecodes[curBC+7] = (byte)(i+1);
+      } else {
+        bytecodes[curBC+5] = (byte)JBC_invokestatic;
+        VM_MemberReference unboxMethod;
+        if (parameters[i].isBooleanType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsBoolean"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)Z"));
+        } else if (parameters[i].isByteType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsByte"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)B"));
+        } else if (parameters[i].isShortType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsShort"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)S"));
+        } else if (parameters[i].isCharType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsChar"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)C"));
+        } else if (parameters[i].isIntType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsInt"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)I"));
+        } else if (parameters[i].isLongType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsLong"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)J"));
+        } else if (parameters[i].isFloatType()) {
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsFloat"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)F"));
+        } else {
+          if (VM.VerifyAssertions) VM._assert (parameters[i].isDoubleType());
+          unboxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                        VM_Atom.findOrCreateUnicodeAtom("unboxAsDouble"),
+                                                        VM_Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)D"));
+        }
+        constantPool[i+1] = VM_Class.packCPEntry(VM_Class.CP_MEMBER, unboxMethod.getId());
+        bytecodes[curBC+6] = (byte)((i+1) >>> 8);
+        bytecodes[curBC+7] = (byte)(i+1);
+      }
+      curBC+=8;
+    }
+    if (isStatic()) {
+      bytecodes[curBC] = (byte)JBC_invokestatic;
+    } else if (isObjectInitializer()) {
+      bytecodes[curBC] = (byte)JBC_invokespecial;
+    } else {
+      bytecodes[curBC] = (byte)JBC_invokevirtual;
+    }
+    constantPool[numParams+1] = VM_Class.packCPEntry(VM_Class.CP_MEMBER, getId());
+    bytecodes[curBC+1] = (byte)((numParams+1) >>> 8);
+    bytecodes[curBC+2] = (byte)(numParams+1);
+    VM_TypeReference returnType = getReturnType();
+    if (!returnType.isPrimitiveType()) {
+      bytecodes[curBC+3] = (byte)JBC_nop;
+      bytecodes[curBC+4] = (byte)JBC_nop;
+      bytecodes[curBC+5] = (byte)JBC_nop;
+    } else if (returnType.isVoidType()) {
+      bytecodes[curBC+3] = (byte)JBC_aconst_null;
+      bytecodes[curBC+4] = (byte)JBC_nop;
+      bytecodes[curBC+5] = (byte)JBC_nop;
+    } else {
+      VM_MemberReference boxMethod;
+      if (returnType.isBooleanType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsBoolean"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(Z)Ljava/lang/Object;"));
+      } else if (returnType.isByteType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsByte"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(B)Ljava/lang/Object;"));
+      } else if (returnType.isShortType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsShort"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(S)Ljava/lang/Object;"));
+      } else if (returnType.isCharType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsChar"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(C)Ljava/lang/Object;"));
+      } else if (returnType.isIntType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsInt"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(I)Ljava/lang/Object;"));
+      } else if (returnType.isLongType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsLong"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(J)Ljava/lang/Object;"));
+      } else if (returnType.isFloatType()) {
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsFloat"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(F)Ljava/lang/Object;"));
+      } else {
+        if (VM.VerifyAssertions) VM._assert (returnType.isDoubleType());
+        boxMethod = VM_MethodReference.findOrCreate(baseReflectionClass,
+                                                    VM_Atom.findOrCreateUnicodeAtom("boxAsDouble"),
+                                                    VM_Atom.findOrCreateUnicodeAtom("(D)Ljava/lang/Object;"));
+      }
+      constantPool[numParams+2] = VM_Class.packCPEntry(VM_Class.CP_MEMBER, boxMethod.getId());
+      bytecodes[curBC+3] = (byte)JBC_invokestatic;
+      bytecodes[curBC+4] = (byte)((numParams+2) >>> 8);
+      bytecodes[curBC+5] = (byte)(numParams+2);
+    }
+    bytecodes[curBC+6] = (byte)JBC_areturn;
+    return new VM_NormalMethod(reflectionClass,
+                               memRef,
+                               (short) (ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC),
+                               null,
+                               (short) 3,
+                               (short) (getParameterWords() + 2),
+                               bytecodes,
+                               null,
+                               null,
+                               constantPool,
+                               null,
+                               null,
+                               null,
+                               null);
+  }
+
+  /**
    * What would be the appropriate return bytecode for the given type
    * reference?
    */
Index: rvm/src/org/jikesrvm/classloader/ReflectionBase.java
===================================================================
--- rvm/src/org/jikesrvm/classloader/ReflectionBase.java	(revision 0)
+++ rvm/src/org/jikesrvm/classloader/ReflectionBase.java	(revision 0)
@@ -0,0 +1,133 @@
+/*
+ *  This file is part of the Jikes RVM project (http://jikesrvm.org).
+ *
+ *  This file is licensed to You under the Common Public License (CPL);
+ *  You may not use this file except in compliance with the License. You
+ *  may obtain a copy of the License at
+ *
+ *      http://www.opensource.org/licenses/cpl1.0.php
+ *
+ *  See the COPYRIGHT.txt file distributed with this work for information
+ *  regarding copyright ownership.
+ */
+package org.jikesrvm.classloader;
+
+import org.vmmagic.pragma.Inline;
+import org.vmmagic.pragma.NoInline;
+
+public abstract class ReflectionBase {
+
+  @NoInline
+  private static void throwIllegalArgumentException() throws IllegalArgumentException {
+    throw new IllegalArgumentException();
+  }
+
+  @Inline
+  protected static boolean unboxAsBoolean(Object obj) {
+    if (!(obj instanceof Boolean)) {
+      throwIllegalArgumentException();
+    }
+    return ((Boolean)obj).booleanValue();
+  }
+
+  @Inline
+  protected static Object boxAsBoolean(boolean b) {
+    return (Boolean)b;
+  }
+
+  @Inline
+  protected static byte unboxAsByte(Object obj) {
+    if (!(obj instanceof Byte)) {
+      throwIllegalArgumentException();
+    }
+    return ((Byte)obj).byteValue();
+  }
+
+  @Inline
+  protected static Object boxAsByte(byte b) {
+    return (Byte)b;
+  }
+
+  @Inline
+  protected static short unboxAsShort(Object obj) {
+    if (!(obj instanceof Short) && !(obj instanceof Byte)) {
+      throwIllegalArgumentException();
+    }
+    return ((Number)obj).shortValue();
+  }
+
+  @Inline
+  protected static Object boxAsShort(short s) {
+    return (Short)s;
+  }
+
+  @Inline
+  protected static char unboxAsChar(Object obj) {
+    if (!(obj instanceof Character)) {
+      throwIllegalArgumentException();
+    }
+    return ((Character)obj).charValue();
+  }
+
+  @Inline
+  protected static Object boxAsChar(char c) {
+    return (Character)c;
+  }
+
+  @Inline
+  protected static int unboxAsInt(Object obj) {
+    if (!(obj instanceof Integer) && !(obj instanceof Character) &&
+        !(obj instanceof Short) && !(obj instanceof Byte)) {
+      throw new IllegalArgumentException();
+    }
+    return ((Number)obj).intValue();
+  }
+
+  @Inline
+  protected static Object boxAsInt(int i) {
+    return (Integer)i;
+  }
+
+  @Inline
+  protected static long unboxAsLong(Object obj) {
+    if (!(obj instanceof Long) && !(obj instanceof Integer) &&
+        !(obj instanceof Character) && (obj instanceof Short) &&
+        !(obj instanceof Byte)) {
+      throw new IllegalArgumentException();
+    }
+    return ((Number)obj).longValue();
+  }
+
+  @Inline
+  protected static Object boxAsLong(long l) {
+    return (Long)l;
+  }
+
+  @Inline
+  protected static float unboxAsFloat(Object obj) {
+    if (!(obj instanceof Float)) {
+      throw new IllegalArgumentException();
+    }
+    return ((Float)obj).floatValue();
+  }
+
+  @Inline
+  protected static Object boxAsFloat(float f) {
+    return (Float)f;
+  }
+
+  @Inline
+  protected static double unboxAsDouble(Object obj) {
+    if (!(obj instanceof Double) && !(obj instanceof Float)) {
+      throw new IllegalArgumentException();
+    }
+    return ((Number)obj).doubleValue();
+  }
+
+  @Inline
+  protected static Object boxAsDouble(double d) {
+    return (Double)d;
+  }
+
+  public abstract Object invoke(Object obj, Object[] args);
+}
Index: rvm/src/org/jikesrvm/compilers/opt/Simplifier.java
===================================================================
--- rvm/src/org/jikesrvm/compilers/opt/Simplifier.java	(revision 14213)
+++ rvm/src/org/jikesrvm/compilers/opt/Simplifier.java	(working copy)
@@ -22,13 +22,18 @@
 import java.lang.reflect.Method;
 
 import org.jikesrvm.VM;
+import org.jikesrvm.classloader.VM_Atom;
 import org.jikesrvm.classloader.VM_Field;
+import org.jikesrvm.classloader.VM_FieldReference;
+import org.jikesrvm.classloader.VM_MemberReference;
 import org.jikesrvm.classloader.VM_Method;
 import org.jikesrvm.classloader.VM_Type;
 import org.jikesrvm.classloader.VM_TypeReference;
 import org.jikesrvm.compilers.opt.driver.Constants;
 import org.jikesrvm.compilers.opt.hir2lir.ConvertToLowLevelIR;
+import org.jikesrvm.compilers.opt.inlining.InlineSequence;
 import org.jikesrvm.compilers.opt.ir.AbstractRegisterPool;
+import org.jikesrvm.compilers.opt.ir.ALoad;
 import org.jikesrvm.compilers.opt.ir.Binary;
 import org.jikesrvm.compilers.opt.ir.BooleanCmp;
 import org.jikesrvm.compilers.opt.ir.BoundsCheck;
@@ -44,6 +49,7 @@
 import org.jikesrvm.compilers.opt.ir.Load;
 import org.jikesrvm.compilers.opt.ir.Move;
 import org.jikesrvm.compilers.opt.ir.NullCheck;
+import org.jikesrvm.compilers.opt.ir.ReflectiveCall;
 import org.jikesrvm.compilers.opt.ir.Operator;
 import org.jikesrvm.compilers.opt.ir.OperatorNames;
 import org.jikesrvm.compilers.opt.ir.StoreCheck;
@@ -58,6 +64,7 @@
 import org.jikesrvm.compilers.opt.ir.operand.ConditionOperand;
 import org.jikesrvm.compilers.opt.ir.operand.ConstantOperand;
 import org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand;
+import org.jikesrvm.compilers.opt.ir.operand.LocationOperand;
 import org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand;
 import org.jikesrvm.compilers.opt.ir.operand.MethodOperand;
 import org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand;
@@ -522,6 +529,9 @@
       case CALL_opcode:
         result = call(hir, regpool, s);
         break;
+      case REFLECTIVE_CALL_opcode:
+        result = reflectiveCall(regpool, s);
+        break;
       case GETFIELD_opcode:
         result = getField(s);
         break;
@@ -3145,6 +3155,146 @@
     return DefUseEffect.UNCHANGED;
   }
 
+  private static void unboxArgument(Operand otherArgsOp, int i,
+      int numHiddenParams, VM_TypeReference[] params, Operand guardOp,
+      AbstractRegisterPool regpool, Instruction s) {
+    RegisterOperand unboxed = regpool.makeTemp(params[i]);
+    boolean needsUnboxing = false;
+    VM_TypeReference boxedType = null;
+    VM_FieldReference boxedFieldRef = null;
+    if (params[i] == VM_TypeReference.Boolean) {
+      boxedType = VM_TypeReference.JavaLangBoolean;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangBoolean,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("Z")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Byte) {
+      boxedType = VM_TypeReference.JavaLangByte;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangByte,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("B")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Short) {
+      boxedType = VM_TypeReference.JavaLangShort;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangShort,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("S")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Char) {
+      boxedType = VM_TypeReference.JavaLangCharacter;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangCharacter,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("C")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Int) {
+      boxedType = VM_TypeReference.JavaLangInteger;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangInteger,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("I")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Long) {
+      boxedType = VM_TypeReference.JavaLangLong;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangLong,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("J")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Float) {
+      boxedType = VM_TypeReference.JavaLangFloat;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangFloat,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("F")).asFieldReference();
+      needsUnboxing = true;
+    } else if (params[i] == VM_TypeReference.Double) {
+      boxedType = VM_TypeReference.JavaLangDouble;
+      boxedFieldRef = VM_MemberReference.findOrCreate(
+          VM_TypeReference.JavaLangDouble,
+          VM_Atom.findOrCreateUnicodeAtom("value"),
+          VM_Atom.findOrCreateUnicodeAtom("D")).asFieldReference();
+      needsUnboxing = true;
+    }
+    if (needsUnboxing) {
+      RegisterOperand temp = regpool.makeTemp(boxedType);
+      LocationOperand loc = new LocationOperand(
+          VM_TypeReference.JavaLangObjectArray);
+      Instruction aload = ALoad.create(REF_ALOAD, temp, otherArgsOp.copy(),
+          new IntConstantOperand(i), loc, guardOp != null ? guardOp.copy()
+              : null);
+      aload.copyPosition(s);
+      s.insertBefore(aload);
+      VM_Field field = boxedFieldRef.resolve();
+      Instruction getfield = GetField.create(GETFIELD, unboxed,
+          temp.copyRO(), new AddressConstantOperand(field.getOffset()),
+          new LocationOperand(boxedFieldRef),
+          guardOp != null ? guardOp.copy() : null);
+      s.insertBefore(getfield);
+    } else {
+      LocationOperand loc = new LocationOperand(
+          VM_TypeReference.JavaLangObjectArray);
+      Instruction aload = ALoad.create(REF_ALOAD, unboxed, otherArgsOp
+          .copy(), new IntConstantOperand(i), loc,
+          guardOp != null ? guardOp.copy() : null);
+      aload.copyPosition(s);
+    }
+    Call.setParam(s, i + numHiddenParams, unboxed.copyRO());
+  }
+
+  private static DefUseEffect reflectiveCall(AbstractRegisterPool regpool, Instruction s) {
+    if (CF_FIELDS) {
+      Operand method = ReflectiveCall.getMethod(s);
+      if (method.isObjectConstant()) {
+        VM_Method target = (VM_Method)method.asObjectConstant().value;
+        Operand nonVirtualOp = ReflectiveCall.getIsNonVirtual(s);
+        MethodOperand methOp;
+        if (target.isStatic()) {
+          methOp = MethodOperand.STATIC(target.getMemberRef().asMethodReference(), target);
+        } else if (nonVirtualOp.isIntConstant() && nonVirtualOp.asIntConstant().value == 1) {
+          methOp = MethodOperand.SPECIAL(target.getMemberRef().asMethodReference(), target);
+        } else {
+          methOp = MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target);
+        }
+        Operand addressOp;
+        if (!target.isCompiled() || target.getMemberRef().needsDynamicLink(s.position.method)) {
+          /* TODO: dynamic linking uses the bytecode stream so resolving things here is broken
+             RegisterOperand offsetrop = regpool.makeTempOffset();
+             Instruction resolve = Unary.create(RESOLVE_MEMBER, offsetrop.copyRO(), methOp.copy());
+             resolve.copyPosition(s);
+             s.insertBefore(resolve);
+             addressOp = offsetrop;
+          */
+          //System.out.println("Unable to eliminate reflective call as needs dynamic link :-(");
+          return DefUseEffect.UNCHANGED;
+        } else {
+          addressOp = new AddressConstantOperand(target.getOffset());
+        }
+        Operand thisOp = ReflectiveCall.getThisArg(s);
+        Operand otherArgsOp = ReflectiveCall.getOtherArgs(s);
+        Operand guardOp = ReflectiveCall.getGuard(s);
+        int numHiddenParams = methOp.isStatic() ? 0 : 1;
+        VM_TypeReference[] params = target.getParameterTypes();
+        Call.mutate(s, CALL, ReflectiveCall.getResult(s), addressOp, methOp, guardOp, params.length + numHiddenParams);
+        for (int i = params.length - 1; i >= 0; i--) {
+          try {
+            unboxArgument(otherArgsOp, i, numHiddenParams, params, guardOp, regpool, s);
+          } catch (OptimizingCompilerException.IllegalUpcast e) {
+            throw new Error("Illegal upcast creating call to " + target + " from " + s.position.method + " argument " + i, e);
+          }
+        }
+        if (numHiddenParams != 0) {
+          Call.setParam(s, 0, thisOp);
+        }
+        return DefUseEffect.REDUCED;
+      }
+    }
+    return DefUseEffect.UNCHANGED;
+  }
+
   private static DefUseEffect call(boolean HIR, AbstractRegisterPool regpool, Instruction s) {
     if (CF_FIELDS) {
       MethodOperand methOp = Call.getMethod(s);
@@ -3177,6 +3327,41 @@
                        new IntConstantOperand(1), // true
                        new ObjectConstantOperand(containingMethod.getDeclaringClass().getClassLoader(), Offset.zero()));
           return DefUseEffect.REDUCED;
+        // Can we remove the need for VM_Class.getClass...FromStackFrame to walk the stack?
+        } else if (method == VM_Entrypoints.getClassLoaderFromStackFrame ||
+                   method == VM_Entrypoints.getClassFromStackFrame) {
+          Operand frameOp = Call.getParam(s, 0);
+          if (frameOp.isIntConstant()) {
+            int frame = frameOp.asIntConstant().value;
+            InlineSequence currentFrame = s.position;
+            while (frame > 0 && currentFrame != null) {
+              currentFrame = currentFrame.caller;
+              frame--;
+            }
+            if (currentFrame != null) {
+              // we found the caller
+              ObjectConstantOperand cop;
+              if (method == VM_Entrypoints.getClassLoaderFromStackFrame) {
+                cop = new ObjectConstantOperand(currentFrame.method.getDeclaringClass().getTypeRef().getClassLoader(), Offset.zero());
+              } else {
+                cop = new ObjectConstantOperand(currentFrame.method.getDeclaringClass(), Offset.zero());
+              }
+              Move.mutate(s, REF_MOVE, Call.getClearResult(s), cop);
+              return DefUseEffect.MOVE_FOLDED;
+            }
+          }
+        // Can we remove the overhead of a reflective call?
+        } else if (java.lang.reflect.VMMember.INVOKE_POLICY == java.lang.reflect.VMMember.OUT_OF_LINE_MACHINE_CODE_SIMPLIFY &&
+                   method == VM_Entrypoints.org_jikesrvm_runtime_VM_Reflection_invokeMethod) {
+          ReflectiveCall.mutate(s, REFLECTIVE_CALL, Call.getResult(s),
+              Call.getParam(s, 0),
+              Call.getParam(s, 1),
+              Call.getParam(s, 2),
+              Call.getParam(s, 3),
+              Call.getGuard(s)
+          );
+          reflectiveCall(regpool, s);
+          return DefUseEffect.REDUCED;
         }
       }
       if (methOp.hasPreciseTarget() && methOp.getTarget().isPure()) {
Index: rvm/src/org/jikesrvm/compilers/opt/SimpleEscape.java
===================================================================
--- rvm/src/org/jikesrvm/compilers/opt/SimpleEscape.java	(revision 14213)
+++ rvm/src/org/jikesrvm/compilers/opt/SimpleEscape.java	(working copy)
@@ -128,6 +128,7 @@
 import static org.jikesrvm.compilers.opt.ir.Operators.REF_SUB_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.REF_USHR_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.REF_XOR_opcode;
+import static org.jikesrvm.compilers.opt.ir.Operators.REFLECTIVE_CALL_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.RETURN_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.SET_CAUGHT_EXCEPTION_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.SHORT_ALOAD_opcode;
@@ -538,6 +539,7 @@
       case INT_SHL_opcode:
       case INT_SHR_opcode:
       case INT_USHR_opcode:
+      case REFLECTIVE_CALL_opcode:
       case SYSCALL_opcode:
       case REF_SHL_opcode:
       case REF_SHR_opcode:
@@ -719,6 +721,7 @@
       case INT_SHL_opcode:
       case INT_SHR_opcode:
       case INT_USHR_opcode:
+      case REFLECTIVE_CALL_opcode:
       case SYSCALL_opcode:
       case REF_SHL_opcode:
       case REF_SHR_opcode:
Index: rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java
===================================================================
--- rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java	(revision 14213)
+++ rvm/src/org/jikesrvm/compilers/opt/hir2lir/ConvertToLowLevelIR.java	(working copy)
@@ -73,6 +73,7 @@
 import static org.jikesrvm.compilers.opt.ir.Operators.REF_IFCMP;
 import static org.jikesrvm.compilers.opt.ir.Operators.REF_LOAD;
 import static org.jikesrvm.compilers.opt.ir.Operators.REF_STORE;
+import static org.jikesrvm.compilers.opt.ir.Operators.REFLECTIVE_CALL_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.RESOLVE;
 import static org.jikesrvm.compilers.opt.ir.Operators.RESOLVE_MEMBER_opcode;
 import static org.jikesrvm.compilers.opt.ir.Operators.SHORT_ALOAD_opcode;
@@ -124,6 +125,7 @@
 import org.jikesrvm.compilers.opt.ir.Operator;
 import org.jikesrvm.compilers.opt.ir.PutField;
 import org.jikesrvm.compilers.opt.ir.PutStatic;
+import org.jikesrvm.compilers.opt.ir.ReflectiveCall;
 import org.jikesrvm.compilers.opt.ir.Store;
 import org.jikesrvm.compilers.opt.ir.TableSwitch;
 import org.jikesrvm.compilers.opt.ir.TrapIf;
@@ -160,7 +162,7 @@
    * loads, (where we can use base + index*scale addressing modes),
    * we'll leave array loads in the LIR.
    */
-  public static final boolean LOWER_ARRAY_ACCESS = VM.BuildForPowerPC;
+  static final boolean LOWER_ARRAY_ACCESS = VM.BuildForPowerPC;
   /**
    * Plant virtual calls via the JTOC rather than from the tib of an
    * object when possible
@@ -289,6 +291,21 @@
           doArrayStore(s, ir, SHORT_STORE, 1);
           break;
 
+        case REFLECTIVE_CALL_opcode: {
+          MethodOperand methOp = MethodOperand.STATIC(VM_Entrypoints.org_jikesrvm_runtime_VM_Reflection_invokeMethod);
+          Operand methodOp = ReflectiveCall.getMethod(s);
+          Operand thisOp = ReflectiveCall.getThisArg(s);
+          Operand otherArgsOp = ReflectiveCall.getOtherArgs(s);
+          Operand nonVirtualOp = ReflectiveCall.getIsNonVirtual(s);
+          Operand guardOp = ReflectiveCall.getGuard(s);
+          Call.mutate4(s, CALL, ReflectiveCall.getResult(s),
+              new AddressConstantOperand(VM_Entrypoints.org_jikesrvm_runtime_VM_Reflection_invokeMethod.getOffset()),
+              methOp, guardOp,
+              methodOp, thisOp, otherArgsOp, nonVirtualOp);
+          s = callHelper(s, ir);
+        }
+          break;
+          
         case CALL_opcode:
           s = callHelper(s, ir);
           break;

