protected void moveAttachmentsFolders(
      MBMessage message,
      long oldAttachmentsFolderId,
      MBThread oldThread,
      MBThread newThread,
      ServiceContext serviceContext)
      throws PortalException {

    if (oldAttachmentsFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {

      Folder newThreadFolder = newThread.addAttachmentsFolder();

      PortletFileRepositoryUtil.movePortletFolder(
          message.getGroupId(),
          message.getUserId(),
          oldAttachmentsFolderId,
          newThreadFolder.getFolderId(),
          serviceContext);
    }

    List<MBMessage> childMessages =
        mbMessagePersistence.findByT_P(oldThread.getThreadId(), message.getMessageId());

    for (MBMessage childMessage : childMessages) {
      moveAttachmentsFolders(
          childMessage,
          childMessage.getAttachmentsFolderId(),
          oldThread,
          newThread,
          serviceContext);
    }
  }
  @Override
  protected void doExportStagedModel(PortletDataContext portletDataContext, MBMessage message)
      throws Exception {

    if ((message.getStatus() != WorkflowConstants.STATUS_APPROVED)
        || (message.getCategoryId() == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {

      return;
    }

    StagedModelDataHandlerUtil.exportStagedModel(portletDataContext, message.getCategory());

    Element messageElement = portletDataContext.getExportDataStagedModelElement(message);

    message.setPriority(message.getPriority());

    MBThread thread = message.getThread();

    messageElement.addAttribute("question", String.valueOf(thread.isQuestion()));

    boolean hasAttachmentsFileEntries = message.getAttachmentsFileEntriesCount() > 0;

    messageElement.addAttribute(
        "hasAttachmentsFileEntries", String.valueOf(hasAttachmentsFileEntries));

    if (portletDataContext.getBooleanParameter(MBPortletDataHandler.NAMESPACE, "attachments")
        && hasAttachmentsFileEntries) {

      for (FileEntry fileEntry : message.getAttachmentsFileEntries()) {
        String name = fileEntry.getTitle();
        String binPath = ExportImportPathUtil.getModelPath(message, name);

        Element attachmentElement = messageElement.addElement("attachment");

        attachmentElement.addAttribute("name", name);
        attachmentElement.addAttribute("bin-path", binPath);

        portletDataContext.addZipEntry(binPath, fileEntry.getContentStream());
      }

      long folderId = message.getAttachmentsFolderId();

      if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
        message.setAttachmentsFolderId(folderId);
      }
    }

    portletDataContext.addClassedModel(
        messageElement,
        ExportImportPathUtil.getModelPath(message),
        message,
        MBPortletDataHandler.NAMESPACE);
  }
  @Override
  public MBThread splitThread(
      long userId, long messageId, String subject, ServiceContext serviceContext)
      throws PortalException {

    MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);

    if (message.isRoot()) {
      throw new SplitThreadException(
          "Unable to split message " + messageId + " because it is a root message");
    }

    MBCategory category = message.getCategory();
    MBThread oldThread = message.getThread();
    MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(oldThread.getRootMessageId());
    long oldAttachmentsFolderId = message.getAttachmentsFolderId();

    // Message flags

    mbMessageLocalService.updateAnswer(message, false, true);

    // Create new thread

    MBThread thread = addThread(message.getCategoryId(), message, serviceContext);

    mbThreadPersistence.update(oldThread);

    // Update messages

    if (Validator.isNotNull(subject)) {
      MBMessageDisplay messageDisplay =
          mbMessageLocalService.getMessageDisplay(
              userId,
              messageId,
              WorkflowConstants.STATUS_ANY,
              MBThreadConstants.THREAD_VIEW_TREE,
              false);

      MBTreeWalker treeWalker = messageDisplay.getTreeWalker();

      List<MBMessage> messages = treeWalker.getMessages();

      int[] range = treeWalker.getChildrenRange(message);

      for (int i = range[0]; i < range[1]; i++) {
        MBMessage curMessage = messages.get(i);

        String oldSubject = message.getSubject();
        String curSubject = curMessage.getSubject();

        if (oldSubject.startsWith("RE: ")) {
          curSubject = StringUtil.replace(curSubject, rootMessage.getSubject(), subject);
        } else {
          curSubject = StringUtil.replace(curSubject, oldSubject, subject);
        }

        curMessage.setSubject(curSubject);

        mbMessagePersistence.update(curMessage);
      }

      message.setSubject(subject);
    }

    message.setThreadId(thread.getThreadId());
    message.setRootMessageId(thread.getRootMessageId());
    message.setParentMessageId(0);

    mbMessagePersistence.update(message);

    // Attachments

    moveAttachmentsFolders(message, oldAttachmentsFolderId, oldThread, thread, serviceContext);

    // Indexer

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

      indexer.reindex(message);
    }

    // Update children

    moveChildrenMessages(message, category, oldThread.getThreadId());

    // Update new thread

    MBUtil.updateThreadMessageCount(thread.getThreadId());

    // Update old thread

    MBUtil.updateThreadMessageCount(oldThread.getThreadId());

    // Category

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

      MBUtil.updateCategoryThreadCount(category.getCategoryId());
    }

    // Indexer

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

    indexer.reindex(oldThread);

    indexer.reindex(message.getThread());

    return thread;
  }