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