private IBlogProviderButtonNotification GetButtonNotification()
        {
            string notificationUrl = String.Format(
                CultureInfo.InvariantCulture,
                "{0}?blog_id={1}&button_id={2}&image_url={3}",
                NotificationUrl,
                HttpUtility.UrlEncode(_hostBlogId),
                HttpUtility.UrlEncode(_buttonId),
                HttpUtility.UrlEncode(ImageUrl));

            // get the content
            HttpWebResponse response = null;
            XmlDocument xmlDocument = new XmlDocument();
            try
            {
                using (Blog blog = new Blog(_blogId))
                    response = blog.SendAuthenticatedHttpRequest(notificationUrl, 10000);

                // parse the results
                xmlDocument.Load(response.GetResponseStream());
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (response != null)
                    response.Close();
            }

            // create namespace manager
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
            nsmgr.AddNamespace("n", "http://schemas.microsoft.com/wlw/buttons/notification");

            // throw if the root element is not manifest
            if (xmlDocument.DocumentElement.LocalName.ToLower(CultureInfo.InvariantCulture) != "notification")
                throw new ArgumentException("Not a valid writer button notification");

            // polling interval
            int checkAgainMinutes = XmlHelper.NodeInt(xmlDocument.SelectSingleNode("//n:checkAgainMinutes", nsmgr), 0);
            if (checkAgainMinutes == 0)
            {
                throw new ArgumentException("You must specify a value for checkAgainMinutes");
            }
            TimeSpan pollingInterval = TimeSpan.FromMinutes(checkAgainMinutes);

            // notification text
            string notificationText = XmlHelper.NodeText(xmlDocument.SelectSingleNode("//n:text", nsmgr));

            // notification image
            Bitmap notificationImage = null;
            string notificationImageUrl = XmlHelper.NodeText(xmlDocument.SelectSingleNode("//n:imageUrl", nsmgr));
            if (notificationImageUrl != String.Empty)
            {
                // compute the absolute url then allow parameter substitution
                notificationImageUrl = BlogClientHelper.GetAbsoluteUrl(notificationImageUrl, NotificationUrl);
                notificationImageUrl = BlogClientHelper.FormatUrl(notificationImageUrl, _homepageUrl, _postApiUrl, _hostBlogId);

                // try to download it (will use the cache if available)
                // note that failing to download it is a recoverable error, we simply won't show a notification image
                try
                {
                    // try to get a credentials context for the download
                    WinInetCredentialsContext credentialsContext = null;
                    try
                    {
                        credentialsContext = BlogClientHelper.GetCredentialsContext(_blogId, notificationImageUrl);
                    }
                    catch (BlogClientOperationCancelledException)
                    {
                    }

                    // execute the download
                    notificationImage = ImageHelper.DownloadBitmap(notificationImageUrl, credentialsContext);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Error downloading notification image: " + ex.ToString());
                }
            }

            // clear notification on click
            bool clearNotificationOnClick = XmlHelper.NodeBool(xmlDocument.SelectSingleNode("//n:resetOnClick", nsmgr), true);

            // return the notification
            return new BlogProviderButtonNotification(pollingInterval, notificationText, notificationImage, clearNotificationOnClick);
        }