Merge pull request #381 from JamesB7/system-security6
[mono.git] / mcs / class / corlib / System / Type.cs
1 //
2 // System.Type.cs
3 //
4 // Authors:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Diagnostics;
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using System.Collections;
38 using System.Collections.Generic;
39 using System.Runtime.InteropServices;
40 using System.Runtime.CompilerServices;
41 using System.Globalization;
42
43 namespace System {
44
45         [Serializable]
46         [ClassInterface (ClassInterfaceType.None)]
47         [ComVisible (true)]
48         [ComDefaultInterface (typeof (_Type))]
49         [StructLayout (LayoutKind.Sequential)]
50         public abstract class Type : MemberInfo, IReflect, _Type {
51                 
52                 internal RuntimeTypeHandle _impl;
53
54                 public static readonly char Delimiter = '.';
55                 public static readonly Type[] EmptyTypes = {};
56                 public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl);
57                 public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl);
58                 public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
59                 public static readonly object Missing = System.Reflection.Missing.Value;
60
61                 internal const BindingFlags DefaultBindingFlags =
62                 BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
63
64                 /* implementation of the delegates for MemberFilter */
65                 static bool FilterName_impl (MemberInfo m, object filterCriteria)
66                 {
67                         string name = (string) filterCriteria;
68                         if (name == null || name.Length == 0 )
69                                 return false; // because m.Name cannot be null or empty
70                                 
71                         if (name [name.Length-1] == '*')
72                                 return string.CompareOrdinal (name, 0, m.Name, 0, name.Length-1) == 0;
73
74                 return name.Equals (m.Name);                    
75                 }
76
77                 static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
78                 {
79                         string name = (string) filterCriteria;
80                         if (name == null || name.Length == 0 )
81                                 return false; // because m.Name cannot be null or empty
82                                 
83                         if (name [name.Length-1] == '*')
84                                 return string.Compare (name, 0, m.Name, 0, name.Length-1, StringComparison.OrdinalIgnoreCase) == 0;
85
86                         return string.Equals (name, m.Name, StringComparison.OrdinalIgnoreCase);
87                 }
88
89                 static bool FilterAttribute_impl (MemberInfo m, object filterCriteria)
90                 {
91                         int flags = ((IConvertible)filterCriteria).ToInt32 (null);
92                         if (m is MethodInfo)
93                                 return ((int)((MethodInfo)m).Attributes & flags) != 0;
94                         if (m is FieldInfo)
95                                 return ((int)((FieldInfo)m).Attributes & flags) != 0;
96                         if (m is PropertyInfo)
97                                 return ((int)((PropertyInfo)m).Attributes & flags) != 0;
98                         if (m is EventInfo)
99                                 return ((int)((EventInfo)m).Attributes & flags) != 0;
100                         return false;
101                 }
102
103                 protected Type ()
104                 {
105                 }
106
107                 /// <summary>
108                 ///   The assembly where the type is defined.
109                 /// </summary>
110                 public abstract Assembly Assembly {
111                         get;
112                 }
113
114                 /// <summary>
115                 ///   Gets the fully qualified name for the type including the
116                 ///   assembly name where the type is defined.
117                 /// </summary>
118                 public abstract string AssemblyQualifiedName {
119                         get;
120                 }
121
122                 /// <summary>
123                 ///   Returns the Attributes associated with the type.
124                 /// </summary>
125                 public TypeAttributes Attributes {
126                         get {
127                                 return GetAttributeFlagsImpl ();
128                         }
129                 }
130
131                 /// <summary>
132                 ///   Returns the basetype for this type
133                 /// </summary>
134                 public abstract Type BaseType {
135                         get;
136                 }
137
138                 /// <summary>
139                 ///   Returns the class that declares the member.
140                 /// </summary>
141                 public override Type DeclaringType {
142                         get {
143                                 return null;
144                         }
145                 }
146
147                 /// <summary>
148                 ///
149                 /// </summary>
150                 public static Binder DefaultBinder {
151                         get {
152                                 return Binder.DefaultBinder;
153                         }
154                 }
155
156                 /// <summary>
157                 ///    The full name of the type including its namespace
158                 /// </summary>
159                 public abstract string FullName {
160                         get;
161                 }
162
163                 public abstract Guid GUID {
164                         get;
165                 }
166
167                 public bool HasElementType {
168                         get {
169                                 return HasElementTypeImpl ();
170                         }
171                 }
172
173                 public bool IsAbstract {
174                         get {
175                                 return (Attributes & TypeAttributes.Abstract) != 0;
176                         }
177                 }
178
179                 public bool IsAnsiClass {
180                         get {
181                                 return (Attributes & TypeAttributes.StringFormatMask)
182                                 == TypeAttributes.AnsiClass;
183                         }
184                 }
185
186                 public bool IsArray {
187                         get {
188                                 return IsArrayImpl ();
189                         }
190                 }
191
192                 public bool IsAutoClass {
193                         get {
194                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
195                         }
196                 }
197
198                 public bool IsAutoLayout {
199                         get {
200                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
201                         }
202                 }
203
204                 public bool IsByRef {
205                         get {
206                                 return IsByRefImpl ();
207                         }
208                 }
209
210                 public bool IsClass {
211                         get {
212                                 if (IsInterface)
213                                         return false;
214
215                                 return !IsValueType;
216                         }
217                 }
218
219                 public bool IsCOMObject {
220                         get {
221                                 return IsCOMObjectImpl ();
222                         }
223                 }
224                 
225 #if NET_4_5
226                 public virtual bool IsConstructedGenericType {
227                         get {
228                                 throw new NotImplementedException ();
229                         }
230                 }
231 #endif
232
233                 public bool IsContextful {
234                         get {
235                                 return IsContextfulImpl ();
236                         }
237                 }
238
239                 public
240 #if NET_4_0
241                 virtual
242 #endif
243                 bool IsEnum {
244                         get {
245                                 return IsSubclassOf (typeof (Enum));
246                         }
247                 }
248
249                 public bool IsExplicitLayout {
250                         get {
251                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
252                         }
253                 }
254
255                 public bool IsImport {
256                         get {
257                                 return (Attributes & TypeAttributes.Import) != 0;
258                         }
259                 }
260
261                 public bool IsInterface {
262                         get {
263                                 return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
264                         }
265                 }
266
267                 public bool IsLayoutSequential {
268                         get {
269                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
270                         }
271                 }
272
273                 public bool IsMarshalByRef {
274                         get {
275                                 return IsMarshalByRefImpl ();
276                         }
277                 }
278
279                 public bool IsNestedAssembly {
280                         get {
281                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
282                         }
283                 }
284
285                 public bool IsNestedFamANDAssem {
286                         get {
287                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
288                         }
289                 }
290
291                 public bool IsNestedFamily {
292                         get {
293                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
294                         }
295                 }
296
297                 public bool IsNestedFamORAssem {
298                         get {
299                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
300                         }
301                 }
302
303                 public bool IsNestedPrivate {
304                         get {
305                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
306                         }
307                 }
308
309                 public bool IsNestedPublic {
310                         get {
311                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
312                         }
313                 }
314
315                 public bool IsNotPublic {
316                         get {
317                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
318                         }
319                 }
320
321                 public bool IsPointer {
322                         get {
323                                 return IsPointerImpl ();
324                         }
325                 }
326
327                 public bool IsPrimitive {
328                         get {
329                                 return IsPrimitiveImpl ();
330                         }
331                 }
332
333                 public bool IsPublic {
334                         get {
335                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
336                         }
337                 }
338
339                 public bool IsSealed {
340                         get {
341                                 return (Attributes & TypeAttributes.Sealed) != 0;
342                         }
343                 }
344
345                 public
346 #if NET_4_0
347                 virtual
348 #endif
349                 bool IsSerializable {
350                         get {
351                                 if ((Attributes & TypeAttributes.Serializable) != 0)
352                                         return true;
353
354                                 // Enums and delegates are always serializable
355
356                                 Type type = UnderlyingSystemType;
357                                 if (type == null)
358                                         return false;
359
360                                 // Fast check for system types
361                                 if (type.IsSystemType)
362                                         return type_is_subtype_of (type, typeof (Enum), false) || type_is_subtype_of (type, typeof (Delegate), false);
363
364                                 // User defined types depend on this behavior
365                                 do {
366                                         if ((type == typeof (Enum)) || (type == typeof (Delegate)))
367                                                 return true;
368
369                                         type = type.BaseType;
370                                 } while (type != null);
371
372                                 return false;
373                         }
374                 }
375
376                 public bool IsSpecialName {
377                         get {
378                                 return (Attributes & TypeAttributes.SpecialName) != 0;
379                         }
380                 }
381
382                 public bool IsUnicodeClass {
383                         get {
384                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
385                         }
386                 }
387
388                 public bool IsValueType {
389                         get {
390                                 return IsValueTypeImpl ();
391                         }
392                 }
393
394                 public override MemberTypes MemberType {
395                         get {
396                                 return MemberTypes.TypeInfo;
397                         }
398                 }
399
400                 public abstract override Module Module {
401                         get;
402                 }
403         
404                 public abstract string Namespace {get;}
405
406                 public override Type ReflectedType {
407                         get {
408                                 return null;
409                         }
410                 }
411
412                 public virtual RuntimeTypeHandle TypeHandle {
413                         get { throw new ArgumentException ("Derived class must provide implementation."); }
414                 }
415
416                 [ComVisible (true)]
417                 public ConstructorInfo TypeInitializer {
418                         get {
419                                 return GetConstructorImpl (
420                                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
421                                         null,
422                                         CallingConventions.Any,
423                                         EmptyTypes,
424                                         null);
425                         }
426                 }
427
428                 /*
429                  * This has NOTHING to do with getting the base type of an enum. Use
430                  * Enum.GetUnderlyingType () for that.
431                  */
432                 public abstract Type UnderlyingSystemType {get;}
433
434                 public override bool Equals (object o)
435                 {
436 #if NET_4_0
437                         return Equals (o as Type);
438 #else
439                         if (o == this)
440                                 return true;
441
442                         Type me = UnderlyingSystemType;
443                         if (me == null)
444                                 return false;
445                         return me.EqualsInternal (o as Type);
446 #endif
447                 }
448
449 #if NET_4_0
450                 public virtual bool Equals (Type o)
451                 {
452                         if ((object)o == (object)this)
453                                 return true;
454                         if ((object)o == null)
455                                 return false;
456                         Type me = UnderlyingSystemType;
457                         if ((object)me == null)
458                                 return false;
459
460                         o = o.UnderlyingSystemType;
461                         if ((object)o == null)
462                                 return false;
463                         if ((object)o == (object)this)
464                                 return true;
465                         return me.EqualsInternal (o);
466                 }               
467 #else
468                 public bool Equals (Type o)
469                 {
470
471                         if (o == this)
472                                 return true;
473                         if (o == null)
474                                 return false;
475                         Type me = UnderlyingSystemType;
476                         if (me == null)
477                                 return false;
478                         return me.EqualsInternal (o.UnderlyingSystemType);
479                 }
480 #endif
481 #if NET_4_0
482                 [MonoTODO ("Implement it properly once 4.0 impl details are known.")]
483                 public static bool operator == (Type left, Type right)
484                 {
485                         return Object.ReferenceEquals (left, right);
486                 }
487
488                 [MonoTODO ("Implement it properly once 4.0 impl details are known.")]
489                 public static bool operator != (Type left, Type right)
490                 {
491                         return !Object.ReferenceEquals (left, right);
492                 }
493
494                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
495                 public virtual Type GetEnumUnderlyingType () {
496                         if (!IsEnum)
497                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
498
499                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
500
501                         if (fields == null || fields.Length != 1)
502                                 throw new ArgumentException ("An enum must have exactly one instance field", "enumType");
503
504                         return fields [0].FieldType;
505                 }
506
507                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
508                 public virtual string[] GetEnumNames () {
509                         if (!IsEnum)
510                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
511
512                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
513
514                         string [] names = new string [fields.Length];
515                         if (0 != names.Length) {
516                                 for (int i = 0; i < fields.Length; ++i)
517                                         names [i] = fields [i].Name;
518                                         
519                                 var et = GetEnumUnderlyingType ();
520                                 var values = Array.CreateInstance (et, names.Length);
521                                 for (int i = 0; i < fields.Length; ++i)
522                                         values.SetValue (fields [i].GetValue (null), i);
523                                 MonoEnumInfo.SortEnums (et, values, names);
524                         }
525
526                         return names;
527                 }
528
529                 static NotImplementedException CreateNIE () {
530                         return new NotImplementedException ();
531                 }
532
533                 public virtual Array GetEnumValues () {
534                         if (!IsEnum)
535                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
536
537                         throw CreateNIE ();
538                 }
539
540                 bool IsValidEnumType (Type type) {
541                         return (type.IsPrimitive && type != typeof (bool) && type != typeof (double) && type != typeof (float)) || type.IsEnum;
542                 }
543
544                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
545                 public virtual string GetEnumName (object value) {
546                         if (value == null)
547                                 throw new ArgumentException ("Value is null", "value");
548                         if (!IsValidEnumType (value.GetType ()))
549                                 throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value");
550                         if (!IsEnum)
551                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
552
553                         object obj = null;
554                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
555                         
556                         for (int i = 0; i < fields.Length; ++i) {
557                                 var fv = fields [i].GetValue (null);
558                                 if (obj == null) {
559                                         try {
560                                                 //XXX we can't use 'this' as argument as it might be an UserType
561                                                 obj = Enum.ToObject (fv.GetType (), value);
562                                         } catch (OverflowException) {
563                                                 return null;
564                                         } catch (InvalidCastException) {
565                                                 throw new ArgumentException ("Value is not valid", "value");
566                                         }
567                                 }
568                                 if (fv.Equals (obj))
569                                         return fields [i].Name;
570                         }
571
572                         return null;
573                 }
574
575                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
576                 public virtual bool IsEnumDefined (object value) {
577                         if (value == null)
578                                 throw new ArgumentException ("Value is null", "value");
579                         if (!IsEnum)
580                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
581
582                         Type vt = value.GetType ();
583                         if (!IsValidEnumType (vt) && vt != typeof (string))
584                                 throw new InvalidOperationException ("Value is not the enum or a valid enum underlying type");
585
586                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
587
588                         if (value is string) {
589                                 for (int i = 0; i < fields.Length; ++i) {
590                                         if (fields [i].Name.Equals (value))
591                                                 return true;
592                                 }
593                         } else {
594                                 if (vt != this && vt != GetEnumUnderlyingType ())
595                                         throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value");
596
597                                 object obj = null;
598                                 for (int i = 0; i < fields.Length; ++i) {
599                                         var fv = fields [i].GetValue (null);
600                                         if (obj == null) {
601                                                 try {
602                                                         //XXX we can't use 'this' as argument as it might be an UserType
603                                                         obj = Enum.ToObject (fv.GetType (), value);
604                                                 } catch (OverflowException) {
605                                                         return false;
606                                                 } catch (InvalidCastException) {
607                                                         throw new ArgumentException ("Value is not valid", "value");
608                                                 }
609                                         }
610                                         if (fv.Equals (obj))
611                                                 return true;
612                                 }
613                         }
614                         return false;
615                 }
616         
617                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver)
618                 {
619                         return GetType (typeName, assemblyResolver, typeResolver, false, false);
620                 }
621         
622                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver, bool throwOnError)
623                 {
624                         return GetType (typeName, assemblyResolver, typeResolver, throwOnError, false);
625                 }
626         
627                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver, bool throwOnError, bool ignoreCase)
628                 {
629                         TypeSpec spec = TypeSpec.Parse (typeName);
630                         return spec.Resolve (assemblyResolver, typeResolver, throwOnError, ignoreCase);
631                 }
632
633                 public virtual bool IsSecurityTransparent
634                 {
635                         get { throw CreateNIE (); }
636                 }
637
638                 public virtual bool IsSecurityCritical
639                 {
640                         get { throw CreateNIE (); }
641                 }
642
643                 public virtual bool IsSecuritySafeCritical
644                 {
645                         get { throw CreateNIE (); }
646                 }
647 #endif
648                 
649                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
650                 internal extern bool EqualsInternal (Type type);
651                 
652                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
653                 private static extern Type internal_from_handle (IntPtr handle);
654                 
655                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
656                 private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase);
657
658                 public static Type GetType(string typeName)
659                 {
660                         if (typeName == null)
661                                 throw new ArgumentNullException ("TypeName");
662
663                         return internal_from_name (typeName, false, false);
664                 }
665
666                 public static Type GetType(string typeName, bool throwOnError)
667                 {
668                         if (typeName == null)
669                                 throw new ArgumentNullException ("TypeName");
670
671                         Type type = internal_from_name (typeName, throwOnError, false);
672                         if (throwOnError && type == null)
673                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
674
675                         return type;
676                 }
677
678                 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
679                 {
680                         if (typeName == null)
681                                 throw new ArgumentNullException ("TypeName");
682
683                         Type t = internal_from_name (typeName, throwOnError, ignoreCase);
684                         if (throwOnError && t == null)
685                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
686
687                         return t;
688                 }
689
690                 public static Type[] GetTypeArray (object[] args) {
691                         if (args == null)
692                                 throw new ArgumentNullException ("args");
693
694                         Type[] ret;
695                         ret = new Type [args.Length];
696                         for (int i = 0; i < args.Length; ++i)
697                                 ret [i] = args[i].GetType ();
698                         return ret;
699                 }
700
701                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
702                 internal extern static TypeCode GetTypeCodeInternal (Type type);
703
704 #if NET_4_0
705                 protected virtual
706 #endif
707                 TypeCode GetTypeCodeImpl () {
708                         Type type = this;
709                         if (type is MonoType)
710                                 return GetTypeCodeInternal (type);
711                         if (type is TypeBuilder)
712                                 return ((TypeBuilder)type).GetTypeCodeInternal ();
713
714                         type = type.UnderlyingSystemType;
715
716                         if (!type.IsSystemType)
717                                 return TypeCode.Object;
718                         else
719                                 return GetTypeCodeInternal (type);
720                 }
721
722                 public static TypeCode GetTypeCode (Type type) {
723                         if (type == null)
724                                 /* MS.NET returns this */
725                                 return TypeCode.Empty;
726                         return type.GetTypeCodeImpl ();
727                 }
728
729                 [MonoTODO("This operation is currently not supported by Mono")]
730                 public static Type GetTypeFromCLSID (Guid clsid)
731                 {
732                         throw new NotImplementedException ();
733                 }
734
735                 [MonoTODO("This operation is currently not supported by Mono")]
736                 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
737                 {
738                         throw new NotImplementedException ();
739                 }
740
741                 [MonoTODO("This operation is currently not supported by Mono")]
742                 public static Type GetTypeFromCLSID (Guid clsid, string server)
743                 {
744                         throw new NotImplementedException ();
745                 }
746
747                 [MonoTODO("This operation is currently not supported by Mono")]
748                 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
749                 {
750                         throw new NotImplementedException ();
751                 }
752
753                 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
754                 {
755                         if (handle.Value == IntPtr.Zero)
756                                 // This is not consistent with the other GetXXXFromHandle methods, but
757                                 // MS.NET seems to do this
758                                 return null;
759
760                         return internal_from_handle (handle.Value);
761                 }
762
763                 [MonoTODO("Mono does not support COM")]
764                 public static Type GetTypeFromProgID (string progID)
765                 {
766                         throw new NotImplementedException ();
767                 }
768
769                 [MonoTODO("Mono does not support COM")]
770                 public static Type GetTypeFromProgID (string progID, bool throwOnError)
771                 {
772                         throw new NotImplementedException ();
773                 }
774
775                 [MonoTODO("Mono does not support COM")]
776                 public static Type GetTypeFromProgID (string progID, string server)
777                 {
778                         throw new NotImplementedException ();
779                 }
780
781                 [MonoTODO("Mono does not support COM")]
782                 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
783                 {
784                         throw new NotImplementedException ();
785                 }
786
787                 public static RuntimeTypeHandle GetTypeHandle (object o)
788                 {
789                         if (o == null)
790                                 throw new ArgumentNullException ();
791
792                         return o.GetType().TypeHandle;
793                 }
794
795                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
796                 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
797
798                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
799                 internal static extern bool type_is_assignable_from (Type a, Type b);
800
801                 public new Type GetType ()
802                 {
803                         return base.GetType ();
804                 }
805
806                 [ComVisible (true)]
807                 public virtual bool IsSubclassOf (Type c)
808                 {
809                         if (c == null || c == this)
810                                 return false;
811
812                         // Fast check for system types
813                         if (IsSystemType)
814                                 return c.IsSystemType && type_is_subtype_of (this, c, false);
815
816                         // User defined types depend on this behavior
817                         for (Type type = BaseType; type != null; type = type.BaseType)
818                                 if (type == c)
819                                         return true;
820
821                         return false;
822                 }
823
824                 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
825                 {
826                         if (filter == null)
827                                 throw new ArgumentNullException ("filter");
828
829                         var ifaces = new List<Type> ();
830                         foreach (Type iface in GetInterfaces ()) {
831                                 if (filter (iface, filterCriteria))
832                                         ifaces.Add (iface);
833                         }
834
835                         return ifaces.ToArray ();
836                 }
837                 
838                 public Type GetInterface (string name) {
839                         return GetInterface (name, false);
840                 }
841
842                 public abstract Type GetInterface (string name, bool ignoreCase);
843
844                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
845                 internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
846
847                 [ComVisible (true)]
848                 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
849                         if (!IsSystemType)
850                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
851                         if (interfaceType == null)
852                                 throw new ArgumentNullException ("interfaceType");
853                         if (!interfaceType.IsSystemType)
854                                 throw new ArgumentException ("interfaceType", "Type is an user type");
855                         InterfaceMapping res;
856                         if (!interfaceType.IsInterface)
857                                 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "interfaceType");
858                         if (IsInterface)
859                                 throw new ArgumentException ("'this' type cannot be an interface itself");
860                         res.TargetType = this;
861                         res.InterfaceType = interfaceType;
862                         GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
863                         if (res.TargetMethods == null)
864                                 throw new ArgumentException (Locale.GetText ("Interface not found"), "interfaceType");
865
866                         return res;
867                 }
868
869                 public abstract Type[] GetInterfaces ();
870
871                 public virtual bool IsAssignableFrom (Type c)
872                 {
873                         if (c == null)
874                                 return false;
875
876                         if (Equals (c))
877                                 return true;
878
879                         if (c is TypeBuilder)
880                                 return ((TypeBuilder)c).IsAssignableTo (this);
881
882                         /* Handle user defined type classes */
883                         if (!IsSystemType) {
884                                 Type systemType = UnderlyingSystemType;
885                                 if (!systemType.IsSystemType)
886                                         return false;
887
888                                 Type other = c.UnderlyingSystemType;
889                                 if (!other.IsSystemType)
890                                         return false;
891
892                                 return systemType.IsAssignableFrom (other);
893                         }
894
895                         if (!c.IsSystemType) {
896                                 Type underlyingType = c.UnderlyingSystemType;
897                                 if (!underlyingType.IsSystemType)
898                                         return false;
899                                 return IsAssignableFrom (underlyingType);
900                         }
901
902                         return type_is_assignable_from (this, c);
903                 }
904
905                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
906                 extern static bool IsInstanceOfType (Type type, object o);
907
908                 public virtual bool IsInstanceOfType (object o)
909                 {
910                         Type type = UnderlyingSystemType;
911                         if (!type.IsSystemType)
912                                 return false;
913                         return IsInstanceOfType (type, o);
914                 }
915
916                 public virtual int GetArrayRank ()
917                 {
918                         throw new NotSupportedException ();     // according to MSDN
919                 }
920
921                 public abstract Type GetElementType ();
922
923                 public EventInfo GetEvent (string name)
924                 {
925                         return GetEvent (name, DefaultBindingFlags);
926                 }
927
928                 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
929
930                 public virtual EventInfo[] GetEvents ()
931                 {
932                         return GetEvents (DefaultBindingFlags);
933                 }
934
935                 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
936
937                 public FieldInfo GetField( string name)
938                 {
939                         return GetField (name, DefaultBindingFlags);
940                 }
941
942                 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
943
944                 public FieldInfo[] GetFields ()
945                 {
946                         return GetFields (DefaultBindingFlags);
947                 }
948
949                 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
950                 
951                 public override int GetHashCode()
952                 {
953                         Type t = UnderlyingSystemType;
954                         if (t != null && t != this)
955                                 return t.GetHashCode ();
956                         return (int)_impl.Value;
957                 }
958
959                 public MemberInfo[] GetMember (string name)
960                 {
961                         return GetMember (name, MemberTypes.All, DefaultBindingFlags);
962                 }
963                 
964                 public virtual MemberInfo[] GetMember (string name, BindingFlags bindingAttr)
965                 {
966                         return GetMember (name, MemberTypes.All, bindingAttr);
967                 }
968
969                 public virtual MemberInfo[] GetMember (string name, MemberTypes type, BindingFlags bindingAttr)
970                 {
971                         if (name == null)
972                                 throw new ArgumentNullException ("name");
973                         if ((bindingAttr & BindingFlags.IgnoreCase) != 0)
974                                 return FindMembers (type, bindingAttr, FilterNameIgnoreCase, name);
975                         else
976                                 return FindMembers (type, bindingAttr, FilterName, name);
977                 }
978
979                 public MemberInfo[] GetMembers ()
980                 {
981                         return GetMembers (DefaultBindingFlags);
982                 }
983
984                 public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr);
985
986                 public MethodInfo GetMethod (string name)
987                 {
988                         if (name == null)
989                                 throw new ArgumentNullException ("name");
990                         return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null);
991                 }
992
993                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr)
994                 {
995                         if (name == null)
996                                 throw new ArgumentNullException ("name");
997                         
998                         return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null);
999                 }
1000                 
1001                 public MethodInfo GetMethod (string name, Type[] types)
1002                 {
1003                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null);
1004                 }
1005
1006                 public MethodInfo GetMethod (string name, Type[] types, ParameterModifier[] modifiers)
1007                 {
1008                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, modifiers);
1009                 }
1010
1011                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
1012                                              Type[] types, ParameterModifier[] modifiers)
1013                 {
1014                         return GetMethod (name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
1015                 }
1016
1017                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
1018                                              CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
1019                 {
1020                         if (name == null)
1021                                 throw new ArgumentNullException ("name");
1022                         if (types == null)
1023                                 throw new ArgumentNullException ("types");
1024
1025                         for (int i = 0; i < types.Length; i++) 
1026                                 if (types[i] == null)
1027                                         throw new ArgumentNullException ("types");
1028
1029                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
1030                 }
1031
1032                 protected abstract MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
1033                                                              CallingConventions callConvention, Type[] types,
1034                                                              ParameterModifier[] modifiers);
1035
1036                 internal MethodInfo GetMethodImplInternal (string name, BindingFlags bindingAttr, Binder binder,
1037                                                                                                                         CallingConventions callConvention, Type[] types,
1038                                                                                                                         ParameterModifier[] modifiers)
1039                 {
1040                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
1041                 }
1042
1043                 internal virtual MethodInfo GetMethod (MethodInfo fromNoninstanciated)
1044                 {
1045                         throw new System.InvalidOperationException ("can only be called in generic type");
1046                 }
1047
1048                 internal virtual ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
1049                 {
1050                         throw new System.InvalidOperationException ("can only be called in generic type");
1051                 }
1052
1053                 internal virtual FieldInfo GetField (FieldInfo fromNoninstanciated)
1054                 {
1055                         throw new System.InvalidOperationException ("can only be called in generic type");
1056                 }
1057
1058                 
1059                 public MethodInfo[] GetMethods ()
1060                 {
1061                         return GetMethods (DefaultBindingFlags);
1062                 }
1063
1064                 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
1065
1066                 public Type GetNestedType (string name)
1067                 {
1068                         return GetNestedType (name, DefaultBindingFlags);
1069                 }
1070
1071                 public abstract Type GetNestedType (string name, BindingFlags bindingAttr);
1072
1073                 public Type[] GetNestedTypes ()
1074                 {
1075                         return GetNestedTypes (DefaultBindingFlags);
1076                 }
1077
1078                 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
1079
1080
1081                 public PropertyInfo[] GetProperties ()
1082                 {
1083                         return GetProperties (DefaultBindingFlags);
1084                 }
1085
1086                 public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr);
1087
1088
1089                 public PropertyInfo GetProperty (string name)
1090                 {
1091                         if (name == null)
1092                                 throw new ArgumentNullException ("name");
1093
1094                         return GetPropertyImpl (name, DefaultBindingFlags, null, null, null, null);
1095                 }
1096
1097                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
1098                 {
1099                         if (name == null)
1100                                 throw new ArgumentNullException ("name");
1101                         return GetPropertyImpl (name, bindingAttr, null, null, null, null);
1102                 }
1103
1104                 public PropertyInfo GetProperty (string name, Type returnType)
1105                 {
1106                         if (name == null)
1107                                 throw new ArgumentNullException ("name");
1108                         return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, null, null);
1109                 }
1110
1111                 public PropertyInfo GetProperty (string name, Type[] types)
1112                 {
1113                         return GetProperty (name, DefaultBindingFlags, null, null, types, null);
1114                 }
1115
1116                 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
1117                 {
1118                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, null);
1119                 }
1120
1121                 public PropertyInfo GetProperty( string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
1122                 {
1123                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, modifiers);
1124                 }
1125
1126                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr, Binder binder, Type returnType,
1127                                                  Type[] types, ParameterModifier[] modifiers)
1128                 {
1129                         if (name == null)
1130                                 throw new ArgumentNullException ("name");
1131                         if (types == null)
1132                                 throw new ArgumentNullException ("types");
1133
1134                         foreach (Type t in types) {
1135                                 if (t == null)
1136                                         throw new ArgumentNullException ("types");
1137                         }
1138
1139                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
1140                 }
1141
1142                 protected abstract PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
1143                                                                  Type returnType, Type[] types, ParameterModifier[] modifiers);
1144
1145                 internal PropertyInfo GetPropertyImplInternal (string name, BindingFlags bindingAttr, Binder binder,
1146                                                                                                            Type returnType, Type[] types, ParameterModifier[] modifiers)
1147                 {
1148                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
1149                 }
1150
1151                 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
1152                                                                        Binder binder,
1153                                                                        CallingConventions callConvention,
1154                                                                        Type[] types,
1155                                                                        ParameterModifier[] modifiers);
1156
1157                 protected abstract TypeAttributes GetAttributeFlagsImpl ();
1158                 protected abstract bool HasElementTypeImpl ();
1159                 protected abstract bool IsArrayImpl ();
1160                 protected abstract bool IsByRefImpl ();
1161                 protected abstract bool IsCOMObjectImpl ();
1162                 protected abstract bool IsPointerImpl ();
1163                 protected abstract bool IsPrimitiveImpl ();
1164                 
1165                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1166                 internal static extern bool IsArrayImpl (Type type);
1167
1168                 protected virtual bool IsValueTypeImpl ()
1169                 {
1170                         if (this == typeof (ValueType) || this == typeof (Enum))
1171                                 return false;
1172
1173                         return IsSubclassOf (typeof (ValueType));
1174                 }
1175                 
1176                 protected virtual bool IsContextfulImpl ()
1177                 {
1178                         return typeof (ContextBoundObject).IsAssignableFrom (this);
1179                 }
1180
1181                 protected virtual bool IsMarshalByRefImpl ()
1182                 {
1183                         return typeof (MarshalByRefObject).IsAssignableFrom (this);
1184                 }
1185
1186                 [ComVisible (true)]
1187                 public ConstructorInfo GetConstructor (Type[] types)
1188                 {
1189                         return GetConstructor (BindingFlags.Public|BindingFlags.Instance, null, CallingConventions.Any, types, null);
1190                 }
1191
1192                 [ComVisible (true)]
1193                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
1194                                                        Type[] types, ParameterModifier[] modifiers)
1195                 {
1196                         return GetConstructor (bindingAttr, binder, CallingConventions.Any, types, modifiers);
1197                 }
1198
1199                 [ComVisible (true)]
1200                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
1201                                                        CallingConventions callConvention,
1202                                                        Type[] types, ParameterModifier[] modifiers)
1203                 {
1204                         if (types == null)
1205                                 throw new ArgumentNullException ("types");
1206
1207                         foreach (Type t in types) {
1208                                 if (t == null)
1209                                         throw new ArgumentNullException ("types");
1210                         }
1211
1212                         return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
1213                 }
1214
1215                 [ComVisible (true)]
1216                 public ConstructorInfo[] GetConstructors ()
1217                 {
1218                         return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
1219                 }
1220
1221                 [ComVisible (true)]
1222                 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
1223
1224                 public virtual MemberInfo[] GetDefaultMembers ()
1225                 {
1226                         object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
1227                         if (att.Length == 0)
1228                                 return new MemberInfo [0];
1229
1230                         MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName);
1231                         return (member != null) ? member : new MemberInfo [0];
1232                 }
1233
1234                 public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr,
1235                                                          MemberFilter filter, object filterCriteria)
1236                 {
1237                         MemberInfo[] result;
1238                         ArrayList l = new ArrayList ();
1239
1240                         // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}",
1241                         // this.FullName, this.GetType().FullName, this.obj_address());
1242                         if ((memberType & MemberTypes.Method) != 0) {
1243                                 MethodInfo[] c = GetMethods (bindingAttr);
1244                                 if (filter != null) {
1245                                         foreach (MemberInfo m in c) {
1246                                                 if (filter (m, filterCriteria))
1247                                                         l.Add (m);
1248                                         }
1249                                 } else {
1250                                         l.AddRange (c);
1251                                 }
1252                         }
1253                         if ((memberType & MemberTypes.Constructor) != 0) {
1254                                 ConstructorInfo[] c = GetConstructors (bindingAttr);
1255                                 if (filter != null) {
1256                                         foreach (MemberInfo m in c) {
1257                                                 if (filter (m, filterCriteria))
1258                                                         l.Add (m);
1259                                         }
1260                                 } else {
1261                                         l.AddRange (c);
1262                                 }
1263                         }
1264                         if ((memberType & MemberTypes.Property) != 0) {
1265                                 PropertyInfo[] c = GetProperties (bindingAttr);
1266
1267
1268                                 if (filter != null) {
1269                                         foreach (MemberInfo m in c) {
1270                                                 if (filter (m, filterCriteria))
1271                                                         l.Add (m);
1272                                         }
1273                                 } else {
1274                                         l.AddRange (c);
1275                                 }
1276
1277                         }
1278                         if ((memberType & MemberTypes.Event) != 0) {
1279                                 EventInfo[] c = GetEvents (bindingAttr);
1280                                 if (filter != null) {
1281                                         foreach (MemberInfo m in c) {
1282                                                 if (filter (m, filterCriteria))
1283                                                         l.Add (m);
1284                                         }
1285                                 } else {
1286                                         l.AddRange (c);
1287                                 }
1288                         }
1289                         if ((memberType & MemberTypes.Field) != 0) {
1290                                 FieldInfo[] c = GetFields (bindingAttr);
1291                                 if (filter != null) {
1292                                         foreach (MemberInfo m in c) {
1293                                                 if (filter (m, filterCriteria))
1294                                                         l.Add (m);
1295                                         }
1296                                 } else {
1297                                         l.AddRange (c);
1298                                 }
1299                         }
1300                         if ((memberType & MemberTypes.NestedType) != 0) {
1301                                 Type[] c = GetNestedTypes (bindingAttr);
1302                                 if (filter != null) {
1303                                         foreach (MemberInfo m in c) {
1304                                                 if (filter (m, filterCriteria)) {
1305                                                         l.Add (m);
1306                                                 }
1307                                         }
1308                                 } else {
1309                                         l.AddRange (c);
1310                                 }
1311                         }
1312
1313                         switch (memberType) {
1314                         case MemberTypes.Constructor :
1315                                 result = new ConstructorInfo [l.Count];
1316                                 break;
1317                         case MemberTypes.Event :
1318                                 result = new EventInfo [l.Count];
1319                                 break;
1320                         case MemberTypes.Field :
1321                                 result = new FieldInfo [l.Count];
1322                                 break;
1323                         case MemberTypes.Method :
1324                                 result = new MethodInfo [l.Count];
1325                                 break;
1326                         case MemberTypes.NestedType :
1327                         case MemberTypes.TypeInfo :
1328                                 result = new Type [l.Count];
1329                                 break;
1330                         case MemberTypes.Property :
1331                                 result = new PropertyInfo [l.Count];
1332                                 break;
1333                         default :
1334                                 result = new MemberInfo [l.Count];
1335                                 break;
1336                         }
1337                         l.CopyTo (result);
1338                         return result;
1339                 }
1340
1341                 [DebuggerHidden]
1342                 [DebuggerStepThrough] 
1343                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args)
1344                 {
1345                         return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
1346                 }
1347
1348                 [DebuggerHidden]
1349                 [DebuggerStepThrough] 
1350                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
1351                                             object target, object[] args, CultureInfo culture)
1352                 {
1353                         return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
1354                 }
1355
1356                 public abstract object InvokeMember (string name, BindingFlags invokeAttr,
1357                                                      Binder binder, object target, object[] args,
1358                                                      ParameterModifier[] modifiers,
1359                                                      CultureInfo culture, string[] namedParameters);
1360
1361                 public override string ToString()
1362                 {
1363                         return FullName;
1364                 }
1365
1366                 internal virtual Type InternalResolve ()
1367                 {
1368                         return UnderlyingSystemType;
1369                 }
1370
1371                 internal bool IsSystemType {
1372                         get {
1373                                 return _impl.Value != IntPtr.Zero;
1374                         }
1375                 }
1376                 
1377 #if NET_4_5
1378                 public virtual Type[] GenericTypeArguments {
1379                         get {
1380                                 return IsGenericType ? GetGenericArguments () : EmptyTypes;
1381                         }
1382                 }
1383 #endif
1384
1385                 public virtual Type[] GetGenericArguments ()
1386                 {
1387                         throw new NotSupportedException ();
1388                 }
1389
1390                 public virtual bool ContainsGenericParameters {
1391                         get { return false; }
1392                 }
1393
1394                 public virtual extern bool IsGenericTypeDefinition {
1395                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1396                         get;
1397                 }
1398
1399                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1400                 internal extern Type GetGenericTypeDefinition_impl ();
1401
1402                 public virtual Type GetGenericTypeDefinition ()
1403                 {
1404                         throw new NotSupportedException ("Derived classes must provide an implementation.");
1405                 }
1406
1407                 public virtual extern bool IsGenericType {
1408                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1409                         get;
1410                 }
1411                 
1412                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1413                 static extern Type MakeGenericType (Type gt, Type [] types);
1414
1415                 static AssemblyBuilder PeelAssemblyBuilder (Type type)
1416                 {
1417                         if (type.Assembly is AssemblyBuilder)
1418                                 return (AssemblyBuilder)type.Assembly;
1419
1420                         if (type.HasElementType)
1421                                 return PeelAssemblyBuilder (type.GetElementType ());
1422
1423                         if (!type.IsGenericType || type.IsGenericParameter || type.IsGenericTypeDefinition)
1424                                 return null;
1425
1426                         foreach (Type arg in type.GetGenericArguments ()) {
1427                                 AssemblyBuilder ab = PeelAssemblyBuilder (arg);
1428                                 if (ab != null)
1429                                         return ab;
1430                         }
1431                         return null;
1432                 }
1433
1434                 public virtual Type MakeGenericType (params Type[] typeArguments)
1435                 {
1436                         if (IsUserType)
1437                                 throw new NotSupportedException ();
1438                         if (!IsGenericTypeDefinition)
1439                                 throw new InvalidOperationException ("not a generic type definition");
1440                         if (typeArguments == null)
1441                                 throw new ArgumentNullException ("typeArguments");
1442                         if (GetGenericArguments().Length != typeArguments.Length)
1443                                 throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", GetGenericArguments ().Length, typeArguments.Length), "typeArguments");
1444
1445                         bool hasUserType = false;
1446
1447                         Type[] systemTypes = new Type[typeArguments.Length];
1448                         for (int i = 0; i < typeArguments.Length; ++i) {
1449                                 Type t = typeArguments [i];
1450                                 if (t == null)
1451                                         throw new ArgumentNullException ("typeArguments");
1452
1453                                 if (!(t is MonoType))
1454                                         hasUserType = true;
1455                                 systemTypes [i] = t;
1456                         }
1457
1458                         if (hasUserType) {
1459                                 return new MonoGenericClass (this, typeArguments);
1460                         }
1461
1462                         Type res = MakeGenericType (this, systemTypes);
1463                         if (res == null)
1464                                 throw new TypeLoadException ();
1465                         return res;
1466                 }
1467
1468                 public virtual bool IsGenericParameter {
1469                         get {
1470                                 return false;
1471                         }
1472                 }
1473
1474                 public bool IsNested {
1475                         get {
1476                                 return DeclaringType != null;
1477                         }
1478                 }
1479
1480                 public bool IsVisible {
1481                         get {
1482                                 if (IsNestedPublic)
1483                                         return DeclaringType.IsVisible;
1484
1485                                 return IsPublic;
1486                         }
1487                 }
1488
1489                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1490                 extern int GetGenericParameterPosition ();
1491                 
1492                 public virtual int GenericParameterPosition {
1493                         get {
1494                                 int res = GetGenericParameterPosition ();
1495                                 if (res < 0)
1496                                         throw new InvalidOperationException ();
1497                                 return res;
1498                         }
1499                 }
1500
1501                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1502                 extern GenericParameterAttributes GetGenericParameterAttributes ();
1503
1504                 public virtual GenericParameterAttributes GenericParameterAttributes {
1505                         get {
1506                                 if (!IsSystemType)
1507                                         throw new NotSupportedException ("Derived classes must provide an implementation.");
1508
1509                                 if (!IsGenericParameter)
1510                                         throw new InvalidOperationException ();
1511
1512                                 return GetGenericParameterAttributes ();
1513                         }
1514                 }
1515
1516                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1517                 extern Type[] GetGenericParameterConstraints_impl ();
1518
1519                 public virtual Type[] GetGenericParameterConstraints ()
1520                 {
1521                         if (!IsSystemType)
1522                                 throw new InvalidOperationException ();
1523
1524                         if (!IsGenericParameter)
1525                                 throw new InvalidOperationException ();
1526
1527                         return GetGenericParameterConstraints_impl ();
1528                 }
1529
1530                 public virtual MethodBase DeclaringMethod {
1531                         get {
1532                                 return null;
1533                         }
1534                 }
1535
1536                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1537                 extern Type make_array_type (int rank);
1538
1539                 public virtual Type MakeArrayType ()
1540                 {
1541                         if (!IsSystemType)
1542                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1543                         return make_array_type (0);
1544                 }
1545
1546                 public virtual Type MakeArrayType (int rank)
1547                 {
1548                         if (!IsSystemType)
1549                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1550                         if (rank < 1 || rank > 255)
1551                                 throw new IndexOutOfRangeException ();
1552                         return make_array_type (rank);
1553                 }
1554
1555                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1556                 extern Type make_byref_type ();
1557
1558                 public virtual Type MakeByRefType ()
1559                 {
1560                         if (!IsSystemType)
1561                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1562                         if (IsByRef)
1563                                 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
1564                         return make_byref_type ();
1565                 }
1566
1567                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1568                 static extern Type MakePointerType (Type type);
1569
1570                 public virtual Type MakePointerType ()
1571                 {
1572                         if (!IsSystemType)
1573                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1574                         return MakePointerType (this);
1575                 }
1576
1577                 public static Type ReflectionOnlyGetType (string typeName, 
1578                                                           bool throwIfNotFound, 
1579                                                           bool ignoreCase)
1580                 {
1581                         if (typeName == null)
1582                                 throw new ArgumentNullException ("typeName");
1583                         int idx = typeName.IndexOf (',');
1584                         if (idx < 0 || idx == 0 || idx == typeName.Length - 1)
1585                                 throw new ArgumentException ("Assembly qualifed type name is required", "typeName");
1586                         string an = typeName.Substring (idx + 1);
1587                         Assembly a;
1588                         try {
1589                                 a = Assembly.ReflectionOnlyLoad (an);
1590                         } catch {
1591                                 if (throwIfNotFound)
1592                                         throw;
1593                                 return null;
1594                         }
1595                         return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase);
1596                 }
1597
1598                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1599                 extern void GetPacking (out int packing, out int size);         
1600
1601                 public virtual StructLayoutAttribute StructLayoutAttribute {
1602                         get {
1603 #if NET_4_0
1604                                 throw new NotSupportedException ();
1605 #else
1606                                 return GetStructLayoutAttribute ();
1607 #endif
1608                         }
1609                 }
1610                 
1611                 internal StructLayoutAttribute GetStructLayoutAttribute ()
1612                 {
1613                         LayoutKind kind;
1614
1615                         if (IsLayoutSequential)
1616                                 kind = LayoutKind.Sequential;
1617                         else if (IsExplicitLayout)
1618                                 kind = LayoutKind.Explicit;
1619                         else
1620                                 kind = LayoutKind.Auto;
1621
1622                         StructLayoutAttribute attr = new StructLayoutAttribute (kind);
1623
1624                         if (IsUnicodeClass)
1625                                 attr.CharSet = CharSet.Unicode;
1626                         else if (IsAnsiClass)
1627                                 attr.CharSet = CharSet.Ansi;
1628                         else
1629                                 attr.CharSet = CharSet.Auto;
1630
1631                         if (kind != LayoutKind.Auto) {
1632                                 int packing;
1633                                 GetPacking (out packing, out attr.Size);
1634                                 // 0 means no data provided, we end up with default value
1635                                 if (packing != 0)
1636                                         attr.Pack = packing;
1637                         }
1638
1639                         return attr;
1640                 }
1641
1642                 internal object[] GetPseudoCustomAttributes ()
1643                 {
1644                         int count = 0;
1645
1646                         /* IsSerializable returns true for delegates/enums as well */
1647                         if ((Attributes & TypeAttributes.Serializable) != 0)
1648                                 count ++;
1649                         if ((Attributes & TypeAttributes.Import) != 0)
1650                                 count ++;
1651
1652                         if (count == 0)
1653                                 return null;
1654                         object[] attrs = new object [count];
1655                         count = 0;
1656
1657                         if ((Attributes & TypeAttributes.Serializable) != 0)
1658                                 attrs [count ++] = new SerializableAttribute ();
1659                         if ((Attributes & TypeAttributes.Import) != 0)
1660                                 attrs [count ++] = new ComImportAttribute ();
1661
1662                         return attrs;
1663                 }                       
1664
1665
1666 #if NET_4_0
1667                 public virtual bool IsEquivalentTo (Type other)
1668                 {
1669                         return this == other;
1670                 }
1671 #endif
1672
1673                 /* 
1674                  * Return whenever this object is an instance of a user defined subclass
1675                  * of System.Type or an instance of TypeDelegator.
1676                  */
1677                 internal bool IsUserType {
1678                         get {
1679                                 /* 
1680                                  * subclasses cannot modify _impl so if it is zero, it means the
1681                                  * type is not created by the runtime.
1682                                  */
1683                                 return _impl.Value == IntPtr.Zero &&
1684                                         (GetType ().Assembly != typeof (Type).Assembly || GetType () == typeof (TypeDelegator));
1685                         }
1686                 }
1687
1688                 void _Type.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1689                 {
1690                         throw new NotImplementedException ();
1691                 }
1692
1693                 void _Type.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1694                 {
1695                         throw new NotImplementedException ();
1696                 }
1697
1698                 void _Type.GetTypeInfoCount (out uint pcTInfo)
1699                 {
1700                         throw new NotImplementedException ();
1701                 }
1702
1703                 void _Type.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1704                 {
1705                         throw new NotImplementedException ();
1706                 }
1707         }
1708 }