2009-12-09 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mono / metadata / icall.c
index fcc85cfb06d1af2bba6e976b001ca29d5e1370a0..20e4ebb4ff0c51a7bf6899d5350010f065f15166 100644 (file)
@@ -6,7 +6,8 @@
  *   Paolo Molaro (lupus@ximian.com)
  *      Patrik Torstensson (patrik.torstensson@labs2.com)
  *
- * (C) 2001 Ximian, Inc.
+ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  */
 
 #include <config.h>
 #include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
 #include <stdlib.h>
 #endif
 
 #include <mono/utils/monobitset.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-string.h>
+#include <mono/utils/mono-error-internals.h>
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
 #include <windows.h>
 #include <shlobj.h>
 #endif
@@ -80,18 +86,55 @@ static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAs
 static MonoArray*
 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
 
+/* This is an implementation of a growable pointer array that avoids doing memory allocations for small sizes.
+ * It works by allocating an initial small array on stack and only going to malloc'd memory if needed. 
+ */
+typedef struct {
+       void **data;
+       int size;
+       int capacity;
+} MonoPtrArray;
+
+#define MONO_PTR_ARRAY_MAX_ON_STACK (16)
+
+#define mono_ptr_array_init(ARRAY, INITIAL_SIZE) do {\
+       (ARRAY).size = 0; \
+       (ARRAY).capacity = MAX (INITIAL_SIZE, MONO_PTR_ARRAY_MAX_ON_STACK); \
+       (ARRAY).data = INITIAL_SIZE > MONO_PTR_ARRAY_MAX_ON_STACK ? mono_gc_alloc_fixed (sizeof (void*) * INITIAL_SIZE, NULL) : g_newa (void*, MONO_PTR_ARRAY_MAX_ON_STACK); \
+} while (0)
+
+#define mono_ptr_array_destroy(ARRAY) do {\
+       if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK) \
+               mono_gc_free_fixed ((ARRAY).data); \
+} while (0)
+
+#define mono_ptr_array_append(ARRAY, VALUE) do { \
+       if ((ARRAY).size >= (ARRAY).capacity) {\
+               void *__tmp = mono_gc_alloc_fixed (sizeof (void*) * (ARRAY).capacity * 2, NULL); \
+               memcpy (__tmp, (ARRAY).data, (ARRAY).capacity * sizeof (void*)); \
+               if ((ARRAY).capacity > MONO_PTR_ARRAY_MAX_ON_STACK)     \
+                       mono_gc_free_fixed ((ARRAY).data);      \
+               (ARRAY).data = __tmp;                                                                                   \
+               (ARRAY).capacity *= 2;\
+       }\
+       ((ARRAY).data [(ARRAY).size++] = VALUE); \
+} while (0)
+
+#define mono_ptr_array_set(ARRAY, IDX, VALUE) do { \
+       ((ARRAY).data [(IDX)] = VALUE); \
+} while (0)
+       
+#define mono_ptr_array_get(ARRAY, IDX) ((ARRAY).data [(IDX)])
+
+#define mono_ptr_array_size(ARRAY) ((ARRAY).size)
+
+
 static inline MonoBoolean
 is_generic_parameter (MonoType *type)
 {
        return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
 }
 
-#ifdef _EGLIB_MAJOR
-/* Need to lock here because EGLIB has locking defined as no-ops, we can not depend on mono_strtod do the right locking */
-/* Ideally this will be fixed in eglib */
-static CRITICAL_SECTION strtod_mutex;
-#endif
-
 /*
  * We expect a pointer to a char, not a string
  */
@@ -109,10 +152,10 @@ mono_double_ParseImpl (char *ptr, double *result)
 #else
        if (*ptr){
 #ifdef _EGLIB_MAJOR
-               /* Need to lock here because EGLIB has locking defined as no-ops, and that breaks mono_strtod */
-               EnterCriticalSection (&strtod_mutex);
+               /* Need to lock here because EGLIB (#464316) has locking defined as no-ops, and that breaks mono_strtod */
+               EnterCriticalSection (&mono_strtod_mutex);
                *result = mono_strtod (ptr, &endptr);
-               LeaveCriticalSection (&strtod_mutex);
+               LeaveCriticalSection (&mono_strtod_mutex);
 #else
                *result = mono_strtod (ptr, &endptr);
 #endif
@@ -179,7 +222,7 @@ ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
        
        for (i = 0; i < ac->rank; i++)
                if ((ind [i] < ao->bounds [i].lower_bound) ||
-                   (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
+                   (ind [i] >=  (mono_array_lower_bound_t)ao->bounds [i].length + ao->bounds [i].lower_bound))
                        mono_raise_exception (mono_get_exception_index_out_of_range ());
 
        pos = ind [0] - ao->bounds [0].lower_bound;
@@ -290,11 +333,11 @@ ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32
 
        et = ec->byval_arg.type;
        if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
-               et = ec->byval_arg.data.klass->enum_basetype->type;
+               et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
 
        vt = vc->byval_arg.type;
        if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
-               vt = vc->byval_arg.data.klass->enum_basetype->type;
+               vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
 
 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
        switch (vt) { \
@@ -492,7 +535,7 @@ ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
        
        for (i = 0; i < ac->rank; i++)
                if ((ind [i] < this->bounds [i].lower_bound) ||
-                   (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
+                   (ind [i] >= (mono_array_lower_bound_t)this->bounds [i].length + this->bounds [i].lower_bound))
                        mono_raise_exception (mono_get_exception_index_out_of_range ());
 
        pos = ind [0] - this->bounds [0].lower_bound;
@@ -678,6 +721,7 @@ ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* d
        if (source->bounds || dest->bounds)
                return FALSE;
 
+       /* there's no integer overflow since mono_array_length returns an unsigned integer */
        if ((dest_idx + length > mono_array_length (dest)) ||
                (source_idx + length > mono_array_length (source)))
                return FALSE;
@@ -769,7 +813,7 @@ ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpoin
 static void
 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
 {
-       MonoClass *ac;
+       MonoClass *ac, *ec;
        MonoArray *ao;
        gint32 esize;
        gpointer *ea;
@@ -778,11 +822,22 @@ ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpoin
 
        ao = (MonoArray *)this;
        ac = (MonoClass *)ao->obj.vtable->klass;
+       ec = ac->element_class;
 
        esize = mono_array_element_size (ac);
        ea = (gpointer*)((char*)ao->vector + (pos * esize));
 
-       memcpy (ea, value, esize);
+       if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
+               g_assert (esize == sizeof (gpointer));
+               mono_gc_wbarrier_generic_store (ea, *(gpointer*)value);
+       } else {
+               g_assert (ec->inited);
+               g_assert (esize == mono_class_value_size (ec, NULL));
+               if (ec->has_references)
+                       mono_gc_wbarrier_value_copy (ea, value, 1, ec);
+               else
+                       memcpy (ea, value, esize);
+       }
 }
 
 static void
@@ -891,16 +946,17 @@ static void
 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
 {
        MonoClass *klass;
-
-       MONO_ARCH_SAVE_REGS;
+       MonoVTable *vtable;
 
        MONO_CHECK_ARG_NULL (handle);
 
        klass = mono_class_from_mono_type (handle);
        MONO_CHECK_ARG (handle, klass);
 
+       vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
+
        /* This will call the type constructor */
-       mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
+       mono_runtime_class_init (vtable);
 }
 
 static void
@@ -911,7 +967,8 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (M
        mono_image_check_for_module_cctor (image);
        if (image->has_module_cctor) {
                MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
-               mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
+               /*It's fine to raise the exception here*/
+               mono_runtime_class_init (mono_class_vtable_full (mono_domain_get (), module_klass, TRUE));
        }
 }
 
@@ -974,7 +1031,7 @@ ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fi
 
        if (values) {
                int i;
-               *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
+               mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
                for (i = 0; i < count; ++i)
                        mono_array_setref (*fields, i, values [i]);
        } else {
@@ -1002,7 +1059,7 @@ ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray
 
        klass = mono_object_class (this);
 
-       if (klass->enumtype && klass->enum_basetype && klass->enum_basetype->type == MONO_TYPE_I4)
+       if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
                return (*(gint32*)((guint8*)this + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
 
        /*
@@ -1086,7 +1143,7 @@ ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray
 
        if (values) {
                int i;
-               *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
+               mono_gc_wbarrier_generic_store (fields, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.object_class, count));
                for (i = 0; i < count; ++i)
                        mono_array_setref (*fields, i, values [i]);
                return FALSE;
@@ -1200,6 +1257,32 @@ get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer
        return FALSE;
 }
 
+static gboolean
+get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+{
+       MonoMethod **dest = data;
+
+       /* skip unmanaged frames */
+       if (!managed)
+               return FALSE;
+
+       if (m->wrapper_type != MONO_WRAPPER_NONE)
+               return FALSE;
+
+       if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
+               return FALSE;
+
+       if (m == *dest) {
+               *dest = NULL;
+               return FALSE;
+       }
+       if (!(*dest)) {
+               *dest = m;
+               return TRUE;
+       }
+       return FALSE;
+}
+
 static MonoReflectionType *
 type_from_name (const char *str, MonoBoolean ignoreCase)
 {
@@ -1224,7 +1307,7 @@ type_from_name (const char *str, MonoBoolean ignoreCase)
                MonoMethod *m = mono_method_get_last_managed ();
                MonoMethod *dest = m;
 
-               mono_stack_walk_no_il (get_caller, &dest);
+               mono_stack_walk_no_il (get_caller_no_reflection, &dest);
                if (!dest)
                        dest = m;
 
@@ -1315,7 +1398,7 @@ ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionTy
        if (c && type->type && c->type)
                return mono_metadata_type_equal (type->type, c->type);
        else
-               return FALSE;
+               return (type == c) ? TRUE : FALSE;
 }
 
 /* System.TypeCode */
@@ -1384,7 +1467,7 @@ handle_enum:
                return TYPECODE_DOUBLE;
        case MONO_TYPE_VALUETYPE:
                if (type->type->data.klass->enumtype) {
-                       t = type->type->data.klass->enum_basetype->type;
+                       t = mono_class_enum_basetype (type->type->data.klass)->type;
                        goto handle_enum;
                } else {
                        MonoClass *k =  type->type->data.klass;
@@ -1512,27 +1595,33 @@ ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *
 }
 
 static MonoReflectionField*
-ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
+ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
 {
+       gboolean found = FALSE;
+       MonoClass *klass;
+       MonoClass *k;
+
        g_assert (handle);
 
-       if (!klass)
+       if (!type) {
                klass = handle->parent;
+       } else {
+               klass = mono_class_from_mono_type (type);
 
-       /* FIXME: check that handle is a field of klass or of a parent: return null
-        * and throw the exception in managed code.
-        */
-       return mono_field_get_object (mono_domain_get (), klass, handle);
-}
-
-static MonoReflectionField*
-ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
-{
-       MONO_ARCH_SAVE_REGS;
+               /* Check that the field belongs to the class */
+               for (k = klass; k; k = k->parent) {
+                       if (k == handle->parent) {
+                               found = TRUE;
+                               break;
+                       }
+               }
 
-       g_assert (handle);
+               if (!found)
+                       /* The managed code will throw the exception */
+                       return NULL;
+       }
 
-       return mono_field_get_object (mono_domain_get (), handle->parent, handle);
+       return mono_field_get_object (mono_domain_get (), klass, handle);
 }
 
 static MonoArray*
@@ -1555,9 +1644,9 @@ ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
                g_assert (mono_loader_get_last_error ());
                mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
        }
-       
-       info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
-       info->ret = mono_type_get_object (domain, sig->ret);
+
+       MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &method->klass->byval_arg));
+       MONO_STRUCT_SETREF (info, ret, mono_type_get_object (domain, sig->ret));
        info->attrs = method->flags;
        info->implattrs = method->iflags;
        if (sig->call_convention == MONO_CALL_DEFAULT)
@@ -1572,11 +1661,11 @@ ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
 }
 
 static MonoArray*
-ves_icall_get_parameter_info (MonoMethod *method)
+ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
 {
        MonoDomain *domain = mono_domain_get (); 
 
-       return mono_param_get_objects (domain, method);
+       return mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL);
 }
 
 static MonoReflectionMarshal*
@@ -1637,6 +1726,9 @@ ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *ob
                mono_raise_exception (mono_get_exception_invalid_operation (
                                        "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
        
+       if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+               mono_security_core_clr_ensure_reflection_access_field (cf);
+
        mono_class_init (field->klass);
 
        if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
@@ -1703,7 +1795,7 @@ ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *ob
 
        vtable = NULL;
        if (is_static) {
-               vtable = mono_class_vtable (domain, cf->parent);
+               vtable = mono_class_vtable_full (domain, cf->parent, TRUE);
                if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
                        mono_runtime_class_init (vtable);
        }
@@ -1755,6 +1847,9 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
                mono_raise_exception (mono_get_exception_invalid_operation (
                                        "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
 
+       if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+               mono_security_core_clr_ensure_reflection_access_field (cf);
+
        v = (gchar *) value;
        if (!cf->type->byref) {
                switch (cf->type->type) {
@@ -1815,7 +1910,7 @@ ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *ob
        }
 
        if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
-               MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
+               MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, TRUE);
                if (!vtable->initialized)
                        mono_runtime_class_init (vtable);
                mono_field_static_set_value (vtable, cf, v);
@@ -1937,26 +2032,26 @@ ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo
 }
 
 static void
-ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
+ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
 {
        MonoDomain *domain = mono_object_domain (event); 
 
        MONO_ARCH_SAVE_REGS;
 
-       info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
-       info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
+       MONO_STRUCT_SETREF (info, reflected_type, mono_type_get_object (domain, &event->klass->byval_arg));
+       MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &event->event->parent->byval_arg));
 
-       info->name = mono_string_new (domain, event->event->name);
+       MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
        info->attrs = event->event->attrs;
-       info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
-       info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
-       info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
+       MONO_STRUCT_SETREF (info, add_method, event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL);
+       MONO_STRUCT_SETREF (info, remove_method, event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL);
+       MONO_STRUCT_SETREF (info, raise_method, event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL);
 
        if (event->event->other) {
                int i, n = 0;
                while (event->event->other [n])
                        n++;
-               info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
+               MONO_STRUCT_SETREF (info, other_methods, mono_array_new (domain, mono_defaults.method_info_class, n));
 
                for (i = 0; i < n; i++)
                        mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
@@ -2006,9 +2101,9 @@ ves_icall_Type_GetInterfaces (MonoReflectionType* type)
        mono_bitset_free (slots);
 
        if (!ifaces)
-               return mono_array_new (domain, mono_defaults.monotype_class, 0);
+               return mono_array_new_cached (domain, mono_defaults.monotype_class, 0);
                
-       intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
+       intf = mono_array_new_cached (domain, mono_defaults.monotype_class, ifaces->len);
        for (i = 0; i < ifaces->len; ++i) {
                MonoClass *ic = g_ptr_array_index (ifaces, i);
                MonoType *ret = &ic->byval_arg, *inflated = NULL;
@@ -2046,9 +2141,8 @@ ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType
        len = mono_class_num_methods (iclass);
        ioffset = mono_class_interface_offset (class, iclass);
        domain = mono_object_domain (type);
-       *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
-       *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
-       iter = NULL;
+       mono_gc_wbarrier_generic_store (targets, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len));
+       mono_gc_wbarrier_generic_store (methods, (MonoObject*) mono_array_new (domain, mono_defaults.method_info_class, len));
        iter = NULL;
        while ((method = mono_class_get_methods (iclass, &iter))) {
                member = mono_method_get_object (domain, method, iclass);
@@ -2077,10 +2171,15 @@ ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *
 static MonoReflectionType*
 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
 {
-       MonoClass *class = mono_class_from_mono_type (type->type);
+       MonoClass *class;
 
        MONO_ARCH_SAVE_REGS;
 
+       if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY)
+               return mono_type_get_object (mono_object_domain (type), &type->type->data.klass->byval_arg);
+
+       class = mono_class_from_mono_type (type->type);
+
        // GetElementType should only return a type for:
        // Array Pointer PassedByRef
        if (type->type->byref)
@@ -2168,9 +2267,9 @@ ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
        if (type->type->byref)
                return NULL;
        if (type->type->type == MONO_TYPE_VAR)
-               class = type->type->data.generic_param->owner->owner.klass;
+               class = mono_type_get_generic_param_owner (type->type)->owner.klass;
        else if (type->type->type == MONO_TYPE_MVAR)
-               class = type->type->data.generic_param->owner->owner.method->klass;
+               class = mono_type_get_generic_param_owner (type->type)->owner.method->klass;
        else
                class = mono_class_from_mono_type (type->type)->nested_in;
 
@@ -2185,8 +2284,8 @@ ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
 
        MONO_ARCH_SAVE_REGS;
 
-       if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
-               return mono_type_get_object (domain, class->enum_basetype);
+       if (class->enumtype && mono_class_enum_basetype (class)) /* types that are modified typebuilders may not have enum_basetype set */
+               return mono_type_get_object (domain, mono_class_enum_basetype (class));
        else if (class->element_class)
                return mono_type_get_object (domain, &class->element_class->byval_arg);
        else
@@ -2233,10 +2332,12 @@ ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
 static gint32
 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
 {
-       MonoClass *class = mono_class_from_mono_type (type->type);
+       MonoClass *class;
 
-       MONO_ARCH_SAVE_REGS;
+       if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY)
+               mono_raise_exception (mono_get_exception_argument ("type", "Type must be an array type"));
 
+       class = mono_class_from_mono_type (type->type);
        return class->rank;
 }
 
@@ -2245,6 +2346,8 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
 {
        MonoArray *res;
        MonoClass *klass, *pklass;
+       MonoDomain *domain = mono_object_domain (type);
+       MonoVTable *array_vtable = mono_class_vtable_full (domain, mono_array_class_get_cached (mono_defaults.systemtype_class, 1), TRUE);
        int i;
        MONO_ARCH_SAVE_REGS;
 
@@ -2252,18 +2355,18 @@ ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
 
        if (klass->generic_container) {
                MonoGenericContainer *container = klass->generic_container;
-               res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
+               res = mono_array_new_specific (array_vtable, container->type_argc);
                for (i = 0; i < container->type_argc; ++i) {
-                       pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
-                       mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
+                       pklass = mono_class_from_generic_parameter (mono_generic_container_get_param (container, i), klass->image, FALSE);
+                       mono_array_setref (res, i, mono_type_get_object (domain, &pklass->byval_arg));
                }
        } else if (klass->generic_class) {
                MonoGenericInst *inst = klass->generic_class->context.class_inst;
-               res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
+               res = mono_array_new_specific (array_vtable, inst->type_argc);
                for (i = 0; i < inst->type_argc; ++i)
-                       mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
+                       mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
        } else {
-               res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
+               res = mono_array_new_specific (array_vtable, 0);
        }
        return res;
 }
@@ -2274,6 +2377,9 @@ ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
        MonoClass *klass;
        MONO_ARCH_SAVE_REGS;
 
+       if (!IS_MONOTYPE (type))
+               return FALSE;
+
        if (type->type->byref)
                return FALSE;
 
@@ -2349,6 +2455,9 @@ ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
        MonoClass *klass;
        MONO_ARCH_SAVE_REGS;
 
+       if (!IS_MONOTYPE (type))
+               return FALSE;
+
        if (type->type->byref)
                return FALSE;
 
@@ -2361,8 +2470,11 @@ ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
 {
        MONO_ARCH_SAVE_REGS;
 
+       if (!IS_MONOTYPE (type))
+               return -1;
+
        if (is_generic_parameter (type->type))
-               return type->type->data.generic_param->num;
+               return mono_type_get_generic_param_num (type->type);
        return -1;
 }
 
@@ -2370,14 +2482,16 @@ static GenericParameterAttributes
 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
 {
        MONO_ARCH_SAVE_REGS;
+
+       g_assert (IS_MONOTYPE (type));
        g_assert (is_generic_parameter (type->type));
-       return type->type->data.generic_param->flags;
+       return mono_generic_param_info (type->type->data.generic_param)->flags;
 }
 
 static MonoArray *
 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
 {
-       MonoGenericParam *param;
+       MonoGenericParamInfo *param_info;
        MonoDomain *domain;
        MonoClass **ptr;
        MonoArray *res;
@@ -2385,14 +2499,16 @@ ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
 
        MONO_ARCH_SAVE_REGS;
 
+       g_assert (IS_MONOTYPE (type));
+
        domain = mono_object_domain (type);
-       param = type->type->data.generic_param;
-       for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
+       param_info = mono_generic_param_info (type->type->data.generic_param);
+       for (count = 0, ptr = param_info->constraints; ptr && *ptr; ptr++, count++)
                ;
 
        res = mono_array_new (domain, mono_defaults.monotype_class, count);
        for (i = 0; i < count; i++)
-               mono_array_setref (res, i, mono_type_get_object (domain, &param->constraints [i]->byval_arg));
+               mono_array_setref (res, i, mono_type_get_object (domain, &param_info->constraints [i]->byval_arg));
 
 
        return res;
@@ -2419,174 +2535,6 @@ ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
        enumtype->type = t->type;
 }
 
-static MonoReflectionType*
-ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
-{
-       MonoDynamicGenericClass *gclass;
-       MonoReflectionType *parent = NULL, *res;
-       MonoDomain *domain;
-       MonoType *inflated;
-       MonoClass *klass;
-
-
-       MONO_ARCH_SAVE_REGS;
-
-       g_assert (type->type.type->data.generic_class->is_dynamic);
-       gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
-
-       domain = mono_object_domain (type);
-       klass = mono_class_from_mono_type (type->generic_type->type.type);
-
-       if (!klass->generic_class && !klass->generic_container)
-               return NULL;
-
-       parent = type->generic_type->parent;
-
-       if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
-               return NULL;
-
-       inflated = mono_class_inflate_generic_type (
-               parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
-
-       res = mono_type_get_object (domain, inflated);
-       mono_metadata_free_type (inflated);
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
-{
-       static MonoClass *System_Reflection_MonoGenericClass;
-       MonoGenericClass *gclass;
-       MonoReflectionTypeBuilder *tb = NULL;
-       MonoClass *klass = NULL;
-       MonoDomain *domain;
-       MonoArray *res;
-       int icount, i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!System_Reflection_MonoGenericClass) {
-               System_Reflection_MonoGenericClass = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
-               g_assert (System_Reflection_MonoGenericClass);
-       }
-
-       domain = mono_object_domain (type);
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       tb = type->generic_type;
-       icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
-
-       res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
-
-       for (i = 0; i < icount; i++) {
-               MonoReflectionType *iface;
-               MonoType *it;
-
-               if (tb) {
-                       iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
-                       it = iface->type;
-               } else
-                       it = &klass->interfaces [i]->byval_arg;
-
-               it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
-
-               iface = mono_type_get_object (domain, it);
-               mono_array_setref (res, i, iface);
-               mono_metadata_free_type (it);
-       }
-
-       return res;
-}
-
-static MonoReflectionMethod*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type, 
-                                                           MonoReflectionMethod* generic)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       domain = mono_object_domain (type);
-
-       for (i = 0; i < dgclass->count_methods; i++)
-               if (generic->method->token == dgclass->methods [i]->token)
-                        return mono_method_get_object (domain, dgclass->methods [i], NULL);
-
-       return NULL;
-}
-
-static MonoReflectionMethod*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type, 
-                                                                MonoReflectionMethod* generic)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       domain = mono_object_domain (type);
-
-       for (i = 0; i < dgclass->count_ctors; i++)
-               if (generic->method->token == dgclass->ctors [i]->token)
-                        return mono_method_get_object (domain, dgclass->ctors [i], NULL);
-
-       return NULL;
-}
-
-
-static MonoReflectionField*
-ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type, 
-                                                          MonoString* generic_name)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-        MonoClass *refclass;
-       char *utf8_name = mono_string_to_utf8 (generic_name);
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (type->type.type);
-
-       domain = mono_object_domain (type);
-
-       for (i = 0; i < dgclass->count_fields; i++)
-               if (strcmp (utf8_name, mono_field_get_name (&dgclass->fields [i])) == 0) {
-                       g_free (utf8_name);
-                        return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
-               }
-       
-       g_free (utf8_name);
-
-       return NULL;
-}
-
-
 static MonoReflectionMethod*
 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type, 
                                                    MonoReflectionMethod* generic)
@@ -2611,193 +2559,24 @@ ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
         return NULL;
 }
 
-static MonoArray*
-ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
-                                      MonoReflectionType *reflected_type)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
 
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
-
-       for (i = 0; i < dgclass->count_methods; i++)
-               mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
-
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
-                                           MonoReflectionType *reflected_type)
-{
-       static MonoClass *System_Reflection_ConstructorInfo;
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!System_Reflection_ConstructorInfo)
-               System_Reflection_ConstructorInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
-
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
-
-       for (i = 0; i < dgclass->count_ctors; i++)
-               mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
-
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
-                                     MonoReflectionType *reflected_type)
-{
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
-
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
-
-       for (i = 0; i < dgclass->count_fields; i++)
-               mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
-
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
-                                         MonoReflectionType *reflected_type)
-{
-       static MonoClass *System_Reflection_PropertyInfo;
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!System_Reflection_PropertyInfo)
-               System_Reflection_PropertyInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "PropertyInfo");
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
-
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
-
-       for (i = 0; i < dgclass->count_properties; i++)
-               mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
-
-       return res;
-}
-
-static MonoArray*
-ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
-                                     MonoReflectionType *reflected_type)
-{
-       static MonoClass *System_Reflection_EventInfo;
-       MonoGenericClass *gclass;
-       MonoDynamicGenericClass *dgclass;
-       MonoDomain *domain;
-       MonoClass *refclass;
-       MonoArray *res;
-       int i;
-
-       MONO_ARCH_SAVE_REGS;
-
-       if (!System_Reflection_EventInfo)
-               System_Reflection_EventInfo = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "EventInfo");
-
-       gclass = type->type.type->data.generic_class;
-       g_assert (gclass->is_dynamic);
-       dgclass = (MonoDynamicGenericClass *) gclass;
-
-       refclass = mono_class_from_mono_type (reflected_type->type);
-
-       domain = mono_object_domain (type);
-       res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
-
-       for (i = 0; i < dgclass->count_events; i++)
-               mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
-
-       return res;
-}
-
-static MonoReflectionType*
-ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass *type,
-                                     MonoReflectionType *target)
-{
-       MonoType *res_type;
-       MonoClass *gklass;
-       MonoReflectionType *res;
-
-       MONO_ARCH_SAVE_REGS;
-
-       gklass = mono_class_from_mono_type (type->type.type);
-       res_type = mono_class_inflate_generic_type (target->type, mono_class_get_context (gklass));
-       res = mono_type_get_object (mono_object_domain (type), res_type);
-       mono_metadata_free_type (res_type);
-       return res;
-}
 
 static MonoReflectionMethod *
-ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
+ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *ref_type)
 {
        MonoMethod *method;
-       MonoClass *klass;
+       MonoType *type = ref_type->type;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
+       if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR))
+               mono_raise_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
+       if (type->type == MONO_TYPE_VAR)
                return NULL;
 
-       method = type->type->data.generic_param->owner->owner.method;
+       method = mono_type_get_generic_param_owner (type)->owner.method;
        g_assert (method);
-       klass = mono_class_from_mono_type (type->type);
-       return mono_method_get_object (mono_object_domain (type), method, klass);
+       return mono_method_get_object (mono_object_domain (ref_type), method, method->klass);
 }
 
 static MonoReflectionDllImportAttribute*
@@ -2817,7 +2596,7 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
        const char *scope = NULL;
        guint32 flags;
 
-       if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+       if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
                return NULL;
 
        if (!DllImportAttributeClass) {
@@ -2835,6 +2614,11 @@ ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
                        import = method_aux->dllentry;
                        scope = method_aux->dll;
                }
+
+               if (!import || !scope) {
+                       mono_raise_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
+                       return NULL;
+               }
        }
        else {
                if (piinfo->implmap_idx) {
@@ -2955,43 +2739,14 @@ ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
 
        for (i = 0; i < count; i++) {
                MonoGenericContainer *container = mono_method_get_generic_container (method->method);
-               MonoGenericParam *param = &container->type_params [i];
-               MonoClass *pklass = mono_class_from_generic_parameter (
-                       param, method->method->klass->image, TRUE);
-               mono_array_setref (res, i,
-                               mono_type_get_object (domain, &pklass->byval_arg));
-       }
-
-       return res;
-}
-
-static void
-ensure_reflection_security (void)
-{
-       MonoMethod *m = mono_method_get_last_managed ();
-
-       while (m) {
-               /*
-               g_print ("method %s.%s.%s in image %s\n",
-                       m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
-               */
-
-               /* We stop at the first method which is not in
-                  System.Reflection or which is not in a platform
-                  image. */
-               if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
-                               !mono_security_core_clr_is_platform_image (m->klass->image)) {
-                       /* If the method is transparent we throw an exception. */
-                       if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
-                               MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
-
-                               mono_raise_exception (ex);
-                       }
-                       return;
-               }
-
-               mono_stack_walk_no_il (get_caller, &m);
+               MonoGenericParam *param = mono_generic_container_get_param (container, i);
+               MonoClass *pklass = mono_class_from_generic_parameter (
+                       param, method->method->klass->image, TRUE);
+               mono_array_setref (res, i,
+                               mono_type_get_object (domain, &pklass->byval_arg));
        }
+
+       return res;
 }
 
 static MonoObject *
@@ -3010,14 +2765,13 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
 
        *exc = NULL;
 
-       if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
-                       mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
-               ensure_reflection_security ();
+       if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)
+               mono_security_core_clr_ensure_reflection_access_method (m);
 
        if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
                if (this) {
                        if (!mono_object_isinst (this, m->klass)) {
-                               *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type.");
+                               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type."));
                                return NULL;
                        }
                        m = mono_object_get_virtual_method (this, m);
@@ -3025,24 +2779,24 @@ ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoAr
                        if (m->klass->valuetype)
                                obj = mono_object_unbox (this);
                } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
-                       *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target.");
+                       mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
                        return NULL;
                }
        }
 
        pcount = params? mono_array_length (params): 0;
        if (pcount != mono_method_signature (m)->param_count) {
-               *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
+               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
                return NULL;
        }
 
        if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
-               *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
+               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
                return NULL;
        }
 
        if (m->klass->image->assembly->ref_only) {
-               *exc = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
+               mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
                return NULL;
        }
        
@@ -3110,7 +2864,7 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
                                                result = *((gpointer *)((char *)this + field->offset));
                                
                                        out_args = mono_array_new (domain, mono_defaults.object_class, 1);
-                                       *outArgs = out_args;
+                                       mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
                                        mono_array_setref (out_args, 0, result);
                                        g_free (str);
                                        return NULL;
@@ -3147,13 +2901,14 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
 
                                        if (field_klass->valuetype) {
                                                size = mono_type_size (field->type, &align);
-                                               memcpy ((char *)this + field->offset, 
-                                                       ((char *)val) + sizeof (MonoObject), size);
-                                       } else 
-                                               *(MonoObject**)((char *)this + field->offset) = val;
+                                               g_assert (size == mono_class_value_size (field_klass, NULL));
+                                               mono_gc_wbarrier_value_copy ((char *)this + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
+                                       } else {
+                                               mono_gc_wbarrier_set_field (this, (char*)this + field->offset, val);
+                                       }
                                
                                        out_args = mono_array_new (domain, mono_defaults.object_class, 0);
-                                       *outArgs = out_args;
+                                       mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
 
                                        g_free (str);
                                        return NULL;
@@ -3192,7 +2947,7 @@ ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoA
                }
        }
 
-       *outArgs = out_args;
+       mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
 
        return result;
 }
@@ -3280,8 +3035,8 @@ ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
                mono_raise_exception (mono_get_exception_argument ("value", "The value passed in must be an enum base or an underlying type for an enum, such as an Int32."));
 
        res = mono_object_new (domain, enumc);
-       val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
-       write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
+       val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? mono_class_enum_basetype (objc)->type: objc->byval_arg.type);
+       write_enum_value ((char *)res + sizeof (MonoObject), mono_class_enum_basetype (enumc)->type, val);
 
        return res;
 }
@@ -3302,7 +3057,7 @@ ves_icall_System_Enum_get_value (MonoObject *this)
 
        g_assert (this->vtable->klass->enumtype);
        
-       enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
+       enumc = mono_class_from_mono_type (mono_class_enum_basetype (this->vtable->klass));
        res = mono_object_new (mono_object_domain (this), enumc);
        dst = (char *)res + sizeof (MonoObject);
        src = (char *)this + sizeof (MonoObject);
@@ -3318,14 +3073,64 @@ ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
 {
        MONO_ARCH_SAVE_REGS;
 
-       return mono_type_get_object (mono_object_domain (type), mono_class_from_mono_type (type->type)->enum_basetype);
+       return mono_type_get_object (mono_object_domain (type), mono_class_enum_basetype (mono_class_from_mono_type (type->type)));
+}
+
+static int
+ves_icall_System_Enum_compare_value_to (MonoObject *this, MonoObject *other)
+{
+       gpointer tdata = (char *)this + sizeof (MonoObject);
+       gpointer odata = (char *)other + sizeof (MonoObject);
+       MonoType *basetype = mono_class_enum_basetype (this->vtable->klass);
+       g_assert (basetype);
+
+#define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
+               ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
+               ENUM_TYPE other = *((ENUM_TYPE*)odata); \
+               if (me == other) \
+                       return 0; \
+               return me > other ? 1 : -1; \
+       } while (0)
+
+#define COMPARE_ENUM_VALUES_RANGE(ENUM_TYPE) do { \
+               ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
+               ENUM_TYPE other = *((ENUM_TYPE*)odata); \
+               if (me == other) \
+                       return 0; \
+               return me - other; \
+       } while (0)
+
+       switch (basetype->type) {
+               case MONO_TYPE_U1:
+                       COMPARE_ENUM_VALUES (guint8);
+               case MONO_TYPE_I1:
+                       COMPARE_ENUM_VALUES (gint8);
+               case MONO_TYPE_CHAR:
+               case MONO_TYPE_U2:
+                       COMPARE_ENUM_VALUES_RANGE (guint16);
+               case MONO_TYPE_I2:
+                       COMPARE_ENUM_VALUES (gint16);
+               case MONO_TYPE_U4:
+                       COMPARE_ENUM_VALUES (guint32);
+               case MONO_TYPE_I4:
+                       COMPARE_ENUM_VALUES (gint32);
+               case MONO_TYPE_U8:
+                       COMPARE_ENUM_VALUES (guint64);
+               case MONO_TYPE_I8:
+                       COMPARE_ENUM_VALUES (gint64);
+               default:
+                       g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
+       }
+#undef COMPARE_ENUM_VALUES_RANGE
+#undef COMPARE_ENUM_VALUES
+       return 0;
 }
 
 static int
 ves_icall_System_Enum_get_hashcode (MonoObject *this)
 {
        gpointer data = (char *)this + sizeof (MonoObject);
-       MonoType *basetype = this->vtable->klass->enum_basetype;
+       MonoType *basetype = mono_class_enum_basetype (this->vtable->klass);
        g_assert (basetype);
 
        switch (basetype->type) {
@@ -3365,11 +3170,11 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
 
        MONO_ARCH_SAVE_REGS;
 
-       info->utype = mono_type_get_object (domain, enumc->enum_basetype);
+       MONO_STRUCT_SETREF (info, utype, mono_type_get_object (domain, mono_class_enum_basetype (enumc)));
        nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
-       info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
-       info->values = mono_array_new (domain, enumc, nvalues);
-       
+       MONO_STRUCT_SETREF (info, names, mono_array_new (domain, mono_defaults.string_class, nvalues));
+       MONO_STRUCT_SETREF (info, values, mono_array_new (domain, enumc, nvalues));
+
        crow = -1;
        iter = NULL;
        while ((field = mono_class_get_fields (enumc, &iter))) {
@@ -3385,7 +3190,7 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
 
                p = mono_class_get_field_default_value (field, &def_type);
                len = mono_metadata_decode_blob_size (p, &p);
-               switch (enumc->enum_basetype->type) {
+               switch (mono_class_enum_basetype (enumc)->type) {
                case MONO_TYPE_U1:
                case MONO_TYPE_I1:
                        mono_array_set (info->values, gchar, j, *p);
@@ -3404,7 +3209,7 @@ ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
                        mono_array_set (info->values, gint64, j, read64 (p));
                        break;
                default:
-                       g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
+                       g_error ("Implement type 0x%02x in get_enum_info", mono_class_enum_basetype (enumc)->type);
                }
                ++j;
        }
@@ -3449,7 +3254,7 @@ ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bfl
        if (type->type->byref)
                return NULL;
 
-       compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
 
 handle_parent:
        if (klass->exception_type != MONO_EXCEPTION_NONE)
@@ -3509,9 +3314,10 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon
        MonoClass *startklass, *klass, *refklass;
        MonoArray *res;
        MonoObject *member;
-       int i, len, match;
+       int i, match;
        gpointer iter;
        MonoClassField *field;
+       MonoPtrArray tmp_array;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -3521,9 +3327,8 @@ ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, Mon
        klass = startklass = mono_class_from_mono_type (type->type);
        refklass = mono_class_from_mono_type (reftype->type);
 
-       i = 0;
-       len = 2;
-       res = mono_array_new (domain, mono_defaults.field_info_class, len);
+       mono_ptr_array_init (tmp_array, 2);
+       
 handle_parent: 
        if (klass->exception_type != MONO_EXCEPTION_NONE)
                mono_raise_exception (mono_class_get_exception_for_failure (klass));
@@ -3556,26 +3361,18 @@ handle_parent:
                if (!match)
                        continue;
                member = (MonoObject*)mono_field_get_object (domain, refklass, field);
-               if (i >= len) {
-                       MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
-                       mono_array_memcpy_refs (new_res, 0, res, 0, len);
-                       len *= 2;
-                       res = new_res;
-               }
-               mono_array_setref (res, i, member);
-               ++i;
+               mono_ptr_array_append (tmp_array, member);
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
-       if (i != len) {
-               MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
-               mono_array_memcpy_refs (new_res, 0, res, 0, i);
-               res = new_res;
-               /*
-                * Better solution for the new GC.
-                * res->max_length = i;
-                */
-       }
+
+       res = mono_array_new_cached (domain, mono_defaults.field_info_class, mono_ptr_array_size (tmp_array));
+
+       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+       mono_ptr_array_destroy (tmp_array);
+
        return res;
 }
 
@@ -3605,14 +3402,19 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        gpointer iter;
        MonoObject *member;
        int i, len, match, nslots;
+       /*FIXME, use MonoBitSet*/
        guint32 method_slots_default [8];
-       guint32 *method_slots;
+       guint32 *method_slots = NULL;
        gchar *mname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        MonoVTable *array_vtable;
-               
+       MonoException *ex;
+       MonoPtrArray tmp_array;
+
        MONO_ARCH_SAVE_REGS;
 
+       mono_ptr_array_init (tmp_array, 4);
+
        if (!MethodInfo_array) {
                MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
                mono_memory_barrier ();
@@ -3620,7 +3422,7 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        }
 
        domain = ((MonoObject *)type)->vtable->domain;
-       array_vtable = mono_class_vtable (domain, MethodInfo_array);
+       array_vtable = mono_class_vtable_full (domain, MethodInfo_array, TRUE);
        if (type->type->byref)
                return mono_array_new_specific (array_vtable, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
@@ -3628,32 +3430,52 @@ ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, gui
        len = 0;
        if (name != NULL) {
                mname = mono_string_to_utf8 (name);
-               compare_func = (ignore_case) ? g_strcasecmp : strcmp;
+               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
+       }
+
+       /* An optimization for calls made from Delegate:CreateDelegate () */
+       if (klass->delegate && mname && !strcmp (mname, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
+               method = mono_get_delegate_invoke (klass);
+               if (mono_loader_get_last_error ())
+                       goto loader_error;
+
+               member = (MonoObject*)mono_method_get_object (domain, method, refklass);
+
+               res = mono_array_new_specific (array_vtable, 1);
+               mono_array_setref (res, 0, member);
+               g_free (mname);
+               return res;
        }
 
        mono_class_setup_vtable (klass);
+       if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+               goto loader_error;
 
        if (is_generic_parameter (type->type))
-               nslots = klass->parent->vtable_size;
+               nslots = mono_class_get_vtable_size (klass->parent);
        else
-               nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
+               nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
        if (nslots >= sizeof (method_slots_default) * 8) {
                method_slots = g_new0 (guint32, nslots / 32 + 1);
        } else {
                method_slots = method_slots_default;
                memset (method_slots, 0, sizeof (method_slots_default));
        }
-       i = 0;
-       len = 1;
-       res = mono_array_new_specific (array_vtable, len);
 handle_parent:
        mono_class_setup_vtable (klass);
-       if (klass->exception_type != MONO_EXCEPTION_NONE)
-               mono_raise_exception (mono_class_get_exception_for_failure (klass));
+       if (klass->exception_type != MONO_EXCEPTION_NONE || mono_loader_get_last_error ())
+               goto loader_error;              
 
        iter = NULL;
        while ((method = mono_class_get_methods (klass, &iter))) {
                match = 0;
+               if (method->slot != -1) {
+                       g_assert (method->slot < nslots);
+                       if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
+                               continue;
+                       method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
+               }
+
                if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
                        continue;
                if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
@@ -3683,23 +3505,10 @@ handle_parent:
                }
                
                match = 0;
-               if (method->slot != -1) {
-                       g_assert (method->slot < nslots);
-                       if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
-                               continue;
-                       method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
-               }
                
                member = (MonoObject*)mono_method_get_object (domain, method, refklass);
                
-               if (i >= len) {
-                       MonoArray *new_res = mono_array_new_specific (array_vtable, len * 2);
-                       mono_array_memcpy_refs (new_res, 0, res, 0, len);
-                       len *= 2;
-                       res = new_res;
-               }
-               mono_array_setref (res, i, member);
-               ++i;
+               mono_ptr_array_append (tmp_array, member);
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
@@ -3707,16 +3516,28 @@ handle_parent:
        g_free (mname);
        if (method_slots != method_slots_default)
                g_free (method_slots);
-       if (i != len) {
-               MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
-               mono_array_memcpy_refs (new_res, 0, res, 0, i);
-               res = new_res;
-               /*
-                * Better solution for the new GC.
-                * res->max_length = i;
-                */
-       }
+
+       res = mono_array_new_specific (array_vtable, mono_ptr_array_size (tmp_array));
+
+       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+       mono_ptr_array_destroy (tmp_array);
        return res;
+
+loader_error:
+       g_free (mname);
+       if (method_slots != method_slots_default)
+               g_free (method_slots);
+       mono_ptr_array_destroy (tmp_array);
+       if (klass->exception_type != MONO_EXCEPTION_NONE) {
+               ex = mono_class_get_exception_for_failure (klass);
+       } else {
+               ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+               mono_loader_clear_error ();
+       }
+       mono_raise_exception (ex);
+       return NULL;
 }
 
 static MonoArray*
@@ -3728,14 +3549,17 @@ ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflag
        MonoArray *res;
        MonoMethod *method;
        MonoObject *member;
-       int i, len, match;
+       int i, match;
        gpointer iter = NULL;
+       MonoPtrArray tmp_array;
        
        MONO_ARCH_SAVE_REGS;
 
+       mono_ptr_array_init (tmp_array, 4); /*FIXME, guestimating*/
+
        domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref)
-               return mono_array_new (domain, mono_defaults.method_info_class, 0);
+               return mono_array_new_cached (domain, mono_defaults.method_info_class, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
        refklass = mono_class_from_mono_type (reftype->type);
 
@@ -3746,9 +3570,6 @@ ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflag
                System_Reflection_ConstructorInfo = mono_class_from_name (
                        mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
 
-       i = 0;
-       len = 2;
-       res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
        iter = NULL;
        while ((method = mono_class_get_methods (klass, &iter))) {
                match = 0;
@@ -3777,24 +3598,16 @@ ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflag
                        continue;
                member = (MonoObject*)mono_method_get_object (domain, method, refklass);
 
-               if (i >= len) {
-                       MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
-                       mono_array_memcpy_refs (new_res, 0, res, 0, len);
-                       len *= 2;
-                       res = new_res;
-               }
-               mono_array_setref (res, i, member);
-               ++i;
-       }
-       if (i != len) {
-               MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
-               mono_array_memcpy_refs (new_res, 0, res, 0, i);
-               res = new_res;
-               /*
-                * Better solution for the new GC.
-                * res->max_length = i;
-                */
+               mono_ptr_array_append (tmp_array, member);
        }
+
+       res = mono_array_new_cached (domain, System_Reflection_ConstructorInfo, mono_ptr_array_size (tmp_array));
+
+       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+       mono_ptr_array_destroy (tmp_array);
+
        return res;
 }
 
@@ -3839,34 +3652,33 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name,
        MonoMethod *method;
        MonoProperty *prop;
        int i, match;
-       int len = 0;
        guint32 flags;
        gchar *propname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        gpointer iter;
        GHashTable *properties;
+       MonoPtrArray tmp_array;
 
        MONO_ARCH_SAVE_REGS;
 
+       mono_ptr_array_init (tmp_array, 8); /*This the average for ASP.NET types*/
+
        if (!System_Reflection_PropertyInfo)
                System_Reflection_PropertyInfo = mono_class_from_name (
                        mono_defaults.corlib, "System.Reflection", "PropertyInfo");
 
        domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref)
-               return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
+               return mono_array_new_cached (domain, System_Reflection_PropertyInfo, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
        if (name != NULL) {
                propname = mono_string_to_utf8 (name);
-               compare_func = (ignore_case) ? g_strcasecmp : strcmp;
+               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
        }
 
        mono_class_setup_vtable (klass);
 
        properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
-       i = 0;
-       len = 2;
-       res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
 handle_parent:
        mono_class_setup_vtable (klass);
        if (klass->exception_type != MONO_EXCEPTION_NONE) {
@@ -3920,14 +3732,7 @@ handle_parent:
                if (g_hash_table_lookup (properties, prop))
                        continue;
 
-               if (i >= len) {
-                       MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
-                       mono_array_memcpy_refs (new_res, 0, res, 0, len);
-                       len *= 2;
-                       res = new_res;
-               }
-               mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
-               ++i;
+               mono_ptr_array_append (tmp_array, mono_property_get_object (domain, startklass, prop));
                
                g_hash_table_insert (properties, prop, prop);
        }
@@ -3936,15 +3741,13 @@ handle_parent:
 
        g_hash_table_destroy (properties);
        g_free (propname);
-       if (i != len) {
-               MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
-               mono_array_memcpy_refs (new_res, 0, res, 0, i);
-               res = new_res;
-               /*
-                * Better solution for the new GC.
-                * res->max_length = i;
-                */
-       }
+
+       res = mono_array_new_cached (domain, System_Reflection_PropertyInfo, mono_ptr_array_size (tmp_array));
+       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+       mono_ptr_array_destroy (tmp_array);
+
        return res;
 }
 
@@ -3990,21 +3793,20 @@ handle_parent:
                                if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
                                        continue;
                        }
-               }
-               else
-                       if (!(bflags & BFLAGS_NonPublic))
-                               continue;
 
-               if (method->flags & METHOD_ATTRIBUTE_STATIC) {
-                       if (!(bflags & BFLAGS_Static))
-                               continue;
-                       if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
-                               continue;
-               } else {
-                       if (!(bflags & BFLAGS_Instance))
+                       if (method->flags & METHOD_ATTRIBUTE_STATIC) {
+                               if (!(bflags & BFLAGS_Static))
+                                       continue;
+                               if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
+                                       continue;
+                       } else {
+                               if (!(bflags & BFLAGS_Instance))
+                                       continue;
+                       }
+               } else 
+                       if (!(bflags & BFLAGS_NonPublic))
                                continue;
-               }
-
+               
                g_free (event_name);
                return mono_event_get_object (domain, startklass, event);
        }
@@ -4025,23 +3827,24 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, Mon
        MonoArray *res;
        MonoMethod *method;
        MonoEvent *event;
-       int i, len, match;
+       int i, match;
        gpointer iter;
+       
+       MonoPtrArray tmp_array;
 
        MONO_ARCH_SAVE_REGS;
 
+       mono_ptr_array_init (tmp_array, 4);
+
        if (!System_Reflection_EventInfo)
                System_Reflection_EventInfo = mono_class_from_name (
                        mono_defaults.corlib, "System.Reflection", "EventInfo");
 
        domain = mono_object_domain (type);
        if (type->type->byref)
-               return mono_array_new (domain, System_Reflection_EventInfo, 0);
+               return mono_array_new_cached (domain, System_Reflection_EventInfo, 0);
        klass = startklass = mono_class_from_mono_type (type->type);
 
-       i = 0;
-       len = 2;
-       res = mono_array_new (domain, System_Reflection_EventInfo, len);
 handle_parent: 
        if (klass->exception_type != MONO_EXCEPTION_NONE)
                mono_raise_exception (mono_class_get_exception_for_failure (klass));
@@ -4084,27 +3887,18 @@ handle_parent:
                                match ++;
                if (!match)
                        continue;
-               match = 0;
-               if (i >= len) {
-                       MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
-                       mono_array_memcpy_refs (new_res, 0, res, 0, len);
-                       len *= 2;
-                       res = new_res;
-               }
-               mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
-               ++i;
+               mono_ptr_array_append (tmp_array, mono_event_get_object (domain, startklass, event));
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
-       if (i != len) {
-               MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
-               mono_array_memcpy_refs (new_res, 0, res, 0, i);
-               res = new_res;
-               /*
-                * Better solution for the new GC.
-                * res->max_length = i;
-                */
-       }
+
+       res = mono_array_new_cached (domain, System_Reflection_EventInfo, mono_ptr_array_size (tmp_array));
+
+       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+       mono_ptr_array_destroy (tmp_array);
+
        return res;
 }
 
@@ -4119,6 +3913,9 @@ ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint3
        
        MONO_ARCH_SAVE_REGS;
 
+       if (name == NULL)
+               mono_raise_exception (mono_get_exception_argument_null ("name"));
+       
        domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref)
                return NULL;
@@ -4171,9 +3968,10 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
        MonoClass *klass;
        MonoArray *res;
        MonoObject *member;
-       int i, len, match;
+       int i, match;
        MonoClass *nested;
        gpointer iter;
+       MonoPtrArray tmp_array;
 
        MONO_ARCH_SAVE_REGS;
 
@@ -4196,9 +3994,7 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
 
-       i = 0;
-       len = 1;
-       res = mono_array_new (domain, mono_defaults.monotype_class, len);
+       mono_ptr_array_init (tmp_array, 1);
        iter = NULL;
        while ((nested = mono_class_get_nested_types (klass, &iter))) {
                match = 0;
@@ -4212,24 +4008,16 @@ ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
                if (!match)
                        continue;
                member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
-               if (i >= len) {
-                       MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
-                       mono_array_memcpy_refs (new_res, 0, res, 0, len);
-                       len *= 2;
-                       res = new_res;
-               }
-               mono_array_setref (res, i, member);
-               ++i;
-       }
-       if (i != len) {
-               MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
-               mono_array_memcpy_refs (new_res, 0, res, 0, i);
-               res = new_res;
-               /*
-                * Better solution for the new GC.
-                * res->max_length = i;
-                */
+               mono_ptr_array_append (tmp_array, member);
        }
+
+       res = mono_array_new_cached (domain, mono_defaults.monotype_class, mono_ptr_array_size (tmp_array));
+
+       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
+               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
+
+       mono_ptr_array_destroy (tmp_array);
+
        return res;
 }
 
@@ -4310,6 +4098,9 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                if (throwOnError)
                        e = mono_get_exception_type_load (name, NULL);
 
+               if (mono_loader_get_last_error () && mono_defaults.generic_ilist_class)
+                       e = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
+
                mono_loader_clear_error ();
 
                if (e != NULL)
@@ -4339,28 +4130,12 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
        return mono_type_get_object (mono_object_domain (assembly), type);
 }
 
-static MonoString *
-ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
+static gboolean
+replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
-       MonoAssembly *mass = assembly->assembly;
-       MonoString *res = NULL;
-       gchar *uri;
-       gchar *absolute;
        gchar *content;
        gchar *shadow_ini_file;
        gsize len;
-       gchar *dirname;
-       
-       MONO_ARCH_SAVE_REGS;
-
-       if (g_path_is_absolute (mass->image->name)) {
-               absolute = g_strdup (mass->image->name);
-               dirname = g_path_get_dirname (absolute);
-       } else {
-               absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
-               dirname = g_strdup (mass->basedir);
-       }
 
        /* Check for shadow-copied assembly */
        if (mono_is_shadow_copy_enabled (domain, dirname)) {
@@ -4375,13 +4150,38 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse
                }
                g_free (shadow_ini_file);
                if (content != NULL) {
-                       g_free (absolute);
-                       absolute = content;
+                       if (*filename)
+                               g_free (*filename);
+                       *filename = content;
+                       return TRUE;
                }
        }
-       g_free (dirname);
+       return FALSE;
+}
+
+static MonoString *
+ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
+{
+       MonoDomain *domain = mono_object_domain (assembly); 
+       MonoAssembly *mass = assembly->assembly;
+       MonoString *res = NULL;
+       gchar *uri;
+       gchar *absolute;
+       gchar *dirname;
+       
+       MONO_ARCH_SAVE_REGS;
+
+       if (g_path_is_absolute (mass->image->name)) {
+               absolute = g_strdup (mass->image->name);
+               dirname = g_path_get_dirname (absolute);
+       } else {
+               absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
+               dirname = g_strdup (mass->basedir);
+       }
 
-#if PLATFORM_WIN32
+       replace_shadow_path (domain, dirname, &absolute);
+       g_free (dirname);
+#if HOST_WIN32
        {
                gint i;
                for (i = strlen (absolute) - 1; i >= 0; i--)
@@ -4393,7 +4193,7 @@ ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *asse
                uri = g_filename_to_uri (absolute, NULL, NULL);
        } else {
                const char *prepend = "file://";
-#if PLATFORM_WIN32
+#if HOST_WIN32
                if (*absolute == '/' && *(absolute + 1) == '/') {
                        prepend = "file:";
                } else {
@@ -4558,7 +4358,7 @@ ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAsse
 
        result = mono_array_new (domain, System_Reflection_AssemblyName, count);
 
-       if (count > 0) {
+       if (count > 0 && !create_culture) {
                MonoMethodDesc *desc = mono_method_desc_new (
                        "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
                create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
@@ -4639,16 +4439,29 @@ ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *asse
        MonoImage *img = assembly->assembly->image;
        MonoArray *res;
        NameSpaceInfo info;
+       int len;
 
        MONO_ARCH_SAVE_REGS;
 
-       if (!img->name_cache)
-               mono_image_init_name_cache (img);
+       mono_image_lock (img);
+       mono_image_init_name_cache (img);
+
+RETRY_LEN:
+       len = g_hash_table_size (img->name_cache);
+       mono_image_unlock (img);
+
+       /*we can't create objects holding the image lock */
+       res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, len);
+
+       mono_image_lock (img);
+       /*len might have changed, create a new array*/
+       if (len != g_hash_table_size (img->name_cache))
+               goto RETRY_LEN;
 
-       res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
        info.res = res;
        info.idx = 0;
        g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
+       mono_image_unlock (img);
 
        return res;
 }
@@ -4709,7 +4522,7 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflection
        else
                module = assembly->assembly->image;
 
-       *ref_module = mono_module_get_object (mono_domain_get (), module);
+       mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) mono_module_get_object (mono_domain_get (), module));
 
        return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
 }
@@ -4889,7 +4702,8 @@ ves_icall_GetCurrentMethod (void)
 {
        MonoMethod *m = mono_method_get_last_managed ();
 
-       MONO_ARCH_SAVE_REGS;
+       while (m->is_inflated)
+               m = ((MonoMethodInflated*)m)->declaring;
 
        return mono_method_get_object (mono_domain_get (), m, NULL);
 }
@@ -5056,7 +4870,7 @@ fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *a
 
                codebase = g_strdup (absolute);
 
-#if PLATFORM_WIN32
+#if HOST_WIN32
                {
                        gint i;
                        for (i = strlen (codebase) - 1; i >= 0; i--)
@@ -5176,11 +4990,16 @@ ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname,
        gboolean res;
        MonoImage *image;
        MonoAssemblyName name;
+       char *dirname
 
        MONO_ARCH_SAVE_REGS;
 
        filename = mono_string_to_utf8 (fname);
 
+       dirname = g_path_get_dirname (filename);
+       replace_shadow_path (mono_domain_get (), dirname, &filename);
+       g_free (dirname);
+
        image = mono_image_open (filename, &status);
 
        if (!image){
@@ -5462,7 +5281,7 @@ ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module
 static gpointer
 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        if (module->image && module->image->is_module_handle)
                return module->image->raw_data;
 #endif
@@ -5861,7 +5680,10 @@ ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
-       aklass = mono_array_class_get (klass, rank);
+       if (rank == 0) //single dimentional array
+               aklass = mono_array_class_get (klass, 1);
+       else
+               aklass = mono_bounded_array_class_get (klass, rank, TRUE);
 
        return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
 }
@@ -5892,7 +5714,7 @@ ves_icall_Type_MakePointerType (MonoReflectionType *type)
 
 static MonoObject *
 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
-                                                  MonoReflectionMethod *info)
+                                                  MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
 {
        MonoClass *delegate_class = mono_class_from_mono_type (type->type);
        MonoObject *delegate;
@@ -5903,16 +5725,14 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
 
        mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
 
-       /* FIME: We must check if target is visible to the caller under coreclr.
-        * The check should be disabled otherwise as it shouldn't raise expection under fulltrust.
-        */
+       if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) {
+               if (!mono_security_core_clr_ensure_delegate_creation (method, throwOnBindFailure))
+                       return NULL;
+       }
 
        delegate = mono_object_new (mono_object_domain (type), delegate_class);
 
-       if (mono_method_needs_static_rgctx_invoke (method, FALSE)) {
-               method = mono_marshal_get_static_rgctx_invoke (method);
-               func = mono_compile_method (method);
-       } else if (method->dynamic) {
+       if (method->dynamic) {
                /* Creating a trampoline would leak memory */
                func = mono_compile_method (method);
        } else {
@@ -5943,7 +5763,7 @@ ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
  */
 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
 static void
 convert_to_absolute_date(SYSTEMTIME *date)
@@ -5973,7 +5793,7 @@ convert_to_absolute_date(SYSTEMTIME *date)
 }
 #endif
 
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
 /*
  * Return's the offset from GMT of a local time.
  * 
@@ -6013,7 +5833,7 @@ gmt_offset(struct tm *tm, time_t t)
 static guint32
 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
 {
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
        MonoDomain *domain = mono_domain_get ();
        struct tm start, tt;
        time_t t;
@@ -6027,8 +5847,8 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
        MONO_CHECK_ARG_NULL (data);
        MONO_CHECK_ARG_NULL (names);
 
-       (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
-       (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+       mono_gc_wbarrier_generic_store (data, (MonoObject*) mono_array_new (domain, mono_defaults.int64_class, 4));
+       mono_gc_wbarrier_generic_store (names, (MonoObject*) mono_array_new (domain, mono_defaults.string_class, 2));
 
        /* 
         * no info is better than crashing: we'll need our own tz data
@@ -6126,8 +5946,8 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
        MONO_CHECK_ARG_NULL (data);
        MONO_CHECK_ARG_NULL (names);
 
-       (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
-       (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
+       mono_gc_wbarrier_generic_store (data, mono_array_new (domain, mono_defaults.int64_class, 4));
+       mono_gc_wbarrier_generic_store (names, mono_array_new (domain, mono_defaults.string_class, 2));
 
        for (i = 0; i < 32; ++i)
                if (!tz_info.DaylightName [i])
@@ -6304,10 +6124,20 @@ ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
 
 /* System.Environment */
 
+MonoString*
+ves_icall_System_Environment_get_UserName (void)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       /* using glib is more portable */
+       return mono_string_new (mono_domain_get (), g_get_user_name ());
+}
+
+
 static MonoString *
 ves_icall_System_Environment_get_MachineName (void)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        gunichar2 *buf;
        guint32 len;
        MonoString *result;
@@ -6321,7 +6151,7 @@ ves_icall_System_Environment_get_MachineName (void)
 
        g_free (buf);
        return result;
-#else
+#elif !defined(DISABLE_SOCKETS)
        gchar buf [256];
        MonoString *result;
 
@@ -6331,13 +6161,15 @@ ves_icall_System_Environment_get_MachineName (void)
                result = NULL;
        
        return result;
+#else
+       return mono_string_new (mono_domain_get (), "mono");
 #endif
 }
 
 static int
 ves_icall_System_Environment_get_Platform (void)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (TARGET_WIN32)
        /* Win32NT */
        return 2;
 #elif defined(__MACH__)
@@ -6365,7 +6197,7 @@ ves_icall_System_Environment_get_NewLine (void)
 {
        MONO_ARCH_SAVE_REGS;
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        return mono_string_new (mono_domain_get (), "\r\n");
 #else
        return mono_string_new (mono_domain_get (), "\n");
@@ -6404,7 +6236,7 @@ ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
  * arm-apple-darwin9.  We'll manually define the symbol on Apple as it does
  * in fact exist on all implementations (so far) 
  */
-gchar ***_NSGetEnviron();
+gchar ***_NSGetEnviron(void);
 #define environ (*_NSGetEnviron())
 #else
 extern
@@ -6416,7 +6248,7 @@ char **environ;
 static MonoArray *
 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        MonoArray *names;
        MonoDomain *domain;
        MonoString *str;
@@ -6508,7 +6340,9 @@ ves_icall_System_Environment_GetEnvironmentVariableNames (void)
 static void
 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
 {
-#ifdef PLATFORM_WIN32
+       MonoError error;
+#ifdef HOST_WIN32
+
        gunichar2 *utf16_name, *utf16_value;
 #else
        gchar *utf8_name, *utf8_value;
@@ -6516,7 +6350,7 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M
 
        MONO_ARCH_SAVE_REGS;
        
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        utf16_name = mono_string_to_utf16 (name);
        if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
                SetEnvironmentVariable (utf16_name, NULL);
@@ -6539,7 +6373,11 @@ ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, M
                return;
        }
 
-       utf8_value = mono_string_to_utf8 (value);
+       utf8_value = mono_string_to_utf8_checked (value, &error);
+       if (!mono_error_ok (&error)) {
+               g_free (utf8_name);
+               mono_error_raise_exception (&error);
+       }
        g_setenv (utf8_name, utf8_value, TRUE);
 
        g_free (utf8_name);
@@ -6574,7 +6412,7 @@ ves_icall_System_Environment_GetGacPath (void)
 static MonoString*
 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        #ifndef CSIDL_FLAG_CREATE
                #define CSIDL_FLAG_CREATE       0x8000
        #endif
@@ -6747,7 +6585,7 @@ ves_icall_System_Environment_get_HasShutdownStarted (void)
 static void
 ves_icall_System_Environment_BroadcastSettingChange (void)
 {
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, NULL, L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
 #endif
 }
@@ -6834,7 +6672,7 @@ ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (Mo
        MONO_ARCH_SAVE_REGS;
 
        klass = mono_class_from_mono_type (type->type);
-       vtable = mono_class_vtable (mono_domain_get (), klass);
+       vtable = mono_class_vtable_full (mono_domain_get (), klass, TRUE);
 
        if (enable) vtable->remote = 1;
        else vtable->remote = 0;
@@ -6856,7 +6694,7 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas
                return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
        } else {
                /* Bypass remoting object creation check */
-               return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
+               return mono_object_new_alloc_specific (mono_class_vtable_full (domain, klass, TRUE));
        }
 }
 
@@ -6868,6 +6706,46 @@ ves_icall_System_IO_get_temp_path (void)
        return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
 }
 
+#ifndef PLATFORM_NO_DRIVEINFO
+static MonoBoolean
+ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
+                                               guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
+                                               gint32 *error)
+{
+       gboolean result;
+       ULARGE_INTEGER wapi_free_bytes_avail;
+       ULARGE_INTEGER wapi_total_number_of_bytes;
+       ULARGE_INTEGER wapi_total_number_of_free_bytes;
+
+       MONO_ARCH_SAVE_REGS;
+
+       *error = ERROR_SUCCESS;
+       result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
+                                    &wapi_total_number_of_free_bytes);
+
+       if (result) {
+               *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
+               *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
+               *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
+       } else {
+               *free_bytes_avail = 0;
+               *total_number_of_bytes = 0;
+               *total_number_of_free_bytes = 0;
+               *error = GetLastError ();
+       }
+
+       return result;
+}
+
+static guint32
+ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
+{
+       MONO_ARCH_SAVE_REGS;
+
+       return GetDriveType (mono_string_chars (root_path_name));
+}
+#endif
+
 static gpointer
 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
 {
@@ -6886,7 +6764,7 @@ ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
 
        path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        /* Avoid mixing '/' and '\\' */
        {
                gint i;
@@ -6926,7 +6804,7 @@ ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
 
        path = g_path_get_dirname (mono_get_config_dir ());
 
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        /* Avoid mixing '/' and '\\' */
        {
                gint i;
@@ -6941,19 +6819,47 @@ ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
        return ipath;
 }
 
+static gboolean
+ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
+{
+       MonoPEResourceDataEntry *entry;
+       MonoImage *image;
+
+       MONO_ARCH_SAVE_REGS;
+
+       if (!assembly || !result || !size)
+               return FALSE;
+
+       *result = NULL;
+       *size = 0;
+       image = assembly->assembly->image;
+       entry = mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
+       if (!entry)
+               return FALSE;
+
+       *result = mono_image_rva_map (image, entry->rde_data_offset);
+       if (!(*result)) {
+               g_free (entry);
+               return FALSE;
+       }
+       *size = entry->rde_size;
+       g_free (entry);
+       return TRUE;
+}
+
 static MonoBoolean
 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
 {
-       return mono_debug_using_mono_debugger ();
+       return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
 }
 
 static void
 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
 {
-#if defined (PLATFORM_WIN32)
+#if defined (HOST_WIN32)
        OutputDebugString (mono_string_chars (message));
 #else
-       g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
+       g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
 #endif
 }
 
@@ -6977,7 +6883,7 @@ ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
 }
 
 static MonoReflectionMethod *
-ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
+ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
 {
        MonoClass *klass, *parent;
        MonoMethod *method = m->method;
@@ -6997,13 +6903,19 @@ ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
 
-       /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
-       for (parent = klass->parent; parent != NULL; parent = parent->parent) {
-               mono_class_setup_vtable (parent);
-               if (parent->vtable_size <= method->slot)
-                       break;
-               klass = parent;
-       }               
+       if (definition) {
+               /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
+               for (parent = klass->parent; parent != NULL; parent = parent->parent) {
+                       mono_class_setup_vtable (parent);
+                       if (parent->vtable_size <= method->slot)
+                               break;
+                       klass = parent;
+               }
+       } else {
+               klass = klass->parent;
+               if (!klass)
+                       return m;
+       }
 
        if (klass == method->klass)
                return m;
@@ -7047,15 +6959,7 @@ mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
        if (start) {
                iter->args = start;
        } else {
-               guint32 i, arg_size;
-               gint32 align;
                iter->args = argsp + sizeof (gpointer);
-#ifndef MONO_ARCH_REGPARMS
-               for (i = 0; i < iter->sig->sentinelpos; ++i) {
-                       arg_size = mono_type_stack_size (iter->sig->params [i], &align);
-                       iter->args = (char*)iter->args + arg_size;
-               }
-#endif
        }
        iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
 
@@ -7331,22 +7235,22 @@ custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
        if (mono_loader_get_last_error ()) {
                mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
                g_assert_not_reached ();
+               /* Not reached */
+               return NULL;
        } else {
                return res;
        }
 }
 
-static MonoBoolean
-GCHandle_CheckCurrentDomain (guint32 gchandle)
-{
-       return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
-}
-
 static MonoString*
 ves_icall_Mono_Runtime_GetDisplayName (void)
 {
-       static const char display_name_str [] = "Mono " VERSION;
-       MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
+       char *info;
+       MonoString *display_name;
+
+       info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
+       display_name = mono_string_new (mono_domain_get (), info);
+       g_free (info);
        return display_name;
 }
 
@@ -7887,7 +7791,7 @@ type_from_typename (char *typename)
        else if (!strcmp (typename, "boolean"))
                klass = mono_defaults.boolean_class;
        else {
-               g_error (typename);
+               g_error ("%s", typename);
                g_assert_not_reached ();
        }
        return &klass->byval_arg;
@@ -7920,7 +7824,7 @@ mono_create_icall_signature (const char *sigstr)
        res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
        res->pinvoke = 1;
 
-#ifdef PLATFORM_WIN32
+#ifdef HOST_WIN32
        /* 
         * Under windows, the default pinvoke calling convention is STDCALL but
         * we need CDECL.