2009-06-22 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Mon, 22 Jun 2009 18:24:19 +0000 (18:24 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Mon, 22 Jun 2009 18:24:19 +0000 (18:24 -0000)
* WeakObjectWrapper.cs, WeakObjectWrapperComparer.cs: added - used
by TypeDescriptor for storage of type description providers.

* TypeDescriptor.cs: implemented part of the 2.0+ API which deals
with adding/removing/getting type description providers.

* AttributeCollection.cs: do not throw NREX when attrList is
null in Count.

2009-06-22  Marek Habersack  <mhabersack@novell.com>

* TypeDescriptorTests.cs: added tests for 2.0+ APIs which deal
with adding/removing/getting type description providers.

svn path=/trunk/mcs/; revision=136634

mcs/class/System/System.ComponentModel/AttributeCollection.cs
mcs/class/System/System.ComponentModel/ChangeLog
mcs/class/System/System.ComponentModel/TypeDescriptor.cs
mcs/class/System/System.ComponentModel/WeakObjectWrapper.cs [new file with mode: 0644]
mcs/class/System/System.ComponentModel/WeakObjectWrapperComparer.cs [new file with mode: 0644]
mcs/class/System/System.dll.sources
mcs/class/System/Test/System.ComponentModel/ChangeLog
mcs/class/System/Test/System.ComponentModel/TypeDescriptorTests.cs

index 56f3464fffe98644da000055338b61d3c5da6a2d..c60ddc8ea0cf98caa443c4f285b4c6d96cc46cc7 100644 (file)
@@ -161,7 +161,7 @@ namespace System.ComponentModel
 
                public int Count {
                        get {
-                               return attrList.Count;
+                               return attrList != null ? attrList.Count : 0;
                        }
                }
 
index 8561892c47e765a30d7d9bd29c02066e132a5a79..04afad39214cce035c30f0a64d6c3bc50143087d 100644 (file)
@@ -1,3 +1,14 @@
+2009-06-22  Marek Habersack  <mhabersack@novell.com>
+
+       * WeakObjectWrapper.cs, WeakObjectWrapperComparer.cs: added - used
+       by TypeDescriptor for storage of type description providers.
+
+       * TypeDescriptor.cs: implemented part of the 2.0+ API which deals
+       with adding/removing/getting type description providers.
+
+       * AttributeCollection.cs: do not throw NREX when attrList is
+       null in Count.
+
 2009-05-14  Jonathan Pryor  <jpryor@novell.com>
 
        * ListChangedEventArgs.cs: Fix .NET compatibility problems (discovered
index 2a9f4b29a2427d199797fe1802024aa8b39ea656..6642c2c1f2b1e5132a8dd236eb71fa213974198f 100644 (file)
@@ -39,6 +39,10 @@ using System.Globalization;
 using System.ComponentModel.Design;
 using System.Security.Permissions;
 
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
 namespace System.ComponentModel
 {
 
@@ -51,43 +55,98 @@ public sealed class TypeDescriptor
        private static Hashtable typeTable = new Hashtable ();
        private static Hashtable editors;
 
+#if NET_2_0
+       static object typeDescriptionProvidersLock = new object ();
+       static Dictionary <Type, LinkedList <TypeDescriptionProvider>> typeDescriptionProviders;
+
+       static object componentDescriptionProvidersLock = new object ();
+       static Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> componentDescriptionProviders;
+
+       static TypeDescriptor ()
+       {
+               typeDescriptionProviders = new Dictionary <Type, LinkedList <TypeDescriptionProvider>> ();
+               componentDescriptionProviders = new Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> (new WeakObjectWrapperComparer ());
+       }
+#endif
        private TypeDescriptor ()
        {
        }
 
 #if NET_2_0
-       [MonoNotSupported ("")]
+       [MonoNotSupported ("Mono does not support COM")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static Type ComObjectType {
                get { throw new NotImplementedException (); }
        }
 
-       [MonoNotSupported("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static TypeDescriptionProvider AddAttributes (object instance, params Attribute [] attributes)
        {
-               throw new NotImplementedException ();
+               if (instance == null)
+                       throw new ArgumentNullException ("instance");
+               if (attributes == null)
+                       throw new ArgumentNullException ("attributes");
+
+               var ret = new AttributeProvider (attributes, GetProvider (instance));
+               AddProvider (ret, instance);
+
+               return ret;
        }
 
-       [MonoNotSupported("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static TypeDescriptionProvider AddAttributes (Type type, params Attribute [] attributes)
        {
-               throw new NotImplementedException ();
-       }
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+               if (attributes == null)
+                       throw new ArgumentNullException ("attributes");
 
-       [MonoNotSupported("")]
+               var ret = new AttributeProvider (attributes, GetProvider (type));
+               AddProvider (ret, type);
+               
+               return ret;
+       }
+       
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static void AddProvider (TypeDescriptionProvider provider, object instance)
        {
-               throw new NotImplementedException ();
+               if (provider == null)
+                       throw new ArgumentNullException ("provider");
+               if (instance == null)
+                       throw new ArgumentNullException ("instance");
+
+               lock (componentDescriptionProvidersLock) {
+                       LinkedList <TypeDescriptionProvider> plist;
+                       WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
+                       
+                       if (!componentDescriptionProviders.TryGetValue (instanceWrapper, out plist)) {
+                               plist = new LinkedList <TypeDescriptionProvider> ();
+                               componentDescriptionProviders.Add (new WeakObjectWrapper (instance), plist);
+                       }
+
+                       plist.AddLast (provider);
+                       instanceWrapper = null;
+               }
        }
 
-       [MonoNotSupported("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static void AddProvider (TypeDescriptionProvider provider, Type type)
        {
-               throw new NotImplementedException ();
+               if (provider == null)
+                       throw new ArgumentNullException ("provider");
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+
+               lock (typeDescriptionProvidersLock) {
+                       LinkedList <TypeDescriptionProvider> plist;
+
+                       if (!typeDescriptionProviders.TryGetValue (type, out plist)) {
+                               plist = new LinkedList <TypeDescriptionProvider> ();
+                               typeDescriptionProviders.Add (type, plist);
+                       }
+
+                       plist.AddLast (provider);
+               }
        }
 
        [MonoTODO]
@@ -695,32 +754,65 @@ public sealed class TypeDescriptor
        }
 
 #if NET_2_0
-       [MonoNotSupported ("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static TypeDescriptionProvider GetProvider (object instance)
        {
-               throw new NotImplementedException ();
+               if (instance == null)
+                       throw new ArgumentNullException ("instance");
+
+               TypeDescriptionProvider ret = null;
+               lock (componentDescriptionProvidersLock) {
+                       LinkedList <TypeDescriptionProvider> plist;
+                       WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
+                       
+                       if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0)
+                               ret = plist.Last.Value;
+                       
+                       instanceWrapper = null;
+               }
+
+               if (ret == null)
+                       ret = new DefaultTypeDescriptionProvider ();
+               
+               return new WrappedTypeDescriptionProvider (ret);
        }
 
-       [MonoNotSupported ("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static TypeDescriptionProvider GetProvider (Type type)
        {
-               throw new NotImplementedException ();
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+               
+               TypeDescriptionProvider ret = null;
+               lock (typeDescriptionProvidersLock) {
+                       LinkedList <TypeDescriptionProvider> plist;
+                       
+                       if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0)
+                               ret = plist.Last.Value;
+               }
+
+               if (ret == null)
+                       ret = new DefaultTypeDescriptionProvider ();
+               
+               return new WrappedTypeDescriptionProvider (ret);
        }
 
-       [MonoNotSupported ("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static Type GetReflectionType (object instance)
        {
-               throw new NotImplementedException ();
+               if (instance == null)
+                       throw new ArgumentNullException ("instance");
+               
+               return instance.GetType ();
        }
 
-       [MonoNotSupported ("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static Type GetReflectionType (Type type)
        {
-               throw new NotImplementedException ();
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+               
+               return type;
        }
 
        [MonoNotSupported("Associations not supported")]
@@ -751,18 +843,73 @@ public sealed class TypeDescriptor
                throw new NotImplementedException ();
        }
 
-       [MonoNotSupported ("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
        {
-               throw new NotImplementedException ();
+               if (provider == null)
+                       throw new ArgumentNullException ("provider");
+               if (instance == null)
+                       throw new ArgumentNullException ("instance");
+
+               bool removed = false;
+               lock (componentDescriptionProvidersLock) {
+                       LinkedList <TypeDescriptionProvider> plist;
+                       WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
+
+                       if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) {
+                               RemoveProvider (provider, plist);
+                               removed = true;
+                       }
+                       
+                       instanceWrapper = null;
+               }
+
+               var refreshed = Refreshed;
+               if (refreshed != null)
+                       refreshed (new RefreshEventArgs (instance));
        }
 
-       [MonoNotSupported ("")]
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
        {
-               throw new NotImplementedException ();
+               if (provider == null)
+                       throw new ArgumentNullException ("provider");
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+
+               bool removed = false;
+               lock (typeDescriptionProvidersLock) {
+                       LinkedList <TypeDescriptionProvider> plist;
+
+                       if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) {
+                               RemoveProvider (provider, plist);
+                               removed = true;
+                       }
+               }
+
+               var refreshed = Refreshed;
+               if (refreshed != null)
+                       refreshed (new RefreshEventArgs (type));
+       }
+
+       static void RemoveProvider (TypeDescriptionProvider provider, LinkedList <TypeDescriptionProvider> plist)
+       {
+               LinkedListNode <TypeDescriptionProvider> node = plist.Last;
+               LinkedListNode <TypeDescriptionProvider> first = plist.First;
+               TypeDescriptionProvider p;
+                               
+               do {
+                       p = node.Value;
+                       if (p == provider) {
+                               plist.Remove (node);
+                               break;
+                       }
+                       if (node == first)
+                               break;
+                                       
+                       node = node.Previous;
+                                       
+               } while (true);
        }
 #endif
 
@@ -874,6 +1021,165 @@ public sealed class TypeDescriptor
                        type = Type.GetType (typeName);
                return type;
        }
+
+#if NET_2_0
+       sealed class AttributeProvider : TypeDescriptionProvider
+       {
+               Attribute[] attributes;
+               
+               public AttributeProvider (Attribute[] attributes, TypeDescriptionProvider parent)
+                       : base (parent)
+               {
+                       this.attributes = attributes;
+               }
+
+               public override ICustomTypeDescriptor GetTypeDescriptor (Type type, object instance)
+               {
+                       return new AttributeTypeDescriptor (base.GetTypeDescriptor (type, instance), attributes);
+               }
+               
+               sealed class AttributeTypeDescriptor : CustomTypeDescriptor
+               {
+                       Attribute[] attributes;
+                       
+                       public AttributeTypeDescriptor (ICustomTypeDescriptor parent, Attribute[] attributes)
+                               : base (parent)
+                       {
+                               this.attributes = attributes;
+                       }
+
+                       public override AttributeCollection GetAttributes ()
+                       {
+                               AttributeCollection attrs = base.GetAttributes ();
+
+                               if (attrs != null && attrs.Count > 0)
+                                       return AttributeCollection.FromExisting (attrs, attributes);
+                               else
+                                       return new AttributeCollection (attributes);
+                       }
+               }
+       }
+
+       sealed class WrappedTypeDescriptionProvider : TypeDescriptionProvider
+       {
+               public TypeDescriptionProvider Wrapped { get; private set; }
+               
+               public WrappedTypeDescriptionProvider (TypeDescriptionProvider wrapped)
+               {
+                       Wrapped = wrapped;
+               }
+
+               public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
+               {
+                       TypeDescriptionProvider wrapped = Wrapped;
+
+                       if (wrapped == null)
+                               return base.CreateInstance (provider, objectType, argTypes, args);
+                       
+                       return wrapped.CreateInstance (provider, objectType, argTypes, args);
+               }
+
+               public override IDictionary GetCache (object instance)
+               {
+                       TypeDescriptionProvider wrapped = Wrapped;
+
+                       if (wrapped == null)
+                               return base.GetCache (instance);
+
+                       return wrapped.GetCache (instance);
+               }
+
+               public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
+               {
+                       return new DefaultTypeDescriptor (this, null, instance);
+               }
+
+               public override string GetFullComponentName (object component)
+               {
+                       TypeDescriptionProvider wrapped = Wrapped;
+
+                       if (wrapped == null)
+                               return base.GetFullComponentName (component);
+
+                       return wrapped.GetFullComponentName (component);
+               }
+
+               public override Type GetReflectionType (Type type, object instance)
+               {
+                       TypeDescriptionProvider wrapped = Wrapped;
+
+                       if (wrapped == null)
+                               return base.GetReflectionType (type, instance);
+
+                       return wrapped.GetReflectionType (type, instance);
+               }
+
+               public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
+               {
+                       return new DefaultTypeDescriptor (this, objectType, instance);
+               }
+       }
+
+       // TODO: this needs more work
+       sealed class DefaultTypeDescriptor : CustomTypeDescriptor
+       {
+               TypeDescriptionProvider owner;
+               Type objectType;
+               object instance;
+
+               public DefaultTypeDescriptor (TypeDescriptionProvider owner, Type objectType, object instance)
+               {
+                       this.owner = owner;
+                       this.objectType = objectType;
+                       this.instance = instance;
+               }
+
+               public override string GetClassName ()
+               {
+                       var wrapped = owner as WrappedTypeDescriptionProvider;
+
+                       if (wrapped != null)
+                               return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetClassName ();
+
+                       return base.GetClassName ();
+               }
+
+               public override PropertyDescriptor GetDefaultProperty ()
+               {
+                       var wrapped = owner as WrappedTypeDescriptionProvider;
+
+                       if (wrapped != null)
+                               return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetDefaultProperty ();
+
+                       PropertyDescriptor ret;
+                       if (objectType != null)
+                               ret = TypeDescriptor.GetTypeInfo (objectType).GetDefaultProperty ();
+                       else if (instance != null)
+                               ret = TypeDescriptor.GetTypeInfo (instance.GetType ()).GetDefaultProperty ();
+                       else
+                               ret = base.GetDefaultProperty ();
+
+                       return ret;
+               }
+       }
+
+       sealed class DefaultTypeDescriptionProvider : TypeDescriptionProvider
+       {
+               public DefaultTypeDescriptionProvider ()
+               {
+               }
+
+               public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
+               {
+                       return new DefaultTypeDescriptor (this, null, instance);
+               }
+
+               public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
+               {
+                       return new DefaultTypeDescriptor (this, objectType, instance);
+               }
+       }
+#endif
 }
 
        internal abstract class Info
diff --git a/mcs/class/System/System.ComponentModel/WeakObjectWrapper.cs b/mcs/class/System/System.ComponentModel/WeakObjectWrapper.cs
new file mode 100644 (file)
index 0000000..8bf4269
--- /dev/null
@@ -0,0 +1,51 @@
+//
+// System.ComponentModel.WeakObjectWrapper.cs
+//
+// Authors:
+//   Marek Habersack <mhabersack@novell.com>
+// 
+//
+// (C) 2009 Novell, Inc (http://novell.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System.ComponentModel
+{
+       sealed class WeakObjectWrapper
+       {
+               public int TargetHashCode { get; private set; }
+               public WeakReference Weak { get; private set; }
+       
+               public WeakObjectWrapper (object target)
+               {
+                       TargetHashCode = target.GetHashCode ();
+                       Weak = new WeakReference (target);
+               }
+       }
+}
+#endif
\ No newline at end of file
diff --git a/mcs/class/System/System.ComponentModel/WeakObjectWrapperComparer.cs b/mcs/class/System/System.ComponentModel/WeakObjectWrapperComparer.cs
new file mode 100644 (file)
index 0000000..830ced2
--- /dev/null
@@ -0,0 +1,67 @@
+//
+// System.ComponentModel.WeakObjectWrapperComparer.cs
+//
+// Authors:
+//   Marek Habersack <mhabersack@novell.com>
+// 
+//
+// (C) 2009 Novell, Inc (http://novell.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System.ComponentModel
+{
+       sealed class WeakObjectWrapperComparer : EqualityComparer <WeakObjectWrapper>
+       {
+               public override bool Equals (WeakObjectWrapper x, WeakObjectWrapper y)
+               {
+                       if (x == null && y == null)
+                               return false;
+
+                       if (x == null || y == null)
+                               return false;
+
+                       WeakReference xWeak = x.Weak;
+                       WeakReference yWeak = y.Weak;
+                       
+                       if (!xWeak.IsAlive && !yWeak.IsAlive)
+                               return false;
+
+                       return xWeak.Target == yWeak.Target;
+               }
+
+               public override int GetHashCode (WeakObjectWrapper obj)
+               {
+                       if (obj == null)
+                               return 0;
+
+                       return obj.TargetHashCode;
+               }
+       }
+}
+#endif
index f7df2051e561ed2ec41968b811491cac1e9babfa..9ba50a8e5ac9a72fe110418542cf33b2ccb262a3 100644 (file)
@@ -409,6 +409,8 @@ System.ComponentModel/UInt16Converter.cs
 System.ComponentModel/UInt32Converter.cs
 System.ComponentModel/UInt64Converter.cs
 System.ComponentModel/WarningException.cs
+System.ComponentModel/WeakObjectWrapper.cs
+System.ComponentModel/WeakObjectWrapperComparer.cs
 System.ComponentModel/Win32Exception.cs
 System.Configuration/ApplicationScopedSettingAttribute.cs
 System.Configuration/ApplicationSettingsBase.cs
index 48306615b1888b561e7168575a7e4d5a344937d9..c47e32828d48f87f33bf12df901b77382183f193 100644 (file)
@@ -1,3 +1,8 @@
+2009-06-22  Marek Habersack  <mhabersack@novell.com>
+
+       * TypeDescriptorTests.cs: added tests for 2.0+ APIs which deal
+       with adding/removing/getting type description providers.
+
 2009-05-14  Jonathan Pryor  <jpryor@novell.com>
 
        * ListChangedEventArgsTest.cs: Fix .NET 1.1 compile error.
index 4f7055db09fb34eb4c55994d3f1f0d52956fc659..82ef9917936de2e510b7fb8d27caafe3b9c348a0 100644 (file)
@@ -14,6 +14,10 @@ using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
 using System.ComponentModel.Design;
 using System.Globalization;
 
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
 using NUnit.Framework;
 
 namespace MonoTests.System.ComponentModel
@@ -362,7 +366,7 @@ namespace MonoTests.System.ComponentModel
        {
                public TestClass()
                {}
-                       
+
                void TestFunction ()
                {}
        }
@@ -390,7 +394,7 @@ namespace MonoTests.System.ComponentModel
 
                public TypeConverter GetConverter()
                {
-                       return new StringConverter();
+                       return new StringConverter ();
                }
 
                public EventDescriptorCollection GetEvents(Attribute[] attributes)
@@ -452,9 +456,53 @@ namespace MonoTests.System.ComponentModel
 
                public string GetClassName()
                {
-                       return this.GetType().Name;
+                       return this.GetType ().Name;
+               }
+       }
+
+#if NET_2_0
+       class MyCustomTypeDescriptor : CustomTypeDescriptor
+       {
+               public MyTypeDescriptionProvider Provider { get; private set; }
+
+               public MyCustomTypeDescriptor (MyTypeDescriptionProvider provider)
+               {
+                       Provider = provider;
+               }
+
+               public override string GetClassName ()
+               {
+                       return Provider.Id;
+               }
+       }
+
+       class MyTypeDescriptionProvider : TypeDescriptionProvider
+       {
+               public string Id { get; private set; }
+               public bool CreateInstanceCalled { get; private set; }
+
+               public MyTypeDescriptionProvider ()
+                       : this (null)
+               {
+               }
+
+               public MyTypeDescriptionProvider (string id)
+               {
+                       Id = id;
+               }
+
+               public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
+               {
+                       return new MyCustomTypeDescriptor (this);
+               }
+
+               public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
+               {
+                       CreateInstanceCalled = true;
+                       return base.CreateInstance (provider, objectType, argTypes, args);
                }
        }
+#endif
 
        [TestFixture]
        public class TypeDescriptorTests
@@ -464,6 +512,550 @@ namespace MonoTests.System.ComponentModel
                MyComponent nfscom = new MyComponent (new NoFilterSite (new MyContainer ()));
                AnotherComponent anothercom = new AnotherComponent ();
                
+#if NET_2_0
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddAttributes_Type_Attributes_1 ()
+               {
+                       TypeDescriptionProvider provider = TypeDescriptor.AddAttributes ((Type) null, null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddAttributes_Type_Attributes_2 ()
+               {
+                       TypeDescriptionProvider provider = TypeDescriptor.AddAttributes (typeof (string), null);
+               }
+
+               [Test]
+               public void TestAddAttributes_Type_Attributes_3 ()
+               {
+                       Attribute[] new_attributes = new Attribute[] {
+                               new ReadOnlyAttribute (true),
+                               new BindableAttribute (true)
+                       };
+
+                       TypeDescriptionProvider provider = null;
+                       ICustomTypeDescriptor descriptor;
+                       AttributeCollection attributes;
+
+                       try {
+                               provider = TypeDescriptor.AddAttributes (typeof (string), new Attribute[] { });
+                               Assert.IsNotNull (provider, "#A1");
+
+                               descriptor = provider.GetTypeDescriptor (typeof (string));
+                               Assert.IsNotNull (descriptor, "#A1-1");
+
+                               attributes = descriptor.GetAttributes ();
+                               Assert.IsNotNull (attributes, "#A1-2");
+                       } finally {
+                               if (provider != null)
+                                       TypeDescriptor.RemoveProvider (provider, typeof (string));
+                       }
+
+                       provider = null;
+                       try {
+                               provider = TypeDescriptor.AddAttributes (typeof (string), new_attributes);
+                               Assert.IsNotNull (provider, "#B1");
+
+                               descriptor = provider.GetTypeDescriptor (typeof (string));
+                               Assert.IsNotNull (descriptor, "#B1-1");
+
+                               attributes = descriptor.GetAttributes ();
+                               Assert.IsNotNull (attributes, "#B1-2");
+                               Assert.AreNotEqual (0, attributes.Count, "#B1-3");
+                               Assert.IsTrue (attributes.Contains (new_attributes));
+                       } finally {
+                               if (provider != null)
+                                       TypeDescriptor.RemoveProvider (provider, typeof (string));
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddAttributes_Instance_Attributes_1 ()
+               {
+                       TypeDescriptionProvider provider = TypeDescriptor.AddAttributes ((object) null, null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddAttributes_Instance_Attributes_2 ()
+               {
+                       string s = "test";
+                       TypeDescriptionProvider provider = TypeDescriptor.AddAttributes (s, null);
+               }
+
+               [Test]
+               public void TestAddAttributes_Instance_Attributes_3 ()
+               {
+                       Attribute[] new_attributes = new Attribute[] {
+                               new ReadOnlyAttribute (true),
+                               new BindableAttribute (true)
+                       };
+
+                       TypeDescriptionProvider provider = null;
+                       ICustomTypeDescriptor descriptor;
+                       AttributeCollection attributes;
+                       string s = "test";
+
+                       try {
+                               provider = TypeDescriptor.AddAttributes (s, new Attribute[] { });
+                               Assert.IsNotNull (provider, "#A1");
+
+                               descriptor = provider.GetTypeDescriptor (s);
+                               Assert.IsNotNull (descriptor, "#A1-1");
+
+                               attributes = descriptor.GetAttributes ();
+                               Assert.IsNotNull (attributes, "#A1-2");
+                       } finally {
+                               if (provider != null)
+                                       TypeDescriptor.RemoveProvider (provider, s);
+                       }
+
+                       provider = null;
+                       try {
+                               provider = TypeDescriptor.AddAttributes (s, new_attributes);
+                               Assert.IsNotNull (provider, "#B1");
+
+                               descriptor = provider.GetTypeDescriptor (s);
+                               Assert.IsNotNull (descriptor, "#B1-1");
+
+                               attributes = descriptor.GetAttributes ();
+                               Assert.IsNotNull (attributes, "#B1-2");
+                               Assert.AreNotEqual (0, attributes.Count, "#B1-3");
+                               Assert.IsTrue (attributes.Contains (new_attributes));
+                       } finally {
+                               if (provider != null)
+                                       TypeDescriptor.RemoveProvider (provider, s);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddProvider_Provider_Instance_1 ()
+               {
+                       TypeDescriptor.AddProvider (null, (object)null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddProvider_Provider_Instance_2 ()
+               {
+                       var provider = new MyTypeDescriptionProvider ();
+                       TypeDescriptor.AddProvider (provider, (object) null);
+               }
+
+               [Test]
+               public void TestAddProvider_Provider_Instance_3 ()
+               {
+                       var instance = new MyComponent ();
+                       var providers = new MyTypeDescriptionProvider[] {
+                               new MyTypeDescriptionProvider ("One"),
+                               new MyTypeDescriptionProvider ("Two"),
+                               new MyTypeDescriptionProvider ("Three"),
+                               new MyTypeDescriptionProvider ("Four")
+                       };
+
+                       try {
+                               TypeDescriptionProvider provider;
+                               ICustomTypeDescriptor descriptor;
+
+                               TypeDescriptor.AddProvider (providers[0], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#A1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#A1-1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#A1-2");
+                               Assert.AreEqual (false, providers[0].CreateInstanceCalled, "#A1-3");
+
+                               descriptor.GetProperties ();
+
+                               TypeDescriptor.AddProvider (providers[1], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#B1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#B1-1");
+                               Assert.AreEqual ("Two", descriptor.GetClassName (), "#B1-2");
+
+                               // Providers are stored in a stack according to docs, but it's in reality
+                               // a FIFO linked list
+                               TypeDescriptor.AddProvider (providers[2], instance);
+                               TypeDescriptor.AddProvider (providers[3], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#C1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#C1-1");
+                               Assert.AreEqual ("Four", descriptor.GetClassName (), "#C1-2");
+
+                               TypeDescriptor.RemoveProvider (providers[2], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#D1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#D1-1");
+                               Assert.AreEqual ("Four", descriptor.GetClassName (), "#D1-2");
+
+                               TypeDescriptor.RemoveProvider (providers[3], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#E1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#E1-1");
+                               Assert.AreEqual ("Two", descriptor.GetClassName (), "#E1-2");
+
+                       } finally {
+                               TypeDescriptor.RemoveProvider (providers[0], instance);
+                               TypeDescriptor.RemoveProvider (providers[1], instance);
+                               TypeDescriptor.RemoveProvider (providers[2], instance);
+                               TypeDescriptor.RemoveProvider (providers[3], instance);
+                       }
+               }
+
+               [Test]
+               public void TestAddProvider_Provider_Instance_4 ()
+               {
+                       var instance = new MyComponent ();
+                       var providers = new MyTypeDescriptionProvider[] {
+                               new MyTypeDescriptionProvider ("One"),
+                               new MyTypeDescriptionProvider ("Two"),
+                               new MyTypeDescriptionProvider ("Three"),
+                               new MyTypeDescriptionProvider ("Four")
+                       };
+
+                       try {
+                               TypeDescriptionProvider provider;
+                               ICustomTypeDescriptor descriptor;
+
+                               TypeDescriptor.AddProvider (providers[0], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#A1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#A1-1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#A1-2");
+                               Assert.AreEqual (false, providers[0].CreateInstanceCalled, "#A1-3");
+
+                               descriptor.GetProperties ();
+
+                               TypeDescriptor.AddProvider (providers[1], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#B1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#B1-1");
+                               Assert.AreEqual ("Two", descriptor.GetClassName (), "#B1-2");
+
+                               // Providers are stored in a stack according to docs, but it's in reality
+                               // a FIFO linked list
+                               TypeDescriptor.AddProvider (providers[0], instance);
+                               TypeDescriptor.AddProvider (providers[0], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#C1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#C1-1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#C1-2");
+
+                               TypeDescriptor.RemoveProvider (providers[0], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#D1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#D1-1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#D1-2");
+
+                               TypeDescriptor.RemoveProvider (providers[0], instance);
+                               provider = TypeDescriptor.GetProvider (instance);
+                               Assert.IsNotNull (provider, "#E1");
+                               descriptor = provider.GetTypeDescriptor (instance.GetType (), instance);
+                               Assert.IsNotNull (descriptor, "#E1-1");
+                               Assert.AreEqual ("Two", descriptor.GetClassName (), "#E1-2");
+
+                       } finally {
+                               TypeDescriptor.RemoveProvider (providers[0], instance);
+                               TypeDescriptor.RemoveProvider (providers[1], instance);
+                               TypeDescriptor.RemoveProvider (providers[2], instance);
+                               TypeDescriptor.RemoveProvider (providers[3], instance);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddProvider_Provider_Type_1 ()
+               {
+                       TypeDescriptor.AddProvider (null, (Type) null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestAddProvider_Provider_Type_2 ()
+               {
+                       var provider = new MyTypeDescriptionProvider ();
+                       TypeDescriptor.AddProvider (provider, (Type) null);
+               }
+
+               [Test]
+               public void TestAddProvider_Provider_Type_3 ()
+               {
+                       var type = typeof (MyComponent);
+                       var providers = new MyTypeDescriptionProvider[] {
+                               new MyTypeDescriptionProvider ("One"),
+                               new MyTypeDescriptionProvider ("Two"),
+                               new MyTypeDescriptionProvider ("Three"),
+                               new MyTypeDescriptionProvider ("Four")
+                       };
+
+                       try {
+                               TypeDescriptionProvider provider;
+                               ICustomTypeDescriptor descriptor;
+
+                               TypeDescriptor.AddProvider (providers[0], type);
+                               provider = TypeDescriptor.GetProvider (type);
+                               Assert.IsNotNull (provider, "#A1");
+                               descriptor = provider.GetTypeDescriptor (type);
+                               Assert.IsNotNull (descriptor, "#A1-1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#A1-2");
+                               Assert.AreEqual (false, providers[0].CreateInstanceCalled, "#A1-3");
+
+                               TypeDescriptor.AddProvider (providers[1], type);
+                               provider = TypeDescriptor.GetProvider (type);
+                               Assert.IsNotNull (provider, "#B1");
+                               descriptor = provider.GetTypeDescriptor (type.GetType (), type);
+                               Assert.IsNotNull (descriptor, "#B1-1");
+                               Assert.AreEqual ("Two", descriptor.GetClassName (), "#B1-2");
+
+                               // Providers are stored in a stack according to docs, but it's in reality
+                               // a FIFO linked list
+                               TypeDescriptor.AddProvider (providers[2], type);
+                               TypeDescriptor.AddProvider (providers[3], type);
+                               provider = TypeDescriptor.GetProvider (type);
+                               Assert.IsNotNull (provider, "#C1");
+                               descriptor = provider.GetTypeDescriptor (type.GetType (), type);
+                               Assert.IsNotNull (descriptor, "#C1-1");
+                               Assert.AreEqual ("Four", descriptor.GetClassName (), "#C1-2");
+
+                               TypeDescriptor.RemoveProvider (providers[2], type);
+                               provider = TypeDescriptor.GetProvider (type);
+                               Assert.IsNotNull (provider, "#D1");
+                               descriptor = provider.GetTypeDescriptor (type.GetType (), type);
+                               Assert.IsNotNull (descriptor, "#D1-1");
+                               Assert.AreEqual ("Four", descriptor.GetClassName (), "#D1-2");
+
+                               TypeDescriptor.RemoveProvider (providers[3], type);
+                               provider = TypeDescriptor.GetProvider (type);
+                               Assert.IsNotNull (provider, "#E1");
+                               descriptor = provider.GetTypeDescriptor (type.GetType (), type);
+                               Assert.IsNotNull (descriptor, "#E1-1");
+                               Assert.AreEqual ("Two", descriptor.GetClassName (), "#E1-2");
+
+                       } finally {
+                               TypeDescriptor.RemoveProvider (providers[0], type);
+                               TypeDescriptor.RemoveProvider (providers[1], type);
+                               TypeDescriptor.RemoveProvider (providers[2], type);
+                               TypeDescriptor.RemoveProvider (providers[3], type);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestGetProvider_Type_1 ()
+               {
+                       TypeDescriptor.GetProvider ((Type)null);
+               }
+
+               [Test]
+               public void TestGetProvider_Type_2 ()
+               {
+                       TypeDescriptionProvider provider = TypeDescriptor.GetProvider (typeof (string));
+                       Assert.IsNotNull (provider, "#A1");
+                       provider = new MyTypeDescriptionProvider ("One");
+
+                       try {
+                               TypeDescriptor.AddProvider (provider, typeof (string));
+                               ICustomTypeDescriptor descriptor = provider.GetTypeDescriptor (typeof (string));
+                               Assert.IsNotNull (descriptor, "#B1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#B1-1");
+                       } finally {
+                               TypeDescriptor.RemoveProvider (provider, typeof (string));
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestGetProvider_Instance_1 ()
+               {
+                       TypeDescriptor.GetProvider ((object) null);
+               }
+
+               [Test]
+               public void TestGetProvider_Instance_2 ()
+               {
+                       var instance = new MyComponent ();
+                       TypeDescriptionProvider provider = TypeDescriptor.GetProvider (instance);
+                       Assert.IsNotNull (provider, "#A1");
+                       provider = new MyTypeDescriptionProvider ("One");
+
+                       try {
+                               TypeDescriptor.AddProvider (provider, instance);
+                               ICustomTypeDescriptor descriptor = provider.GetTypeDescriptor (instance);
+                               Assert.IsNotNull (descriptor, "#B1");
+                               Assert.AreEqual ("One", descriptor.GetClassName (), "#B1-1");
+                       } finally {
+                               TypeDescriptor.RemoveProvider (provider, instance);
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestRemoveProvider_Provider_Type_1 ()
+               {
+                       TypeDescriptor.RemoveProvider (null, (Type)null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestRemoveProvider_Provider_Type_2 ()
+               {
+                       var provider = new MyTypeDescriptionProvider ();
+                       TypeDescriptor.RemoveProvider (provider, null);
+               }
+
+               [Test]
+               public void TestRemoveProvider_Provider_Type_3 ()
+               {
+                       var provider = new MyTypeDescriptionProvider ();
+                       bool refreshedCalled = false;
+                       bool refreshedCorrectComponentChanged = false;
+                       bool refreshedCorrectTypeChanged = false;
+
+                       RefreshEventHandler handler = (RefreshEventArgs args) => {
+                               refreshedCalled = true;
+                               refreshedCorrectComponentChanged = args.ComponentChanged == null;
+                               refreshedCorrectTypeChanged = args.TypeChanged == typeof (string);
+                       };
+
+                       try {
+                               TypeDescriptor.Refreshed += handler;
+
+                               TypeDescriptor.RemoveProvider (provider, typeof (string));
+                               Assert.AreEqual (true, refreshedCalled, "#A1");
+                               Assert.AreEqual (true, refreshedCorrectComponentChanged, "#A2");
+                               Assert.AreEqual (true, refreshedCorrectTypeChanged, "#A3");
+                       } finally {
+                               TypeDescriptor.Refreshed -= handler;
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestRemoveProvider_Provider_Instance_1 ()
+               {
+                       TypeDescriptor.RemoveProvider (null, (object)null);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestRemoveProvider_Provider_Instance_2 ()
+               {
+                       var provider = new MyTypeDescriptionProvider ();
+                       TypeDescriptor.RemoveProvider (provider, (object)null);
+               }
+
+               [Test]
+               public void TestRemoveProvider_Provider_Instance_3 ()
+               {
+                       var instance = new MyComponent ();
+                       var provider = new MyTypeDescriptionProvider ();
+                       bool refreshedCalled = false;
+                       bool refreshedCorrectComponentChanged = false;
+                       bool refreshedCorrectTypeChanged = false;
+
+                       RefreshEventHandler handler = (RefreshEventArgs args) => {
+                               refreshedCalled = true;
+                               refreshedCorrectComponentChanged = args.ComponentChanged == instance;
+                               refreshedCorrectTypeChanged = args.TypeChanged == typeof (MyComponent);
+                       };
+
+                       try {
+                               TypeDescriptor.Refreshed += handler;
+
+                               TypeDescriptor.RemoveProvider (provider, instance);
+                               Assert.AreEqual (true, refreshedCalled, "#A1");
+                               Assert.AreEqual (true, refreshedCorrectComponentChanged, "#A2");
+                               Assert.AreEqual (true, refreshedCorrectTypeChanged, "#A3");
+                       } finally {
+                               TypeDescriptor.Refreshed -= handler;
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestGetReflectionType_Type_1 ()
+               {
+                       TypeDescriptor.GetReflectionType ((Type) null);
+               }
+
+               [Test]
+               public void TestGetReflectionType_Type_2 ()
+               {
+                       Type type = TypeDescriptor.GetReflectionType (typeof (string));
+                       Assert.IsNotNull (type, "#A1");
+                       Assert.AreEqual (typeof (string), type, "#A1-1");
+
+                       type = TypeDescriptor.GetReflectionType (typeof (MyComponent));
+                       Assert.IsNotNull (type, "#B1");
+                       Assert.AreEqual (typeof (MyComponent), type, "#B1-1");
+
+                       type = TypeDescriptor.GetReflectionType (typeof (List<string>));
+                       Assert.IsNotNull (type, "#C1");
+                       Assert.AreEqual (typeof (List <string>), type, "#C1-1");
+
+                       type = TypeDescriptor.GetReflectionType (typeof (IList<>));
+                       Assert.IsNotNull (type, "#D1");
+                       Assert.AreEqual (typeof (IList<>), type, "#D1-1");
+
+                       type = TypeDescriptor.GetReflectionType (typeof (IDictionary<,>));
+                       Assert.IsNotNull (type, "#E1");
+                       Assert.AreEqual (typeof (IDictionary<,>), type, "#E1-1");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void TestGetReflectionType_Instance_1 ()
+               {
+                       TypeDescriptor.GetReflectionType ((object) null);
+               }
+
+               [Test]
+               public void TestGetReflectionType_Instance_2 ()
+               {
+                       string s = "string";
+                       Type type = TypeDescriptor.GetReflectionType (s);
+                       Assert.IsNotNull (type, "#A1");
+                       Assert.AreEqual (typeof (string), type, "#A1-1");
+
+                       var mc = new MyComponent ();
+                       type = TypeDescriptor.GetReflectionType (mc);
+                       Assert.IsNotNull (type, "#B1");
+                       Assert.AreEqual (typeof (MyComponent), type, "#B1-1");
+
+                       var l = new List<string> ();
+                       type = TypeDescriptor.GetReflectionType (l);
+                       Assert.IsNotNull (type, "#C1");
+                       Assert.AreEqual (typeof (List<string>), type, "#C1-1");
+
+                       IList il = new List<string> ();
+                       type = TypeDescriptor.GetReflectionType (il);
+                       Assert.IsNotNull (type, "#D1");
+                       Assert.AreEqual (typeof (List<string>), type, "#D1-1");
+
+                       IDictionary id = new Dictionary<string, object> ();
+                       type = TypeDescriptor.GetReflectionType (id);
+                       Assert.IsNotNull (type, "#E1");
+                       Assert.AreEqual (typeof (Dictionary<string,object>), type, "#E1-1");
+
+                       object o = 1;
+                       type = TypeDescriptor.GetReflectionType (o);
+                       Assert.IsNotNull (type, "#F1");
+                       Assert.AreEqual (typeof (int), type, "#F1-1");
+               }
+#endif
+
                [Test]
                public void TestICustomTypeDescriptor ()
                {