Merge pull request #487 from mayerwin/patch-1
[mono.git] / mono / metadata / reflection.c
index 281d34f8ddad4b89fd06c9abab19088f04e4d2a8..0c3d2364822f6823828307a9b66db80e72c149dd 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
  *
  */
 #include <config.h>
 #include <mono/metadata/mempool-internals.h>
 #include <mono/metadata/security-core-clr.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/verify-internals.h>
+#include <mono/metadata/mono-ptr-array.h>
 #include <mono/utils/mono-string.h>
 #include <mono/utils/mono-error-internals.h>
 
-
-#if HAVE_SGEN_GC
-static void* reflection_info_desc = NULL;
-#define MOVING_GC_REGISTER(addr) do {  \
-               if (!reflection_info_desc) {    \
-                       gsize bmap = 1;         \
-                       reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);       \
-               }       \
-               mono_gc_register_root ((char*)(addr), sizeof (gpointer), reflection_info_desc); \
-       } while (0)
-#else
-#define MOVING_GC_REGISTER(addr)
-#endif
-
 static gboolean is_usertype (MonoReflectionType *ref);
 static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
 
@@ -157,7 +146,7 @@ const unsigned char table_sizes [MONO_TABLE_NUM] = {
 
 #ifndef DISABLE_REFLECTION_EMIT
 static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec);
-static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_methodspec);
+static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, gboolean create_open_instance);
 static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
 static void    ensure_runtime_vtable (MonoClass *klass);
@@ -201,6 +190,9 @@ static guint32 mono_image_get_methodspec_token (MonoDynamicImage *assembly, Mono
 static guint32 mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m);
 static MonoMethod * inflate_method (MonoReflectionType *type, MonoObject *obj);
 
+static guint32 create_typespec (MonoDynamicImage *assembly, MonoType *type);
+static void init_type_builder_generics (MonoObject *type);
+
 #define RESOLVE_TYPE(type) do { type = (void*)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type); } while (0)
 #define RESOLVE_ARRAY_TYPE_ELEMENT(array, index) do {  \
        MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index);        \
@@ -1171,7 +1163,9 @@ lookup_custom_attr (MonoImage *image, gpointer member)
        if (!res)
                return NULL;
 
-       return g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+       res = g_memdup (res, MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * res->num_attrs);
+       res->cached = 0;
+       return res;
 }
 
 static gboolean
@@ -1296,6 +1290,11 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo
                switch (mono_metadata_token_table (token)) {
                case MONO_TABLE_METHOD:
                        type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+                       /*
+                        * fixup_cattrs () needs to fix this up. We can't use image->tokens, since it contains the old token for the
+                        * method, not the one returned by mono_image_create_token ().
+                        */
+                       mono_g_hash_table_insert (assembly->remapped_tokens, GUINT_TO_POINTER (token), cattr->ctor);
                        break;
                case MONO_TABLE_MEMBERREF:
                        type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
@@ -1549,29 +1548,35 @@ mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuild
        MonoDynamicTable *table;
        guint32 *values;
        guint32 tok;
+       MonoReflectionMethod *m;
+       int i;
 
-       if (!mb->override_method)
+       if (!mb->override_methods)
                return;
 
-       table = &assembly->tables [MONO_TABLE_METHODIMPL];
-       table->rows ++;
-       alloc_table (table, table->rows);
-       values = table->values + table->rows * MONO_METHODIMPL_SIZE;
-       values [MONO_METHODIMPL_CLASS] = tb->table_idx;
-       values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+       for (i = 0; i < mono_array_length (mb->override_methods); ++i) {
+               m = mono_array_get (mb->override_methods, MonoReflectionMethod*, i);
 
-       tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE, FALSE);
-       switch (mono_metadata_token_table (tok)) {
-       case MONO_TABLE_MEMBERREF:
-               tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
-               break;
-       case MONO_TABLE_METHOD:
-               tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
-               break;
-       default:
-               g_assert_not_reached ();
+               table = &assembly->tables [MONO_TABLE_METHODIMPL];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_METHODIMPL_SIZE;
+               values [MONO_METHODIMPL_CLASS] = tb->table_idx;
+               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+               tok = mono_image_create_token (assembly, (MonoObject*)m, FALSE, FALSE);
+               switch (mono_metadata_token_table (tok)) {
+               case MONO_TABLE_MEMBERREF:
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
+                       break;
+               case MONO_TABLE_METHOD:
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+               values [MONO_METHODIMPL_DECLARATION] = tok;
        }
-       values [MONO_METHODIMPL_DECLARATION] = tok;
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -1711,13 +1716,31 @@ field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *
 {
        SigBuffer buf;
        guint32 idx;
+       guint32 typespec = 0;
+       MonoType *type;
+       MonoClass *class;
+
+       init_type_builder_generics (fb->type);
+
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
+       class = mono_class_from_mono_type (type);
 
        sigbuffer_init (&buf, 32);
        
        sigbuffer_add_value (&buf, 0x06);
        encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
        /* encode custom attributes before the type */
-       encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
+
+       if (class->generic_container)
+               typespec = create_typespec (assembly, type);
+
+       if (typespec) {
+               MonoGenericClass *gclass;
+               gclass = mono_metadata_lookup_generic_class (class, class->generic_container->context.class_inst, TRUE);
+               encode_generic_class (assembly, gclass, &buf);
+       } else {
+               encode_type (assembly, type, &buf);
+       }
        idx = sigbuffer_add_to_blob_cached (assembly, &buf);
        sigbuffer_free (&buf);
        return idx;
@@ -1778,12 +1801,18 @@ handle_enum:
 #endif
 #endif
                break;
-       case MONO_TYPE_VALUETYPE:
-               if (val->vtable->klass->enumtype) {
-                       *ret_type = mono_class_enum_basetype (val->vtable->klass)->type;
+       case MONO_TYPE_VALUETYPE: {
+               MonoClass *klass = val->vtable->klass;
+               
+               if (klass->enumtype) {
+                       *ret_type = mono_class_enum_basetype (klass)->type;
                        goto handle_enum;
-               } else
-                       g_error ("we can't encode valuetypes");
+               } else if (mono_is_corlib_image (klass->image) && strcmp (klass->name_space, "System") == 0 && strcmp (klass->name, "DateTime") == 0) {
+                       len = 8;
+               } else 
+                       g_error ("we can't encode valuetypes, we should have never reached this line");
+               break;
+       }
        case MONO_TYPE_CLASS:
                break;
        case MONO_TYPE_STRING: {
@@ -1981,7 +2010,10 @@ property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBui
        if (!mb && smb && smb->parameters)
                nparams = mono_array_length (smb->parameters) - 1;
        sigbuffer_init (&buf, 32);
-       sigbuffer_add_byte (&buf, 0x08);
+       if (fb->call_conv & 0x20)
+               sigbuffer_add_byte (&buf, 0x28);
+       else
+               sigbuffer_add_byte (&buf, 0x08);
        sigbuffer_add_value (&buf, nparams);
        if (mb) {
                encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf);
@@ -2172,7 +2204,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        entry = g_new0 (GenericParamTableEntry, 1);
        entry->owner = owner;
        /* FIXME: track where gen_params should be freed and remove the GC root as well */
-       MOVING_GC_REGISTER (&entry->gparam);
+       MONO_GC_REGISTER_ROOT_IF_MOVING (entry->gparam);
        entry->gparam = gparam;
        
        g_ptr_array_add (assembly->gen_params, entry);
@@ -2649,11 +2681,13 @@ mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtor
        if (token)
                return token;
 
-       g_assert (tb->generic_params);
-
        reflection_methodbuilder_from_ctor_builder (&rmb, mb);
 
-       parent = create_generic_typespec (assembly, tb);
+       if (tb->generic_params)
+               parent = create_generic_typespec (assembly, tb);
+       else
+               parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)tb));
+       
        name = mono_string_to_utf8 (rmb.name);
        sig = method_builder_encode_signature (assembly, &rmb);
 
@@ -2704,29 +2738,29 @@ get_field_on_inst_generic_type (MonoClassField *field)
 
 #ifndef DISABLE_REFLECTION_EMIT
 static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoClassField *field)
 {
        MonoType *type;
        guint32 token;
-       MonoClassField *field;
+
+       g_assert (field);
+       g_assert (field->parent);
 
        token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, f));
        if (token)
                return token;
-       g_assert (f->field->parent);
 
-       field = f->field;
        if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) {
                int index = field - field->parent->fields;
                type = field->parent->generic_class->container_class->fields [index].type;
        } else {
-               if (is_field_on_inst (f->field))
-                       type = get_field_on_inst_generic_type (f->field);
+               if (is_field_on_inst (field))
+                       type = get_field_on_inst_generic_type (field);
                else
-                       type = f->field->type;
+                       type = mono_field_get_type (field);
        }
-       token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg, 
-                                                                                       mono_field_get_name (f->field),  
+       token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
+                                                                                       mono_field_get_name (field),
                                                                                        fieldref_encode_signature (assembly, field->parent->image, type));
        mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER(token));
        return token;
@@ -2768,7 +2802,7 @@ mono_image_get_field_on_inst_token (MonoDynamicImage *assembly, MonoReflectionFi
                token = mono_image_get_memberref_token (assembly, &klass->byval_arg, field->name, sig);
        } else {
                char *name = mono_type_get_full_name (mono_object_class (f->fb));
-               g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
+               g_error ("mono_image_get_field_on_inst_token: don't know how to handle %s", name);
        }
 
        mono_g_hash_table_insert (assembly->handleref_managed, f, GUINT_TO_POINTER (token));
@@ -2838,6 +2872,8 @@ mono_reflection_method_on_tb_inst_get_handle (MonoReflectionMethodOnTypeBuilderI
        MonoMethod *method, *inflated;
        int count, i;
 
+       init_type_builder_generics ((MonoObject*)m->inst);
+
        method = inflate_method (m->inst, (MonoObject*)m->mb);
 
        klass = method->klass;
@@ -3139,12 +3175,25 @@ add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *mod
        return t;
 }
 
+static void
+init_type_builder_generics (MonoObject *type)
+{
+       MonoReflectionTypeBuilder *tb;
+
+       if (!is_sre_type_builder(mono_object_class (type)))
+               return;
+       tb = (MonoReflectionTypeBuilder *)type;
+
+       if (tb && tb->generic_container)
+               mono_reflection_create_generic_class (tb);
+}
+
 static guint32
 mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
 {
        MonoDynamicTable *table;
        MonoClass *klass;
-       MonoType *custom = NULL;
+       MonoType *custom = NULL, *type;
        guint32 *values;
        guint32 token, pclass, parent, sig;
        gchar *name;
@@ -3156,15 +3205,17 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        klass = mono_class_from_mono_type (mono_reflection_type_get_handle (fb->typeb));
        name = mono_string_to_utf8 (fb->name);
 
+       /*FIXME this is one more layer of ugliness due how types are created.*/
+       init_type_builder_generics (fb->type);
+
        /* fb->type does not include the custom modifiers */
        /* FIXME: We should do this in one place when a fieldbuilder is created */
-       if (fb->modreq || fb->modopt) {
-               custom = add_custom_modifiers (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type), fb->modreq, fb->modopt);
-               sig = fieldref_encode_signature (assembly, NULL, custom);
-               g_free (custom);
-       } else {
-               sig = fieldref_encode_signature (assembly, NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
-       }
+       type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
+       if (fb->modreq || fb->modopt)
+               type = custom = add_custom_modifiers (assembly, type, fb->modreq, fb->modopt);
+
+       sig = fieldref_encode_signature (assembly, NULL, type);
+       g_free (custom);
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
        g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
@@ -3501,11 +3552,11 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
 #endif
 
 static void
-collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
+collect_types (MonoPtrArray *types, MonoReflectionTypeBuilder *type)
 {
        int i;
 
-       g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */
+       mono_ptr_array_append (*types, type);
 
        if (!type->subtypes)
                return;
@@ -3755,29 +3806,32 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu
        }
 }
 
-static guint32
-add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass)
+static void
+add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass, guint32 parent_index)
 {
        MonoDynamicTable *table;
        guint32 *values;
-       guint32 scope, idx, res, impl;
+       guint32 scope, scope_idx, impl, current_idx;
        gboolean forwarder = TRUE;
+       gpointer iter = NULL;
+       MonoClass *nested;
 
        if (klass->nested_in) {
-               impl = add_exported_type (assemblyb, assembly, klass->nested_in);
+               impl = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
                forwarder = FALSE;
        } else {
                scope = resolution_scope_from_image (assembly, klass->image);
                g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
-               idx = scope >> MONO_RESOLTION_SCOPE_BITS;
-               impl = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+               scope_idx = scope >> MONO_RESOLTION_SCOPE_BITS;
+               impl = (scope_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
        }
 
        table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
 
        table->rows++;
        alloc_table (table, table->rows);
-       values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
+       current_idx = table->next_idx;
+       values = table->values + current_idx * MONO_EXP_TYPE_SIZE;
 
        values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
        values [MONO_EXP_TYPE_TYPEDEF] = 0;
@@ -3785,11 +3839,10 @@ add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *a
        values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
        values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
 
-       res = (table->next_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
-
        table->next_idx++;
 
-       return res;
+       while ((nested = mono_class_get_nested_types (klass, &iter)))
+               add_exported_type (assemblyb, assembly, nested, current_idx);
 }
 
 static void
@@ -3812,7 +3865,7 @@ mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder
 
                klass = mono_class_from_mono_type (type);
 
-               add_exported_type (assemblyb, assembly, klass);
+               add_exported_type (assemblyb, assembly, klass, 0);
        }
 }
 
@@ -4281,13 +4334,17 @@ fixup_cattrs (MonoDynamicImage *assembly)
                if ((type & MONO_CUSTOM_ATTR_TYPE_MASK) == MONO_CUSTOM_ATTR_TYPE_METHODDEF) {
                        idx = type >> MONO_CUSTOM_ATTR_TYPE_BITS;
                        token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
-                       ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+                       ctor = mono_g_hash_table_lookup (assembly->remapped_tokens, GUINT_TO_POINTER (token));
                        g_assert (ctor);
 
                        if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
                                MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
                                idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
                                values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
+                       } else if (!strcmp (ctor->vtable->klass->name, "ConstructorBuilder")) {
+                               MonoMethod *m = ((MonoReflectionCtorBuilder*)ctor)->mhandle;
+                               idx = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->method_to_table_idx, m));
+                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
                        }
                }
        }
@@ -4531,7 +4588,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
        MonoDynamicImage *assembly;
        MonoReflectionAssemblyBuilder *assemblyb;
        MonoDomain *domain;
-       GPtrArray *types;
+       MonoPtrArray types;
        guint32 *values;
        int i, j;
 
@@ -4589,34 +4646,34 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
        mono_image_fill_module_table (domain, moduleb, assembly);
 
        /* Collect all types into a list sorted by their table_idx */
-       types = g_ptr_array_new ();
+       mono_ptr_array_init (types, moduleb->num_types);
 
        if (moduleb->types)
                for (i = 0; i < moduleb->num_types; ++i) {
                        MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
-                       collect_types (types, type);
+                       collect_types (&types, type);
                }
 
-       g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx);
+       mono_ptr_array_sort (types, (gpointer)compare_types_by_table_idx);
        table = &assembly->tables [MONO_TABLE_TYPEDEF];
-       table->rows += types->len;
+       table->rows += mono_ptr_array_size (types);
        alloc_table (table, table->rows);
 
        /*
         * Emit type names + namespaces at one place inside the string heap,
         * so load_class_names () needs to touch fewer pages.
         */
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *tb = mono_ptr_array_get (types, i);
                string_heap_insert_mstring (&assembly->sheap, tb->nspace);
        }
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *tb = mono_ptr_array_get (types, i);
                string_heap_insert_mstring (&assembly->sheap, tb->name);
        }
 
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *type = mono_ptr_array_get (types, i);
                mono_image_get_type_info (domain, type, assembly);
        }
 
@@ -4650,8 +4707,8 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
                }
        }
 
-       for (i = 0; i < types->len; ++i) {
-               MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+       for (i = 0; i < mono_ptr_array_size (types); ++i) {
+               MonoReflectionTypeBuilder *type = mono_ptr_array_get (types, i);
                if (type->methods) {
                        for (j = 0; j < type->num_methods; ++j) {
                                MonoReflectionMethodBuilder *mb = mono_array_get (
@@ -4662,7 +4719,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
                }
        }
 
-       g_ptr_array_free (types, TRUE);
+       mono_ptr_array_destroy (types);
 
        fixup_cattrs (assembly);
 }
@@ -4745,11 +4802,12 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
 {
        MonoClass *klass;
        guint32 token = 0;
+       MonoMethodSignature *sig;
 
        klass = obj->vtable->klass;
        if (strcmp (klass->name, "MonoMethod") == 0) {
                MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
-               MonoMethodSignature *sig, *old;
+               MonoMethodSignature *old;
                guint32 sig_token, parent;
                int nargs, i;
 
@@ -4787,13 +4845,37 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
        } else if (strcmp (klass->name, "MethodBuilder") == 0) {
                MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
                ReflectionMethodBuilder rmb;
-               guint32 parent, sig;
+               guint32 parent, sig_token;
+               int nopt_args, nparams, ngparams, i;
                char *name;
 
                reflection_methodbuilder_from_method_builder (&rmb, mb);
                rmb.opt_types = opt_param_types;
+               nopt_args = mono_array_length (opt_param_types);
 
-               sig = method_builder_encode_signature (assembly, &rmb);
+               nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
+               ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
+               sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);
+
+               sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
+               sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
+               sig->call_convention = rmb.call_conv;
+               sig->generic_param_count = ngparams;
+               sig->param_count = nparams + nopt_args;
+               sig->sentinelpos = nparams;
+               sig->ret = mono_reflection_type_get_handle (rmb.rtype);
+
+               for (i = 0; i < nparams; i++) {
+                       MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
+                       sig->params [i] = mono_reflection_type_get_handle (rt);
+               }
+
+               for (i = 0; i < nopt_args; i++) {
+                       MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
+                       sig->params [nparams + i] = mono_reflection_type_get_handle (rt);
+               }
+
+               sig_token = method_builder_encode_signature (assembly, &rmb);
 
                parent = mono_image_create_token (assembly, obj, TRUE, TRUE);
                g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
@@ -4803,12 +4885,14 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
 
                name = mono_string_to_utf8 (rmb.name);
                token = mono_image_get_varargs_method_token (
-                       assembly, parent, name, sig);
+                       assembly, parent, name, sig_token);
                g_free (name);
        } else {
                g_error ("requested method token for %s\n", klass->name);
        }
 
+       g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
+       mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
        return token;
 }
 
@@ -4825,7 +4909,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
  */
 guint32
 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
-                                                gboolean create_methodspec, gboolean register_token)
+                                                gboolean create_open_instance, gboolean register_token)
 {
        MonoClass *klass;
        guint32 token = 0;
@@ -4844,7 +4928,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                if (tb->module->dynamic_image == assembly && !tb->generic_params && !mb->generic_params)
                        token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
                else
-                       token = mono_image_get_methodbuilder_token (assembly, mb, create_methodspec);
+                       token = mono_image_get_methodbuilder_token (assembly, mb, create_open_instance);
                /*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
        } else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
                MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
@@ -4861,16 +4945,32 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                if (tb->generic_params) {
                        token = mono_image_get_generic_field_token (assembly, fb);
                } else {
-                       token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+                       if (tb->module->dynamic_image == assembly) {
+                               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+                       } else {
+                               token = mono_image_get_fieldref_token (assembly, (MonoObject*)fb, fb->handle);
+                       }
                }
        } else if (strcmp (klass->name, "TypeBuilder") == 0) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
-               token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+               if (create_open_instance && tb->generic_params) {
+                       MonoType *type;
+                       init_type_builder_generics (obj);
+                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+                       token = mono_image_typedef_or_ref_full (assembly, type, TRUE);
+                       token = mono_metadata_token_from_dor (token);
+               } else if (tb->module->dynamic_image == assembly) {
+                       token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
+               } else {
+                       MonoType *type;
+                       type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
+                       token = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, type));
+               }
        } else if (strcmp (klass->name, "MonoType") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                MonoClass *mc = mono_class_from_mono_type (type);
                token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL));
+                       mono_image_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance));
        } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                token = mono_metadata_token_from_dor (
@@ -4885,7 +4985,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                   strcmp (klass->name, "MonoGenericCMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
                if (m->method->is_inflated) {
-                       if (create_methodspec)
+                       if (create_open_instance)
                                token = mono_image_get_methodspec_token (assembly, m->method);
                        else
                                token = mono_image_get_inflated_method_token (assembly, m->method);
@@ -4908,7 +5008,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                                token = MONO_TOKEN_METHOD_DEF | method_table_idx;
                        }
                } else {
-                       token = mono_image_get_methodref_token (assembly, m->method, create_methodspec);
+                       token = mono_image_get_methodref_token (assembly, m->method, create_open_instance);
                }
                /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
        } else if (strcmp (klass->name, "MonoField") == 0) {
@@ -4918,7 +5018,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
                } else {
-                       token = mono_image_get_fieldref_token (assembly, f);
+                       token = mono_image_get_fieldref_token (assembly, (MonoObject*)f, f->field);
                }
                /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
        } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
@@ -4936,10 +5036,10 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
                token = mono_image_get_field_on_inst_token (assembly, f);
        } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) {
                MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
-               token = mono_image_get_ctor_on_inst_token (assembly, c, create_methodspec);
+               token = mono_image_get_ctor_on_inst_token (assembly, c, create_open_instance);
        } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
                MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
-               token = mono_image_get_method_on_inst_token (assembly, m, create_methodspec);
+               token = mono_image_get_method_on_inst_token (assembly, m, create_open_instance);
        } else if (is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) {
                MonoReflectionType *type = (MonoReflectionType *)obj;
                token = mono_metadata_token_from_dor (
@@ -4987,6 +5087,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
                version = mono_get_runtime_info ()->runtime_version;
 
 #if HAVE_BOEHM_GC
+       /* The MonoGHashTable's need GC tracking */
        image = GC_MALLOC (sizeof (MonoDynamicImage));
 #else
        image = g_new0 (MonoDynamicImage, 1);
@@ -5013,6 +5114,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->method_to_table_idx = g_hash_table_new (NULL, NULL);
        image->field_to_table_idx = g_hash_table_new (NULL, NULL);
        image->method_aux_hash = g_hash_table_new (NULL, NULL);
+       image->vararg_aux_hash = g_hash_table_new (NULL, NULL);
        image->handleref = g_hash_table_new (NULL, NULL);
        image->handleref_managed = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC);
        image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
@@ -5022,6 +5124,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
        image->gen_params = g_ptr_array_new ();
+       image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
 
        /*g_print ("string heap create for image %p (%s)\n", image, module_name);*/
        string_heap_init (&image->sheap);
@@ -5062,6 +5165,26 @@ free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
        g_free (key);
 }
 
+static void
+release_hashtable (MonoGHashTable **hash)
+{
+       if (*hash) {
+               mono_g_hash_table_destroy (*hash);
+               *hash = NULL;
+       }
+}
+
+void
+mono_dynamic_image_release_gc_roots (MonoDynamicImage *image)
+{
+       release_hashtable (&image->token_fixups);
+       release_hashtable (&image->handleref_managed);
+       release_hashtable (&image->tokens);
+       release_hashtable (&image->remapped_tokens);
+       release_hashtable (&image->generic_def_objects);
+       release_hashtable (&image->methodspec);
+}
+
 void
 mono_dynamic_image_free (MonoDynamicImage *image)
 {
@@ -5081,6 +5204,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                mono_g_hash_table_destroy (di->handleref_managed);
        if (di->tokens)
                mono_g_hash_table_destroy (di->tokens);
+       if (di->remapped_tokens)
+               mono_g_hash_table_destroy (di->remapped_tokens);
        if (di->generic_def_objects)
                mono_g_hash_table_destroy (di->generic_def_objects);
        if (di->blob_cache) {
@@ -5099,11 +5224,6 @@ mono_dynamic_image_free (MonoDynamicImage *image)
        if (di->gen_params) {
                for (i = 0; i < di->gen_params->len; i++) {
                        GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i);
-                       if (entry->gparam->type.type) {
-                               MonoGenericParam *param = entry->gparam->type.type->data.generic_param;
-                               g_free ((char*)mono_generic_param_info (param)->name);
-                               g_free (param);
-                       }
                        mono_gc_deregister_root ((char*) &entry->gparam);
                        g_free (entry);
                }
@@ -5117,6 +5237,8 @@ mono_dynamic_image_free (MonoDynamicImage *image)
                g_hash_table_destroy (di->field_to_table_idx);
        if (di->method_aux_hash)
                g_hash_table_destroy (di->method_aux_hash);
+       if (di->vararg_aux_hash)
+               g_hash_table_destroy (di->vararg_aux_hash);
        g_free (di->strong_name);
        g_free (di->win32_res);
        if (di->public_key)
@@ -5157,6 +5279,7 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
                return;
 
 #if HAVE_BOEHM_GC
+       /* assembly->assembly.image might be GC allocated */
        assembly = assemblyb->dynamic_assembly = GC_MALLOC (sizeof (MonoDynamicAssembly));
 #else
        assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
@@ -6117,14 +6240,18 @@ mono_image_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflecti
 MonoReflectionAssembly*
 mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
 {
-       static MonoClass *System_Reflection_Assembly;
+       static MonoClass *assembly_type;
        MonoReflectionAssembly *res;
        
        CHECK_OBJECT (MonoReflectionAssembly *, assembly, NULL);
-       if (!System_Reflection_Assembly)
-               System_Reflection_Assembly = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "Assembly");
-       res = (MonoReflectionAssembly *)mono_object_new (domain, System_Reflection_Assembly);
+       if (!assembly_type) {
+               MonoClass *class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoAssembly");
+               if (class == NULL)
+                       class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Assembly");
+               g_assert (class);
+               assembly_type = class;
+       }
+       res = (MonoReflectionAssembly *)mono_object_new (domain, assembly_type);
        res->assembly = assembly;
 
        CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
@@ -6135,15 +6262,19 @@ mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
 MonoReflectionModule*   
 mono_module_get_object   (MonoDomain *domain, MonoImage *image)
 {
-       static MonoClass *System_Reflection_Module;
+       static MonoClass *module_type;
        MonoReflectionModule *res;
        char* basename;
        
        CHECK_OBJECT (MonoReflectionModule *, image, NULL);
-       if (!System_Reflection_Module)
-               System_Reflection_Module = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "Module");
-       res = (MonoReflectionModule *)mono_object_new (domain, System_Reflection_Module);
+       if (!module_type) {
+               MonoClass *class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoModule");
+               if (class == NULL)
+                       class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
+               g_assert (class);
+               module_type = class;
+       }
+       res = (MonoReflectionModule *)mono_object_new (domain, module_type);
 
        res->image = image;
        MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
@@ -6175,7 +6306,7 @@ mono_module_get_object   (MonoDomain *domain, MonoImage *image)
 MonoReflectionModule*   
 mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_index)
 {
-       static MonoClass *System_Reflection_Module;
+       static MonoClass *module_type;
        MonoReflectionModule *res;
        MonoTableInfo *table;
        guint32 cols [MONO_FILE_SIZE];
@@ -6183,10 +6314,14 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        guint32 i, name_idx;
        const char *val;
        
-       if (!System_Reflection_Module)
-               System_Reflection_Module = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "Module");
-       res = (MonoReflectionModule *)mono_object_new (domain, System_Reflection_Module);
+       if (!module_type) {
+               MonoClass *class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoModule");
+               if (class == NULL)
+                       class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
+               g_assert (class);
+               module_type = class;
+       }
+       res = (MonoReflectionModule *)mono_object_new (domain, module_type);
 
        table = &image->tables [MONO_TABLE_FILE];
        g_assert (table_index < table->rows);
@@ -6214,146 +6349,6 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        return res;
 }
 
-static gboolean
-mymono_metadata_type_equal (MonoType *t1, MonoType *t2)
-{
-       if ((t1->type != t2->type) ||
-           (t1->byref != t2->byref))
-               return FALSE;
-
-       switch (t1->type) {
-       case MONO_TYPE_VOID:
-       case MONO_TYPE_BOOLEAN:
-       case MONO_TYPE_CHAR:
-       case MONO_TYPE_I1:
-       case MONO_TYPE_U1:
-       case MONO_TYPE_I2:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_I4:
-       case MONO_TYPE_U4:
-       case MONO_TYPE_I8:
-       case MONO_TYPE_U8:
-       case MONO_TYPE_R4:
-       case MONO_TYPE_R8:
-       case MONO_TYPE_STRING:
-       case MONO_TYPE_I:
-       case MONO_TYPE_U:
-       case MONO_TYPE_OBJECT:
-       case MONO_TYPE_TYPEDBYREF:
-               return TRUE;
-       case MONO_TYPE_VALUETYPE:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_SZARRAY:
-               return t1->data.klass == t2->data.klass;
-       case MONO_TYPE_PTR:
-               return mymono_metadata_type_equal (t1->data.type, t2->data.type);
-       case MONO_TYPE_ARRAY:
-               if (t1->data.array->rank != t2->data.array->rank)
-                       return FALSE;
-               return t1->data.array->eklass == t2->data.array->eklass;
-       case MONO_TYPE_GENERICINST: {
-               int i;
-               MonoGenericInst *i1 = t1->data.generic_class->context.class_inst;
-               MonoGenericInst *i2 = t2->data.generic_class->context.class_inst;
-               if (i1->type_argc != i2->type_argc)
-                       return FALSE;
-               if (!mono_metadata_type_equal (&t1->data.generic_class->container_class->byval_arg,
-                                              &t2->data.generic_class->container_class->byval_arg))
-                       return FALSE;
-               /* FIXME: we should probably just compare the instance pointers directly.  */
-               for (i = 0; i < i1->type_argc; ++i) {
-                       if (!mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i]))
-                               return FALSE;
-               }
-               return TRUE;
-       }
-       case MONO_TYPE_VAR:
-       case MONO_TYPE_MVAR:
-               return t1->data.generic_param == t2->data.generic_param;
-       default:
-               g_error ("implement type compare for %0x!", t1->type);
-               return FALSE;
-       }
-
-       return FALSE;
-}
-
-static guint
-mymono_metadata_type_hash (MonoType *t1)
-{
-       guint hash;
-
-       hash = t1->type;
-
-       hash |= t1->byref << 6; /* do not collide with t1->type values */
-       switch (t1->type) {
-       case MONO_TYPE_VALUETYPE:
-       case MONO_TYPE_CLASS:
-       case MONO_TYPE_SZARRAY:
-               /* check if the distribution is good enough */
-               return ((hash << 5) - hash) ^ g_str_hash (t1->data.klass->name);
-       case MONO_TYPE_PTR:
-               return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
-       case MONO_TYPE_GENERICINST: {
-               int i;
-               MonoGenericInst *inst = t1->data.generic_class->context.class_inst;
-               hash += g_str_hash (t1->data.generic_class->container_class->name);
-               hash *= 13;
-               for (i = 0; i < inst->type_argc; ++i) {
-                       hash += mymono_metadata_type_hash (inst->type_argv [i]);
-                       hash *= 13;
-               }
-               return hash;
-       }
-       }
-       return hash;
-}
-
-static MonoReflectionGenericClass*
-mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
-{
-       static MonoClass *System_Reflection_MonoGenericClass;
-       MonoReflectionGenericClass *res;
-       MonoClass *klass, *gklass;
-       MonoGenericInst *ginst;
-       MonoArray *type_args;
-       int i;
-       MonoObject *tb;
-
-       g_assert (0); /*This code path should not be taken anymore, all MGC instantiation must happen in managed code*/
-
-       if (!System_Reflection_MonoGenericClass) {
-               System_Reflection_MonoGenericClass = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
-               g_assert (System_Reflection_MonoGenericClass);
-       }
-
-       klass = mono_class_from_mono_type (geninst);
-       gklass = klass->generic_class->container_class;
-
-       mono_class_init (klass);
-
-#ifdef HAVE_SGEN_GC
-       res = (MonoReflectionGenericClass *) mono_gc_alloc_pinned_obj (mono_class_vtable (domain, System_Reflection_MonoGenericClass), mono_class_instance_size (System_Reflection_MonoGenericClass));
-#else
-       res = (MonoReflectionGenericClass *) mono_object_new (domain, System_Reflection_MonoGenericClass);
-#endif
-
-       res->type.type = geninst;
-       tb = mono_class_get_ref_info (gklass);
-       g_assert (tb);
-       g_assert (!strcmp (tb->vtable->klass->name, "TypeBuilder"));
-       MONO_OBJECT_SETREF (res, generic_type, tb);
-
-       ginst = klass->generic_class->context.class_inst;
-       type_args = mono_array_new (domain, mono_defaults.systemtype_class, ginst->type_argc);
-       for (i = 0; i < ginst->type_argc; ++i)
-               mono_array_setref (type_args, i, mono_type_get_object (domain, ginst->type_argv [i]));
-       MONO_OBJECT_SETREF (res, type_arguments, type_args);
-
-       return res;
-}
-
 static gboolean
 verify_safe_for_managed_space (MonoType *type)
 {
@@ -6383,6 +6378,49 @@ verify_safe_for_managed_space (MonoType *type)
        return TRUE;
 }
 
+static MonoType*
+mono_type_normalize (MonoType *type)
+{
+       int i;
+       MonoGenericClass *gclass;
+       MonoGenericInst *ginst;
+       MonoClass *gtd;
+       MonoGenericContainer *gcontainer;
+       MonoType **argv = NULL;
+       gboolean is_denorm_gtd = TRUE, requires_rebind = FALSE;
+
+       if (type->type != MONO_TYPE_GENERICINST)
+               return type;
+
+       gclass = type->data.generic_class;
+       ginst = gclass->context.class_inst;
+       if (!ginst->is_open)
+               return type;
+
+       gtd = gclass->container_class;
+       gcontainer = gtd->generic_container;
+       argv = g_newa (MonoType*, ginst->type_argc);
+
+       for (i = 0; i < ginst->type_argc; ++i) {
+               MonoType *t = ginst->type_argv [i], *norm;
+               if (t->type != MONO_TYPE_VAR || t->data.generic_param->num != i || t->data.generic_param->owner != gcontainer)
+                       is_denorm_gtd = FALSE;
+               norm = mono_type_normalize (t);
+               argv [i] = norm;
+               if (norm != t)
+                       requires_rebind = TRUE;
+       }
+
+       if (is_denorm_gtd)
+               return type->byref == gtd->byval_arg.byref ? &gtd->byval_arg : &gtd->this_arg;
+
+       if (requires_rebind) {
+               MonoClass *klass = mono_class_bind_generic_parameters (gtd, ginst->type_argc, argv, gclass->is_dynamic);
+               return type->byref == klass->byval_arg.byref ? &klass->byval_arg : &klass->this_arg;
+       }
+
+       return type;
+}
 /*
  * mono_type_get_object:
  * @domain: an app domain
@@ -6393,6 +6431,7 @@ verify_safe_for_managed_space (MonoType *type)
 MonoReflectionType*
 mono_type_get_object (MonoDomain *domain, MonoType *type)
 {
+       MonoType *norm_type;
        MonoReflectionType *res;
        MonoClass *klass = mono_class_from_mono_type (type);
 
@@ -6423,22 +6462,34 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
        mono_loader_lock (); /*FIXME mono_class_init and mono_class_vtable acquire it*/
        mono_domain_lock (domain);
        if (!domain->type_hash)
-               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
-                               (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+               domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
+                               (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC);
        if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) {
                mono_domain_unlock (domain);
                mono_loader_unlock ();
                return res;
        }
-       /* Create a MonoGenericClass object for instantiations of not finished TypeBuilders */
-       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder) {
-               res = (MonoReflectionType *)mono_generic_class_get_object (domain, type);
+
+       /*Types must be normalized so a generic instance of the GTD get's the same inner type.
+        * For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
+        * The second Bar will be encoded a generic instance of Bar with <A> as parameter.
+        * On all other places, Bar<A> will be encoded as the GTD itself. This is an implementation
+        * artifact of how generics are encoded and should be transparent to managed code so we
+        * need to weed out this diference when retrieving managed System.Type objects.
+        */
+       norm_type = mono_type_normalize (type);
+       if (norm_type != type) {
+               res = mono_type_get_object (domain, norm_type);
                mono_g_hash_table_insert (domain->type_hash, type, res);
                mono_domain_unlock (domain);
                mono_loader_unlock ();
                return res;
        }
 
+       /* This MonoGenericClass hack is no longer necessary. Let's leave it here until we finish with the 2-stage type-builder setup.*/
+       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder)
+               g_assert (0);
+
        if (!verify_safe_for_managed_space (type)) {
                mono_domain_unlock (domain);
                mono_loader_unlock ();
@@ -6473,13 +6524,8 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                        return mono_class_get_ref_info (klass);
                }
        }
-       // FIXME: Get rid of this, do it in the icalls for Type
-       mono_class_init (klass);
-#ifdef HAVE_SGEN_GC
-       res = (MonoReflectionType *)mono_gc_alloc_pinned_obj (mono_class_vtable (domain, mono_defaults.monotype_class), mono_class_instance_size (mono_defaults.monotype_class));
-#else
-       res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class);
-#endif
+       /* This is stored in vtables/JITted code so it has to be pinned */
+       res = (MonoReflectionType *)mono_object_new_pinned (domain, mono_defaults.monotype_class);
        res->type = type;
        mono_g_hash_table_insert (domain->type_hash, type, res);
 
@@ -6601,11 +6647,15 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res->klass = klass;
        res->field = field;
        MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));
-       if (is_field_on_inst (field))
+
+       if (is_field_on_inst (field)) {
                res->attrs = get_field_on_inst_generic_type (field)->attrs;
-       else
-               res->attrs = field->type->attrs;
-       MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+               MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+       } else {
+               if (field->type)
+                       MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+               res->attrs = mono_field_get_flags (field);
+       }
        CACHE_OBJECT (MonoReflectionField *, field, res, klass);
 }
 
@@ -6716,6 +6766,7 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
 {
        static MonoClass *System_Reflection_ParameterInfo;
        static MonoClass *System_Reflection_ParameterInfo_array;
+       MonoError error;
        MonoArray *res = NULL;
        MonoReflectionMethod *member = NULL;
        MonoReflectionParameter *param = NULL;
@@ -6740,8 +6791,12 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
                mono_memory_barrier ();
                System_Reflection_ParameterInfo_array = klass;
        }
-       
-       if (!mono_method_signature (method)->param_count)
+
+       sig = mono_method_signature_checked (method, &error);
+       if (!mono_error_ok (&error))
+               mono_error_raise_exception (&error);
+
+       if (!sig->param_count)
                return mono_array_new_specific (mono_class_vtable (domain, System_Reflection_ParameterInfo_array), 0);
 
        /* Note: the cache is based on the address of the signature into the method
@@ -6749,7 +6804,6 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
         */
        CHECK_OBJECT (MonoArray*, &(method->signature), refclass);
 
-       sig = mono_method_signature (method);
        member = mono_method_get_object (domain, method, refclass);
        names = g_new (char *, sig->param_count);
        mono_method_get_param_names (method, (const char **) names);
@@ -6808,7 +6862,7 @@ mono_param_get_objects_internal (MonoDomain *domain, MonoMethod *method, MonoCla
                }
 
                if (mspecs [i + 1])
-                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
+                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
                
                mono_array_setref (res, i, param);
        }
@@ -6845,13 +6899,17 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        static MonoClass *System_Reflection_LocalVariableInfo = NULL;
        static MonoClass *System_Reflection_ExceptionHandlingClause = NULL;
        MonoReflectionMethodBody *ret;
-       MonoMethodNormal *mn;
        MonoMethodHeader *header;
+       MonoImage *image;
        guint32 method_rva, local_var_sig_token;
     char *ptr;
        unsigned char format, flags;
        int i;
 
+       /* for compatibility with .net */
+    if (method->dynamic)
+        mono_raise_exception (mono_get_exception_invalid_operation (NULL));
+
        if (!System_Reflection_MethodBody)
                System_Reflection_MethodBody = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MethodBody");
        if (!System_Reflection_LocalVariableInfo)
@@ -6866,27 +6924,31 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
            (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
            (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME))
                return NULL;
-       mn = (MonoMethodNormal *)method;
+
+       image = method->klass->image;
        header = mono_method_get_header (method);
-       
-       /* Obtain local vars signature token */
-       method_rva = mono_metadata_decode_row_col (&method->klass->image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
-       ptr = mono_image_rva_map (method->klass->image, method_rva);
-       flags = *(const unsigned char *) ptr;
-       format = flags & METHOD_HEADER_FORMAT_MASK;
-       switch (format){
-       case METHOD_HEADER_TINY_FORMAT:
-               local_var_sig_token = 0;
-               break;
-       case METHOD_HEADER_FAT_FORMAT:
-               ptr += 2;
-               ptr += 2;
-               ptr += 4;
-               local_var_sig_token = read32 (ptr);
-               break;
-       default:
-               g_assert_not_reached ();
-       }
+
+       if (!image->dynamic) {
+               /* Obtain local vars signature token */
+               method_rva = mono_metadata_decode_row_col (&image->tables [MONO_TABLE_METHOD], mono_metadata_token_index (method->token) - 1, MONO_METHOD_RVA);
+               ptr = mono_image_rva_map (image, method_rva);
+               flags = *(const unsigned char *) ptr;
+               format = flags & METHOD_HEADER_FORMAT_MASK;
+               switch (format){
+               case METHOD_HEADER_TINY_FORMAT:
+                       local_var_sig_token = 0;
+                       break;
+               case METHOD_HEADER_FAT_FORMAT:
+                       ptr += 2;
+                       ptr += 2;
+                       ptr += 4;
+                       local_var_sig_token = read32 (ptr);
+                       break;
+               default:
+                       g_assert_not_reached ();
+               }
+       } else
+               local_var_sig_token = 0; //FIXME
 
        ret = (MonoReflectionMethodBody*)mono_object_new (domain, System_Reflection_MethodBody);
 
@@ -6925,6 +6987,7 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
                mono_array_setref (ret->clauses, i, info);
        }
 
+       mono_metadata_free_mh (header);
        CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
        return ret;
 }
@@ -7053,23 +7116,35 @@ static int
 assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        int found_sep;
        char *s;
+       gboolean quoted = FALSE;
 
        memset (assembly, 0, sizeof (MonoAssemblyName));
-       assembly->name = p;
        assembly->culture = "";
        memset (assembly->public_key_token, 0, MONO_PUBLIC_KEY_TOKEN_LENGTH);
 
-       while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@'))
+       if (*p == '"') {
+               quoted = TRUE;
+               p++;
+       }
+       assembly->name = p;
+       while (*p && (isalnum (*p) || *p == '.' || *p == '-' || *p == '_' || *p == '$' || *p == '@' || g_ascii_isspace (*p)))
                p++;
-       found_sep = 0;
-       while (g_ascii_isspace (*p) || *p == ',') {
-               *p++ = 0;
-               found_sep = 1;
-               continue;
-       }
-       /* failed */
-       if (!found_sep)
+       if (quoted) {
+               if (*p != '"')
+                       return 1;
+               *p = 0;
+               p++;
+       }
+       if (*p != ',')
                return 1;
+       *p = 0;
+       /* Remove trailing whitespace */
+       s = p - 1;
+       while (*s && g_ascii_isspace (*s))
+               *s-- = 0;
+       p ++;
+       while (g_ascii_isspace (*p))
+               p++;
        while (*p) {
                if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
                        p += 8;
@@ -7257,7 +7332,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                                        if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
                                                return 0;
 
-                                       if (fqname) {
+                                       /*MS is lenient on [] delimited parameters that aren't fqn - and F# uses them.*/
+                                       if (fqname && (*p != ']')) {
                                                char *aname;
 
                                                if (*p != ',')
@@ -7282,6 +7358,8 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                                                if (!*aname ||
                                                    !assembly_name_to_aname (&subinfo->assembly, aname))
                                                        return 0;
+                                       } else if (fqname && (*p == ']')) {
+                                               *p++ = 0;
                                        }
 
                                        if (i + 1 < arity) {
@@ -7429,7 +7507,6 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
        }
        if (!klass)
                return NULL;
-       mono_class_init (klass);
 
        if (info->type_arguments) {
                MonoType **type_args = g_new0 (MonoType *, info->type_arguments->len);
@@ -7470,7 +7547,6 @@ mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoT
                } else { /* array rank */
                        klass = mono_bounded_array_class_get (klass, modval, bounded);
                }
-               mono_class_init (klass);
        }
 
        return &klass->byval_arg;
@@ -7647,14 +7723,17 @@ mono_reflection_get_token (MonoObject *obj)
        } else if (strcmp (klass->name, "FieldBuilder") == 0) {
                MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
 
-               /* Call mono_image_create_token so the object gets added to the tokens hash table */
-               token = mono_image_create_token (((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image, obj, FALSE, TRUE);
+               token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
        } else if (strcmp (klass->name, "TypeBuilder") == 0) {
                MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
                token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
        } else if (strcmp (klass->name, "MonoType") == 0) {
-               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
-               token = mono_class_from_mono_type (type)->type_token;
+               MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
+               MonoClass *mc = mono_class_from_mono_type (type);
+               if (!mono_class_init (mc))
+                       mono_raise_exception (mono_class_get_exception_for_failure (mc));
+
+               token = mc->type_token;
        } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                   strcmp (klass->name, "MonoMethod") == 0 ||
                   strcmp (klass->name, "MonoGenericMethod") == 0 ||
@@ -7693,11 +7772,11 @@ mono_reflection_get_token (MonoObject *obj)
                g_assert (mono_class_is_reflection_method_or_constructor (member_class));
 
                token = mono_method_get_param_token (((MonoReflectionMethod*)p->MemberImpl)->method, p->PositionImpl);
-       } else if (strcmp (klass->name, "Module") == 0) {
+       } else if (strcmp (klass->name, "Module") == 0 || strcmp (klass->name, "MonoModule") == 0) {
                MonoReflectionModule *m = (MonoReflectionModule*)obj;
 
                token = m->token;
-       } else if (strcmp (klass->name, "Assembly") == 0) {
+       } else if (strcmp (klass->name, "Assembly") == 0 || strcmp (klass->name, "MonoAssembly") == 0) {
                token = mono_metadata_make_token (MONO_TABLE_ASSEMBLY, 1);
        } else {
                gchar *msg = g_strdup_printf ("MetadataToken is not supported for type '%s.%s'", klass->name_space, klass->name);
@@ -7767,9 +7846,18 @@ handle_enum:
                        type = mono_class_enum_basetype (t->data.klass)->type;
                        goto handle_enum;
                } else {
-                       g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
+                       MonoClass *k =  t->data.klass;
+                       
+                       if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
+                               guint64 *val = g_malloc (sizeof (guint64));
+                               *val = read64 (p);
+                               *end = p + 8;
+                               return val;
+                       }
                }
+               g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
                break;
+               
        case MONO_TYPE_STRING:
                if (*p == (char)0xFF) {
                        *end = p + 1;
@@ -7815,13 +7903,17 @@ handle_type:
                        int etype = *p;
                        p ++;
 
-                       if (etype == 0x51)
-                               /* See Partition II, Appendix B3 */
-                               etype = MONO_TYPE_OBJECT;
                        type = MONO_TYPE_SZARRAY;
-                       simple_type.type = etype;
-                       tklass = mono_class_from_mono_type (&simple_type);
-                       goto handle_enum;
+                       if (etype == 0x50) {
+                               tklass = mono_defaults.systemtype_class;
+                       } else {
+                               if (etype == 0x51)
+                                       /* See Partition II, Appendix B3 */
+                                       etype = MONO_TYPE_OBJECT;
+                               simple_type.type = etype;
+                               tklass = mono_class_from_mono_type (&simple_type);
+                       }
+                       goto handle_enum;
                } else if (subt == 0x55) {
                        char *n;
                        MonoType *t;
@@ -7844,7 +7936,7 @@ handle_type:
                val = load_cattr_value (image, &subc->byval_arg, p, end);
                obj = mono_object_new (mono_domain_get (), subc);
                g_assert (!subc->has_references);
-               memcpy ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
+               mono_gc_memmove ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
                g_free (val);
                return obj;
        }
@@ -8046,7 +8138,7 @@ find_event_index (MonoClass *klass, MonoEvent *event) {
 }
 
 static MonoObject*
-create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoError *error)
 {
        const char *p = (const char*)data;
        const char *named;
@@ -8056,8 +8148,15 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, gu
        void **params;
        MonoMethodSignature *sig;
 
+       mono_error_init (error);
+
        mono_class_init (method->klass);
 
+       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL)) {
+               mono_error_set_generic_error (error, "System.Reflection", "CustomAttributeFormatException", "Binary format of the specified custom attribute was invalid.");
+               return NULL;
+       }
+
        if (len == 0) {
                attr = mono_object_new (mono_domain_get (), method->klass);
                mono_runtime_invoke (method, attr, NULL, NULL);
@@ -8158,6 +8257,9 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
        guint32 i, j, num_named;
        CattrNamedArg *arginfo = NULL;
 
+       if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL))
+               return;
+
        mono_class_init (method->klass);
 
        *typed_args = NULL;
@@ -8256,35 +8358,35 @@ mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *meth
        *named_args = namedargs;
 }
 
-static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+void
+mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args)
 {
-       MonoArray *typedargs, *namedargs;
-       static MonoMethod *ctor;
        MonoDomain *domain;
-       MonoObject *attr;
-       void *params [3];
+       MonoArray *typedargs, *namedargs;
+       MonoImage *image;
+       MonoMethod *method;
        CattrNamedArg *arginfo;
        int i;
 
-       mono_class_init (method->klass);
+       *ctor_args = NULL;
+       *named_args = NULL;
 
-       if (!ctor)
-               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+       if (len == 0)
+               return;
 
-       domain = mono_domain_get ();
-       if (len == 0) {
-               /* This is for Attributes with no parameters */
-               attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
-               params [0] = mono_method_get_object (domain, method, NULL);
-               params [1] = params [2] = NULL;
-               mono_runtime_invoke (method, attr, params, NULL);
-               return attr;
-       }
+       image = assembly->assembly->image;
+       method = ref_method->method;
+       domain = mono_object_domain (ref_method);
+
+       if (!mono_class_init (method->klass))
+               mono_raise_exception (mono_class_get_exception_for_failure (method->klass));
 
        mono_reflection_create_custom_attr_data_args (image, method, data, len, &typedargs, &namedargs, &arginfo);
+       if (mono_loader_get_last_error ())
+               mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
+
        if (!typedargs || !namedargs)
-               return NULL;
+               return;
 
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
                MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
@@ -8309,51 +8411,59 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *dat
                mono_array_setref (namedargs, i, namedarg);
        }
 
-       attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
-       params [0] = mono_method_get_object (domain, method, NULL);
-       params [1] = typedargs;
-       params [2] = namedargs;
-       mono_runtime_invoke (ctor, attr, params, NULL);
-       return attr;
+       *ctor_args = typedargs;
+       *named_args = namedargs;
 }
 
-MonoArray*
-mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr)
 {
-       MonoArray *result;
+       static MonoMethod *ctor;
+       MonoDomain *domain;
        MonoObject *attr;
-       int i;
+       void *params [4];
 
-       result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
-       for (i = 0; i < cinfo->num_attrs; ++i) {
-               if (!cinfo->attrs [i].ctor)
-                       /* The cattr type is not finished yet */
-                       /* We should include the type name but cinfo doesn't contain it */
-                       mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
-               attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
-               mono_array_setref (result, i, attr);
-       }
-       return result;
+       g_assert (image->assembly);
+
+       if (!ctor)
+               ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);
+
+       domain = mono_domain_get ();
+       attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
+       params [0] = mono_method_get_object (domain, cattr->ctor, NULL);
+       params [1] = mono_assembly_get_object (domain, image->assembly);
+       params [2] = (gpointer)&cattr->data;
+       params [3] = &cattr->data_size;
+       mono_runtime_invoke (ctor, attr, params, NULL);
+       return attr;
 }
 
 static MonoArray*
-mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
+mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass, MonoError *error)
 {
        MonoArray *result;
        MonoObject *attr;
        int i, n;
 
+       mono_error_init (error);
+
        n = 0;
        for (i = 0; i < cinfo->num_attrs; ++i) {
-               if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
+               if (!attr_klass || mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
                        n ++;
        }
 
        result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n);
        n = 0;
        for (i = 0; i < cinfo->num_attrs; ++i) {
-               if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
-                       attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
+               if (!cinfo->attrs [i].ctor)
+                       /* The cattr type is not finished yet */
+                       /* We should include the type name but cinfo doesn't contain it */
+                       mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+               if (!attr_klass || mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
+                       attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size, error);
+                       if (!mono_error_ok (error))
+                               return result;
                        mono_array_setref (result, n, attr);
                        n ++;
                }
@@ -8361,6 +8471,14 @@ mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_
        return result;
 }
 
+MonoArray*
+mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
+{
+       MonoError error;
+
+       return mono_custom_attrs_construct_by_type (cinfo, NULL, &error);
+}
+
 static MonoArray*
 mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
 {
@@ -8370,7 +8488,7 @@ mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
        
        result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs);
        for (i = 0; i < cinfo->num_attrs; ++i) {
-               attr = create_custom_attr_data (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
+               attr = create_custom_attr_data (cinfo->image, &cinfo->attrs [i]);
                mono_array_setref (result, i, attr);
        }
        return result;
@@ -8430,6 +8548,14 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
                        g_free (ainfo);
                        return NULL;
                }
+
+               if (!mono_verifier_verify_cattr_blob (image, cols [MONO_CUSTOM_ATTR_VALUE], NULL)) {
+                       /*FIXME raising an exception here doesn't make any sense*/
+                       g_warning ("Invalid custom attribute blob on image %s for index %x", image->name, idx);
+                       g_list_free (list);
+                       g_free (ainfo);
+                       return NULL;
+               }
                data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
                ainfo->attrs [i].data_size = mono_metadata_decode_value (data, &data);
                ainfo->attrs [i].data = (guchar*)data;
@@ -8597,6 +8723,8 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
 
        image = method->klass->image;
        method_index = mono_method_get_index (method);
+       if (!method_index)
+               return NULL;
        ca = &image->tables [MONO_TABLE_METHOD];
 
        param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
@@ -8680,11 +8808,12 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
        if (klass == mono_defaults.monotype_class) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
                klass = mono_class_from_mono_type (type);
+               /*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
                cinfo = mono_custom_attrs_from_class (klass);
-       } else if (strcmp ("Assembly", klass->name) == 0) {
+       } else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
                MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
                cinfo = mono_custom_attrs_from_assembly (rassembly->assembly);
-       } else if (strcmp ("Module", klass->name) == 0) {
+       } else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
                MonoReflectionModule *module = (MonoReflectionModule*)obj;
                cinfo = mono_custom_attrs_from_module (module->image);
        } else if (strcmp ("MonoProperty", klass->name) == 0) {
@@ -8716,11 +8845,13 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                        g_assert (method);
 
                        cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
-               } else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
+               } 
+#ifndef DISABLE_REFLECTION_EMIT
+               else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
                        MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl);
                        cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
                } else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
-               MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
+                       MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
                        MonoMethod *method = NULL;
                        if (is_sre_ctor_builder (mono_object_class (c->cb)))
                                method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
@@ -8730,7 +8861,9 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
                                g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
 
                        cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
-               } else {
+               } 
+#endif
+               else {
                        char *type_name = mono_type_get_full_name (member_class);
                        char *msg = g_strdup_printf ("Custom attributes on a ParamInfo with member %s are not supported", type_name);
                        MonoException *ex = mono_get_exception_not_supported  (msg);
@@ -8776,17 +8909,16 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
  * occurs.
  */
 MonoArray*
-mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error)
 {
        MonoArray *result;
        MonoCustomAttrInfo *cinfo;
 
+       mono_error_init (error);
+
        cinfo = mono_reflection_get_custom_attrs_info (obj);
        if (cinfo) {
-               if (attr_klass)
-                       result = mono_custom_attrs_construct_by_type (cinfo, attr_klass);
-               else
-                       result = mono_custom_attrs_construct (cinfo);
+               result = mono_custom_attrs_construct_by_type (cinfo, attr_klass, error);
                if (!cinfo->cached)
                        mono_custom_attrs_free (cinfo);
        } else {
@@ -8809,7 +8941,9 @@ mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass
 MonoArray*
 mono_reflection_get_custom_attrs (MonoObject *obj)
 {
-       return mono_reflection_get_custom_attrs_by_type (obj, NULL);
+       MonoError error;
+
+       return mono_reflection_get_custom_attrs_by_type (obj, NULL, &error);
 }
 
 /*
@@ -8849,7 +8983,6 @@ mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
         return (MonoReflectionType *) mono_runtime_invoke (usertype_method, t, NULL, NULL);
 }
 
-#ifndef DISABLE_REFLECTION_EMIT
 
 static gboolean
 is_corlib_type (MonoClass *class)
@@ -8868,6 +9001,8 @@ is_corlib_type (MonoClass *class)
        return FALSE; \
 } while (0) \
 
+
+#ifndef DISABLE_REFLECTION_EMIT
 static gboolean
 is_sre_array (MonoClass *class)
 {
@@ -8916,42 +9051,6 @@ is_sre_field_builder (MonoClass *class)
        check_corlib_type_cached (class, "System.Reflection.Emit", "FieldBuilder");
 }
 
-static gboolean
-is_sr_mono_method (MonoClass *class)
-{
-       check_corlib_type_cached (class, "System.Reflection", "MonoMethod");
-}
-
-static gboolean
-is_sr_mono_cmethod (MonoClass *class)
-{
-       check_corlib_type_cached (class, "System.Reflection", "MonoCMethod");
-}
-
-static gboolean
-is_sr_mono_generic_method (MonoClass *class)
-{
-       check_corlib_type_cached (class, "System.Reflection", "MonoGenericMethod");
-}
-
-static gboolean
-is_sr_mono_generic_cmethod (MonoClass *class)
-{
-       check_corlib_type_cached (class, "System.Reflection", "MonoGenericCMethod");
-}
-
-static gboolean
-is_sr_mono_field (MonoClass *class)
-{
-       check_corlib_type_cached (class, "System.Reflection", "MonoField");
-}
-
-static gboolean
-is_sr_mono_property (MonoClass *class)
-{
-       check_corlib_type_cached (class, "System.Reflection", "MonoProperty");
-}
-
 static gboolean
 is_sre_method_on_tb_inst (MonoClass *class)
 {
@@ -8964,12 +9063,6 @@ is_sre_ctor_on_tb_inst (MonoClass *class)
        check_corlib_type_cached (class, "System.Reflection.Emit", "ConstructorOnTypeBuilderInst");
 }
 
-gboolean
-mono_class_is_reflection_method_or_constructor (MonoClass *class)
-{
-       return is_sr_mono_method (class) || is_sr_mono_cmethod (class) || is_sr_mono_generic_method (class) || is_sr_mono_generic_cmethod (class);
-}
-
 MonoType*
 mono_reflection_type_get_handle (MonoReflectionType* ref)
 {
@@ -9070,8 +9163,8 @@ mono_reflection_register_with_runtime (MonoReflectionType *type)
                mono_class_setup_supertypes (class);
        } else {
                if (!domain->type_hash)
-                       domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
-                                       (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
+                       domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mono_metadata_type_hash, 
+                                       (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC);
                mono_g_hash_table_insert (domain->type_hash, res, type);
        }
        mono_domain_unlock (domain);
@@ -9187,8 +9280,56 @@ is_sre_generic_instance (MonoClass *class)
        return FALSE;
 }
 
+static void
+init_type_builder_generics (MonoObject *type)
+{
+}
+
 #endif /* !DISABLE_REFLECTION_EMIT */
 
+
+static gboolean
+is_sr_mono_field (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoField");
+}
+
+static gboolean
+is_sr_mono_property (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoProperty");
+}
+
+static gboolean
+is_sr_mono_method (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoMethod");
+}
+
+static gboolean
+is_sr_mono_cmethod (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoCMethod");
+}
+
+static gboolean
+is_sr_mono_generic_method (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoGenericMethod");
+}
+
+static gboolean
+is_sr_mono_generic_cmethod (MonoClass *class)
+{
+       check_corlib_type_cached (class, "System.Reflection", "MonoGenericCMethod");
+}
+
+gboolean
+mono_class_is_reflection_method_or_constructor (MonoClass *class)
+{
+       return is_sr_mono_method (class) || is_sr_mono_cmethod (class) || is_sr_mono_generic_method (class) || is_sr_mono_generic_cmethod (class);
+}
+
 static gboolean
 is_usertype (MonoReflectionType *ref)
 {
@@ -9694,7 +9835,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                        (!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
                klass->instance_size = sizeof (MonoObject);
                klass->size_inited = 1;
-               mono_class_setup_vtable_general (klass, NULL, 0);
+               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
        }
 
        mono_class_setup_mono_type (klass);
@@ -9773,6 +9914,7 @@ mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
                /*Make sure we are a diferent type instance */
                klass->generic_container->type_params [i].param.owner = klass->generic_container;
                klass->generic_container->type_params [i].info.pklass = NULL;
+               klass->generic_container->type_params [i].info.flags = gparam->attrs;
 
                g_assert (klass->generic_container->type_params [i].param.owner);
        }
@@ -9827,7 +9969,7 @@ mono_reflection_create_internal_class (MonoReflectionTypeBuilder *tb)
                 * to create objects of the enum type (for use in SetConstant).
                 */
                /* FIXME: Does this mean enums can't have method overrides ? */
-               mono_class_setup_vtable_general (klass, NULL, 0);
+               mono_class_setup_vtable_general (klass, NULL, 0, NULL);
        }
        mono_loader_unlock ();
 }
@@ -9877,45 +10019,46 @@ mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
 }
 #endif /* !DISABLE_REFLECTION_EMIT */
 
-MonoReflectionMarshal*
-mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
+MonoReflectionMarshalAsAttribute*
+mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
                                                                                   MonoMarshalSpec *spec)
 {
-       static MonoClass *System_Reflection_Emit_UnmanagedMarshalClass;
-       MonoReflectionMarshal *minfo;
+       static MonoClass *System_Reflection_Emit_MarshalAsAttribute;
+       MonoReflectionMarshalAsAttribute *minfo;
        MonoType *mtype;
 
-       if (!System_Reflection_Emit_UnmanagedMarshalClass) {
-               System_Reflection_Emit_UnmanagedMarshalClass = mono_class_from_name (
-                  mono_defaults.corlib, "System.Reflection.Emit", "UnmanagedMarshal");
-               g_assert (System_Reflection_Emit_UnmanagedMarshalClass);
+       if (!System_Reflection_Emit_MarshalAsAttribute) {
+               System_Reflection_Emit_MarshalAsAttribute = mono_class_from_name (
+                  mono_defaults.corlib, "System.Runtime.InteropServices", "MarshalAsAttribute");
+               g_assert (System_Reflection_Emit_MarshalAsAttribute);
        }
 
-       minfo = (MonoReflectionMarshal*)mono_object_new (domain, System_Reflection_Emit_UnmanagedMarshalClass);
-       minfo->type = spec->native;
+       minfo = (MonoReflectionMarshalAsAttribute*)mono_object_new (domain, System_Reflection_Emit_MarshalAsAttribute);
+       minfo->utype = spec->native;
 
-       switch (minfo->type) {
+       switch (minfo->utype) {
        case MONO_NATIVE_LPARRAY:
-               minfo->eltype = spec->data.array_data.elem_type;
-               minfo->count = spec->data.array_data.num_elem;
-               minfo->param_num = spec->data.array_data.param_num;
+               minfo->array_subtype = spec->data.array_data.elem_type;
+               minfo->size_const = spec->data.array_data.num_elem;
+               if (spec->data.array_data.param_num != -1)
+                       minfo->size_param_index = spec->data.array_data.param_num;
                break;
 
        case MONO_NATIVE_BYVALTSTR:
        case MONO_NATIVE_BYVALARRAY:
-               minfo->count = spec->data.array_data.num_elem;
+               minfo->size_const = spec->data.array_data.num_elem;
                break;
 
        case MONO_NATIVE_CUSTOM:
                if (spec->data.custom_data.custom_name) {
                        mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
                        if (mtype)
-                               MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype));
+                               MONO_OBJECT_SETREF (minfo, marshal_type_ref, mono_type_get_object (domain, mtype));
 
-                       MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name));
+                       MONO_OBJECT_SETREF (minfo, marshal_type, mono_string_new (domain, spec->data.custom_data.custom_name));
                }
                if (spec->data.custom_data.cookie)
-                       MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie));
+                       MONO_OBJECT_SETREF (minfo, marshal_cookie, mono_string_new (domain, spec->data.custom_data.cookie));
                break;
 
        default:
@@ -9933,7 +10076,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
 {
        MonoError error;
        MonoMethod *m;
-       MonoMethodNormal *pm;
+       MonoMethodWrapper *wrapperm;
        MonoMarshalSpec **specs;
        MonoReflectionMethodAux *method_aux;
        MonoImage *image;
@@ -9957,21 +10100,19 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
-       else if (rmb->refs)
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
        else
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodNormal, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
 
-       pm = (MonoMethodNormal*)m;
+       wrapperm = (MonoMethodWrapper*)m;
 
        m->dynamic = dynamic;
        m->slot = -1;
        m->flags = rmb->attrs;
        m->iflags = rmb->iattrs;
-       m->name = mono_string_to_utf8_image (image, rmb->name, &error);
-       g_assert (mono_error_ok (&error));
+       m->name = mono_string_to_utf8_image_ignore (image, rmb->name);
        m->klass = klass;
        m->signature = sig;
+       m->sre_method = TRUE;
        m->skip_visibility = rmb->skip_visibility;
        if (rmb->table_idx)
                m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
@@ -10051,7 +10192,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                 rmb->ilgen, num_clauses);
                }
 
-               pm->header = header;
+               wrapperm->header = header;
        }
 
        if (rmb->generic_params) {
@@ -10074,6 +10215,23 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        container->type_params [i] = *param;
                }
 
+               /*
+                * The method signature might have pointers to generic parameters that belong to other methods.
+                * This is a valid SRE case, but the resulting method signature must be encoded using the proper
+                * generic parameters.
+                */
+               for (i = 0; i < m->signature->param_count; ++i) {
+                       MonoType *t = m->signature->params [i];
+                       if (t->type == MONO_TYPE_MVAR) {
+                               MonoGenericParam *gparam =  t->data.generic_param;
+                               if (gparam->num < count) {
+                                       m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
+                                       m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
+                               }
+
+                       }
+               }
+
                if (klass->generic_container) {
                        container->parent = klass->generic_container;
                        container->context.class_inst = klass->generic_container->context.class_inst;
@@ -10224,10 +10382,12 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
 {
        MonoClassField *field;
        MonoType *custom;
+       MonoError error;
 
        field = g_new0 (MonoClassField, 1);
 
-       field->name = mono_string_to_utf8 (fb->name);
+       field->name = mono_string_to_utf8_image (klass->image, fb->name, &error);
+       g_assert (mono_error_ok (&error));
        if (fb->attrs || fb->modreq || fb->modopt) {
                field->type = mono_metadata_type_dup (NULL, mono_reflection_type_get_handle ((MonoReflectionType*)fb->type));
                field->type->attrs = fb->attrs;
@@ -10235,7 +10395,8 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
                g_assert (klass->image->dynamic);
                custom = add_custom_modifiers ((MonoDynamicImage*)klass->image, field->type, fb->modreq, fb->modopt);
                g_free (field->type);
-               field->type = custom;
+               field->type = mono_metadata_type_dup (klass->image, custom);
+               g_free (custom);
        } else {
                field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
        }
@@ -10381,6 +10542,9 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
                mono_loader_unlock ();
        }
+
+       if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
+               mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
        
        return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
 }
@@ -10404,7 +10568,7 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
 
        context = mono_class_get_context (klass);
 
-       if (klass->method.count) {
+       if (klass->method.count && klass->methods) {
                /* Find the already created inflated method */
                for (i = 0; i < klass->method.count; ++i) {
                        g_assert (klass->methods [i]->is_inflated);
@@ -10466,9 +10630,7 @@ inflate_method (MonoReflectionType *type, MonoObject *obj)
 
 /*TODO avoid saving custom attrs for generic classes as it's enough to have them on the generic type definition.*/
 void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
-                                         MonoArray *ctors, MonoArray *fields, MonoArray *properties,
-                                         MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
 {
        MonoGenericClass *gclass;
        MonoDynamicGenericClass *dgclass;
@@ -10494,27 +10656,11 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        gklass = gclass->container_class;
        mono_class_init (gklass);
 
-       dgclass->count_methods = methods ? mono_array_length (methods) : 0;
-       dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
        dgclass->count_fields = fields ? mono_array_length (fields) : 0;
 
-       dgclass->methods = g_new0 (MonoMethod *, dgclass->count_methods);
-       dgclass->ctors = g_new0 (MonoMethod *, dgclass->count_ctors);
-       dgclass->fields = g_new0 (MonoClassField, dgclass->count_fields);
-       dgclass->field_objects = g_new0 (MonoObject*, dgclass->count_fields);
-       dgclass->field_generic_types = g_new0 (MonoType*, dgclass->count_fields);
-
-       for (i = 0; i < dgclass->count_methods; i++) {
-               MonoObject *obj = mono_array_get (methods, gpointer, i);
-
-               dgclass->methods [i] = inflate_method ((MonoReflectionType*)type, obj);
-       }
-
-       for (i = 0; i < dgclass->count_ctors; i++) {
-               MonoObject *obj = mono_array_get (ctors, gpointer, i);
-
-               dgclass->ctors [i] = inflate_method ((MonoReflectionType*)type, obj);
-       }
+       dgclass->fields = mono_image_set_new0 (gclass->owner, MonoClassField, dgclass->count_fields);
+       dgclass->field_objects = mono_image_set_new0 (gclass->owner, MonoObject*, dgclass->count_fields);
+       dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
 
        for (i = 0; i < dgclass->count_fields; i++) {
                MonoObject *obj = mono_array_get (fields, gpointer, i);
@@ -10534,19 +10680,36 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
                dgclass->fields [i].type = mono_class_inflate_generic_type (
                        field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass));
                dgclass->field_generic_types [i] = field->type;
-               MOVING_GC_REGISTER (&dgclass->field_objects [i]);
+               MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
                dgclass->field_objects [i] = obj;
 
                if (inflated_field) {
                        g_free (inflated_field);
                } else {
-                       dgclass->fields [i].name = g_strdup (dgclass->fields [i].name);
+                       dgclass->fields [i].name = mono_image_set_strdup (gclass->owner, dgclass->fields [i].name);
                }
        }
 
        dgclass->initialized = TRUE;
 }
 
+void
+mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+{
+       MonoDynamicGenericClass *dgclass;
+       int i;
+
+       g_assert (gclass->is_dynamic);
+
+       dgclass = (MonoDynamicGenericClass *)gclass;
+
+       for (i = 0; i < dgclass->count_fields; ++i) {
+               MonoClassField *field = dgclass->fields + i;
+               mono_metadata_free_type (field->type);
+               MONO_GC_UNREGISTER_ROOT_IF_MOVING (dgclass->field_objects [i]);
+       }
+}
+
 static void
 fix_partial_generic_class (MonoClass *klass)
 {
@@ -10558,6 +10721,25 @@ fix_partial_generic_class (MonoClass *klass)
                return;
 
        dgclass = (MonoDynamicGenericClass *)  klass->generic_class;
+       if (klass->parent != gklass->parent) {
+               MonoError error;
+               MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, &error);
+               if (mono_error_ok (&error)) {
+                       MonoClass *parent = mono_class_from_mono_type (parent_type);
+                       mono_metadata_free_type (parent_type);
+                       if (parent != klass->parent) {
+                               /*fool mono_class_setup_parent*/
+                               klass->supertypes = NULL;
+                               mono_class_setup_parent (klass, parent);
+                       }
+               } else {
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+                       mono_error_cleanup (&error);
+                       if (gklass->wastypebuilder)
+                               klass->wastypebuilder = TRUE;
+                       return;
+               }
+       }
 
        if (!dgclass->initialized)
                return;
@@ -10653,8 +10835,12 @@ ensure_runtime_vtable (MonoClass *klass)
        }
 
        if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
-               for (i = 0; i < klass->method.count; ++i)
-                       klass->methods [i]->slot = i;
+               int slot_num = 0;
+               for (i = 0; i < klass->method.count; ++i) {
+                       MonoMethod *im = klass->methods [i];
+                       if (!(im->flags & METHOD_ATTRIBUTE_STATIC))
+                               im->slot = slot_num++;
+               }
                
                klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
                mono_class_setup_interface_offsets (klass);
@@ -10673,11 +10859,51 @@ ensure_runtime_vtable (MonoClass *klass)
         */
 }
 
+static MonoMethod*
+mono_reflection_method_get_handle (MonoObject *method)
+{
+       MonoClass *class = mono_object_class (method);
+       if (is_sr_mono_method (class) || is_sr_mono_generic_method (class)) {
+               MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
+               return sr_method->method;
+       }
+       if (is_sre_method_builder (class)) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
+               return mb->mhandle;
+       }
+       if (is_sre_method_on_tb_inst (class)) {
+               MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
+               MonoMethod *result;
+               /*FIXME move this to a proper method and unify with resolve_object*/
+               if (m->method_args) {
+                       result = mono_reflection_method_on_tb_inst_get_handle (m);
+               } else {
+                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
+                       MonoClass *inflated_klass = mono_class_from_mono_type (type);
+                       MonoMethod *mono_method;
+
+                       if (is_sre_method_builder (mono_object_class (m->mb)))
+                               mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
+                       else if (is_sr_mono_method (mono_object_class (m->mb)))
+                               mono_method = ((MonoReflectionMethod *)m->mb)->method;
+                       else
+                               g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));
+
+                       result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
+               }
+               return result;
+       }
+
+       g_error ("Can't handle methods of type %s:%s", class->name_space, class->name);
+       return NULL;
+}
+
 void
 mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
 {
        MonoReflectionTypeBuilder *tb;
-       int i, onum;
+       int i, j, onum;
+       MonoReflectionMethod *m;
 
        *overrides = NULL;
        *num_overrides = 0;
@@ -10696,8 +10922,8 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder *mb = 
                                mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (mb->override_method)
-                               onum ++;
+                       if (mb->override_methods)
+                               onum += mono_array_length (mb->override_methods);
                }
        }
 
@@ -10708,17 +10934,17 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder *mb = 
                                mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       if (mb->override_method) {
-                               (*overrides) [onum * 2] = 
-                                       mb->override_method->method;
-                               (*overrides) [onum * 2 + 1] =
-                                       mb->mhandle;
+                       if (mb->override_methods) {
+                               for (j = 0; j < mono_array_length (mb->override_methods); ++j) {
+                                       m = mono_array_get (mb->override_methods, MonoReflectionMethod*, j);
+
+                                       (*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject*)m);
+                                       (*overrides) [onum * 2 + 1] = mb->mhandle;
 
-                               /* FIXME: What if 'override_method' is a MethodBuilder ? */
-                               g_assert (mb->override_method->method);
-                               g_assert (mb->mhandle);
+                                       g_assert (mb->mhandle);
 
-                               onum ++;
+                                       onum ++;
+                               }
                        }
                }
        }
@@ -10743,7 +10969,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        mono_error_init (error);
 
        if (tb->class_size) {
-               g_assert ((tb->packing_size & 0xfffffff0) == 0);
+               if ((tb->packing_size & 0xfffffff0) != 0) {
+                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", klass->name, tb->packing_size);
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+                       return;
+               }
                klass->packing_size = tb->packing_size;
                real_size = klass->instance_size + tb->class_size;
        }
@@ -10766,6 +10996,7 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        klass->size_inited = 1;
 
        for (i = 0; i < klass->field.count; ++i) {
+               MonoArray *rva_data;
                fb = mono_array_get (tb->fields, gpointer, i);
                field = &klass->fields [i];
                field->name = mono_string_to_utf8_image (image, fb->name, error);
@@ -10777,14 +11008,23 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
                } else {
                        field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type);
                }
-               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
-                       klass->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
+
+               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
+                       char *base = mono_array_addr (rva_data, char, 0);
+                       size_t size = mono_array_length (rva_data);
+                       char *data = mono_image_alloc (klass->image, size);
+                       memcpy (data, base, size);
+                       klass->ext->field_def_values [i].data = data;
+               }
                if (fb->offset != -1)
                        field->offset = fb->offset;
                field->parent = klass;
                fb->handle = field;
                mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
+               if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
+                       klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type);
+               }
                if (fb->def_value) {
                        MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                        field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
@@ -10834,6 +11074,21 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error)
                        properties [i].set = pb->set_method->mhandle;
 
                mono_save_custom_attrs (klass->image, &properties [i], pb->cattrs);
+               if (pb->def_value) {
+                       guint32 len, idx;
+                       const char *p, *p2;
+                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
+                       if (!klass->ext->prop_def_values)
+                               klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count);
+                       properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT;
+                       idx = encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type);
+                       /* Copy the data from the blob since it might get realloc-ed */
+                       p = assembly->blob.data + idx;
+                       len = mono_metadata_decode_blob_size (p, &p2);
+                       len += p2 - p;
+                       klass->ext->prop_def_values [i].data = mono_image_alloc (image, len);
+                       memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len);
+               }
        }
 }
 
@@ -11030,6 +11285,12 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        klass->flags = tb->attrs;
        klass->has_cctor = 1;
        klass->has_finalize = 1;
+       klass->has_finalize_inited = 1;
+
+       /* fool mono_class_setup_parent */
+       klass->supertypes = NULL;
+       mono_class_setup_parent (klass, klass->parent);
+       mono_class_setup_mono_type (klass);
 
 #if 0
        if (!((MonoDynamicImage*)klass->image)->run) {
@@ -11125,10 +11386,17 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
        MonoGenericParamFull *param;
        MonoImage *image;
        MonoClass *pklass;
+       MonoError error;
 
        MONO_ARCH_SAVE_REGS;
 
-       param = g_new0 (MonoGenericParamFull, 1);
+       image = &gparam->tbuilder->module->dynamic_image->image;
+
+       param = mono_image_new0 (image, MonoGenericParamFull, 1);
+
+       param->info.name = mono_string_to_utf8_image (image, gparam->name, &error);
+       g_assert (mono_error_ok (&error));
+       param->param.num = gparam->index;
 
        if (gparam->mbuilder) {
                if (!gparam->mbuilder->generic_container) {
@@ -11152,10 +11420,6 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
                param->param.owner = gparam->tbuilder->generic_container;
        }
 
-       param->info.name = mono_string_to_utf8 (gparam->name);
-       param->param.num = gparam->index;
-
-       image = &gparam->tbuilder->module->dynamic_image->image;
        pklass = mono_class_from_generic_parameter ((MonoGenericParam *) param, image, gparam->mbuilder != NULL);
 
        gparam->type.type = &pklass->byval_arg;
@@ -11224,15 +11488,47 @@ mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
        return result;
 }
 
+typedef struct {
+       MonoMethod *handle;
+       MonoDomain *domain;
+} DynamicMethodReleaseData;
+
+/*
+ * The runtime automatically clean up those after finalization.
+*/     
+static MonoReferenceQueue *dynamic_method_queue;
+
+static void
+free_dynamic_method (void *dynamic_method)
+{
+       DynamicMethodReleaseData *data = dynamic_method;
+
+       mono_runtime_free_method (data->domain, data->handle);
+       g_free (data);
+}
+
 void 
 mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 {
+       MonoReferenceQueue *queue;
+       MonoMethod *handle;
+       DynamicMethodReleaseData *release_data;
        ReflectionMethodBuilder rmb;
        MonoMethodSignature *sig;
        MonoClass *klass;
        GSList *l;
        int i;
 
+       if (mono_runtime_is_shutting_down ())
+               mono_raise_exception (mono_get_exception_invalid_operation (""));
+
+       if (!(queue = dynamic_method_queue)) {
+               mono_loader_lock ();
+               if (!(queue = dynamic_method_queue))
+                       queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
+               mono_loader_unlock ();
+       }
+
        sig = dynamic_method_to_signature (mb);
 
        reflection_methodbuilder_from_dynamic_method (&rmb, mb);
@@ -11290,7 +11586,12 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 
        klass = mb->owner ? mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner)) : mono_defaults.object_class;
 
-       mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+       mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+       release_data = g_new (DynamicMethodReleaseData, 1);
+       release_data->handle = handle;
+       release_data->domain = mono_object_get_domain ((MonoObject*)mb);
+       if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
+               g_free (release_data);
 
        /* Fix up refs entries pointing at us */
        for (l = mb->referenced_by; l; l = l->next) {
@@ -11316,16 +11617,6 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
 
 #endif /* DISABLE_REFLECTION_EMIT */
 
-void
-mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
-{
-       g_assert (mb);
-
-       if (mb->mhandle)
-               mono_runtime_free_method (
-                       mono_object_get_domain ((MonoObject*)mb), mb->mhandle);
-}
-
 /**
  * 
  * mono_reflection_is_valid_dynamic_token:
@@ -11339,6 +11630,19 @@ mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
        return mono_g_hash_table_lookup (image->tokens, GUINT_TO_POINTER (token)) != NULL;
 }
 
+MonoMethodSignature *
+mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token)
+{
+       MonoMethodSignature *sig;
+       g_assert (image->dynamic);
+
+       sig = g_hash_table_lookup (((MonoDynamicImage*)image)->vararg_aux_hash, GUINT_TO_POINTER (token));
+       if (sig)
+               return sig;
+
+       return mono_method_signature (method);
+}
+
 #ifndef DISABLE_REFLECTION_EMIT
 
 /**
@@ -11412,6 +11716,10 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                g_assert (result);
        } else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
                MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
+               MonoClass *mc = mono_class_from_mono_type (type);
+               if (!mono_class_init (mc))
+                       mono_raise_exception (mono_class_get_exception_for_failure (mc));
+
                if (context) {
                        MonoType *inflated = mono_class_inflate_generic_type (type, context);
                        result = mono_class_from_mono_type (inflated);
@@ -11615,6 +11923,8 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
                if (m->method_args) {
                        result = mono_reflection_method_on_tb_inst_get_handle (m);
+                       if (context)
+                               result = mono_class_inflate_generic_method (result, context);
                } else {
                        MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context);
                        MonoClass *inflated_klass = mono_class_from_mono_type (type);
@@ -11663,7 +11973,14 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, Mon
                                is_sre_pointer (mono_object_get_class(obj))) {
                MonoReflectionType *ref_type = (MonoReflectionType *)obj;
                MonoType *type = mono_reflection_type_get_handle (ref_type);
-               result = mono_class_from_mono_type (type);
+
+               if (context) {
+                       MonoType *inflated = mono_class_inflate_generic_type (type, context);
+                       result = mono_class_from_mono_type (inflated);
+                       mono_metadata_free_type (inflated);
+               } else {
+                       result = mono_class_from_mono_type (type);
+               }
                *handle_class = mono_defaults.typehandle_class;
        } else {
                g_print ("%s\n", obj->vtable->klass->name);
@@ -11746,7 +12063,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, Mon
 
 guint32
 mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, 
-                                                gboolean create_methodspec, gboolean register_token)
+                                                gboolean create_open_instance, gboolean register_token)
 {
        g_assert_not_reached ();
        return 0;
@@ -11758,9 +12075,7 @@ mono_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObject
 }
 
 void
-mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
-                                         MonoArray *ctors, MonoArray *fields, MonoArray *properties,
-                                         MonoArray *events)
+mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *fields)
 {
        g_assert_not_reached ();
 }
@@ -11825,6 +12140,12 @@ mono_reflection_type_get_handle (MonoReflectionType* ref)
        return ref->type;
 }
 
+void
+mono_reflection_free_dynamic_generic_class (MonoGenericClass *gclass)
+{
+       g_assert_not_reached ();
+}
+
 #endif /* DISABLE_REFLECTION_EMIT */
 
 /* SECURITY_ACTION_* are defined in mono/metadata/tabledefs.h */
@@ -12284,3 +12605,18 @@ mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass)
        else
                return *(MonoBoolean*)mono_object_unbox (res);
 }
+
+/**
+ * mono_reflection_type_get_type:
+ * @reftype: the System.Type object
+ *
+ * Returns the MonoType* associated with the C# System.Type object @reftype.
+ */
+MonoType*
+mono_reflection_type_get_type (MonoReflectionType *reftype)
+{
+       g_assert (reftype);
+
+       return mono_reflection_type_get_handle (reftype);
+}
+