public Patch(SnapShot from, SnapShot to)
            : this() {
            this.Section = to.Section;
            this.Assembly = to.Assembly;

            DiffDictionary(from.Settings, to.Settings, false);
            DiffDictionary(from.ConnectionStrings, to.ConnectionStrings, true);
        }
        /// <summary>
        /// Loads the settings from the database. This is only called when a propery in the Settings object
        /// is used the first time, each time after that the assembly uses it's local cache
        /// </summary>
        /// <param name="context"></param>
        /// <param name="properties"></param>
        /// <returns>The requested settings</returns>
        public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties) {
            SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
            string section = GetSectionName(context);
            settings = SnapShot.GetFor(section);
            foreach (SettingsProperty property in properties) {

                SpecialSettingAttribute attribute = property.Attributes[typeof(SpecialSettingAttribute)] as SpecialSettingAttribute;
                if (attribute != null && (attribute.SpecialSetting == SpecialSetting.ConnectionString))
                    values.Add(GetConnectionStringValue(section, property));
                else if (IsApplicationSetting(property))
                    values.Add(GetApplcationSetting(property));
                else
                    throw new ConfigurationErrorsException("User settings are not supported in this provider");
            }
            
            return values;

        }
 public Patch(SnapShot inital, Action.ActionType action)
     : this() {
     this.Assembly = inital.Assembly;
     this.Section = inital.Section;
     foreach (var setting in inital.Settings)
         Actions.Add(new Action() {
             Name = setting.Key,
             Value = setting.Value,
             IsConnectionString = false,
             Type = action
         });
     foreach (var connection in inital.ConnectionStrings) {
         Actions.Add(new Action() {
             Name = connection.Key,
             Value = connection.Value,
             IsConnectionString = true,
             Type = action
         });
     }
 }
        /// <summary>
        /// builds a patch from the defaults as defined in the assembly<br/>
        /// Returns an empty patch for assemblies that don't use settings or
        /// are not using the settings provider
        /// </summary>
        /// <param name="assembly"></param>
        /// <returns></returns>
        public static SnapShot BuildFrom(Assembly assembly) {
            SnapShot ret = new SnapShot();
            ret.Assembly = assembly.FullName;

            Type settingsT = assembly.GetSettingsType();
            
            if (settingsT == null)
                throw new ArgumentException("Assembly does not support the SharePoint Primitves Settings Provider.");

            ret.Section = settingsT.FullName;

            var settings = settingsT.GetProperties().Where(p => p.HasCustomAttribute<ApplicationScopedSettingAttribute>(true));
            
            foreach (var setting in settings) {
                if (setting.IsConnectionString())
                    ret.ConnectionStrings.Add(settingsT.FullName + "." + setting.Name, setting.DefaultValue());
                else
                    ret.Settings.Add(setting.Name, setting.DefaultValue());
            }
            return ret;
        }
 public static SnapShot GetFor(string sectionName) {
     SnapShot ret = new SnapShot();
     ret.Section = sectionName;
     
     using (var database = new SettingsProviderDatabase()) {
         var section = database.Sections.FirstOrDefault(s => s.Name == sectionName);
         if (section != null)
             ret.Assembly = section.AssemblyName;
         ret.Settings = database.GetApplcationSettingsFor(sectionName);
         ret.ConnectionStrings = database.GetNamedConnectionsFor(sectionName);
     }
     return ret;
 }