@Override
 public void updatePost(Post post, int type) {
   switch (type) {
     case HIDDEN:
       if (post.getIsHidden() == true) {
         ForumActivityContext ctx = ForumActivityContext.makeContextForUpdatePost(post);
         PostActivityTask task = PostActivityTask.HIDE_POST;
         ActivityExecutor.execute(task, ctx);
       } else {
         ForumActivityContext ctx = ForumActivityContext.makeContextForUpdatePost(post);
         PostActivityTask task = PostActivityTask.UNHIDE_POST;
         ActivityExecutor.execute(task, ctx);
       }
       break;
     case WAITING:
       if (post.getIsWaiting() == true) {
         ForumActivityContext ctx = ForumActivityContext.makeContextForUpdatePost(post);
         PostActivityTask task = PostActivityTask.HIDE_POST;
         ActivityExecutor.execute(task, ctx);
       } else {
         ForumActivityContext ctx = ForumActivityContext.makeContextForUpdatePost(post);
         PostActivityTask task = PostActivityTask.UNHIDE_POST;
         ActivityExecutor.execute(task, ctx);
       }
       break;
     default:
       return;
   }
 }
 @Override
 public void updatePost(Post post) {
   ForumActivityContext ctx = ForumActivityContext.makeContextForUpdatePost(post);
   PostActivityTask task = PostActivityTask.UPDATE_POST;
   ctx = ForumActivityUtils.processBBCode(ctx);
   ActivityExecutor.execute(task, ctx);
 }
 @Override
 public void moveTopic(Topic topic, String toCategoryName, String toForumName) {
   ForumActivityContext ctx =
       ForumActivityContext.makeContextForMoveTopic(topic, toCategoryName, toForumName);
   TopicActivityTask task = TopicActivityTask.MOVE_TOPIC;
   ActivityExecutor.execute(task, ctx);
 }
  private void updateProperties(Topic topic, ForumActivityContext ctx) {
    PropertyChangeSupport newPcs = new PropertyChangeSupport(topic);
    PropertyChangeSupport pcs = topic.getPcs();

    // Topic.TOPIC_NAME
    if (pcs.hasPropertyName(Topic.TOPIC_NAME)) {
      newPcs.addPropertyChange(pcs.getPropertyChange(Topic.TOPIC_NAME));
    }

    // Topic.TOPIC_CONTENT
    if (pcs.hasPropertyName(Topic.TOPIC_CONTENT)) {
      newPcs.addPropertyChange(pcs.getPropertyChange(Topic.TOPIC_CONTENT));
    }

    if (newPcs.getChangeEvents().length > 1) {
      ctx.setPcs(newPcs);

      // 1. executes task
      TopicActivityTask task = TopicActivityTask.UPDATE_TOPIC_PROPERTIES;
      ctx = ForumActivityUtils.processBBCode(ctx);
      ActivityExecutor.execute(task, ctx);
      // 2. remove events
      pcs.removePropertyChange(Topic.TOPIC_NAME);
      pcs.removePropertyChange(Topic.TOPIC_CONTENT);
    }
  }
 @Override
 public void updateTopics(List<Topic> topics, boolean isLock) {
   for (Topic topic : topics) {
     topic.setIsLock(isLock);
     ForumActivityContext ctx = ForumActivityContext.makeContextForAddTopic(topic);
     TopicActivityTask task = TopicActivityTask.UPDATE_FORUM_TOPIC;
     ActivityExecutor.execute(task, ctx);
   }
 }
  @Override
  public void addTopic(Topic topic) {
    ForumActivityContext ctx = ForumActivityContext.makeContextForAddTopic(topic);
    TopicActivityTask task = TopicActivityTask.ADD_TOPIC;
    ctx = ForumActivityUtils.processBBCode(ctx);
    ExoSocialActivity got = ActivityExecutor.execute(task, ctx);

    //
    ForumActivityUtils.takeActivityBack(topic, got);
  }
  @Override
  public void addPost(Post post) {
    ForumActivityContext ctx = ForumActivityContext.makeContextForAddPost(post);
    PostActivityTask task = PostActivityTask.ADD_POST;
    ctx = ForumActivityUtils.processBBCode(ctx);
    ExoSocialActivity comment = ActivityExecutor.execute(task, ctx);

    //
    ForumActivityUtils.takeCommentBack(post, comment);
  }
  @Override
  public void mergeTopic(Topic newTopic, String removeActivityId1, String removeActivityId2) {
    ForumActivityContext ctx =
        ForumActivityContext.makeContextForMergeTopic(
            newTopic, removeActivityId1, removeActivityId2);
    TopicActivityTask task = TopicActivityTask.MERGE_TOPIC;
    ExoSocialActivity got = ActivityExecutor.execute(task, ctx);

    //
    ForumActivityUtils.takeActivityBack(ctx.getTopic(), got);
  }
  @Override
  public void splitTopic(Topic newTopic, Topic splitedTopic, String removeActivityId) {
    /** 1. Call delete activityId */
    /** 2. Call add topic */
    ForumActivityContext ctx =
        ForumActivityContext.makeContextForSplitTopic(newTopic, splitedTopic, removeActivityId);
    TopicActivityTask task = TopicActivityTask.SPLIT_TOPIC;
    ExoSocialActivity activity = ActivityExecutor.execute(task, ctx);

    //
    ForumActivityUtils.takeActivityBack(newTopic, activity);
  }
  @Override
  public void updateTopic(Topic topic) {

    TopicActivityTask task = null;
    ForumActivityContext ctx = ForumActivityContext.makeContextForUpdateTopic(topic);

    updateProperties(topic, ctx);

    PropertyChangeEvent[] events = topic.getChangeEvent();

    for (int i = 0; i < events.length; i++) {
      task = getTaskFromUpdateTopic(events[i], ctx);
      ActivityExecutor.execute(task, ctx);
    }
  }