Hide some more methods
[mono.git] / mono / metadata / reflection.c
index c0e197ebe9934736b26aea15fc996fab91a2cdb6..1e69c00c1545b6b14296d718e8e39add6c38e785 100644 (file)
@@ -20,6 +20,7 @@
 #include "mono/metadata/object-internals.h"
 #include <mono/metadata/exception.h>
 #include <mono/metadata/marshal.h>
+#include <mono/metadata/security-manager.h>
 #include <stdio.h>
 #include <glib.h>
 #include <errno.h>
@@ -139,7 +140,7 @@ static void    encode_type (MonoDynamicImage *assembly, MonoType *type, char *p,
 static guint32 type_get_signature_size (MonoType *type);
 static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
 static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
-
+static inline MonoType *dup_type (const MonoType *original);
 
 static void
 alloc_table (MonoDynamicTable *table, guint nrows)
@@ -284,7 +285,7 @@ add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int
        guint32 idx;
        char *copy;
        gpointer oldkey, oldval;
-       
+
        copy = g_malloc (s1+s2);
        memcpy (copy, b1, s1);
        memcpy (copy + s1, b2, s2);
@@ -495,7 +496,10 @@ encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf)
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_CLASS: {
                MonoClass *k = mono_class_from_mono_type (type);
-               mono_metadata_encode_value (type->type, p, &p);
+               /*
+                * Make sure we use the correct type.
+                */
+               mono_metadata_encode_value (k->byval_arg.type, p, &p);
                /*
                 * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
                 * otherwise two typerefs could point to the same type, leading to
@@ -770,7 +774,7 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
        char *b = blob_size;
        int i;
 
-       size = 10 + nl * 30;
+       size = 50 + nl * 30;
        p = buf = g_malloc (size);
        table = &assembly->tables [MONO_TABLE_STANDALONESIG];
        idx = table->next_idx ++;
@@ -849,8 +853,10 @@ method_encode_clauses (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, g
                        if (ex_block->extype) {
                                clause->data.catch_class = mono_class_from_mono_type (ex_block->extype->type);
                        } else {
-                               /* FIXME: handle filters */
-                               clause->data.filter_offset = 0;
+                               if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
+                                       clause->data.filter_offset = ex_block->filter_offset;
+                               else
+                                       clause->data.filter_offset = 0;
                        }
                        finally_start = ex_block->start + ex_block->len;
 
@@ -873,8 +879,8 @@ method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
        gint maybe_small;
        guint32 fat_flags;
        char fat_header [12];
-       guint32 *intp;
-       guint16 *shortp;
+       guint32 int_value;
+       guint16 short_value;
        guint32 local_sig = 0;
        guint32 header_size = 12;
        MonoArray *code;
@@ -940,12 +946,12 @@ fat_header:
                fat_flags |= METHOD_HEADER_INIT_LOCALS;
        fat_header [0] = fat_flags;
        fat_header [1] = (header_size / 4 ) << 4;
-       shortp = (guint16*)(fat_header + 2);
-       *shortp = GUINT16_TO_LE (max_stack);
-       intp = (guint32*)(fat_header + 4);
-       *intp = GUINT32_TO_LE (code_size);
-       intp = (guint32*)(fat_header + 8);
-       *intp = GUINT32_TO_LE (local_sig);
+       short_value = GUINT16_TO_LE (max_stack);
+       memcpy (fat_header + 2, &short_value, 2);
+       int_value = GUINT32_TO_LE (code_size);
+       memcpy (fat_header + 4, &int_value, 4);
+       int_value = GUINT32_TO_LE (local_sig);
+       memcpy (fat_header + 8, &int_value, 4);
        idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
        /* add to the fixup todo list */
        if (mb->ilgen && mb->ilgen->num_token_fixups)
@@ -998,8 +1004,10 @@ fat_header:
                                        if (ex_block->extype) {
                                                val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, ex_block->extype->type));
                                        } else {
-                                               /* FIXME: handle filters */
-                                               val = 0;
+                                               if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
+                                                       val = ex_block->filter_offset;
+                                               else
+                                                       val = 0;
                                        }
                                        val = GUINT32_TO_LE (val);
                                        mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
@@ -1036,10 +1044,24 @@ find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32
 
 static GHashTable *dynamic_custom_attrs = NULL;
 
+static gboolean
+custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
+{
+       /* FIXME: Need to do more checks */
+       if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
+               int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+
+               if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 static MonoCustomAttrInfo*
 mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
 {
-       int i, count;
+       int i, index, count, not_visible;
        MonoCustomAttrInfo *ainfo;
        MonoReflectionCustomAttr *cattr;
 
@@ -1049,16 +1071,30 @@ mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
 
        count = mono_array_length (cattrs);
 
+       /* Skip nonpublic attributes since MS.NET seems to do the same */
+       /* FIXME: This needs to be done more globally */
+       not_visible = 0;
+       for (i = 0; i < count; ++i) {
+               cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
+               if (!custom_attr_visible (image, cattr))
+                       not_visible ++;
+       }
+       count -= not_visible;
+
        ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
 
        ainfo->image = image;
        ainfo->num_attrs = count;
+       index = 0;
        for (i = 0; i < count; ++i) {
                cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
-               ainfo->attrs [i].ctor = cattr->ctor->method;
-               /* FIXME: might want to memdup the data here */
-               ainfo->attrs [i].data = mono_array_addr (cattr->data, char, 0);
-               ainfo->attrs [i].data_size = mono_array_length (cattr->data);
+               if (custom_attr_visible (image, cattr)) {
+                       ainfo->attrs [index].ctor = cattr->ctor->method;
+                       /* FIXME: might want to memdup the data here */
+                       ainfo->attrs [index].data = mono_array_addr (cattr->data, char, 0);
+                       ainfo->attrs [index].data_size = mono_array_length (cattr->data);
+                       index ++;
+               }
        }
 
        return ainfo;
@@ -1487,12 +1523,12 @@ fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
        if (!assembly->save)
                return 0;
 
-       p = buf = g_malloc (64);
+       p = buf = g_malloc (256);
        
        mono_metadata_encode_value (0x06, p, &p);
        /* encode custom attributes before the type */
        encode_type (assembly, type, p, &p);
-       g_assert (p-buf < 64);
+       g_assert (p-buf < 256);
        mono_metadata_encode_value (p-buf, b, &b);
        idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
        g_free (buf);
@@ -1528,6 +1564,12 @@ encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type)
        char *p, *box_val;
        char* buf;
        guint32 idx = 0, len = 0, dummy = 0;
+#ifdef ARM_FPU_FPA
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+       guint32 fpa_double [2];
+       guint32 *fpa_p;
+#endif
+#endif
        
        p = buf = g_malloc (64);
        if (!val) {
@@ -1557,8 +1599,18 @@ handle_enum:
                break;
        case MONO_TYPE_U8:
        case MONO_TYPE_I8:
+               len = 8;
+               break;
        case MONO_TYPE_R8:
                len = 8;
+#ifdef ARM_FPU_FPA
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+               fpa_p = (guint32*)box_val;
+               fpa_double [0] = fpa_p [1];
+               fpa_double [1] = fpa_p [0];
+               box_val = (char*)fpa_double;
+#endif
+#endif
                break;
        case MONO_TYPE_VALUETYPE:
                if (val->vtable->klass->enumtype) {
@@ -1655,24 +1707,14 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
                } else {
                        mono_metadata_encode_value (0, p, &p);
                }
-               if (minfo->marshaltype) {
-                       str = mono_string_to_utf8 (minfo->marshaltype);
-                       len = strlen (str);
-                       mono_metadata_encode_value (len, p, &p);
-                       if (p + len >= buf + bufsize) {
-                               idx = p - buf;
-                               bufsize *= 2;
-                               buf = g_realloc (buf, bufsize);
-                               p = buf + idx;
-                       }
-                       memcpy (p, str, len);
-                       p += len;
-                       g_free (str);
-               } else {
-                       mono_metadata_encode_value (0, p, &p);
-               }
-               if (minfo->marshaltyperef) {
-                       str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
+               /* native type name */
+               mono_metadata_encode_value (0, p, &p);
+               /* custom marshaler type name */
+               if (minfo->marshaltype || minfo->marshaltyperef) {
+                       if (minfo->marshaltyperef)
+                               str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
+                       else
+                               str = mono_string_to_utf8 (minfo->marshaltype);
                        len = strlen (str);
                        mono_metadata_encode_value (len, p, &p);
                        if (p + len >= buf + bufsize) {
@@ -1685,6 +1727,7 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
                        p += len;
                        g_free (str);
                } else {
+                       /* FIXME: Actually a bug, since this field is required.  Punting for now ... */
                        mono_metadata_encode_value (0, p, &p);
                }
                if (minfo->mcookie) {
@@ -1933,63 +1976,6 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass
        }
 }
 
-static void
-encode_new_constraint (MonoDynamicImage *assembly, guint32 owner)
-{
-       static MonoClass *NewConstraintAttr;
-       static MonoMethod *NewConstraintAttr_ctor;
-       MonoDynamicTable *table;
-       guint32 *values;
-       guint32 token, type;
-       char blob_size [4] = { 0x01, 0x00, 0x00, 0x00 };
-       char *buf, *p;
-
-       if (!NewConstraintAttr)
-               NewConstraintAttr = mono_class_from_name ( mono_defaults.corlib, 
-                       "System.Runtime.CompilerServices", "NewConstraintAttribute");
-       g_assert (NewConstraintAttr);
-
-       if (!NewConstraintAttr_ctor) {
-               NewConstraintAttr_ctor = mono_class_get_method_from_name (NewConstraintAttr, ".ctor", -1);
-               g_assert (NewConstraintAttr_ctor);
-       }
-
-       table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
-       table->rows += 1;
-       alloc_table (table, table->rows);
-
-       values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
-       owner <<= MONO_CUSTOM_ATTR_BITS;
-       owner |= MONO_CUSTOM_ATTR_GENERICPAR;
-       values [MONO_CUSTOM_ATTR_PARENT] = owner;
-
-       token = mono_image_get_methodref_token (assembly, NewConstraintAttr_ctor);
-
-       type = mono_metadata_token_index (token);
-       type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
-       switch (mono_metadata_token_table (token)) {
-       case MONO_TABLE_METHOD:
-               type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
-               break;
-       case MONO_TABLE_MEMBERREF:
-               type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
-               break;
-       default:
-               g_warning ("got wrong token in custom attr");
-               return;
-       }
-       values [MONO_CUSTOM_ATTR_TYPE] = type;
-
-       buf = p = g_malloc (1);
-       mono_metadata_encode_value (4, p, &p);
-       g_assert (p-buf == 1);
-
-       values [MONO_CUSTOM_ATTR_VALUE] = add_to_blob_cached (assembly, buf, 1, blob_size, 4);
-
-       values += MONO_CUSTOM_ATTR_SIZE;
-       ++table->next_idx;
-}
-
 static void
 encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
 {
@@ -2026,9 +2012,6 @@ encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynam
                values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
                        assembly, constraint->type);
        }
-
-       if (gparam->attrs &  GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT)
-               encode_new_constraint (assembly, owner);
 }
 
 static void
@@ -2045,7 +2028,7 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
 
        entry = g_new0 (GenericParamTableEntry, 1);
        entry->owner = owner;
-       entry->gparam = gparam;
+       entry->gparam = gparam; /* FIXME: GC object stored in unmanaged mem */
 
        g_ptr_array_add (assembly->gen_params, entry);
 }
@@ -2069,6 +2052,8 @@ write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *e
        values [MONO_GENERICPARAM_NUMBER] = param->num;
        values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
 
+       mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs);
+
        encode_constraints (entry->gparam, table_idx, assembly);
 }
 
@@ -2476,29 +2461,30 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
 }
 
 static guint32
-mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
+mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
 {
        MonoMethodInflated *imethod;
+       MonoMethod *inflated;
        guint32 token;
        
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
        if (token)
                return token;
 
-       g_assert (m->is_inflated);
-       m = mono_get_inflated_method (m);
-       imethod = (MonoMethodInflated *) m;
+       g_assert (method->is_inflated);
+       inflated = mono_get_inflated_method (method);
+       imethod = (MonoMethodInflated *) inflated;
 
        if (mono_method_signature (imethod->declaring)->generic_param_count) {
-               token = method_encode_methodspec (assembly, m);
+               token = method_encode_methodspec (assembly, inflated);
        } else {
                guint32 sig = method_encode_signature (
                        assembly, mono_method_signature (imethod->declaring));
                token = mono_image_get_memberref_token (
-                       assembly, &m->klass->byval_arg, m->name, sig);
+                       assembly, &inflated->klass->byval_arg, inflated->name, sig);
        }
 
-       g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -2922,7 +2908,7 @@ collect_types (GPtrArray *types, MonoReflectionTypeBuilder *type)
 {
        int i;
 
-       g_ptr_array_add (types, type);
+       g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */
 
        if (!type->subtypes)
                return;
@@ -3011,17 +2997,31 @@ type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) {
 }
 
 static void
-module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *mb) {
+module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *moduleb)
+{
        int i;
        
-       mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_MODULE, mb->cattrs);
-       
-       /* no types in the module */
-       if (!mb->types)
-               return;
+       mono_image_add_cattrs (assembly, moduleb->table_idx, MONO_CUSTOM_ATTR_MODULE, moduleb->cattrs);
+
+       if (moduleb->global_methods) {
+               for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
+                       MonoReflectionMethodBuilder* mb = mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i);
+                       mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs);
+                       params_add_cattrs (assembly, mb->pinfo);
+               }
+       }
+
+       if (moduleb->global_fields) {
+               for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
+                       MonoReflectionFieldBuilder *fb = mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i);
+                       mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs);
+               }
+       }
        
-       for (i = 0; i < mb->num_types; ++i)
-               type_add_cattrs (assembly, mono_array_get (mb->types, MonoReflectionTypeBuilder*, i));
+       if (moduleb->types) {
+               for (i = 0; i < moduleb->num_types; ++i)
+                       type_add_cattrs (assembly, mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i));
+       }
 }
 
 static void
@@ -3161,6 +3161,44 @@ mono_image_fill_export_table_from_module (MonoDomain *domain, MonoReflectionModu
        }
 }
 
+static void
+mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
+{
+       MonoDynamicTable *table;
+       MonoClass *klass;
+       guint32 *values;
+       guint32 scope, idx;
+       int i;
+
+       table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
+
+       if (assemblyb->type_forwarders) {
+               for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
+                       MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType*, i);
+                       if (!t)
+                               continue;
+
+                       g_assert (t->type);
+
+                       klass = mono_class_from_mono_type (t->type);
+
+                       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;
+
+                       table->rows++;
+                       alloc_table (table, table->rows);
+                       values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
+
+                       values [MONO_EXP_TYPE_FLAGS] = TYPE_ATTRIBUTE_FORWARDER;
+                       values [MONO_EXP_TYPE_TYPEDEF] = 0;
+                       values [MONO_EXP_TYPE_IMPLEMENTATION] = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+                       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);
+               }
+       }
+}
+
 #define align_pointer(base,p)\
        do {\
                guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\
@@ -3345,8 +3383,8 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        *p++ = 'B'; *p++ = 'S'; *p++ = 'J'; *p++ = 'B';
        /* version numbers and 4 bytes reserved */
        int16val = (guint16*)p;
-       *int16val++ = GUINT16_TO_LE (1);
-       *int16val = GUINT16_TO_LE (1);
+       *int16val++ = GUINT16_TO_LE (meta->md_version_major);
+       *int16val = GUINT16_TO_LE (meta->md_version_minor);
        p += 8;
        /* version string */
        int32val = (guint32*)p;
@@ -3769,8 +3807,18 @@ load_public_key (MonoArray *pkey, MonoDynamicImage *assembly) {
        token = mono_image_add_stream_data (&assembly->blob, blob_size, b - blob_size);
        mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, guint8, 0), len);
 
-       /* need to get the actual value from the key type... */
-       assembly->strong_name_size = 128;
+       /* Special case: check for ECMA key (16 bytes) */
+       if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, guint8, 0), len)) {
+               /* In this case we must reserve 128 bytes (1024 bits) for the signature */
+               assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH;
+       } else if (len >= MONO_PUBLIC_KEY_HEADER_LENGTH + MONO_MINIMUM_PUBLIC_KEY_LENGTH) {
+               /* minimum key size (in 2.0) is 384 bits */
+               assembly->strong_name_size = len - MONO_PUBLIC_KEY_HEADER_LENGTH;
+       } else {
+               /* FIXME - verifier */
+               g_warning ("Invalid public key length: %d bits (total: %d)", (int)MONO_PUBLIC_KEY_BIT_SIZE (len), (int)len);
+               assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH; /* to be safe */
+       }
        assembly->strong_name = g_malloc0 (assembly->strong_name_size);
 
        return token;
@@ -3837,6 +3885,8 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb)
                        mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly);
                }
        }
+       if (assemblyb->type_forwarders)
+               mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly);
 
        /* Emit MANIFESTRESOURCE table */
        module_index = 0;
@@ -3943,6 +3993,27 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
                table->rows += types->len;
                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);
+                       char *n;
+
+                       n = mono_string_to_utf8 (tb->nspace);
+                       string_heap_insert (&assembly->sheap, n);
+                       g_free (n);
+               }
+               for (i = 0; i < types->len; ++i) {
+                       MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+                       char *n;
+
+                       n = mono_string_to_utf8 (tb->name);
+                       string_heap_insert (&assembly->sheap, n);
+                       g_free (n);
+               }
+
                for (i = 0; i < types->len; ++i) {
                        MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
                        mono_image_get_type_info (domain, type, assembly);
@@ -4239,7 +4310,9 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, c
        image->image.name = assembly_name;
        image->image.assembly_name = image->image.name; /* they may be different */
        image->image.module_name = module_name;
-       image->image.version = version;
+       image->image.version = g_strdup (version);
+       image->image.md_version_major = 1;
+       image->image.md_version_minor = 1;
        image->image.dynamic = TRUE;
        image->image.ref_count = 1;
 
@@ -4424,6 +4497,7 @@ resource_tree_create (MonoArray *win32_resources)
 
                /* Create node */
 
+               /* FIXME: BUG: this stores managed references in unmanaged memory */
                lang_node = g_new0 (ResTreeNode, 1);
                lang_node->id = win32_res->lang_id;
                lang_node->win32_res = win32_res;
@@ -4986,7 +5060,7 @@ mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
        name = mono_string_to_utf8 (fileName);
 
        image = mono_image_open (name, &status);
-       if (status) {
+       if (!image) {
                MonoException *exc;
                if (status == MONO_IMAGE_ERROR_ERRNO)
                        exc = mono_get_exception_file_not_found (fileName);
@@ -5007,6 +5081,7 @@ mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
        if (image->assembly->image->modules)
                memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
        new_modules [module_count] = image;
+       mono_image_addref (image);
 
        g_free (image->assembly->image->modules);
        image->assembly->image->modules = new_modules;
@@ -5130,6 +5205,7 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
                if (ass->modules)
                        memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
                new_modules [module_count] = &image->image;
+               mono_image_addref (&image->image);
 
                g_free (ass->modules);
                ass->modules = new_modules;
@@ -5176,11 +5252,12 @@ mono_module_get_object   (MonoDomain *domain, MonoImage *image)
        res = (MonoReflectionModule *)mono_object_new (domain, System_Reflection_Module);
 
        res->image = image;
-       res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
+       MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
 
-       res->fqname    = mono_string_new (domain, image->name);
-       res->name      = mono_string_new (domain, basename = g_path_get_basename (image->name));
-       res->scopename = mono_string_new (domain, image->module_name);
+       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, image->name));
+       basename = g_path_get_basename (image->name);
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, basename));
+       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, image->module_name));
        
        g_free (basename);
 
@@ -5197,8 +5274,6 @@ mono_module_get_object   (MonoDomain *domain, MonoImage *image)
                g_assert (res->token);
        }
 
-       mono_image_addref (image);
-
        CACHE_OBJECT (MonoReflectionModule *, image, res, NULL);
 }
 
@@ -5222,8 +5297,8 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        g_assert (table_index < table->rows);
        mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE);
 
-       res->image = 0;
-       res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
+       res->image = NULL;
+       MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
        name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
 
        /* Check whenever the row has a corresponding row in the moduleref table */
@@ -5235,9 +5310,9 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
                        res->image = image->modules [i];
        }
 
-       res->fqname    = mono_string_new (domain, name);
-       res->name      = mono_string_new (domain, name);
-       res->scopename = mono_string_new (domain, name);
+       MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
+       MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
        res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA;
        res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
 
@@ -5321,6 +5396,17 @@ mymono_metadata_type_hash (MonoType *t1)
                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->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;
 }
@@ -5341,6 +5427,7 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
 
        gclass = mono_get_inflated_generic_class (geninst->data.generic_class);
        gklass = gclass->generic_class.container_class;
+       g_assert (gklass->generic_container);
 
        mono_class_init (gclass->klass);
 
@@ -5348,14 +5435,42 @@ mono_generic_class_get_object (MonoDomain *domain, MonoType *geninst)
 
        res->type.type = geninst;
        if (gklass->wastypebuilder && gklass->reflection_info)
-               res->generic_type = gklass->reflection_info;
+               MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
        else
-               res->generic_type = mono_type_get_object (
-                       domain, &gclass->generic_class.container_class->byval_arg);
+               MONO_OBJECT_SETREF (res, generic_type, mono_type_get_object (domain, &gklass->byval_arg));
 
        return res;
 }
 
+static gboolean
+verify_safe_for_managed_space (MonoType *type)
+{
+       switch (type->type) {
+#ifdef DEBUG_HARDER
+       case MONO_TYPE_ARRAY:
+               return verify_safe_for_managed_space (&type->data.array->eklass->byval_arg);
+       case MONO_TYPE_PTR:
+               return verify_safe_for_managed_space (type->data.type);
+       case MONO_TYPE_SZARRAY:
+               return verify_safe_for_managed_space (&type->data.klass->byval_arg);
+       case MONO_TYPE_GENERICINST: {
+               MonoGenericInst *inst = type->data.generic_class->inst;
+               int i;
+               if (!inst->is_open)
+                       break;
+               for (i = 0; i < inst->type_argc; ++i)
+                       if (!verify_safe_for_managed_space (inst->type_argv [i]))
+                               return FALSE;
+               break;
+       }
+#endif
+       case MONO_TYPE_VAR:
+       case MONO_TYPE_MVAR:
+               return type->data.generic_param->owner != NULL;
+       }
+       return TRUE;
+}
+
 /*
  * mono_type_get_object:
  * @domain: an app domain
@@ -5383,6 +5498,12 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                mono_domain_unlock (domain);
                return res;
        }
+
+       if (!verify_safe_for_managed_space (type)) {
+               mono_domain_unlock (domain);
+               mono_raise_exception (mono_get_exception_invalid_operation ("This type cannot be propagated to managed space"));
+       }
+
        if (klass->reflection_info && !klass->wastypebuilder) {
                /* g_assert_not_reached (); */
                /* should this be considered an error condition? */
@@ -5421,6 +5542,7 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
        if (method->is_inflated) {
                MonoReflectionGenericMethod *gret;
 
+               method = mono_get_inflated_method (method);
                refclass = method->klass;
                CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
                if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor")))
@@ -5431,9 +5553,9 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
 
                gret = (MonoReflectionGenericMethod*)mono_object_new (domain, klass);
                gret->method.method = method;
-               gret->method.name = mono_string_new (domain, method->name);
-               gret->method.reftype = mono_type_get_object (domain, &refclass->byval_arg);
-               CACHE_OBJECT (MonoReflectionMethod *, method, gret, refclass);
+               MONO_OBJECT_SETREF (gret, method.name, mono_string_new (domain, method->name));
+               MONO_OBJECT_SETREF (gret, method.reftype, mono_type_get_object (domain, &refclass->byval_arg));
+               CACHE_OBJECT (MonoReflectionMethod *, method, (MonoReflectionMethod*)gret, refclass);
        }
 
        if (!refclass)
@@ -5448,8 +5570,8 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method, MonoClass *refcl
 
        ret = (MonoReflectionMethod*)mono_object_new (domain, klass);
        ret->method = method;
-       ret->name = mono_string_new (domain, method->name);
-       ret->reftype = mono_type_get_object (domain, &refclass->byval_arg);
+       MONO_OBJECT_SETREF (ret, name, mono_string_new (domain, method->name));
+       MONO_OBJECT_SETREF (ret, reftype, mono_type_get_object (domain, &refclass->byval_arg));
        CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass);
 }
 
@@ -5473,12 +5595,12 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res = (MonoReflectionField *)mono_object_new (domain, oklass);
        res->klass = klass;
        res->field = field;
-       res->name = mono_string_new (domain, field->name);
+       MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name));
        if (field->generic_info)
                res->attrs = field->generic_info->generic_type->attrs;
        else
                res->attrs = field->type->attrs;
-       res->type = mono_type_get_object (domain, field->type);
+       MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
        CACHE_OBJECT (MonoReflectionField *, field, res, klass);
 }
 
@@ -5572,14 +5694,14 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
        res = mono_array_new (domain, System_Reflection_ParameterInfo, mono_method_signature (method)->param_count);
        for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
                param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo);
-               param->ClassImpl = mono_type_get_object (domain, mono_method_signature (method)->params [i]);
-               param->MemberImpl = (MonoObject*)member;
-               param->NameImpl = mono_string_new (domain, names [i]);
+               MONO_OBJECT_SETREF (param, ClassImpl, mono_type_get_object (domain, mono_method_signature (method)->params [i]));
+               MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member);
+               MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i]));
                param->PositionImpl = i;
                param->AttrsImpl = mono_method_signature (method)->params [i]->attrs;
 
                if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
-                       param->DefaultValueImpl = dbnull;
+                       MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
                } else {
 
                        if (!blobs) {
@@ -5598,18 +5720,18 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
                        else    
                                type->data.klass = mono_class_from_mono_type (type);
                        
-                       param->DefaultValueImpl = mono_get_object_from_blob (domain, type, blobs [i]);
+                       MONO_OBJECT_SETREF (param, DefaultValueImpl, mono_get_object_from_blob (domain, type, blobs [i]));
 
                        /* Type in the Constant table is MONO_TYPE_CLASS for nulls */
                        if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) 
-                               param->DefaultValueImpl = dbnull;
+                               MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
                        
                }
 
                if (mspecs [i + 1])
-                       param->MarshalAsImpl = (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]);
+                       MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
                
-               mono_array_set (res, gpointer, i, param);
+               mono_array_setref (res, i, param);
        }
        g_free (names);
        g_free (blobs);
@@ -5687,21 +5809,21 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
        ret->init_locals = header->init_locals;
        ret->max_stack = header->max_stack;
        ret->local_var_sig_token = local_var_sig_token;
-       ret->il = mono_array_new (domain, mono_defaults.byte_class, header->code_size);
-       memcpy (mono_array_addr (ret->il, guint8*, 0), header->code, header->code_size);
+       MONO_OBJECT_SETREF (ret, il, mono_array_new (domain, mono_defaults.byte_class, header->code_size));
+       memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size);
 
        /* Locals */
-       ret->locals = mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals);
+       MONO_OBJECT_SETREF (ret, locals, mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals));
        for (i = 0; i < header->num_locals; ++i) {
                MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new (domain, System_Reflection_LocalVariableInfo);
-               info->local_type = mono_type_get_object (domain, header->locals [i]);
+               MONO_OBJECT_SETREF (info, local_type, mono_type_get_object (domain, header->locals [i]));
                info->is_pinned = header->locals [i]->pinned;
                info->local_index = i;
-               mono_array_set (ret->locals, MonoReflectionLocalVariableInfo*, i, info);
+               mono_array_setref (ret->locals, i, info);
        }
 
        /* Exceptions */
-       ret->clauses = mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses);
+       MONO_OBJECT_SETREF (ret, clauses, mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses));
        for (i = 0; i < header->num_clauses; ++i) {
                MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new (domain, System_Reflection_ExceptionHandlingClause);
                MonoExceptionClause *clause = &header->clauses [i];
@@ -5714,9 +5836,9 @@ mono_method_body_get_object (MonoDomain *domain, MonoMethod *method)
                if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
                        info->filter_offset = clause->data.filter_offset;
                else if (clause->data.catch_class)
-                       info->catch_type = mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg);
+                       MONO_OBJECT_SETREF (info, catch_type, mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg));
 
-               mono_array_set (ret->clauses, MonoReflectionExceptionHandlingClause*, i, info);
+               mono_array_setref (ret->clauses, i, info);
        }
 
        CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
@@ -5760,14 +5882,13 @@ get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
        if (!methodsig->param_count)
                return;
 
-       if (klass->generic_class) {
-               return; /* FIXME - ??? */
-       }
-
        mono_class_init (klass);
 
        if (klass->image->dynamic) {
-               MonoReflectionMethodAux *aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+               MonoReflectionMethodAux *aux;
+               if (method->is_inflated)
+                       method = ((MonoMethodInflated*)method)->declaring;
+               aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
                if (aux && aux->param_defaults) {
                        memcpy (blobs, &(aux->param_defaults [1]), methodsig->param_count * sizeof (char*));
                        memcpy (types, &(aux->param_default_types [1]), methodsig->param_count * sizeof (guint32));
@@ -6400,12 +6521,7 @@ mono_reflection_get_token (MonoObject *obj)
                token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
        } else if (strcmp (klass->name, "FieldBuilder") == 0) {
                MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
-               MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
-               if (tb->generic_params) {
-                       g_assert_not_reached ();
-               } else {
-                       token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
-               }
+               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;
@@ -6413,20 +6529,22 @@ mono_reflection_get_token (MonoObject *obj)
                MonoReflectionType *tb = (MonoReflectionType *)obj;
                token = mono_class_from_mono_type (tb->type)->type_token;
        } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
-                       strcmp (klass->name, "MonoMethod") == 0) {
+                  strcmp (klass->name, "MonoMethod") == 0 ||
+                  strcmp (klass->name, "MonoGenericMethod") == 0 ||
+                  strcmp (klass->name, "MonoGenericCMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
                if (m->method->is_inflated) {
-                       g_assert_not_reached ();
-               } else if (mono_method_signature (m->method)->generic_param_count) {
-                       g_assert_not_reached ();
-               } else if (m->method->klass->generic_class) {
-                       g_assert_not_reached ();
+                       MonoMethodInflated *inflated = (MonoMethodInflated *) m->method;
+                       return inflated->declaring->token;
                } else {
                        token = m->method->token;
                }
        } else if (strcmp (klass->name, "MonoField") == 0) {
                MonoReflectionField *f = (MonoReflectionField*)obj;
 
+               if (f->field->generic_info && f->field->generic_info->reflection_info)
+                       return mono_reflection_get_token (f->field->generic_info->reflection_info);
+
                token = mono_class_get_field_token (f->field);
        } else if (strcmp (klass->name, "MonoProperty") == 0) {
                MonoReflectionProperty *p = (MonoReflectionProperty*)obj;
@@ -6460,6 +6578,8 @@ static void*
 load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end)
 {
        int slen, type = t->type;
+       MonoClass *tklass = t->data.klass;
+
 handle_enum:
        switch (type) {
        case MONO_TYPE_U1:
@@ -6550,6 +6670,15 @@ handle_type:
                } else if (subt == 0x0E) {
                        type = MONO_TYPE_STRING;
                        goto handle_enum;
+               } else if (subt == 0x1D) {
+                       MonoType simple_type = {{0}};
+                       int etype = *p;
+                       p ++;
+
+                       type = MONO_TYPE_SZARRAY;
+                       simple_type.type = etype;
+                       tklass = mono_class_from_mono_type (&simple_type);
+                       goto handle_enum;
                } else if (subt == 0x55) {
                        char *n;
                        MonoType *t;
@@ -6584,8 +6713,8 @@ handle_type:
                        *end = p;
                        return NULL;
                }
-               arr = mono_array_new (mono_domain_get(), t->data.klass, alen);
-               basetype = t->data.klass->byval_arg.type;
+               arr = mono_array_new (mono_domain_get(), tklass, alen);
+               basetype = tklass->byval_arg.type;
                switch (basetype)
                {
                        case MONO_TYPE_U1:
@@ -6627,8 +6756,8 @@ handle_type:
                        case MONO_TYPE_OBJECT:
                        case MONO_TYPE_STRING:
                                for (i = 0; i < alen; i++) {
-                                       MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p);
-                                       mono_array_set (arr, gpointer, i, item);
+                                       MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p);
+                                       mono_array_setref (arr, i, item);
                                }
                                break;
                        default:
@@ -6818,6 +6947,7 @@ create_custom_attr (MonoImage *image, MonoMethod *method, const char *data, guin
                        type_name [type_len] = 0;
                        named += type_len;
                        /* FIXME: lookup the type and check type consistency */
+                       g_free (type_name);
                } else if (data_type == MONO_TYPE_SZARRAY && (named_type == 0x54 || named_type == 0x53)) {
                        /* this seems to be the type of the element of the array */
                        /* g_print ("skipping 0x%02x after prop\n", *named); */
@@ -6900,7 +7030,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data,
                obj = type_is_reference (mono_method_signature (method)->params [i]) ? 
                        val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val);
                typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
-               mono_array_set (typedargs, void*, i, typedarg);
+               mono_array_setref (typedargs, i, typedarg);
 
                if (!type_is_reference (mono_method_signature (method)->params [i]))
                        g_free (val);
@@ -6925,6 +7055,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data,
                        type_name [type_len] = 0;
                        named += type_len;
                        /* FIXME: lookup the type and check type consistency */
+                       g_free (type_name);
                } else if (data_type == MONO_TYPE_SZARRAY && (named_type == 0x54 || named_type == 0x53)) {
                        /* this seems to be the type of the element of the array */
                        /* g_print ("skipping 0x%02x after prop\n", *named); */
@@ -6944,7 +7075,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data,
                        obj = type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val);
                        typedarg = create_cattr_typed_arg (field->type, obj);
                        namedarg = create_cattr_named_arg (minfo, typedarg);
-                       mono_array_set (namedargs, void*, j, namedarg);
+                       mono_array_setref (namedargs, j, namedarg);
                        if (!type_is_reference (field->type))
                                g_free (val);
                } else if (named_type == 0x54) {
@@ -6960,7 +7091,7 @@ create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data,
                        obj = type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val);
                        typedarg = create_cattr_typed_arg (prop_type, obj);
                        namedarg = create_cattr_named_arg (minfo, typedarg);
-                       mono_array_set (namedargs, void*, j, namedarg);
+                       mono_array_setref (namedargs, j, namedarg);
                        if (!type_is_reference (prop_type))
                                g_free (val);
                }
@@ -6986,12 +7117,39 @@ mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
        result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs);
        for (i = 0; i < cinfo->num_attrs; ++i) {
                attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
-               mono_array_set (result, gpointer, i, attr);
+               mono_array_setref (result, i, attr);
        }
        return result;
 }
 
-MonoArray*
+static MonoArray*
+mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
+{
+       MonoArray *result;
+       MonoObject *attr;
+       MonoClass *klass;
+       int i, n;
+
+       n = 0;
+       for (i = 0; i < cinfo->num_attrs; ++i) {
+               if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
+                       n ++;
+       }
+
+       klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
+       result = mono_array_new (mono_domain_get (), klass, 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);
+                       mono_array_setref (result, n, attr);
+                       n ++;
+               }
+       }
+       return result;
+}
+
+static MonoArray*
 mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
 {
        MonoArray *result;
@@ -7005,7 +7163,7 @@ mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
        result = mono_array_new (mono_domain_get (), klass, 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);
-               mono_array_set (result, gpointer, i, attr);
+               mono_array_setref (result, i, attr);
        }
        return result;
 }
@@ -7301,6 +7459,15 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
        } else if (strcmp ("ModuleBuilder", klass->name) == 0) {
                MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
                cinfo = mono_custom_attrs_from_builders (&mb->dynamic_image->image, mb->cattrs);
+       } else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
+               MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (cb->mhandle->klass->image, cb->cattrs);
+       } else if (strcmp ("MethodBuilder", klass->name) == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (mb->mhandle->klass->image, mb->cattrs);
+       } else if (strcmp ("FieldBuilder", klass->name) == 0) {
+               MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
+               cinfo = mono_custom_attrs_from_builders (&((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
        } else { /* handle other types here... */
                g_error ("get custom attrs not yet supported for %s", klass->name);
        }
@@ -7309,21 +7476,25 @@ mono_reflection_get_custom_attrs_info (MonoObject *obj)
 }
 
 /*
- * mono_reflection_get_custom_attrs:
+ * mono_reflection_get_custom_attrs_by_type:
  * @obj: a reflection object handle
  *
  * Return an array with all the custom attributes defined of the
- * reflection handle @obj. The objects are fully build.
+ * reflection handle @obj. If @attr_klass is non-NULL, only custom attributes 
+ * of that type are returned. The objects are fully build.
  */
 MonoArray*
-mono_reflection_get_custom_attrs (MonoObject *obj)
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
 {
        MonoArray *result;
        MonoCustomAttrInfo *cinfo;
 
        cinfo = mono_reflection_get_custom_attrs_info (obj);
        if (cinfo) {
-               result = mono_custom_attrs_construct (cinfo);
+               if (attr_klass)
+                       result = mono_custom_attrs_construct_by_type (cinfo, attr_klass);
+               else
+                       result = mono_custom_attrs_construct (cinfo);
                if (!cinfo->cached)
                        mono_custom_attrs_free (cinfo);
        } else {
@@ -7335,6 +7506,19 @@ mono_reflection_get_custom_attrs (MonoObject *obj)
        return result;
 }
 
+/*
+ * mono_reflection_get_custom_attrs:
+ * @obj: a reflection object handle
+ *
+ * Return an array with all the custom attributes defined of the
+ * reflection handle @obj. The objects are fully build.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs (MonoObject *obj)
+{
+       return mono_reflection_get_custom_attrs_by_type (obj, NULL);
+}
+
 /*
  * mono_reflection_get_custom_attrs_data:
  * @obj: a reflection obj handle
@@ -7574,7 +7758,15 @@ handle_type:
                *retbuffer = buffer;
                eclass = type->data.klass;
                arg_eclass = mono_object_class (arg)->element_class;
-               if (eclass->valuetype && arg_eclass->valuetype) {
+               if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
+                       /* Happens when we are called from the MONO_TYPE_OBJECT case below */
+                       char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
+                       int elsize = mono_class_array_element_size (arg_eclass);
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr);
+                               elptr += elsize;
+                       }
+               } else if (eclass->valuetype && arg_eclass->valuetype) {
                        char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
                        int elsize = mono_class_array_element_size (eclass);
                        for (i = 0; i < len; ++i) {
@@ -7588,12 +7780,17 @@ handle_type:
                }
                break;
        }
-       /* it may be a boxed value or a Type */
        case MONO_TYPE_OBJECT: {
                MonoClass *klass;
                char *str;
                guint32 slen;
 
+               /*
+                * The parameter type is 'object' but the type of the actual
+                * argument is not. So we have to add type information to the blob
+                * too. This is completely undocumented in the spec.
+                */
+
                if (arg == NULL) {
                        *p++ = MONO_TYPE_STRING;        // It's same hack as MS uses
                        *p++ = 0xFF;
@@ -7602,7 +7799,7 @@ handle_type:
                
                klass = mono_object_class (arg);
 
-               if (mono_object_isinst (arg, mono_defaults.monotype_class)) {
+               if (mono_object_isinst (arg, mono_defaults.systemtype_class)) {
                        *p++ = 0x50;
                        goto handle_type;
                } else if (klass->enumtype) {
@@ -7611,6 +7808,11 @@ handle_type:
                        simple_type = MONO_TYPE_STRING;
                        *p++ = 0x0E;
                        goto handle_enum;
+               } else if (klass->rank == 1) {
+                       simple_type = MONO_TYPE_SZARRAY;
+                       *p++ = 0x1D;
+                       *p++ = klass->element_class->byval_arg.type;
+                       goto handle_enum;
                } else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
                        *p++ = simple_type = klass->byval_arg.type;
                        goto handle_enum;
@@ -7815,7 +8017,6 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
                klass = mono_class_from_mono_type (tb->type.type);
                klass->parent = NULL;
                /* fool mono_class_setup_parent */
-               g_free (klass->supertypes);
                klass->supertypes = NULL;
                mono_class_setup_parent (klass, parent);
                mono_class_setup_mono_type (klass);
@@ -7834,7 +8035,7 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
        klass->flags = tb->attrs;
 
        klass->element_class = klass;
-       klass->reflection_info = tb; /* need to pin. */
+       klass->reflection_info = tb; /* FIXME: GC need to pin. */
 
        /* Put into cache so mono_class_get () will find it */
        mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
@@ -8063,12 +8264,12 @@ mono_reflection_marshal_from_marshal_spec (MonoDomain *domain, MonoClass *klass,
                if (spec->data.custom_data.custom_name) {
                        mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
                        if (mtype)
-                               minfo->marshaltyperef = mono_type_get_object (domain, mtype);
+                               MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype));
 
-                       minfo->marshaltype = mono_string_new (domain, spec->data.custom_data.custom_name);
+                       MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name));
                }
                if (spec->data.custom_data.cookie)
-                       minfo->mcookie = mono_string_new (domain, spec->data.custom_data.cookie);
+                       MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie));
                break;
 
        default:
@@ -8089,6 +8290,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        MonoReflectionMethodAux *method_aux;
        int i;
 
+       g_assert (!klass->generic_class);
+
        if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                m = (MonoMethod *)g_new0 (MonoMethodPInvoke, 1);
@@ -8187,8 +8390,9 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
        if (rmb->generic_params) {
                int count = mono_array_length (rmb->generic_params);
                MonoGenericContainer *container;
+               MonoGenericContext *context;
 
-               pm->generic_container = container = rmb->generic_container;
+               m->generic_container = container = rmb->generic_container;
                container->type_argc = count;
                container->type_params = g_new0 (MonoGenericParam, count);
 
@@ -8197,7 +8401,16 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
 
                        container->type_params [i] = *gp->type.type->data.generic_param;
+                       container->type_params [i].method = m;
                }
+
+               context = &container->context;
+               context->container = container;
+               if (klass->generic_container) {
+                       container->parent = klass->generic_container;
+                       context->gclass = klass->generic_container->context.gclass;
+               }
+               context->gmethod = mono_get_shared_generic_method (container);
        }
 
        if (rmb->refs) {
@@ -8229,7 +8442,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                        m->signature->params [i - 1]->attrs = pb->attrs;
                                }
 
-                               if (pb->def_value) {
+                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
                                        MonoDynamicImage *assembly;
                                        guint32 idx, def_type, len;
                                        char *p;
@@ -8335,9 +8548,6 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        const char *p, *p2;
        guint32 len, idx;
 
-       if (fb->handle)
-               return fb->handle;
-
        field = g_new0 (MonoClassField, 1);
 
        field->name = mono_string_to_utf8 (fb->name);
@@ -8349,11 +8559,10 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
                field->type = fb->type->type;
        }
        if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
-               field->data = mono_array_addr (fb->rva_data, char, 0);
+               field->data = mono_array_addr (fb->rva_data, char, 0); /* FIXME: GC pin array */
        if (fb->offset != -1)
                field->offset = fb->offset;
        field->parent = klass;
-       fb->handle = field;
        mono_save_custom_attrs (klass->image, field, fb->cattrs);
 
        if (fb->def_value) {
@@ -8371,9 +8580,8 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        return field;
 }
 
-static MonoType*
-do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types,
-                                           MonoType *parent)
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
 {
        MonoClass *klass;
        MonoReflectionTypeBuilder *tb = NULL;
@@ -8383,7 +8591,7 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        gboolean is_dynamic = FALSE;
        MonoDomain *domain;
        MonoType *geninst;
-       int icount, i;
+       int i;
 
        klass = mono_class_from_mono_type (type->type);
        if (!klass->generic_container && !klass->generic_class &&
@@ -8397,7 +8605,6 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
                tb = (MonoReflectionTypeBuilder *) type;
 
-               icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
                is_dynamic = TRUE;
        } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
                MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
@@ -8406,15 +8613,11 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
                g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder"));
                tb = (MonoReflectionTypeBuilder *) rgt;
 
-               icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
                is_dynamic = TRUE;
        } else if (klass->wastypebuilder) {
                tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
 
-               icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
                is_dynamic = TRUE;
-       } else {
-               icount = klass->interface_count;
        }
 
        if (is_dynamic) {
@@ -8432,16 +8635,21 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        gclass->inst = g_new0 (MonoGenericInst, 1);
 
        gclass->inst->type_argc = type_argc;
-       gclass->inst->type_argv = types;
+       gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
        gclass->inst->is_reference = 1;
 
        for (i = 0; i < gclass->inst->type_argc; ++i) {
+               MonoType *t = dup_type (types [i]);
+
                if (!gclass->inst->is_open)
-                       gclass->inst->is_open = mono_class_is_open_constructed_type (types [i]);
+                       gclass->inst->is_open = mono_class_is_open_constructed_type (t);
                if (gclass->inst->is_reference)
-                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (types [i]);
+                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
+               gclass->inst->type_argv [i] = t;
        }
 
+       gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
        gclass->container_class = klass;
 
        if (klass->generic_class) {
@@ -8483,6 +8691,8 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
                        gclass->inst->type_argv [i] = t;
                }
 
+               gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
                gclass->container_class = kgclass->container_class;
        }
 
@@ -8503,82 +8713,11 @@ do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_a
        gclass->context->container = gclass->container_class->generic_container;
        gclass->context->gclass = gclass;
 
-       if (is_dynamic) {
-               dgclass->parent = parent;
-               dgclass->ifaces = g_new0 (MonoType *, icount);
-               dgclass->count_ifaces = icount;
-
-               for (i = 0; i < icount; i++) {
-                       MonoReflectionType *itype;
-
-                       if (tb)
-                               itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
-                       else
-                               itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
-                       dgclass->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
-                       if (!dgclass->ifaces [i])
-                               dgclass->ifaces [i] = itype->type;
-               }
-       }
-
        mono_loader_unlock ();
 
        return geninst;
 }
 
-MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
-{
-       MonoClass *klass, *pklass = NULL;
-       MonoReflectionType *parent = NULL;
-       MonoType *the_parent = NULL, *geninst;
-       MonoReflectionTypeBuilder *tb = NULL;
-       MonoGenericClass *gclass;
-       MonoDomain *domain;
-
-       domain = mono_object_domain (type);
-       klass = mono_class_from_mono_type (type->type);
-
-       if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
-               tb = (MonoReflectionTypeBuilder *) type;
-
-               if (tb->parent) {
-                       parent = tb->parent;
-                       pklass = mono_class_from_mono_type (parent->type);
-               }
-       } else if (klass->wastypebuilder) {
-               tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
-               if (tb->parent) {
-                       parent = tb->parent;
-                       pklass = mono_class_from_mono_type (parent->type);
-               }
-       } else {
-               pklass = klass->parent;
-               if (pklass)
-                       parent = mono_type_get_object (domain, &pklass->byval_arg);
-               else if (klass->generic_class && klass->generic_class->is_dynamic) {
-                       MonoDynamicGenericClass *dgclass;
-
-                       dgclass = (MonoDynamicGenericClass *) klass->generic_class;
-                       if (dgclass->parent) {
-                               parent = mono_type_get_object (domain, dgclass->parent);
-                               pklass = mono_class_from_mono_type (dgclass->parent);
-                       }
-               }
-       }
-
-       if (pklass && pklass->generic_class)
-               the_parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
-
-       geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, the_parent);
-       if (!geninst)
-               return NULL;
-
-       gclass = geninst->data.generic_class;
-
-       return geninst;
-}
-
 MonoType*
 mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **types)
 {
@@ -8586,7 +8725,7 @@ mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **ty
        MonoGenericClass *gclass, *cached;
        MonoInflatedGenericClass *igclass;
        MonoType *geninst;
-       int icount, i;
+       int i;
 
        klass = mono_class_from_mono_type (type);
        if (!klass->generic_container && !klass->generic_class &&
@@ -8595,24 +8734,28 @@ mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **ty
 
        mono_loader_lock ();
 
-       icount = klass->interface_count;
-
        igclass = g_new0 (MonoInflatedGenericClass, 1);
        gclass = &igclass->generic_class;
        gclass->is_inflated = TRUE;
 
        gclass->inst = g_new0 (MonoGenericInst, 1);
        gclass->inst->type_argc = type_argc;
-       gclass->inst->type_argv = types;
+       gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
        gclass->inst->is_reference = 1;
 
        for (i = 0; i < gclass->inst->type_argc; ++i) {
+               MonoType *t = dup_type (types [i]);
+
                if (!gclass->inst->is_open)
-                       gclass->inst->is_open = mono_class_is_open_constructed_type (types [i]);
+                       gclass->inst->is_open = mono_class_is_open_constructed_type (t);
                if (gclass->inst->is_reference)
-                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (types [i]);
+                       gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
+
+               gclass->inst->type_argv [i] = t;
        }
 
+       gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
        gclass->container_class = klass;
 
        if (klass->generic_class) {
@@ -8645,6 +8788,8 @@ mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **ty
                        gclass->inst->type_argv [i] = t;
                }
 
+               gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
+
                gclass->container_class = kgclass->container_class;
        }
 
@@ -8679,6 +8824,10 @@ dup_type (const MonoType *original)
        r->byref = original->byref;
        if (original->type == MONO_TYPE_PTR)
                r->data.type = dup_type (original->data.type);
+       else if (original->type == MONO_TYPE_ARRAY)
+               r->data.array = mono_dup_array_type (original->data.array);
+       else if (original->type == MONO_TYPE_FNPTR)
+               r->data.method = mono_metadata_signature_deep_dup (original->data.method);
        mono_stats.generics_metadata_size += sizeof (MonoType);
        return r;
 }
@@ -8714,7 +8863,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        if (count != mono_array_length (types))
                return NULL;
 
-       container = ((MonoMethodNormal*) method)->generic_container;
+       container = method->generic_container;
        g_assert (container);
 
        if (!container->method_hash)
@@ -8768,33 +8917,41 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
 static MonoMethod *
 inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
 {
-       MonoGenericMethod *gmethod;
+       MonoGenericMethod *gmethod = NULL;
        MonoInflatedGenericClass *gclass;
        MonoGenericContext *context;
-       int i;
+       MonoClass *klass;
+       int i, n;
 
+       klass = mono_class_from_mono_type (type->type.type);
        gclass = mono_get_inflated_generic_class (type->type.type->data.generic_class);
+       n = mono_method_signature (method)->generic_param_count;
 
-       gmethod = g_new0 (MonoGenericMethod, 1);
-       gmethod->generic_class = &gclass->generic_class;
-       gmethod->inst = g_new0 (MonoGenericInst, 1);
-       gmethod->reflection_info = obj;
+       context = gclass->generic_class.context;
+       g_assert (context && context->container);
+       if (n) {
+               gmethod = g_new0 (MonoGenericMethod, 1);
+               gmethod->generic_class = &gclass->generic_class;
+               gmethod->container = method->generic_container;
+               gmethod->reflection_info = obj;
 
-       gmethod->inst->type_argc = mono_method_signature (method)->generic_param_count;
-       gmethod->inst->type_argv = g_new0 (MonoType *, gmethod->inst->type_argc);
+               gmethod->inst = g_new0 (MonoGenericInst, 1);
+               gmethod->inst->type_argc = n;
+               gmethod->inst->type_argv = g_new0 (MonoType *, n);
 
-       for (i = 0; i < gmethod->inst->type_argc; i++) {
-               MonoMethodNormal *mn = (MonoMethodNormal *) method;
-               MonoGenericParam *gparam = &mn->generic_container->type_params [i];
+               for (i = 0; i < n; i++) {
+                       MonoGenericParam *gparam = &method->generic_container->type_params [i];
+                       g_assert (gparam->pklass);
+                       gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
+               }
 
-               g_assert (gparam->pklass);
-               gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
-       }
+               g_assert (gmethod->container->parent == context->container);
 
-       context = g_new0 (MonoGenericContext, 1);
-       context->container = gclass->generic_class.container_class->generic_container;
-       context->gclass = &gclass->generic_class;
-       context->gmethod = gmethod;
+               context = g_new0 (MonoGenericContext, 1);
+               context->container = gmethod->container;
+               context->gclass = &gclass->generic_class;
+               context->gmethod = gmethod;
+       }
 
        return mono_class_inflate_generic_method (method, context);
 }
@@ -8803,14 +8960,14 @@ static MonoMethod *
 inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
 {
        MonoMethod *method;
-       MonoClass *klass;
+       MonoClass *gklass;
 
-       klass = mono_class_from_mono_type (type->type.type);
+       gklass = mono_class_from_mono_type (type->generic_type->type);
 
        if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
-               method = methodbuilder_to_mono_method (klass, (MonoReflectionMethodBuilder *) obj);
+               method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj);
        else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder"))
-               method = ctorbuilder_to_mono_method (klass, (MonoReflectionCtorBuilder *) obj);
+               method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj);
        else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
                method = ((MonoReflectionMethod *) obj)->method;
        else {
@@ -8828,7 +8985,7 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
 {
        MonoGenericClass *gclass;
        MonoDynamicGenericClass *dgclass;
-       MonoClass *klass, *gklass, *pklass;
+       MonoClass *klass, *gklass;
        int i;
 
        MONO_ARCH_SAVE_REGS;
@@ -8845,11 +9002,6 @@ mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, Mono
        gklass = gclass->container_class;
        mono_class_init (gklass);
 
-       if (dgclass->parent)
-               pklass = mono_class_from_mono_type (dgclass->parent);
-       else
-               pklass = gklass->parent;
-
        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;
@@ -8956,8 +9108,7 @@ static void
 ensure_runtime_vtable (MonoClass *klass)
 {
        MonoReflectionTypeBuilder *tb = klass->reflection_info;
-       int i, num, j, onum;
-       MonoMethod **overrides;
+       int i, num, j;
 
        if (!tb || klass->wastypebuilder)
                return;
@@ -8985,15 +9136,43 @@ ensure_runtime_vtable (MonoClass *klass)
                }
        }
 
-       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE)
+       if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
                for (i = 0; i < klass->method.count; ++i)
                        klass->methods [i]->slot = i;
+               
+               mono_class_setup_interface_offsets (klass);
+       }
+
+       /*
+        * The generic vtable is needed even if image->run is not set since some
+        * runtime code like ves_icall_Type_GetMethodsByName depends on 
+        * method->slot being defined.
+        */
+
+       /* 
+        * tb->methods could not be freed since it is used for determining 
+        * overrides during dynamic vtable construction.
+        */
+}
+
+void
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
+{
+       MonoReflectionTypeBuilder *tb;
+       int i, onum;
 
-       if (!((MonoDynamicImage*)klass->image)->run)
-               /* No need to create a generic vtable */
+       *overrides = NULL;
+       *num_overrides = 0;
+
+       g_assert (klass->image->dynamic);
+
+       if (!klass->reflection_info)
                return;
 
-       /* Overrides */
+       g_assert (strcmp (((MonoObject*)klass->reflection_info)->vtable->klass->name, "TypeBuilder") == 0);
+
+       tb = (MonoReflectionTypeBuilder*)klass->reflection_info;
+
        onum = 0;
        if (tb->methods) {
                for (i = 0; i < tb->num_methods; ++i) {
@@ -9004,20 +9183,21 @@ ensure_runtime_vtable (MonoClass *klass)
                }
        }
 
-       overrides = g_new0 (MonoMethod*, onum * 2);
+       if (onum) {
+               *overrides = g_new0 (MonoMethod*, onum * 2);
 
-       if (tb->methods) {
                onum = 0;
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder *mb = 
                                mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
                        if (mb->override_method) {
-                               /* FIXME: What if 'override_method' is a MethodBuilder ? */
-                               overrides [onum * 2] = 
+                               (*overrides) [onum * 2] = 
                                        mb->override_method->method;
-                               overrides [onum * 2 + 1] =
+                               (*overrides) [onum * 2 + 1] =
                                        mb->mhandle;
 
+                               /* FIXME: What if 'override_method' is a MethodBuilder ? */
+                               g_assert (mb->override_method->method);
                                g_assert (mb->mhandle);
 
                                onum ++;
@@ -9025,8 +9205,7 @@ ensure_runtime_vtable (MonoClass *klass)
                }
        }
 
-       mono_class_setup_vtable_general (klass, overrides, onum);
-       g_free (overrides);
+       *num_overrides = onum;
 }
 
 static void
@@ -9041,7 +9220,6 @@ typebuilder_setup_fields (MonoClass *klass)
 
        klass->field.count = tb->num_fields;
        klass->field.first = 0;
-       klass->field.last = klass->field.count;
 
        if (!klass->field.count)
                return;
@@ -9091,7 +9269,6 @@ typebuilder_setup_properties (MonoClass *klass)
 
        klass->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
        klass->property.first = 0;
-       klass->property.last = klass->property.count;
 
        klass->properties = g_new0 (MonoProperty, klass->property.count);
        for (i = 0; i < klass->property.count; ++i) {
@@ -9147,7 +9324,6 @@ typebuilder_setup_events (MonoClass *klass)
 
        klass->event.count = tb->events ? mono_array_length (tb->events) : 0;
        klass->event.first = 0;
-       klass->event.last = klass->event.count;
 
        klass->events = g_new0 (MonoEvent, klass->event.count);
        for (i = 0; i < klass->event.count; ++i) {
@@ -9260,6 +9436,7 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
 
        res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
        g_assert (res != (MonoReflectionType*)tb);
+
        return res;
 }
 
@@ -9278,22 +9455,8 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
                        gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
                param->owner = gparam->mbuilder->generic_container;
        } else if (gparam->tbuilder) {
-               MonoReflectionTypeBuilder *nesting = (MonoReflectionTypeBuilder*) gparam->tbuilder->nesting_type;
-               MonoGenericContainer *container = gparam->tbuilder->generic_container;
-
-               while (nesting) {
-                       int count;
-
-                       count = nesting->generic_params ? mono_array_length (nesting->generic_params) : 0;
-                       if (gparam->index >= count)
-                               break;
-
-                       container = nesting->generic_container;
-                       nesting = (MonoReflectionTypeBuilder*) nesting->nesting_type;
-               }
-
-               g_assert (container);
-               param->owner = container;
+               g_assert (gparam->tbuilder->generic_container);
+               param->owner = gparam->tbuilder->generic_container;
        }
 
        param->method = NULL;
@@ -9303,7 +9466,7 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
        image = &gparam->tbuilder->module->dynamic_image->image;
        mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
 
-       param->pklass->reflection_info = gparam;
+       param->pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
 
        gparam->type.type = g_new0 (MonoType, 1);
        gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
@@ -9322,7 +9485,7 @@ mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
 
        MONO_ARCH_SAVE_REGS;
 
-       p = buf = g_malloc (size = 10 + na * 10);
+       p = buf = g_malloc (size = 50 + na * 50);
 
        mono_metadata_encode_value (0x07, p, &p);
        mono_metadata_encode_value (na, p, &p);
@@ -9384,18 +9547,23 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
        /*
         * Resolve references.
         */
+       /* 
+        * Every second entry in the refs array is reserved for storing handle_class,
+        * which is needed by the ldtoken implementation in the JIT.
+        */
        rmb.nrefs = mb->nrefs;
        rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
-       for (i = 0; i < mb->nrefs; ++i) {
+       for (i = 0; i < mb->nrefs; i += 2) {
                MonoClass *handle_class;
                gpointer ref = resolve_object (mb->module->image, 
                                               mono_array_get (mb->refs, MonoObject*, i), &handle_class);
                if (!ref) {
                        g_free (rmb.refs);
-                       mono_raise_exception (mono_get_exception_type_load (NULL));
+                       mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
                        return;
                }
-               rmb.refs [i] = ref;
+               rmb.refs [i] = ref; /* FIXME: GC object stored in unamanged memory (change also resolve_object() signature) */
+               rmb.refs [i + 1] = handle_class;
        }               
 
        /* FIXME: class */
@@ -9440,11 +9608,10 @@ resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class)
                result = mono_class_from_mono_type (tb->type);
                *handle_class = mono_defaults.typehandle_class;
                g_assert (result);
-       } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0) {
-               result = ((MonoReflectionMethod*)obj)->method;
-               *handle_class = mono_defaults.methodhandle_class;
-               g_assert (result);
-       } else if (strcmp (obj->vtable->klass->name, "MonoCMethod") == 0) {
+       } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
+                  strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
+                  strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
+                  strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
                result = ((MonoReflectionMethod*)obj)->method;
                *handle_class = mono_defaults.methodhandle_class;
                g_assert (result);