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