public static string ToXml(AutoUpdateManifest manifest, Encoding encoding)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                XmlAutoUpdateManifestWriter writer = new XmlAutoUpdateManifestWriter(stream, encoding);

                writer.Write(manifest);

                stream.Close();

                return(encoding.GetString(stream.GetBuffer()));
            }
        }
        /// <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>
        /// Writes the Test specified to the file specified using the specified encoding
        /// </summary>
        /// <param name="test">The test to write</param>
        /// <param name="path">The file to write to</param>
        /// <param name="encoding">The encoding to write with</param>
        public static void Write(AutoUpdateManifest manifest, string path, Encoding encoding)
        {
            // create a new manifest writer
            using (FileStream stream = new FileStream(path, FileMode.Create))
            {
                // create a writer to write the test
                XmlAutoUpdateManifestWriter writer = new XmlAutoUpdateManifestWriter(stream, encoding);

                // write the test
                writer.Write(manifest);

                stream.Close();
            }
        }
        /// <summary>
        /// Writes the Test specified to the file specified using the specified encoding
        /// </summary>
        /// <param name="test">The test to write</param>
        /// <param name="path">The file to write to</param>
        /// <param name="encoding">The encoding to write with</param>
        public static AutoUpdateManifest Read(string path)
        {
            AutoUpdateManifest manifest = null;

            // create a new test writer
            using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // create a reader to read the manifest
                XmlAutoUpdateManifestReader reader = new XmlAutoUpdateManifestReader(stream);

                // read the manifest
                manifest = reader.Read();

                stream.Close();
            }

            return(manifest);
        }
        /// <summary>
        /// Writes an Xml document containing the AutoUpdateManifest specified
        /// </summary>
        /// <param name="manifest">The manifest to write.</param>
        public void Write(AutoUpdateManifest manifest)
        {
            if (manifest == null)
            {
                throw new ArgumentNullException("manifest");
            }

            // start the document
            _writer.WriteStartDocument();

            // comment on the version, and some props to me
//			_writer.WriteComment(@"Object design by Mark Belles, Xml formatting by Mark Belles");

            // start the manifest element
            _writer.WriteStartElement(manifest.GetType().Name);

            // write the manifest id (which is the update id needed for registration hashing)
            XmlWriterUtils.WriteAttributes(_writer,
                                           new XmlStringPair("Id", manifest.Id),
                                           new XmlStringPair("Url", manifest.UrlOfUpdate),
                                           new XmlStringPair("Size", manifest.SizeOfUpdate.ToString())
                                           );

            // write the product
            this.WriteProductDescriptor(manifest.Product);

            // write the more info href
            this.WriteHref(manifest.MoreInfo);

            // write the change summaries
            this.WriteChangeSummaries(manifest.ChangeSummaries);

            // end the manifest element
            _writer.WriteEndElement();

            // end the document
            _writer.WriteEndDocument();

            // NOTE: Always flush the DAMN writer
            _writer.Flush();
        }
        public virtual AutoUpdateManifest Read()
        {
            // create an xpath navigator so that we can traverse the elements inside the xml
            XPathNavigator navigator = _document.CreateNavigator();

            // move to the version element
            navigator.MoveToFirstChild();

//			// move to the file format description element
//			navigator.MoveToNext();
//
//			// move to the shout outs element
//			navigator.MoveToNext();

            AutoUpdateManifest manifest = new AutoUpdateManifest();

            // read the manifest
            this.Read(navigator, manifest);

            return(manifest);
        }
		public virtual AutoUpdateManifest Read()
		{
			// create an xpath navigator so that we can traverse the elements inside the xml
			XPathNavigator navigator = _document.CreateNavigator();

			// move to the version element
			navigator.MoveToFirstChild();

//			// move to the file format description element
//			navigator.MoveToNext();
//
//			// move to the shout outs element
//			navigator.MoveToNext();

			AutoUpdateManifest manifest = new AutoUpdateManifest();
            
			// read the manifest
			this.Read(navigator, manifest);

			return manifest;
		}
        public static string ToXml(AutoUpdateManifest manifest, Encoding encoding)
        {
            if (manifest == null)
            {
                throw new ArgumentNullException("manifest");
            }

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

            using (MemoryStream stream = new MemoryStream())
            {
                XmlAutoUpdateManifestWriter writer = new XmlAutoUpdateManifestWriter(stream, encoding);

                writer.Write(manifest);

                stream.Close();

                return(encoding.GetString(stream.GetBuffer()));
            }
        }
        /// <summary>
        /// Writes the Test specified to the file specified using the specified encoding
        /// </summary>
        /// <param name="test">The test to write</param>
        /// <param name="path">The file to write to</param>
        /// <param name="encoding">The encoding to write with</param>
        public static void Write(AutoUpdateManifest manifest, string path, Encoding encoding)
        {
            if (manifest == null)
            {
                throw new ArgumentNullException("manifest");
            }

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

            // create a new manifest writer
            using (FileStream stream = new FileStream(path, FileMode.Create))
            {
                // create a writer to write the test
                XmlAutoUpdateManifestWriter writer = new XmlAutoUpdateManifestWriter(stream, encoding);

                // write the test
                writer.Write(manifest);

                stream.Close();
            }
        }
		public static string ToXml(AutoUpdateManifest manifest, Encoding encoding)
		{
			if (manifest == null)
				throw new ArgumentNullException("manifest");

			if (encoding == null)
				throw new ArgumentNullException("encoding");

			using (MemoryStream stream = new MemoryStream())
			{
				XmlAutoUpdateManifestWriter writer = new XmlAutoUpdateManifestWriter(stream, encoding);

				writer.Write(manifest);

				stream.Close();

				return encoding.GetString(stream.GetBuffer());
			}
		}
		/// <summary>
		/// Writes the Test specified to the file specified using the specified encoding
		/// </summary>
		/// <param name="test">The test to write</param>
		/// <param name="path">The file to write to</param>
		/// <param name="encoding">The encoding to write with</param>
		public static void Write(AutoUpdateManifest manifest, string path, Encoding encoding)
		{
			if (manifest == null)
				throw new ArgumentNullException("manifest");

			if (encoding == null)
				throw new ArgumentNullException("encoding");
	
			// create a new manifest writer
			using (FileStream stream = new FileStream(path, FileMode.Create))
			{
				// create a writer to write the test
				XmlAutoUpdateManifestWriter writer = new XmlAutoUpdateManifestWriter(stream, encoding);

				// write the test
				writer.Write(manifest);
				
				stream.Close();
			}
		}
		/// <summary>
		/// Writes an Xml document containing the AutoUpdateManifest specified
		/// </summary>
		/// <param name="manifest">The manifest to write.</param>
		public void Write(AutoUpdateManifest manifest)
		{
			if (manifest == null)
			{
				throw new ArgumentNullException("manifest");
			}

			// start the document
			_writer.WriteStartDocument();

			// comment on the version, and some props to me
//			_writer.WriteComment(@"Object design by Mark Belles, Xml formatting by Mark Belles");

			// start the manifest element
			_writer.WriteStartElement(manifest.GetType().Name);

			// write the manifest id (which is the update id needed for registration hashing)
			XmlWriterUtils.WriteAttributes(_writer, 
				new XmlStringPair("Id", manifest.Id),
				new XmlStringPair("Url", manifest.UrlOfUpdate),
				new XmlStringPair("Size", manifest.SizeOfUpdate.ToString())
				);

				// write the product
				this.WriteProductDescriptor(manifest.Product);

				// write the more info href
				this.WriteHref(manifest.MoreInfo);

				// write the change summaries
				this.WriteChangeSummaries(manifest.ChangeSummaries);

			// end the manifest element
			_writer.WriteEndElement();

			// end the document
			_writer.WriteEndDocument();

			// NOTE: Always flush the DAMN writer
			_writer.Flush();
		}
        public virtual void Read(XPathNavigator navigator, AutoUpdateManifest manifest)
        {
            Debug.Assert(navigator != null);
            Debug.Assert(manifest != null);

            if (navigator.HasAttributes)
            {
                // clone the current navigator so we can save our position
                XPathNavigator attributesNavigator = navigator.Clone();

                // move to the first attribute
                if (attributesNavigator.MoveToFirstAttribute())
                {
                    do
                    {
                        // parse the attributes from the test element
                        switch (attributesNavigator.Name)
                        {
                        case @"Id":
                            manifest.Id = attributesNavigator.Value;
                            break;

                        case @"Url":
                            manifest.UrlOfUpdate = attributesNavigator.Value;
                            break;

                        case @"Size":
                            manifest.SizeOfUpdate = long.Parse(attributesNavigator.Value);
                            break;
                        }
                        ;
                    }while(attributesNavigator.MoveToNextAttribute());
                }
            }

            // move inward to the first child
            if (navigator.MoveToFirstChild())
            {
                do
                {
                    switch (navigator.Name)
                    {
                    case @"AutoUpdateProductDescriptor":
                    {
                        AutoUpdateProductDescriptor product;
                        this.ReadProductDescriptor(navigator, out product);
                        manifest.Product = product;
                        navigator.MoveToParent();
                        break;
                    }

                    case @"AutoUpdateHref":
                    {
                        AutoUpdateHref moreInfo;
                        this.ReadHref(navigator, out moreInfo);
                        manifest.MoreInfo = moreInfo;
                        navigator.MoveToParent();
                        break;
                    }

                    case @"AutoUpdateChangeSummaryList":
                    {
                        AutoUpdateChangeSummaryList changeSummaryList;
                        this.ReadChangeSummaries(navigator, out changeSummaryList);
                        manifest.ChangeSummaries = changeSummaryList;
                        navigator.MoveToParent();
                        break;
                    }
                    }
                    ;
                }while(navigator.MoveToNext());
            }
        }
		public virtual void Read(XPathNavigator navigator, AutoUpdateManifest manifest)
		{
			Debug.Assert(navigator != null);
			Debug.Assert(manifest != null);

			if (navigator.HasAttributes)
			{
				// clone the current navigator so we can save our position
				XPathNavigator attributesNavigator = navigator.Clone();

				// move to the first attribute
				if (attributesNavigator.MoveToFirstAttribute())
				{
					do
					{
						// parse the attributes from the test element
						switch(attributesNavigator.Name)
						{
							case @"Id":
								manifest.Id = attributesNavigator.Value;
								break;
						
							case @"Url":
								manifest.UrlOfUpdate = attributesNavigator.Value;
								break;

							case @"Size":
								manifest.SizeOfUpdate = long.Parse(attributesNavigator.Value);
								break;
						};
					}
					while(attributesNavigator.MoveToNextAttribute());
				}
			}

			// move inward to the first child
			if (navigator.MoveToFirstChild())
			{
				do
				{
					switch(navigator.Name)
					{
						case @"AutoUpdateProductDescriptor":						
						{
							AutoUpdateProductDescriptor product;
							this.ReadProductDescriptor(navigator, out product);
							manifest.Product = product;
							navigator.MoveToParent();
							break;
						}

						case @"AutoUpdateHref":											
						{
							AutoUpdateHref moreInfo;
							this.ReadHref(navigator, out moreInfo);
							manifest.MoreInfo = moreInfo;
							navigator.MoveToParent();
							break;
						}

						case @"AutoUpdateChangeSummaryList":												
						{
							AutoUpdateChangeSummaryList changeSummaryList;
							this.ReadChangeSummaries(navigator, out changeSummaryList);
							manifest.ChangeSummaries = changeSummaryList;
							navigator.MoveToParent();
							break;
						}
					};

				}
				while(navigator.MoveToNext());
			}				
		}