protected override void DoWork()
        {
            using (new BlogClientUIContextScope(_uiContext))
            {
                // NOTE: LocalSupportingFileUploader temporarily modifies the contents of the BlogPost.Contents to
                // have the correct remote references to embedded images, etc. When it is disposed it returns the
                // value of BlogPost.Contents to its original value.
                using (LocalSupportingFileUploader supportingFileUploader = new LocalSupportingFileUploader(_publishingContext))
                {
                    //hook to publish files before the post is published
                    supportingFileUploader.UploadFilesBeforePublish();

                    // now submit the post
                    using (Blog blog = new Blog(_publishingContext.EditingContext.BlogId))
                    {
                        BlogPost blogPost = _publishingContext.GetBlogPostForPublishing();

                        PostResult postResult;
                        if (blogPost.IsNew)
                        {
                            postResult = blog.NewPost(blogPost, _publishingContext, _publish);
                        }
                        else
                        {
                            postResult = blog.EditPost(blogPost, _publishingContext, _publish);
                        }

                        // try to get published post hash and permalink (but failure shouldn't
                        // stop publishing -- if we allow this then the user will end up
                        // "double-posting" content because the actual publish did succeed
                        // whereas Writer's status would indicate it hadn't)
                        string publishedPostHash = null, permaLink = null, slug = null;
                        try
                        {
                            BlogPost publishedPost = blog.GetPost(postResult.PostId, blogPost.IsPage);
                            publishedPostHash = BlogPost.CalculateContentsSignature(publishedPost);
                            permaLink = publishedPost.Permalink;
                            slug = publishedPost.Slug;
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine("Unexpected error retrieving published post: " + ex.ToString());
                        }

                        BlogPostPublishingResult publishingResult = new BlogPostPublishingResult();

                        // Hook to publish files after the post is published (note that if this
                        // fails it is not a fatal error since the publish itself already
                        // succeeded. In the case of a failure note the exception so that the
                        // UI layer can inform/prompt the user as appropriate
                        try
                        {
                            supportingFileUploader.UploadFilesAfterPublish(postResult.PostId);
                        }
                        catch (Exception ex)
                        {
                            publishingResult.AfterPublishFileUploadException = ex;
                        }

                        // populate the publishing result
                        publishingResult.PostResult = postResult;
                        publishingResult.PostPermalink = permaLink;
                        publishingResult.PostContentHash = publishedPostHash;
                        publishingResult.Slug = slug;
                        publishingResult.PostPublished = _publish;

                        // set the post result
                        _publishingContext.SetPublishingPostResult(publishingResult);

                        // send pings if appropriate
                        if (_publish && PostEditorSettings.Ping && !blogPost.IsTemporary)
                            SafeAsyncSendPings(blog.Name, blog.HomepageUrl);
                    }
                }
            }
        }