@Override
  public MBThread moveThread(long groupId, long categoryId, long threadId)
      throws PortalException, SystemException {

    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);

    long oldCategoryId = thread.getCategoryId();

    MBCategory oldCategory = null;

    if (oldCategoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
      oldCategory = mbCategoryPersistence.fetchByPrimaryKey(oldCategoryId);
    }

    MBCategory category = null;

    if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
      category = mbCategoryPersistence.fetchByPrimaryKey(categoryId);
    }

    // Thread

    thread.setModifiedDate(new Date());
    thread.setCategoryId(categoryId);

    mbThreadPersistence.update(thread);

    // Messages

    List<MBMessage> messages =
        mbMessagePersistence.findByG_C_T(groupId, oldCategoryId, thread.getThreadId());

    for (MBMessage message : messages) {
      message.setCategoryId(categoryId);

      mbMessagePersistence.update(message);

      // Indexer

      if (!message.isDiscussion()) {
        Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(MBMessage.class);

        indexer.reindex(message);
      }
    }

    // Category

    if ((oldCategory != null) && (categoryId != oldCategoryId)) {
      MBUtil.updateCategoryStatistics(oldCategory.getCompanyId(), oldCategory.getCategoryId());
    }

    if ((category != null) && (categoryId != oldCategoryId)) {
      MBUtil.updateCategoryStatistics(category.getCompanyId(), category.getCategoryId());
    }

    return thread;
  }
  @Override
  public MBThread updateStatus(long userId, long threadId, int status) throws PortalException {

    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);

    // Thread

    User user = userPersistence.findByPrimaryKey(userId);

    thread.setStatus(status);
    thread.setStatusByUserId(user.getUserId());
    thread.setStatusByUserName(user.getFullName());
    thread.setStatusDate(new Date());

    mbThreadPersistence.update(thread);

    // Messages

    if (thread.getCategoryId() != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

      // Category

      MBCategory category = mbCategoryPersistence.fetchByPrimaryKey(thread.getCategoryId());

      if (category != null) {
        MBUtil.updateCategoryStatistics(category.getCategoryId());
      }
    }

    // Indexer

    Indexer<MBThread> indexer = IndexerRegistryUtil.nullSafeGetIndexer(MBThread.class);

    indexer.reindex(thread);

    return thread;
  }
  @Override
  public MBThread updateStatus(long userId, long threadId, int status, int categoryStatus)
      throws PortalException, SystemException {

    MBThread thread = mbThreadPersistence.findByPrimaryKey(threadId);

    if (categoryStatus != WorkflowConstants.STATUS_IN_TRASH) {

      // Thread

      User user = userPersistence.findByPrimaryKey(userId);

      Date now = new Date();

      int oldStatus = thread.getStatus();

      thread.setModifiedDate(now);
      thread.setStatus(status);
      thread.setStatusByUserId(user.getUserId());
      thread.setStatusByUserName(user.getFullName());
      thread.setStatusDate(now);

      mbThreadPersistence.update(thread);

      // Messages

      updateDependentStatus(thread.getGroupId(), threadId, status);

      if (thread.getCategoryId() != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

        // Category

        MBCategory category = mbCategoryPersistence.fetchByPrimaryKey(thread.getCategoryId());

        if (category != null) {
          MBUtil.updateCategoryStatistics(category.getCompanyId(), category.getCategoryId());
        }
      }

      MBMessage message = mbMessageLocalService.getMBMessage(thread.getRootMessageId());

      JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();

      extraDataJSONObject.put("rootMessageId", thread.getRootMessageId());
      extraDataJSONObject.put("title", message.getSubject());

      if (status == WorkflowConstants.STATUS_IN_TRASH) {

        // Social

        socialActivityLocalService.addActivity(
            userId,
            thread.getGroupId(),
            MBThread.class.getName(),
            thread.getThreadId(),
            SocialActivityConstants.TYPE_MOVE_TO_TRASH,
            extraDataJSONObject.toString(),
            0);

        // Trash

        trashEntryLocalService.addTrashEntry(
            userId,
            thread.getGroupId(),
            MBThread.class.getName(),
            thread.getThreadId(),
            oldStatus,
            null,
            null);
      } else {

        // Social

        socialActivityLocalService.addActivity(
            userId,
            thread.getGroupId(),
            MBThread.class.getName(),
            thread.getThreadId(),
            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
            extraDataJSONObject.toString(),
            0);

        // Trash

        trashEntryLocalService.deleteEntry(MBThread.class.getName(), thread.getThreadId());
      }
    } else {
      updateDependentStatus(thread.getGroupId(), threadId, status);
    }

    return thread;
  }
  @Override
  @SystemEvent(
      action = SystemEventConstants.ACTION_SKIP,
      send = false,
      type = SystemEventConstants.TYPE_DELETE)
  public void deleteThread(MBThread thread) throws PortalException, SystemException {

    MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(thread.getRootMessageId());

    // Indexer

    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(MBMessage.class);

    indexer.delete(thread);

    // Attachments

    long folderId = thread.getAttachmentsFolderId();

    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
      PortletFileRepositoryUtil.deleteFolder(folderId);
    }

    // Subscriptions

    subscriptionLocalService.deleteSubscriptions(
        thread.getCompanyId(), MBThread.class.getName(), thread.getThreadId());

    // Thread flags

    mbThreadFlagPersistence.removeByThreadId(thread.getThreadId());

    // Messages

    List<MBMessage> messages = mbMessagePersistence.findByThreadId(thread.getThreadId());

    for (MBMessage message : messages) {

      // Ratings

      ratingsStatsLocalService.deleteStats(message.getWorkflowClassName(), message.getMessageId());

      // Asset

      assetEntryLocalService.deleteEntry(message.getWorkflowClassName(), message.getMessageId());

      // Resources

      if (!message.isDiscussion()) {
        resourceLocalService.deleteResource(
            message.getCompanyId(),
            message.getWorkflowClassName(),
            ResourceConstants.SCOPE_INDIVIDUAL,
            message.getMessageId());
      }

      // Message

      mbMessagePersistence.remove(message);

      // Statistics

      if (!message.isDiscussion()) {
        mbStatsUserLocalService.updateStatsUser(message.getGroupId(), message.getUserId());
      }

      // Workflow

      workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
          message.getCompanyId(), message.getGroupId(),
          message.getWorkflowClassName(), message.getMessageId());
    }

    // Category

    if ((rootMessage.getCategoryId() != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID)
        && (rootMessage.getCategoryId() != MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {

      try {
        MBCategory category = mbCategoryPersistence.findByPrimaryKey(thread.getCategoryId());

        MBUtil.updateCategoryStatistics(category.getCompanyId(), category.getCategoryId());
      } catch (NoSuchCategoryException nsce) {
        if (!thread.isInTrash()) {
          throw nsce;
        }
      }
    }

    // Thread Asset

    AssetEntry assetEntry =
        assetEntryLocalService.fetchEntry(MBThread.class.getName(), thread.getThreadId());

    if (assetEntry != null) {
      assetEntry.setTitle(rootMessage.getSubject());

      assetEntryLocalService.updateAssetEntry(assetEntry);
    }

    assetEntryLocalService.deleteEntry(MBThread.class.getName(), thread.getThreadId());

    // Trash

    trashEntryLocalService.deleteEntry(MBThread.class.getName(), thread.getThreadId());

    // Thread

    mbThreadPersistence.remove(thread);
  }