Merge pull request #1659 from alexanderkyte/stringbuilder-referencesource
[mono.git] / mcs / class / corlib / Test / Microsoft.Win32 / RegistryKeyTest.cs
old mode 100644 (file)
new mode 100755 (executable)
index 87c3459..7279f71
 
 using System;
 using System.IO;
+using System.Runtime.InteropServices;
 
 using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
 
 using NUnit.Framework;
 
@@ -23,9 +25,9 @@ namespace MonoTests.Microsoft.Win32
        public class RegistryKeyTest
        {
                private const string mimeroot = @"MIME\Database\Content Type";
+
                [Test]
-               [Category("NotWorking")]
-               // This will not work on Linux ever
+               [Category ("NotWorking")] // this will not work on Linux ever
                public void TestGetValue ()
                {
                        RegistryKey root = Registry.ClassesRoot;
@@ -37,15 +39,12 @@ namespace MonoTests.Microsoft.Win32
                        Assert.AreEqual (null, key.GetValue ("Extension"), "GetValue #2");
                }
 
-               //
-               // Unit test for bug #77212
-               //
-               [Test]
+               [Test] // bug #77212
                public void TestHandle ()
                {
                        // this test is for Windows only
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        // this regpath always exists under windows
                        RegistryKey k = Registry.CurrentUser
@@ -127,13 +126,6 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
-               [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void OpenSubKey_Name_Null ()
-               {
-                       Registry.CurrentUser.OpenSubKey (null);
-               }
-
                [Test]
                [Category ("NotWorking")] // MS should not allow this
                public void OpenSubKey_Name_Empty ()
@@ -148,6 +140,60 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+               [Test]
+               public void OpenSubKey_Name_MaxLength ()
+               {
+                       string name = new string ('a', 254);
+
+                       Assert.IsNull (Registry.CurrentUser.OpenSubKey (name), "#A1");
+
+                       name = new string ('a', 255);
+
+                       Assert.IsNull (Registry.CurrentUser.OpenSubKey (name), "#B1");
+
+                       name = new string ('a', 256);
+
+                       try {
+                               Registry.CurrentUser.OpenSubKey (name);
+                               Assert.Fail ("#C1");
+                       } catch (ArgumentException ex) {
+                               // 1.x: Registry subkeys should not be
+                               // greater than or equal to 255 characters
+                               //
+                               // 2.x: Registry subkeys should not be
+                               // greater than 255 characters
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+                               Assert.IsNull (ex.InnerException, "#C3");
+                               Assert.IsNotNull (ex.Message, "#c4");
+                               Assert.IsTrue (ex.Message.IndexOf ("255") != -1, "#C5");
+                               Assert.IsNull (ex.ParamName, "#C6");
+                       }
+               }
+
+               [Test]
+               public void OpenSubKey_Name_Null ()
+               {
+                       try {
+                               Registry.CurrentUser.OpenSubKey (null);
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.AreEqual ("name", ex.ParamName, "#A5");
+                       }
+
+                       try {
+                               Registry.CurrentUser.OpenSubKey (null, true);
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.AreEqual ("name", ex.ParamName, "#B5");
+                       }
+               }
+
                [Test]
                public void Close_Local_Hive ()
                {
@@ -255,7 +301,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        RegistryKey hive = RegistryKey.OpenRemoteBaseKey (
                                RegistryHive.CurrentUser, Environment.MachineName);
@@ -345,7 +391,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        RegistryKey hive = RegistryKey.OpenRemoteBaseKey (
                                RegistryHive.CurrentUser, Environment.MachineName);
@@ -438,16 +484,45 @@ namespace MonoTests.Microsoft.Win32
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // check if key was successfully created
-                               Assert.IsNotNull (createdKey, "#1");
-                               // software subkey should not be created automatically
-                               Assert.IsNull (createdKey.OpenSubKey ("software"), "#2");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // check if key was successfully created
+                                       Assert.IsNotNull (createdKey, "#A1");
+                                       // software subkey should not be created automatically
+                                       Assert.IsNull (createdKey.OpenSubKey ("software"), "#A2");
+                               }
+
+                               using (RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       // check if key was successfully created
+                                       Assert.IsNotNull (createdKey, "#B1");
+                                       // software subkey should not be created automatically
+                                       Assert.IsNull (createdKey.OpenSubKey ("software"), "#B2");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
+
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                               // check if key was successfully created
+                                               Assert.IsNotNull (createdKey, "#C1");
+                                               // software subkey should not be created automatically
+                                               Assert.IsNull (softwareKey.OpenSubKey ("software"), "#C2");
+                                       }
+
+                                       using (RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName)) {
+                                               // check if key was successfully created
+                                               Assert.IsNotNull (createdKey, "#D1");
+                                               // software subkey should not be created automatically
+                                               Assert.IsNull (softwareKey.OpenSubKey ("software"), "#D2");
+                                       }
+                               } finally {
+                                       // clean-up
+                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                               }
+                       }
                }
 
                [Test]
@@ -521,13 +596,229 @@ namespace MonoTests.Microsoft.Win32
                }
 
                [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
+               public void CreateSubKey_Name_MaxLength ()
+               {
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               string subKeyName = new string ('a', 254);
+
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                               Assert.IsNotNull (createdKey, "#A1");
+                                               Assert.IsNotNull (softwareKey.OpenSubKey (subKeyName), "#A2");
+                                       }
+                               } finally {
+                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                               }
+
+                               subKeyName = new string ('a', 255);
+
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                               Assert.IsNotNull (createdKey, "#B1");
+                                               Assert.IsNotNull (softwareKey.OpenSubKey (subKeyName), "#B2");
+                                       }
+                               } finally {
+                                       softwareKey.DeleteSubKey (subKeyName);
+                               }
+
+                               subKeyName = new string ('a', 256);
+
+                               try {
+                                       softwareKey.CreateSubKey (subKeyName);
+                                       Assert.Fail ("#C1");
+                               } catch (ArgumentException ex) {
+                                       // 1.x: Registry subkeys should not be
+                                       // greater than or equal to 255 characters
+                                       //
+                                       // 2.x: Registry subkeys should not be
+                                       // greater than 255 characters
+                                       Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+                                       Assert.IsNull (ex.InnerException, "#C3");
+                                       Assert.IsNotNull (ex.Message, "#C4");
+                                       Assert.IsTrue (ex.Message.IndexOf ("255") != -1, "#C5");
+                                       Assert.IsNull (ex.ParamName, "#C6");
+                               }
+                       }
+               }
+
+               [Test]
                public void CreateSubKey_Name_Null ()
                {
                        using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
-                               softwareKey.CreateSubKey (null);
+                               try {
+                                       softwareKey.CreateSubKey (null);
+                                       Assert.Fail ("#1");
+                               } catch (ArgumentNullException ex) {
+                                       Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                                       Assert.IsNull (ex.InnerException, "#3");
+                                       Assert.IsNotNull (ex.Message, "#4");
+                                       Assert.AreEqual ("name", ex.ParamName, "#5");
+                               }
+                       }
+               }
+
+#if NET_4_0
+               // Unfortunately we can't test that the scenario where a volatile
+               // key is not alive after a reboot, but we can test other bits.
+               [Test]
+               public void CreateSubKey_Volatile ()
+               {
+                       RegistryKey key = null;
+                       RegistryKey subkey = null;
+                       string subKeyName = "VolatileKey";
+
+                       try {
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               subkey = key.CreateSubKey ("Child", RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key.Close ();
+
+                               key = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               subkey = key.OpenSubKey ("Child");
+                               Assert.AreEqual (true, subkey != null, "#A1");
+                       } finally {
+                               if (subkey != null)
+                                       subkey.Close ();
+                               if (key != null)
+                                       key.Close ();
+                       }
+               }
+
+               [Test]
+               public void CreateSubKey_Volatile_Child ()
+               {
+                       RegistryKey key = null;
+                       RegistryKey subkey = null;
+                       string subKeyName = "VolatileKey";
+
+                       try {
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               subkey = key.CreateSubKey ("Child"); // Non volatile child
+                               Assert.Fail ("#Exc");
+                       } catch (IOException) {
+                       } finally {
+                               if (subkey != null)
+                                       subkey.Close ();
+                               if (key != null)
+                                       key.Close ();
+                       }
+               }
+
+               [Test]
+               public void CreateSubKey_Volatile_Conflict ()
+               {
+                       RegistryKey key = null;
+                       RegistryKey key2 = null;
+                       RegistryKey subkey = null;
+                       string subKeyName = "VolatileKey";
+
+                       try {
+                               // 
+                               // Create a volatile key and try to open it as a normal one
+                               //
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key2 = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
+                               Assert.AreEqual (key.Name, key2.Name, "A0");
+
+                               subkey = key2.CreateSubKey ("Child", RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               Assert.AreEqual (true, key.OpenSubKey ("Child") != null, "#A1");
+                               Assert.AreEqual (true, key2.OpenSubKey ("Child") != null, "#A2");
+
+                               subkey.Close ();
+                               key.Close ();
+                               key2.Close ();
+
+                               // 
+                               // Create a non-volatile key and try to open it as a volatile one
+                               //
+                               subKeyName = "NonVolatileKey";
+                               key2 = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
+                               key2.SetValue ("Name", "Mono");
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               Assert.AreEqual (key.Name, key2.Name, "B0");
+                               Assert.AreEqual ("Mono", key.GetValue ("Name"), "#B1");
+                               Assert.AreEqual ("Mono", key2.GetValue ("Name"), "#B2");
+
+                               key.CreateSubKey ("Child");
+                               Assert.AreEqual (true, key.OpenSubKey ("Child") != null, "#B3");
+                               Assert.AreEqual (true, key2.OpenSubKey ("Child") != null, "#B4");
+
+                               // 
+                               // Close the non-volatile key and try to re-open it as a volatile one
+                               //
+                               key.Close ();
+                               key2.Close ();
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               Assert.AreEqual ("Mono", key.GetValue ("Name"), "#C0");
+                               Assert.AreEqual (true, key.OpenSubKey ("Child") != null, "#C1");
+                       } finally {
+                               if (subkey != null)
+                                       subkey.Close ();
+                               if (key != null)
+                                       key.Close ();
+                               if (key2 != null)
+                                       key2.Close ();
+                       }
+               }
+
+               [Test]
+               public void DeleteSubKey_Volatile ()
+               {                       
+                       RegistryKey key = null;
+                       RegistryKey subkey = null;
+                       string subKeyName = "VolatileKey";
+
+                       try {
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key.CreateSubKey ("VolatileKeyChild", RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key.SetValue ("Name", "Mono");
+                               key.Close ();
+
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+
+                               key = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               Assert.AreEqual (null, key, "#A0");
+                       } finally {
+                               if (subkey != null)
+                                       subkey.Close ();
+                               if (key != null)
+                                       key.Close ();
+                       }
+               }
+
+               // Define a normal key, and create a normal and a volatile key under it, and retrieve their names.
+               [Test]
+               public void GetSubKeyNames_Volatile ()
+               {           
+                       RegistryKey key = null;
+                       RegistryKey subkey = null;
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       string volChildKeyName = "volatilechildkey";
+                       string childKeyName = "childkey";
+
+                       try {
+                               key = Registry.CurrentUser.CreateSubKey (subKeyName);
+                               key.CreateSubKey (volChildKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.Volatile);
+                               key.CreateSubKey (childKeyName, RegistryKeyPermissionCheck.Default, RegistryOptions.None);
+                               key.Close ();
+
+                               key = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               string [] keyNames = key.GetSubKeyNames ();
+
+                               // we can guarantee the order of the child keys, so we sort the two of them
+                               Array.Sort (keyNames);
+
+                               Assert.AreEqual (2, keyNames.Length, "#A0");
+                               Assert.AreEqual (childKeyName, keyNames [0], "#A1");
+                               Assert.AreEqual (volChildKeyName, keyNames [1], "#A2");
+                       } finally {
+                               if (subkey != null)
+                                       subkey.Close ();
+                               if (key != null)
+                                       key.Close ();
                        }
+
                }
+#endif
 
                [Test]
                public void DeleteSubKey ()
@@ -639,8 +930,9 @@ namespace MonoTests.Microsoft.Win32
                        } catch (ArgumentException ex) {
                                // Cannot delete a subkey tree because the subkey does not exist
                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
-                               Assert.IsNotNull (ex.Message, "#A3");
-                               Assert.IsNull (ex.InnerException, "#A4");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsNull (ex.ParamName, "#A5");
                        }
 
                        try {
@@ -649,8 +941,9 @@ namespace MonoTests.Microsoft.Win32
                        } catch (ArgumentException ex) {
                                // Cannot delete a subkey tree because the subkey does not exist
                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
-                               Assert.IsNotNull (ex.Message, "#B3");
-                               Assert.IsNull (ex.InnerException, "#B4");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsNull (ex.ParamName, "#B5");
                        }
 
                        Registry.CurrentUser.DeleteSubKey (subKeyName, false);
@@ -682,8 +975,9 @@ namespace MonoTests.Microsoft.Win32
                                                // Cannot delete a subkey tree because the subkey does
                                                // not exist
                                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#6");
-                                               Assert.IsNotNull (ex.Message, "#7");
-                                               Assert.IsNull (ex.InnerException, "#8");
+                                               Assert.IsNull (ex.InnerException, "#7");
+                                               Assert.IsNotNull (ex.Message, "#8");
+                                               Assert.IsNull (ex.ParamName, "#9");
                                        }
                                }
                        } finally {
@@ -724,6 +1018,43 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+               [Test]
+               public void DeleteSubKey_Name_MaxLength ()
+               {
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               string subKeyName = new string ('a', 254);
+
+                               using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                       createdKey.Close ();
+                               }
+                               using (RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName, false)) {
+                                       Assert.IsNotNull (createdKey, "#A1");
+                               }
+                               softwareKey.DeleteSubKey (subKeyName);
+                               using (RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName, false)) {
+                                       Assert.IsNull (createdKey, "#A2");
+                               }
+
+                               subKeyName = new string ('a', 256);
+
+                               try {
+                                       softwareKey.DeleteSubKey (subKeyName);
+                                       Assert.Fail ("#B1");
+                               } catch (ArgumentException ex) {
+                                       // 1.x: Registry subkeys should not be
+                                       // greater than or equal to 255 characters
+                                       //
+                                       // 2.x: Registry subkeys should not be
+                                       // greater than 255 characters
+                                       Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                                       Assert.IsNull (ex.InnerException, "#B3");
+                                       Assert.IsNotNull (ex.Message, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf ("255") != -1, "#B5");
+                                       Assert.IsNull (ex.ParamName, "#B6");
+                               }
+                       }
+               }
+
                [Test]
                public void DeleteSubKey_Name_Null ()
                {
@@ -736,10 +1067,10 @@ namespace MonoTests.Microsoft.Win32
                                                createdKey.DeleteSubKey (null);
                                                Assert.Fail ("#1");
                                        } catch (ArgumentNullException ex) {
-                                               // Value cannot be null. Parameter name: subkey
                                                Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
-                                               Assert.IsNotNull (ex.Message, "#3");
-                                               Assert.IsNull (ex.InnerException, "#4");
+                                               Assert.IsNull (ex.InnerException, "#3");
+                                               Assert.IsNotNull (ex.Message, "#4");
+                                               Assert.AreEqual ("name", ex.ParamName, "#5");
                                        }
                                } finally {
                                        try {
@@ -763,13 +1094,41 @@ namespace MonoTests.Microsoft.Win32
                }
 
                [Test]
-               [ExpectedException (typeof (ArgumentException))]
                public void DeleteSubKeyTree_Key_DoesNotExist ()
                {
                        // Cannot delete a subkey tree because the subkey does not exist
                        string subKeyName = Guid.NewGuid ().ToString ();
-                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                       try {
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNull (ex.ParamName, "#5");
+                       }
+               }
+
+#if NET_4_0
+               [Test]
+               public void DeleteSubKeyTree_Key_DoesNotExist_Overload ()
+               {
+                       // Cannot delete a subkey tree because the subkey does not exist
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       try {
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName, true);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentException ex) {
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNull (ex.ParamName, "#5");
+                       }
+
+                       // It's enough to know this line is not throwing an exception.
+                       Registry.CurrentUser.DeleteSubKey (subKeyName, false);
                }
+#endif
 
                [Test]
                public void DeleteSubKeyTree_Key_ReadOnly ()
@@ -832,8 +1191,9 @@ namespace MonoTests.Microsoft.Win32
                                                // Cannot delete a subkey tree because the subkey does
                                                // not exist
                                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#6");
-                                               Assert.IsNotNull (ex.Message, "#7");
-                                               Assert.IsNull (ex.InnerException, "#8");
+                                               Assert.IsNull (ex.InnerException, "#7");
+                                               Assert.IsNotNull (ex.Message, "#8");
+                                               Assert.IsNull (ex.ParamName, "#9");
                                        }
                                }
                        } finally {
@@ -874,6 +1234,43 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+               [Test]
+               public void DeleteSubKeyTree_Name_MaxLength ()
+               {
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               string subKeyName = new string ('a', 254);
+
+                               using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                       createdKey.Close ();
+                               }
+                               using (RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName, false)) {
+                                       Assert.IsNotNull (createdKey, "#A1");
+                               }
+                               softwareKey.DeleteSubKeyTree (subKeyName);
+                               using (RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName, false)) {
+                                       Assert.IsNull (createdKey, "#A2");
+                               }
+
+                               subKeyName = new string ('a', 256);
+
+                               try {
+                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                                       Assert.Fail ("#B1");
+                               } catch (ArgumentException ex) {
+                                       // 1.x: Registry subkeys should not be
+                                       // greater than or equal to 255 characters
+                                       //
+                                       // 2.x: Registry subkeys should not be
+                                       // greater than 255 characters
+                                       Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                                       Assert.IsNull (ex.InnerException, "#B3");
+                                       Assert.IsNotNull (ex.Message, "#B4");
+                                       Assert.IsTrue (ex.Message.IndexOf ("255") != -1, "#B5");
+                                       Assert.IsNull (ex.ParamName, "#B6");
+                               }
+                       }
+               }
+
                [Test]
                public void DeleteSubKeyTree_Name_Null ()
                {
@@ -882,10 +1279,10 @@ namespace MonoTests.Microsoft.Win32
                                        softwareKey.DeleteSubKeyTree (null);
                                        Assert.Fail ("#1");
                                } catch (ArgumentNullException ex) {
-                                       // Value cannot be null. Parameter name: subkey
                                        Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
-                                       Assert.IsNotNull (ex.Message, "#3");
-                                       Assert.IsNull (ex.InnerException, "#4");
+                                       Assert.IsNull (ex.InnerException, "#3");
+                                       Assert.IsNotNull (ex.Message, "#4");
+                                       Assert.AreEqual ("name", ex.ParamName, "#5");
                                }
                        }
                }
@@ -922,6 +1319,7 @@ namespace MonoTests.Microsoft.Win32
                                        Assert.AreEqual ("name2", names [0], "#B5");
                                        Assert.IsNotNull (createdKey.GetValue ("name2"), "#B6");
                                        Assert.AreEqual ("value2", createdKey.GetValue ("name2"), "#B7");
+                                       createdKey.DeleteValue (new string ('a', 400), false);
                                }
                                using (RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
                                        string [] names = createdKey.GetValueNames ();
@@ -1082,8 +1480,9 @@ namespace MonoTests.Microsoft.Win32
                                        } catch (ArgumentException ex) {
                                                // No value exists with that name
                                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
-                                               Assert.IsNotNull (ex.Message, "#B3");
-                                               Assert.IsNull (ex.InnerException, "#B4");
+                                               Assert.IsNull (ex.InnerException, "#B3");
+                                               Assert.IsNotNull (ex.Message, "#B4");
+                                               Assert.IsNull (ex.ParamName, "#B5");
                                        }
 
                                        try {
@@ -1092,8 +1491,9 @@ namespace MonoTests.Microsoft.Win32
                                        } catch (ArgumentException ex) {
                                                // No value exists with that name
                                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
-                                               Assert.IsNotNull (ex.Message, "#C3");
-                                               Assert.IsNull (ex.InnerException, "#C4");
+                                               Assert.IsNull (ex.InnerException, "#C3");
+                                               Assert.IsNotNull (ex.Message, "#C4");
+                                               Assert.IsNull (ex.ParamName, "#C5");
                                        }
 
                                        createdKey.DeleteValue ("name2", false);
@@ -1152,8 +1552,9 @@ namespace MonoTests.Microsoft.Win32
                                        } catch (ArgumentException ex) {
                                                // No value exists with that name
                                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
-                                               Assert.IsNotNull (ex.Message, "#C3");
-                                               Assert.IsNull (ex.InnerException, "#C4");
+                                               Assert.IsNull (ex.InnerException, "#C3");
+                                               Assert.IsNotNull (ex.Message, "#C4");
+                                               Assert.IsNull (ex.ParamName, "#C5");
                                        }
 
                                        try {
@@ -1162,8 +1563,9 @@ namespace MonoTests.Microsoft.Win32
                                        } catch (ArgumentException ex) {
                                                // No value exists with that name
                                                Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
-                                               Assert.IsNotNull (ex.Message, "#D3");
-                                               Assert.IsNull (ex.InnerException, "#D4");
+                                               Assert.IsNull (ex.InnerException, "#D3");
+                                               Assert.IsNotNull (ex.Message, "#D4");
+                                               Assert.IsNull (ex.ParamName, "#D5");
                                        }
 
                                        createdKey.DeleteValue (string.Empty, false);
@@ -1218,30 +1620,30 @@ namespace MonoTests.Microsoft.Win32
                                                createdKey.DeleteValue (null);
                                                Assert.Fail ("#B1");
                                        } catch (ArgumentNullException ex) {
-                                               // Value cannot be null. Parameter name: name
                                                Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
-                                               Assert.IsNotNull (ex.Message, "#B3");
-                                               Assert.IsNull (ex.InnerException, "#B4");
+                                               Assert.IsNull (ex.InnerException, "#B3");
+                                               Assert.IsNotNull (ex.Message, "#B4");
+                                               Assert.AreEqual ("name", ex.ParamName, "#B5");
                                        }
 
                                        try {
                                                createdKey.DeleteValue (null, true);
                                                Assert.Fail ("#C1");
                                        } catch (ArgumentNullException ex) {
-                                               // Value cannot be null. Parameter name: name
                                                Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
-                                               Assert.IsNotNull (ex.Message, "#C3");
-                                               Assert.IsNull (ex.InnerException, "#C4");
+                                               Assert.IsNull (ex.InnerException, "#C3");
+                                               Assert.IsNotNull (ex.Message, "#C4");
+                                               Assert.AreEqual ("name", ex.ParamName, "#C5");
                                        }
 
                                        try {
                                                createdKey.DeleteValue (null, false);
                                                Assert.Fail ("#D1");
                                        } catch (ArgumentNullException ex) {
-                                               // Value cannot be null. Parameter name: name
                                                Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#D2");
-                                               Assert.IsNotNull (ex.Message, "#D3");
-                                               Assert.IsNull (ex.InnerException, "#D4");
+                                               Assert.IsNull (ex.InnerException, "#D3");
+                                               Assert.IsNotNull (ex.Message, "#D4");
+                                               Assert.AreEqual ("name", ex.ParamName, "#D5");
                                        }
                                }
                        } finally {
@@ -1256,6 +1658,102 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+#if NET_4_0
+               [DllImport ("advapi32.dll", CharSet = CharSet.Unicode)]
+               static extern int RegOpenKeyEx (IntPtr keyBase, string keyName, IntPtr reserved, int access, out IntPtr keyHandle);
+        
+               const int RegCurrentUserHive = -2147483647;
+               const int RegAccessRead = 0x00020019;
+
+               // FromHandle is specially designed to retrieve a RegistryKey instance based on a IntPtr
+               // retrieved using any unmanaged registry function, so we use directly RegOpenKeyEx to load
+               // our handle and then pass it to the new 4.0 method.
+               [Test]
+               public void FromHandle ()
+               {
+                       // Not supported on Unix
+                       if (RunningOnUnix)
+                               Assert.Ignore ("Running on Unix.");
+
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       try {
+                               using (RegistryKey key = Registry.CurrentUser.CreateSubKey (subKeyName))
+                                       key.SetValue ("Name", "Mono001");
+
+                               IntPtr handle;
+                               int res = RegOpenKeyEx (new IntPtr (RegCurrentUserHive), subKeyName, IntPtr.Zero, RegAccessRead, out handle);
+
+                               using (RegistryKey key = RegistryKey.FromHandle (new SafeRegistryHandle (handle, true))) {
+                                       Assert.AreEqual (String.Empty, key.Name, "#A0");
+                                       Assert.AreEqual ("Mono001", key.GetValue ("Name"), "#A1");
+                               }
+                       } finally {
+                               RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               if (createdKey != null) {
+                                       createdKey.Close ();
+                                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                               }
+                       }
+               }
+
+               [Test]
+               public void FromHandle_InvalidHandle ()
+               {
+                       // Not supported on Unix
+                       if (RunningOnUnix)
+                               Assert.Ignore ("Running on Unix.");
+
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       try {
+                               using (RegistryKey key = RegistryKey.FromHandle (new SafeRegistryHandle (IntPtr.Zero, true))) {
+                                       Assert.AreEqual (String.Empty, key.Name, "#A0");
+
+                                       // Any operation should throw a IOException, since even if we have a RegistryKey instance,
+                                       // the handle is not valid.
+                                       key.CreateSubKey ("ChildSubKey");
+                                       Assert.Fail ("#Exc0");
+                               }
+                       } catch (IOException) {
+                       } finally {
+                               RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName);
+                               if (createdKey != null) {
+                                       createdKey.Close ();
+                                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                               }
+                       }
+               }
+
+               [Test]
+               public void Handle ()
+               {
+                       if (RunningOnUnix)
+                               Assert.Ignore ("Running on Unix.");
+
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       RegistryKey subkey = null;
+                       try {
+                               subkey = Registry.CurrentUser.CreateSubKey (subKeyName);
+                               Assert.AreEqual (true, subkey.Handle != null, "#A0");
+                               Assert.AreEqual (false, subkey.Handle.IsClosed, "#A1");
+                               Assert.AreEqual (false, subkey.Handle.IsInvalid, "#A2");
+
+                               subkey.Close ();
+                               try {
+                                       if (subkey.Handle != null)
+                                               Console.WriteLine (); // Avoids a warning at compile time
+                                       Assert.Fail ("#Disposed");
+                               } catch (ObjectDisposedException) {
+                               }
+
+                       } finally {
+                               if (subkey != null) {
+                                       subkey.Close ();
+                                       Registry.CurrentUser.DeleteSubKeyTree (subKeyName, false);
+                               }
+                       }
+               }
+#endif
+
                [Test]
                public void GetValue ()
                {
@@ -1275,6 +1773,7 @@ namespace MonoTests.Microsoft.Win32
                                        Assert.IsNull (createdKey.GetValue ("name3"), "#5");
                                        Assert.AreEqual ("value3", createdKey.GetValue ("name3", "value3"), "#6");
                                        Assert.IsNull (createdKey.GetValue ("name3", null), "#7");
+                                       Assert.IsNull (createdKey.GetValue (new string ('a', 400)), "#8");
                                }
                        } finally {
                                try {
@@ -1419,7 +1918,6 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
-#if NET_2_0
                [Test]
                public void GetValue_Expand ()
                {
@@ -1518,7 +2016,6 @@ namespace MonoTests.Microsoft.Win32
                                }
                        }
                }
-#endif
 
                [Test]
                public void GetValueNames ()
@@ -1672,7 +2169,7 @@ namespace MonoTests.Microsoft.Win32
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        RegistryKey hive = RegistryKey.OpenRemoteBaseKey (
                                RegistryHive.CurrentUser, Environment.MachineName);
@@ -1686,18 +2183,27 @@ namespace MonoTests.Microsoft.Win32
                }
 
                [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
                public void OpenRemoteBaseKey_MachineName_Null ()
                {
-                       RegistryKey.OpenRemoteBaseKey (RegistryHive.CurrentUser, null);
+                       try {
+                               RegistryKey.OpenRemoteBaseKey (RegistryHive.CurrentUser, null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.AreEqual ("machineName", ex.ParamName, "#5");
+                       }
                }
 
                [Test]
+               // This hangs on windows
+               [Category ("NotWorking")]
                public void OpenRemoteBaseKey_MachineName_DoesNotExist ()
                {
                        // access to registry of remote machines is not implemented on unix
                        if (RunningOnUnix)
-                               return;
+                               Assert.Ignore ("Running on Unix.");
 
                        try {
                                RegistryKey.OpenRemoteBaseKey (RegistryHive.CurrentUser,
@@ -1711,20 +2217,71 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
-               [Test]
-               public void SetValue_Name_Null ()
+               [Test] // bug #322839
+               public void SetValue1_EntityReferences ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               createdKey.SetValue (null, "value1");
-                               string [] names = createdKey.GetValueNames ();
-                               Assert.IsNotNull (names, "#A1");
-                               Assert.AreEqual (1, names.Length, "#A2");
-                               Assert.IsNotNull (names [0], "#A3");
-                               Assert.AreEqual (string.Empty, names [0], "#A4");
-                               Assert.IsNotNull (createdKey.GetValue (string.Empty), "#A5");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("FirstName&\"<LastName>\""), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("FirstName&\"<LastName>\"", "<'Miguel' & \"de Icaza\">!");
+                                       // get value
+                                       object name = createdKey.GetValue ("FirstName&\"<LastName>\"");
+                                       // value should exist
+                                       Assert.IsNotNull (name, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string), name.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual ("<'Miguel' & \"de Icaza\">!", name, "#A4");
+
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Info"), "#B1");
+                                       // create value
+                                       createdKey.SetValue ("Info", new string [] { "Mono&<Novell>!", "<CLR&BCL>" });
+                                       // get value
+                                       object info = createdKey.GetValue ("Info");
+                                       // value should exist
+                                       Assert.IsNotNull (info, "#B2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string []), info.GetType (), "#B3");
+                                       // ensure value matches
+                                       Assert.AreEqual (new string [] { "Mono&<Novell>!", "<CLR&BCL>" }, info, "#B4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object name = openedKey.GetValue ("FirstName&\"<LastName>\"");
+                                       Assert.IsNotNull (name, "#C1");
+                                       Assert.AreEqual (typeof (string), name.GetType (), "#C2");
+                                       Assert.AreEqual ("<'Miguel' & \"de Icaza\">!", name, "#C3");
+
+                                       object info = openedKey.GetValue ("Info");
+                                       Assert.IsNotNull (info, "#D1");
+                                       Assert.AreEqual (typeof (string []), info.GetType (), "#D2");
+                                       Assert.AreEqual (new string [] { "Mono&<Novell>!", "<CLR&BCL>" }, info, "#D3");
+                               }
+                       } finally {
+                               // clean-up
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                       }
+               }
+
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Name_Null ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
+                       try {
+                               createdKey.SetValue (null, "value1");
+                               string [] names = createdKey.GetValueNames ();
+                               Assert.IsNotNull (names, "#A1");
+                               Assert.AreEqual (1, names.Length, "#A2");
+                               Assert.IsNotNull (names [0], "#A3");
+                               Assert.AreEqual (string.Empty, names [0], "#A4");
+                               Assert.IsNotNull (createdKey.GetValue (string.Empty), "#A5");
                                Assert.AreEqual ("value1", createdKey.GetValue (string.Empty), "#A6");
                                Assert.IsNotNull (createdKey.GetValue (null), "#A7");
                                Assert.AreEqual ("value1", createdKey.GetValue (null), "#A8");
@@ -1745,8 +2302,8 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
-               [Test]
-               public void SetValue_Name_Empty ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Name_Empty ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
@@ -1779,118 +2336,207 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
-               [Test]
-               [ExpectedException (typeof (ArgumentNullException))]
-               public void SetValue_Null ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Name_MaxLength ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       try {
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       string name = new string ('a', 254);
+
+                                       createdKey.SetValue (name, "value1");
+                                       Assert.IsNotNull (createdKey.GetValue (name), "#A1");
+                                       createdKey.DeleteValue (name);
+                                       Assert.IsNull (createdKey.GetValue (name), "#A2");
+
+                                       name = new string ('a', 255);
+
+                                       createdKey.SetValue (name, "value2");
+                                       Assert.IsNotNull (createdKey.GetValue (name), "#B1");
+                                       createdKey.DeleteValue (name);
+                                       Assert.IsNull (createdKey.GetValue (name), "#B2");
+
+                                       name = new string ('a', 256);
+
+                                       try {
+                                               createdKey.SetValue (name, "value2");
+                                               Assert.Fail ("#C1");
+                                       } catch (ArgumentException ex) {
+                                               // 1.x: Registry subkeys should not be
+                                               // greater than or equal to 255 characters
+                                               //
+                                               // 2.x: Registry subkeys should not be
+                                               // greater than 255 characters
+                                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+                                               Assert.IsNull (ex.InnerException, "#C3");
+                                               Assert.IsNotNull (ex.Message, "#C4");
+                                               Assert.IsTrue (ex.Message.IndexOf ("255") != -1, "#C5");
+                                               Assert.IsNull (ex.ParamName, "#C6");
+                                       }
+                               }
+                       } finally {
+                               try {
+                                       RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName);
+                                       if (createdKey != null) {
+                                               createdKey.Close ();
+                                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                                       }
+                               } catch {
+                               }
+                       }
+               }
+
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Value_Null ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
                        RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // null value should result in ArgumentNullException
-                               createdKey.SetValue ("Name", null);
+                               try {
+                                       createdKey.SetValue ("Name", null);
+                                       Assert.Fail ("#1");
+                               } catch (ArgumentNullException ex) {
+                                       Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                                       Assert.IsNull (ex.InnerException, "#3");
+                                       Assert.IsNotNull (ex.Message, "#4");
+                                       Assert.AreEqual ("value", ex.ParamName, "#5");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_Boolean ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Boolean ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("Installed"), "#1");
-                               // create value
-                               createdKey.SetValue ("Installed", true);
-                               // get value
-                               object value = createdKey.GetValue ("Installed");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (string), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual (true.ToString (), value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Installed"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("Installed", true);
+                                       // get value
+                                       object value = createdKey.GetValue ("Installed");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual (true.ToString (), value, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("Installed");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#B2");
+                                       Assert.AreEqual (true.ToString (), value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_Byte ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Byte ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("Flags"), "#1");
-                               // create value
-                               createdKey.SetValue ("Flags", (byte) 5);
-                               // get value
-                               object value = createdKey.GetValue ("Flags");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (string), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual ("5", value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Flags"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("Flags", (byte) 5);
+                                       // get value
+                                       object value = createdKey.GetValue ("Flags");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual ("5", value, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("Flags");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#B2");
+                                       Assert.AreEqual ("5", value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_ByteArray ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_ByteArray ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("Flags"), "#1");
-                               // create value
-                               createdKey.SetValue ("Flags", new byte[] { 1, 5 });
-                               // get value
-                               object value = createdKey.GetValue ("Flags");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (byte[]), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual (new byte[] { 1, 5 }, value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Flags"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("Flags", new byte [] { 1, 5 });
+                                       // get value
+                                       object value = createdKey.GetValue ("Flags");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (byte []), value.GetType (), "#3");
+                                       // ensure value matches
+                                       Assert.AreEqual (new byte [] { 1, 5 }, value, "#4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("Flags");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (byte []), value.GetType (), "#B2");
+                                       Assert.AreEqual (new byte [] { 1, 5 }, value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_DateTime ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_DateTime ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
                                object rawValue = DateTime.Now;
 
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("Path"), "#1");
-                               // create value
-                               createdKey.SetValue ("Path", rawValue);
-                               // get value
-                               object value = createdKey.GetValue ("Path");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (string), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual (rawValue.ToString (), value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Path"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("Path", rawValue);
+                                       // get value
+                                       object value = createdKey.GetValue ("Path");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual (rawValue.ToString (), value, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("Path");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#B2");
+                                       Assert.AreEqual (rawValue.ToString (), value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
@@ -1902,103 +2548,135 @@ namespace MonoTests.Microsoft.Win32
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("RefCount"), "#1");
-                               // create value
-                               createdKey.SetValue ("RefCount", 5);
-                               // get value
-                               object value = createdKey.GetValue ("RefCount");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be int
-                               Assert.AreEqual (typeof (int), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual (5, value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("RefCount"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("RefCount", 5);
+                                       // get value
+                                       object value = createdKey.GetValue ("RefCount");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be int
+                                       Assert.AreEqual (typeof (int), value.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual (5, value, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("RefCount");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (int), value.GetType (), "#B2");
+                                       Assert.AreEqual (5, value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_Int64 ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Int64 ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("Ticks"), "#1");
-                               // create value
-                               createdKey.SetValue ("Ticks", 500L);
-                               // get value
-                               object value = createdKey.GetValue ("Ticks");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (string), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual ("500", value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Ticks"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("Ticks", 500L);
+                                       // get value
+                                       object value = createdKey.GetValue ("Ticks");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual ("500", value, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("Ticks");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (string), value.GetType (), "#B2");
+                                       Assert.AreEqual ("500", value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_String ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_String ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("Path"), "#1");
-                               // create value
-                               createdKey.SetValue ("Path", "/usr/lib/whatever");
-                               // get value
-                               object value = createdKey.GetValue ("Path");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (string), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual ("/usr/lib/whatever", value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("Path"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("Path", "/usr/lib/whatever");
+                                       // get value
+                                       object path = createdKey.GetValue ("Path");
+                                       // value should exist
+                                       Assert.IsNotNull (path, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string), path.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual ("/usr/lib/whatever", path, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object path = openedKey.GetValue ("Path");
+                                       Assert.IsNotNull (path, "#B1");
+                                       Assert.AreEqual (typeof (string), path.GetType (), "#B2");
+                                       Assert.AreEqual ("/usr/lib/whatever", path, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_StringArray ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_StringArray ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
-                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
                        try {
-                               // we created a new subkey, so value should not exist
-                               Assert.IsNull (createdKey.GetValue ("DependsOnGroup"), "#1");
-                               // create value
-                               createdKey.SetValue ("DependsOnGroup", new string[] { "A", "B" });
-                               // get value
-                               object value = createdKey.GetValue ("DependsOnGroup");
-                               // value should exist
-                               Assert.IsNotNull (value, "#2");
-                               // type of value should be string
-                               Assert.AreEqual (typeof (string[]), value.GetType (), "#3");
-                               // ensure value matches
-                               Assert.AreEqual (new string[] { "A", "B" }, value, "#4");
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       // we created a new subkey, so value should not exist
+                                       Assert.IsNull (createdKey.GetValue ("DependsOnGroup"), "#A1");
+                                       // create value
+                                       createdKey.SetValue ("DependsOnGroup", new string [] { "A", "B" });
+                                       // get value
+                                       object value = createdKey.GetValue ("DependsOnGroup");
+                                       // value should exist
+                                       Assert.IsNotNull (value, "#A2");
+                                       // type of value should be string
+                                       Assert.AreEqual (typeof (string []), value.GetType (), "#A3");
+                                       // ensure value matches
+                                       Assert.AreEqual (new string [] { "A", "B" }, value, "#A4");
+                               }
+
+                               using (RegistryKey openedKey = Registry.CurrentUser.OpenSubKey (subKeyName)) {
+                                       object value = openedKey.GetValue ("DependsOnGroup");
+                                       Assert.IsNotNull (value, "#B1");
+                                       Assert.AreEqual (typeof (string []), value.GetType (), "#B2");
+                                       Assert.AreEqual (new string [] { "A", "B" }, value, "#B3");
+                               }
                        } finally {
                                // clean-up
                                Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
                        }
                }
 
-               [Test]
-               public void SetValue_Key_ReadOnly ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Key_ReadOnly ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
@@ -2043,8 +2721,8 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
-               [Test]
-               public void SetValue_Key_Removed ()
+               [Test] // SetValue (String, Object)
+               public void SetValue1_Key_Removed ()
                {
                        string subKeyName = Guid.NewGuid ().ToString ();
 
@@ -2077,6 +2755,235 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+               [Test] // SetValue (String, Object, RegistryValueKind)
+               public void SetValue2_Key_ReadOnly ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software")) {
+                               try {
+                                       softwareKey.SetValue ("name1", "value1",
+                                               RegistryValueKind.String);
+                                       Assert.Fail ("#1");
+                               } catch (UnauthorizedAccessException ex) {
+                                       // Cannot write to the registry key
+                                       Assert.AreEqual (typeof (UnauthorizedAccessException), ex.GetType (), "#2");
+                                       Assert.IsNotNull (ex.Message, "#3");
+                                       Assert.IsNull (ex.InnerException, "#4");
+                               }
+                       }
+
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                       }
+
+                                       using (RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName)) {
+                                               try {
+                                                       createdKey.SetValue ("name1", "value1",
+                                                               RegistryValueKind.String);
+                                                       Assert.Fail ("#1");
+                                               } catch (UnauthorizedAccessException ex) {
+                                                       // Cannot write to the registry key
+                                                       Assert.AreEqual (typeof (UnauthorizedAccessException), ex.GetType (), "#2");
+                                                       Assert.IsNotNull (ex.Message, "#3");
+                                                       Assert.IsNull (ex.InnerException, "#4");
+                                               }
+                                       }
+                               } finally {
+                                       try {
+                                               RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName);
+                                               if (createdKey != null) {
+                                                       createdKey.Close ();
+                                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                                               }
+                                       } catch {
+                                       }
+                               }
+                       }
+               }
+
+               [Test] // SetValue (String, Object, RegistryValueKind)
+               public void SetValue2_Key_Removed ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                               softwareKey.DeleteSubKeyTree (subKeyName);
+                                               Assert.IsNull (softwareKey.OpenSubKey (subKeyName), "#1");
+                                               try {
+                                                       createdKey.SetValue ("name1", "value1",
+                                                               RegistryValueKind.String);
+                                                       Assert.Fail ("#2");
+                                               } catch (IOException ex) {
+                                                       // Illegal operation attempted on a registry key that
+                                                       // has been marked for deletion
+                                                       Assert.AreEqual (typeof (IOException), ex.GetType (), "#3");
+                                                       Assert.IsNotNull (ex.Message, "#4");
+                                                       Assert.IsNull (ex.InnerException, "#5");
+                                               }
+                                       }
+                               } finally {
+                                       try {
+                                               RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName);
+                                               if (createdKey != null) {
+                                                       createdKey.Close ();
+                                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                                               }
+                                       } catch {
+                                       }
+                               }
+                       }
+               }
+
+               [Test] // SetValue (String, Object, RegistryValueKind)
+               public void SetValue2_Name_Empty ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
+                       try {
+                               createdKey.SetValue (string.Empty, "value1",
+                                       RegistryValueKind.String);
+                               string [] names = createdKey.GetValueNames ();
+                               Assert.IsNotNull (names, "#A1");
+                               Assert.AreEqual (1, names.Length, "#A2");
+                               Assert.IsNotNull (names [0], "#A3");
+                               Assert.AreEqual (string.Empty, names [0], "#A4");
+                               Assert.IsNotNull (createdKey.GetValue (string.Empty), "#A5");
+                               Assert.AreEqual ("value1", createdKey.GetValue (string.Empty), "#A6");
+                               Assert.IsNotNull (createdKey.GetValue (null), "#A7");
+                               Assert.AreEqual ("value1", createdKey.GetValue (null), "#A8");
+
+                               createdKey.SetValue (null, "value2",
+                                       RegistryValueKind.String);
+                               names = createdKey.GetValueNames ();
+                               Assert.IsNotNull (names, "#B1");
+                               Assert.AreEqual (1, names.Length, "#B2");
+                               Assert.IsNotNull (names [0], "#B3");
+                               Assert.AreEqual (string.Empty, names [0], "#B4");
+                               Assert.IsNotNull (createdKey.GetValue (string.Empty), "#B5");
+                               Assert.AreEqual ("value2", createdKey.GetValue (string.Empty), "#B6");
+                               Assert.IsNotNull (createdKey.GetValue (null), "#B7");
+                               Assert.AreEqual ("value2", createdKey.GetValue (null), "#B8");
+                       } finally {
+                               // clean-up
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                       }
+               }
+
+               [Test] // SetValue (String, Object, RegistryValueKind)
+               public void SetValue2_Name_MaxLength ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       try {
+                               using (RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName)) {
+                                       string name = new string ('a', 254);
+
+                                       createdKey.SetValue (name, "value1",
+                                               RegistryValueKind.String);
+                                       Assert.IsNotNull (createdKey.GetValue (name), "#A1");
+                                       createdKey.DeleteValue (name);
+                                       Assert.IsNull (createdKey.GetValue (name), "#A2");
+
+                                       name = new string ('a', 255);
+
+                                       createdKey.SetValue (name, "value2",
+                                               RegistryValueKind.String);
+                                       Assert.IsNotNull (createdKey.GetValue (name), "#B1");
+                                       createdKey.DeleteValue (name);
+                                       Assert.IsNull (createdKey.GetValue (name), "#B2");
+
+                                       name = new string ('a', 256);
+
+                                       try {
+                                               createdKey.SetValue (name, "value2",
+                                                       RegistryValueKind.String);
+                                               Assert.Fail ("#C1");
+                                       } catch (ArgumentException ex) {
+                                               // Registry subkeys should not be
+                                               // greater than 255 characters
+                                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+                                               Assert.IsNull (ex.InnerException, "#C3");
+                                               Assert.IsNotNull (ex.Message, "#C4");
+                                               Assert.IsTrue (ex.Message.IndexOf ("255") != -1, "#C5");
+                                               Assert.IsNull (ex.ParamName, "#C6");
+                                       }
+                               }
+                       } finally {
+                               try {
+                                       RegistryKey createdKey = Registry.CurrentUser.OpenSubKey (subKeyName);
+                                       if (createdKey != null) {
+                                               createdKey.Close ();
+                                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                                       }
+                               } catch {
+                               }
+                       }
+               }
+
+               [Test] // SetValue (String, Object, RegistryValueKind)
+               public void SetValue2_Name_Null ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
+                       try {
+                               createdKey.SetValue (null, "value1",
+                                       RegistryValueKind.String);
+                               string [] names = createdKey.GetValueNames ();
+                               Assert.IsNotNull (names, "#A1");
+                               Assert.AreEqual (1, names.Length, "#A2");
+                               Assert.IsNotNull (names [0], "#A3");
+                               Assert.AreEqual (string.Empty, names [0], "#A4");
+                               Assert.IsNotNull (createdKey.GetValue (string.Empty), "#A5");
+                               Assert.AreEqual ("value1", createdKey.GetValue (string.Empty), "#A6");
+                               Assert.IsNotNull (createdKey.GetValue (null), "#A7");
+                               Assert.AreEqual ("value1", createdKey.GetValue (null), "#A8");
+
+                               createdKey.SetValue (string.Empty, "value2",
+                                       RegistryValueKind.String);
+                               names = createdKey.GetValueNames ();
+                               Assert.IsNotNull (names, "#B1");
+                               Assert.AreEqual (1, names.Length, "#B2");
+                               Assert.IsNotNull (names [0], "#B3");
+                               Assert.AreEqual (string.Empty, names [0], "#B4");
+                               Assert.IsNotNull (createdKey.GetValue (string.Empty), "#B5");
+                               Assert.AreEqual ("value2", createdKey.GetValue (string.Empty), "#B6");
+                               Assert.IsNotNull (createdKey.GetValue (null), "#B7");
+                               Assert.AreEqual ("value2", createdKey.GetValue (null), "#B8");
+                       } finally {
+                               // clean-up
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                       }
+               }
+
+               [Test] // SetValue (String, Object, RegistryValueKind)
+               public void SetValue2_Value_Null ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+
+                       RegistryKey createdKey = Registry.CurrentUser.CreateSubKey (subKeyName);
+                       try {
+                               try {
+                                       createdKey.SetValue ("Name", null,
+                                               RegistryValueKind.String);
+                                       Assert.Fail ("#1");
+                               } catch (ArgumentNullException ex) {
+                                       Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                                       Assert.IsNull (ex.InnerException, "#3");
+                                       Assert.IsNotNull (ex.Message, "#4");
+                                       Assert.AreEqual ("value", ex.ParamName, "#5");
+                               }
+                       } finally {
+                               // clean-up
+                               Registry.CurrentUser.DeleteSubKeyTree (subKeyName);
+                       }
+               }
+
                [Test]
                public void SubKeyCount ()
                {
@@ -2282,6 +3189,122 @@ namespace MonoTests.Microsoft.Win32
                        }
                }
 
+               // Bug Xamarin 3632
+               [Test]
+               public void TypeCastTests ()
+               {
+                       string subKeyName = Guid.NewGuid ().ToString ();
+                       using (RegistryKey softwareKey = Registry.CurrentUser.OpenSubKey ("software", true)) {
+                               try {
+                                       using (RegistryKey createdKey = softwareKey.CreateSubKey (subKeyName)) {
+                                               createdKey.SetValue ("test-int", (int) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-uint", (uint) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-byte", (byte) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-sbyte", (sbyte) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-short", (short) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-ushort", (ushort) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-long", (long) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-ulong", (ulong) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-decimal", (decimal) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-float", (float) 1, RegistryValueKind.DWord);
+                                               createdKey.SetValue ("test-bool", true, RegistryValueKind.DWord);
+
+                                               createdKey.SetValue ("dtest-int", (int) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-uint", (uint) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-byte", (byte) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-sbyte", (sbyte) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-short", (short) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-ushort", (ushort) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-long", (long) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-ulong", (ulong) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-decimal", (decimal) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-float", (float) 1, RegistryValueKind.QWord);
+                                               createdKey.SetValue ("dtest-bool", true, RegistryValueKind.QWord);
+
+                                               object r = createdKey.GetValue ("test-int");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               
+                                               r = createdKey.GetValue ("test-uint");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-byte");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-sbyte");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-short");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-ushort");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-long");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+                                               r = createdKey.GetValue ("test-ulong");
+                                               Assert.AreEqual (r is int, true);
+                                               Assert.AreEqual ((int) r, 1);
+
+                                               r = createdKey.GetValue ("dtest-int");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-uint");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-byte");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-sbyte");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-short");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-ushort");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-long");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-ulong");
+                                               Assert.AreEqual (r is long, true);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-decimal");
+                                               Assert.IsTrue (r is long);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-float");
+                                               Assert.IsTrue (r is long);
+                                               Assert.AreEqual ((long) r, 1);
+                                               r = createdKey.GetValue ("dtest-bool");
+                                               Assert.AreEqual (typeof (long), r.GetType ());
+
+                                               try {
+                                                       createdKey.SetValue ("test-int", uint.MaxValue, RegistryValueKind.DWord);
+                                                       Assert.Fail ("#100");
+
+                                                       createdKey.SetValue ("test-int", ulong.MaxValue, RegistryValueKind.QWord);
+                                                       Assert.Fail ("#101");
+                                               } catch (ArgumentException) {
+                                               }
+                                               
+                                               createdKey.Close ();
+                                               softwareKey.DeleteSubKeyTree (subKeyName);
+                                       }
+                               } finally {
+                                       try {
+                                               RegistryKey createdKey = softwareKey.OpenSubKey (subKeyName);
+                                               if (createdKey != null) {
+                                                       createdKey.Close ();
+                                                       softwareKey.DeleteSubKeyTree (subKeyName);
+                                               }
+                                       } catch {
+                                       }
+                               }
+                       }
+               }
+               
                [Test]
                public void bug79059 ()
                {
@@ -2478,12 +3501,8 @@ namespace MonoTests.Microsoft.Win32
 
                private bool RunningOnUnix {
                        get {
-#if NET_2_0
-                               return Environment.OSVersion.Platform == PlatformID.Unix;
-#else
                                int p = (int) Environment.OSVersion.Platform;
-                               return ((p == 4) || (p == 128));
-#endif
+                               return ((p == 4) || (p == 128) || (p == 6));
                        }
                }
        }