Merge branch 'master' of github.com:mono/mono
[mono.git] / mcs / class / System / System.ComponentModel / TypeDescriptor.cs
1 //
2 // System.ComponentModel.TypeDescriptor.cs
3 //
4 // Authors:
5 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //   Ivan N. Zlatev (contact@i-nz.net)
8 // 
9 //
10 // (C) 2002 Ximian, Inc (http://www.ximian.com)
11 // (C) 2003 Andreas Nahr
12 // (C) 2008 Novell, Inc (http://www.novell.com)
13 //
14
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System.Collections;
37 using System.Reflection;
38 using System.Globalization;
39 using System.ComponentModel.Design;
40 using System.Security.Permissions;
41
42 using System.Collections.Generic;
43
44 namespace System.ComponentModel
45 {
46
47 public sealed class TypeDescriptor
48 {
49         private static readonly object creatingDefaultConverters = new object ();
50         private static ArrayList defaultConverters;
51         private static IComNativeDescriptorHandler descriptorHandler;
52         private static Hashtable componentTable = new Hashtable ();
53         private static Hashtable typeTable = new Hashtable ();
54         private static Hashtable editors;
55
56         static object typeDescriptionProvidersLock = new object ();
57         static Dictionary <Type, LinkedList <TypeDescriptionProvider>> typeDescriptionProviders;
58
59         static object componentDescriptionProvidersLock = new object ();
60         static Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> componentDescriptionProviders;
61
62         static TypeDescriptor ()
63         {
64                 typeDescriptionProviders = new Dictionary <Type, LinkedList <TypeDescriptionProvider>> ();
65                 componentDescriptionProviders = new Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> (new WeakObjectWrapperComparer ());
66         }
67
68         private TypeDescriptor ()
69         {
70         }
71
72         [MonoNotSupported ("Mono does not support COM")]
73         [EditorBrowsable (EditorBrowsableState.Advanced)]
74         public static Type ComObjectType {
75                 get { throw new NotImplementedException (); }
76         }
77
78 #if NET_4_0
79         [EditorBrowsable (EditorBrowsableState.Advanced)]
80         public static Type InterfaceType {
81                 get {
82                         return typeof (TypeDescriptorInterface);
83                 }
84         }
85 #endif
86
87         [EditorBrowsable (EditorBrowsableState.Advanced)]
88         public static TypeDescriptionProvider AddAttributes (object instance, params Attribute [] attributes)
89         {
90                 if (instance == null)
91                         throw new ArgumentNullException ("instance");
92                 if (attributes == null)
93                         throw new ArgumentNullException ("attributes");
94
95                 var ret = new AttributeProvider (attributes, GetProvider (instance));
96                 AddProvider (ret, instance);
97
98                 return ret;
99         }
100
101         [EditorBrowsable (EditorBrowsableState.Advanced)]
102         public static TypeDescriptionProvider AddAttributes (Type type, params Attribute [] attributes)
103         {
104                 if (type == null)
105                         throw new ArgumentNullException ("type");
106                 if (attributes == null)
107                         throw new ArgumentNullException ("attributes");
108
109                 var ret = new AttributeProvider (attributes, GetProvider (type));
110                 AddProvider (ret, type);
111                 
112                 return ret;
113         }
114         
115         [EditorBrowsable (EditorBrowsableState.Advanced)]
116         public static void AddProvider (TypeDescriptionProvider provider, object instance)
117         {
118                 if (provider == null)
119                         throw new ArgumentNullException ("provider");
120                 if (instance == null)
121                         throw new ArgumentNullException ("instance");
122
123                 lock (componentDescriptionProvidersLock) {
124                         LinkedList <TypeDescriptionProvider> plist;
125                         WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
126                         
127                         if (!componentDescriptionProviders.TryGetValue (instanceWrapper, out plist)) {
128                                 plist = new LinkedList <TypeDescriptionProvider> ();
129                                 componentDescriptionProviders.Add (new WeakObjectWrapper (instance), plist);
130                         }
131
132                         plist.AddLast (provider);
133                         instanceWrapper = null;
134                         Refresh (instance);
135                 }
136         }
137
138         [EditorBrowsable (EditorBrowsableState.Advanced)]
139         public static void AddProvider (TypeDescriptionProvider provider, Type type)
140         {
141                 if (provider == null)
142                         throw new ArgumentNullException ("provider");
143                 if (type == null)
144                         throw new ArgumentNullException ("type");
145
146                 lock (typeDescriptionProvidersLock) {
147                         LinkedList <TypeDescriptionProvider> plist;
148
149                         if (!typeDescriptionProviders.TryGetValue (type, out plist)) {
150                                 plist = new LinkedList <TypeDescriptionProvider> ();
151                                 typeDescriptionProviders.Add (type, plist);
152                         }
153
154                         plist.AddLast (provider);
155                         Refresh (type);
156                 }
157         }
158
159         [MonoTODO]
160         public static object CreateInstance (IServiceProvider provider, Type objectType, Type [] argTypes, object [] args)
161         {
162                 if (objectType == null)
163                         throw new ArgumentNullException ("objectType");
164
165                 object instance = null;
166
167                 if (provider != null) {
168                         TypeDescriptionProvider typeDescrProvider = provider.GetService (typeof (TypeDescriptionProvider)) as TypeDescriptionProvider;
169                         if (typeDescrProvider != null)
170                                 instance = typeDescrProvider.CreateInstance (provider, objectType, argTypes, args);
171                 }
172
173                 // TODO: also search and use the internal providers table once Add/RemoveProvider have been implemented
174
175                 if (instance == null)
176                         instance = Activator.CreateInstance (objectType, args);
177
178                 return instance;
179         }
180
181         [EditorBrowsable (EditorBrowsableState.Advanced)]
182 #if !NET_2_1
183         public
184 #else
185         internal
186 #endif
187         static void AddEditorTable (Type editorBaseType, Hashtable table)
188         {
189                 if (editorBaseType == null)
190                         throw new ArgumentNullException ("editorBaseType");
191
192                 if (editors == null)
193                         editors = new Hashtable ();
194
195                 if (!editors.ContainsKey (editorBaseType))
196                         editors [editorBaseType] = table;
197         }
198
199         public static IDesigner CreateDesigner(IComponent component, Type designerBaseType)
200         {
201                 string tn = designerBaseType.AssemblyQualifiedName;
202                 AttributeCollection col = GetAttributes (component);
203                 
204                 foreach (Attribute at in col) {
205                         DesignerAttribute dat = at as DesignerAttribute;
206                         if (dat != null && tn == dat.DesignerBaseTypeName) {
207                                 Type designerType = GetTypeFromName (component, dat.DesignerTypeName);
208                                 if (designerType != null)
209                                         return (IDesigner) Activator.CreateInstance (designerType);
210                         }
211                 }
212                                 
213                 return null;
214         }
215
216         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
217         public static EventDescriptor CreateEvent (Type componentType,
218                                                    string name,
219                                                    Type type,
220                                                    params Attribute [] attributes)
221         {
222                 return new ReflectionEventDescriptor (componentType, name, type, attributes);
223         }
224
225         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
226         public static EventDescriptor CreateEvent (Type componentType,
227                                                    EventDescriptor oldEventDescriptor,
228                                                    params Attribute [] attributes)
229         {
230                 return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes);
231         }
232
233         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
234         public static PropertyDescriptor CreateProperty (Type componentType,
235                                                          string name,
236                                                          Type type,
237                                                          params Attribute [] attributes)
238         {
239                 return new ReflectionPropertyDescriptor (componentType, name, type, attributes);
240         }
241
242         [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
243         public static PropertyDescriptor CreateProperty (Type componentType,
244                                                          PropertyDescriptor oldPropertyDescriptor,
245                                                          params Attribute [] attributes)
246         {
247                 return new ReflectionPropertyDescriptor (componentType, oldPropertyDescriptor, attributes);
248         }
249
250         public static AttributeCollection GetAttributes (Type componentType)
251         {
252                 if (componentType == null)
253                         return AttributeCollection.Empty;
254
255                 return GetTypeInfo (componentType).GetAttributes ();
256         }
257
258         public static AttributeCollection GetAttributes (object component)
259         {
260                 return GetAttributes (component, false);
261         }
262
263         [EditorBrowsable (EditorBrowsableState.Advanced)]
264         public static AttributeCollection GetAttributes (object component, bool noCustomTypeDesc)
265         {
266                 if (component == null)
267                         return AttributeCollection.Empty;
268
269                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
270                         return ((ICustomTypeDescriptor) component).GetAttributes ();
271                 } else {
272                         IComponent com = component as IComponent;
273                         if (com != null && com.Site != null)
274                                 return GetComponentInfo (com).GetAttributes ();
275                         else
276                                 return GetTypeInfo (component.GetType()).GetAttributes ();
277                 }
278         }
279
280         public static string GetClassName (object component)
281         {
282                 return GetClassName (component, false);
283         }
284
285         [EditorBrowsable (EditorBrowsableState.Advanced)]
286         public static string GetClassName (object component, bool noCustomTypeDesc)
287         {
288                 if (component == null)
289                         throw new ArgumentNullException ("component", "component cannot be null");
290
291                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
292                         String res = ((ICustomTypeDescriptor) component).GetClassName ();
293                         if (res == null)
294                                 res = ((ICustomTypeDescriptor) component).GetComponentName ();
295                         if (res == null)
296                                 res = component.GetType ().FullName;
297                         return res;
298                 } else {
299                         return component.GetType ().FullName;
300                 }
301         }
302
303         public static string GetComponentName (object component)
304         {
305                 return GetComponentName (component, false);
306         }
307
308         [EditorBrowsable (EditorBrowsableState.Advanced)]
309         public static string GetComponentName (object component, bool noCustomTypeDesc)
310         {
311                 if (component == null)
312                         throw new ArgumentNullException ("component", "component cannot be null");
313
314                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
315                         return ((ICustomTypeDescriptor) component).GetComponentName ();
316                 } else {
317                         IComponent c = component as IComponent;
318                         if (c != null && c.Site != null)
319                                 return c.Site.Name;
320                         return null;
321                 }
322         }
323
324         [MonoNotSupported("")]
325         public static string GetFullComponentName (object component)
326         {
327                 throw new NotImplementedException ();
328         }
329
330         [MonoNotSupported("")]
331         public static string GetClassName (Type componentType)
332         {
333                 throw new NotImplementedException ();
334         }
335
336         public static TypeConverter GetConverter (object component)
337         {
338                 return GetConverter (component, false);
339         }
340
341         [EditorBrowsable (EditorBrowsableState.Advanced)]
342         public static TypeConverter GetConverter (object component, bool noCustomTypeDesc)
343         {
344                 if (component == null)
345                         throw new ArgumentNullException ("component", "component cannot be null");
346
347                 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
348                         return ((ICustomTypeDescriptor) component).GetConverter ();
349                 } 
350                 else {
351                         Type converterType = null;
352                         AttributeCollection atts = GetAttributes (component, false);
353                         TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
354                         if (tca != null && tca.ConverterTypeName.Length > 0)
355                                 converterType = GetTypeFromName (component as IComponent, tca.ConverterTypeName);
356                         if (converterType == null)
357                                 converterType = FindDefaultConverterType (component.GetType ());
358                         
359                         if (converterType != null) {
360                                 ConstructorInfo ci = converterType.GetConstructor (new Type[] { typeof(Type) });
361                                 if (ci != null)
362                                         return (TypeConverter) ci.Invoke (new object[] { component.GetType () });
363                                 else
364                                         return (TypeConverter) Activator.CreateInstance (converterType);
365                         } else
366                                 return null;
367                 }
368         }
369
370         private static ArrayList DefaultConverters
371         {
372                 get {
373                         lock (creatingDefaultConverters) {
374                                 if (defaultConverters != null)
375                                         return defaultConverters;
376                                 
377                                 defaultConverters = new ArrayList ();
378                                 defaultConverters.Add (new DictionaryEntry (typeof (bool), typeof (BooleanConverter)));
379                                 defaultConverters.Add (new DictionaryEntry (typeof (byte), typeof (ByteConverter)));
380                                 defaultConverters.Add (new DictionaryEntry (typeof (sbyte), typeof (SByteConverter)));
381                                 defaultConverters.Add (new DictionaryEntry (typeof (string), typeof (StringConverter)));
382                                 defaultConverters.Add (new DictionaryEntry (typeof (char), typeof (CharConverter)));
383                                 defaultConverters.Add (new DictionaryEntry (typeof (short), typeof (Int16Converter)));
384                                 defaultConverters.Add (new DictionaryEntry (typeof (int), typeof (Int32Converter)));
385                                 defaultConverters.Add (new DictionaryEntry (typeof (long), typeof (Int64Converter)));
386                                 defaultConverters.Add (new DictionaryEntry (typeof (ushort), typeof (UInt16Converter)));
387                                 defaultConverters.Add (new DictionaryEntry (typeof (uint), typeof (UInt32Converter)));
388                                 defaultConverters.Add (new DictionaryEntry (typeof (ulong), typeof (UInt64Converter)));
389                                 defaultConverters.Add (new DictionaryEntry (typeof (float), typeof (SingleConverter)));
390                                 defaultConverters.Add (new DictionaryEntry (typeof (double), typeof (DoubleConverter)));
391                                 defaultConverters.Add (new DictionaryEntry (typeof (decimal), typeof (DecimalConverter)));
392                                 defaultConverters.Add (new DictionaryEntry (typeof (void), typeof (TypeConverter)));
393                                 defaultConverters.Add (new DictionaryEntry (typeof (Array), typeof (ArrayConverter)));
394                                 defaultConverters.Add (new DictionaryEntry (typeof (CultureInfo), typeof (CultureInfoConverter)));
395                                 defaultConverters.Add (new DictionaryEntry (typeof (DateTime), typeof (DateTimeConverter)));
396                                 defaultConverters.Add (new DictionaryEntry (typeof (Guid), typeof (GuidConverter)));
397                                 defaultConverters.Add (new DictionaryEntry (typeof (TimeSpan), typeof (TimeSpanConverter)));
398                                 defaultConverters.Add (new DictionaryEntry (typeof (ICollection), typeof (CollectionConverter)));
399                                 defaultConverters.Add (new DictionaryEntry (typeof (Enum), typeof (EnumConverter)));
400                         }
401                         return defaultConverters;
402                 }
403         }
404         
405         public static TypeConverter GetConverter (Type type)
406         {
407                 if (type == null)
408                         throw new ArgumentNullException ("type");
409                 
410                 Type converterType = null;
411                 AttributeCollection atts = GetAttributes (type);
412                 TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
413                 if (tca != null && tca.ConverterTypeName.Length > 0)
414                         converterType = GetTypeFromName (null, tca.ConverterTypeName);
415                 if (converterType == null)
416                         converterType = FindDefaultConverterType (type);
417
418                 if (converterType != null) {
419                         ConstructorInfo ci = converterType.GetConstructor (new Type[] { typeof(Type) });
420                         if (ci != null)
421                                 return (TypeConverter) ci.Invoke (new object[] { type });
422                         else
423                                 return (TypeConverter) Activator.CreateInstance (converterType);
424                 }
425                 else
426                         return null;
427         }
428
429         private static Type FindDefaultConverterType (Type type)
430         {
431                 Type converterType = null;
432                 if (type != null) {
433                         if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
434                                 return typeof(NullableConverter);
435                         // Is there a default converter
436                         foreach (DictionaryEntry entry in DefaultConverters) {
437                                 if ((Type)entry.Key == type)
438                                         return (Type)entry.Value;
439                         }
440                 }
441                 
442                 // Find default converter with a baseType this baseType is assignable to
443                 Type baseType = type;
444                 while (baseType != null && baseType != typeof (object)) {
445                         foreach (DictionaryEntry entry in DefaultConverters) {
446                                 Type defType = (Type)entry.Key;
447                                 if (defType.IsAssignableFrom (baseType)) {
448                                         converterType = (Type)entry.Value;
449                                         break;
450                                 }
451                         }
452                         baseType = baseType.BaseType;
453                 }
454
455                 if (converterType == null) {
456                         if (type != null && type.IsInterface)
457                                 converterType = typeof (ReferenceConverter);
458                         else
459                                 converterType = typeof (TypeConverter);
460                 }
461
462                 return converterType;
463         }
464
465         public static EventDescriptor GetDefaultEvent (Type componentType)
466         {
467                 return GetTypeInfo (componentType).GetDefaultEvent ();
468         }
469
470         public static EventDescriptor GetDefaultEvent (object component)
471         {
472                 return GetDefaultEvent (component, false);
473         }
474
475         [EditorBrowsable (EditorBrowsableState.Advanced)]
476         public static EventDescriptor GetDefaultEvent (object component, bool noCustomTypeDesc)
477         {
478                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
479                         return ((ICustomTypeDescriptor) component).GetDefaultEvent ();
480                 else {
481                         IComponent com = component as IComponent;
482                         if (com != null && com.Site != null)
483                                 return GetComponentInfo (com).GetDefaultEvent ();
484                         else
485                                 return GetTypeInfo (component.GetType()).GetDefaultEvent ();
486                 }
487         }
488
489         public static PropertyDescriptor GetDefaultProperty (Type componentType)
490         {
491                 return GetTypeInfo (componentType).GetDefaultProperty ();
492         }
493
494         public static PropertyDescriptor GetDefaultProperty (object component)
495         {
496                 return GetDefaultProperty (component, false);
497         }
498
499         [EditorBrowsable (EditorBrowsableState.Advanced)]
500         public static PropertyDescriptor GetDefaultProperty (object component, bool noCustomTypeDesc)
501         {
502                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
503                         return ((ICustomTypeDescriptor) component).GetDefaultProperty ();
504                 else {
505                         IComponent com = component as IComponent;
506                         if (com != null && com.Site != null)
507                                 return GetComponentInfo (com).GetDefaultProperty ();
508                         else
509                                 return GetTypeInfo (component.GetType()).GetDefaultProperty ();
510                 }
511         }
512                 
513         internal static object CreateEditor (Type t, Type componentType)
514         {
515                 if (t == null) 
516                         return null;
517
518                 try {
519                         return Activator.CreateInstance (t);
520                 } catch {}
521
522                 try {
523                         return Activator.CreateInstance (t, new object [] {componentType});
524                 } catch {}
525
526                 return null;
527         }
528                 
529         private static object FindEditorInTable (Type componentType, Type editorBaseType, Hashtable table)
530         {
531                 object editorReference = null;
532                 object editor = null;
533                 
534                 if (componentType == null || editorBaseType == null || table == null)
535                         return null;
536                         
537                 Type ct = componentType;
538                 while (ct != null) {                                            
539                         editorReference = table [ct];
540                         if (editorReference != null)
541                                 break;                  
542                         ct = ct.BaseType;
543                 }
544                 
545                 if (editorReference == null) {
546                         foreach (Type iface in componentType.GetInterfaces ()) {
547                                 editorReference = table [iface];
548                                 if (editorReference != null) 
549                                         break;
550                         }
551                 }
552                                 
553                 if (editorReference == null)
554                         return null;
555                                 
556                 if (editorReference is string)
557                         editor = CreateEditor (Type.GetType ((string) editorReference), componentType);
558                 else if (editorReference is Type)
559                         editor = CreateEditor ((Type) editorReference, componentType);
560                 else if (editorReference.GetType ().IsSubclassOf (editorBaseType))
561                         editor = editorReference;
562                 
563                 if (editor != null) 
564                         table [componentType] = editor;
565                 
566                 return editor;
567         }
568
569         public static object GetEditor (Type componentType, Type editorBaseType)
570         {
571                 Type editorType = null;
572                 object editor = null;
573                 object [] atts = componentType.GetCustomAttributes (typeof(EditorAttribute), true);
574                 
575                 if (atts != null && atts.Length != 0) {
576                         foreach (EditorAttribute ea in atts) {
577                                 editorType = GetTypeFromName (null, ea.EditorTypeName);
578                                 if (editorType != null && editorType.IsSubclassOf(editorBaseType))
579                                         break;
580                         }
581                 }
582                 
583                 if (editorType != null)
584                         editor = CreateEditor (editorType, componentType);
585                         
586                 if (editorType == null || editor == null) {
587 #if !TARGET_JVM
588                         // Make sure the editorBaseType's static constructor has been called,
589                         // since that's where we're putting the initialization of its editor table.
590                         
591                         System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (editorBaseType.TypeHandle);
592 #endif                          
593                         if (editors != null)
594                                 editor = FindEditorInTable (componentType, editorBaseType, editors [editorBaseType] as Hashtable);
595                 }
596
597                 return editor;
598         }
599
600         public static object GetEditor (object component, Type editorBaseType)
601         {
602                 return GetEditor (component, editorBaseType, false);
603         }
604
605         [EditorBrowsable (EditorBrowsableState.Advanced)]
606         public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
607         {
608                 if (component == null)
609                         throw new ArgumentNullException ("component");
610                 if (editorBaseType == null)
611                         throw new ArgumentNullException ("editorBaseType");
612                 
613                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
614                         return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
615
616                 object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
617                 if (atts.Length == 0)
618                         return null;
619                 string target = editorBaseType.AssemblyQualifiedName;
620                 
621                 foreach (EditorAttribute ea in atts){
622                         if (ea.EditorBaseTypeName == target){
623                                 Type t = Type.GetType (ea.EditorTypeName, true);
624
625                                 return Activator.CreateInstance (t);
626                         }
627                 }
628                 return null;
629         }
630
631         public static EventDescriptorCollection GetEvents (object component)
632         {
633                 return GetEvents (component, false);
634         }
635
636         public static EventDescriptorCollection GetEvents (Type componentType)
637         {
638                 return GetEvents (componentType, null);
639         }
640
641         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
642         {
643                 return GetEvents (component, attributes, false);
644         }
645
646         [EditorBrowsable (EditorBrowsableState.Advanced)]
647         public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
648         {
649                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
650                         return ((ICustomTypeDescriptor) component).GetEvents ();
651                 else {
652                         IComponent com = component as IComponent;
653                         if (com != null && com.Site != null)
654                                 return GetComponentInfo (com).GetEvents ();
655                         else
656                                 return GetTypeInfo (component.GetType()).GetEvents ();
657                 }
658         }
659
660         public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
661         {
662                 return GetTypeInfo (componentType).GetEvents (attributes);
663         }
664
665         [EditorBrowsable (EditorBrowsableState.Advanced)]
666         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
667         {
668                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
669                         return ((ICustomTypeDescriptor) component).GetEvents (attributes);
670                 else {
671                         IComponent com = component as IComponent;
672                         if (com != null && com.Site != null)
673                                 return GetComponentInfo (com).GetEvents (attributes);
674                         else
675                                 return GetTypeInfo (component.GetType()).GetEvents (attributes);
676                 }
677         }
678
679         public static PropertyDescriptorCollection GetProperties (object component)
680         {
681                 return GetProperties (component, false);
682         }
683
684         public static PropertyDescriptorCollection GetProperties (Type componentType)
685         {
686                 return GetProperties (componentType, null);
687         }
688
689         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
690         {
691                 return GetProperties (component, attributes, false);
692         }
693
694         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
695         {
696                 if (component == null)
697                         return PropertyDescriptorCollection.Empty;
698
699                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
700                         return ((ICustomTypeDescriptor) component).GetProperties (attributes);
701                 else {
702                         IComponent com = component as IComponent;
703                         if (com != null && com.Site != null)
704                                 return GetComponentInfo (com).GetProperties (attributes);
705                         else
706                                 return GetTypeInfo (component.GetType()).GetProperties (attributes);
707                 }
708         }
709
710         [EditorBrowsable (EditorBrowsableState.Advanced)]
711         public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
712         {
713                 if (component == null)
714                         return PropertyDescriptorCollection.Empty;
715
716                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
717                         return ((ICustomTypeDescriptor) component).GetProperties ();
718                 else {
719                         IComponent com = component as IComponent;
720                         if (com != null && com.Site != null)
721                                 return GetComponentInfo (com).GetProperties ();
722                         else
723                                 return GetTypeInfo (component.GetType()).GetProperties ();
724                 }
725         }
726
727         public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
728         {
729                 return GetTypeInfo (componentType).GetProperties (attributes);
730         }
731
732         [EditorBrowsable (EditorBrowsableState.Advanced)]
733         public static TypeDescriptionProvider GetProvider (object instance)
734         {
735                 if (instance == null)
736                         throw new ArgumentNullException ("instance");
737
738                 TypeDescriptionProvider ret = null;
739                 lock (componentDescriptionProvidersLock) {
740                         LinkedList <TypeDescriptionProvider> plist;
741                         WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
742                         
743                         if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0)
744                                 ret = plist.Last.Value;
745                         
746                         instanceWrapper = null;
747                 }
748
749                 if (ret == null)
750                         ret = GetProvider (instance.GetType ());
751
752                 if (ret == null)
753                         return new DefaultTypeDescriptionProvider ();
754                 else
755                         return new WrappedTypeDescriptionProvider (ret);
756         }
757
758         [EditorBrowsable (EditorBrowsableState.Advanced)]
759         public static TypeDescriptionProvider GetProvider (Type type)
760         {
761                 if (type == null)
762                         throw new ArgumentNullException ("type");
763                 
764                 TypeDescriptionProvider ret = null;
765                 lock (typeDescriptionProvidersLock) {
766                         LinkedList <TypeDescriptionProvider> plist;
767                         
768                         while (!typeDescriptionProviders.TryGetValue (type, out plist)) {
769                                 plist = null;
770                                 type = type.BaseType;
771                                 if (type == null)
772                                         break;
773                         }
774
775                         if (plist != null && plist.Count > 0)
776                                 ret = plist.Last.Value;
777                 }
778
779                 if (ret == null)
780                         return new DefaultTypeDescriptionProvider ();
781                 else
782                         return new WrappedTypeDescriptionProvider (ret);
783         }
784
785         [EditorBrowsable (EditorBrowsableState.Advanced)]
786         public static Type GetReflectionType (object instance)
787         {
788                 if (instance == null)
789                         throw new ArgumentNullException ("instance");
790                 
791                 return instance.GetType ();
792         }
793
794         [EditorBrowsable (EditorBrowsableState.Advanced)]
795         public static Type GetReflectionType (Type type)
796         {
797                 if (type == null)
798                         throw new ArgumentNullException ("type");
799                 
800                 return type;
801         }
802
803         [MonoNotSupported("Associations not supported")]
804         [EditorBrowsable (EditorBrowsableState.Advanced)]
805         public static void CreateAssociation (object primary, object secondary)
806         {
807                 throw new NotImplementedException ();
808         }
809
810         [MonoNotSupported ("Associations not supported")]
811         [EditorBrowsable (EditorBrowsableState.Advanced)]
812         public static object GetAssociation (Type type, object primary)
813         {
814                 throw new NotImplementedException ();
815         }
816
817         [MonoNotSupported ("Associations not supported")]
818         [EditorBrowsable (EditorBrowsableState.Advanced)]
819         public static void RemoveAssociation (object primary, object secondary)
820         {
821                 throw new NotImplementedException ();
822         }
823
824         [MonoNotSupported ("Associations not supported")]
825         [EditorBrowsable (EditorBrowsableState.Advanced)]
826         public static void RemoveAssociations (object primary)
827         {
828                 throw new NotImplementedException ();
829         }
830
831         [EditorBrowsable (EditorBrowsableState.Advanced)]
832         public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
833         {
834                 if (provider == null)
835                         throw new ArgumentNullException ("provider");
836                 if (instance == null)
837                         throw new ArgumentNullException ("instance");
838
839                 //bool removed = false;
840                 lock (componentDescriptionProvidersLock) {
841                         LinkedList <TypeDescriptionProvider> plist;
842                         WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
843
844                         if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) {
845                                 RemoveProvider (provider, plist);
846                                 //removed = true;
847                         }
848                         
849                         instanceWrapper = null;
850                 }
851
852                 var refreshed = Refreshed;
853                 if (refreshed != null)
854                         refreshed (new RefreshEventArgs (instance));
855         }
856
857         [EditorBrowsable (EditorBrowsableState.Advanced)]
858         public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
859         {
860                 if (provider == null)
861                         throw new ArgumentNullException ("provider");
862                 if (type == null)
863                         throw new ArgumentNullException ("type");
864
865                 lock (typeDescriptionProvidersLock) {
866                         LinkedList <TypeDescriptionProvider> plist;
867
868                         if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) {
869                                 RemoveProvider (provider, plist);
870                         }
871                 }
872
873                 var refreshed = Refreshed;
874                 if (refreshed != null)
875                         refreshed (new RefreshEventArgs (type));
876         }
877
878         static void RemoveProvider (TypeDescriptionProvider provider, LinkedList <TypeDescriptionProvider> plist)
879         {
880                 LinkedListNode <TypeDescriptionProvider> node = plist.Last;
881                 LinkedListNode <TypeDescriptionProvider> first = plist.First;
882                 TypeDescriptionProvider p;
883                                 
884                 do {
885                         p = node.Value;
886                         if (p == provider) {
887                                 plist.Remove (node);
888                                 break;
889                         }
890                         if (node == first)
891                                 break;
892                                         
893                         node = node.Previous;
894                                         
895                 } while (true);
896         }
897
898         public static void SortDescriptorArray (IList infos)
899         {
900                 string[] names = new string [infos.Count];
901                 object[] values = new object [infos.Count];
902                 for (int n=0; n<names.Length; n++) {
903                         names[n] = ((MemberDescriptor)infos[n]).Name;
904                         values[n] = infos[n];
905                 }
906                 Array.Sort (names, values);
907                 infos.Clear();
908                 foreach (object ob in values)
909                         infos.Add (ob);
910         }
911
912         // well, ComObjectType is not implemented, but we don't support COM anyways ...
913         [Obsolete ("Use ComObjectType")]
914         public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
915                 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
916                 get { return descriptorHandler; }
917                 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
918                 set { descriptorHandler = value; }
919         }
920
921         public static void Refresh (Assembly assembly)
922         {
923                 foreach (Type type in assembly.GetTypes())
924                         Refresh (type);
925         }
926
927         public static void Refresh (Module module)
928         {
929                 foreach (Type type in module.GetTypes())
930                         Refresh (type);
931         }
932
933         public static void Refresh (object component)
934         {
935                 lock (componentTable)
936                 {
937                         componentTable.Remove (component);
938                 }
939                 if (Refreshed != null) Refreshed (new RefreshEventArgs (component));
940         }
941
942         public static void Refresh (Type type)
943         {
944                 lock (typeTable)
945                 {
946                         typeTable.Remove (type);
947                 }
948                 if (Refreshed != null) Refreshed (new RefreshEventArgs (type));
949         }
950
951         static EventHandler onDispose;
952
953         static void OnComponentDisposed (object sender, EventArgs args)
954         {
955                 lock (componentTable) {
956                         componentTable.Remove (sender);
957                 }
958         }
959
960         public static event RefreshEventHandler Refreshed;
961         
962         internal static ComponentInfo GetComponentInfo (IComponent com)
963         {
964                 lock (componentTable)
965                 {
966                         ComponentInfo ci = (ComponentInfo) componentTable [com];
967                         if (ci == null) {
968                                 if (onDispose == null)
969                                         onDispose = new EventHandler (OnComponentDisposed);
970
971                                 com.Disposed += onDispose;
972                                 ci = new ComponentInfo (com);
973                                 componentTable [com] = ci;
974                         }
975                         return ci;
976                 }
977         }
978         
979         internal static TypeInfo GetTypeInfo (Type type)
980         {
981                 lock (typeTable)
982                 {
983                         TypeInfo ci = (TypeInfo) typeTable [type];
984                         if (ci == null) {
985                                 ci = new TypeInfo (type);
986                                 typeTable [type] = ci;
987                         }
988                         return ci;
989                 }
990         }
991         
992         private static Type GetTypeFromName (IComponent component, string typeName)
993         {
994                 Type type = null;
995                 if (component != null && component.Site != null) {
996                         ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
997                         if (resver != null)
998                                 type = resver.GetType (typeName);
999                 }
1000                 if (type == null)
1001                         type = Type.GetType (typeName);
1002                 return type;
1003         }
1004
1005         sealed class AttributeProvider : TypeDescriptionProvider
1006         {
1007                 Attribute[] attributes;
1008                 
1009                 public AttributeProvider (Attribute[] attributes, TypeDescriptionProvider parent)
1010                         : base (parent)
1011                 {
1012                         this.attributes = attributes;
1013                 }
1014
1015                 public override ICustomTypeDescriptor GetTypeDescriptor (Type type, object instance)
1016                 {
1017                         return new AttributeTypeDescriptor (base.GetTypeDescriptor (type, instance), attributes);
1018                 }
1019                 
1020                 sealed class AttributeTypeDescriptor : CustomTypeDescriptor
1021                 {
1022                         Attribute[] attributes;
1023                         
1024                         public AttributeTypeDescriptor (ICustomTypeDescriptor parent, Attribute[] attributes)
1025                                 : base (parent)
1026                         {
1027                                 this.attributes = attributes;
1028                         }
1029
1030                         public override AttributeCollection GetAttributes ()
1031                         {
1032                                 AttributeCollection attrs = base.GetAttributes ();
1033
1034                                 if (attrs != null && attrs.Count > 0)
1035                                         return AttributeCollection.FromExisting (attrs, attributes);
1036                                 else
1037                                         return new AttributeCollection (attributes);
1038                         }
1039                 }
1040         }
1041
1042         sealed class WrappedTypeDescriptionProvider : TypeDescriptionProvider
1043         {
1044                 public TypeDescriptionProvider Wrapped { get; private set; }
1045                 
1046                 public WrappedTypeDescriptionProvider (TypeDescriptionProvider wrapped)
1047                 {
1048                         Wrapped = wrapped;
1049                 }
1050
1051                 public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
1052                 {
1053                         TypeDescriptionProvider wrapped = Wrapped;
1054
1055                         if (wrapped == null)
1056                                 return base.CreateInstance (provider, objectType, argTypes, args);
1057                         
1058                         return wrapped.CreateInstance (provider, objectType, argTypes, args);
1059                 }
1060
1061                 public override IDictionary GetCache (object instance)
1062                 {
1063                         TypeDescriptionProvider wrapped = Wrapped;
1064
1065                         if (wrapped == null)
1066                                 return base.GetCache (instance);
1067
1068                         return wrapped.GetCache (instance);
1069                 }
1070
1071                 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1072                 {
1073                         return new DefaultTypeDescriptor (this, null, instance);
1074                 }
1075
1076                 public override string GetFullComponentName (object component)
1077                 {
1078                         TypeDescriptionProvider wrapped = Wrapped;
1079
1080                         if (wrapped == null)
1081                                 return base.GetFullComponentName (component);
1082
1083                         return wrapped.GetFullComponentName (component);
1084                 }
1085
1086                 public override Type GetReflectionType (Type type, object instance)
1087                 {
1088                         TypeDescriptionProvider wrapped = Wrapped;
1089
1090                         if (wrapped == null)
1091                                 return base.GetReflectionType (type, instance);
1092
1093                         return wrapped.GetReflectionType (type, instance);
1094                 }
1095
1096                 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1097                 {
1098                         TypeDescriptionProvider wrapped = Wrapped;
1099
1100                         if (wrapped == null)
1101                                 return new DefaultTypeDescriptor (this, objectType, instance);
1102
1103                         return wrapped.GetTypeDescriptor (objectType, instance);
1104                 }
1105         }
1106
1107         // TODO: this needs more work
1108         sealed class DefaultTypeDescriptor : CustomTypeDescriptor
1109         {
1110                 TypeDescriptionProvider owner;
1111                 Type objectType;
1112                 object instance;
1113
1114                 public DefaultTypeDescriptor (TypeDescriptionProvider owner, Type objectType, object instance)
1115                 {
1116                         this.owner = owner;
1117                         this.objectType = objectType;
1118                         this.instance = instance;
1119                 }
1120
1121                 public override AttributeCollection GetAttributes ()
1122                 {
1123                         var wrapped = owner as WrappedTypeDescriptionProvider;
1124
1125                         if (wrapped != null)
1126                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetAttributes ();
1127
1128                         if (instance != null)
1129                                 return TypeDescriptor.GetAttributes (instance, false);
1130
1131                         if (objectType != null)
1132                                 return TypeDescriptor.GetTypeInfo (objectType).GetAttributes ();
1133                         
1134                         return base.GetAttributes ();
1135                 }
1136                 
1137                 public override string GetClassName ()
1138                 {
1139                         var wrapped = owner as WrappedTypeDescriptionProvider;
1140
1141                         if (wrapped != null)
1142                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetClassName ();
1143
1144                         return base.GetClassName ();
1145                 }
1146
1147                 public override PropertyDescriptor GetDefaultProperty ()
1148                 {
1149                         var wrapped = owner as WrappedTypeDescriptionProvider;
1150
1151                         if (wrapped != null)
1152                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetDefaultProperty ();
1153
1154                         PropertyDescriptor ret;
1155                         if (objectType != null)
1156                                 ret = TypeDescriptor.GetTypeInfo (objectType).GetDefaultProperty ();
1157                         else if (instance != null)
1158                                 ret = TypeDescriptor.GetTypeInfo (instance.GetType ()).GetDefaultProperty ();
1159                         else
1160                                 ret = base.GetDefaultProperty ();
1161
1162                         return ret;
1163                 }
1164
1165                 public override PropertyDescriptorCollection GetProperties ()
1166                 {
1167                         var wrapped = owner as WrappedTypeDescriptionProvider;
1168
1169                         if (wrapped != null)
1170                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetProperties ();
1171
1172                         if (instance != null)
1173                                 return TypeDescriptor.GetProperties (instance, null, false);
1174
1175                         if (objectType != null)
1176                                 return TypeDescriptor.GetTypeInfo (objectType).GetProperties (null);
1177
1178                         return base.GetProperties ();
1179                 }               
1180         }
1181
1182         sealed class DefaultTypeDescriptionProvider : TypeDescriptionProvider
1183         {
1184                 public DefaultTypeDescriptionProvider ()
1185                 {
1186                 }
1187
1188                 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1189                 {
1190                         return new DefaultTypeDescriptor (this, null, instance);
1191                 }
1192
1193                 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1194                 {
1195                         return new DefaultTypeDescriptor (this, objectType, instance);
1196                 }
1197         }
1198 }
1199
1200         internal abstract class Info
1201         {
1202                 Type _infoType;
1203                 EventDescriptor _defaultEvent;
1204                 bool _gotDefaultEvent;
1205                 PropertyDescriptor _defaultProperty;
1206                 bool _gotDefaultProperty;
1207                 AttributeCollection _attributes;
1208                 
1209                 public Info (Type infoType)
1210                 {
1211                         _infoType = infoType;
1212                 }
1213                 
1214                 public abstract AttributeCollection GetAttributes ();
1215                 public abstract EventDescriptorCollection GetEvents ();
1216                 public abstract PropertyDescriptorCollection GetProperties ();
1217                 
1218                 public Type InfoType
1219                 {
1220                         get { return _infoType; }
1221                 }
1222                 
1223                 public EventDescriptorCollection GetEvents (Attribute[] attributes)
1224                 {
1225                         EventDescriptorCollection evs = GetEvents ();
1226                         if (attributes == null)
1227                                 return evs;
1228                         else
1229                                 return evs.Filter (attributes);
1230                 }
1231                 
1232                 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
1233                 {
1234                         PropertyDescriptorCollection props = GetProperties ();
1235                         if (attributes == null)
1236                                 return props;
1237                         else
1238                                 return props.Filter (attributes);
1239                 }
1240                 
1241                 public EventDescriptor GetDefaultEvent ()
1242                 {
1243                         if (_gotDefaultEvent)
1244                                 return _defaultEvent;
1245                         
1246                         DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
1247                         if (attr == null || attr.Name == null) 
1248                                 _defaultEvent = null;
1249                         else {
1250                                 EventDescriptorCollection events = GetEvents ();
1251                                 _defaultEvent = events [attr.Name];
1252 #if !NET_2_0
1253                                 // In our test case (TypeDescriptorTest.TestGetDefaultEvent), we have
1254                                 // a scenario where a custom filter adds the DefaultEventAttribute,
1255                                 // but its FilterEvents method removes the event the
1256                                 // DefaultEventAttribute applied to.  .NET 1.x accepts this and returns
1257                                 // the *other* event defined in the class.
1258                                 //
1259                                 // Consequently, we know we have a DefaultEvent, but we need to check
1260                                 // and ensure that the requested event is unfiltered.  If it is, just
1261                                 // grab the first element in the collection.
1262                                 if (_defaultEvent == null && events.Count > 0)
1263                                         _defaultEvent = events [0];
1264 #endif
1265                         }
1266                         _gotDefaultEvent = true;
1267                         return _defaultEvent;
1268                 }
1269                 
1270                 public PropertyDescriptor GetDefaultProperty ()
1271                 {
1272                         if (_gotDefaultProperty)
1273                                 return _defaultProperty;
1274                         
1275                         DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
1276                         if (attr == null || attr.Name == null) 
1277                                 _defaultProperty = null;
1278                         else {
1279                                 PropertyDescriptorCollection properties = GetProperties ();
1280                                 _defaultProperty = properties[attr.Name];
1281                         }
1282                         _gotDefaultProperty = true;
1283                         return _defaultProperty;
1284                 }
1285                 
1286                 protected AttributeCollection GetAttributes (IComponent comp)
1287                 {
1288                         if (_attributes != null)
1289                                 return _attributes;
1290                         
1291                         bool cache = true;
1292                         ArrayList attributesList = new ArrayList ();
1293
1294                         // 1) Attributes of the type
1295                         foreach (Attribute attribute in _infoType.GetCustomAttributes (false))
1296                                 attributesList.Add (attribute);
1297
1298                         // 2) Attributes of the base types
1299                         Type baseType = _infoType.BaseType;
1300                         while (baseType != null && baseType != typeof (object)) {
1301                                 foreach (Attribute attribute in baseType.GetCustomAttributes (false))
1302                                         attributesList.Add (attribute);
1303                                 baseType = baseType.BaseType;
1304                         }
1305
1306                         // 3) Attributes of the type's implemented interfaces and their interfaces as well
1307                         foreach (Type inface in _infoType.GetInterfaces ())
1308                                 foreach (Attribute attribute in TypeDescriptor.GetAttributes (inface))
1309                                         attributesList.Add (attribute);
1310
1311                         // Filter out duplicate attributes, so that the base types have higher precedence 
1312                         // than the interfaces and the type higher than both.
1313                         Hashtable attributesTable = new Hashtable ();
1314                         for (int i = attributesList.Count - 1; i >= 0; i--) {
1315                                 Attribute attribute = (Attribute)attributesList[i];
1316                                 attributesTable[attribute.TypeId] = attribute;
1317                         }
1318
1319                         if (comp != null && comp.Site != null) 
1320                         {
1321                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
1322                                 if (filter != null)
1323                                         cache = filter.FilterAttributes (comp, attributesTable);
1324                         }
1325
1326                         Attribute[] attributes = new Attribute[attributesTable.Values.Count];
1327                         attributesTable.Values.CopyTo (attributes, 0);
1328                         AttributeCollection attCol = new AttributeCollection (attributes);
1329                         if (cache)
1330                                 _attributes = attCol;
1331                         return attCol;
1332                 }
1333         }
1334
1335         internal class ComponentInfo : Info
1336         {
1337                 IComponent _component;
1338                 EventDescriptorCollection _events;
1339                 PropertyDescriptorCollection _properties;
1340                 
1341                 public ComponentInfo (IComponent component): base (component.GetType())
1342                 {
1343                         _component = component;
1344                 }
1345                 
1346                 public override AttributeCollection GetAttributes ()
1347                 {
1348                         return base.GetAttributes (_component);
1349                 }
1350                 
1351                 public override EventDescriptorCollection GetEvents ()
1352                 {
1353                         if (_events != null)
1354                                 return _events;
1355                         
1356                         bool cache = true;
1357                         EventInfo[] events = _component.GetType().GetEvents ();
1358                         Hashtable t = new Hashtable ();
1359                         foreach (EventInfo ev in events)
1360                                 t [ev.Name] = new ReflectionEventDescriptor (ev);
1361                                         
1362                         if (_component.Site != null) 
1363                         {
1364                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1365                                 if (filter != null)
1366                                         cache = filter.FilterEvents (_component, t);
1367                         }
1368                         
1369                         ArrayList atts = new ArrayList ();
1370                         atts.AddRange (t.Values);
1371                         EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
1372                         if (cache) _events = attCol;
1373                         return attCol;
1374                 }
1375                 
1376                 public override PropertyDescriptorCollection GetProperties ()
1377                 {
1378                         if (_properties != null)
1379                                 return _properties;
1380                         
1381                         bool cache = true;
1382                         PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
1383                         Hashtable t = new Hashtable ();
1384                         for (int i = props.Length-1; i >= 0; i--)
1385                                 t [props[i].Name] = new ReflectionPropertyDescriptor (props[i]);
1386                                         
1387                         if (_component.Site != null) 
1388                         {
1389                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1390                                 if (filter != null)
1391                                         cache = filter.FilterProperties (_component, t);
1392                         }
1393
1394                         PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
1395                         t.Values.CopyTo (descriptors, 0);
1396                         PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
1397                         if (cache)
1398                                 _properties = attCol;
1399                         return attCol;
1400                 }
1401         }
1402         
1403         internal class TypeInfo : Info
1404         {
1405                 EventDescriptorCollection _events;
1406                 PropertyDescriptorCollection _properties;
1407                 
1408                 public TypeInfo (Type t): base (t)
1409                 {
1410                 }
1411                 
1412                 public override AttributeCollection GetAttributes ()
1413                 {
1414                         return base.GetAttributes (null);
1415                 }
1416                 
1417                 public override EventDescriptorCollection GetEvents ()
1418                 {
1419                         if (_events != null)
1420                                 return _events;
1421                         
1422                         EventInfo[] events = InfoType.GetEvents ();
1423                         EventDescriptor[] descs = new EventDescriptor [events.Length];
1424                         for (int n=0; n<events.Length; n++)
1425                                 descs [n] = new ReflectionEventDescriptor (events[n]);
1426
1427                         _events = new EventDescriptorCollection (descs);
1428                         return _events;
1429                 }
1430                 
1431                 public override PropertyDescriptorCollection GetProperties ()
1432                 {
1433                         if (_properties != null)
1434                                 return _properties;
1435
1436                         Hashtable propertiesHash = new Hashtable (); // name - null
1437                         ArrayList propertiesList = new ArrayList (); // propertydescriptors
1438                         Type currentType = InfoType;
1439                         // Getting properties type by type, because in the case of a property in the child type, where
1440                         // the "new" keyword is used and also the return type is changed Type.GetProperties returns 
1441                         // also the parent property. 
1442                         // 
1443                         // Note that we also have to preserve the properties order here.
1444                         // 
1445                         while (currentType != null && currentType != typeof (object)) {
1446                                 PropertyInfo[] props = currentType.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
1447                                 foreach (PropertyInfo property in props) {
1448                                         if (property.GetIndexParameters ().Length == 0 &&
1449                                             property.CanRead &&
1450                                             !propertiesHash.ContainsKey (property.Name)) {
1451                                                 propertiesList.Add (new ReflectionPropertyDescriptor (property));
1452                                                 propertiesHash.Add (property.Name, null);
1453                                         }
1454                                 }
1455                                 currentType = currentType.BaseType;
1456                         }
1457
1458                         _properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) propertiesList.ToArray (typeof (PropertyDescriptor)), true);
1459                         return _properties;
1460                 }
1461         }
1462
1463 #if NET_4_0
1464         // In .net this class seems to be a dummy and empty class
1465         // used to represent internally any extender provider associated with
1466         // all the interfaces.
1467         sealed class TypeDescriptorInterface
1468         {
1469         }
1470 #endif
1471 }