Sat Jan 8 19:03:26 CET 2005 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / metadata / class.c
index 636cd6ae38e9c18caf32ed8685a25eeae90cc602..361f4745a5a202d35722855b3f0868c33d5e4077 100644 (file)
@@ -32,6 +32,7 @@
 #include <mono/metadata/mono-endian.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/reflection.h>
+#include <mono/metadata/mono-debug-debugger.h>
 #include <mono/os/gc_wrapper.h>
 
 MonoStats mono_stats;
@@ -40,6 +41,7 @@ gboolean mono_print_vtable = FALSE;
 
 static MonoClass * mono_class_create_from_typedef (MonoImage *image, guint32 type_token);
 
+void (*mono_debugger_start_class_init_func) (MonoClass *klass) = NULL;
 void (*mono_debugger_class_init_func) (MonoClass *klass) = NULL;
 
 MonoClass *
@@ -57,16 +59,16 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token)
        name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
        nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
        
-       idx = cols [MONO_TYPEREF_SCOPE] >> RESOLTION_SCOPE_BITS;
-       switch (cols [MONO_TYPEREF_SCOPE] & RESOLTION_SCOPE_MASK) {
-       case RESOLTION_SCOPE_MODULE:
+       idx = cols [MONO_TYPEREF_SCOPE] >> MONO_RESOLTION_SCOPE_BITS;
+       switch (cols [MONO_TYPEREF_SCOPE] & MONO_RESOLTION_SCOPE_MASK) {
+       case MONO_RESOLTION_SCOPE_MODULE:
                if (!idx)
                        g_error ("null ResolutionScope not yet handled");
                /* a typedef in disguise */
                return mono_class_from_name (image, nspace, name);
-       case RESOLTION_SCOPE_MODULEREF:
+       case MONO_RESOLTION_SCOPE_MODULEREF:
                return mono_class_from_name (image->modules [idx - 1], nspace, name);
-       case RESOLTION_SCOPE_TYPEREF: {
+       case MONO_RESOLTION_SCOPE_TYPEREF: {
                MonoClass *enclosing = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | idx);
                GList *tmp;
                mono_class_init (enclosing);
@@ -78,30 +80,16 @@ mono_class_from_typeref (MonoImage *image, guint32 type_token)
                g_warning ("TypeRef ResolutionScope not yet handled (%d)", idx);
                return NULL;
        }
-       case RESOLTION_SCOPE_ASSEMBLYREF:
+       case MONO_RESOLTION_SCOPE_ASSEMBLYREF:
                break;
        }
 
        references = image->references;
-       if (!references ||  !references [idx-1]) {
-               /* 
-                * detected a reference to mscorlib, we simply return a reference to a dummy 
-                * until we have a better solution.
-                * 
-                * once a better solution is in place, the System.MonoDummy
-                * class should be removed from CVS.
-                */
-               fprintf(stderr, "Sending dummy where %s.%s expected\n", mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]), mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME])); 
-               
-               res = mono_class_from_name (image, "System", "MonoDummy");
-               /* prevent method loading */
-               res->dummy = 1;
-               /* some storage if the type is used  - very ugly hack */
-               res->instance_size = 2*sizeof (gpointer);
-               return res;
-       }       
-
-       /* load referenced assembly */
+       if (!references [idx-1])
+               mono_assembly_load_reference (image, idx - 1);
+       if (references [idx - 1] == (gpointer)-1)
+               return NULL;
+
        image = references [idx-1]->image;
 
        return mono_class_from_name (image, nspace, name);
@@ -113,12 +101,14 @@ dup_type (MonoType* t, const MonoType *original)
        MonoType *r = g_new0 (MonoType, 1);
        *r = *t;
        r->attrs = original->attrs;
+       r->byref = original->byref;
        mono_stats.generics_metadata_size += sizeof (MonoType);
        return r;
 }
 
 static void
-mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed)
+mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed,
+                           gboolean include_ns, gboolean include_arity)
 {
        MonoClass *klass;
        
@@ -126,7 +116,9 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed)
        case MONO_TYPE_ARRAY: {
                int i, rank = type->data.array->rank;
 
-               mono_type_get_name_recurse (&type->data.array->eklass->byval_arg, str, FALSE);
+               mono_type_get_name_recurse (
+                       &type->data.array->eklass->byval_arg, str,
+                       FALSE, include_ns, include_arity);
                g_string_append_c (str, '[');
                for (i = 1; i < rank; i++)
                        g_string_append_c (str, ',');
@@ -134,45 +126,54 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed)
                break;
        }
        case MONO_TYPE_SZARRAY:
-               mono_type_get_name_recurse (&type->data.klass->byval_arg, str, FALSE);
+               mono_type_get_name_recurse (
+                       &type->data.klass->byval_arg, str, FALSE, include_ns, include_arity);
                g_string_append (str, "[]");
                break;
        case MONO_TYPE_PTR:
-               mono_type_get_name_recurse (type->data.type, str, FALSE);
+               mono_type_get_name_recurse (type->data.type, str, FALSE, include_ns, include_arity);
                g_string_append_c (str, '*');
                break;
        default:
                klass = mono_class_from_mono_type (type);
                if (klass->nested_in) {
-                       mono_type_get_name_recurse (&klass->nested_in->byval_arg, str, TRUE);
+                       mono_type_get_name_recurse (
+                               &klass->nested_in->byval_arg, str, TRUE, include_ns, include_arity);
                        g_string_append_c (str, '+');
                }
-               if (*klass->name_space) {
+               if (include_ns && *klass->name_space) {
                        g_string_append (str, klass->name_space);
                        g_string_append_c (str, '.');
                }
-               g_string_append (str, klass->name);
+               if (!include_arity) {
+                       char *s = strchr (klass->name, '`');
+                       int len = s ? s - klass->name : strlen (klass->name);
+
+                       g_string_append_len (str, klass->name, len);
+               } else
+                       g_string_append (str, klass->name);
                if (is_recursed)
                        break;
-               if (klass->generic_inst) {
-                       MonoGenericInst *ginst = klass->generic_inst;
+               if (klass->generic_class) {
+                       MonoGenericClass *gclass = klass->generic_class;
                        int i;
 
                        g_string_append_c (str, '[');
-                       for (i = 0; i < ginst->type_argc; i++) {
+                       for (i = 0; i < gclass->inst->type_argc; i++) {
                                if (i)
                                        g_string_append_c (str, ',');
-                               mono_type_get_name_recurse (ginst->type_argv [i], str, FALSE);
+                               mono_type_get_name_recurse (
+                                       gclass->inst->type_argv [i], str, FALSE, include_ns, include_arity);
                        }
                        g_string_append_c (str, ']');
-               } else if (klass->gen_params) {
+               } else if (klass->generic_container) {
                        int i;
 
                        g_string_append_c (str, '[');
-                       for (i = 0; i < klass->num_gen_params; i++) {
+                       for (i = 0; i < klass->generic_container->type_argc; i++) {
                                if (i)
                                        g_string_append_c (str, ',');
-                               g_string_append (str, klass->gen_params [i].name);
+                               g_string_append (str, klass->generic_container->type_params [i].name);
                        }
                        g_string_append_c (str, ']');
                }
@@ -180,18 +181,19 @@ mono_type_get_name_recurse (MonoType *type, GString *str, gboolean is_recursed)
        }
 }
 
-/*
+/**
  * mono_type_get_name:
  * @type: a type
  *
- * Returns the string representation for type as required by System.Reflection.
+ * Returns: the string representation for type as required by System.Reflection.
  * The inverse of mono_reflection_parse_type ().
  */
-char*
-mono_type_get_name (MonoType *type)
+static char*
+_mono_type_get_name (MonoType *type, gboolean is_recursed, gboolean include_ns,
+                    gboolean include_arity)
 {
        GString* result = g_string_new ("");
-       mono_type_get_name_recurse (type, result, FALSE);
+       mono_type_get_name_recurse (type, result, is_recursed, include_ns, include_arity);
 
        if (type->byref)
                g_string_append_c (result, '&');
@@ -199,6 +201,35 @@ mono_type_get_name (MonoType *type)
        return g_string_free (result, FALSE);
 }
 
+char*
+mono_type_get_name (MonoType *type)
+{
+       return _mono_type_get_name (type, TRUE, TRUE, TRUE);
+}
+
+char*
+mono_type_get_full_name (MonoType *type)
+{
+       return _mono_type_get_name (type, FALSE, TRUE, TRUE);
+}
+
+MonoType*
+mono_type_get_underlying_type (MonoType *type)
+{
+       switch (type->type) {
+       case MONO_TYPE_VALUETYPE:
+               if (type->data.klass->enumtype)
+                       return type->data.klass->enum_basetype;
+               break;
+       case MONO_TYPE_GENERICINST:
+               return mono_type_get_underlying_type (&type->data.generic_class->container_class->byval_arg);
+       default:
+               break;
+       }
+
+       return type;
+}
+
 gboolean
 mono_class_is_open_constructed_type (MonoType *t)
 {
@@ -213,13 +244,13 @@ mono_class_is_open_constructed_type (MonoType *t)
        case MONO_TYPE_PTR:
                return mono_class_is_open_constructed_type (t->data.type);
        case MONO_TYPE_GENERICINST: {
-               MonoGenericInst *ginst = t->data.generic_inst;
+               MonoGenericClass *gclass = t->data.generic_class;
                int i;
 
-               if (mono_class_is_open_constructed_type (ginst->generic_type))
+               if (mono_class_is_open_constructed_type (&gclass->container_class->byval_arg))
                        return TRUE;
-               for (i = 0; i < ginst->type_argc; i++)
-                       if (mono_class_is_open_constructed_type (ginst->type_argv [i]))
+               for (i = 0; i < gclass->inst->type_argc; i++)
+                       if (mono_class_is_open_constructed_type (gclass->inst->type_argv [i]))
                                return TRUE;
                return FALSE;
        }
@@ -228,21 +259,59 @@ mono_class_is_open_constructed_type (MonoType *t)
        }
 }
 
+static MonoGenericClass *
+inflate_generic_class (MonoGenericClass *ogclass, MonoGenericContext *context)
+{
+       MonoGenericClass *ngclass, *cached;
+
+       if (ogclass->is_dynamic) {
+               MonoDynamicGenericClass *dgclass = g_new0 (MonoDynamicGenericClass, 1);
+               ngclass = &dgclass->generic_class;
+               ngclass->is_dynamic = 1;
+       } else
+               ngclass = g_new0 (MonoGenericClass, 1);
+
+       *ngclass = *ogclass;
+
+       ngclass->inst = mono_metadata_inflate_generic_inst (ogclass->inst, context);
+
+       ngclass->klass = NULL;
+
+       ngclass->context = g_new0 (MonoGenericContext, 1);
+       ngclass->context->container = context->container;
+       ngclass->context->gclass = ngclass;
+
+       ngclass->initialized = FALSE;
+
+       mono_loader_lock ();
+       cached = mono_metadata_lookup_generic_class (ngclass);
+       mono_loader_unlock ();
+       if (cached) {
+               g_free (ngclass);
+               return cached;
+       }
+
+       mono_class_create_generic (ngclass);
+       mono_class_create_generic_2 (ngclass);
+
+       return ngclass;
+}
+
 static MonoType*
 inflate_generic_type (MonoType *type, MonoGenericContext *context)
 {
        switch (type->type) {
        case MONO_TYPE_MVAR:
-               if (context->gmethod && context->gmethod->mtype_argv)
+               if (context->gmethod && context->gmethod->inst->type_argv)
                        return dup_type (
-                               context->gmethod->mtype_argv [type->data.generic_param->num],
+                               context->gmethod->inst->type_argv [type->data.generic_param->num],
                                type);
                else
                        return NULL;
        case MONO_TYPE_VAR:
-               if (context->ginst)
+               if (context->gclass)
                        return dup_type (
-                               context->ginst->type_argv [type->data.generic_param->num],
+                               context->gclass->inst->type_argv [type->data.generic_param->num],
                                type);
                else
                        return NULL;
@@ -256,55 +325,25 @@ inflate_generic_type (MonoType *type, MonoGenericContext *context)
                return nt;
        }
        case MONO_TYPE_GENERICINST: {
-               MonoGenericInst *oginst = type->data.generic_inst;
-               MonoGenericInst *nginst;
+               MonoGenericClass *ngclass = inflate_generic_class (type->data.generic_class, context);
+               MonoType *nt = dup_type (type, type);
+               nt->data.generic_class = ngclass;
+               return nt;
+       }
+       case MONO_TYPE_CLASS:
+       case MONO_TYPE_VALUETYPE: {
+               MonoClass *klass = type->data.klass;
+               MonoGenericClass *gclass;
                MonoType *nt;
-               int i;
-
-               nginst = g_new0 (MonoGenericInst, 1);
-               *nginst = *oginst;
 
-               nginst->is_open = FALSE;
-
-               nginst->type_argv = g_new0 (MonoType *, oginst->type_argc);
-
-               for (i = 0; i < oginst->type_argc; i++) {
-                       MonoType *t = oginst->type_argv [i];
-                       nginst->type_argv [i] = mono_class_inflate_generic_type (t, context);
-
-                       if (!nginst->is_open)
-                               nginst->is_open = mono_class_is_open_constructed_type (nginst->type_argv [i]);
-               };
-
-               nginst->klass = NULL;
-
-               nginst->context = g_new0 (MonoGenericContext, 1);
-               nginst->context->ginst = nginst;
-
-               mono_loader_lock ();
-               nt = g_hash_table_lookup (oginst->klass->image->generic_inst_cache, nginst);
-
-               if (nt) {
-                       g_free (nginst->type_argv);
-                       g_free (nginst);
-                       mono_loader_unlock ();
-                       return nt;
-               }
-
-               nginst->dynamic_info = NULL;
-               nginst->initialized = FALSE;
-
-               mono_class_create_generic (nginst);
+               if (!klass->generic_container)
+                       return NULL;
 
-               mono_stats.generic_instance_count++;
-               mono_stats.generics_metadata_size += sizeof (MonoGenericInst) +
-                       sizeof (MonoGenericContext) +
-                       nginst->type_argc * sizeof (MonoType);
+               gclass = inflate_generic_class (klass->generic_container->context.gclass, context);
 
                nt = dup_type (type, type);
-               nt->data.generic_inst = nginst;
-               g_hash_table_insert (oginst->klass->image->generic_inst_cache, nginst, nt);
-               mono_loader_unlock ();
+               nt->type = MONO_TYPE_GENERICINST;
+               nt->data.generic_class = gclass;
                return nt;
        }
        default:
@@ -319,26 +358,36 @@ mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context)
        MonoType *inflated = inflate_generic_type (type, context);
 
        if (!inflated)
-               return type;
+               return dup_type (type, type);
 
        mono_stats.inflated_type_count++;
        return inflated;
 }
 
-static MonoMethodSignature*
-inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig,
-                          MonoGenericContext *context)
+MonoMethodSignature*
+mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context)
 {
        MonoMethodSignature *res;
+       gboolean is_open;
        int i;
+
+       if (!context)
+               return sig;
+
        res = mono_metadata_signature_alloc (image, sig->param_count);
        res->ret = mono_class_inflate_generic_type (sig->ret, context);
-       for (i = 0; i < sig->param_count; ++i)
+       is_open = mono_class_is_open_constructed_type (res->ret);
+       for (i = 0; i < sig->param_count; ++i) {
                res->params [i] = mono_class_inflate_generic_type (sig->params [i], context);
+               if (!is_open)
+                       is_open = mono_class_is_open_constructed_type (res->params [i]);
+       }
        res->hasthis = sig->hasthis;
        res->explicit_this = sig->explicit_this;
        res->call_convention = sig->call_convention;
        res->generic_param_count = sig->generic_param_count;
+       res->sentinelpos = sig->sentinelpos;
+       res->has_type_parameters = is_open;
        res->is_inflated = 1;
        return res;
 }
@@ -356,59 +405,98 @@ inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
        res->init_locals = header->init_locals;
        res->num_locals = header->num_locals;
        res->clauses = header->clauses;
-       res->gen_params = header->gen_params;
        for (i = 0; i < header->num_locals; ++i)
                res->locals [i] = mono_class_inflate_generic_type (header->locals [i], context);
        return res;
 }
 
+static MonoGenericContext *
+inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with)
+{
+       MonoGenericContext *res = g_new0 (MonoGenericContext, 1);
+
+       res->container = context->container;
+
+       if (context->gclass)
+               res->gclass = inflate_generic_class (context->gclass, inflate_with);
+
+       if (context->gmethod) {
+               res->gmethod = g_new0 (MonoGenericMethod, 1);
+
+               res->gmethod->container = context->gmethod->container;
+               res->gmethod->inst = mono_metadata_inflate_generic_inst (context->gmethod->inst, inflate_with);
+       } else
+               res->gmethod = inflate_with->gmethod;
+
+       return res;
+}
+
 MonoMethod*
 mono_class_inflate_generic_method (MonoMethod *method, MonoGenericContext *context,
                                   MonoClass *klass)
 {
        MonoMethodInflated *result;
+       MonoClass *rklass;
 
        if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
            (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                return method;
 
+       if (method->is_inflated || method->signature->is_inflated) {
+               MonoMethodInflated *imethod = (MonoMethodInflated *) method;
+
+               context = inflate_generic_context (imethod->context, context);
+               method = imethod->declaring;
+       }
+
        mono_stats.inflated_method_count++;
-       mono_stats.generics_metadata_size +=
-               sizeof (MonoMethodInflated) - sizeof (MonoMethodNormal);
 
        result = g_new0 (MonoMethodInflated, 1);
        result->nmethod = *(MonoMethodNormal*)method;
+       result->nmethod.method.is_inflated = 1;
+       result->context = context;
+       result->declaring = method;
 
-       if (result->nmethod.header)
-               result->nmethod.header = inflate_generic_header (
-                       result->nmethod.header, context);
+       if (result->nmethod.method.klass->generic_class)
+               result->nmethod.method.klass = result->nmethod.method.klass->generic_class->container_class;
 
-       if (klass)
-               result->nmethod.method.klass = klass;
-       else {
-               MonoType *declaring = mono_class_inflate_generic_type (
-                       &method->klass->byval_arg, context);
-               result->nmethod.method.klass = mono_class_from_mono_type (declaring);
-       }
+       return (MonoMethod *) result;
+}
 
-       result->nmethod.method.signature = inflate_generic_signature (
-               method->klass->image, method->signature, context);
+MonoMethod *
+mono_get_inflated_method (MonoMethod *method)
+{
+       MonoMethodInflated *imethod, *res;
+       MonoMethodHeader *mh;
+       MonoType *dtype;
+       MonoClass *rklass;
 
-       if (context->gmethod) {
-               result->context = g_new0 (MonoGenericContext, 1);
-               result->context->gmethod = context->gmethod;
-               result->context->ginst = result->nmethod.method.klass->generic_inst;
+       if (!method->is_inflated)
+               return method;
 
-               mono_stats.generics_metadata_size += sizeof (MonoGenericContext);
-       } else
-               result->context = result->nmethod.method.klass->generic_inst->context;
+       imethod = (MonoMethodInflated *) method;
+       if (imethod->inflated)
+               return (MonoMethod *) imethod->inflated;
 
-       if (method->signature->is_inflated)
-               result->declaring = ((MonoMethodInflated *) method)->declaring;
-       else
-               result->declaring = method;
+       mono_stats.inflated_method_count_2++;
+       mono_stats.generics_metadata_size +=
+               sizeof (MonoMethodInflated) - sizeof (MonoMethodNormal);
 
-       return (MonoMethod *) result;
+       res = g_new0 (MonoMethodInflated, 1);
+       *res = *imethod;
+       res->inflated = imethod->inflated = res;
+
+       mh = mono_method_get_header (method);
+       if (mh)
+               res->nmethod.header = inflate_generic_header (mh, imethod->context);
+
+       dtype = mono_class_inflate_generic_type (&method->klass->byval_arg, imethod->context);
+       rklass = res->nmethod.method.klass = mono_class_from_mono_type (dtype);
+
+       res->nmethod.method.signature = mono_class_inflate_generic_signature (
+               method->klass->image, method->signature, imethod->context);
+
+       return (MonoMethod *) res;
 }
 
 /** 
@@ -462,9 +550,13 @@ class_compute_field_layout (MonoClass *class)
                        class->instance_size = MAX (real_size, class->instance_size);
                }
                class->size_inited = 1;
+               class->blittable = blittable;
                return;
        }
 
+       if (layout == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+               blittable = FALSE;
+
        class->fields = g_new0 (MonoClassField, top);
 
        /*
@@ -474,6 +566,7 @@ class_compute_field_layout (MonoClass *class)
                const char *sig;
                guint32 cols [MONO_FIELD_SIZE];
                int idx = class->field.first + i;
+               MonoGenericContainer *container = NULL;
 
                field = &class->fields [i];
                mono_metadata_decode_row (t, idx, cols, MONO_FIELD_SIZE);
@@ -483,13 +576,20 @@ class_compute_field_layout (MonoClass *class)
                mono_metadata_decode_value (sig, &sig);
                /* FIELD signature == 0x06 */
                g_assert (*sig == 0x06);
-               field->type = mono_metadata_parse_field_type (
-                       m, cols [MONO_FIELD_FLAGS], sig + 1, &sig);
+               if (class->generic_container)
+                       container = class->generic_container;
+               else if (class->generic_class) {
+                       container = class->generic_class->container_class->generic_container;
+                       g_assert (container);
+               }
+               field->type = mono_metadata_parse_type_full (
+                       m, (MonoGenericContext *) container, MONO_PARSE_FIELD,
+                       cols [MONO_FIELD_FLAGS], sig + 1, &sig);
                if (mono_field_is_deleted (field))
                        continue;
-               if (class->generic_inst) {
+               if (class->generic_class) {
                        field->type = mono_class_inflate_generic_type (
-                               field->type, class->generic_inst->context);
+                               field->type, class->generic_class->context);
                        field->type->attrs = cols [MONO_FIELD_FLAGS];
                }
 
@@ -497,7 +597,7 @@ class_compute_field_layout (MonoClass *class)
 
                /* Only do these checks if we still think this type is blittable */
                if (blittable && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
-                       if (field->type->byref) {
+                       if (field->type->byref || MONO_TYPE_IS_REFERENCE (field->type)) {
                                blittable = FALSE;
                        } else {
                                MonoClass *field_class = mono_class_from_mono_type (field->type);
@@ -516,7 +616,7 @@ class_compute_field_layout (MonoClass *class)
                        mono_metadata_field_info (m, idx, NULL, &rva, NULL);
                        if (!rva)
                                g_warning ("field %s in %s should have RVA data, but hasn't", field->name, class->name);
-                       field->data = mono_cli_rva_map (class->image->image_info, rva);
+                       field->data = mono_image_rva_map (class->image, rva);
                }
 
                if (class->enumtype && !(cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_STATIC)) {
@@ -541,7 +641,8 @@ class_compute_field_layout (MonoClass *class)
                class->instance_size = MAX (real_size, class->instance_size);
        }
 
-       if (class->gen_params)
+       if (class->generic_container ||
+           (class->generic_class && class->generic_class->inst->is_open))
                return;
 
        mono_class_layout_fields (class);
@@ -690,7 +791,7 @@ mono_class_layout_fields (MonoClass *class)
                int size, align;
                field = &class->fields [i];
                        
-               if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
+               if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC) || field->type->attrs & FIELD_ATTRIBUTE_LITERAL)
                        continue;
                if (mono_field_is_deleted (field))
                        continue;
@@ -751,25 +852,39 @@ init_events (MonoClass *class)
 
        class->events = g_new0 (MonoEvent, class->event.count);
        for (i = class->event.first; i < class->event.last; ++i) {
+               MonoEvent *event = &class->events [i - class->event.first];
+                       
                mono_metadata_decode_row (pt, i, cols, MONO_EVENT_SIZE);
-               class->events [i - class->event.first].parent = class;
-               class->events [i - class->event.first].attrs = cols [MONO_EVENT_FLAGS];
-               class->events [i - class->event.first].name = mono_metadata_string_heap (class->image, cols [MONO_EVENT_NAME]);
+               event->parent = class;
+               event->attrs = cols [MONO_EVENT_FLAGS];
+               event->name = mono_metadata_string_heap (class->image, cols [MONO_EVENT_NAME]);
 
                startm = mono_metadata_methods_from_event (class->image, i, &endm);
                for (j = startm; j < endm; ++j) {
                        mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE);
                        switch (cols [MONO_METHOD_SEMA_SEMANTICS]) {
                        case METHOD_SEMANTIC_ADD_ON:
-                               class->events [i - class->event.first].add = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
+                               event->add = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
                                break;
                        case METHOD_SEMANTIC_REMOVE_ON:
-                               class->events [i - class->event.first].remove = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
+                               event->remove = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
                                break;
                        case METHOD_SEMANTIC_FIRE:
-                               class->events [i - class->event.first].raise = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
+                               event->raise = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
+                               break;
+                       case METHOD_SEMANTIC_OTHER: {
+                               int n = 0;
+
+                               if (event->other == NULL) {
+                                       event->other = g_new0 (MonoMethod*, 1);
+                               } else {
+                                       while (event->other [n])
+                                               n++;
+                                       event->other = g_realloc (event->other, (n + 1) * sizeof (MonoMethod*));
+                               }
+                               event->other [n] = class->methods [cols [MONO_METHOD_SEMA_METHOD] - 1 - class->method.first];
                                break;
-                       case METHOD_SEMANTIC_OTHER: /* don't care for now */
+                       }
                        default:
                                break;
                        }
@@ -826,8 +941,8 @@ collect_implemented_interfaces_aux (MonoClass *klass, GPtrArray **res)
        }
 }
 
-static inline GPtrArray*
-collect_implemented_interfaces (MonoClass *klass)
+GPtrArray*
+mono_class_get_implemented_interfaces (MonoClass *klass)
 {
        GPtrArray *res = NULL;
 
@@ -867,7 +982,7 @@ setup_interface_offsets (MonoClass *class, int cur_slot)
        for (i = 0; i <= max_iid; i++)
                class->interface_offsets [i] = -1;
 
-       ifaces = collect_implemented_interfaces (class);
+       ifaces = mono_class_get_implemented_interfaces (class);
        if (ifaces) {
                for (i = 0; i < ifaces->len; ++i) {
                        ic = g_ptr_array_index (ifaces, i);
@@ -878,7 +993,7 @@ setup_interface_offsets (MonoClass *class, int cur_slot)
        }
 
        for (k = class->parent; k ; k = k->parent) {
-               ifaces = collect_implemented_interfaces (k);
+               ifaces = mono_class_get_implemented_interfaces (k);
                if (ifaces) {
                        for (i = 0; i < ifaces->len; ++i) {
                                ic = g_ptr_array_index (ifaces, i);
@@ -908,7 +1023,7 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
        MonoMethod **vtable;
        int i, max_vtsize = 0, max_iid, cur_slot = 0;
        GPtrArray *ifaces;
-       MonoGHashTable *override_map = NULL;
+       GHashTable *override_map = NULL;
 
        /* setup_vtable() must be called only once on the type */
        if (class->interface_offsets) {
@@ -916,7 +1031,7 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
                return;
        }
 
-       ifaces = collect_implemented_interfaces (class);
+       ifaces = mono_class_get_implemented_interfaces (class);
        if (ifaces) {
                for (i = 0; i < ifaces->len; i++) {
                        MonoClass *ic = g_ptr_array_index (ifaces, i);
@@ -953,15 +1068,15 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
                        vtable [dslot] = overrides [i*2 + 1];
                        vtable [dslot]->slot = dslot;
                        if (!override_map)
-                               override_map = mono_g_hash_table_new (NULL, NULL);
+                               override_map = g_hash_table_new (NULL, NULL);
 
-                       mono_g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]);
+                       g_hash_table_insert (override_map, overrides [i * 2], overrides [i * 2 + 1]);
                }
        }
 
        for (k = class; k ; k = k->parent) {
                int nifaces = 0;
-               ifaces = collect_implemented_interfaces (k);
+               ifaces = mono_class_get_implemented_interfaces (k);
                if (ifaces)
                        nifaces = ifaces->len;
                for (i = 0; i < nifaces; i++) {
@@ -1032,15 +1147,24 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
 
                        for (l = 0; l < ic->method.count; l++) {
                                MonoMethod *im = ic->methods [l];                                               
-                               char *qname, *fqname;
+                               char *qname, *fqname, *cname, *the_cname;
                                MonoClass *k1;
                                
                                if (vtable [io + l])
                                        continue;
+
+                               if (ic->generic_class) {
+                                       MonoClass *the_ic = ic->generic_class->container_class;
+                                       the_cname = _mono_type_get_name (&the_ic->byval_arg, TRUE, FALSE, TRUE);
+                                       cname = the_cname;
+                               } else {
+                                       the_cname = NULL;
+                                       cname = (char*)ic->name;
+                               }
                                        
-                               qname = g_strconcat (ic->name, ".", im->name, NULL); 
+                               qname = g_strconcat (cname, ".", im->name, NULL);
                                if (ic->name_space && ic->name_space [0])
-                                       fqname = g_strconcat (ic->name_space, ".", ic->name, ".", im->name, NULL);
+                                       fqname = g_strconcat (ic->name_space, ".", cname, ".", im->name, NULL);
                                else
                                        fqname = NULL;
 
@@ -1059,6 +1183,7 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
                                                }
                                        }
                                }
+                               g_free (the_cname);
                                g_free (qname);
                                g_free (fqname);
                        }
@@ -1152,8 +1277,8 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
                                                slot = k->methods [j]->slot;
                                                g_assert (cm->slot < max_vtsize);
                                                if (!override_map)
-                                                       override_map = mono_g_hash_table_new (NULL, NULL);
-                                               mono_g_hash_table_insert (override_map, m1, cm);
+                                                       override_map = g_hash_table_new (NULL, NULL);
+                                               g_hash_table_insert (override_map, m1, cm);
                                                break;
                                        }
                                }
@@ -1179,8 +1304,8 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
                        vtable [decl->slot] = overrides [i*2 + 1];
                        overrides [i * 2 + 1]->slot = decl->slot;
                        if (!override_map)
-                               override_map = mono_g_hash_table_new (NULL, NULL);
-                       mono_g_hash_table_insert (override_map, decl, overrides [i * 2 + 1]);
+                               override_map = g_hash_table_new (NULL, NULL);
+                       g_hash_table_insert (override_map, decl, overrides [i * 2 + 1]);
                }
        }
 
@@ -1191,16 +1316,16 @@ mono_class_setup_vtable (MonoClass *class, MonoMethod **overrides, int onum)
        if (override_map) {
                for (i = 0; i < max_vtsize; ++i)
                        if (vtable [i]) {
-                               MonoMethod *cm = mono_g_hash_table_lookup (override_map, vtable [i]);
+                               MonoMethod *cm = g_hash_table_lookup (override_map, vtable [i]);
                                if (cm)
                                        vtable [i] = cm;
                        }
 
-               mono_g_hash_table_destroy (override_map);
+               g_hash_table_destroy (override_map);
        }
 
-       if (class->generic_inst) {
-               MonoClass *gklass = mono_class_from_mono_type (class->generic_inst->generic_type);
+       if (class->generic_class) {
+               MonoClass *gklass = class->generic_class->container_class;
 
                mono_class_init (gklass);
                class->vtable_size = gklass->vtable_size;
@@ -1298,34 +1423,33 @@ mono_class_init (MonoClass *class)
 
        class->init_pending = 1;
 
-       mono_stats.initialized_class_count++;
+       if (mono_debugger_start_class_init_func)
+               mono_debugger_start_class_init_func (class);
 
-       if (class->generic_inst && !class->generic_inst->is_dynamic) {
-               MonoGenericInst *ginst = class->generic_inst;
-               MonoClass *gklass;
-               GList *list;
+       mono_stats.initialized_class_count++;
 
-               gklass = mono_class_from_mono_type (ginst->generic_type);
-               mono_class_init (gklass);
+       if (class->generic_class && !class->generic_class->is_dynamic) {
+               MonoGenericClass *gclass = class->generic_class;
+               MonoClass *gklass = gclass->container_class;
 
-               if (ginst->parent)
-                       class->parent = mono_class_from_mono_type (ginst->parent);
-               else
-                       class->parent = gklass->parent;
+               mono_stats.generic_class_count++;
 
-               mono_class_setup_parent (class, class->parent);
+               mono_class_init (gklass);
 
                if (MONO_CLASS_IS_INTERFACE (class))
                        class->interface_id = mono_get_unique_iid (class);
 
-               class->method = gklass->method;
+               g_assert (class->method.count == gklass->method.count);
                class->methods = g_new0 (MonoMethod *, class->method.count);
 
-               for (i = 0; i < class->method.count; i++)
-                       class->methods [i] = mono_class_inflate_generic_method (
-                               gklass->methods [i], ginst->context, ginst->klass);
+               for (i = 0; i < class->method.count; i++) {
+                       MonoMethod *inflated = mono_class_inflate_generic_method (
+                               gklass->methods [i], gclass->context, gclass->klass);
+
+                       class->methods [i] = mono_get_inflated_method (inflated);
+               }
 
-               class->field = gklass->field;
+               g_assert (class->field.count == gklass->field.count);
                class->fields = g_new0 (MonoClassField, class->field.count);
 
                for (i = 0; i < class->field.count; i++) {
@@ -1336,7 +1460,7 @@ mono_class_init (MonoClass *class)
                        class->fields [i].generic_info = ifield;
                        class->fields [i].parent = class;
                        class->fields [i].type = mono_class_inflate_generic_type (
-                               class->fields [i].type, ginst->context);
+                               class->fields [i].type, gclass->context);
                }
 
                class->property = gklass->property;
@@ -1349,27 +1473,15 @@ mono_class_init (MonoClass *class)
 
                        if (prop->get)
                                prop->get = mono_class_inflate_generic_method (
-                                       prop->get, ginst->context, ginst->klass);
+                                       prop->get, gclass->context, gclass->klass);
                        if (prop->set)
                                prop->set = mono_class_inflate_generic_method (
-                                       prop->set, ginst->context, ginst->klass);
+                                       prop->set, gclass->context, gclass->klass);
 
                        prop->parent = class;
                }
 
-               class->interface_count = gklass->interface_count;
-               class->interfaces = g_new0 (MonoClass *, class->interface_count);
-               for (i = 0; i < class->interface_count; i++) {
-                       MonoType *it = &gklass->interfaces [i]->byval_arg;
-                       MonoType *inflated = mono_class_inflate_generic_type (
-                               it, ginst->context);
-                       class->interfaces [i] = mono_class_from_mono_type (inflated);
-                       mono_class_init (class->interfaces [i]);
-               }
-
-               for (list = gklass->nested_classes; list; list = list->next)
-                       class->nested_classes = g_list_append (
-                               class->nested_classes, list->data);
+               g_assert (class->interface_count == gklass->interface_count);
        }
 
        if (class->parent && !class->parent->inited)
@@ -1418,7 +1530,7 @@ mono_class_init (MonoClass *class)
                        class->methods [1] = ctor;
                }
        } else {
-               if (!class->generic_inst && !class->methods) {
+               if (!class->generic_class && !class->methods) {
                        class->methods = g_new (MonoMethod*, class->method.count);
                        for (i = 0; i < class->method.count; ++i) {
                                class->methods [i] = mono_get_method (class->image,
@@ -1427,7 +1539,7 @@ mono_class_init (MonoClass *class)
                }
        }
 
-       if (!class->generic_inst) {
+       if (!class->generic_class) {
                init_properties (class);
                init_events (class);
 
@@ -1456,6 +1568,10 @@ mono_class_init (MonoClass *class)
                 */
                setup_interface_offsets (class, 0);
                mono_loader_unlock ();
+
+               if (mono_debugger_class_init_func)
+                       mono_debugger_class_init_func (class);
+
                return;
        }
 
@@ -1523,7 +1639,6 @@ mono_class_init (MonoClass *class)
                mono_debugger_class_init_func (class);
 }
 
-
 void
 mono_class_setup_mono_type (MonoClass *class)
 {
@@ -1668,7 +1783,7 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent)
                if (!parent)
                        g_assert_not_reached (); /* FIXME */
 
-               if (parent->generic_inst && !parent->name) {
+               if (parent->generic_class && !parent->name) {
                        /*
                         * If the parent is a generic instance, we may get
                         * called before it is fully initialized, especially
@@ -1731,6 +1846,81 @@ mono_class_setup_supertypes (MonoClass *class)
        }
 }      
 
+/*
+ * If we inherit a type parameter from an outer class, set its owner to that class.
+ */
+static int
+set_generic_param_owner (MonoGenericContainer *container, MonoClass *klass, int pos)
+{
+       MonoGenericContainer *gc;
+       int i;
+
+       if (klass->nested_in)
+               pos = set_generic_param_owner (container, klass->nested_in, pos);
+
+       if (!klass->generic_container)
+               return pos;
+
+       gc = klass->generic_container;
+       for (i = pos; i < gc->type_argc; i++)
+               container->type_params [i].owner = gc;
+
+       return pos + gc->type_argc;
+}
+
+static MonoGenericInst *
+get_shared_inst (MonoGenericContainer *container)
+{
+       MonoGenericInst *nginst;
+       int i;
+
+       nginst = g_new0 (MonoGenericInst, 1);
+       nginst->type_argc = container->type_argc;
+       nginst->type_argv = g_new0 (MonoType *, nginst->type_argc);
+       nginst->is_open = 1;
+
+       for (i = 0; i < nginst->type_argc; i++) {
+               MonoType *t = g_new0 (MonoType, 1);
+
+               t->type = container->is_method ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
+               t->data.generic_param = &container->type_params [i];
+
+               nginst->type_argv [i] = t;
+       }
+
+       return mono_metadata_lookup_generic_inst (nginst);
+}
+
+MonoGenericClass *
+mono_get_shared_generic_class (MonoGenericContainer *container, gboolean is_dynamic)
+{
+       MonoGenericClass *gclass;
+       MonoGenericClass *cached;
+
+       if (is_dynamic) {
+               MonoDynamicGenericClass *dgclass = g_new0 (MonoDynamicGenericClass, 1);
+               gclass = &dgclass->generic_class;
+               gclass->is_dynamic = 1;
+       } else
+               gclass = g_new0 (MonoGenericClass, 1);
+
+       gclass->context = &container->context;
+       gclass->container_class = container->klass;
+       gclass->inst = get_shared_inst (container);
+
+#if 0
+       cached = mono_metadata_lookup_generic_class (gclass);
+       if (cached) {
+               g_free (gclass);
+               return cached;
+       }
+#endif
+
+       gclass->klass = container->klass;
+
+       return gclass;
+}
+
 /**
  * @image: context where the image is created
  * @type_token:  typedef token
@@ -1743,6 +1933,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        guint32 cols [MONO_TYPEDEF_SIZE];
        guint32 cols_next [MONO_TYPEDEF_SIZE];
        guint tidx = mono_metadata_token_index (type_token);
+       MonoGenericContext *context = NULL;
        const char *name, *nspace;
        guint icount = 0; 
        MonoClass **interfaces;
@@ -1755,22 +1946,13 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        }
 
        g_assert (mono_metadata_token_table (type_token) == MONO_TABLE_TYPEDEF);
-       
+
        mono_metadata_decode_row (tt, tidx - 1, cols, MONO_TYPEDEF_SIZE);
        
        name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
        nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
 
-       if (cols [MONO_TYPEDEF_EXTENDS])
-               parent = mono_class_get (image, mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS]));
-       interfaces = mono_metadata_interfaces_from_typedef (image, type_token, &icount);
-
        class = g_malloc0 (sizeof (MonoClass));
-                          
-       g_hash_table_insert (image->class_cache, GUINT_TO_POINTER (type_token), class);
-
-       class->interfaces = interfaces;
-       class->interface_count = icount;
 
        class->name = name;
        class->name_space = nspace;
@@ -1779,6 +1961,29 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        class->type_token = type_token;
        class->flags = cols [MONO_TYPEDEF_FLAGS];
 
+       g_hash_table_insert (image->class_cache, GUINT_TO_POINTER (type_token), class);
+
+       class->generic_container = mono_metadata_load_generic_params (image, class->type_token, NULL);
+       if (class->generic_container) {
+               class->generic_container->klass = class;
+               context = &class->generic_container->context;
+
+               context->gclass = mono_get_shared_generic_class (context->container, FALSE);
+       }
+
+       if (cols [MONO_TYPEDEF_EXTENDS])
+               parent = mono_class_get_full (
+                       image, mono_metadata_token_from_dor (cols [MONO_TYPEDEF_EXTENDS]), context);
+
+       mono_class_setup_parent (class, parent);
+
+       mono_class_setup_mono_type (class);
+
+       interfaces = mono_metadata_interfaces_from_typedef_full (image, type_token, &icount, context);
+
+       class->interfaces = interfaces;
+       class->interface_count = icount;
+
        if ((class->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_UNICODE_CLASS)
                class->unicode = 1;
        /* fixme: maybe we must set this on windows 
@@ -1790,10 +1995,6 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
 
        /*g_print ("Load class %s\n", name);*/
 
-       mono_class_setup_parent (class, parent);
-
-       mono_class_setup_mono_type (class);
-
        /*
         * Compute the field and method lists
         */
@@ -1832,24 +2033,24 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
        if ((type_token = mono_metadata_nested_in_typedef (image, type_token)))
                class->nested_in = mono_class_create_from_typedef (image, type_token);
 
-       class->gen_params = mono_metadata_load_generic_params (image, class->type_token, &icount);
-       class->num_gen_params = icount;
+       if (class->nested_in && class->generic_container)
+               set_generic_param_owner (class->generic_container, class->nested_in, 0);
 
        mono_loader_unlock ();
 
        return class;
 }
 
-MonoClass*
-mono_class_create_generic (MonoGenericInst *ginst)
+void
+mono_class_create_generic (MonoGenericClass *gclass)
 {
        MonoClass *klass, *gklass;
 
-       if (!ginst->klass)
-               ginst->klass = g_malloc0 (sizeof (MonoClass));
-       klass = ginst->klass;
+       if (!gclass->klass)
+               gclass->klass = g_malloc0 (sizeof (MonoClass));
+       klass = gclass->klass;
 
-       gklass = mono_class_from_mono_type (ginst->generic_type);
+       gklass = gclass->container_class;
 
        klass->nested_in = gklass->nested_in;
 
@@ -1858,23 +2059,63 @@ mono_class_create_generic (MonoGenericInst *ginst)
        klass->image = gklass->image;
        klass->flags = gklass->flags;
 
-       klass->generic_inst = ginst;
+       klass->generic_class = gclass;
 
        klass->this_arg.type = klass->byval_arg.type = MONO_TYPE_GENERICINST;
-       klass->this_arg.data.generic_inst = klass->byval_arg.data.generic_inst = ginst;
+       klass->this_arg.data.generic_class = klass->byval_arg.data.generic_class = gclass;
        klass->this_arg.byref = TRUE;
 
        klass->cast_class = klass->element_class = klass;
 
-       if (ginst->is_dynamic) {
+       if (gclass->is_dynamic) {
                klass->instance_size = gklass->instance_size;
                klass->class_size = gklass->class_size;
                klass->size_inited = 1;
+               klass->inited = 1;
 
                klass->valuetype = gklass->valuetype;
+
+               mono_class_setup_supertypes (klass);
        }
+}
 
-       return klass;
+void
+mono_class_create_generic_2 (MonoGenericClass *gclass)
+{
+       MonoClass *klass, *gklass;
+       GList *list;
+       int i;
+
+       if (gclass->is_dynamic)
+               return;
+
+       klass = gclass->klass;
+       gklass = gclass->container_class;
+
+       klass->method = gklass->method;
+       klass->field = gklass->field;
+
+       klass->interface_count = gklass->interface_count;
+       klass->interfaces = g_new0 (MonoClass *, klass->interface_count);
+       for (i = 0; i < klass->interface_count; i++) {
+               MonoType *it = &gklass->interfaces [i]->byval_arg;
+               MonoType *inflated = mono_class_inflate_generic_type (it, gclass->context);
+               klass->interfaces [i] = mono_class_from_mono_type (inflated);
+       }
+
+       for (list = gklass->nested_classes; list; list = list->next)
+               klass->nested_classes = g_list_append (
+                       klass->nested_classes, list->data);
+
+       if (gclass->parent)
+               klass->parent = mono_class_from_mono_type (gclass->parent);
+       else if (gklass->parent) {
+               MonoType *inflated = mono_class_inflate_generic_type (&gklass->parent->byval_arg, gclass->context);
+
+               klass->parent = mono_class_from_mono_type (inflated);
+       }
+
+       mono_class_setup_parent (klass, klass->parent);
 }
 
 MonoClass *
@@ -1904,7 +2145,7 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb
                        klass->interfaces [i - pos] = param->constraints [i];
        }
 
-       g_assert (param->name);
+       g_assert (param->name && param->owner);
 
        klass->name = param->name;
        klass->name_space = "";
@@ -1930,6 +2171,8 @@ my_mono_class_from_generic_parameter (MonoGenericParam *param, gboolean is_mvar)
        if (param->pklass)
                return param->pklass;
 
+       g_assert (param->owner);
+
        klass = g_new0 (MonoClass, 1);
 
        if (param->name)
@@ -1970,8 +2213,8 @@ mono_ptr_class_get (MonoType *type)
        result = g_new0 (MonoClass, 1);
 
        result->parent = NULL; /* no parent for PTR types */
-       result->name = "System";
-       result->name_space = "MonoPtrFakeClass";
+       result->name_space = el_class->name_space;
+       result->name = g_strdup_printf ("%s*", el_class->name);
        result->image = el_class->image;
        result->inited = TRUE;
        result->flags = TYPE_ATTRIBUTE_CLASS | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK);
@@ -2016,7 +2259,7 @@ mono_fnptr_class_get (MonoMethodSignature *sig)
        result->name_space = "MonoFNPtrFakeClass";
        result->image = NULL; /* need to fix... */
        result->inited = TRUE;
-       result->flags = TYPE_ATTRIBUTE_CLASS; // | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK);
+       result->flags = TYPE_ATTRIBUTE_CLASS; /* | (el_class->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK); */
        /* Can pointers get boxed? */
        result->instance_size = sizeof (gpointer);
        result->cast_class = result->element_class = result;
@@ -2089,8 +2332,8 @@ mono_class_from_mono_type (MonoType *type)
        case MONO_TYPE_VALUETYPE:
                return type->data.klass;
        case MONO_TYPE_GENERICINST:
-               g_assert (type->data.generic_inst->klass);
-               return type->data.generic_inst->klass;
+               g_assert (type->data.generic_class->klass);
+               return type->data.generic_class->klass;
        case MONO_TYPE_VAR:
                return my_mono_class_from_generic_parameter (type->data.generic_param, FALSE);
        case MONO_TYPE_MVAR:
@@ -2114,7 +2357,7 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec,
        MonoType *type, *inflated;
        MonoClass *class;
 
-       type = mono_type_create_from_typespec (image, type_spec);
+       type = mono_type_create_from_typespec_full (image, context, type_spec);
 
        switch (type->type) {
        case MONO_TYPE_ARRAY:
@@ -2124,11 +2367,11 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec,
                class = mono_array_class_get (type->data.klass, 1);
                break;
        case MONO_TYPE_PTR:
-               class = mono_class_from_mono_type (type->data.type);
+               class = mono_ptr_class_get (type->data.type);
                break;
        case MONO_TYPE_GENERICINST:
-               g_assert (type->data.generic_inst->klass);
-               class = type->data.generic_inst->klass;
+               g_assert (type->data.generic_class->klass);
+               class = type->data.generic_class->klass;
                break;
        default:
                /* it seems any type can be stored in TypeSpec as well */
@@ -2136,7 +2379,7 @@ mono_class_create_from_typespec (MonoImage *image, guint32 type_spec,
                break;
        }
 
-       if (!class || !context)
+       if (!class || !context || (!context->gclass && !context->gmethod))
                return class;
 
        inflated = mono_class_inflate_generic_type (&class->byval_arg, context);
@@ -2276,6 +2519,8 @@ mono_class_instance_size (MonoClass *klass)
        if (!klass->size_inited)
                mono_class_init (klass);
 
+       g_assert (!klass->generic_container &&
+                 (!klass->generic_class || !klass->generic_class->inst->is_open));
        return klass->instance_size;
 }
 
@@ -2390,6 +2635,48 @@ mono_class_get_field_from_name (MonoClass *klass, const char *name)
        return NULL;
 }
 
+guint32
+mono_class_get_field_token (MonoClassField *field)
+{
+       MonoClass *klass = field->parent;
+       int i;
+
+       while (klass) {
+               for (i = 0; i < klass->field.count; ++i) {
+                       if (&klass->fields [i] == field)
+                               return mono_metadata_make_token (MONO_TABLE_FIELD, klass->field.first + i + 1);
+               }
+               klass = klass->parent;
+       }
+
+       g_assert_not_reached ();
+       return 0;
+}
+
+guint32
+mono_class_get_event_token (MonoEvent *event)
+{
+       MonoClass *klass = event->parent;
+       int i;
+
+       while (klass) {
+               for (i = 0; i < klass->event.count; ++i) {
+                       if (&klass->events [i] == event)
+                               return mono_metadata_make_token (MONO_TABLE_EVENT, klass->event.first + i + 1);
+               }
+               klass = klass->parent;
+       }
+
+       g_assert_not_reached ();
+       return 0;
+}
+
+void *
+mono_vtable_get_static_field_data (MonoVTable *vt)
+{
+       return vt->data;
+}
+
 MonoProperty*
 mono_class_get_property_from_name (MonoClass *klass, const char *name)
 {
@@ -2405,6 +2692,24 @@ mono_class_get_property_from_name (MonoClass *klass, const char *name)
        return NULL;
 }
 
+guint32
+mono_class_get_property_token (MonoProperty *prop)
+{
+       MonoClass *klass = prop->parent;
+       int i;
+
+       while (klass) {
+               for (i = 0; i < klass->property.count; ++i) {
+                       if (&klass->properties [i] == prop)
+                               return mono_metadata_make_token (MONO_TABLE_PROPERTY, klass->property.first + i + 1);
+               }
+               klass = klass->parent;
+       }
+
+       g_assert_not_reached ();
+       return 0;
+}
+
 /**
  * mono_class_get:
  * @image: the image where the class resides
@@ -2413,8 +2718,8 @@ mono_class_get_property_from_name (MonoClass *klass, const char *name)
  *
  * Returns: the MonoClass that represents @type_token in @image
  */
-MonoClass *
-mono_class_get (MonoImage *image, guint32 type_token)
+static MonoClass *
+_mono_class_get (MonoImage *image, guint32 type_token, MonoGenericContext *context)
 {
        MonoClass *class = NULL;
 
@@ -2429,7 +2734,7 @@ mono_class_get (MonoImage *image, guint32 type_token)
                class = mono_class_from_typeref (image, type_token);
                break;
        case MONO_TOKEN_TYPE_SPEC:
-               class = mono_class_create_from_typespec (image, type_token, NULL);
+               class = mono_class_create_from_typespec (image, type_token, context);
                break;
        default:
                g_warning ("unknown token type %x", type_token & 0xff000000);
@@ -2442,18 +2747,24 @@ mono_class_get (MonoImage *image, guint32 type_token)
        return class;
 }
 
+MonoClass *
+mono_class_get (MonoImage *image, guint32 type_token)
+{
+       return _mono_class_get (image, type_token, NULL);
+}
+
 MonoClass *
 mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context)
 {
-       MonoClass *class = mono_class_get (image, type_token);
+       MonoClass *class = _mono_class_get (image, type_token, context);
        MonoType *inflated;
 
-       if (!class || !context)
+       if (!class || !context || (!context->gclass && !context->gmethod))
                return class;
 
        switch (class->byval_arg.type) {
        case MONO_TYPE_GENERICINST:
-               if (!class->generic_inst->is_open)
+               if (!class->generic_class->inst->is_open)
                        return class;
                break;
        case MONO_TYPE_VAR:
@@ -2470,6 +2781,22 @@ mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *c
        return mono_class_from_mono_type (inflated);
 }
 
+/**
+ * mono_class_from_name_case:
+ * @image: The MonoImage where the type is looked up in, or NULL for looking up in all loaded assemblies
+ * @name_space: the type namespace
+ * @name: the type short name.
+ *
+ * Obtains a MonoClass with a given namespace and a given name which
+ * is located in the given MonoImage.   The namespace and name
+ * lookups are case insensitive.
+ *
+ * You can also pass @NULL to the image, and that will lookup for
+ * a type with the given namespace and name in all of the loaded
+ * assemblies: notice that since there might be a name clash in this
+ * case, passing @NULL is not encouraged if you need a precise type.
+ *
+ */
 MonoClass *
 mono_class_from_name_case (MonoImage *image, const char* name_space, const char *name)
 {
@@ -2515,6 +2842,22 @@ return_nested_in (MonoClass *class, char *nested) {
        return NULL;
 }
 
+
+/**
+ * mono_class_from_name_case:
+ * @image: The MonoImage where the type is looked up in, or NULL for looking up in all loaded assemblies
+ * @name_space: the type namespace
+ * @name: the type short name.
+ *
+ * Obtains a MonoClass with a given namespace and a given name which
+ * is located in the given MonoImage.   
+ *
+ * You can also pass `NULL' to the image, and that will lookup for
+ * a type with the given namespace and name in all of the loaded
+ * assemblies: notice that since there might be a name clash in this
+ * case, passing NULL is not encouraged if you need a precise type.
+ *
+ */
 MonoClass *
 mono_class_from_name (MonoImage *image, const char* name_space, const char *name)
 {
@@ -2558,8 +2901,8 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name
                mono_metadata_decode_row (t, idx - 1, cols, MONO_EXP_TYPE_SIZE);
 
                impl = cols [MONO_EXP_TYPE_IMPLEMENTATION];
-               if ((impl & IMPLEMENTATION_MASK) == IMPLEMENTATION_FILE) {
-                       loaded_image = mono_assembly_load_module (image->assembly, impl >> IMPLEMENTATION_BITS);
+               if ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE) {
+                       loaded_image = mono_assembly_load_module (image->assembly, impl >> MONO_IMPLEMENTATION_BITS);
                        if (!loaded_image)
                                return NULL;
                        class = mono_class_from_name (loaded_image, name_space, name);
@@ -2584,6 +2927,7 @@ mono_class_is_subclass_of (MonoClass *klass, MonoClass *klassc,
                           gboolean check_interfaces)
 {
  again:
+       g_assert (klassc->idepth > 0);
        if (check_interfaces && MONO_CLASS_IS_INTERFACE (klassc) && !MONO_CLASS_IS_INTERFACE (klass)) {
                if ((klassc->interface_id <= klass->max_interface_id) &&
                        (klass->interface_offsets [klassc->interface_id] >= 0))
@@ -2599,16 +2943,6 @@ mono_class_is_subclass_of (MonoClass *klass, MonoClass *klassc,
        } else {
                if (!MONO_CLASS_IS_INTERFACE (klass) && mono_class_has_parent (klass, klassc))
                        return TRUE;
-               if (klass->generic_inst) {
-                       MonoType *parent = klass->generic_inst->parent;
-                       if (!parent)
-                               return FALSE;
-
-                       if (mono_metadata_type_equal (parent, &klassc->byval_arg))
-                               return TRUE;
-                       klass = mono_class_from_mono_type (parent);
-                       goto again;
-               }
        }
 
        /* 
@@ -2617,6 +2951,17 @@ mono_class_is_subclass_of (MonoClass *klass, MonoClass *klassc,
         */
        if (klassc == mono_defaults.object_class)
                return TRUE;
+
+       if (klass->generic_class) {
+               MonoType *parent = klass->generic_class->parent;
+               if (!parent)
+                       return FALSE;
+
+               if (mono_metadata_type_equal (parent, &klassc->byval_arg))
+                       return TRUE;
+               klass = mono_class_from_mono_type (parent);
+               goto again;
+       }
        
        return FALSE;
 }
@@ -2694,17 +3039,20 @@ mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller)
        return FALSE;
 }
 
-/*
- * Returns the nnumber of bytes an element of type klass
+/**
+ * mono_class_array_element_size:
+ * @klass: 
+ *
+ * Returns: the number of bytes an element of type @klass
  * uses when stored into an array.
  */
 gint32
 mono_class_array_element_size (MonoClass *klass)
 {
-       int t = klass->byval_arg.type;
+       MonoType *type = &klass->byval_arg;
        
 handle_enum:
-       switch (t) {
+       switch (type->type) {
        case MONO_TYPE_I1:
        case MONO_TYPE_U1:
        case MONO_TYPE_BOOLEAN:
@@ -2733,13 +3081,17 @@ handle_enum:
        case MONO_TYPE_R8:
                return 8;
        case MONO_TYPE_VALUETYPE:
-               if (klass->enumtype) {
-                       t = klass->enum_basetype->type;
+               if (type->data.klass->enumtype) {
+                       type = type->data.klass->enum_basetype;
+                       klass = klass->element_class;
                        goto handle_enum;
                }
                return mono_class_instance_size (klass) - sizeof (MonoObject);
+       case MONO_TYPE_GENERICINST:
+               type = &type->data.generic_class->container_class->byval_arg;
+               goto handle_enum;
        default:
-               g_error ("unknown type 0x%02x in mono_class_array_element_size", t);
+               g_error ("unknown type 0x%02x in mono_class_array_element_size", type->type);
        }
        return -1;
 }
@@ -2870,102 +3222,216 @@ mono_class_get_image (MonoClass *klass)
        return klass->image;
 }
 
+/**
+ * mono_class_get_element_class:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the element class of an array or an enumeration.
+ */
 MonoClass*
 mono_class_get_element_class (MonoClass *klass)
 {
        return klass->element_class;
 }
 
+/**
+ * mono_class_is_valuetype:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: true if the MonoClass represents a ValueType.
+ */
 gboolean
 mono_class_is_valuetype (MonoClass *klass)
 {
        return klass->valuetype;
 }
 
+/**
+ * mono_class_is_enum:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: true if the MonoClass represents an enumeration.
+ */
 gboolean
 mono_class_is_enum (MonoClass *klass)
 {
        return klass->enumtype;
 }
 
+/**
+ * mono_class_enum_basetype:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the underlying type representation for an enumeration.
+ */
 MonoType*
 mono_class_enum_basetype (MonoClass *klass)
 {
        return klass->enum_basetype;
 }
 
+/**
+ * mono_class_get_parent
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the parent class for this class.
+ */
 MonoClass*
 mono_class_get_parent (MonoClass *klass)
 {
        return klass->parent;
 }
 
+/**
+ * mono_class_get_nesting_type;
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the container type where this type is nested or NULL if this type is not a nested type.
+ */
 MonoClass*
 mono_class_get_nesting_type (MonoClass *klass)
 {
        return klass->nested_in;
 }
 
+/**
+ * mono_class_get_rank:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the rank for the array (the number of dimensions).
+ */
 int
 mono_class_get_rank (MonoClass *klass)
 {
        return klass->rank;
 }
 
+/**
+ * mono_class_get_flags:
+ * @klass: the MonoClass to act on
+ *
+ * The type flags from the TypeDef table from the metadata.
+ * see the TYPE_ATTRIBUTE_* definitions on tabledefs.h for the
+ * different values.
+ *
+ * Returns: the flags from the TypeDef table.
+ */
 guint32
 mono_class_get_flags (MonoClass *klass)
 {
        return klass->flags;
 }
 
+/**
+ * mono_class_get_name
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the name of the class.
+ */
 const char*
 mono_class_get_name (MonoClass *klass)
 {
        return klass->name;
 }
 
+/**
+ * mono_class_get_namespace:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the namespace of the class.
+ */
 const char*
 mono_class_get_namespace (MonoClass *klass)
 {
        return klass->name_space;
 }
 
+/**
+ * mono_class_get_type:
+ * @klass: the MonoClass to act on
+ *
+ * This method returns the internal Type representation for the class.
+ *
+ * Returns: the MonoType from the class.
+ */
 MonoType*
 mono_class_get_type (MonoClass *klass)
 {
        return &klass->byval_arg;
 }
 
+/**
+ * mono_class_get_byref_type:
+ * @klass: the MonoClass to act on
+ *
+ * 
+ */
 MonoType*
 mono_class_get_byref_type (MonoClass *klass)
 {
        return &klass->this_arg;
 }
 
+/**
+ * mono_class_num_fields:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the number of static and instance fields in the class.
+ */
 int
 mono_class_num_fields (MonoClass *klass)
 {
        return klass->field.count;
 }
 
+/**
+ * mono_class_num_methods:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the number of methods in the class.
+ */
 int
 mono_class_num_methods (MonoClass *klass)
 {
        return klass->method.count;
 }
 
+/**
+ * mono_class_num_properties
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the number of properties in the class.
+ */
 int
 mono_class_num_properties (MonoClass *klass)
 {
        return klass->property.count;
 }
 
+/**
+ * mono_class_num_events:
+ * @klass: the MonoClass to act on
+ *
+ * Returns: the number of events in the class.
+ */
 int
 mono_class_num_events (MonoClass *klass)
 {
        return klass->event.count;
 }
 
+/**
+ * mono_class_get_fields:
+ * @klass: the MonoClass to act on
+ *
+ * This routine is an iterator routine for retrieving the fields in a class.
+ *
+ * You must pass a gpointer that points to zero and is treated as an opaque handle to
+ * iterate over all of the elements.  When no more values are
+ * available, the return value is NULL.
+ *
+ * Returns: a @MonoClassField* on each iteration, or NULL when no more fields are available.
+ */
 MonoClassField*
 mono_class_get_fields (MonoClass* klass, gpointer *iter)
 {
@@ -2991,6 +3457,18 @@ mono_class_get_fields (MonoClass* klass, gpointer *iter)
        return NULL;
 }
 
+/**
+ * mono_class_get_methods
+ * @klass: the MonoClass to act on
+ *
+ * This routine is an iterator routine for retrieving the fields in a class.
+ *
+ * You must pass a gpointer that points to zero and is treated as an opaque handle to
+ * iterate over all of the elements.  When no more values are
+ * available, the return value is NULL.
+ *
+ * Returns: a MonoMethod on each iteration or NULL when no more methods are available.
+ */
 MonoMethod*
 mono_class_get_methods (MonoClass* klass, gpointer *iter)
 {
@@ -3018,6 +3496,18 @@ mono_class_get_methods (MonoClass* klass, gpointer *iter)
        return NULL;
 }
 
+/**
+ * mono_class_get_properties:
+ * @klass: the MonoClass to act on
+ *
+ * This routine is an iterator routine for retrieving the properties in a class.
+ *
+ * You must pass a gpointer that points to zero and is treated as an opaque handle to
+ * iterate over all of the elements.  When no more values are
+ * available, the return value is NULL.
+ *
+ * Returns: a @MonoProperty* on each invocation, or NULL when no more are available.
+ */
 MonoProperty*
 mono_class_get_properties (MonoClass* klass, gpointer *iter)
 {
@@ -3043,6 +3533,18 @@ mono_class_get_properties (MonoClass* klass, gpointer *iter)
        return NULL;
 }
 
+/**
+ * mono_class_get_events:
+ * @klass: the MonoClass to act on
+ *
+ * This routine is an iterator routine for retrieving the properties in a class.
+ *
+ * You must pass a gpointer that points to zero and is treated as an opaque handle to
+ * iterate over all of the elements.  When no more values are
+ * available, the return value is NULL.
+ *
+ * Returns: a @MonoEvent* on each invocation, or NULL when no more are available.
+ */
 MonoEvent*
 mono_class_get_events (MonoClass* klass, gpointer *iter)
 {
@@ -3068,6 +3570,18 @@ mono_class_get_events (MonoClass* klass, gpointer *iter)
        return NULL;
 }
 
+/**
+ * mono_class_get_interfaces
+ * @klass: the MonoClass to act on
+ *
+ * This routine is an iterator routine for retrieving the interfaces implemented by this class.
+ *
+ * You must pass a gpointer that points to zero and is treated as an opaque handle to
+ * iterate over all of the elements.  When no more values are
+ * available, the return value is NULL.
+ *
+ * Returns: a @Monoclass* on each invocation, or NULL when no more are available.
+ */
 MonoClass*
 mono_class_get_interfaces (MonoClass* klass, gpointer *iter)
 {
@@ -3095,6 +3609,18 @@ mono_class_get_interfaces (MonoClass* klass, gpointer *iter)
        return NULL;
 }
 
+/**
+ * mono_class_get_nested_types
+ * @klass: the MonoClass to act on
+ *
+ * This routine is an iterator routine for retrieving the nested types of a class.
+ *
+ * You must pass a gpointer that points to zero and is treated as an opaque handle to
+ * iterate over all of the elements.  When no more values are
+ * available, the return value is NULL.
+ *
+ * Returns: a @Monoclass* on each invocation, or NULL when no more are available.
+ */
 MonoClass*
 mono_class_get_nested_types (MonoClass* klass, gpointer *iter)
 {
@@ -3122,93 +3648,219 @@ mono_class_get_nested_types (MonoClass* klass, gpointer *iter)
        return NULL;
 }
 
+/**
+ * mono_field_get_name:
+ * @field: the MonoClassField to act on
+ *
+ * Returns: the name of the field.
+ */
 const char*
 mono_field_get_name (MonoClassField *field)
 {
        return field->name;
 }
 
+/**
+ * mono_field_get_type:
+ * @field: the MonoClassField to act on
+ *
+ * Returns: MonoType of the field.
+ */
 MonoType*
 mono_field_get_type (MonoClassField *field)
 {
        return field->type;
 }
 
+/**
+ * mono_field_get_type:
+ * @field: the MonoClassField to act on
+ *
+ * Returns: MonoClass where the field was defined.
+ */
 MonoClass*
 mono_field_get_parent (MonoClassField *field)
 {
        return field->parent;
 }
 
+/**
+ * mono_field_get_flags;
+ * @field: the MonoClassField to act on
+ *
+ * The metadata flags for a field are encoded using the
+ * FIELD_ATTRIBUTE_* constants.  See the tabledefs.h file for details.
+ *
+ * Returns: the flags for the field.
+ */
 guint32
 mono_field_get_flags (MonoClassField *field)
 {
        return field->type->attrs;
 }
 
+/**
+ * mono_property_get_name: 
+ * @prop: the MonoProperty to act on
+ *
+ * Returns: the name of the property
+ */
 const char*
 mono_property_get_name (MonoProperty *prop)
 {
        return prop->name;
 }
 
+/**
+ * mono_property_get_set_method
+ * @prop: the MonoProperty to act on.
+ *
+ * Returns: the setter method of the property (A MonoMethod)
+ */
 MonoMethod*
 mono_property_get_set_method (MonoProperty *prop)
 {
        return prop->set;
 }
 
+/**
+ * mono_property_get_get_method
+ * @prop: the MonoProperty to act on.
+ *
+ * Returns: the setter method of the property (A MonoMethod)
+ */
 MonoMethod*
 mono_property_get_get_method (MonoProperty *prop)
 {
        return prop->get;
 }
 
+/**
+ * mono_property_get_parent:
+ * @prop: the MonoProperty to act on.
+ *
+ * Returns: the MonoClass where the property was defined.
+ */
 MonoClass*
 mono_property_get_parent (MonoProperty *prop)
 {
        return prop->parent;
 }
 
+/**
+ * mono_property_get_flags:
+ * @prop: the MonoProperty to act on.
+ *
+ * The metadata flags for a property are encoded using the
+ * PROPERTY_ATTRIBUTE_* constants.  See the tabledefs.h file for details.
+ *
+ * Returns: the flags for the property.
+ */
 guint32
 mono_property_get_flags (MonoProperty *prop)
 {
        return prop->attrs;
 }
 
+/**
+ * mono_event_get_name:
+ * @event: the MonoEvent to act on
+ *
+ * Returns: the name of the event.
+ */
 const char*
 mono_event_get_name (MonoEvent *event)
 {
        return event->name;
 }
 
+/**
+ * mono_event_get_add_method:
+ * @event: The MonoEvent to act on.
+ *
+ * Returns: the @add' method for the event (a MonoMethod).
+ */
 MonoMethod*
 mono_event_get_add_method (MonoEvent *event)
 {
        return event->add;
 }
 
+/**
+ * mono_event_get_remove_method:
+ * @event: The MonoEvent to act on.
+ *
+ * Returns: the @remove method for the event (a MonoMethod).
+ */
 MonoMethod*
 mono_event_get_remove_method (MonoEvent *event)
 {
        return event->remove;
 }
 
+/**
+ * mono_event_get_raise_method:
+ * @event: The MonoEvent to act on.
+ *
+ * Returns: the @raise method for the event (a MonoMethod).
+ */
 MonoMethod*
 mono_event_get_raise_method (MonoEvent *event)
 {
        return event->raise;
 }
 
+/**
+ * mono_event_get_parent:
+ * @event: the MonoEvent to act on.
+ *
+ * Returns: the MonoClass where the event is defined.
+ */
 MonoClass*
 mono_event_get_parent (MonoEvent *event)
 {
        return event->parent;
 }
 
+/**
+ * mono_event_get_flags
+ * @event: the MonoEvent to act on.
+ *
+ * The metadata flags for an event are encoded using the
+ * EVENT_* constants.  See the tabledefs.h file for details.
+ *
+ * Returns: the flags for the event.
+ */
 guint32
 mono_event_get_flags (MonoEvent *event)
 {
        return event->attrs;
 }
 
+/**
+ * mono_find_method_by_name:
+ * @klass: where to look for the method
+ * @name_space: name of the method
+ * @param_count: number of parameters. -1 for any number.
+ *
+ * Obtains a MonoMethod with a given name and number of parameters.
+ * It only works if there are no multiple signatures for any given method name.
+ */
+MonoMethod *
+mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_count)
+{
+       MonoMethod *res = NULL;
+       int i;
+
+       mono_class_init (klass);
+
+       for (i = 0; i < klass->method.count; ++i) {
+               if (klass->methods [i]->name[0] == name [0] && 
+                   !strcmp (name, klass->methods [i]->name) &&
+                   (param_count == -1 || klass->methods [i]->signature->param_count == param_count)) {
+                       res = klass->methods [i];
+                       break;
+               }
+       }
+       return res;
+}