Implement MachineKey.Protect and MachineKey.Unprotect
[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                         // Make sure the editorBaseType's static constructor has been called,
604                         // since that's where we're putting the initialization of its editor table.
605                         
606                         System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (editorBaseType.TypeHandle);
607                         if (editors != null)
608                                 editor = FindEditorInTable (componentType, editorBaseType, editors [editorBaseType] as Hashtable);
609                 }
610
611                 return editor;
612         }
613
614         public static object GetEditor (object component, Type editorBaseType)
615         {
616                 return GetEditor (component, editorBaseType, false);
617         }
618
619         [EditorBrowsable (EditorBrowsableState.Advanced)]
620         public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
621         {
622                 if (component == null)
623                         throw new ArgumentNullException ("component");
624                 if (editorBaseType == null)
625                         throw new ArgumentNullException ("editorBaseType");
626                 
627                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
628                         return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
629
630                 object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
631                 if (atts.Length == 0)
632                         return null;
633                 string target = editorBaseType.AssemblyQualifiedName;
634                 
635                 foreach (EditorAttribute ea in atts){
636                         if (ea.EditorBaseTypeName == target){
637                                 Type t = Type.GetType (ea.EditorTypeName, true);
638
639                                 return Activator.CreateInstance (t);
640                         }
641                 }
642                 return null;
643         }
644
645         public static EventDescriptorCollection GetEvents (object component)
646         {
647                 return GetEvents (component, false);
648         }
649
650         public static EventDescriptorCollection GetEvents (Type componentType)
651         {
652                 return GetEvents (componentType, null);
653         }
654
655         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
656         {
657                 return GetEvents (component, attributes, false);
658         }
659
660         [EditorBrowsable (EditorBrowsableState.Advanced)]
661         public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
662         {
663                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
664                         return ((ICustomTypeDescriptor) component).GetEvents ();
665                 else {
666                         IComponent com = component as IComponent;
667                         if (com != null && com.Site != null)
668                                 return GetComponentInfo (com).GetEvents ();
669                         else
670                                 return GetTypeInfo (component.GetType()).GetEvents ();
671                 }
672         }
673
674         public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
675         {
676                 return GetTypeInfo (componentType).GetEvents (attributes);
677         }
678
679         [EditorBrowsable (EditorBrowsableState.Advanced)]
680         public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
681         {
682                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
683                         return ((ICustomTypeDescriptor) component).GetEvents (attributes);
684                 else {
685                         IComponent com = component as IComponent;
686                         if (com != null && com.Site != null)
687                                 return GetComponentInfo (com).GetEvents (attributes);
688                         else
689                                 return GetTypeInfo (component.GetType()).GetEvents (attributes);
690                 }
691         }
692
693         public static PropertyDescriptorCollection GetProperties (object component)
694         {
695                 return GetProperties (component, false);
696         }
697
698         public static PropertyDescriptorCollection GetProperties (Type componentType)
699         {
700                 return GetProperties (componentType, null);
701         }
702
703         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
704         {
705                 return GetProperties (component, attributes, false);
706         }
707
708         public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
709         {
710                 if (component == null)
711                         return PropertyDescriptorCollection.Empty;
712
713                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
714                         return ((ICustomTypeDescriptor) component).GetProperties (attributes);
715                 else {
716                         IComponent com = component as IComponent;
717                         if (com != null && com.Site != null)
718                                 return GetComponentInfo (com).GetProperties (attributes);
719                         else
720                                 return GetTypeInfo (component.GetType()).GetProperties (attributes);
721                 }
722         }
723
724         [EditorBrowsable (EditorBrowsableState.Advanced)]
725         public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
726         {
727                 if (component == null)
728                         return PropertyDescriptorCollection.Empty;
729
730                 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
731                         return ((ICustomTypeDescriptor) component).GetProperties ();
732                 else {
733                         IComponent com = component as IComponent;
734                         if (com != null && com.Site != null)
735                                 return GetComponentInfo (com).GetProperties ();
736                         else
737                                 return GetTypeInfo (component.GetType()).GetProperties ();
738                 }
739         }
740
741         public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
742         {
743                 return GetTypeInfo (componentType).GetProperties (attributes);
744         }
745
746         [EditorBrowsable (EditorBrowsableState.Advanced)]
747         public static TypeDescriptionProvider GetProvider (object instance)
748         {
749                 if (instance == null)
750                         throw new ArgumentNullException ("instance");
751
752                 TypeDescriptionProvider ret = null;
753                 lock (componentDescriptionProvidersLock) {
754                         LinkedList <TypeDescriptionProvider> plist;
755                         WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
756                         
757                         if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0)
758                                 ret = plist.Last.Value;
759                         
760                         instanceWrapper = null;
761                 }
762
763                 if (ret == null)
764                         ret = GetProvider (instance.GetType ());
765
766                 if (ret == null)
767                         return new DefaultTypeDescriptionProvider ();
768                 else
769                         return new WrappedTypeDescriptionProvider (ret);
770         }
771
772         [EditorBrowsable (EditorBrowsableState.Advanced)]
773         public static TypeDescriptionProvider GetProvider (Type type)
774         {
775                 if (type == null)
776                         throw new ArgumentNullException ("type");
777                 
778                 TypeDescriptionProvider ret = null;
779                 lock (typeDescriptionProvidersLock) {
780                         LinkedList <TypeDescriptionProvider> plist;
781                         
782                         while (!typeDescriptionProviders.TryGetValue (type, out plist)) {
783                                 plist = null;
784                                 type = type.BaseType;
785                                 if (type == null)
786                                         break;
787                         }
788
789                         if (plist != null && plist.Count > 0)
790                                 ret = plist.Last.Value;
791                 }
792
793                 if (ret == null)
794                         return new DefaultTypeDescriptionProvider ();
795                 else
796                         return new WrappedTypeDescriptionProvider (ret);
797         }
798
799         [EditorBrowsable (EditorBrowsableState.Advanced)]
800         public static Type GetReflectionType (object instance)
801         {
802                 if (instance == null)
803                         throw new ArgumentNullException ("instance");
804                 
805                 return instance.GetType ();
806         }
807
808         [EditorBrowsable (EditorBrowsableState.Advanced)]
809         public static Type GetReflectionType (Type type)
810         {
811                 if (type == null)
812                         throw new ArgumentNullException ("type");
813                 
814                 return type;
815         }
816
817         [MonoNotSupported("Associations not supported")]
818         [EditorBrowsable (EditorBrowsableState.Advanced)]
819         public static void CreateAssociation (object primary, object secondary)
820         {
821                 throw new NotImplementedException ();
822         }
823
824         [MonoNotSupported ("Associations not supported")]
825         [EditorBrowsable (EditorBrowsableState.Advanced)]
826         public static object GetAssociation (Type type, object primary)
827         {
828                 throw new NotImplementedException ();
829         }
830
831         [MonoNotSupported ("Associations not supported")]
832         [EditorBrowsable (EditorBrowsableState.Advanced)]
833         public static void RemoveAssociation (object primary, object secondary)
834         {
835                 throw new NotImplementedException ();
836         }
837
838         [MonoNotSupported ("Associations not supported")]
839         [EditorBrowsable (EditorBrowsableState.Advanced)]
840         public static void RemoveAssociations (object primary)
841         {
842                 throw new NotImplementedException ();
843         }
844
845         [EditorBrowsable (EditorBrowsableState.Advanced)]
846         public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
847         {
848                 if (provider == null)
849                         throw new ArgumentNullException ("provider");
850                 if (instance == null)
851                         throw new ArgumentNullException ("instance");
852
853                 //bool removed = false;
854                 lock (componentDescriptionProvidersLock) {
855                         LinkedList <TypeDescriptionProvider> plist;
856                         WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
857
858                         if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) {
859                                 RemoveProvider (provider, plist);
860                                 //removed = true;
861                         }
862                         
863                         instanceWrapper = null;
864                 }
865
866                 var refreshed = Refreshed;
867                 if (refreshed != null)
868                         refreshed (new RefreshEventArgs (instance));
869         }
870
871         [EditorBrowsable (EditorBrowsableState.Advanced)]
872         public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
873         {
874                 if (provider == null)
875                         throw new ArgumentNullException ("provider");
876                 if (type == null)
877                         throw new ArgumentNullException ("type");
878
879                 lock (typeDescriptionProvidersLock) {
880                         LinkedList <TypeDescriptionProvider> plist;
881
882                         if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) {
883                                 RemoveProvider (provider, plist);
884                         }
885                 }
886
887                 var refreshed = Refreshed;
888                 if (refreshed != null)
889                         refreshed (new RefreshEventArgs (type));
890         }
891
892 #if NET_4_0
893         [MonoLimitation ("Security not applied.")]
894         [EditorBrowsable (EditorBrowsableState.Advanced)]
895         public static void RemoveProviderTransparent (TypeDescriptionProvider provider, object instance)
896         {
897                 RemoveProvider (provider, instance);
898         }
899
900         [MonoLimitation ("Security not applied.")]
901         [EditorBrowsable (EditorBrowsableState.Advanced)]
902         public static void RemoveProviderTransparent (TypeDescriptionProvider provider, Type type)
903         {
904                 RemoveProvider (provider, type);
905         }
906 #endif
907
908         static void RemoveProvider (TypeDescriptionProvider provider, LinkedList <TypeDescriptionProvider> plist)
909         {
910                 LinkedListNode <TypeDescriptionProvider> node = plist.Last;
911                 LinkedListNode <TypeDescriptionProvider> first = plist.First;
912                 TypeDescriptionProvider p;
913                                 
914                 do {
915                         p = node.Value;
916                         if (p == provider) {
917                                 plist.Remove (node);
918                                 break;
919                         }
920                         if (node == first)
921                                 break;
922                                         
923                         node = node.Previous;
924                                         
925                 } while (true);
926         }
927
928         public static void SortDescriptorArray (IList infos)
929         {
930                 string[] names = new string [infos.Count];
931                 object[] values = new object [infos.Count];
932                 for (int n=0; n<names.Length; n++) {
933                         names[n] = ((MemberDescriptor)infos[n]).Name;
934                         values[n] = infos[n];
935                 }
936                 Array.Sort (names, values);
937                 infos.Clear();
938                 foreach (object ob in values)
939                         infos.Add (ob);
940         }
941
942         // well, ComObjectType is not implemented, but we don't support COM anyways ...
943         [Obsolete ("Use ComObjectType")]
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         sealed class AttributeProvider : TypeDescriptionProvider
1036         {
1037                 Attribute[] attributes;
1038                 
1039                 public AttributeProvider (Attribute[] attributes, TypeDescriptionProvider parent)
1040                         : base (parent)
1041                 {
1042                         this.attributes = attributes;
1043                 }
1044
1045                 public override ICustomTypeDescriptor GetTypeDescriptor (Type type, object instance)
1046                 {
1047                         return new AttributeTypeDescriptor (base.GetTypeDescriptor (type, instance), attributes);
1048                 }
1049                 
1050                 sealed class AttributeTypeDescriptor : CustomTypeDescriptor
1051                 {
1052                         Attribute[] attributes;
1053                         
1054                         public AttributeTypeDescriptor (ICustomTypeDescriptor parent, Attribute[] attributes)
1055                                 : base (parent)
1056                         {
1057                                 this.attributes = attributes;
1058                         }
1059
1060                         public override AttributeCollection GetAttributes ()
1061                         {
1062                                 AttributeCollection attrs = base.GetAttributes ();
1063
1064                                 if (attrs != null && attrs.Count > 0)
1065                                         return AttributeCollection.FromExisting (attrs, attributes);
1066                                 else
1067                                         return new AttributeCollection (attributes);
1068                         }
1069                 }
1070         }
1071
1072         sealed class WrappedTypeDescriptionProvider : TypeDescriptionProvider
1073         {
1074                 public TypeDescriptionProvider Wrapped { get; private set; }
1075                 
1076                 public WrappedTypeDescriptionProvider (TypeDescriptionProvider wrapped)
1077                 {
1078                         Wrapped = wrapped;
1079                 }
1080
1081                 public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
1082                 {
1083                         TypeDescriptionProvider wrapped = Wrapped;
1084
1085                         if (wrapped == null)
1086                                 return base.CreateInstance (provider, objectType, argTypes, args);
1087                         
1088                         return wrapped.CreateInstance (provider, objectType, argTypes, args);
1089                 }
1090
1091                 public override IDictionary GetCache (object instance)
1092                 {
1093                         TypeDescriptionProvider wrapped = Wrapped;
1094
1095                         if (wrapped == null)
1096                                 return base.GetCache (instance);
1097
1098                         return wrapped.GetCache (instance);
1099                 }
1100
1101                 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1102                 {
1103                         return new DefaultTypeDescriptor (this, null, instance);
1104                 }
1105
1106                 public override string GetFullComponentName (object component)
1107                 {
1108                         TypeDescriptionProvider wrapped = Wrapped;
1109
1110                         if (wrapped == null)
1111                                 return base.GetFullComponentName (component);
1112
1113                         return wrapped.GetFullComponentName (component);
1114                 }
1115
1116                 public override Type GetReflectionType (Type type, object instance)
1117                 {
1118                         TypeDescriptionProvider wrapped = Wrapped;
1119
1120                         if (wrapped == null)
1121                                 return base.GetReflectionType (type, instance);
1122
1123                         return wrapped.GetReflectionType (type, instance);
1124                 }
1125
1126                 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1127                 {
1128                         TypeDescriptionProvider wrapped = Wrapped;
1129
1130                         if (wrapped == null)
1131                                 return new DefaultTypeDescriptor (this, objectType, instance);
1132
1133                         return wrapped.GetTypeDescriptor (objectType, instance);
1134                 }
1135         }
1136
1137         // TODO: this needs more work
1138         sealed class DefaultTypeDescriptor : CustomTypeDescriptor
1139         {
1140                 TypeDescriptionProvider owner;
1141                 Type objectType;
1142                 object instance;
1143
1144                 public DefaultTypeDescriptor (TypeDescriptionProvider owner, Type objectType, object instance)
1145                 {
1146                         this.owner = owner;
1147                         this.objectType = objectType;
1148                         this.instance = instance;
1149                 }
1150
1151                 public override AttributeCollection GetAttributes ()
1152                 {
1153                         var wrapped = owner as WrappedTypeDescriptionProvider;
1154
1155                         if (wrapped != null)
1156                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetAttributes ();
1157
1158                         if (instance != null)
1159                                 return TypeDescriptor.GetAttributes (instance, false);
1160
1161                         if (objectType != null)
1162                                 return TypeDescriptor.GetTypeInfo (objectType).GetAttributes ();
1163                         
1164                         return base.GetAttributes ();
1165                 }
1166                 
1167                 public override string GetClassName ()
1168                 {
1169                         var wrapped = owner as WrappedTypeDescriptionProvider;
1170
1171                         if (wrapped != null)
1172                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetClassName ();
1173
1174                         return base.GetClassName ();
1175                 }
1176
1177                 public override PropertyDescriptor GetDefaultProperty ()
1178                 {
1179                         var wrapped = owner as WrappedTypeDescriptionProvider;
1180
1181                         if (wrapped != null)
1182                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetDefaultProperty ();
1183
1184                         PropertyDescriptor ret;
1185                         if (objectType != null)
1186                                 ret = TypeDescriptor.GetTypeInfo (objectType).GetDefaultProperty ();
1187                         else if (instance != null)
1188                                 ret = TypeDescriptor.GetTypeInfo (instance.GetType ()).GetDefaultProperty ();
1189                         else
1190                                 ret = base.GetDefaultProperty ();
1191
1192                         return ret;
1193                 }
1194
1195                 public override PropertyDescriptorCollection GetProperties ()
1196                 {
1197                         var wrapped = owner as WrappedTypeDescriptionProvider;
1198
1199                         if (wrapped != null)
1200                                 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetProperties ();
1201
1202                         if (instance != null)
1203                                 return TypeDescriptor.GetProperties (instance, null, false);
1204
1205                         if (objectType != null)
1206                                 return TypeDescriptor.GetTypeInfo (objectType).GetProperties (null);
1207
1208                         return base.GetProperties ();
1209                 }               
1210         }
1211
1212         sealed class DefaultTypeDescriptionProvider : TypeDescriptionProvider
1213         {
1214                 public DefaultTypeDescriptionProvider ()
1215                 {
1216                 }
1217
1218                 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1219                 {
1220                         return new DefaultTypeDescriptor (this, null, instance);
1221                 }
1222
1223                 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1224                 {
1225                         return new DefaultTypeDescriptor (this, objectType, instance);
1226                 }
1227         }
1228 }
1229
1230         internal abstract class Info
1231         {
1232                 Type _infoType;
1233                 EventDescriptor _defaultEvent;
1234                 bool _gotDefaultEvent;
1235                 PropertyDescriptor _defaultProperty;
1236                 bool _gotDefaultProperty;
1237                 AttributeCollection _attributes;
1238                 
1239                 public Info (Type infoType)
1240                 {
1241                         _infoType = infoType;
1242                 }
1243                 
1244                 public abstract AttributeCollection GetAttributes ();
1245                 public abstract EventDescriptorCollection GetEvents ();
1246                 public abstract PropertyDescriptorCollection GetProperties ();
1247                 
1248                 public Type InfoType
1249                 {
1250                         get { return _infoType; }
1251                 }
1252                 
1253                 public EventDescriptorCollection GetEvents (Attribute[] attributes)
1254                 {
1255                         EventDescriptorCollection evs = GetEvents ();
1256                         if (attributes == null)
1257                                 return evs;
1258                         else
1259                                 return evs.Filter (attributes);
1260                 }
1261                 
1262                 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
1263                 {
1264                         PropertyDescriptorCollection props = GetProperties ();
1265                         if (attributes == null)
1266                                 return props;
1267                         else
1268                                 return props.Filter (attributes);
1269                 }
1270                 
1271                 public EventDescriptor GetDefaultEvent ()
1272                 {
1273                         if (_gotDefaultEvent)
1274                                 return _defaultEvent;
1275                         
1276                         DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
1277                         if (attr == null || attr.Name == null) 
1278                                 _defaultEvent = null;
1279                         else {
1280                                 EventDescriptorCollection events = GetEvents ();
1281                                 _defaultEvent = events [attr.Name];
1282                         }
1283                         _gotDefaultEvent = true;
1284                         return _defaultEvent;
1285                 }
1286                 
1287                 public PropertyDescriptor GetDefaultProperty ()
1288                 {
1289                         if (_gotDefaultProperty)
1290                                 return _defaultProperty;
1291                         
1292                         DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
1293                         if (attr == null || attr.Name == null) 
1294                                 _defaultProperty = null;
1295                         else {
1296                                 PropertyDescriptorCollection properties = GetProperties ();
1297                                 _defaultProperty = properties[attr.Name];
1298                         }
1299                         _gotDefaultProperty = true;
1300                         return _defaultProperty;
1301                 }
1302                 
1303                 protected AttributeCollection GetAttributes (IComponent comp)
1304                 {
1305                         if (_attributes != null)
1306                                 return _attributes;
1307                         
1308                         bool cache = true;
1309                         ArrayList attributesList = new ArrayList ();
1310
1311                         // 1) Attributes of the type
1312                         foreach (Attribute attribute in _infoType.GetCustomAttributes (false))
1313                                 attributesList.Add (attribute);
1314
1315                         // 2) Attributes of the base types
1316                         Type baseType = _infoType.BaseType;
1317                         while (baseType != null && baseType != typeof (object)) {
1318                                 foreach (Attribute attribute in baseType.GetCustomAttributes (false))
1319                                         attributesList.Add (attribute);
1320                                 baseType = baseType.BaseType;
1321                         }
1322
1323                         // 3) Attributes of the type's implemented interfaces and their interfaces as well
1324                         foreach (Type inface in _infoType.GetInterfaces ())
1325                                 foreach (Attribute attribute in TypeDescriptor.GetAttributes (inface))
1326                                         attributesList.Add (attribute);
1327
1328                         // Filter out duplicate attributes, so that the base types have higher precedence 
1329                         // than the interfaces and the type higher than both.
1330                         Hashtable attributesTable = new Hashtable ();
1331                         for (int i = attributesList.Count - 1; i >= 0; i--) {
1332                                 Attribute attribute = (Attribute)attributesList[i];
1333                                 attributesTable[attribute.TypeId] = attribute;
1334                         }
1335
1336                         if (comp != null && comp.Site != null) 
1337                         {
1338                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
1339                                 if (filter != null)
1340                                         cache = filter.FilterAttributes (comp, attributesTable);
1341                         }
1342
1343                         Attribute[] attributes = new Attribute[attributesTable.Values.Count];
1344                         attributesTable.Values.CopyTo (attributes, 0);
1345                         AttributeCollection attCol = new AttributeCollection (attributes);
1346                         if (cache)
1347                                 _attributes = attCol;
1348                         return attCol;
1349                 }
1350         }
1351
1352         internal class ComponentInfo : Info
1353         {
1354                 IComponent _component;
1355                 EventDescriptorCollection _events;
1356                 PropertyDescriptorCollection _properties;
1357                 
1358                 public ComponentInfo (IComponent component): base (component.GetType())
1359                 {
1360                         _component = component;
1361                 }
1362                 
1363                 public override AttributeCollection GetAttributes ()
1364                 {
1365                         return base.GetAttributes (_component);
1366                 }
1367                 
1368                 public override EventDescriptorCollection GetEvents ()
1369                 {
1370                         if (_events != null)
1371                                 return _events;
1372                         
1373                         bool cache = true;
1374                         EventInfo[] events = _component.GetType().GetEvents ();
1375                         Hashtable t = new Hashtable ();
1376                         foreach (EventInfo ev in events)
1377                                 t [ev.Name] = new ReflectionEventDescriptor (ev);
1378                                         
1379                         if (_component.Site != null) 
1380                         {
1381                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1382                                 if (filter != null)
1383                                         cache = filter.FilterEvents (_component, t);
1384                         }
1385                         
1386                         ArrayList atts = new ArrayList ();
1387                         atts.AddRange (t.Values);
1388                         EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
1389                         if (cache) _events = attCol;
1390                         return attCol;
1391                 }
1392                 
1393                 public override PropertyDescriptorCollection GetProperties ()
1394                 {
1395                         if (_properties != null)
1396                                 return _properties;
1397                         
1398                         bool cache = true;
1399                         PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
1400                         Hashtable t = new Hashtable ();
1401                         for (int i = props.Length-1; i >= 0; i--)
1402                                 t [props[i].Name] = new ReflectionPropertyDescriptor (props[i]);
1403                                         
1404                         if (_component.Site != null) 
1405                         {
1406                                 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1407                                 if (filter != null)
1408                                         cache = filter.FilterProperties (_component, t);
1409                         }
1410
1411                         PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
1412                         t.Values.CopyTo (descriptors, 0);
1413                         PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
1414                         if (cache)
1415                                 _properties = attCol;
1416                         return attCol;
1417                 }
1418         }
1419         
1420         internal class TypeInfo : Info
1421         {
1422                 EventDescriptorCollection _events;
1423                 PropertyDescriptorCollection _properties;
1424                 
1425                 public TypeInfo (Type t): base (t)
1426                 {
1427                 }
1428                 
1429                 public override AttributeCollection GetAttributes ()
1430                 {
1431                         return base.GetAttributes (null);
1432                 }
1433                 
1434                 public override EventDescriptorCollection GetEvents ()
1435                 {
1436                         if (_events != null)
1437                                 return _events;
1438                         
1439                         EventInfo[] events = InfoType.GetEvents ();
1440                         EventDescriptor[] descs = new EventDescriptor [events.Length];
1441                         for (int n=0; n<events.Length; n++)
1442                                 descs [n] = new ReflectionEventDescriptor (events[n]);
1443
1444                         _events = new EventDescriptorCollection (descs);
1445                         return _events;
1446                 }
1447                 
1448                 public override PropertyDescriptorCollection GetProperties ()
1449                 {
1450                         if (_properties != null)
1451                                 return _properties;
1452
1453                         Hashtable propertiesHash = new Hashtable (); // name - null
1454                         ArrayList propertiesList = new ArrayList (); // propertydescriptors
1455                         Type currentType = InfoType;
1456                         // Getting properties type by type, because in the case of a property in the child type, where
1457                         // the "new" keyword is used and also the return type is changed Type.GetProperties returns 
1458                         // also the parent property. 
1459                         // 
1460                         // Note that we also have to preserve the properties order here.
1461                         // 
1462                         while (currentType != null && currentType != typeof (object)) {
1463                                 PropertyInfo[] props = currentType.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
1464                                 foreach (PropertyInfo property in props) {
1465                                         if (property.GetIndexParameters ().Length == 0 &&
1466                                             property.CanRead &&
1467                                             !propertiesHash.ContainsKey (property.Name)) {
1468                                                 propertiesList.Add (new ReflectionPropertyDescriptor (property));
1469                                                 propertiesHash.Add (property.Name, null);
1470                                         }
1471                                 }
1472                                 currentType = currentType.BaseType;
1473                         }
1474
1475                         _properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) propertiesList.ToArray (typeof (PropertyDescriptor)), true);
1476                         return _properties;
1477                 }
1478         }
1479
1480 #if NET_4_0
1481         // In .net this class seems to be a dummy and empty class
1482         // used to represent internally any extender provider associated with
1483         // all the interfaces.
1484         sealed class TypeDescriptorInterface
1485         {
1486         }
1487 #endif
1488 }