/// <summary>
        /// Saves all of the AutoUpdate options.
        /// </summary>
        /// <param name="options"></param>
        public static void Save(AutoUpdateOptions options, AutoUpdateOptions defaultOptions)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

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

            try
            {
                Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyCheckForUpdates);
                Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyDownloadUpdates);
                Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyInstallUpdates);
                Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallySwitchToNewVersion);
                Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath);
                Save(options, defaultOptions, AutoUpdateOptionNames.AlternatePath);
                Save(options, defaultOptions, AutoUpdateOptionNames.WebServiceUrl);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
        /// <summary>
        /// Loads the AutoUpdate options given a set of default options.
        /// </summary>
        /// <param name="defaultOptions">The default options to use if the options do not exist in the configuration files.</param>
        /// <returns></returns>
        public static AutoUpdateOptions Load(AutoUpdateOptions defaultOptions)
        {
            if (defaultOptions == null)
            {
                throw new ArgumentNullException("defaultOptions");
            }
            AutoUpdateOptions options = new AutoUpdateOptions();

            try
            {
                options.BeginInit();

                options.AutomaticallyCheckForUpdates     = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyCheckForUpdates));
                options.AutomaticallyDownloadUpdates     = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyDownloadUpdates));
                options.AutomaticallyInstallUpdates      = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyInstallUpdates));
                options.AutomaticallySwitchToNewVersion  = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallySwitchToNewVersion));
                options.AutomaticallyUpdateAlternatePath = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath));
                options.AlternatePath = Convert.ToString(Load(defaultOptions, AutoUpdateOptionNames.AlternatePath));
                options.WebServiceUrl = Convert.ToString(Load(defaultOptions, AutoUpdateOptionNames.WebServiceUrl));
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                options.EndInit();
            }

            return(options);
        }
        /// <summary>
        /// Instructs the AutoUpdateDownloader to query for the latest version available
        /// </summary>
        /// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
        /// <param name="options">The options that affect this downloader</param>
        /// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
        /// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
        /// <returns></returns>
        public virtual bool QueryLatestVersion(
            IProgressViewer progressViewer,
            AutoUpdateOptions options,
            AutoUpdateProductDescriptor productToUpdate,
            out AutoUpdateDownloadDescriptor updateAvailable)
        {
            updateAvailable = null;

            return(false);
        }
		/// <summary>
		/// Instructs the AutoUpdateDownloader to query for the latest version available 
		/// </summary>
		/// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
		/// <param name="options">The options that affect this downloader</param>
		/// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
		/// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
		/// <returns></returns>
		public override bool QueryLatestVersion(IProgressViewer progressViewer, AutoUpdateOptions options, AutoUpdateProductDescriptor productToUpdate, out AutoUpdateDownloadDescriptor updateAvailable)
		{
			updateAvailable = null;
			
			try
			{
				// create a manual web service proxy based on the url specified in the options
				Debug.WriteLine(string.Format("Creating a web service proxy to the following url.\n\tThe web service url is '{0}'.", options.WebServiceUrl), MY_TRACE_CATEGORY);			
				AutoUpdateWebServiceProxy service = new AutoUpdateWebServiceProxy(options.WebServiceUrl);

				// use the web service to query for updates
				Debug.WriteLine(string.Format("Querying the web service for the latest version of '{0}'.\n\tThe current product's version is '{1}'.\n\tThe current product's id is '{2}'.\n\tThe web service url is '{3}'.", productToUpdate.Name, productToUpdate.Version.ToString(), productToUpdate.Id, options.WebServiceUrl), MY_TRACE_CATEGORY);			
				XmlNode node = service.QueryLatestVersion(productToUpdate.Name, productToUpdate.Version.ToString(), productToUpdate.Id);
				
				// if the service returned no results, then there is no update availabe
				if (node == null)
				{
					// bail out 
					Debug.WriteLine(string.Format("No updates are available from the web service at '{0}' for this product.", options.WebServiceUrl), MY_TRACE_CATEGORY);
					return false;
				}

				// otherwise create a reader and try and read the xml from the xml node returned from the web service
				XmlAutoUpdateManifestReader reader = new XmlAutoUpdateManifestReader(node);

				// using the reader we can recreate the manifeset from the xml
				AutoUpdateManifest manifest = reader.Read();	

				/*
				* now create a download descriptor that says, yes we have found an update.
				* we are capable of downloading it, according to these options.
				* the autoupdate manager will decide which downloader to use to download the update
				* */
				updateAvailable = new AutoUpdateDownloadDescriptor(manifest, this, options);
				
				// just to let everyone know that there is a version available
				Debug.WriteLine(string.Format("Version '{0}' of '{1}' is available for download.\n\tThe download url is '{2}'.\n\tThe size of the download is {3}.", updateAvailable.Manifest.Product.Version.ToString(), updateAvailable.Manifest.Product.Name, updateAvailable.Manifest.UrlOfUpdate, this.FormatFileLengthForDisplay(updateAvailable.Manifest.SizeOfUpdate)), MY_TRACE_CATEGORY);

				// we've successfully queried for the latest version of the product to update
				return true;
			}
			catch(ThreadAbortException)
			{

			}
			catch (WebException ex)
			{
                Debug.WriteLine(ex.Message, MY_TRACE_CATEGORY);
			}
			return false;
		}
 /// <summary>
 /// Initializes a new instance of the AutoUpdateDownloadDescriptor class
 /// </summary>
 /// <param name="manifest">A manifest file containing information about the product, and a summary of the changes new to the version specified</param>
 /// <param name="downloader">The downloader that will be responsible for downloading the .update</param>
 /// <param name="options">The options to be used by the downloader while downloading the .update file</param>
 public AutoUpdateDownloadDescriptor(AutoUpdateManifest manifest, AutoUpdateDownloader downloader, AutoUpdateOptions options)
 {
     _manifest   = manifest;
     _downloader = downloader;
     _options    = options;
 }
 /// <summary>
 /// Initializes a new instance of the AutoUpdateDownloadDescriptor class
 /// </summary>
 public AutoUpdateDownloadDescriptor()
 {
     _manifest   = new AutoUpdateManifest();
     _downloader = null;
     _options    = null;
 }
		/// <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>
        /// Adjusts the url where the .update can be found, using the product descriptor and the alternate download path 
        /// </summary>
        /// <remarks>
        /// By default the url probably points to some web url. When the update is copied to the alternate download path
        /// we want the download to occur from that path, so the url in the manifest must be manipulated to point the download
        /// to the update in the alternate path.
        /// </remarks>
        /// <param name="options"></param>
        /// <param name="downloadDescriptor"></param>
        public virtual void AdjustUrlOfUpdateInManifest(AutoUpdateOptions options, AutoUpdateDownloadDescriptor downloadDescriptor)
        {
            /*
             * we're supposed to be adjusting the the url where the update can be downloaded
             * to point to the alternate path
             * where ideally the manifest file will reside alongside the update
             * 
             * the problem is that the manifest file contains a url to where the update was originally downloaded
             * most likely some web server somewhere, which after the manifest is copied to some network file share
             * we won't want to use, more likely in an effort to keep the downloaders from going over the web
             * we'll try and tweak the url to just be the unc path of the download as it resides next to the 
             * manifest in the alternate download path
             * 
             * */

            try
            {

                // if there's no alternate path, don't worry about adjusting anything
                // as nothing is going to be copied anyways
                if (options.AlternatePath == null || options.AlternatePath == string.Empty)
                    // if there
                    return;

                // redirect the url of the update to the alternate location
                downloadDescriptor.Manifest.UrlOfUpdate = string.Format("{0}\\{1}\\{1}-{2}.Update", options.AlternatePath, downloadDescriptor.Manifest.Product.Name, downloadDescriptor.Manifest.Product.Version.ToString());			
            }
            catch(ThreadAbortException)
            {

            }
        }
        /// <summary>
        /// Initializes a new instance of the AutoUpdateManager class
        /// </summary>
        /// <param name="options">The options that will control the behaviour of the engine</param>
        /// <param name="productToUpdate">A product descriptor that will be used as the product to find updates for</param>
        public AutoUpdateManager(AutoUpdateOptions options, AutoUpdateProductDescriptor productToUpdate)
        {
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}

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

            /*
             * however if we wanted to not do the norm
             * and create an update engine that could update another app
             * then we are all about it, makes no never mind at all
             * */
            _options = options;
            _productToUpdate = productToUpdate;
            _downloaders = new AutoUpdateDownloaderList();
            _downloaders.AddRange(this.CreateDownloadersForInternalUse());
            if (_options.DownloadPath == null || _options.DownloadPath == string.Empty)
                _options.DownloadPath = this.GetBootstrapPath();		
        }	
		/// <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 AutoUpdateDownloadDescriptor class
		/// </summary>
		/// <param name="manifest">A manifest file containing information about the product, and a summary of the changes new to the version specified</param>
		/// <param name="downloader">The downloader that will be responsible for downloading the .update</param>
		/// <param name="options">The options to be used by the downloader while downloading the .update file</param>
		public AutoUpdateDownloadDescriptor(AutoUpdateManifest manifest, AutoUpdateDownloader downloader, AutoUpdateOptions options)
		{
			_manifest = manifest;
			_downloader = downloader;
			_options = options;						
		}
		/// <summary>
		/// Initializes a new instance of the AutoUpdateDownloadDescriptor class
		/// </summary>
		public AutoUpdateDownloadDescriptor()
		{
			_manifest = new AutoUpdateManifest();
			_downloader = null;
			_options = null;
		}
 /// <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>
		/// Loads the AutoUpdate options given a set of default options.
		/// </summary>
		/// <param name="defaultOptions">The default options to use if the options do not exist in the configuration files.</param>
		/// <returns></returns>
		public static AutoUpdateOptions Load(AutoUpdateOptions defaultOptions)
		{
			if (defaultOptions == null)
			{
				throw new ArgumentNullException("defaultOptions");
			}
			AutoUpdateOptions options = new AutoUpdateOptions();

			try
			{
				options.BeginInit();

				options.AutomaticallyCheckForUpdates = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyCheckForUpdates));
				options.AutomaticallyDownloadUpdates = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyDownloadUpdates));
				options.AutomaticallyInstallUpdates  = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyInstallUpdates));
				options.AutomaticallySwitchToNewVersion = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallySwitchToNewVersion));
				options.AutomaticallyUpdateAlternatePath = Convert.ToBoolean(Load(defaultOptions, AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath));
				options.AlternatePath = Convert.ToString(Load(defaultOptions, AutoUpdateOptionNames.AlternatePath));
				options.WebServiceUrl = Convert.ToString(Load(defaultOptions, AutoUpdateOptionNames.WebServiceUrl));
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex);
			}
			finally
			{
				options.EndInit();
			}

			return options;
		}
		/// <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>
		/// Instructs the AutoUpdateDownloader to query for the latest version available 
		/// </summary>
		/// <param name="progressViewer">The progress viewer by which progress should be displayed</param>
		/// <param name="options">The options that affect this downloader</param>
		/// <param name="productToUpdate">The product descriptor for the product that should be updated</param>
		/// <param name="updateAvailable">The download descriptor that describes the download that could potentially occur</param>
		/// <returns></returns>
		public virtual bool QueryLatestVersion(
			IProgressViewer progressViewer,
			AutoUpdateOptions options,
			AutoUpdateProductDescriptor productToUpdate, 
			out AutoUpdateDownloadDescriptor updateAvailable)
		{			
			updateAvailable = null;

			return false;							
		}
		/// <summary>
		/// Saves all of the AutoUpdate options.
		/// </summary>
		/// <param name="options"></param>
		public static void Save(AutoUpdateOptions options, AutoUpdateOptions defaultOptions)
		{
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}

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

			try
			{
				Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyCheckForUpdates);
				Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyDownloadUpdates);
				Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyInstallUpdates);
				Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallySwitchToNewVersion);
				Save(options, defaultOptions, AutoUpdateOptionNames.AutomaticallyUpdateAlternatePath);
				Save(options, defaultOptions, AutoUpdateOptionNames.AlternatePath);
				Save(options, defaultOptions, AutoUpdateOptionNames.WebServiceUrl);
			}
			catch (Exception ex)
			{
				Debug.WriteLine(ex);
			}
		}
        /// <summary>
        /// Initializes a new instance of the AutoUpdateManager class
        /// </summary>
        /// <param name="options">The options that will control the behaviour of the engine</param>
        public AutoUpdateManager(AutoUpdateOptions options) 
        {
            // we can't do anything without options to control our behavior
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}

            /*
             * the default options will be used
             * to update the current hosting engine 
             * and download into the bootstrap directory along side the other versions of this hosting engine
             * */
            _options = options;					
            _productToUpdate = AutoUpdateProductDescriptor.FromAssembly(PluginContext.Current.StartingAssembly, PluginContext.Current.AppVersion);			
            _downloaders = new AutoUpdateDownloaderList();
            _downloaders.AddRange(this.CreateDownloadersForInternalUse());
            if (_options.DownloadPath == null || _options.DownloadPath == string.Empty)
                _options.DownloadPath = this.GetBootstrapPath();		
        }