class ForumRTFFormatter extends ForumFormatter {

    private String convertHTMLMarkupToRTF(final String originalText) {
        String htmlText = originalText;

        // escape reserved chars in RTF: '{', '}', '\'
        final Matcher mbs = PATTERN_RTX_RESERVED_BACKSLASH.matcher(htmlText);
        final StringBuffer backslashes = new StringBuffer();
        while (mbs.find()) {
            mbs.appendReplacement(backslashes, "\\\\\\\\");
        }
        mbs.appendTail(backslashes);
        htmlText = backslashes.toString();

        final Matcher mbro = PATTERN_RTX_RESERVED_BRACE_OPEN.matcher(htmlText);
        final StringBuffer openBraces = new StringBuffer();
        while (mbro.find()) {
            mbro.appendReplacement(openBraces, "\\\\{ ");
        }
        mbro.appendTail(openBraces);
        htmlText = openBraces.toString();

        final Matcher mbrc = PATTERN_RTX_RESERVED_BRACE_CLOSE.matcher(htmlText);
        final StringBuffer closedBraces = new StringBuffer();
        while (mbrc.find()) {
            mbrc.appendReplacement(closedBraces, "\\\\} ");
        }
        mbrc.appendTail(closedBraces);
        htmlText = closedBraces.toString();

        // search for lists and convert in RTF
        final StringBuffer rtfLists = new StringBuffer();
        final List<ListDefinition> lists = new ArrayList<ListDefinition>();
        final Matcher mli = PATTERN_HTML_LIST.matcher(htmlText);
        int counter = 1;
        while (mli.find()) {
            final String listDefinition = mli.group();
            final boolean orderedList = listDefinition.contains("<ol>");
            final ListDefinition list = new ListDefinition(orderedList);

            final String listElements = mli.group(orderedList ? 2 : 3);
            final Matcher le = PATTERN_HTML_LIST_ELEMENT.matcher(listElements);
            while (le.find()) {
                // ticket I-130710-0028
                // $ character causes problems calling Matcher.appendReplacement
                list.elements.add(le.group(1).replace("$", "&#36"));
            }
            lists.add(list);
            mli.appendReplacement(rtfLists, getListRTF(list, counter));
            counter++;
        }
        mli.appendTail(rtfLists);
        // unescape $ characters again
        htmlText = rtfLists.toString().replace("&#36", "$");

        if (!lists.isEmpty()) {
            htmlText = prepareListRTF(lists) + htmlText;
        }

        final Matcher mb = PATTERN_HTML_BOLD.matcher(htmlText);
        final StringBuffer bolds = new StringBuffer();
        while (mb.find()) {
            mb.appendReplacement(bolds, "{\\\\b $1} ");
        }
        mb.appendTail(bolds);
        htmlText = bolds.toString();

        final Matcher mi = PATTERN_HTML_ITALIC.matcher(htmlText);
        final StringBuffer italics = new StringBuffer();
        while (mi.find()) {
            mi.appendReplacement(italics, "{\\\\i $1} ");
        }
        mi.appendTail(italics);
        htmlText = italics.toString();

        final Matcher mbr = PATTERN_HTML_BREAK.matcher(htmlText);
        final StringBuffer breaks = new StringBuffer();
        while (mbr.find()) {
            mbr.appendReplacement(breaks, "\\\\line ");
        }
        mbr.appendTail(breaks);
        htmlText = breaks.toString();

        final Matcher mofo = PATTERN_CSS_O_FOQUOTE.matcher(htmlText);
        final StringBuffer foquotes = new StringBuffer();
        while (mofo.find()) {
            mofo.appendReplacement(foquotes, "\\\\line {\\\\i $1} {\\\\pard $2\\\\par}");
        }
        mofo.appendTail(foquotes);
        htmlText = foquotes.toString();

        final Matcher mp = PATTERN_HTML_PARAGRAPH.matcher(htmlText);
        final StringBuffer paragraphs = new StringBuffer();
        while (mp.find()) {
            mp.appendReplacement(paragraphs, "\\\\line $1 \\\\line");
        }
        mp.appendTail(paragraphs);
        htmlText = paragraphs.toString();

        final Matcher mahref = PATTERN_HTML_AHREF.matcher(htmlText);
        final StringBuffer ahrefs = new StringBuffer();
        while (mahref.find()) {
            mahref.appendReplacement(ahrefs, "{\\\\field{\\\\*\\\\fldinst{HYPERLINK\"$1\"}}{\\\\fldrslt{\\\\ul $2}}}");
        }
        mahref.appendTail(ahrefs);
        htmlText = ahrefs.toString();

        final Matcher mtp = PATTERN_THREEPOINTS.matcher(htmlText);
        final StringBuffer tps = new StringBuffer();
        while (mtp.find()) {
            mtp.appendReplacement(tps, THREEPOINTS);
        }
        mtp.appendTail(tps);
        htmlText = tps.toString();

        // strip all other html-fragments, because not convertable that easy
        htmlText = FilterFactory.getHtmlTagsFilter().filter(htmlText);

        // Remove all &nbsp;
        final Matcher tmp = PATTERN_HTML_SPACE.matcher(htmlText);
        htmlText = tmp.replaceAll(" ");
        htmlText = StringHelper.unescapeHtml(htmlText);

        return htmlText;
    }

    public  ForumRTFFormatter(final VFSContainer container, final boolean filePerThread);

}