internal static void CustomUnregisterFunction(Type serverType, RegistrationType registrationType)
        {
            //  Get the junction point.
            var junctionPoint = NamespaceExtensionJunctionPointAttribute.GetJunctionPoint(serverType);

            //  If the junction point is not defined, we must fail.
            if (junctionPoint == null)
            {
                throw new InvalidOperationException("Unable to register a SharpNamespaceExtension as it is missing it's junction point definition.");
            }

            //  Work out the hive and view to use, based on the junction point availability
            //  and the registration mode.
            var hive = junctionPoint.Availablity == NamespaceExtensionAvailability.CurrentUser
                ? RegistryHive.CurrentUser
                : RegistryHive.LocalMachine;
            var view = registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32;

            //  Now open the base key.
            using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
            {
                //  Create the path to the virtual folder namespace key.
                var virtualFolderNamespacePath =
                    string.Format(@"Software\Microsoft\Windows\CurrentVersion\Explorer\{0}\NameSpace",
                                  RegistryKeyAttribute.GetRegistryKey(junctionPoint.Location));

                //  Open the virtual folder namespace key,
                using (var namespaceKey = baseKey.OpenSubKey(virtualFolderNamespacePath,
                                                             RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.WriteKey))
                {
                    //  If we don't have the key, we've got a problem.
                    if (namespaceKey == null)
                    {
                        throw new InvalidOperationException("Cannot open the Virtual Folder NameSpace key.");
                    }

                    //  Delete the shell extension key, which is just it's CLSID.
                    namespaceKey.DeleteSubKeyTree(serverType.GUID.ToRegistryString());
                }
            }
        }
        internal static void CustomRegisterFunction(Type serverType, RegistrationType registrationType)
        {
            //  Get the junction point.
            var junctionPoint = NamespaceExtensionJunctionPointAttribute.GetJunctionPoint(serverType);

            //  If the junction point is not defined, we must fail.
            if (junctionPoint == null)
            {
                throw new InvalidOperationException("Unable to register a SharpNamespaceExtension as it is missing it's junction point definition.");
            }

            //  Now we have the junction point, we can build the key as below:

            /* HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
             *     Software
             *        Microsoft
             *           Windows
             *              CurrentVersion
             *                 Explorer
             *                    Virtual Folder Name
             *                       NameSpace
             *                          {Extension CLSID}
             *                             (Default) = Junction Point Name
             */

            //  Work out the hive and view to use, based on the junction point availability
            //  and the registration mode.
            var hive = junctionPoint.Availablity == NamespaceExtensionAvailability.CurrentUser
                ? RegistryHive.CurrentUser
                : RegistryHive.LocalMachine;
            var view = registrationType == RegistrationType.OS64Bit ? RegistryView.Registry64 : RegistryView.Registry32;

            //  Now open the base key.
            using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
            {
                //  Create the path to the virtual folder namespace key.
                var virtualFolderNamespacePath =
                    string.Format(@"Software\Microsoft\Windows\CurrentVersion\Explorer\{0}\NameSpace",
                                  RegistryKeyAttribute.GetRegistryKey(junctionPoint.Location));

                //  Open the virtual folder namespace key,
                using (var namespaceKey = baseKey.OpenSubKey(virtualFolderNamespacePath,
                                                             RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.WriteKey))
                {
                    //  If we don't have the key, we've got a problem.
                    if (namespaceKey == null)
                    {
                        throw new InvalidOperationException("Cannot open the Virtual Folder NameSpace key.");
                    }

                    //  Write the server guid as a key, then the Junction Point Name as it's default value.
                    var serverKey = namespaceKey.CreateSubKey(serverType.GUID.ToRegistryString());
                    if (serverKey == null)
                    {
                        throw new InvalidOperationException("Failed to create the Virtual Folder NameSpace extension.");
                    }
                    serverKey.SetValue(null, junctionPoint.Name, RegistryValueKind.String);
                }
            }

            //  We can now customise the class registration as needed.
            //  The class is already registered by the Installation of the server, we're only
            //  adapting it here.

            //  Open the classes root.
            using (var classesBaseKey = registrationType == RegistrationType.OS64Bit
                ? RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry64) :
                                        RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Registry32))
            {
                //  Our server guid.
                var serverGuid = serverType.GUID.ToRegistryString();

                //  Open the Class Key.
                using (var classKey = classesBaseKey
                                      .OpenSubKey(string.Format(@"CLSID\{0}", serverGuid),
                                                  RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.WriteKey))
                {
                    //  If we don't have the key, we've got a problem.
                    if (classKey == null)
                    {
                        throw new InvalidOperationException("Cannot open the class key.");
                    }

                    //  Create an instance of the server to get it's registration settings.
                    var serverInstance       = (SharpNamespaceExtension)Activator.CreateInstance(serverType);
                    var registrationSettings = serverInstance.GetRegistrationSettings();

                    //  Apply basic settings.
                    if (registrationSettings.HideFolderVerbs)
                    {
                        classKey.SetValue("HideFolderVerbs", 1, RegistryValueKind.DWord);
                    }

                    //  The default value is the junction point name.
                    classKey.SetValue(null, junctionPoint.Name, RegistryValueKind.String);

                    //  Set the infotip.
                    if (string.IsNullOrEmpty(registrationSettings.Tooltip) != true)
                    {
                        classKey.SetValue(@"InfoTip", registrationSettings.Tooltip, RegistryValueKind.String);
                    }

                    //  Set the default icon to the assembly icon if we are using it.
                    if (registrationSettings.UseAssemblyIcon)
                    {
                        using (var defaultIconKey = classKey.CreateSubKey(@"DefaultIcon"))
                        {
                            if (defaultIconKey == null)
                            {
                                throw new InvalidOperationException("An exception occured creating the DefaultIcon key.");
                            }
                            defaultIconKey.SetValue(null, serverType.Assembly.Location, RegistryValueKind.String);
                        }
                    }

                    //  Set the attributes.
                    using (var shellFolderKey = classKey.CreateSubKey("ShellFolder"))
                    {
                        if (shellFolderKey == null)
                        {
                            throw new InvalidOperationException("An exception occured creating the ShellFolder key.");
                        }
                        shellFolderKey.SetValue("Attributes", (int)registrationSettings.ExtensionAttributes, RegistryValueKind.DWord);
                    }
                }
            }
        }