private object Deserialize()
        {
            object value = null;

            // Attempt 1: Try creating from SerializedValue
            if (SerializedValue != null)
            {
                bool throwBinaryFormatterDeprecationException = false;
                try
                {
                    if (SerializedValue is string)
                    {
                        value = GetObjectFromString(Property.PropertyType, Property.SerializeAs, (string)SerializedValue);
                    }
                    else
                    {
                        if (SettingsProperty.EnableUnsafeBinaryFormatterInPropertyValueSerialization)
                        {
                            using (MemoryStream ms = new MemoryStream((byte[])SerializedValue))
                            {
#pragma warning disable SYSLIB0011 // BinaryFormatter serialization is obsolete and should not be used.
                                value = (new BinaryFormatter()).Deserialize(ms);
#pragma warning restore SYSLIB0011
                            }
                        }
                        else
                        {
                            throwBinaryFormatterDeprecationException = true;
                        }
                    }
                }
                catch (Exception exception)
                {
                    try
                    {
                        if (IsHostedInAspnet())
                        {
                            object[] args = new object[] { Property, this, exception };

                            const string webBaseEventTypeName = "System.Web.Management.WebBaseEvent, System.Web";
                            Type         type = Type.GetType(webBaseEventTypeName, true);

                            type.InvokeMember("RaisePropertyDeserializationWebErrorEvent",
                                              BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod,
                                              null, null, args, CultureInfo.InvariantCulture);
                        }
                    }
                    catch
                    {
                    }
                }

                if (throwBinaryFormatterDeprecationException)
                {
                    throw new NotSupportedException(Obsoletions.BinaryFormatterMessage);
                }

                if (value != null && !Property.PropertyType.IsAssignableFrom(value.GetType())) // is it the correct type
                {
                    value = null;
                }
            }

            // Attempt 2: Try creating from default value
            if (value == null)
            {
                UsingDefaultValue = true;
                if (Property.DefaultValue == null || Property.DefaultValue.ToString() == "[null]")
                {
                    if (Property.PropertyType.IsValueType)
                    {
                        return(TypeUtil.CreateInstance(Property.PropertyType));
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (!(Property.DefaultValue is string))
                {
                    value = Property.DefaultValue;
                }
                else
                {
                    try
                    {
                        value = GetObjectFromString(Property.PropertyType, Property.SerializeAs, (string)Property.DefaultValue);
                    }
                    catch (Exception e)
                    {
                        throw new ArgumentException(SR.Format(SR.Could_not_create_from_default_value, Property.Name, e.Message));
                    }
                }

                if (value != null && !Property.PropertyType.IsAssignableFrom(value.GetType())) // is it the correct type
                {
                    throw new ArgumentException(SR.Format(SR.Could_not_create_from_default_value_2, Property.Name));
                }
            }

            // Attempt 3: Create via the parameterless constructor
            if (value == null)
            {
                if (Property.PropertyType == typeof(string))
                {
                    value = string.Empty;
                }
                else
                {
                    try
                    {
                        value = TypeUtil.CreateInstance(Property.PropertyType);
                    }
                    catch { }
                }
            }

            return(value);
        }
        /// <summary>
        /// Creates a SettingsProperty object using the metadata on the given property
        /// and returns it.
        /// </summary>
        private SettingsProperty CreateSetting(PropertyInfo propertyInfo)
        {
            // Initialization method -
            // be careful not to access properties here to prevent stack overflow.

            object[]         attributes        = propertyInfo.GetCustomAttributes(false);
            SettingsProperty settingsProperty  = new SettingsProperty(Initializer);
            bool             explicitSerialize = _explicitSerializeOnClass;

            settingsProperty.Name         = propertyInfo.Name;
            settingsProperty.PropertyType = propertyInfo.PropertyType;

            for (int i = 0; i < attributes.Length; i++)
            {
                Attribute attribute = attributes[i] as Attribute;
                if (attribute == null)
                {
                    continue;
                }

                if (attribute is DefaultSettingValueAttribute)
                {
                    settingsProperty.DefaultValue = ((DefaultSettingValueAttribute)attribute).Value;
                }
                else if (attribute is ReadOnlyAttribute)
                {
                    settingsProperty.IsReadOnly = true;
                }
                else if (attribute is SettingsProviderAttribute)
                {
                    string providerTypeName = ((SettingsProviderAttribute)attribute).ProviderTypeName;
                    Type   providerType     = Type.GetType(providerTypeName);
                    if (providerType == null)
                    {
                        throw new ConfigurationErrorsException(SR.Format(SR.ProviderTypeLoadFailed, providerTypeName));
                    }

                    SettingsProvider settingsProvider = TypeUtil.CreateInstance(providerType) as SettingsProvider;

                    if (settingsProvider == null)
                    {
                        throw new ConfigurationErrorsException(SR.Format(SR.ProviderInstantiationFailed, providerTypeName));
                    }

                    settingsProvider.Initialize(null, null);
                    settingsProvider.ApplicationName = ConfigurationManagerInternalFactory.Instance.ExeProductName;

                    // See if we already have a provider of the same name in our collection. If so,
                    // re-use the existing instance, since we cannot have multiple providers of the same name.
                    SettingsProvider existing = _providers[settingsProvider.Name];
                    if (existing != null)
                    {
                        settingsProvider = existing;
                    }

                    settingsProperty.Provider = settingsProvider;
                }
                else if (attribute is SettingsSerializeAsAttribute)
                {
                    settingsProperty.SerializeAs = ((SettingsSerializeAsAttribute)attribute).SerializeAs;
                    explicitSerialize            = true;
                }
                else
                {
                    // This isn't an attribute we care about, so simply pass it on
                    // to the SettingsProvider.
                    //
                    // NOTE: The key is the type. So if an attribute was found at class
                    //       level and also property level, the latter overrides the former
                    //       for a given setting. This is exactly the behavior we want.

                    settingsProperty.Attributes.Add(attribute.GetType(), attribute);
                }
            }

            if (!explicitSerialize)
            {
                // Serialization method was not explicitly attributed.

                TypeConverter tc = TypeDescriptor.GetConverter(propertyInfo.PropertyType);
                if (tc.CanConvertTo(typeof(string)) && tc.CanConvertFrom(typeof(string)))
                {
                    // We can use string
                    settingsProperty.SerializeAs = SettingsSerializeAs.String;
                }
                else
                {
                    // Fallback is Xml
                    settingsProperty.SerializeAs = SettingsSerializeAs.Xml;
                }
            }

            return(settingsProperty);
        }