/**
  * @param mn
  * @param forumFormatter
  * @param metaInfo
  * @return
  */
 private String formatThread(
     final MessageNode mn, final ForumFormatter forumFormatter, final Map metaInfo) {
   forumFormatter.setForumMetaInformation(metaInfo);
   final StringBuilder formattedThread = new StringBuilder();
   forumFormatter.openThread();
   final TreeVisitor tv = new TreeVisitor(forumFormatter, mn, false);
   tv.visitAll();
   return formattedThread.append(formattedThread.append(forumFormatter.closeThread())).toString();
 }
  private void doInsert(UserRequest ureq, TreePosition tp) {
    ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());

    int insertPos = tp.getChildpos();
    CourseNode selectedNode = getCourseNode(tp.getParentTreeNode());
    CourseEditorTreeNode insertParent =
        course.getEditorTreeModel().getCourseEditorNodeById(selectedNode.getIdent());

    // check if insert position is within the to-be-copied tree
    if (course.getEditorTreeModel().checkIfIsChild(insertParent, moveCopyFrom)) {
      showError("movecopynode.error.overlap");
      fireEvent(ureq, Event.CANCELLED_EVENT);
    } else if (copy) { // do a copy
      // copy subtree and save model
      recursiveCopy(
          moveCopyFrom,
          insertParent,
          insertPos,
          true,
          CourseFactory.getCourseEditSession(ores.getResourceableId()));
      CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());

      ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_COPIED, getClass());
      fireEvent(ureq, Event.DONE_EVENT);
    } else { // move only
      if (insertParent.getIdent().equals(moveCopyFrom.getParent().getIdent())) {
        // same parent, adjust insertPos
        if (insertPos > moveCopyFrom.getPosition()) insertPos--;
      }
      insertParent.insert(moveCopyFrom, insertPos);

      moveCopyFrom.setDirty(true);
      // mark subtree as dirty
      TreeVisitor tv =
          new TreeVisitor(
              new Visitor() {
                @Override
                public void visit(INode node) {
                  CourseEditorTreeNode cetn = (CourseEditorTreeNode) node;
                  cetn.setDirty(true);
                }
              },
              moveCopyFrom,
              true);
      tv.visitAll();
      CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
      showInfo("movecopynode.info.condmoved");

      ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_MOVED, getClass());
      fireEvent(ureq, Event.DONE_EVENT);
    }
  }
 /**
  * @param topNodeList
  * @param forumFormatter
  * @param metaInfo
  * @return
  */
 private String formatForum(
     final List topNodeList, final ForumFormatter forumFormatter, final Map metaInfo) {
   forumFormatter.setForumMetaInformation(metaInfo);
   final StringBuilder formattedForum = new StringBuilder();
   forumFormatter.openForum();
   for (final Iterator iterTop = topNodeList.iterator(); iterTop.hasNext(); ) {
     final MessageNode mn = (MessageNode) iterTop.next();
     // a new top thread starts, inform formatter
     forumFormatter.openThread();
     final TreeVisitor tv = new TreeVisitor(forumFormatter, mn, false);
     tv.visitAll();
     // commit
     formattedForum.append(forumFormatter.closeThread());
   }
   return formattedForum.append(forumFormatter.closeForum().toString()).toString();
 }