/**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param user {@link org.blojsom.blog.BlogUser}instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws org.blojsom.plugin.BlojsomPluginException If there is an error processing the blog
   *     entries
   */
  public org.blojsom.blog.BlogEntry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      BlogUser user,
      Map context,
      org.blojsom.blog.BlogEntry[] entries)
      throws org.blojsom.plugin.BlojsomPluginException {
    Map emoticonsForBlog = readEmoticonsMapForBlog(user.getId());
    if (emoticonsForBlog == null) {
      return entries;
    }

    List availableEmoticons = parseEmoticons((String) emoticonsForBlog.get(EMOTICONS_PARAM));
    String blogBaseUrl = user.getBlog().getBlogBaseURL();
    for (int i = 0; i < entries.length; i++) {
      BlogEntry entry = entries[i];
      if (!BlojsomUtils.checkMapForKey(
          entry.getMetaData(), BLOJSOM_PLUGIN_METADATA_EMOTICONS_DISABLED)) {
        String updatedDescription = entry.getDescription();
        Iterator iter = availableEmoticons.iterator();
        while (iter.hasNext()) {
          String emoticon = (String) iter.next();
          updatedDescription =
              replaceEmoticon(emoticonsForBlog, updatedDescription, emoticon, blogBaseUrl);
        }
        entry.setDescription(updatedDescription);
      }
    }
    return entries;
  }
  /**
   * Edits a given post. Optionally, will publish the blog after making the edit
   *
   * @param appkey Unique identifier/passcode of the application sending the post
   * @param postid Unique identifier of the post to be changed
   * @param userid Login for a Blogger user who has permission to post to the blog
   * @param password Password for said username
   * @param content Contents of the post
   * @param publish If true, the blog will be published immediately after the post is made
   * @throws XmlRpcException If the user was not authenticated correctly, if there was an I/O
   *     exception, or if the entry permalink ID is invalid
   * @return <code>true</code> if the entry was edited, <code>false</code> otherwise
   */
  public boolean editPost(
      String appkey, String postid, String userid, String password, String content, boolean publish)
      throws Exception {
    _logger.debug("editPost() Called ========[ SUPPORTED ]=====");
    _logger.debug("     Appkey: " + appkey);
    _logger.debug("     PostId: " + postid);
    _logger.debug("     UserId: " + userid);
    _logger.debug("   Password: "******"    Publish: " + publish);
    _logger.debug("     Content:\n " + content);

    try {
      _authorizationProvider.loadAuthenticationCredentials(_blogUser);
      _authorizationProvider.authorize(_blogUser, null, userid, password);

      boolean result = false;

      String category;
      String permalink;
      String match = "?" + PERMALINK_PARAM + "=";

      int pos = postid.indexOf(match);
      if (pos != -1) {
        category = postid.substring(0, pos);
        category = BlojsomUtils.normalize(category);
        permalink = postid.substring(pos + match.length());

        Map fetchMap = new HashMap();
        BlogCategory blogCategory = _fetcher.newBlogCategory();
        blogCategory.setCategory(category);
        blogCategory.setCategoryURL(_blog.getBlogURL() + category);
        fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, blogCategory);
        fetchMap.put(BlojsomFetcher.FETCHER_PERMALINK, permalink);
        BlogEntry[] _entries = _fetcher.fetchEntries(fetchMap, _blogUser);

        if (_entries != null && _entries.length > 0) {
          BlogEntry _entry = _entries[0];
          try {
            _entry.setTitle(null);
            _entry.setDescription(content);
            _entry.save(_blogUser);
            result = true;
          } catch (BlojsomException e) {
            _logger.error(e);
            throw new XmlRpcException(UNKNOWN_EXCEPTION, UNKNOWN_EXCEPTION_MSG);
          }
        } else {
          throw new XmlRpcException(INVALID_POSTID, INVALID_POSTID_MSG);
        }
      }

      return result;
    } catch (BlojsomException e) {
      _logger.error(
          "Failed to authenticate user [" + userid + "] with password [" + password + "]");
      throw new XmlRpcException(AUTHORIZATION_EXCEPTION, AUTHORIZATION_EXCEPTION_MSG);
    }
  }
  /**
   * Get a particular post for a blojsom category
   *
   * @since blojsom 1.9.3
   * @param appkey Unique identifier/passcode of the application sending the post
   * @param blogid Unique identifier of the blog the post will be added to
   * @param userid Login for a Blogger user who has permission to post to the blog
   * @param password Password for said username
   * @throws XmlRpcException If the user was not authenticated correctly
   * @return Post to the blog
   */
  public Object getPost(String appkey, String blogid, String userid, String password)
      throws Exception {
    _logger.debug("getPost() Called ===========[ SUPPORTED ]=====");
    _logger.debug("     Appkey: " + appkey);
    _logger.debug("     BlogId: " + blogid);
    _logger.debug("     UserId: " + userid);
    _logger.debug("   Password: "******"?" + PERMALINK_PARAM + "=";

      int pos = blogid.indexOf(match);
      if (pos != -1) {
        category = blogid.substring(0, pos);
        category = BlojsomUtils.normalize(category);
        permalink = blogid.substring(pos + match.length());

        Map fetchMap = new HashMap();
        BlogCategory blogCategory = _fetcher.newBlogCategory();
        blogCategory.setCategory(category);
        blogCategory.setCategoryURL(_blog.getBlogURL() + category);
        fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, blogCategory);
        fetchMap.put(BlojsomFetcher.FETCHER_PERMALINK, permalink);
        BlogEntry[] _entries = _fetcher.fetchEntries(fetchMap, _blogUser);

        if (_entries != null && _entries.length > 0) {
          BlogEntry entry = _entries[0];
          Hashtable entrystruct = new Hashtable();
          entrystruct.put(MEMBER_POSTID, entry.getId());
          entrystruct.put(MEMBER_BLOGID, entry.getCategory());
          entrystruct.put(MEMBER_TITLE, entry.getEscapedTitle());
          entrystruct.put(MEMBER_URL, entry.getEscapedLink());
          entrystruct.put(MEMBER_CONTENT, entry.getTitle() + "\n" + entry.getDescription());
          entrystruct.put(MEMBER_DATECREATED, entry.getDate());
          entrystruct.put(MEMBER_AUTHORNAME, _blog.getBlogOwner());
          entrystruct.put(MEMBER_AUTHOREMAIL, _blog.getBlogOwnerEmail());

          return entrystruct;
        } else {
          throw new XmlRpcException(INVALID_POSTID, INVALID_POSTID_MSG);
        }
      } else {
        throw new XmlRpcException(INVALID_POSTID, INVALID_POSTID_MSG);
      }
    } catch (BlojsomException e) {
      _logger.error(
          "Failed to authenticate user [" + userid + "] with password [" + password + "]");
      throw new XmlRpcException(AUTHORIZATION_EXCEPTION, AUTHORIZATION_EXCEPTION_MSG);
    }
  }
  /**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param user {@link BlogUser} instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws BlojsomPluginException If there is an error processing the blog entries
   */
  public BlogEntry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      BlogUser user,
      Map context,
      BlogEntry[] entries)
      throws BlojsomPluginException {
    Blog blog = user.getBlog();

    // If there are no entries return
    if (entries.length <= 0) {
      return entries;
    } else {
      // Pull the latest entry, check its date to see if its newer than the lastPingDate, and
      // if so, ping weblogs.com
      BlogEntry entry = entries[0];
      if (_lastPingDate.before(entry.getDate())) {
        synchronized (_lastPingDate) {
          _lastPingDate = entry.getDate();
        }

        try {
          XmlRpcClient client = new XmlRpcClient(DEFAULT_WEBLOGS_URL);
          Vector params = new Vector();
          params.add(blog.getBlogName());
          params.add(blog.getBlogURL());
          client.executeAsync(WEBLOGS_PING_METHOD, params, _callbackHandler);
        } catch (IOException e) {
          _logger.error(e);
        }
      } else {
        _logger.debug("Latest entry date occurs before latest ping date.");
      }
    }

    return entries;
  }
  /**
   * Makes a new post to a designated blog. Optionally, will publish the blog after making the post
   *
   * @param appkey Unique identifier/passcode of the application sending the post
   * @param blogid Unique identifier of the blog the post will be added to
   * @param userid Login for a Blogger user who has permission to post to the blog
   * @param password Password for said username
   * @param content Contents of the post
   * @param publish If true, the blog will be published immediately after the post is made
   * @throws XmlRpcException If the user was not authenticated correctly or if there was an I/O
   *     exception
   * @return Post ID of the added entry
   */
  public String newPost(
      String appkey, String blogid, String userid, String password, String content, boolean publish)
      throws Exception {
    _logger.debug("newPost() Called ===========[ SUPPORTED ]=====");
    _logger.debug("     Appkey: " + appkey);
    _logger.debug("     BlogId: " + blogid);
    _logger.debug("     UserId: " + userid);
    _logger.debug("   Password: "******"    Publish: " + publish);
    _logger.debug("     Content:\n " + content);

    blogid = BlojsomUtils.normalize(blogid);

    try {
      _authorizationProvider.loadAuthenticationCredentials(_blogUser);
      _authorizationProvider.authorize(_blogUser, null, userid, password);

      String result = null;

      // Quick verify that the category is valid
      File blogCategory = getBlogCategoryDirectory(blogid);
      if (blogCategory.exists() && blogCategory.isDirectory()) {

        String filename = getBlogEntryFilename(content);
        String outputfile = blogCategory.getAbsolutePath() + File.separator + filename;
        String postid = blogid + "?" + PERMALINK_PARAM + "=" + filename;

        try {
          File sourceFile = new File(outputfile);
          BlogEntry entry = _fetcher.newBlogEntry();
          Map attributeMap = new HashMap();
          Map blogEntryMetaData = new HashMap();

          attributeMap.put(SOURCE_ATTRIBUTE, sourceFile);
          entry.setAttributes(attributeMap);
          entry.setCategory(blogid);
          entry.setDescription(content);
          blogEntryMetaData.put(BLOG_ENTRY_METADATA_AUTHOR, userid);
          blogEntryMetaData.put(
              BLOG_ENTRY_METADATA_TIMESTAMP, new Long(new Date().getTime()).toString());
          entry.setMetaData(blogEntryMetaData);
          entry.save(_blogUser);
          result = postid;
        } catch (BlojsomException e) {
          _logger.error(e);
          throw new XmlRpcException(UNKNOWN_EXCEPTION, UNKNOWN_EXCEPTION_MSG);
        }
      }

      return result;
    } catch (BlojsomException e) {
      _logger.error(
          "Failed to authenticate user [" + userid + "] with password [" + password + "]");
      throw new XmlRpcException(AUTHORIZATION_EXCEPTION, AUTHORIZATION_EXCEPTION_MSG);
    }
  }
  /**
   * Get a list of recent posts for a blojsom category
   *
   * @param appkey Unique identifier/passcode of the application sending the post
   * @param blogid Unique identifier of the blog the post will be added to
   * @param userid Login for a Blogger user who has permission to post to the blog
   * @param password Password for said username
   * @param numposts Number of Posts to Retrieve
   * @throws XmlRpcException If the user was not authenticated correctly
   * @return Recent posts to the blog
   */
  public Object getRecentPosts(
      String appkey, String blogid, String userid, String password, int numposts) throws Exception {
    _logger.debug("getRecentPosts() Called ===========[ SUPPORTED ]=====");
    _logger.debug("     Appkey: " + appkey);
    _logger.debug("     BlogId: " + blogid);
    _logger.debug("     UserId: " + userid);
    _logger.debug("   Password: "******"     Number: " + numposts);

    Vector recentPosts = new Vector();
    blogid = BlojsomUtils.normalize(blogid);

    try {
      _authorizationProvider.loadAuthenticationCredentials(_blogUser);
      _authorizationProvider.authorize(_blogUser, null, userid, password);

      // Quick verify that the categories are valid
      File blogCategoryFile =
          new File(_blog.getBlogHome() + BlojsomUtils.removeInitialSlash(blogid));
      if (blogCategoryFile.exists() && blogCategoryFile.isDirectory()) {

        String requestedCategory = BlojsomUtils.removeInitialSlash(blogid);
        BlogCategory blogCategory = _fetcher.newBlogCategory();
        blogCategory.setCategory(blogid);
        blogCategory.setCategoryURL(_blog.getBlogURL() + requestedCategory);

        BlogEntry[] entries;
        Map fetchMap = new HashMap();

        if (BlojsomUtils.checkNullOrBlank(requestedCategory)) {
          fetchMap.put(BlojsomFetcher.FETCHER_FLAVOR, DEFAULT_FLAVOR_HTML);
          fetchMap.put(BlojsomFetcher.FETCHER_NUM_POSTS_INTEGER, new Integer(numposts));
          entries = _fetcher.fetchEntries(fetchMap, _blogUser);
        } else {
          fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, blogCategory);
          fetchMap.put(BlojsomFetcher.FETCHER_NUM_POSTS_INTEGER, new Integer(numposts));
          entries = _fetcher.fetchEntries(fetchMap, _blogUser);
        }

        if (entries != null && entries.length > 0) {
          for (int x = 0; x < entries.length; x++) {
            BlogEntry entry = entries[x];
            Hashtable entrystruct = new Hashtable();
            entrystruct.put(MEMBER_POSTID, entry.getId());
            entrystruct.put(MEMBER_BLOGID, entry.getCategory());
            entrystruct.put(MEMBER_TITLE, entry.getEscapedTitle());
            entrystruct.put(MEMBER_URL, entry.getEscapedLink());
            entrystruct.put(MEMBER_CONTENT, entry.getTitle() + "\n" + entry.getDescription());
            entrystruct.put(MEMBER_DATECREATED, entry.getDate());
            entrystruct.put(MEMBER_AUTHORNAME, _blog.getBlogOwner());
            entrystruct.put(MEMBER_AUTHOREMAIL, _blog.getBlogOwnerEmail());
            recentPosts.add(entrystruct);
          }
        }
      }

      return recentPosts;
    } catch (BlojsomException e) {
      _logger.error(
          "Failed to authenticate user [" + userid + "] with password [" + password + "]");
      throw new XmlRpcException(AUTHORIZATION_EXCEPTION, AUTHORIZATION_EXCEPTION_MSG);
    }
  }
  /**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param user {@link org.blojsom.blog.BlogUser} instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws BlojsomPluginException If there is an error processing the blog entries
   */
  public BlogEntry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      BlogUser user,
      Map context,
      BlogEntry[] entries)
      throws BlojsomPluginException {
    if (!authenticateUser(httpServletRequest, httpServletResponse, context, user)) {
      httpServletRequest.setAttribute(PAGE_PARAM, ADMIN_LOGIN_PAGE);

      return entries;
    }

    String username = getUsernameFromSession(httpServletRequest, user.getBlog());
    if (!checkPermission(user, null, username, EDIT_BLOG_ENTRIES_PERMISSION)) {
      httpServletRequest.setAttribute(PAGE_PARAM, ADMIN_ADMINISTRATION_PAGE);
      addOperationResultMessage(
          context,
          getAdminResource(
              FAILED_PERMISSION_EDIT_KEY,
              FAILED_PERMISSION_EDIT_KEY,
              user.getBlog().getBlogAdministrationLocale()));

      return entries;
    }

    String action = BlojsomUtils.getRequestValue(ACTION_PARAM, httpServletRequest);
    if (BlojsomUtils.checkNullOrBlank(action)) {
      _logger.debug("User did not request edit action");
      httpServletRequest.setAttribute(PAGE_PARAM, ADMIN_ADMINISTRATION_PAGE);
    } else if (PAGE_ACTION.equals(action)) {
      _logger.debug("User requested edit blog entries page");

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRIES_PAGE);
    } else if (EDIT_BLOG_ENTRIES_ACTION.equals(action)) {
      _logger.debug("User requested edit blog entries list page");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);

      BlogCategory category;
      category = _fetcher.newBlogCategory();
      category.setCategory(blogCategoryName);
      category.setCategoryURL(
          user.getBlog().getBlogURL() + BlojsomUtils.removeInitialSlash(blogCategoryName));

      Map fetchMap = new HashMap();
      fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, category);
      fetchMap.put(BlojsomFetcher.FETCHER_NUM_POSTS_INTEGER, new Integer(-1));
      try {
        entries = _fetcher.fetchEntries(fetchMap, user);
        if (entries != null) {
          _logger.debug(
              "Retrieved " + entries.length + " entries from category: " + blogCategoryName);
          Arrays.sort(entries, BlojsomUtils.FILE_TIME_COMPARATOR);
        } else {
          _logger.debug("No entries found in category: " + blogCategoryName);
        }
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
        entries = new BlogEntry[0];
      }

      context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
      context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_LIST, entries);
      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRIES_LIST_PAGE);
    } else if (EDIT_BLOG_ENTRY_ACTION.equals(action)) {
      _logger.debug("User requested edit blog entry action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      _logger.debug("Blog entry id: " + blogEntryId);

      try {
        BlogEntry entry = BlojsomUtils.fetchEntry(_fetcher, user, blogCategoryName, blogEntryId);
        context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entry);

        _blojsomConfiguration
            .getEventBroadcaster()
            .processEvent(
                new ProcessBlogEntryEvent(
                    this,
                    new Date(),
                    entry,
                    user,
                    httpServletRequest,
                    httpServletResponse,
                    context));
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
        addOperationResultMessage(
            context,
            formatAdminResource(
                FAILED_RETRIEVE_BLOG_ENTRY_KEY,
                FAILED_RETRIEVE_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {blogEntryId}));
        entries = new BlogEntry[0];
      }

      context.put(
          BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, BlojsomUtils.addSlashes(blogCategoryName));
      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_PAGE);
    } else if (UPDATE_BLOG_ENTRY_ACTION.equals(action)) {
      _logger.debug("User requested update blog entry action");

      Blog blog = user.getBlog();
      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String updatedBlogCategoryName =
          BlojsomUtils.getRequestValue(UPDATED_BLOG_CATEGORY_NAME, httpServletRequest);
      updatedBlogCategoryName = BlojsomUtils.normalize(updatedBlogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      String blogEntryDescription =
          BlojsomUtils.getRequestValue(BLOG_ENTRY_DESCRIPTION, httpServletRequest);
      String blogEntryTitle = BlojsomUtils.getRequestValue(BLOG_ENTRY_TITLE, httpServletRequest);
      if (BlojsomUtils.checkNullOrBlank(blogEntryTitle)) {
        blogEntryDescription = BlojsomUtils.LINE_SEPARATOR + blogEntryDescription;
      }
      String allowComments =
          BlojsomUtils.getRequestValue(BLOG_METADATA_COMMENTS_DISABLED, httpServletRequest);
      String allowTrackbacks =
          BlojsomUtils.getRequestValue(BLOG_METADATA_TRACKBACKS_DISABLED, httpServletRequest);
      String blogTrackbackURLs =
          BlojsomUtils.getRequestValue(BLOG_TRACKBACK_URLS, httpServletRequest);
      String pingBlogURLS = BlojsomUtils.getRequestValue(PING_BLOG_URLS, httpServletRequest);
      String sendPingbacks =
          BlojsomUtils.getRequestValue(
              PingbackPlugin.PINGBACK_PLUGIN_METADATA_SEND_PINGBACKS, httpServletRequest);

      _logger.debug("Blog entry id: " + blogEntryId);

      try {
        BlogEntry entryToUpdate =
            BlojsomUtils.fetchEntry(_fetcher, user, blogCategoryName, blogEntryId);
        entryToUpdate.setTitle(blogEntryTitle);
        entryToUpdate.setDescription(blogEntryDescription);

        boolean movingCategory = !blogCategoryName.equals(updatedBlogCategoryName);

        Map entryMetaData = entryToUpdate.getMetaData();
        if (entryMetaData == null) {
          entryMetaData = new HashMap();
        }

        if (!BlojsomUtils.checkNullOrBlank(allowComments)) {
          entryMetaData.put(BLOG_METADATA_COMMENTS_DISABLED, "y");
        } else {
          entryMetaData.remove(BLOG_METADATA_COMMENTS_DISABLED);
        }

        if (!BlojsomUtils.checkNullOrBlank(allowTrackbacks)) {
          entryMetaData.put(BLOG_METADATA_TRACKBACKS_DISABLED, "y");
        } else {
          entryMetaData.remove(BLOG_METADATA_TRACKBACKS_DISABLED);
        }

        if (BlojsomUtils.checkNullOrBlank(pingBlogURLS)) {
          entryMetaData.put(WeblogsPingPlugin.NO_PING_WEBLOGS_METADATA, "true");
        } else {
          entryMetaData.remove(WeblogsPingPlugin.NO_PING_WEBLOGS_METADATA);
        }

        if (!BlojsomUtils.checkNullOrBlank(sendPingbacks)) {
          entryMetaData.put(PingbackPlugin.PINGBACK_PLUGIN_METADATA_SEND_PINGBACKS, "true");
        } else {
          entryMetaData.remove(PingbackPlugin.PINGBACK_PLUGIN_METADATA_SEND_PINGBACKS);
        }

        String entryPublishDateTime = httpServletRequest.getParameter(BLOG_ENTRY_PUBLISH_DATETIME);
        if (!BlojsomUtils.checkNullOrBlank(entryPublishDateTime)) {
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
          try {
            Date publishDateTime = simpleDateFormat.parse(entryPublishDateTime);
            _logger.debug("Publishing blog entry at: " + publishDateTime.toString());
            entryMetaData.put(
                BlojsomMetaDataConstants.BLOG_ENTRY_METADATA_TIMESTAMP,
                Long.toString(publishDateTime.getTime()));
          } catch (ParseException e) {
            _logger.error(e);
          }
        }

        entryToUpdate.setMetaData(entryMetaData);

        _blojsomConfiguration
            .getEventBroadcaster()
            .processEvent(
                new ProcessBlogEntryEvent(
                    this,
                    new Date(),
                    entryToUpdate,
                    user,
                    httpServletRequest,
                    httpServletResponse,
                    context));

        if (movingCategory) {
          _logger.debug("Moving entry from " + blogCategoryName + " to " + updatedBlogCategoryName);
          BlogEntry movedEntry = _fetcher.newBlogEntry();

          BlogCategory category;
          category = _fetcher.newBlogCategory();
          category.setCategory(updatedBlogCategoryName);
          category.setCategoryURL(
              user.getBlog().getBlogURL()
                  + BlojsomUtils.removeInitialSlash(updatedBlogCategoryName));

          movedEntry.setTitle(blogEntryTitle);
          movedEntry.setCategory(updatedBlogCategoryName);
          movedEntry.setDescription(blogEntryDescription);
          movedEntry.setBlogCategory(category);
          movedEntry.setMetaData(entryMetaData);

          movedEntry.setComments(entryToUpdate.getComments());
          movedEntry.setTrackbacks(entryToUpdate.getTrackbacks());
          movedEntry.setPingbacks(entryToUpdate.getPingbacks());

          movedEntry.save(user);

          _logger.debug("Moving " + entryToUpdate.getNumComments() + " comments");
          List comments = entryToUpdate.getComments();
          for (int i = 0; i < comments.size(); i++) {
            BlogComment blogComment = (BlogComment) comments.get(i);
            try {
              BlogComment movedComment = _fetcher.newBlogComment();
              movedComment.setAuthor(blogComment.getAuthor());
              movedComment.setAuthorEmail(blogComment.getAuthorEmail());
              movedComment.setAuthorURL(blogComment.getAuthorURL());
              movedComment.setBlogEntry(movedEntry);
              movedComment.setComment(blogComment.getComment());
              movedComment.setMetaData(blogComment.getMetaData());
              movedComment.setId(blogComment.getId());
              movedComment.setCommentDateLong(blogComment.getCommentDateLong());

              movedComment.save(user);
              blogComment.delete(user);
            } catch (BlojsomException e) {
              _logger.error(e);
            }
          }

          _logger.debug("Moving " + entryToUpdate.getNumTrackbacks() + " trackbacks");
          List trackbacks = entryToUpdate.getTrackbacks();
          for (int i = 0; i < trackbacks.size(); i++) {
            Trackback trackback = (Trackback) trackbacks.get(i);
            try {
              Trackback movedTrackback = _fetcher.newTrackback();
              movedTrackback.setBlogEntry(movedEntry);
              movedTrackback.setBlogName(trackback.getBlogName());
              movedTrackback.setExcerpt(trackback.getExcerpt());
              movedTrackback.setId(trackback.getId());
              movedTrackback.setMetaData(trackback.getMetaData());
              movedTrackback.setTitle(trackback.getTitle());
              movedTrackback.setUrl(trackback.getUrl());
              movedTrackback.setTrackbackDateLong(trackback.getTrackbackDateLong());

              movedTrackback.save(user);
              trackback.delete(user);
            } catch (BlojsomException e) {
              _logger.error(e);
            }
          }

          _logger.debug("Moving " + entryToUpdate.getNumPingbacks() + " pingbacks");
          List pingbacks = entryToUpdate.getPingbacks();
          for (int i = 0; i < pingbacks.size(); i++) {
            Pingback pingback = (Pingback) pingbacks.get(i);
            try {
              Pingback movedPingback = _fetcher.newPingback();
              movedPingback.setBlogEntry(movedEntry);
              movedPingback.setBlogName(pingback.getBlogName());
              movedPingback.setExcerpt(pingback.getExcerpt());
              movedPingback.setId(pingback.getId());
              movedPingback.setMetaData(pingback.getMetaData());
              movedPingback.setTitle(pingback.getTitle());
              movedPingback.setUrl(pingback.getUrl());
              movedPingback.setTrackbackDateLong(pingback.getTrackbackDateLong());

              movedPingback.save(user);
              pingback.delete(user);
            } catch (BlojsomException e) {
              _logger.error(e);
            }
          }

          movedEntry.load(user);
          entryToUpdate.delete(user);
          entryToUpdate = movedEntry;
        } else {
          entryToUpdate.save(user);
        }

        entryToUpdate.load(user);

        _logger.debug("Updated blog entry: " + entryToUpdate.getLink());

        StringBuffer entryLink = new StringBuffer();
        entryLink
            .append("<a href=\"")
            .append(user.getBlog().getBlogURL())
            .append(BlojsomUtils.removeInitialSlash(entryToUpdate.getCategory()))
            .append("?")
            .append(PERMALINK_PARAM)
            .append("=")
            .append(entryToUpdate.getPermalink())
            .append("\">")
            .append(entryToUpdate.getTitle())
            .append("</a>");
        addOperationResultMessage(
            context,
            formatAdminResource(
                UPDATED_BLOG_ENTRY_KEY,
                UPDATED_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {entryLink.toString()}));

        UpdatedBlogEntryEvent updateEvent =
            new UpdatedBlogEntryEvent(this, new Date(), entryToUpdate, user);
        _blojsomConfiguration.getEventBroadcaster().broadcastEvent(updateEvent);

        // Send trackback pings
        if (!BlojsomUtils.checkNullOrBlank(blogTrackbackURLs)) {
          sendTrackbackPings(blog, entryToUpdate, blogTrackbackURLs);
        }

        httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_PAGE);
        context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entryToUpdate);

        if (movingCategory) {
          blogCategoryName = updatedBlogCategoryName;
        }
        blogCategoryName = BlojsomUtils.addSlashes(blogCategoryName);
        context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
        addOperationResultMessage(
            context,
            formatAdminResource(
                FAILED_RETRIEVE_BLOG_ENTRY_KEY,
                FAILED_RETRIEVE_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {blogEntryId}));
        httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRIES_PAGE);
        entries = new BlogEntry[0];
      } catch (BlojsomException e) {
        _logger.error(e);
        addOperationResultMessage(
            context,
            formatAdminResource(
                FAILED_RETRIEVE_BLOG_ENTRY_KEY,
                FAILED_RETRIEVE_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {blogEntryId}));
        entries = new BlogEntry[0];
        httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRIES_PAGE);
      }
    } else if (DELETE_BLOG_ENTRY_ACTION.equals(action)) {
      _logger.debug("User requested delete blog entry action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      _logger.debug("Blog entry id: " + blogEntryId);

      try {
        BlogEntry entryToDelete =
            BlojsomUtils.fetchEntry(_fetcher, user, blogCategoryName, blogEntryId);
        String title = entryToDelete.getTitle();
        entryToDelete.delete(user);
        addOperationResultMessage(
            context,
            formatAdminResource(
                DELETED_BLOG_ENTRY_KEY,
                DELETED_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {title}));
        DeletedBlogEntryEvent deleteEvent =
            new DeletedBlogEntryEvent(this, new Date(), entryToDelete, user);
        _blojsomConfiguration.getEventBroadcaster().broadcastEvent(deleteEvent);
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
        addOperationResultMessage(
            context,
            formatAdminResource(
                FAILED_DELETE_BLOG_ENTRY_KEY,
                FAILED_DELETE_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {blogEntryId}));
        entries = new BlogEntry[0];
      } catch (BlojsomException e) {
        _logger.error(e);
        addOperationResultMessage(
            context,
            formatAdminResource(
                FAILED_DELETE_BLOG_ENTRY_KEY,
                FAILED_DELETE_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {blogEntryId}));
        entries = new BlogEntry[0];
      }

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRIES_PAGE);
    } else if (NEW_BLOG_ENTRY_ACTION.equals(action)) {
      _logger.debug("User requested new blog entry action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);

      _blojsomConfiguration
          .getEventBroadcaster()
          .processEvent(
              new ProcessBlogEntryEvent(
                  this, new Date(), null, user, httpServletRequest, httpServletResponse, context));

      context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
      httpServletRequest.setAttribute(PAGE_PARAM, ADD_BLOG_ENTRY_PAGE);
    } else if (ADD_BLOG_ENTRY_ACTION.equals(action)) {
      _logger.debug("User requested add blog entry action");
      Blog blog = user.getBlog();

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      if (!blogCategoryName.endsWith("/")) {
        blogCategoryName += "/";
      }
      String blogEntryDescription =
          BlojsomUtils.getRequestValue(BLOG_ENTRY_DESCRIPTION, httpServletRequest);
      String blogEntryTitle = BlojsomUtils.getRequestValue(BLOG_ENTRY_TITLE, httpServletRequest);

      if (BlojsomUtils.checkNullOrBlank(blogEntryTitle)
          && BlojsomUtils.checkNullOrBlank(blogEntryDescription)) {
        httpServletRequest.setAttribute(PAGE_PARAM, ADD_BLOG_ENTRY_PAGE);
        _blojsomConfiguration
            .getEventBroadcaster()
            .processEvent(
                new ProcessBlogEntryEvent(
                    this,
                    new Date(),
                    null,
                    user,
                    httpServletRequest,
                    httpServletResponse,
                    context));

        addOperationResultMessage(
            context,
            getAdminResource(
                BLANK_ENTRY_KEY, BLANK_ENTRY_KEY, user.getBlog().getBlogAdministrationLocale()));

        return entries;
      }

      if (BlojsomUtils.checkNullOrBlank(blogEntryTitle)) {
        blogEntryDescription = BlojsomUtils.LINE_SEPARATOR + blogEntryDescription;
      }
      String allowComments =
          BlojsomUtils.getRequestValue(BLOG_METADATA_COMMENTS_DISABLED, httpServletRequest);
      String allowTrackbacks =
          BlojsomUtils.getRequestValue(BLOG_METADATA_TRACKBACKS_DISABLED, httpServletRequest);
      String blogTrackbackURLs =
          BlojsomUtils.getRequestValue(BLOG_TRACKBACK_URLS, httpServletRequest);
      String proposedBlogFilename =
          BlojsomUtils.getRequestValue(BLOG_ENTRY_PROPOSED_NAME, httpServletRequest);
      String pingBlogURLS = BlojsomUtils.getRequestValue(PING_BLOG_URLS, httpServletRequest);
      String sendPingbacks =
          BlojsomUtils.getRequestValue(
              PingbackPlugin.PINGBACK_PLUGIN_METADATA_SEND_PINGBACKS, httpServletRequest);

      BlogCategory category;
      category = _fetcher.newBlogCategory();
      category.setCategory(blogCategoryName);
      category.setCategoryURL(
          user.getBlog().getBlogURL() + BlojsomUtils.removeInitialSlash(blogCategoryName));

      BlogEntry entry;
      entry = _fetcher.newBlogEntry();
      entry.setTitle(blogEntryTitle);
      entry.setCategory(blogCategoryName);
      entry.setDescription(blogEntryDescription);
      entry.setBlogCategory(category);

      Map entryMetaData = new HashMap();
      username =
          (String)
              httpServletRequest
                  .getSession()
                  .getAttribute(
                      user.getBlog().getBlogAdminURL() + "_" + BLOJSOM_ADMIN_PLUGIN_USERNAME_KEY);
      entryMetaData.put(BlojsomMetaDataConstants.BLOG_ENTRY_METADATA_AUTHOR, username);

      String entryPublishDateTime = httpServletRequest.getParameter(BLOG_ENTRY_PUBLISH_DATETIME);
      if (!BlojsomUtils.checkNullOrBlank(entryPublishDateTime)) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        try {
          Date publishDateTime = simpleDateFormat.parse(entryPublishDateTime);
          _logger.debug("Publishing blog entry at: " + publishDateTime.toString());
          entryMetaData.put(
              BlojsomMetaDataConstants.BLOG_ENTRY_METADATA_TIMESTAMP,
              Long.toString(publishDateTime.getTime()));
        } catch (ParseException e) {
          _logger.error(e);
          entryMetaData.put(
              BlojsomMetaDataConstants.BLOG_ENTRY_METADATA_TIMESTAMP,
              Long.toString(new Date().getTime()));
        }
      } else {
        entryMetaData.put(
            BlojsomMetaDataConstants.BLOG_ENTRY_METADATA_TIMESTAMP,
            Long.toString(new Date().getTime()));
      }

      if (!BlojsomUtils.checkNullOrBlank(allowComments)) {
        entryMetaData.put(BLOG_METADATA_COMMENTS_DISABLED, "y");
      }

      if (!BlojsomUtils.checkNullOrBlank(allowTrackbacks)) {
        entryMetaData.put(BLOG_METADATA_TRACKBACKS_DISABLED, "y");
      }

      if (BlojsomUtils.checkNullOrBlank(pingBlogURLS)) {
        entryMetaData.put(WeblogsPingPlugin.NO_PING_WEBLOGS_METADATA, "true");
      }

      if (!BlojsomUtils.checkNullOrBlank(sendPingbacks)) {
        entryMetaData.put(PingbackPlugin.PINGBACK_PLUGIN_METADATA_SEND_PINGBACKS, "true");
      }

      entry.setMetaData(entryMetaData);

      try {
        _blojsomConfiguration
            .getEventBroadcaster()
            .processEvent(
                new ProcessBlogEntryEvent(
                    this,
                    new Date(),
                    entry,
                    user,
                    httpServletRequest,
                    httpServletResponse,
                    context));

        entry.save(user);
        entry.load(user);

        StringBuffer entryLink = new StringBuffer();
        entry.setLink(
            user.getBlog().getBlogURL()
                + BlojsomUtils.removeInitialSlash(entry.getCategory())
                + "?"
                + PERMALINK_PARAM
                + "="
                + entry.getPermalink());
        entryLink
            .append("<a href=\"")
            .append(entry.getLink())
            .append("\">")
            .append(entry.getTitle())
            .append("</a>");
        addOperationResultMessage(
            context,
            formatAdminResource(
                ADDED_BLOG_ENTRY_KEY,
                ADDED_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {entryLink.toString()}));

        AddBlogEntryEvent addEvent = new AddBlogEntryEvent(this, new Date(), entry, user);
        _blojsomConfiguration.getEventBroadcaster().broadcastEvent(addEvent);
      } catch (BlojsomException e) {
        _logger.error(e);
        addOperationResultMessage(
            context,
            formatAdminResource(
                FAILED_ADD_BLOG_ENTRY_KEY,
                FAILED_ADD_BLOG_ENTRY_KEY,
                user.getBlog().getBlogAdministrationLocale(),
                new Object[] {blogCategoryName}));
      }

      // Send trackback pings
      if (!BlojsomUtils.checkNullOrBlank(blogTrackbackURLs)) {
        sendTrackbackPings(blog, entry, blogTrackbackURLs);
      }

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_ACTION);
      context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entry);
      context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
    } else if (DELETE_BLOG_COMMENTS.equals(action)) {
      _logger.debug("User requested delete blog comments action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      try {
        blogEntryId = URLDecoder.decode(blogEntryId, UTF8);
      } catch (UnsupportedEncodingException e) {
        _logger.error(e);
      }
      _logger.debug("Blog entry id: " + blogEntryId);

      BlogCategory category;
      category = _fetcher.newBlogCategory();
      category.setCategory(blogCategoryName);
      category.setCategoryURL(
          user.getBlog().getBlogURL() + BlojsomUtils.removeInitialSlash(blogCategoryName));

      Map fetchMap = new HashMap();
      fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, category);
      fetchMap.put(BlojsomFetcher.FETCHER_PERMALINK, blogEntryId);
      try {
        entries = _fetcher.fetchEntries(fetchMap, user);
        if (entries != null) {
          _logger.debug(
              "Retrieved " + entries.length + " entries from category: " + blogCategoryName);
          BlogEntry entryToUpdate = entries[0];

          String[] blogCommentIDs = httpServletRequest.getParameterValues(BLOG_COMMENT_ID);
          if (blogCommentIDs != null && blogCommentIDs.length > 0) {
            for (int i = 0; i < blogCommentIDs.length; i++) {
              String blogCommentID = blogCommentIDs[i];
              BlogComment[] blogComments = entryToUpdate.getCommentsAsArray();
              for (int j = 0; j < blogComments.length; j++) {
                BlogComment blogComment = blogComments[j];
                if (blogComment.getId().equals(blogCommentID)) {
                  try {
                    blogComment.delete(user);

                    _blojsomConfiguration
                        .getEventBroadcaster()
                        .broadcastEvent(
                            new CommentDeletedEvent(this, new Date(), blogComment, user));
                  } catch (BlojsomException e) {
                    _logger.error(e);
                  }
                }
              }
            }

            addOperationResultMessage(
                context,
                formatAdminResource(
                    DELETED_COMMENTS_KEY,
                    DELETED_COMMENTS_KEY,
                    user.getBlog().getBlogAdministrationLocale(),
                    new Object[] {new Integer(blogCommentIDs.length)}));

            entries = _fetcher.fetchEntries(fetchMap, user);
            entryToUpdate = entries[0];
          }

          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entryToUpdate);
          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
        }
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
      }

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_PAGE);
    } else if (APPROVE_BLOG_COMMENTS.equals(action)) {
      _logger.debug("User requested approve blog comments action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      try {
        blogEntryId = URLDecoder.decode(blogEntryId, UTF8);
      } catch (UnsupportedEncodingException e) {
        _logger.error(e);
      }
      _logger.debug("Blog entry id: " + blogEntryId);

      BlogCategory category;
      category = _fetcher.newBlogCategory();
      category.setCategory(blogCategoryName);
      category.setCategoryURL(
          user.getBlog().getBlogURL() + BlojsomUtils.removeInitialSlash(blogCategoryName));

      Map fetchMap = new HashMap();
      fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, category);
      fetchMap.put(BlojsomFetcher.FETCHER_PERMALINK, blogEntryId);
      try {
        entries = _fetcher.fetchEntries(fetchMap, user);
        if (entries != null) {
          _logger.debug(
              "Retrieved " + entries.length + " entries from category: " + blogCategoryName);
          BlogEntry entryToUpdate = entries[0];

          String[] blogCommentIDs = httpServletRequest.getParameterValues(BLOG_COMMENT_ID);
          if (blogCommentIDs != null && blogCommentIDs.length > 0) {
            for (int i = 0; i < blogCommentIDs.length; i++) {
              String blogCommentID = blogCommentIDs[i];
              BlogComment[] blogComments = entryToUpdate.getCommentsAsArray();

              for (int j = 0; j < blogComments.length; j++) {
                BlogComment blogComment = blogComments[j];
                if (blogComment.getId().equals(blogCommentID)) {
                  Map blogCommentMetaData = blogComment.getMetaData();

                  blogCommentMetaData.put(
                      CommentModerationPlugin.BLOJSOM_COMMENT_MODERATION_PLUGIN_APPROVED, "true");
                  try {
                    blogComment.save(user);

                    _blojsomConfiguration
                        .getEventBroadcaster()
                        .broadcastEvent(
                            new CommentApprovedEvent(this, new Date(), blogComment, user));
                  } catch (BlojsomException e) {
                    _logger.error(e);
                  }
                }
              }
            }

            addOperationResultMessage(
                context,
                formatAdminResource(
                    APPROVED_COMMENTS_KEY,
                    APPROVED_COMMENTS_KEY,
                    user.getBlog().getBlogAdministrationLocale(),
                    new Object[] {new Integer(blogCommentIDs.length)}));

            entries = _fetcher.fetchEntries(fetchMap, user);
            entryToUpdate = entries[0];
          }

          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entryToUpdate);
          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
        }
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
      }

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_PAGE);
    } else if (DELETE_BLOG_TRACKBACKS.equals(action)) {
      _logger.debug("User requested delete blog trackbacks action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      try {
        blogEntryId = URLDecoder.decode(blogEntryId, UTF8);
      } catch (UnsupportedEncodingException e) {
        _logger.error(e);
      }
      _logger.debug("Blog entry id: " + blogEntryId);

      BlogCategory category;
      category = _fetcher.newBlogCategory();
      category.setCategory(blogCategoryName);
      category.setCategoryURL(
          user.getBlog().getBlogURL() + BlojsomUtils.removeInitialSlash(blogCategoryName));

      Map fetchMap = new HashMap();
      fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, category);
      fetchMap.put(BlojsomFetcher.FETCHER_PERMALINK, blogEntryId);
      try {
        entries = _fetcher.fetchEntries(fetchMap, user);
        if (entries != null) {
          _logger.debug(
              "Retrieved " + entries.length + " entries from category: " + blogCategoryName);
          BlogEntry entryToUpdate = entries[0];

          String[] blogTrackbackIDs = httpServletRequest.getParameterValues(BLOG_TRACKBACK_ID);
          if (blogTrackbackIDs != null && blogTrackbackIDs.length > 0) {
            for (int i = 0; i < blogTrackbackIDs.length; i++) {
              String blogTrackbackID = blogTrackbackIDs[i];
              Trackback[] trackbacks = entryToUpdate.getTrackbacksAsArray();

              for (int j = 0; j < trackbacks.length; j++) {
                Trackback trackback = trackbacks[j];
                if (trackback.getId().equals(blogTrackbackID)) {
                  try {
                    trackback.delete(user);

                    _blojsomConfiguration
                        .getEventBroadcaster()
                        .broadcastEvent(
                            new TrackbackDeletedEvent(this, new Date(), trackback, user));
                  } catch (BlojsomException e) {
                    _logger.error(e);
                  }
                }
              }
            }

            addOperationResultMessage(
                context,
                formatAdminResource(
                    DELETED_TRACKBACKS_KEY,
                    DELETED_TRACKBACKS_KEY,
                    user.getBlog().getBlogAdministrationLocale(),
                    new Object[] {new Integer(blogTrackbackIDs.length)}));

            entries = _fetcher.fetchEntries(fetchMap, user);
            entryToUpdate = entries[0];
          }

          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entryToUpdate);
          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
        }
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
      }

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_PAGE);

    } else if (APPROVE_BLOG_TRACKBACKS.equals(action)) {
      _logger.debug("User requested approve blog trackbacks action");

      String blogCategoryName =
          BlojsomUtils.getRequestValue(BLOG_CATEGORY_NAME, httpServletRequest);
      blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
      String blogEntryId = BlojsomUtils.getRequestValue(BLOG_ENTRY_ID, httpServletRequest);
      try {
        blogEntryId = URLDecoder.decode(blogEntryId, UTF8);
      } catch (UnsupportedEncodingException e) {
        _logger.error(e);
      }
      _logger.debug("Blog entry id: " + blogEntryId);

      BlogCategory category;
      category = _fetcher.newBlogCategory();
      category.setCategory(blogCategoryName);
      category.setCategoryURL(
          user.getBlog().getBlogURL() + BlojsomUtils.removeInitialSlash(blogCategoryName));

      Map fetchMap = new HashMap();
      fetchMap.put(BlojsomFetcher.FETCHER_CATEGORY, category);
      fetchMap.put(BlojsomFetcher.FETCHER_PERMALINK, blogEntryId);
      try {
        entries = _fetcher.fetchEntries(fetchMap, user);
        if (entries != null) {
          _logger.debug(
              "Retrieved " + entries.length + " entries from category: " + blogCategoryName);
          BlogEntry entryToUpdate = entries[0];

          String[] blogTrackbackIDs = httpServletRequest.getParameterValues(BLOG_TRACKBACK_ID);
          if (blogTrackbackIDs != null && blogTrackbackIDs.length > 0) {
            for (int i = 0; i < blogTrackbackIDs.length; i++) {
              String blogTrackbackID = blogTrackbackIDs[i];
              Trackback[] trackbacks = entryToUpdate.getTrackbacksAsArray();

              for (int j = 0; j < trackbacks.length; j++) {
                Trackback trackback = trackbacks[j];
                if (trackback.getId().equals(blogTrackbackID)) {
                  Map blogTrackbackMetaData = trackback.getMetaData();

                  blogTrackbackMetaData.put(
                      TrackbackModerationPlugin.BLOJSOM_TRACKBACK_MODERATION_PLUGIN_APPROVED,
                      "true");
                  try {
                    trackback.save(user);

                    _blojsomConfiguration
                        .getEventBroadcaster()
                        .broadcastEvent(
                            new TrackbackApprovedEvent(this, new Date(), trackback, user));
                  } catch (BlojsomException e) {
                    _logger.error(e);
                  }
                }
              }
            }

            addOperationResultMessage(
                context,
                formatAdminResource(
                    APPROVED_TRACKBACKS_KEY,
                    APPROVED_TRACKBACKS_KEY,
                    user.getBlog().getBlogAdministrationLocale(),
                    new Object[] {new Integer(blogTrackbackIDs.length)}));

            entries = _fetcher.fetchEntries(fetchMap, user);
            entryToUpdate = entries[0];
          }

          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_ENTRY, entryToUpdate);
          context.put(BLOJSOM_PLUGIN_EDIT_BLOG_ENTRIES_CATEGORY, blogCategoryName);
        }
      } catch (BlojsomFetcherException e) {
        _logger.error(e);
      }

      httpServletRequest.setAttribute(PAGE_PARAM, EDIT_BLOG_ENTRY_PAGE);
    }

    return entries;
  }
  /**
   * Send trackback pings to a comma-separated list of trackback URLs
   *
   * @param blog Blog information
   * @param entry Blog entry
   * @param blogTrackbackURLs Trackback URLs
   */
  protected void sendTrackbackPings(Blog blog, BlogEntry entry, String blogTrackbackURLs) {
    // Build the URL parameters for the trackback ping URL
    StringBuffer trackbackPingURLParameters = new StringBuffer();
    try {
      trackbackPingURLParameters
          .append("&")
          .append(TrackbackPlugin.TRACKBACK_URL_PARAM)
          .append("=")
          .append(entry.getLink());
      trackbackPingURLParameters
          .append("&")
          .append(TrackbackPlugin.TRACKBACK_TITLE_PARAM)
          .append("=")
          .append(URLEncoder.encode(entry.getTitle(), UTF8));
      trackbackPingURLParameters
          .append("&")
          .append(TrackbackPlugin.TRACKBACK_BLOG_NAME_PARAM)
          .append("=")
          .append(URLEncoder.encode(blog.getBlogName(), UTF8));

      String excerpt = entry.getDescription().replaceAll("<.*?>", "");
      if (excerpt.length() > 255) {
        excerpt = excerpt.substring(0, 251);
        excerpt += "...";
      }
      trackbackPingURLParameters
          .append("&")
          .append(TrackbackPlugin.TRACKBACK_EXCERPT_PARAM)
          .append("=")
          .append(URLEncoder.encode(excerpt, UTF8));
    } catch (UnsupportedEncodingException e) {
      _logger.error(e);
    }

    String[] trackbackURLs = BlojsomUtils.parseDelimitedList(blogTrackbackURLs, WHITESPACE);
    if (trackbackURLs != null && trackbackURLs.length > 0) {
      for (int i = 0; i < trackbackURLs.length; i++) {
        String trackbackURL = trackbackURLs[i].trim();
        StringBuffer trackbackPingURL = new StringBuffer(trackbackURL);

        _logger.debug(
            "Automatically sending trackback ping to URL: " + trackbackPingURL.toString());

        try {
          URL trackbackUrl = new URL(trackbackPingURL.toString());

          // Open a connection to the trackback URL and read its input
          HttpURLConnection trackbackUrlConnection =
              (HttpURLConnection) trackbackUrl.openConnection();
          trackbackUrlConnection.setRequestMethod("POST");
          trackbackUrlConnection.setRequestProperty("Content-Encoding", UTF8);
          trackbackUrlConnection.setRequestProperty(
              "Content-Type", "application/x-www-form-urlencoded");
          trackbackUrlConnection.setRequestProperty(
              "Content-Length", "" + trackbackPingURLParameters.length());
          trackbackUrlConnection.setDoOutput(true);
          trackbackUrlConnection
              .getOutputStream()
              .write(trackbackPingURLParameters.toString().getBytes(UTF8));
          trackbackUrlConnection.connect();
          BufferedReader trackbackStatus =
              new BufferedReader(new InputStreamReader(trackbackUrlConnection.getInputStream()));
          String line;
          StringBuffer status = new StringBuffer();
          while ((line = trackbackStatus.readLine()) != null) {
            status.append(line).append("\n");
          }
          trackbackUrlConnection.disconnect();

          _logger.debug("Trackback status for ping to " + trackbackURL + ": " + status.toString());
        } catch (IOException e) {
          _logger.error(e);
        }
      }
    }
  }
  /**
   * Process the blog entries
   *
   * @param httpServletRequest Request
   * @param httpServletResponse Response
   * @param user {@link BlogUser} instance
   * @param context Context
   * @param entries Blog entries retrieved for the particular request
   * @return Modified set of blog entries
   * @throws BlojsomPluginException If there is an error processing the blog entries
   */
  public BlogEntry[] process(
      HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse,
      BlogUser user,
      Map context,
      BlogEntry[] entries)
      throws BlojsomPluginException {
    String wantsToSeeMore = httpServletRequest.getParameter(SHOW_ME_MORE_PARAM);
    if ("y".equalsIgnoreCase(wantsToSeeMore)) {
      return entries;
    } else {
      ShowMeMoreConfiguration showMeMoreConfiguration;
      try {
        showMeMoreConfiguration =
            ShowMeMoreUtilities.loadConfiguration(
                user.getId(), _showMeMoreConfigurationFile, _blojsomConfiguration, _servletConfig);
      } catch (IOException e) {
        _logger.error(e);

        return entries;
      }

      int cutoff = showMeMoreConfiguration.getCutoff();
      String textCutoff = showMeMoreConfiguration.getTextCutoff();
      String moreText = showMeMoreConfiguration.getMoreText();
      String textCutoffStart = showMeMoreConfiguration.getTextCutoffStart();
      String textCutoffEnd = showMeMoreConfiguration.getTextCutoffEnd();

      for (int i = 0; i < entries.length; i++) {
        BlogEntry entry = entries[i];
        String description = entry.getDescription();
        StringBuffer partialDescription = new StringBuffer();
        int indexOfCutoffText;

        if (!BlojsomUtils.checkNullOrBlank(textCutoffStart)
            && !BlojsomUtils.checkNullOrBlank(textCutoffEnd)) {
          StringBuffer showMeMoreText = new StringBuffer("<a href=\"");
          showMeMoreText.append(entry.getLink());
          showMeMoreText.append("&amp;");
          showMeMoreText.append(SHOW_ME_MORE_PARAM);
          showMeMoreText.append("=y\">");
          showMeMoreText.append(moreText);
          showMeMoreText.append("</a>");
          Pattern cutoffPattern =
              Pattern.compile(
                  "(" + textCutoffStart + ".*?" + textCutoffEnd + ").*?",
                  Pattern.DOTALL | Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
          Matcher cutoffMatcher = cutoffPattern.matcher(description);
          if (cutoffMatcher.find()) {
            description = cutoffMatcher.replaceAll(showMeMoreText.toString());
            entry.setDescription(description);
          }
        }

        if (!BlojsomUtils.checkNullOrBlank(textCutoff)) {
          indexOfCutoffText = description.indexOf(textCutoff);
          if (indexOfCutoffText != -1) {
            partialDescription.append(description.substring(0, indexOfCutoffText));
            partialDescription.append("&nbsp; <a href=\"");
            partialDescription.append(entry.getLink());
            partialDescription.append("&amp;");
            partialDescription.append(SHOW_ME_MORE_PARAM);
            partialDescription.append("=y\">");
            partialDescription.append(moreText);
            partialDescription.append("</a>");
            entry.setDescription(partialDescription.toString());
          } else if ((cutoff > 0) && (description.length() > cutoff)) {
            partialDescription.append(description.substring(0, cutoff));
            partialDescription.append("&nbsp; <a href=\"");
            partialDescription.append(entry.getLink());
            partialDescription.append("&amp;");
            partialDescription.append(SHOW_ME_MORE_PARAM);
            partialDescription.append("=y\">");
            partialDescription.append(moreText);
            partialDescription.append("</a>");
            entry.setDescription(partialDescription.toString());
          }
        } else if ((cutoff > 0) && (description.length() > cutoff)) {
          partialDescription.append(description.substring(0, cutoff));
          partialDescription.append("&nbsp; <a href=\"");
          partialDescription.append(entry.getLink());
          partialDescription.append("&amp;");
          partialDescription.append(SHOW_ME_MORE_PARAM);
          partialDescription.append("=y\">");
          partialDescription.append(moreText);
          partialDescription.append("</a>");
          entry.setDescription(partialDescription.toString());
        }
      }

      return entries;
    }
  }