public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
        {
            RegistryKey appk = null;
            RegistryKey usrk = null;

            try
            {
                foreach (SettingsPropertyValue value in collection)
                {
                    SettingsProperty       property = value.Property;
                    Type                   t        = property.PropertyType;
                    RegistryKey            rk;
                    RegistryKey            bk                     = null;
                    RegistryKey            sk                     = null;
                    string                 name                   = value.Name;
                    SubKeyAttribute        subKeyAttribute        = (SubKeyAttribute)property.Attributes[typeof(SubKeyAttribute)];
                    NameAttribute          nameAttribute          = (NameAttribute)property.Attributes[typeof(NameAttribute)];
                    BaseKeyAttribute       baseKeyAttribute       = (BaseKeyAttribute)property.Attributes[typeof(BaseKeyAttribute)];
                    TypeConverterAttribute typeConverterAttribute = (TypeConverterAttribute)property.Attributes[typeof(TypeConverterAttribute)];

                    if (baseKeyAttribute != null)
                    {
                        rk = bk = Microsoft.Win32.RegistryKey.OpenBaseKey(baseKeyAttribute.Hive, baseKeyAttribute.View);
                    }
                    else if (property.Attributes[typeof(UserScopedSettingAttribute)] != null)
                    {
                        rk = usrk ?? (usrk = Registry.CurrentUser.CreateSubKey(this.RegistryKey));
                    }
                    else if (property.Attributes[typeof(ApplicationScopedSettingAttribute)] != null)
                    {
                        rk = appk ?? (appk = Registry.LocalMachine.CreateSubKey(this.RegistryKey));
                    }
                    else
                    {
                        throw new Exception("Property must be marked with either BaseKeyAttribute, UserScopedSettingAttribute or ApplicationScopedSettingAttribute.");
                    }

                    try
                    {
                        if (rk != null && subKeyAttribute != null)
                        {
                            rk = sk = rk.CreateSubKey(subKeyAttribute.SubKey);
                        }

                        if (property.Attributes[typeof(DefaultKeyAttribute)] != null)
                        {
                            name = string.Empty;
                        }
                        else if (nameAttribute != null)
                        {
                            name = nameAttribute.Name;
                        }

                        if (property.Attributes[typeof(SerializeAsStringAttribute)] != null)
                        {
                            rk.SetValue(name, value.SerializedValue ?? string.Empty, RegistryValueKind.String);
                        }
                        else
                        {
                            object v            = value.PropertyValue;
                            bool   hasConverter = (typeConverterAttribute != null && (typeConverterAttribute.SourceType == null || typeConverterAttribute.SourceType == t));

                            if (hasConverter)
                            {
                                v = typeConverterAttribute.Converter.ConvertTo(new RegistrySettingsProviderContext(t, typeConverterAttribute.TargetType, v, value.SerializedValue, property), CultureInfo.InvariantCulture, v, typeConverterAttribute.TargetType);
                                t = typeConverterAttribute.TargetType;
                            }

                            if (t.IsEnum && (property.Attributes[typeof(EnumAsStringAttribute)] == null))
                            {
                                t = Enum.GetUnderlyingType(t);
                            }

                            if (t == typeof(sbyte) || t == typeof(short) || t == typeof(int) ||
                                t == typeof(byte) || t == typeof(ushort) || t == typeof(uint) ||
                                (t == typeof(bool) && (property.Attributes[typeof(BoolAsStringAttribute)] == null)))
                            {
                                rk.SetValue(name, v, RegistryValueKind.DWord);
                            }
                            else if (t == typeof(long) || t == typeof(ulong))
                            {
                                rk.SetValue(name, v, RegistryValueKind.QWord);
                            }
                            else if (t == typeof(byte[]))
                            {
                                rk.SetValue(name, v ?? new byte[0], RegistryValueKind.Binary);
                            }
                            else if (t == typeof(string[]))
                            {
                                rk.SetValue(name, v ?? new string[0], RegistryValueKind.MultiString);
                            }
                            else if (t == typeof(StringCollection))
                            {
                                rk.SetValue(name, (v == null)
                                                                        ? new string[0]
                                                                        : ((StringCollection)v).Cast <string>().ToArray(), RegistryValueKind.MultiString);
                            }
                            else if (property.Attributes[typeof(ExpandableStringAttribute)] != null)
                            {
                                rk.SetValue(name, v ?? string.Empty, RegistryValueKind.ExpandString);
                            }
                            else if (t == typeof(string) || hasConverter)
                            {
                                rk.SetValue(name, v ?? string.Empty, RegistryValueKind.String);
                            }
                            else
                            {
                                rk.SetValue(name, value.SerializedValue ?? string.Empty, RegistryValueKind.String);
                            }
                        }
                    }
                    finally
                    {
                        if (sk != null)
                        {
                            sk.Dispose();
                        }

                        if (bk != null)
                        {
                            bk.Dispose();
                        }
                    }

                    value.IsDirty = false;
                }
            }
            finally
            {
                if (appk != null)
                {
                    appk.Dispose();
                }

                if (usrk != null)
                {
                    usrk.Dispose();
                }
            }
        }