2004-09-02 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / reflection.c
index 5305535bbf441200858a2587481f5490ef675f78..dc70fab01662290b310d451fb0e144a6863fddf1 100644 (file)
 #include "mono/utils/mono-digest.h"
 #include "mono/metadata/reflection.h"
 #include "mono/metadata/tabledefs.h"
+#include "mono/metadata/metadata-internals.h"
+#include "mono/metadata/class-internals.h"
 #include "mono/metadata/tokentype.h"
-#include "mono/metadata/appdomain.h"
+#include "mono/metadata/domain-internals.h"
 #include "mono/metadata/opcodes.h"
 #include "mono/metadata/assembly.h"
+#include "mono/metadata/object-internals.h"
 #include <mono/metadata/exception.h>
 #include <stdio.h>
 #include <glib.h>
@@ -41,6 +44,7 @@ typedef struct {
        MonoArray *parameters;
        MonoArray *generic_params;
        MonoArray *pinfo;
+       MonoArray *opt_types;
        guint32 attrs;
        guint32 iattrs;
        guint32 call_conv;
@@ -59,6 +63,11 @@ typedef struct {
        gpointer *refs;
 } ReflectionMethodBuilder;
 
+typedef struct {
+       guint32 owner;
+       MonoReflectionGenericParam *gparam;
+} GenericParamTableEntry;
+
 const unsigned char table_sizes [64] = {
        MONO_MODULE_SIZE,
        MONO_TYPEREF_SIZE,
@@ -134,6 +143,7 @@ static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, Mon
 static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper);
 static void    mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly);
 static guint32 encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo);
+static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type);
 static char*   type_get_qualified_name (MonoType *type, MonoAssembly *ass);
 static void    ensure_runtime_vtable (MonoClass *klass);
 static gpointer resolve_object (MonoImage *image, MonoObject *obj);
@@ -541,7 +551,6 @@ generic_inst_get_signature_size (MonoGenericInst *ginst)
 
        if (!ginst) {
                g_assert_not_reached ();
-               return;
        }
 
        size += 1 + type_get_signature_size (ginst->generic_type);
@@ -559,7 +568,6 @@ type_get_signature_size (MonoType *type)
 
        if (!type) {
                g_assert_not_reached ();
-               return;
        }
                
        if (type->byref)
@@ -604,6 +612,7 @@ type_get_signature_size (MonoType *type)
 
        default:
                g_error ("need to encode type %x", type->type);
+               return size;
        }
 }
 
@@ -619,6 +628,8 @@ method_get_signature_size (MonoMethodSignature *sig)
 
        if (sig->generic_param_count)
                size += 4;
+       if (sig->sentinelpos >= 0)
+               size++;
 
        return size;    
 }
@@ -652,8 +663,11 @@ method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
                mono_metadata_encode_value (sig->generic_param_count, p, &p);
        mono_metadata_encode_value (nparams, p, &p);
        encode_type (assembly, sig->ret, p, &p);
-       for (i = 0; i < nparams; ++i)
+       for (i = 0; i < nparams; ++i) {
+               if (i == sig->sentinelpos)
+                       *p++ = MONO_TYPE_SENTINEL;
                encode_type (assembly, sig->params [i], p, &p);
+       }
        /* store length */
        g_assert (p - buf < size);
        mono_metadata_encode_value (p-buf, b, &b);
@@ -673,7 +687,8 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui
        int i;
        guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
        guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
-       guint32 size = 21 + nparams * 20;
+       guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
+       guint32 size = 21 + nparams * 20 + notypes * 20;
        guint32 idx;
        char blob_size [6];
        char *b = blob_size;
@@ -690,7 +705,7 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui
        p++;
        if (ngparams)
                mono_metadata_encode_value (ngparams, p, &p);
-       mono_metadata_encode_value (nparams, p, &p);
+       mono_metadata_encode_value (nparams + notypes, p, &p);
        encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, p, &p);
        encode_reflection_type (assembly, mb->rtype, p, &p);
        for (i = 0; i < nparams; ++i) {
@@ -706,6 +721,15 @@ method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBui
                pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
                encode_reflection_type (assembly, pt, p, &p);
        }
+       if (notypes)
+               *p++ = MONO_TYPE_SENTINEL;
+       for (i = 0; i < notypes; ++i) {
+               MonoReflectionType *pt;
+
+               pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
+               encode_reflection_type (assembly, pt, p, &p);
+       }
+
        /* store length */
        g_assert (p - buf < size);
        mono_metadata_encode_value (p-buf, b, &b);
@@ -739,6 +763,10 @@ encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
        mono_metadata_encode_value (nl, p, &p);
        for (i = 0; i < nl; ++i) {
                MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
+               
+               if (lb->is_pinned)
+                       mono_metadata_encode_value (MONO_TYPE_PINNED, p, &p);
+               
                encode_reflection_type (assembly, lb->type, p, &p);
        }
        g_assert (p - buf < size);
@@ -1018,6 +1046,7 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
                dynamic_custom_attrs = g_hash_table_new (NULL, NULL);
 
        g_hash_table_insert (dynamic_custom_attrs, obj, ainfo);
+       ainfo->cached = TRUE;
 }
 
 void
@@ -1031,7 +1060,7 @@ mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
 
 /*
  * idx is the table index of the object
- * type is one of CUSTOM_ATTR_*
+ * type is one of MONO_CUSTOM_ATTR_*
  */
 static void
 mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs)
@@ -1051,20 +1080,20 @@ mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, Mo
        table->rows += count;
        alloc_table (table, table->rows);
        values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
-       idx <<= CUSTOM_ATTR_BITS;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
        idx |= type;
        for (i = 0; i < count; ++i) {
                cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
                values [MONO_CUSTOM_ATTR_PARENT] = idx;
-               token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor);
+               token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE);
                type = mono_metadata_token_index (token);
-               type <<= CUSTOM_ATTR_TYPE_BITS;
+               type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
                switch (mono_metadata_token_table (token)) {
                case MONO_TABLE_METHOD:
-                       type |= CUSTOM_ATTR_TYPE_METHODDEF;
+                       type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
                        break;
                case MONO_TABLE_MEMBERREF:
-                       type |= CUSTOM_ATTR_TYPE_MEMBERREF;
+                       type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
                        break;
                default:
                        g_warning ("got wrong token in custom attr");
@@ -1103,16 +1132,16 @@ mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token,
                values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE;
 
                idx = mono_metadata_token_index (parent_token);
-               idx <<= HAS_DECL_SECURITY_BITS;
+               idx <<= MONO_HAS_DECL_SECURITY_BITS;
                switch (mono_metadata_token_table (parent_token)) {
                case MONO_TABLE_TYPEDEF:
-                       idx |= HAS_DECL_SECURITY_TYPEDEF;
+                       idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
                        break;
                case MONO_TABLE_METHOD:
-                       idx |= HAS_DECL_SECURITY_METHODDEF;
+                       idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
                        break;
                case MONO_TABLE_ASSEMBLY:
-                       idx |= HAS_DECL_SECURITY_ASSEMBLY;
+                       idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
                        break;
                default:
                        g_assert_not_reached ();
@@ -1182,18 +1211,29 @@ mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly
                                        name = mono_string_to_utf8 (pb->name);
                                        values [MONO_PARAM_NAME] = string_heap_insert (&assembly->sheap, name);
                                        g_free (name);
-                               }
-                               else
+                               } else {
                                        values [MONO_PARAM_NAME] = 0;
+                               }
                                values += MONO_PARAM_SIZE;
                                if (pb->marshal_info) {
                                        mtable->rows++;
                                        alloc_table (mtable, mtable->rows);
                                        mvalues = mtable->values + mtable->rows * MONO_FIELD_MARSHAL_SIZE;
-                                       mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_PARAMDEF;
+                                       mvalues [MONO_FIELD_MARSHAL_PARENT] = (table->next_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_PARAMDEF;
                                        mvalues [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, pb->marshal_info);
                                }
                                pb->table_idx = table->next_idx++;
+                               if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
+                                       guint32 field_type = 0;
+                                       mtable = &assembly->tables [MONO_TABLE_CONSTANT];
+                                       mtable->rows ++;
+                                       alloc_table (mtable, mtable->rows);
+                                       mvalues = mtable->values + mtable->rows * MONO_CONSTANT_SIZE;
+                                       mvalues [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_PARAM | (pb->table_idx << MONO_HASCONSTANT_BITS);
+                                       mvalues [MONO_CONSTANT_VALUE] = encode_constant (assembly, pb->def_value, &field_type);
+                                       mvalues [MONO_CONSTANT_TYPE] = field_type;
+                                       mvalues [MONO_CONSTANT_PADDING] = 0;
+                               }
                        }
                }
        }
@@ -1207,6 +1247,7 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb,
        rmb->rtype = mb->rtype;
        rmb->parameters = mb->parameters;
        rmb->generic_params = mb->generic_params;
+       rmb->opt_types = NULL;
        rmb->pinfo = mb->pinfo;
        rmb->attrs = mb->attrs;
        rmb->iattrs = mb->iattrs;
@@ -1236,6 +1277,7 @@ reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb,
        rmb->rtype = mono_type_get_object (mono_domain_get (), &mono_defaults.void_class->byval_arg);
        rmb->parameters = mb->parameters;
        rmb->generic_params = NULL;
+       rmb->opt_types = NULL;
        rmb->pinfo = mb->pinfo;
        rmb->attrs = mb->attrs;
        rmb->iattrs = mb->iattrs;
@@ -1263,6 +1305,7 @@ reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb,
        rmb->rtype = mb->rtype;
        rmb->parameters = mb->parameters;
        rmb->generic_params = NULL;
+       rmb->opt_types = NULL;
        rmb->pinfo = NULL;
        rmb->attrs = mb->attrs;
        rmb->iattrs = 0;
@@ -1330,14 +1373,15 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *a
                alloc_table (table, table->rows);
                values = table->values + table->rows * MONO_METHODIMPL_SIZE;
                values [MONO_METHODIMPL_CLASS] = tb->table_idx;
-               values [MONO_METHODIMPL_BODY] = METHODDEFORREF_METHODDEF | (mb->table_idx << METHODDEFORREF_BITS);
-               tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method);
+               values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+               tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE);
                switch (mono_metadata_token_table (tok)) {
                case MONO_TABLE_MEMBERREF:
-                       tok = (mono_metadata_token_index (tok) << METHODDEFORREF_BITS ) | METHODDEFORREF_METHODREF;
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
                        break;
                case MONO_TABLE_METHOD:
-                       tok = (mono_metadata_token_index (tok) << METHODDEFORREF_BITS ) | METHODDEFORREF_METHODDEF;
+                       tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
                        break;
                default:
                        g_assert_not_reached ();
@@ -1379,11 +1423,11 @@ type_get_fully_qualified_name (MonoType *type) {
        klass = my_mono_class_from_mono_type (type);
        ta = klass->image->assembly;
 
-       /* missing public key */
-       result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s",
+       result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s",
                name, ta->aname.name,
                ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
-               ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral");
+               ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral",
+               ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null");
        g_free (name);
        return result;
 }
@@ -1548,7 +1592,16 @@ encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
                mono_metadata_encode_value (minfo->type, p, &p);
                mono_metadata_encode_value (minfo->count, p, &p);
                break;
-               /* FIXME: handle ARRAY and other unmanaged types that need extra info */
+       case MONO_NATIVE_LPARRAY:
+               mono_metadata_encode_value (minfo->type, p, &p);
+               if (minfo->eltype || (minfo->count > 0)) {
+                       mono_metadata_encode_value (minfo->eltype, p, &p);
+                       if (minfo->count > 0) {
+                               mono_metadata_encode_value (0, p, &p);
+                               mono_metadata_encode_value (minfo->count, p, &p);
+                       }
+               }
+               break;
        case MONO_NATIVE_CUSTOM:
                mono_metadata_encode_value (minfo->type, p, &p);
                if (minfo->guid) {
@@ -1655,7 +1708,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
                table->rows ++;
                alloc_table (table, table->rows);
                values = table->values + table->rows * MONO_CONSTANT_SIZE;
-               values [MONO_CONSTANT_PARENT] = HASCONSTANT_FIEDDEF | (fb->table_idx << HASCONSTANT_BITS);
+               values [MONO_CONSTANT_PARENT] = MONO_HASCONSTANT_FIEDDEF | (fb->table_idx << MONO_HASCONSTANT_BITS);
                values [MONO_CONSTANT_VALUE] = encode_constant (assembly, fb->def_value, &field_type);
                values [MONO_CONSTANT_TYPE] = field_type;
                values [MONO_CONSTANT_PADDING] = 0;
@@ -1681,7 +1734,7 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *ass
                table->rows ++;
                alloc_table (table, table->rows);
                values = table->values + table->rows * MONO_FIELD_MARSHAL_SIZE;
-               values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << HAS_FIELD_MARSHAL_BITS) | HAS_FIELD_MARSHAL_FIELDSREF;
+               values [MONO_FIELD_MARSHAL_PARENT] = (fb->table_idx << MONO_HAS_FIELD_MARSHAL_BITS) | MONO_HAS_FIELD_MARSHAL_FIELDSREF;
                values [MONO_FIELD_MARSHAL_NATIVE_TYPE] = encode_marshal_blob (assembly, fb->marshal_info);
        }
 }
@@ -1766,14 +1819,14 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImag
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
                values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
        }
        if (pb->set_method) {
                semaidx = table->next_idx ++;
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
                values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY;
        }
 }
 
@@ -1818,22 +1871,91 @@ mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *ass
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_ADD_ON;
                values [MONO_METHOD_SEMA_METHOD] = eb->add_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
        }
        if (eb->remove_method) {
                semaidx = table->next_idx ++;
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_REMOVE_ON;
                values [MONO_METHOD_SEMA_METHOD] = eb->remove_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
        }
        if (eb->raise_method) {
                semaidx = table->next_idx ++;
                values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
                values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_FIRE;
                values [MONO_METHOD_SEMA_METHOD] = eb->raise_method->table_idx;
-               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (eb->table_idx << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT;
+       }
+}
+
+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) {
+               int i;
+
+               for (i = 0; i < NewConstraintAttr->method.count; i++) {
+                       MonoMethod *m = NewConstraintAttr->methods [i];
+
+                       if (strcmp (m->name, ".ctor"))
+                               continue;
+
+                       NewConstraintAttr_ctor = m;
+                       break;
+               }
+
+               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
@@ -1845,23 +1967,59 @@ encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynam
        guint32 table_idx;
 
        table = &assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
-       num_constraints = gparam ? mono_array_length (gparam->constraints) : 0;
+       num_constraints = gparam->iface_constraints ?
+               mono_array_length (gparam->iface_constraints) : 0;
        table->rows += num_constraints;
+       if (gparam->base_type)
+               table->rows++;
        alloc_table (table, table->rows);
 
+       if (gparam->base_type) {
+               table_idx = table->next_idx ++;
+               values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
+
+               values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
+               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
+                       assembly, gparam->base_type->type);
+       }
+
        for (i = 0; i < num_constraints; i++) {
-               MonoReflectionType *constraint = mono_array_get (gparam->constraints, gpointer, i);
+               MonoReflectionType *constraint = mono_array_get (
+                       gparam->iface_constraints, gpointer, i);
 
                table_idx = table->next_idx ++;
                values = table->values + table_idx * MONO_GENPARCONSTRAINT_SIZE;
 
                values [MONO_GENPARCONSTRAINT_GENERICPAR] = owner;
-               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (assembly, constraint->type);
+               values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
+                       assembly, constraint->type);
        }
+
+       if (gparam->has_ctor_constraint)
+               encode_new_constraint (assembly, owner);
 }
 
 static void
 mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
+{
+       GenericParamTableEntry *entry;
+
+       /*
+        * The GenericParam table must be sorted according to the `owner' field.
+        * We need to do this sorting prior to writing the GenericParamConstraint
+        * table, since we have to use the final GenericParam table indices there
+        * and they must also be sorted.
+        */
+
+       entry = g_new0 (GenericParamTableEntry, 1);
+       entry->owner = owner;
+       entry->gparam = gparam;
+
+       g_ptr_array_add (assembly->gen_params, entry);
+}
+
+static void
+write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry)
 {
        MonoDynamicTable *table;
        MonoGenericParam *param;
@@ -1872,17 +2030,20 @@ mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 o
        table_idx = table->next_idx ++;
        values = table->values + table_idx * MONO_GENERICPARAM_SIZE;
 
-       param = gparam->type.type->data.generic_param;
+       param = entry->gparam->type.type->data.generic_param;
 
-       values [MONO_GENERICPARAM_OWNER] = owner;
-       values [MONO_GENERICPARAM_FLAGS] = param->flags;
+       values [MONO_GENERICPARAM_OWNER] = entry->owner;
+       if (entry->gparam->has_value_type)
+               values [MONO_GENERICPARAM_FLAGS] = 0x18;
+       else if (entry->gparam->has_reference_type)
+               values [MONO_GENERICPARAM_FLAGS] = 0x04;
+       else
+               values [MONO_GENERICPARAM_FLAGS] = 0x00;
        values [MONO_GENERICPARAM_NUMBER] = param->num;
        values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
        values [MONO_GENERICPARAM_KIND] = 0;
-       values [MONO_GENERICPARAM_DEPRECATED_CONSTRAINT] = 0;
 
-       if (gparam->constraints)
-               encode_constraints (gparam, table_idx, assembly);
+       encode_constraints (entry->gparam, table_idx, assembly);
 }
 
 static guint32
@@ -1906,8 +2067,8 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
                values = table->values + token * MONO_MODULEREF_SIZE;
                values [MONO_MODULEREF_NAME] = string_heap_insert (&assembly->sheap, image->module_name);
 
-               token <<= RESOLTION_SCOPE_BITS;
-               token |= RESOLTION_SCOPE_MODULEREF;
+               token <<= MONO_RESOLTION_SCOPE_BITS;
+               token |= MONO_RESOLTION_SCOPE_MODULEREF;
                g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
 
                return token;
@@ -1927,10 +2088,7 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
        table->rows ++;
        alloc_table (table, table->rows);
        values = table->values + token * MONO_ASSEMBLYREF_SIZE;
-       if (strcmp ("corlib", image->assembly_name) == 0)
-               values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, "mscorlib");
-       else
-               values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
+       values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
        values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
        values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
        values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
@@ -1939,63 +2097,21 @@ resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
        values [MONO_ASSEMBLYREF_CULTURE] = 0;
        values [MONO_ASSEMBLYREF_HASH_VALUE] = 0;
 
+       if (strcmp ("", image->assembly->aname.culture)) {
+               values [MONO_ASSEMBLYREF_CULTURE] = string_heap_insert (&assembly->sheap,
+                               image->assembly->aname.culture);
+       }
+
        if ((pubkey = mono_image_get_public_key (image, &publen))) {
                guchar pubtoken [9];
                pubtoken [0] = 8;
                mono_digest_get_public_token (pubtoken + 1, pubkey, publen);
                values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, pubtoken, 9);
        } else {
-               /* 
-                * We add the pubtoken from ms, so that the ms runtime can handle our binaries.
-                * This is currently only a problem with references to System.Xml (see bug#27706),
-                * but there may be other cases that makes this necessary. Note, we need to set 
-                * the version as well. When/if we sign our assemblies, we'd need to get our pubtoken 
-                * recognized by ms, yuck!
-                * FIXME: need to add more assembly names, as needed.
-                */
-               if (strcmp (image->assembly_name, "corlib") == 0 ||
-                               strcmp (image->assembly_name, "mscorlib") == 0 ||
-                               strcmp (image->assembly_name, "System") == 0 ||
-                               strcmp (image->assembly_name, "System.Runtime.Remoting") == 0 ||
-                               strcmp (image->assembly_name, "System.Xml") == 0 ||
-                               strcmp (image->assembly_name, "System.Data") == 0 ||
-                               strcmp (image->assembly_name, "System.Windows.Forms") == 0) {
-                       static const guchar ptoken [9] = {8, '\xB7', '\x7A', '\x5C', '\x56', '\x19', '\x34', '\xE0', '\x89'};
-                       values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, ptoken, 9);
-                       values [MONO_ASSEMBLYREF_MAJOR_VERSION] = 1;
-                       values [MONO_ASSEMBLYREF_BUILD_NUMBER] = 3300;
-               } else if (strcmp (image->assembly_name, "Accessibility") == 0 ||
-                               strcmp (image->assembly_name, "cscompmgd") == 0 ||
-                               strcmp (image->assembly_name, "CustomMarshalers") == 0 ||
-                               strcmp (image->assembly_name, "Microsoft.JScript") == 0 ||
-                               strcmp (image->assembly_name, "Microsoft.VisualBasic") == 0 ||
-                               strcmp (image->assembly_name, "Microsoft.VisualBasic.Vsa") == 0 ||
-                               strcmp (image->assembly_name, "Microsoft.VisualC") == 0 ||
-                               strcmp (image->assembly_name, "Microsoft.Vsa") == 0 ||
-                               strcmp (image->assembly_name, "System.Configuration.Install") == 0 ||
-                               strcmp (image->assembly_name, "System.DirectoryServices") == 0 ||
-                               strcmp (image->assembly_name, "System.Design") == 0 ||
-                               strcmp (image->assembly_name, "System.Drawing") == 0 ||
-                               strcmp (image->assembly_name, "System.Drawing.Design") == 0 ||
-                               strcmp (image->assembly_name, "System.EnterpriseServices") == 0 ||
-                               strcmp (image->assembly_name, "System.Management") == 0 ||
-                               strcmp (image->assembly_name, "System.Messaging") == 0 ||
-                               strcmp (image->assembly_name, "System.Runtime.Serialization.Formatters.Soap") == 0 ||
-                               strcmp (image->assembly_name, "System.Security") == 0 ||
-                               strcmp (image->assembly_name, "System.ServiceProcess") == 0 ||
-                               strcmp (image->assembly_name, "System.Web.Services") == 0 ||
-                               strcmp (image->assembly_name, "CustomMarshalers") == 0 ||
-                               strcmp (image->assembly_name, "System.Web") == 0) {
-                       static const guchar ptoken [9] = {8, '\xb0', '\x3f', '\x5f', '\x7f', '\x11', '\xd5', '\x0a', '\x3a'};
-                       values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, ptoken, 9);
-                       values [MONO_ASSEMBLYREF_MAJOR_VERSION] = 1;
-                       values [MONO_ASSEMBLYREF_BUILD_NUMBER] = 3300;
-               } else {
-                       values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
-               }
+               values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
        }
-       token <<= RESOLTION_SCOPE_BITS;
-       token |= RESOLTION_SCOPE_ASSEMBLYREF;
+       token <<= MONO_RESOLTION_SCOPE_BITS;
+       token |= MONO_RESOLTION_SCOPE_ASSEMBLYREF;
        g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
        return token;
 }
@@ -2043,7 +2159,7 @@ create_typespec (MonoDynamicImage *assembly, MonoType *type)
                values [MONO_TYPESPEC_SIGNATURE] = token;
        }
 
-       token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
+       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
        g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        return token;
@@ -2076,7 +2192,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
        if ((klass->image == &assembly->image) &&
            (type->type != MONO_TYPE_VAR) && (type->type != MONO_TYPE_MVAR)) {
                MonoReflectionTypeBuilder *tb = klass->reflection_info;
-               token = TYPEDEFORREF_TYPEDEF | (tb->table_idx << TYPEDEFORREF_BITS);
+               token = MONO_TYPEDEFORREF_TYPEDEF | (tb->table_idx << MONO_TYPEDEFORREF_BITS);
                mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
                return token;
        }
@@ -2084,8 +2200,8 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
        if (klass->nested_in) {
                enclosing = mono_image_typedef_or_ref (assembly, &klass->nested_in->byval_arg);
                /* get the typeref idx of the enclosing type */
-               enclosing >>= TYPEDEFORREF_BITS;
-               scope = (enclosing << RESOLTION_SCOPE_BITS) | RESOLTION_SCOPE_TYPEREF;
+               enclosing >>= MONO_TYPEDEFORREF_BITS;
+               scope = (enclosing << MONO_RESOLTION_SCOPE_BITS) | MONO_RESOLTION_SCOPE_TYPEREF;
        } else {
                scope = resolution_scope_from_image (assembly, klass->image);
        }
@@ -2097,7 +2213,7 @@ mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
                values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
                values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
        }
-       token = TYPEDEFORREF_TYPEREF | (table->next_idx << TYPEDEFORREF_BITS); /* typeref */
+       token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
        g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass->reflection_info);
@@ -2119,29 +2235,29 @@ mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, cons
        guint32 parent;
 
        parent = mono_image_typedef_or_ref (assembly, type);
-       switch (parent & TYPEDEFORREF_MASK) {
-       case TYPEDEFORREF_TYPEREF:
-               pclass = MEMBERREF_PARENT_TYPEREF;
+       switch (parent & MONO_TYPEDEFORREF_MASK) {
+       case MONO_TYPEDEFORREF_TYPEREF:
+               pclass = MONO_MEMBERREF_PARENT_TYPEREF;
                break;
-       case TYPEDEFORREF_TYPESPEC:
-               pclass = MEMBERREF_PARENT_TYPESPEC;
+       case MONO_TYPEDEFORREF_TYPESPEC:
+               pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
                break;
-       case TYPEDEFORREF_TYPEDEF:
-               pclass = MEMBERREF_PARENT_TYPEDEF;
+       case MONO_TYPEDEFORREF_TYPEDEF:
+               pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
                break;
        default:
                g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
                return 0;
        }
        /* extract the index */
-       parent >>= TYPEDEFORREF_BITS;
+       parent >>= MONO_TYPEDEFORREF_BITS;
 
        table = &assembly->tables [MONO_TABLE_MEMBERREF];
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
                values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS);
+               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
                values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
                values [MONO_MEMBERREF_SIGNATURE] = sig;
        }
@@ -2166,6 +2282,30 @@ mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method)
        return token;
 }
 
+static guint32
+mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original,
+                                    const gchar *name, guint32 sig)
+{
+       MonoDynamicTable *table;
+       guint32 token;
+       guint32 *values;
+       
+       table = &assembly->tables [MONO_TABLE_MEMBERREF];
+
+       if (assembly->save) {
+               alloc_table (table, table->rows + 1);
+               values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
+               values [MONO_MEMBERREF_CLASS] = original;
+               values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
+               values [MONO_MEMBERREF_SIGNATURE] = sig;
+       }
+
+       token = MONO_TOKEN_MEMBER_REF | table->next_idx;
+       table->next_idx ++;
+
+       return token;
+}
+
 static guint32
 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
 {
@@ -2214,7 +2354,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *
        if (token)
                return token;
        g_assert (f->field->parent);
-       type = f->field->generic_type ? f->field->generic_type : f->field->type;
+       type = f->field->generic_info ? f->field->generic_info->generic_type : f->field->type;
        token = mono_image_get_memberref_token (assembly, &f->klass->byval_arg, 
                f->field->name,  fieldref_encode_signature (assembly, type));
        g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
@@ -2240,7 +2380,7 @@ encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmetho
        /*
         * FIXME: vararg, explicit_this, differenc call_conv values...
         */
-       mono_metadata_encode_value (0xa, p, &p); /// FIXME FIXME FIXME
+       mono_metadata_encode_value (0xa, p, &p); /* FIXME FIXME FIXME */
        mono_metadata_encode_value (nparams, p, &p);
 
        for (i = 0; i < nparams; i++)
@@ -2260,34 +2400,34 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token, mtoken = 0, sig;
-       MonoGenericMethod *gmethod;
+       MonoMethodInflated *imethod;
        MonoMethod *declaring;
 
        table = &assembly->tables [MONO_TABLE_METHODSPEC];
 
-       g_assert ((gmethod = method->signature->gen_method) != NULL);
-       declaring = gmethod->generic_method;
-       if (declaring->signature->gen_method)
-               declaring = declaring->signature->gen_method->generic_method;
+       g_assert (method->signature->is_inflated);
+       imethod = (MonoMethodInflated *) method;
+       declaring = imethod->declaring;
+
        sig = method_encode_signature (assembly, declaring->signature);
        mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
                                                 declaring->name, sig);
 
-       if (!gmethod->generic_method->signature->generic_param_count)
+       if (!declaring->signature->generic_param_count)
                return mtoken;
 
        switch (mono_metadata_token_table (mtoken)) {
        case MONO_TABLE_MEMBERREF:
-               mtoken = (mono_metadata_token_index (mtoken) << METHODDEFORREF_BITS) | METHODDEFORREF_METHODREF;
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF;
                break;
        case MONO_TABLE_METHOD:
-               mtoken = (mono_metadata_token_index (mtoken) << METHODDEFORREF_BITS) | METHODDEFORREF_METHODDEF;
+               mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
                break;
        default:
                g_assert_not_reached ();
        }
 
-       sig = encode_generic_method_sig (assembly, gmethod);
+       sig = encode_generic_method_sig (assembly, imethod->context->gmethod);
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
@@ -2305,27 +2445,42 @@ method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
 static guint32
 mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
 {
-       MonoGenericMethod *gmethod;
+       MonoMethodInflated *imethod;
        guint32 token;
        
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
        if (token)
                return token;
 
-       g_assert ((gmethod = m->signature->gen_method) != NULL);
+       g_assert (m->signature->is_inflated);
+       imethod = (MonoMethodInflated *) m;
 
-       if (gmethod->generic_method->signature->generic_param_count)
+       if (imethod->declaring->signature->generic_param_count)
                token = method_encode_methodspec (assembly, m);
        else {
-               guint32 sig = method_encode_signature (assembly, gmethod->generic_method->signature);
+               guint32 sig = method_encode_signature (
+                       assembly, imethod->declaring->signature);
                token = mono_image_get_memberref_token (
-                       assembly, &m->klass->byval_arg, gmethod->generic_method->name, sig);
+                       assembly, &m->klass->byval_arg, m->name, sig);
        }
 
        g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token));
        return token;
 }
 
+static guint32
+mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m)
+{
+       MonoMethodInflated *imethod = (MonoMethodInflated *) m;
+       guint32 sig, token;
+
+       sig = method_encode_signature (assembly, imethod->declaring->signature);
+       token = mono_image_get_memberref_token (
+               assembly, &m->klass->byval_arg, m->name, sig);
+
+       return token;
+}
+
 static guint32
 create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb)
 {
@@ -2339,6 +2494,16 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *
        char *b = blob_size;
        int count, i;
 
+       /*
+        * We're creating a TypeSpec for the TypeBuilder of a generic type declaration,
+        * ie. what we'd normally use as the generic type in a TypeSpec signature.
+        * Because of this, we must not insert it into the `typeref' hash table.
+        */
+
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, tb->type.type));
+       if (token)
+               return token;
+
        g_assert (tb->generic_params);
        klass = mono_class_from_mono_type (tb->type.type);
 
@@ -2365,8 +2530,8 @@ create_generic_typespec (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *
                values [MONO_TYPESPEC_SIGNATURE] = token;
        }
 
-       token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
-       g_hash_table_insert (assembly->typeref, tb->type.type, GUINT_TO_POINTER(token));
+       token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
+       g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        return token;
 }
@@ -2380,30 +2545,34 @@ mono_image_get_generic_field_token (MonoDynamicImage *assembly, MonoReflectionFi
        guint32 token, pclass, parent, sig;
        gchar *name;
 
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, fb));
+       if (token)
+               return token;
+
        klass = mono_class_from_mono_type (fb->typeb->type);
        name = mono_string_to_utf8 (fb->name);
 
        sig = fieldref_encode_signature (assembly, fb->type->type);
 
        parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
-       g_assert ((parent & TYPEDEFORREF_MASK) == TYPEDEFORREF_TYPESPEC);
+       g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_TYPEDEFORREF_TYPESPEC);
        
-       pclass = MEMBERREF_PARENT_TYPESPEC;
-       parent >>= TYPEDEFORREF_BITS;
+       pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
+       parent >>= MONO_TYPEDEFORREF_BITS;
 
        table = &assembly->tables [MONO_TABLE_MEMBERREF];
 
        if (assembly->save) {
                alloc_table (table, table->rows + 1);
                values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
-               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS);
+               values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
                values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
                values [MONO_MEMBERREF_SIGNATURE] = sig;
        }
 
        token = MONO_TOKEN_MEMBER_REF | table->next_idx;
        table->next_idx ++;
-
+       g_hash_table_insert (assembly->handleref, fb, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -2517,6 +2686,7 @@ mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMetho
        nparams = mono_array_length (m->parameters);
        sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * nparams);
        sig->hasthis = 1;
+       sig->sentinelpos = -1;
        sig->call_convention = reflection_cc_to_file (m->call_conv);
        sig->param_count = nparams;
        sig->ret = m->ret? m->ret->type: &mono_defaults.void_class->byval_arg;
@@ -2584,7 +2754,8 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
         * if we have explicitlayout or sequentiallayouts, output data in the
         * ClassLayout table.
         */
-       if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) && (tb->class_size != -1)) {
+       if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
+           ((tb->class_size > 0) || (tb->packing_size > 0))) {
                table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
                table->rows++;
                alloc_table (table, table->rows);
@@ -2609,19 +2780,6 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
                }
        }
 
-       /* handle generic parameters */
-       if (tb->generic_params) {
-               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
-               table->rows += mono_array_length (tb->generic_params);
-               alloc_table (table, table->rows);
-               for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
-                       guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
-
-                       mono_image_get_generic_param_info (
-                               mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
-               }
-       }
-
        /* handle fields */
        if (tb->fields) {
                table = &assembly->tables [MONO_TABLE_FIELD];
@@ -2682,6 +2840,19 @@ mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, Mon
                                mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly);
        }
 
+       /* handle generic parameters */
+       if (tb->generic_params) {
+               table = &assembly->tables [MONO_TABLE_GENERICPARAM];
+               table->rows += mono_array_length (tb->generic_params);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
+                       guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);
+
+                       mono_image_get_generic_param_info (
+                               mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
+               }
+       }
+
        mono_image_add_decl_security (assembly, 
                                                                  mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx),
                                                                  tb->permissions);
@@ -2749,7 +2920,7 @@ params_add_cattrs (MonoDynamicImage *assembly, MonoArray *pinfo) {
                pb = mono_array_get (pinfo, MonoReflectionParamBuilder *, i);
                if (!pb)
                        continue;
-               mono_image_add_cattrs (assembly, pb->table_idx, CUSTOM_ATTR_PARAMDEF, pb->cattrs);
+               mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PARAMDEF, pb->cattrs);
        }
 }
 
@@ -2757,33 +2928,33 @@ static void
 type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) {
        int i;
        
-       mono_image_add_cattrs (assembly, tb->table_idx, CUSTOM_ATTR_TYPEDEF, tb->cattrs);
+       mono_image_add_cattrs (assembly, tb->table_idx, MONO_CUSTOM_ATTR_TYPEDEF, tb->cattrs);
        if (tb->fields) {
                for (i = 0; i < tb->num_fields; ++i) {
                        MonoReflectionFieldBuilder* fb;
                        fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i);
-                       mono_image_add_cattrs (assembly, fb->table_idx, CUSTOM_ATTR_FIELDDEF, fb->cattrs);
+                       mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs);
                }
        }
        if (tb->events) {
                for (i = 0; i < mono_array_length (tb->events); ++i) {
                        MonoReflectionEventBuilder* eb;
                        eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
-                       mono_image_add_cattrs (assembly, eb->table_idx, CUSTOM_ATTR_EVENT, eb->cattrs);
+                       mono_image_add_cattrs (assembly, eb->table_idx, MONO_CUSTOM_ATTR_EVENT, eb->cattrs);
                }
        }
        if (tb->properties) {
                for (i = 0; i < mono_array_length (tb->properties); ++i) {
                        MonoReflectionPropertyBuilder* pb;
                        pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
-                       mono_image_add_cattrs (assembly, pb->table_idx, CUSTOM_ATTR_PROPERTY, pb->cattrs);
+                       mono_image_add_cattrs (assembly, pb->table_idx, MONO_CUSTOM_ATTR_PROPERTY, pb->cattrs);
                }
        }
        if (tb->ctors) {
                for (i = 0; i < mono_array_length (tb->ctors); ++i) {
                        MonoReflectionCtorBuilder* cb;
                        cb = mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i);
-                       mono_image_add_cattrs (assembly, cb->table_idx, CUSTOM_ATTR_METHODDEF, cb->cattrs);
+                       mono_image_add_cattrs (assembly, cb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, cb->cattrs);
                        params_add_cattrs (assembly, cb->pinfo);
                }
        }
@@ -2792,7 +2963,7 @@ type_add_cattrs (MonoDynamicImage *assembly, MonoReflectionTypeBuilder *tb) {
                for (i = 0; i < tb->num_methods; ++i) {
                        MonoReflectionMethodBuilder* mb;
                        mb = mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
-                       mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_METHODDEF, mb->cattrs);
+                       mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs);
                        params_add_cattrs (assembly, mb->pinfo);
                }
        }
@@ -2807,7 +2978,7 @@ static void
 module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *mb) {
        int i;
        
-       mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_MODULE, mb->cattrs);
+       mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_MODULE, mb->cattrs);
        
        /* no types in the module */
        if (!mb->types)
@@ -2893,9 +3064,9 @@ mono_image_fill_export_table_from_class (MonoDomain *domain, MonoClass *klass,
        values [MONO_EXP_TYPE_FLAGS] = klass->flags;
        values [MONO_EXP_TYPE_TYPEDEF] = klass->type_token;
        if (klass->nested_in)
-               values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << IMPLEMENTATION_BITS) + IMPLEMENTATION_EXP_TYPE;
+               values [MONO_EXP_TYPE_IMPLEMENTATION] = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
        else
-               values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << IMPLEMENTATION_BITS) + IMPLEMENTATION_FILE;
+               values [MONO_EXP_TYPE_IMPLEMENTATION] = (module_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_FILE;
        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);
 
@@ -3003,6 +3174,30 @@ compare_nested (const void *a, const void *b)
        return a_values [MONO_NESTED_CLASS_NESTED] - b_values [MONO_NESTED_CLASS_NESTED];
 }
 
+static int
+compare_genericparam (const void *a, const void *b)
+{
+       const GenericParamTableEntry **a_entry = (const GenericParamTableEntry **) a;
+       const GenericParamTableEntry **b_entry = (const GenericParamTableEntry **) b;
+
+       return (*a_entry)->owner - (*b_entry)->owner;
+}
+
+static void
+pad_heap (MonoDynamicStream *sh)
+{
+       if (sh->index & 3) {
+               int sz = 4 - (sh->index & 3);
+               memset (sh->data + sh->index, 0, sz);
+               sh->index += sz;
+       }
+}
+
+static struct StreamDesc {
+       const char *name;
+       MonoDynamicStream *stream;
+} stream_desc [5];
+
 /*
  * build_compressed_metadata() fills in the blob of data that represents the 
  * raw metadata as it will be saved in the PE file. The five streams are output 
@@ -3026,10 +3221,11 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        MonoImage *meta;
        unsigned char *p;
 
-       struct StreamDesc {
-               const char *name;
-               MonoDynamicStream *stream;
-       } stream_desc [5];
+       qsort (assembly->gen_params->pdata, assembly->gen_params->len, sizeof (gpointer), compare_genericparam);
+       for (i = 0; i < assembly->gen_params->len; i++){
+               GenericParamTableEntry *entry = g_ptr_array_index (assembly->gen_params, i);
+               write_generic_param_entry (assembly, entry);
+       }
 
        stream_desc[0].name  = "#~"; stream_desc[0].stream = &assembly->tstream;
        stream_desc[1].name  = "#Strings"; stream_desc[1].stream = &assembly->sheap;
@@ -3043,12 +3239,18 @@ build_compressed_metadata (MonoDynamicImage *assembly)
                | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
                | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
                | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
-               | ((guint64)1 << MONO_TABLE_DECLSECURITY);
+               | ((guint64)1 << MONO_TABLE_DECLSECURITY) | ((guint64)1 << MONO_TABLE_GENERICPARAM);
        
        /* Compute table sizes */
        /* the MonoImage has already been created in mono_image_basic_init() */
        meta = &assembly->image;
-       
+
+       /* sizes should be multiple of 4 */
+       pad_heap (&assembly->blob);
+       pad_heap (&assembly->guid);
+       pad_heap (&assembly->sheap);
+       pad_heap (&assembly->us);
+
        /* Setup the info used by compute_sizes () */
        meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
        meta->idx_guid_wide = assembly->guid.index >= 65536 ? 1 : 0;
@@ -3073,6 +3275,9 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        }
        heapt_size += 24; /* #~ header size */
        heapt_size += ntables * 4;
+       /* make multiple of 4 */
+       heapt_size += 3;
+       heapt_size &= ~3;
        meta_size += heapt_size;
        meta->raw_metadata = g_malloc0 (meta_size);
        p = meta->raw_metadata;
@@ -3122,8 +3327,17 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        int32val = (guint32*)p;
        *int32val = GUINT32_TO_LE (0); /* reserved */
        p += 4;
-       *p++ = 1; /* version */
-       *p++ = 0;
+
+       if ((assembly->tables [MONO_TABLE_GENERICPARAM].rows > 0) ||
+           (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) ||
+           (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) {
+               *p++ = 1; /* version */
+               *p++ = 1;
+       } else {
+               *p++ = 1; /* version */
+               *p++ = 0;
+       }
+
        if (meta->idx_string_wide)
                *p |= 0x01;
        if (meta->idx_guid_wide)
@@ -3158,6 +3372,7 @@ build_compressed_metadata (MonoDynamicImage *assembly)
        if (table->rows)
                qsort (table->values + MONO_NESTED_CLASS_SIZE, table->rows, sizeof (guint32) * MONO_NESTED_CLASS_SIZE, compare_nested);
 
+
        /* compress the tables */
        for (i = 0; i < 64; i++){
                int row, col;
@@ -3272,7 +3487,9 @@ fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicImage *asse
                                continue;
                        } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
                                MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
-                               g_assert (f->generic_type);
+                               g_assert (f->generic_info);
+                               continue;
+                       } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
                                continue;
                        } else {
                                g_assert_not_reached ();
@@ -3316,8 +3533,8 @@ fixup_cattrs (MonoDynamicImage *assembly)
                values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
 
                type = values [MONO_CUSTOM_ATTR_TYPE];
-               if ((type & CUSTOM_ATTR_TYPE_MASK) == CUSTOM_ATTR_TYPE_METHODDEF) {
-                       idx = type >> CUSTOM_ATTR_TYPE_BITS;
+               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));
                        g_assert (ctor);
@@ -3325,7 +3542,7 @@ fixup_cattrs (MonoDynamicImage *assembly)
                        if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
                                MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
                                idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
-                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << CUSTOM_ATTR_TYPE_BITS) | CUSTOM_ATTR_TYPE_METHODDEF;
+                               values [MONO_CUSTOM_ATTR_TYPE] = (idx << MONO_CUSTOM_ATTR_TYPE_BITS) | MONO_CUSTOM_ATTR_TYPE_METHODDEF;
                        }
                }
        }
@@ -3381,7 +3598,7 @@ assembly_add_resource (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assemb
                g_free (name);
                idx = table->next_idx++;
                rsrc->offset = 0;
-               idx = IMPLEMENTATION_FILE | (idx << IMPLEMENTATION_BITS);
+               idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS);
        } else {
                char sizebuf [4];
                offset = mono_array_length (rsrc->data);
@@ -3531,7 +3748,7 @@ mono_image_emit_manifest (MonoReflectionModuleBuilder *moduleb)
                                int len = mono_array_length (file_module->resources);
                                for (j = 0; j < len; ++j) {
                                        MonoReflectionResource* res = (MonoReflectionResource*)mono_array_addr (file_module->resources, MonoReflectionResource, j);
-                                       assembly_add_resource_manifest (file_module, assembly, res, IMPLEMENTATION_FILE | (module_index << IMPLEMENTATION_BITS));
+                                       assembly_add_resource_manifest (file_module, assembly, res, MONO_IMPLEMENTATION_FILE | (module_index << MONO_IMPLEMENTATION_BITS));
                                }
                        }
                }
@@ -3634,7 +3851,7 @@ mono_image_build_metadata (MonoReflectionModuleBuilder *moduleb)
         * table->rows is already set above and in mono_image_fill_module_table.
         */
        /* add all the custom attributes at the end, once all the indexes are stable */
-       mono_image_add_cattrs (assembly, 1, CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
+       mono_image_add_cattrs (assembly, 1, MONO_CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
 
        module_add_cattrs (assembly, moduleb);
 
@@ -3691,6 +3908,78 @@ mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
        return MONO_TOKEN_STRING | idx;
 }
 
+guint32
+mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj,
+                               MonoArray *opt_param_types)
+{
+       MonoClass *klass;
+       guint32 token = 0;
+
+       klass = obj->vtable->klass;
+       if (strcmp (klass->name, "MonoMethod") == 0) {
+               MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
+               MonoMethodSignature *sig, *old;
+               guint32 sig_token, parent;
+               int nargs, i;
+
+               g_assert (opt_param_types && (method->signature->sentinelpos >= 0));
+
+               nargs = mono_array_length (opt_param_types);
+               old = method->signature;
+               sig = mono_metadata_signature_alloc (
+                       &assembly->image, old->param_count + nargs);
+
+               sig->hasthis = old->hasthis;
+               sig->explicit_this = old->explicit_this;
+               sig->call_convention = old->call_convention;
+               sig->generic_param_count = old->generic_param_count;
+               sig->param_count = old->param_count + nargs;
+               sig->sentinelpos = old->param_count;
+               sig->ret = old->ret;
+
+               for (i = 0; i < old->param_count; i++)
+                       sig->params [i] = old->params [i];
+
+               for (i = 0; i < nargs; i++) {
+                       MonoReflectionType *rt = mono_array_get (
+                               opt_param_types, MonoReflectionType *, i);
+                       sig->params [old->param_count + i] = rt->type;
+               }
+
+               parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
+               g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
+               parent >>= MONO_TYPEDEFORREF_BITS;
+
+               parent <<= MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_TYPEREF;
+
+               sig_token = method_encode_signature (assembly, sig);
+               token = mono_image_get_varargs_method_token (
+                       assembly, parent, method->name, sig_token);
+       } else if (strcmp (klass->name, "MethodBuilder") == 0) {
+               MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
+               ReflectionMethodBuilder rmb;
+               guint32 parent, sig;
+       
+               reflection_methodbuilder_from_method_builder (&rmb, mb);
+               rmb.opt_types = opt_param_types;
+
+               sig = method_builder_encode_signature (assembly, &rmb);
+
+               parent = mono_image_create_token (assembly, obj, TRUE);
+               g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);
+
+               parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
+               parent |= MONO_MEMBERREF_PARENT_METHODDEF;
+
+               token = mono_image_get_varargs_method_token (
+                       assembly, parent, mono_string_to_utf8 (rmb.name), sig);
+       } else
+               g_error ("requested method token for %s\n", klass->name);
+
+       return token;
+}
+
 /*
  * mono_image_create_token:
  * @assembly: a dynamic assembly
@@ -3708,7 +3997,8 @@ mono_image_insert_string (MonoReflectionModuleBuilder *module, MonoString *str)
  *     TypeBuilder
  */
 guint32
-mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
+mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj,
+                        gboolean create_methodspec)
 {
        MonoClass *klass;
        guint32 token = 0;
@@ -3746,7 +4036,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
                token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
        }
        else if (strcmp (klass->name, "MonoType") == 0 ||
-                strcmp (klass->name, "MonoGenericParam") == 0) {
+                strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
                MonoReflectionType *tb = (MonoReflectionType *)obj;
                token = mono_metadata_token_from_dor (
                        mono_image_typedef_or_ref (assembly, tb->type));
@@ -3759,27 +4049,40 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj)
        else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                        strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
-               if (m->method->signature->gen_method) {
-                       token = mono_image_get_methodspec_token (assembly, m->method);
+               if (m->method->signature->is_inflated) {
+                       if (create_methodspec)
+                               token = mono_image_get_methodspec_token (
+                                       assembly, m->method);
+                       else
+                               token = mono_image_get_inflated_method_token (
+                                       assembly, m->method);
                } else if (m->method->signature->generic_param_count) {
                        g_assert_not_reached ();
                } else if ((m->method->klass->image == &assembly->image) &&
                         !m->method->klass->generic_inst) {
                        static guint32 method_table_idx = 0xffffff;
-                       /*
-                        * Each token should have a unique index, but the indexes are
-                        * assigned by managed code, so we don't know about them. An
-                        * easy solution is to count backwards...
-                        */
-                       method_table_idx --;
-                       token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+                       if (m->method->klass->wastypebuilder) {
+                               /* we use the same token as the one that was assigned
+                                * to the Methodbuilder.
+                                * FIXME: do the equivalent for Fields.
+                                */
+                               token = m->method->token;
+                       } else {
+                               /*
+                                * Each token should have a unique index, but the indexes are
+                                * assigned by managed code, so we don't know about them. An
+                                * easy solution is to count backwards...
+                                */
+                               method_table_idx --;
+                               token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+                       }
                } else
                        token = mono_image_get_methodref_token (assembly, m->method);
                /*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
        }
        else if (strcmp (klass->name, "MonoField") == 0) {
                MonoReflectionField *f = (MonoReflectionField *)obj;
-               if ((f->klass->image == &assembly->image) && !f->field->generic_type) {
+               if ((f->klass->image == &assembly->image) && !f->field->generic_info) {
                        static guint32 field_table_idx = 0xffffff;
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
@@ -3827,12 +4130,7 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly,
        MonoDynamicImage *image;
        int i;
 
-       /*
-        * We need to use the current ms version or the ms runtime it won't find
-        * the support dlls. D'oh!
-        * const char *version = "mono-" VERSION;
-        */
-       const char *version = "v1.0.3705";
+       const char *version = mono_get_runtime_version ();
 
 #if HAVE_BOEHM_GC
        image = GC_MALLOC (sizeof (MonoDynamicImage));
@@ -3858,8 +4156,10 @@ create_dynamic_mono_image (MonoDynamicAssembly *assembly,
        image->method_aux_hash = mono_g_hash_table_new (NULL, NULL);
        image->handleref = g_hash_table_new (NULL, NULL);
        image->tokens = mono_g_hash_table_new (NULL, NULL);
+       image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
        image->blob_cache = mono_g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
+       image->gen_params = g_ptr_array_new ();
 
        string_heap_init (&image->sheap);
        mono_image_add_stream_data (&image->us, "", 1);
@@ -4342,23 +4642,25 @@ mono_image_create_pefile (MonoReflectionModuleBuilder *mb) {
        size &= ~(VIRT_ALIGN - 1);
        header->nt.pe_image_size = GUINT32_FROM_LE (size);
 
-       //
+       /*
        // Translate the PEFileKind value to the value expected by the Windows loader
-       //
+       */
        {
-               short kind = assemblyb->pekind;
+               short kind;
 
-               //
+               /*
+               // PEFileKinds.Dll == 1
                // PEFileKinds.ConsoleApplication == 2
                // PEFileKinds.WindowApplication == 3
                //
                // need to get:
                //     IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
                 //     IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
-               if (kind == 2)
-                       kind = 3;
-               else if (kind == 3)
+               */
+               if (assemblyb->pekind == 3)
                        kind = 2;
+               else
+                       kind = 3;
                
                header->nt.pe_subsys_required = GUINT16_FROM_LE (kind);
        }    
@@ -4630,7 +4932,7 @@ mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
                 * we don't know which module it belongs to, since that is only 
                 * determined at assembly save time.
                 */
-               //image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image;
+               /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
                image = create_dynamic_mono_image (ab->dynamic_assembly, mono_string_to_utf8 (ab->name), mono_string_to_utf8 (moduleb->module.fqname));
 
                moduleb->module.image = &image->image;
@@ -4713,7 +5015,7 @@ mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_ind
        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
+       /* Check whenever the row has a corresponding row in the moduleref table */
        table = &image->tables [MONO_TABLE_MODULEREF];
        for (i = 0; i < table->rows; ++i) {
                name_idx = mono_metadata_decode_row_col (table, i, MONO_MODULEREF_NAME);
@@ -4827,6 +5129,8 @@ mono_generic_inst_get_object (MonoDomain *domain, MonoType *geninst)
        ginst = geninst->data.generic_inst;
        gklass = mono_class_from_mono_type (ginst->generic_type);
 
+       mono_class_init (ginst->klass);
+
        res = (MonoReflectionGenericInst *) mono_object_new (domain, System_Reflection_MonoGenericInst);
 
        res->type.type = geninst;
@@ -4859,14 +5163,14 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
                mono_domain_unlock (domain);
                return res;
        }
-       if (type->type == MONO_TYPE_GENERICINST) {
+       if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_inst->is_dynamic) {
                res = (MonoReflectionType *)mono_generic_inst_get_object (domain, type);
                mono_g_hash_table_insert (domain->type_hash, type, res);
                mono_domain_unlock (domain);
                return res;
        }
        if (klass->reflection_info && !klass->wastypebuilder) {
-               //g_assert_not_reached ();
+               /* g_assert_not_reached (); */
                /* should this be considered an error condition? */
                if (!type->byref) {
                        mono_domain_unlock (domain);
@@ -4939,7 +5243,10 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        res->klass = klass;
        res->field = field;
        res->name = mono_string_new (domain, field->name);
-       res->attrs = field->type->attrs;
+       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);
        CACHE_OBJECT (field, res, klass);
        return res;
@@ -5052,7 +5359,8 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        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 == '@'))
                p++;
        found_sep = 0;
@@ -5065,7 +5373,7 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
        if (!found_sep)
                return 1;
        while (*p) {
-               if (*p == 'V' && strncmp (p, "Version=", 8) == 0) {
+               if (*p == 'V' && g_ascii_strncasecmp (p, "Version=", 8) == 0) {
                        p += 8;
                        assembly->major = strtoul (p, &s, 10);
                        if (s == p || *s != '.')
@@ -5082,9 +5390,10 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
                        assembly->revision = strtoul (p, &s, 10);
                        if (s == p)
                                return 1;
-               } else if (*p == 'C' && strncmp (p, "Culture=", 8) == 0) {
+                       p = s;
+               } else if (*p == 'C' && g_ascii_strncasecmp (p, "Culture=", 8) == 0) {
                        p += 8;
-                       if (strncmp (p, "neutral", 7) == 0) {
+                       if (g_ascii_strncasecmp (p, "neutral", 7) == 0) {
                                assembly->culture = "";
                                p += 7;
                        } else {
@@ -5093,26 +5402,21 @@ assembly_name_to_aname (MonoAssemblyName *assembly, char *p) {
                                        p++;
                                }
                        }
-               } else if (*p == 'P' && strncmp (p, "PublicKeyToken=", 15) == 0) {
+               } else if (*p == 'P' && g_ascii_strncasecmp (p, "PublicKeyToken=", 15) == 0) {
                        p += 15;
-                       s = p;
-                       while (*s && isxdigit (*s)) {
-                               *s = tolower (*s);
-                               s++;
-                       }
-                       assembly->hash_len = s - p;
-                       if (!(s-p) || ((s-p) & 1))
-                               return 1;
-                       assembly->hash_value = s = p;
-                       while (*s && isxdigit (*s)) {
-                               int val;
-                               val = *s >= '0' && *s <= '9'? *s - '0': *s - 'a' + 10;
-                               s++;
-                               *p = val << 4;
-                               *p |= *s >= '0' && *s <= '9'? *s - '0': *s - 'a' + 10;
-                               p++;
+                       if (strncmp (p, "null", 4) == 0) {
+                               p += 4;
+                       } else {
+                               int len;
+                               gchar *start = p;
+                               while (*p && *p != ',') {
+                                       p++;
+                               }
+                               len = (p - start + 1);
+                               if (len > MONO_PUBLIC_KEY_TOKEN_LENGTH)
+                                       len = MONO_PUBLIC_KEY_TOKEN_LENGTH;
+                               g_strlcpy (assembly->public_key_token, start, len);
                        }
-                       p = s;
                } else {
                        while (*p && *p != ',')
                                p++;
@@ -5343,7 +5647,7 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
        if (!mono_domain_has_type_resolve (mono_domain_get ()))
                return NULL;
        
-       // Reconstruct the type name
+       /* Reconstruct the type name */
        fullName = g_string_new ("");
        if (info->name_space && (info->name_space [0] != '\0'))
                g_string_printf (fullName, "%s.%s", info->name_space, info->name);
@@ -5355,9 +5659,36 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
        assembly = 
                mono_domain_try_type_resolve (
                        mono_domain_get (), fullName->str, NULL);
-       if (assembly && (!image || (assembly->assembly->image == image)))
-               type = mono_reflection_get_type_internal (assembly->assembly->image, 
-                                                                                info, ignorecase);
+       if (assembly && (!image || (assembly->assembly->image == image))) {
+
+               if (assembly->assembly->dynamic) {
+                       /* Enumerate all modules */
+                       MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
+                       int i;
+
+                       type = NULL;
+                       if (abuilder->modules) {
+                               for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
+                                       MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
+                                       type = mono_reflection_get_type_internal (&mb->dynamic_image->image, info, ignorecase);
+                                       if (type)
+                                               break;
+                               }
+                       }
+
+                       if (!type && abuilder->loaded_modules) {
+                               for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
+                                       MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
+                                       type = mono_reflection_get_type_internal (mod->image, info, ignorecase);
+                                       if (type)
+                                               break;
+                               }
+                       }
+               }
+               else
+                       type = mono_reflection_get_type_internal (assembly->assembly->image, 
+                                                                                                         info, ignorecase);
+       }
        g_string_free (fullName, TRUE);
        return type;
 }
@@ -5378,9 +5709,14 @@ mono_reflection_type_from_name (char *name, MonoImage *image)
        MonoType *type;
        MonoTypeNameParse info;
        MonoAssembly *assembly;
+       char *tmp;
+
+       /* Make a copy since parse_type modifies its argument */
+       tmp = g_strdup (name);
        
        /*g_print ("requested type %s\n", str);*/
-       if (!mono_reflection_parse_type (name, &info)) {
+       if (!mono_reflection_parse_type (tmp, &info)) {
+               g_free (tmp);
                g_list_free (info.modifiers);
                g_list_free (info.nested);
                return NULL;
@@ -5388,14 +5724,17 @@ mono_reflection_type_from_name (char *name, MonoImage *image)
 
        if (info.assembly.name) {
                assembly = mono_assembly_loaded (&info.assembly);
-               /* do we need to load if it's not already loaded? */
                if (!assembly) {
-                       g_list_free (info.modifiers);
-                       g_list_free (info.nested);
-                       return NULL;
+                       /* then we must load the assembly ourselve - see #60439 */
+                       assembly = mono_assembly_load (&info.assembly, NULL, NULL);
+                       if (!assembly) {
+                               g_free (tmp);
+                               g_list_free (info.modifiers);
+                               g_list_free (info.nested);
+                               return NULL;
+                       }
                }
-               else
-                       image = assembly->image;
+               image = assembly->image;
        } else if (image == NULL) {
                image = mono_defaults.corlib;
        }
@@ -5405,7 +5744,8 @@ mono_reflection_type_from_name (char *name, MonoImage *image)
                image = mono_defaults.corlib;
                type = mono_reflection_get_type (image, &info, FALSE);
        }
-       
+
+       g_free (tmp);
        g_list_free (info.modifiers);
        g_list_free (info.nested);
        return type;
@@ -5584,6 +5924,7 @@ handle_type:
                                }
                                break;
                        case MONO_TYPE_CLASS:
+                       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);
@@ -5746,11 +6087,11 @@ create_custom_attr (MonoImage *image, MonoMethod *method,
                        type_name [type_len] = 0;
                        named += type_len;
                        /* FIXME: lookup the type and check type consistency */
+               } 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); */
+                       named++;
                }
-               else
-                       if (data_type == MONO_TYPE_SZARRAY)
-                               /* The spec does not mention this */
-                               named ++;
                name_len = mono_metadata_decode_blob_size (named, &named);
                name = g_malloc (name_len + 1);
                memcpy (name, named, name_len);
@@ -5759,9 +6100,9 @@ create_custom_attr (MonoImage *image, MonoMethod *method,
                if (named_type == 0x53) {
                        MonoClassField *field = mono_class_get_field_from_name (mono_object_class (attr), name);
                        void *val = load_cattr_value (image, field->type, named, &named);
-                               mono_field_set_value (attr, field, val);
-                               if (!type_is_reference (field->type))
-                                       g_free (val);
+                       mono_field_set_value (attr, field, val);
+                       if (!type_is_reference (field->type))
+                               g_free (val);
                } else if (named_type == 0x54) {
                        MonoProperty *prop;
                        void *pparams [1];
@@ -5828,12 +6169,12 @@ mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
        ainfo->image = image;
        for (i = 0, tmp = list; i < len; ++i, tmp = tmp->next) {
                mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
-               mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
-               switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
-               case CUSTOM_ATTR_TYPE_METHODDEF:
+               mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
+               switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
+               case MONO_CUSTOM_ATTR_TYPE_METHODDEF:
                        mtoken |= MONO_TOKEN_METHOD_DEF;
                        break;
-               case CUSTOM_ATTR_TYPE_MEMBERREF:
+               case MONO_CUSTOM_ATTR_TYPE_MEMBERREF:
                        mtoken |= MONO_TOKEN_MEMBER_REF;
                        break;
                default:
@@ -5861,8 +6202,8 @@ mono_custom_attrs_from_method (MonoMethod *method)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, method)))
                return cinfo;
        idx = find_method_index (method);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_METHODDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_METHODDEF;
        return mono_custom_attrs_from_index (method->klass->image, idx);
 }
 
@@ -5875,8 +6216,8 @@ mono_custom_attrs_from_class (MonoClass *klass)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, klass)))
                return cinfo;
        idx = mono_metadata_token_index (klass->type_token);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_TYPEDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_TYPEDEF;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -5889,8 +6230,8 @@ mono_custom_attrs_from_assembly (MonoAssembly *assembly)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, assembly)))
                return cinfo;
        idx = 1; /* there is only one assembly */
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_ASSEMBLY;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
        return mono_custom_attrs_from_index (assembly->image, idx);
 }
 
@@ -5903,8 +6244,8 @@ mono_custom_attrs_from_module (MonoImage *image)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, image)))
                return cinfo;
        idx = 1; /* there is only one module */
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_MODULE;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_MODULE;
        return mono_custom_attrs_from_index (image, idx);
 }
 
@@ -5917,8 +6258,8 @@ mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, property)))
                return cinfo;
        idx = find_property_index (klass, property);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_PROPERTY;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_PROPERTY;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -5931,8 +6272,8 @@ mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, event)))
                return cinfo;
        idx = find_event_index (klass, event);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_EVENT;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_EVENT;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -5945,8 +6286,8 @@ mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
        if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
                return cinfo;
        idx = find_field_index (klass, field);
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_FIELDDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_FIELDDEF;
        return mono_custom_attrs_from_index (klass->image, idx);
 }
 
@@ -5972,7 +6313,7 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
 
        if (method->klass->generic_inst || method->klass->gen_params ||
            method->signature->generic_param_count) {
-               // FIXME FIXME FIXME
+               /* FIXME FIXME FIXME */
                return NULL;
        }
 
@@ -5995,8 +6336,8 @@ mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
        if (!found)
                return NULL;
        idx = i;
-       idx <<= CUSTOM_ATTR_BITS;
-       idx |= CUSTOM_ATTR_PARAMDEF;
+       idx <<= MONO_CUSTOM_ATTR_BITS;
+       idx |= MONO_CUSTOM_ATTR_PARAMDEF;
        return mono_custom_attrs_from_index (image, idx);
 }
 
@@ -6056,6 +6397,8 @@ mono_reflection_get_custom_attrs (MonoObject *obj)
 
        if (cinfo) {
                result = mono_custom_attrs_construct (cinfo);
+               if (!cinfo->cached)
+                       mono_custom_attrs_free (cinfo);
        } else {
                klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
                result = mono_array_new (mono_domain_get (), klass, 0);
@@ -6146,10 +6489,21 @@ get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
        }
 }
 
+/*
+ * Encode a value in a custom attribute stream of bytes.
+ * The value to encode is either supplied as an object in argument val
+ * (valuetypes are boxed), or as a pointer to the data in the
+ * argument argval.
+ * @type represents the type of the value
+ * @buffer is the start of the buffer
+ * @p the current position in the buffer
+ * @buflen contains the size of the buffer and is used to return the new buffer size
+ * if this needs to be realloced.
+ * @retbuffer and @retp return the start and the position of the buffer
+ */
 static void
-encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg)
+encode_cattr_value (MonoAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg, char *argval)
 {
-       char *argval;
        MonoTypeEnum simple_type;
        
        if ((p-buffer) + 10 >= *buflen) {
@@ -6159,7 +6513,8 @@ encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint3
                p = newbuf + (p-buffer);
                buffer = newbuf;
        }
-       argval = ((char*)arg + sizeof (MonoObject));
+       if (!argval)
+               argval = ((char*)arg + sizeof (MonoObject));
        simple_type = type->type;
 handle_enum:
        switch (simple_type) {
@@ -6248,7 +6603,7 @@ handle_type:
        }
        case MONO_TYPE_SZARRAY: {
                int len, i;
-               MonoClass *eclass;
+               MonoClass *eclass, *arg_eclass;
 
                if (!arg) {
                        *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
@@ -6262,8 +6617,18 @@ handle_type:
                *retp = p;
                *retbuffer = buffer;
                eclass = type->data.klass;
-               for (i = 0; i < len; ++i) {
-                       encode_cattr_value (buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i));
+               arg_eclass = mono_object_class (arg)->element_class;
+               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) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, NULL, elptr);
+                               elptr += elsize;
+                       }
+               } else {
+                       for (i = 0; i < len; ++i) {
+                               encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL);
+                       }
                }
                break;
        }
@@ -6326,7 +6691,7 @@ handle_type:
  * Returns: a Byte array representing the blob of data.
  */
 MonoArray*
-mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
+mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
 {
        MonoArray *result;
        MonoMethodSignature *sig;
@@ -6349,7 +6714,7 @@ mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, Mo
        *p++ = 0;
        for (i = 0; i < sig->param_count; ++i) {
                arg = mono_array_get (ctorArgs, MonoObject*, i);
-               encode_cattr_value (buffer, p, &buffer, &p, &buflen, sig->params [i], arg);
+               encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL);
        }
        i = 0;
        if (properties)
@@ -6410,7 +6775,7 @@ mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, Mo
                        mono_metadata_encode_value (len, p, &p);
                        memcpy (p, pname, len);
                        p += len;
-                       encode_cattr_value (buffer, p, &buffer, &p, &buflen, ptype, (MonoObject*)mono_array_get (propValues, gpointer, i));
+                       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ptype, (MonoObject*)mono_array_get (propValues, gpointer, i), NULL);
                        g_free (pname);
                }
        }
@@ -6447,12 +6812,14 @@ mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, Mo
                                g_free (str);
                        } else {
                                mono_metadata_encode_value (ftype->type, p, &p);
+                               if (ftype->type == MONO_TYPE_SZARRAY)
+                                       mono_metadata_encode_value (ftype->data.klass->this_arg.type, p, &p);
                        }
                        len = strlen (fname);
                        mono_metadata_encode_value (len, p, &p);
                        memcpy (p, fname, len);
                        p += len;
-                       encode_cattr_value (buffer, p, &buffer, &p, &buflen, ftype, (MonoObject*)mono_array_get (fieldValues, gpointer, i));
+                       encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, ftype, (MonoObject*)mono_array_get (fieldValues, gpointer, i), NULL);
                        g_free (fname);
                }
        }
@@ -6483,10 +6850,6 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 
        MONO_ARCH_SAVE_REGS;
 
-       klass = g_new0 (MonoClass, 1);
-
-       klass->image = &tb->module->dynamic_image->image;
-
        if (tb->parent) {
                /* check so we can compile corlib correctly */
                if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
@@ -6497,6 +6860,22 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
        } else
                parent = NULL;
        
+       /* the type has already being created: it means we just have to change the parent */
+       if (tb->type.type) {
+               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);
+               return;
+       }
+       
+       klass = g_new0 (MonoClass, 1);
+
+       klass->image = &tb->module->dynamic_image->image;
+
        klass->inited = 1; /* we lie to the runtime */
        klass->name = mono_string_to_utf8 (tb->name);
        klass->name_space = mono_string_to_utf8 (tb->nspace);
@@ -6741,19 +7120,19 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                                                                 num_clauses);
                }
 
-               if (rmb->generic_params) {
-                       int count = mono_array_length (rmb->generic_params);
-                       header->gen_params = g_new0 (MonoGenericParam, count);
-                       for (i = 0; i < count; i++) {
-                               MonoReflectionGenericParam *gp =
-                                       mono_array_get (rmb->generic_params,
-                                                       MonoReflectionGenericParam*, i);
+               pm->header = header;
+       }
 
-                               header->gen_params [i] = *gp->type.type->data.generic_param;
-                       }
-               }
+       if (rmb->generic_params) {
+               int count = mono_array_length (rmb->generic_params);
+               pm->gen_params = g_new0 (MonoGenericParam, count);
+               for (i = 0; i < count; i++) {
+                       MonoReflectionGenericParam *gp =
+                               mono_array_get (rmb->generic_params,
+                                               MonoReflectionGenericParam*, i);
 
-               pm->header = header;
+                       pm->gen_params [i] = *gp->type.type->data.generic_param;
+               }
        }
 
        if (rmb->refs) {
@@ -6885,59 +7264,25 @@ fieldbuilder_to_mono_class_field (MonoClass *klass, MonoReflectionFieldBuilder*
        if (fb->def_value) {
                MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-               field->def_value = g_new0 (MonoConstant, 1);
-               idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+               idx = encode_constant (assembly, fb->def_value, &field->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;
-               field->def_value->value = g_malloc (len);
-               memcpy (field->def_value->value, p, len);
+               field->data = g_malloc (len);
+               memcpy (field->data, p, len);
        }
 
        return field;
 }
 
 static MonoType*
-bind_nested_generic_parameters (MonoReflectionTypeBuilder *ntype, int type_argc,
-                               MonoType **types, MonoType *geninst)
+do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc,
+                                           MonoType **types)
 {
-       MonoType **ntypes;
-       int ntype_argc, j;
-
-       ntype_argc = ntype->generic_params ? mono_array_length (ntype->generic_params) : 0;
-
-       if (ntype_argc > type_argc) {
-               ntypes = g_new0 (MonoType *, ntype_argc);
-
-               for (j = 0; j < type_argc; j++)
-                       ntypes [j] = types [j];
-
-               for (j = type_argc; j < ntype_argc; j++) {
-                       MonoReflectionGenericParam *ngparam;
-                       MonoType *pt = g_new0 (MonoType, 1);
-
-                       ngparam = mono_array_get (ntype->generic_params, gpointer, j);
-
-                       pt->type = MONO_TYPE_VAR;
-                       pt->data.generic_param = ngparam->type.type->data.generic_param;
-
-                       ntypes [j] = pt;
-               }
-       } else
-               ntypes = types;
-
-       return mono_reflection_bind_generic_parameters ((MonoReflectionType *) ntype, ntype_argc, ntypes, geninst);
-}
-
-MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc,
-                                        MonoType **types, MonoType *nested_in)
-{
-       MonoClass *klass, *pklass = NULL;
+       MonoClass *klass;
        MonoReflectionTypeBuilder *tb = NULL;
-       MonoGenericInst *ginst;
-       MonoReflectionType *parent = NULL;
+       MonoGenericInst *ginst, *cached;
        MonoDomain *domain;
        MonoType *geninst;
        int icount, i;
@@ -6952,7 +7297,6 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
        domain = mono_object_domain (type);
 
        ginst = g_new0 (MonoGenericInst, 1);
-       ginst->is_dynamic = 1;
 
        if (!klass->generic_inst) {
                ginst->type_argc = type_argc;
@@ -6985,37 +7329,39 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
                ginst->generic_type = kginst->generic_type;
        }
 
-       geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
-       if (geninst) {
+       geninst = g_new0 (MonoType, 1);
+       geninst->type = MONO_TYPE_GENERICINST;
+
+       cached = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
+       if (cached) {
                g_free (ginst);
                mono_loader_unlock ();
+               geninst->data.generic_inst = cached;
                return geninst;
        }
 
+       geninst->data.generic_inst = ginst;
+
+       ginst->context = g_new0 (MonoGenericContext, 1);
+       ginst->context->ginst = ginst;
+
        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 {
-               pklass = klass->parent;
-               if (pklass)
-                       parent = mono_type_get_object (domain, &pklass->byval_arg);
-       }
-
-       geninst = g_new0 (MonoType, 1);
-       geninst->type = MONO_TYPE_GENERICINST;
-       geninst->data.generic_inst = ginst;
+               icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
+               ginst->is_dynamic = TRUE;
+       } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericInst")) {
+               MonoReflectionGenericInst *rgi = (MonoReflectionGenericInst *) type;
+               MonoReflectionType *rgt = rgi->generic_type;
 
-       if (pklass && pklass->generic_inst)
-               ginst->parent = mono_reflection_bind_generic_parameters (parent, type_argc, types, NULL);
+               g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder"));
+               tb = (MonoReflectionTypeBuilder *) rgt;
 
-       if (tb)
                icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
-       else
+               ginst->is_dynamic = TRUE;
+       } else
                icount = klass->interface_count;
+
        ginst->ifaces = g_new0 (MonoType *, icount);
        ginst->count_ifaces = icount;
 
@@ -7026,28 +7372,54 @@ mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc
                        itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
                else
                        itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
-               ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types, NULL);
+               ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
                if (!ginst->ifaces [i])
                        ginst->ifaces [i] = itype->type;
        }
 
-       ginst->nested_in = nested_in;
+       mono_class_create_generic (ginst);
+
+       g_hash_table_insert (klass->image->generic_inst_cache, ginst, ginst);
+
+       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 *geninst;
+       MonoReflectionTypeBuilder *tb = NULL;
+       MonoGenericInst *ginst;
+       MonoDomain *domain;
 
-       if (tb) {
-               int ncount = tb->subtypes ? mono_array_length (tb->subtypes) : 0;
-               for (i = 0; i < ncount; i++) {
-                       MonoReflectionTypeBuilder *ntype = mono_array_get (tb->subtypes, gpointer, i);
-                       MonoType *nested = bind_nested_generic_parameters (ntype, type_argc, types, geninst);
+       domain = mono_object_domain (type);
+       klass = mono_class_from_mono_type (type->type);
 
-                       ginst->nested = g_list_prepend (ginst->nested, nested);
+       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 {
+               pklass = klass->parent;
+               if (pklass)
+                       parent = mono_type_get_object (domain, &pklass->byval_arg);
        }
 
-       mono_class_create_generic (ginst);
+       geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types);
+       if (!geninst)
+               return NULL;
 
-       g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
+       ginst = geninst->data.generic_inst;
 
-       mono_loader_unlock ();
+       if (pklass && pklass->generic_inst)
+               ginst->parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
 
        return geninst;
 }
@@ -7058,6 +7430,7 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
        MonoMethod *method, *inflated;
        MonoReflectionMethodBuilder *mb = NULL;
        MonoGenericMethod *gmethod;
+       MonoGenericContext *context;
        int count, i;
 
        MONO_ARCH_SAVE_REGS;
@@ -7078,7 +7451,6 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                return NULL;
 
        gmethod = g_new0 (MonoGenericMethod, 1);
-       gmethod->generic_method = method;
        gmethod->mtype_argc = count;
        gmethod->mtype_argv = g_new0 (MonoType *, count);
        for (i = 0; i < count; i++) {
@@ -7086,9 +7458,13 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                gmethod->mtype_argv [i] = garg->type;
        }
 
-       gmethod->generic_inst = method->klass->generic_inst;
+       gmethod->reflection_info = rmethod;
+
+       context = g_new0 (MonoGenericContext, 1);
+       context->ginst = method->klass->generic_inst;
+       context->gmethod = gmethod;
 
-       inflated = mono_class_inflate_generic_method (method, gmethod, NULL);
+       inflated = mono_class_inflate_generic_method (method, context, NULL);
 
        return mono_method_get_object (
                mono_object_domain (rmethod), inflated, NULL);
@@ -7099,15 +7475,30 @@ inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoOb
 {
        MonoGenericMethod *gmethod;
        MonoGenericInst *ginst;
+       MonoGenericContext *context;
+       int i;
 
        ginst = type->type.type->data.generic_inst;
 
        gmethod = g_new0 (MonoGenericMethod, 1);
-       gmethod->generic_method = method;
        gmethod->reflection_info = obj;
-       gmethod->generic_inst = ginst;
 
-       return mono_class_inflate_generic_method (method, gmethod, ginst->klass);
+       gmethod->mtype_argc = method->signature->generic_param_count;
+       gmethod->mtype_argv = g_new0 (MonoType *, gmethod->mtype_argc);
+
+       for (i = 0; i < gmethod->mtype_argc; i++) {
+               MonoMethodNormal *mn = (MonoMethodNormal *) method;
+               MonoGenericParam *gparam = &mn->gen_params [i];
+
+               g_assert (gparam->pklass);
+               gmethod->mtype_argv [i] = &gparam->pklass->byval_arg;
+       }
+
+       context = g_new0 (MonoGenericContext, 1);
+       context->ginst = ginst;
+       context->gmethod = gmethod;
+
+       return mono_class_inflate_generic_method (method, context, ginst->klass);
 }
 
 static MonoMethod *
@@ -7125,8 +7516,10 @@ inflate_method (MonoReflectionGenericInst *type, MonoObject *obj)
        else if (!strcmp (obj->vtable->klass->name, "MonoMethod") ||
                 !strcmp (obj->vtable->klass->name, "MonoCMethod"))
                method = ((MonoReflectionMethod *) obj)->method;
-       else
+       else {
+               method = NULL; /* prevent compiler warning */
                g_assert_not_reached ();
+       }
 
        return inflate_mono_method (type, method, obj);
 }
@@ -7134,7 +7527,8 @@ inflate_method (MonoReflectionGenericInst *type, MonoObject *obj)
 void
 mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                                         MonoArray *methods, MonoArray *ctors,
-                                        MonoArray *fields, MonoArray *properties)
+                                        MonoArray *fields, MonoArray *properties,
+                                        MonoArray *events)
 {
        MonoGenericInst *ginst;
        MonoDynamicGenericInst *dginst;
@@ -7165,11 +7559,13 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
        dginst->count_ctors = ctors ? mono_array_length (ctors) : 0;
        dginst->count_fields = fields ? mono_array_length (fields) : 0;
        dginst->count_properties = properties ? mono_array_length (properties) : 0;
+       dginst->count_events = events ? mono_array_length (events) : 0;
 
        dginst->methods = g_new0 (MonoMethod *, dginst->count_methods);
        dginst->ctors = g_new0 (MonoMethod *, dginst->count_ctors);
        dginst->fields = g_new0 (MonoClassField, dginst->count_fields);
        dginst->properties = g_new0 (MonoProperty, dginst->count_properties);
+       dginst->events = g_new0 (MonoEvent, dginst->count_events);
 
        for (i = 0; i < dginst->count_methods; i++) {
                MonoObject *obj = mono_array_get (methods, gpointer, i);
@@ -7186,17 +7582,24 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
        for (i = 0; i < dginst->count_fields; i++) {
                MonoObject *obj = mono_array_get (fields, gpointer, i);
                MonoClassField *field;
+               MonoInflatedField *ifield;
 
                if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
                        field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
                else if (!strcmp (obj->vtable->klass->name, "MonoField"))
                        field = ((MonoReflectionField *) obj)->field;
-               else
+               else {
+                       field = NULL; /* prevent compiler warning */
                        g_assert_not_reached ();
+               }
+
+               ifield = g_new0 (MonoInflatedField, 1);
+               ifield->generic_type = field->type;
+               ifield->reflection_info = obj;
 
                dginst->fields [i] = *field;
-               dginst->fields [i].generic_type = field->type;
-               dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst, NULL);
+               dginst->fields [i].generic_info = ifield;
+               dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context);
        }
 
        for (i = 0; i < dginst->count_properties; i++) {
@@ -7224,6 +7627,31 @@ mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
                        g_assert_not_reached ();
        }
 
+       for (i = 0; i < dginst->count_events; i++) {
+               MonoObject *obj = mono_array_get (events, gpointer, i);
+               MonoEvent *event = &dginst->events [i];
+
+               if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
+                       MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
+
+                       event->parent = klass;
+                       event->attrs = eb->attrs;
+                       event->name = mono_string_to_utf8 (eb->name);
+                       if (eb->add_method)
+                               event->add = inflate_method (type, (MonoObject *) eb->add_method);
+                       if (eb->remove_method)
+                               event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
+               } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
+                       *event = *((MonoReflectionEvent *) obj)->event;
+
+                       if (event->add)
+                               event->add = inflate_mono_method (type, event->add, NULL);
+                       if (event->remove)
+                               event->remove = inflate_mono_method (type, event->remove, NULL);
+               } else
+                       g_assert_not_reached ();
+       }
+
        ginst->initialized = TRUE;
 }
 
@@ -7341,14 +7769,13 @@ typebuilder_setup_fields (MonoClass *klass)
                if (fb->def_value) {
                        MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
                        field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-                       field->def_value = g_new0 (MonoConstant, 1);
-                       idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+                       idx = encode_constant (assembly, fb->def_value, &field->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;
-                       field->def_value->value = g_malloc (len);
-                       memcpy (field->def_value->value, p, len);
+                       field->data = g_malloc (len);
+                       memcpy (field->data, p, len);
                }
        }
        mono_class_layout_fields (klass);
@@ -7378,6 +7805,38 @@ typebuilder_setup_properties (MonoClass *klass)
        }
 }
 
+MonoReflectionEvent *
+mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+       MonoEvent *event = g_new0 (MonoEvent, 1);
+       MonoClass *klass;
+       int j;
+
+       klass = my_mono_class_from_mono_type (tb->type.type);
+
+       event->parent = klass;
+       event->attrs = eb->attrs;
+       event->name = mono_string_to_utf8 (eb->name);
+       if (eb->add_method)
+               event->add = eb->add_method->mhandle;
+       if (eb->remove_method)
+               event->remove = eb->remove_method->mhandle;
+       if (eb->raise_method)
+               event->raise = eb->raise_method->mhandle;
+
+       if (eb->other_methods) {
+               event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods));
+               for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
+                       MonoReflectionMethodBuilder *mb = 
+                               mono_array_get (eb->other_methods,
+                                               MonoReflectionMethodBuilder*, j);
+                       event->other [j] = mb->mhandle;
+               }
+       }
+
+       return mono_event_get_object (mono_object_domain (tb), klass, event);
+}
+
 static void
 typebuilder_setup_events (MonoClass *klass)
 {
@@ -7467,74 +7926,29 @@ mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
        return res;
 }
 
-MonoReflectionGenericParam *
-mono_reflection_define_generic_parameter (MonoReflectionTypeBuilder *tb, MonoReflectionMethodBuilder *mb, MonoString *name, guint32 index)
-{
-       static MonoClass *System_Reflection_MonoGenericParam;
-       MonoImage *image;
-       MonoGenericParam *param;
-       MonoReflectionGenericParam *res;
-       MonoDomain *domain;
-
-       if (!System_Reflection_MonoGenericParam) {
-               System_Reflection_MonoGenericParam = mono_class_from_name (
-                       mono_defaults.corlib, "System.Reflection", "MonoGenericParam");
-               g_assert (System_Reflection_MonoGenericParam);
-       }
-
-       param = g_new0 (MonoGenericParam, 1);
-
-       if (mb)
-               tb = (MonoReflectionTypeBuilder *) mb->type;
-
-       domain = mono_object_domain (tb);
-       image = (MonoImage*)tb->module->dynamic_image;
-
-       param->method = NULL;
-       param->name = mono_string_to_utf8 (name);
-       param->num = index;
-
-       res = (MonoReflectionGenericParam *)mono_object_new (domain, System_Reflection_MonoGenericParam);
-       res->type.type = g_new0 (MonoType, 1);
-       res->type.type->type = mb ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
-       res->type.type->data.generic_param = param;
-
-       res->refobj = mb ? (MonoObject *) mb : (MonoObject *) tb;
-       res->index = index;
-       res->name = name;
-
-       return res;
-}
-
 void
 mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
 {
        MonoGenericParam *param;
-       MonoReflectionMethodBuilder *mb = NULL;
-       MonoReflectionTypeBuilder *tb;
        MonoImage *image;
-       int count, i;
 
-       param = gparam->type.type->data.generic_param;
-       count = gparam->constraints ? mono_array_length (gparam->constraints) : 0;
-       param->constraints = g_new0 (MonoClass *, count + 1);
-       for (i = 0; i < count; i++) {
-               MonoReflectionType *constraint = mono_array_get (gparam->constraints, MonoReflectionType *, i);
+       MONO_ARCH_SAVE_REGS;
 
-               param->constraints [i] = mono_class_from_mono_type (constraint->type);
-       }
+       param = g_new0 (MonoGenericParam, 1);
 
-       if (!strcmp (gparam->refobj->vtable->klass->name, "MethodBuilder")) {
-               mb = (MonoReflectionMethodBuilder *) gparam->refobj;
-               tb = (MonoReflectionTypeBuilder *) mb->type;
-       } else
-               tb = (MonoReflectionTypeBuilder *) gparam->refobj;
+       param->method = NULL;
+       param->name = mono_string_to_utf8 (gparam->name);
+       param->num = gparam->index;
 
-       image = (MonoImage*)tb->module->dynamic_image;
+       image = &gparam->tbuilder->module->dynamic_image->image;
+       mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
 
-       param->pklass = mono_class_from_generic_parameter (param, image, mb != NULL);
+       param->pklass->reflection_info = gparam;
 
-       gparam->initialized = TRUE;
+       gparam->type.type = g_new0 (MonoType, 1);
+       gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
+       gparam->type.type->attrs = TYPE_ATTRIBUTE_PUBLIC;
+       gparam->type.type->data.generic_param = param;
 }
 
 MonoArray *