public String cleanText () {
        // Time-saving check.
        if (source.indexOf ("<lj") < 0) {
            return source;
        }
        
        sourceLength = source.length ();
        
        // Create a mirror string which is all lower case, to facilitate tag matching
        lcSource = source.toLowerCase ();
        destBuf = new StringBuffer (sourceLength);
        sourceIndex = 0;
        for (;;) {
            // Copy all characters up to the next tag of interest.
            int tidx = lcSource.indexOf ("<lj", sourceIndex);
            int ctidx = lcSource.indexOf ("</lj", sourceIndex);
            if (ctidx > 0 && (tidx < 0 || tidx > ctidx)) {
                // The next event of interest is a close tag
                // TODO process close tag
                copyUpToIndex (ctidx);
                skipLJCloseTag();
            }
            else if (tidx > 0) {
                // The next event of interest is an open tag
                copyUpToIndex (tidx);
                if (sourceLength - sourceIndex >= 7 && "<lj-cut".equals(lcSource.substring (sourceIndex, sourceIndex+7))) {
                    processLJCutTag ();
                }
                else {
                    processLJTag ();
                }
            }
            else {
                // All done. Copy the rest and return it.
                copyUpToIndex (sourceLength);
                break;
            }
        }
        return destBuf.toString ();
    }