/// <summary>
		/// Loads the value of the option specified. Creates the option if it does not exist, and writes the default value to the option.
		/// </summary>
		/// <param name="defaultOptions">The default options to use to create the option if the option does not exist.</param>
		/// <param name="optionName">The name of the option to load.</param>
		/// <returns></returns>
		public static object Load(AutoUpdateOptions defaultOptions, AutoUpdateOptionNames optionName)
		{
			if (defaultOptions == null)
			{
				throw new ArgumentNullException("defaultOptions");
			}

			try
			{
				XmlConfiguration configuration = AllUsersConfigurationProvider.Current.Configuration;
				XmlConfigurationCategory category = configuration.Categories[ConfigurationCategoryName, true];
				XmlConfigurationOption option = null;

				switch (optionName)
				{				
					case AutoUpdateOptionNames.AutomaticallyCheckForUpdates:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyCheckForUpdates];
							option.DisplayName = @"Automatically Check for Updates";
							option.Category = @"General";
							option.Description = @"Determines whether the AutoUpdateManager automatically checks for updates on startup.";
						}
						break;

					case AutoUpdateOptionNames.AutomaticallyDownloadUpdates:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyDownloadUpdates];
							option.DisplayName = @"Automatically Download Updates";
							option.Category = @"General";
							option.Description = @"Determines whether the AutoUpdateManager automatically downloads available updates without prompting.";
						}
						break;

					case AutoUpdateOptionNames.AutomaticallyInstallUpdates:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyInstallUpdates];
							option.DisplayName = @"Automatically Install Updates";
							option.Category = @"General";
							option.Description = @"Determines whether the AutoUpdateManager automatically installs the updates after downloading.";
						}
						break;

					case AutoUpdateOptionNames.AutomaticallySwitchToNewVersion:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallySwitchToNewVersion];
							option.DisplayName = @"Automatically Switch to Newest Version";
							option.Category = @"General";
							option.Description = @"Determines whether the AutoUpdateManager automatically switches to the newest version after installation.";
						}
						break;

					case AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyUpdateAlternatePath];
							option.DisplayName = @"Automatically Update Alternate Path";
							option.Category = @"General";
							option.Description = @"Determines whether the AutoUpdateManager automatically creates backup copies of the .Manifest and .Update files after installation.";
						}
						break;

					case AutoUpdateOptionNames.AlternatePath:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.AlternatePath];
							option.DisplayName = @"Alternate Download Path";
							option.Category = @"General";
							option.Description = @"This alternate path (url or unc path) will be checked first before attempting to use the web service url to locate updates.";
							option.EditorAssemblyQualifiedName = typeof(FolderBrowserUITypeEditor).AssemblyQualifiedName;
						}
						break;

					case AutoUpdateOptionNames.WebServiceUrl:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							option = category.Options[optionName.ToString(), true, defaultOptions.WebServiceUrl];
							option.DisplayName = @"Web Service Url";
							option.Category = @"General";
							option.Description = @"The url specifying where the AutoUpdate Web Service can be located.";
						}
						break;
				};

				return option.Value;
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex);
			}

			return null;
		}
		/// <summary>
		/// Saves the AutoUpdate options specified.
		/// </summary>
		/// <param name="options">The options to retrieve the value of the option to save.</param>
		/// <param name="optionToSave">The name of the option to save.</param>
		public static void Save(AutoUpdateOptions options, AutoUpdateOptions defaultOptions, AutoUpdateOptionNames optionName)
		{
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}

			if (defaultOptions == null)
			{
				throw new ArgumentNullException("defaultOptions");
			}

			try
			{
				XmlConfiguration configuration = AllUsersConfigurationProvider.Current.Configuration;
				XmlConfigurationCategory category = configuration.Categories[ConfigurationCategoryName, true];
				XmlConfigurationOption option = null;

				// this could be refactored again
				// into another method, but i'm in a massive hurry today

				switch (optionName)
				{
					case AutoUpdateOptionNames.AutomaticallyCheckForUpdates:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.AutomaticallyCheckForUpdates;
						break;

					case AutoUpdateOptionNames.AutomaticallyDownloadUpdates:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.AutomaticallyDownloadUpdates;
						break;

					case AutoUpdateOptionNames.AutomaticallyInstallUpdates:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.AutomaticallyInstallUpdates;
						break;

					case AutoUpdateOptionNames.AutomaticallySwitchToNewVersion:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.AutomaticallySwitchToNewVersion;
						break;

					case AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.AutomaticallyUpdateAlternatePath;
						break;

					case AutoUpdateOptionNames.AlternatePath:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.AlternatePath;
						break;

					case AutoUpdateOptionNames.WebServiceUrl:
						if ((option = category.Options[optionName.ToString()]) == null)
						{
							Load(defaultOptions, optionName);
							option = category.Options[optionName.ToString()];
						}
						option.Value = options.WebServiceUrl;
						break;
				};
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex);
			}
		}
		/// <summary>
		/// Initializes a new instance of the AutoUpdateOptionsEventArgs class.
		/// </summary>
		/// <param name="options">The options that contain the changes.</param>
		/// <param name="optionThatChanged">The name of the option that changed.</param>
		public AutoUpdateOptionsEventArgs(AutoUpdateOptions options, AutoUpdateOptionNames optionThatChanged)
			: base()
		{
			_options = options;
			_optionThatChanged = optionThatChanged;
		}
 /// <summary>
 /// Initializes a new instance of the AutoUpdateOptionsEventArgs class.
 /// </summary>
 /// <param name="options">The options that contain the changes.</param>
 /// <param name="optionThatChanged">The name of the option that changed.</param>
 public AutoUpdateOptionsEventArgs(AutoUpdateOptions options, AutoUpdateOptionNames optionThatChanged)
     : base()
 {
     _options           = options;
     _optionThatChanged = optionThatChanged;
 }
        /// <summary>
        /// Saves the AutoUpdate options specified.
        /// </summary>
        /// <param name="options">The options to retrieve the value of the option to save.</param>
        /// <param name="optionToSave">The name of the option to save.</param>
        public static void Save(AutoUpdateOptions options, AutoUpdateOptions defaultOptions, AutoUpdateOptionNames optionName)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            if (defaultOptions == null)
            {
                throw new ArgumentNullException("defaultOptions");
            }

            try
            {
                XmlConfiguration         configuration = AllUsersConfigurationProvider.Current.Configuration;
                XmlConfigurationCategory category      = configuration.Categories[ConfigurationCategoryName, true];
                XmlConfigurationOption   option        = null;

                // this could be refactored again
                // into another method, but i'm in a massive hurry today

                switch (optionName)
                {
                case AutoUpdateOptionNames.AutomaticallyCheckForUpdates:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.AutomaticallyCheckForUpdates;
                    break;

                case AutoUpdateOptionNames.AutomaticallyDownloadUpdates:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.AutomaticallyDownloadUpdates;
                    break;

                case AutoUpdateOptionNames.AutomaticallyInstallUpdates:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.AutomaticallyInstallUpdates;
                    break;

                case AutoUpdateOptionNames.AutomaticallySwitchToNewVersion:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.AutomaticallySwitchToNewVersion;
                    break;

                case AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.AutomaticallyUpdateAlternatePath;
                    break;

                case AutoUpdateOptionNames.AlternatePath:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.AlternatePath;
                    break;

                case AutoUpdateOptionNames.WebServiceUrl:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        Load(defaultOptions, optionName);
                        option = category.Options[optionName.ToString()];
                    }
                    option.Value = options.WebServiceUrl;
                    break;
                }
                ;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
        /// <summary>
        /// Loads the value of the option specified. Creates the option if it does not exist, and writes the default value to the option.
        /// </summary>
        /// <param name="defaultOptions">The default options to use to create the option if the option does not exist.</param>
        /// <param name="optionName">The name of the option to load.</param>
        /// <returns></returns>
        public static object Load(AutoUpdateOptions defaultOptions, AutoUpdateOptionNames optionName)
        {
            if (defaultOptions == null)
            {
                throw new ArgumentNullException("defaultOptions");
            }

            try
            {
                XmlConfiguration         configuration = AllUsersConfigurationProvider.Current.Configuration;
                XmlConfigurationCategory category      = configuration.Categories[ConfigurationCategoryName, true];
                XmlConfigurationOption   option        = null;

                switch (optionName)
                {
                case AutoUpdateOptionNames.AutomaticallyCheckForUpdates:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyCheckForUpdates];
                        option.DisplayName = @"Automatically Check for Updates";
                        option.Category    = @"General";
                        option.Description = @"Determines whether the AutoUpdateManager automatically checks for updates on startup.";
                    }
                    break;

                case AutoUpdateOptionNames.AutomaticallyDownloadUpdates:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyDownloadUpdates];
                        option.DisplayName = @"Automatically Download Updates";
                        option.Category    = @"General";
                        option.Description = @"Determines whether the AutoUpdateManager automatically downloads available updates without prompting.";
                    }
                    break;

                case AutoUpdateOptionNames.AutomaticallyInstallUpdates:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyInstallUpdates];
                        option.DisplayName = @"Automatically Install Updates";
                        option.Category    = @"General";
                        option.Description = @"Determines whether the AutoUpdateManager automatically installs the updates after downloading.";
                    }
                    break;

                case AutoUpdateOptionNames.AutomaticallySwitchToNewVersion:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallySwitchToNewVersion];
                        option.DisplayName = @"Automatically Switch to Newest Version";
                        option.Category    = @"General";
                        option.Description = @"Determines whether the AutoUpdateManager automatically switches to the newest version after installation.";
                    }
                    break;

                case AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.AutomaticallyUpdateAlternatePath];
                        option.DisplayName = @"Automatically Update Alternate Path";
                        option.Category    = @"General";
                        option.Description = @"Determines whether the AutoUpdateManager automatically creates backup copies of the .Manifest and .Update files after installation.";
                    }
                    break;

                case AutoUpdateOptionNames.AlternatePath:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.AlternatePath];
                        option.DisplayName = @"Alternate Download Path";
                        option.Category    = @"General";
                        option.Description = @"This alternate path (url or unc path) will be checked first before attempting to use the web service url to locate updates.";
                        option.EditorAssemblyQualifiedName = typeof(FolderBrowserUITypeEditor).AssemblyQualifiedName;
                    }
                    break;

                case AutoUpdateOptionNames.WebServiceUrl:
                    if ((option = category.Options[optionName.ToString()]) == null)
                    {
                        option             = category.Options[optionName.ToString(), true, defaultOptions.WebServiceUrl];
                        option.DisplayName = @"Web Service Url";
                        option.Category    = @"General";
                        option.Description = @"The url specifying where the AutoUpdate Web Service can be located.";
                    }
                    break;
                }
                ;

                return(option.Value);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }

            return(null);
        }
        /// <summary>
        /// Monitors the all users configuration for changes to the AutoUpdate options.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void HandleConfigurationChanged(object sender, XmlConfigurationElementEventArgs e)
        {
            // bail if the element is being edited
            if (e.Element.IsBeingEdited)
            {
                return;
            }

            // we only care about options
            if (e.Element.GetElementType() == XmlConfigurationElementTypes.XmlConfigurationOption)
            {
                string[] optionNames = Enum.GetNames(typeof(AutoUpdateOptionNames));

                foreach (string name in optionNames)
                {
                    string fullPath = string.Format("{0}\\{1}\\{2}", AllUsersConfigurationProvider.Current.ConfigurationName, ConfigurationCategoryName, name);

                    if (string.Compare(e.Element.Fullpath, fullPath, true) == 0)
                    {
                        AutoUpdateOptionNames optionName = (AutoUpdateOptionNames)Enum.Parse(typeof(AutoUpdateOptionNames), name);

                        try
                        {
                            this.BeginInit();

                            XmlConfigurationOption option = (XmlConfigurationOption)e.Element;

                            // read the value back out into our copy
                            switch (optionName)
                            {
                            case AutoUpdateOptionNames.AutomaticallyCheckForUpdates:
                                this.AutomaticallyCheckForUpdates = Convert.ToBoolean(option.Value);
                                break;

                            case AutoUpdateOptionNames.AutomaticallyDownloadUpdates:
                                this.AutomaticallyDownloadUpdates = Convert.ToBoolean(option.Value);
                                break;

                            case AutoUpdateOptionNames.AutomaticallyInstallUpdates:
                                this.AutomaticallyInstallUpdates = Convert.ToBoolean(option.Value);
                                break;

                            case AutoUpdateOptionNames.AutomaticallySwitchToNewVersion:
                                this.AutomaticallySwitchToNewVersion = Convert.ToBoolean(option.Value);
                                break;

                            case AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath:
                                this.AutomaticallyUpdateAlternatePath = Convert.ToBoolean(option.Value);
                                break;

                            case AutoUpdateOptionNames.AlternatePath:
                                this.AlternatePath = Convert.ToString(option.Value);
                                break;

                            case AutoUpdateOptionNames.WebServiceUrl:
                                this.WebServiceUrl = Convert.ToString(option.Value);
                                break;
                            }
                            ;
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex);
                        }
                        finally
                        {
                            this.EndInit();
                        }

                        // raise the changed event to signal that this option was changed
                        EventManager.Raise <AutoUpdateOptionsEventArgs>(this.Changed, this, new AutoUpdateOptionsEventArgs(this, optionName));
                        break;
                    }
                }
            }
        }