private void reformatComment()

in java/java.source.base/src/org/netbeans/modules/java/source/save/Reformatter.java [4800:5424]


        private void reformatComment() {
            if (tokens.token().id() != BLOCK_COMMENT && tokens.token().id() != JAVADOC_COMMENT)
                return;
            TokenSequence<JavadocTokenId> javadocTokens = null;
            TokenSequence<?> embedded = tokens.embedded();
            if (embedded != null) {
                if (JavadocTokenId.language().equals(embedded.language())) {
                    javadocTokens = (TokenSequence<JavadocTokenId>) embedded;
                } else {
                    return;
                }
            }
            final String text = tokens.token().text().toString();
            final int offset = tokens.offset();
            LinkedList<Pair<Integer, JavadocReformattingActionType>> marks = new LinkedList<>();
            int maxParamNameLength = 0;
            int maxExcNameLength = 0;
            int initTextEndOffset = Integer.MAX_VALUE;
            if (javadocTokens != null) {
                JavadocReformattingState state = JavadocReformattingState.INITIAL_TEXT;
                int currWSOffset = -1;
                int lastWSOffset = -1;
                int identStart = -1;
                int lastNLOffset = -1;
                int lastAddedNLOffset = -1;
                boolean afterText = false;
                boolean insideTag = false;
                int nestedParenCnt = 0;
                StringBuilder cseq = null;
                Pair<Integer, JavadocReformattingActionType> marker = null;
                Pair<Integer, JavadocReformattingActionType> nlAdd = null;
                while (javadocTokens.moveNext()) {
                    switch (javadocTokens.token().id()) {
                        case TAG:
                            marker = null;
                            nlAdd = null;
                            String tokenText = javadocTokens.token().text().toString();
                            JavadocReformattingState newState;
                            if (hasInlineTagPrefix(text, tokenText, javadocTokens.offset() - offset)) {
                                insideTag = true;
                                addMark(Pair.of(currWSOffset, JavadocReformattingActionType.NO_FORMAT), marks, state);
                                lastWSOffset = currWSOffset = -1;
                                break;
                            } else if (JDOC_PARAM_TAG.equalsIgnoreCase(tokenText)) {
                                newState = JavadocReformattingState.AFTER_PARAM_TAG;
                            } else if (JDOC_RETURN_TAG.equalsIgnoreCase(tokenText)) {
                                newState = JavadocReformattingState.RETURN_DESCRIPTION;
                            } else if (JDOC_THROWS_TAG.equalsIgnoreCase(tokenText)
                                    || JDOC_EXCEPTION_TAG.equalsIgnoreCase(tokenText)) {
                                newState = JavadocReformattingState.AFTER_THROWS_TAG;
                            } else {
                                if (insideTag)
                                    break;
                                newState = JavadocReformattingState.AFTER_OTHER_TAG;
                            }
                            if (lastWSOffset < initTextEndOffset && (newState != JavadocReformattingState.INITIAL_TEXT)) {
                                initTextEndOffset = lastWSOffset;
                            }
                            if (currWSOffset >= 0 && afterText) {
                                addMark(Pair.of(currWSOffset, state == JavadocReformattingState.INITIAL_TEXT && cs.blankLineAfterJavadocDescription()
                                    || state == JavadocReformattingState.PARAM_DESCRIPTION && newState != JavadocReformattingState.AFTER_PARAM_TAG && cs.blankLineAfterJavadocParameterDescriptions()
                                    || state == JavadocReformattingState.RETURN_DESCRIPTION && cs.blankLineAfterJavadocReturnTag() ? JavadocReformattingActionType.ADD_BLANK_LINE : JavadocReformattingActionType.ADD_NEW_LINE), marks, state);
                            }
                            state = newState;
                            if (state == JavadocReformattingState.RETURN_DESCRIPTION && cs.alignJavadocReturnDescription()) {
                                marker = Pair.of(javadocTokens.offset() + javadocTokens.token().length() - offset, JavadocReformattingActionType.ALIGN_RETURN);
                            }
                            lastWSOffset = currWSOffset = -1;
                            break;
                        case IDENT:
                            if (marker != null) {
                                addMark(marker, marks, state);
                                marker = null;
                            }
                            nlAdd = null;
                            if (identStart < 0 && (state == JavadocReformattingState.AFTER_PARAM_TAG || state == JavadocReformattingState.AFTER_THROWS_TAG))
                                identStart = javadocTokens.offset() - offset;
                            lastWSOffset = currWSOffset = -1;
                            afterText = true;
                            break;
                        case HTML_TAG:
                            if (marker != null) {
                                addMark(marker, marks, state);
                            }
                            nlAdd = null;
                            tokenText = javadocTokens.token().text().toString();
                            if (tokenText.endsWith(">")) { //NOI18N
                                if (P_TAG.equalsIgnoreCase(tokenText) || END_P_TAG.equalsIgnoreCase(tokenText)) {
                                    if (currWSOffset >= 0 && currWSOffset > lastAddedNLOffset && (marker == null || marker.first() < currWSOffset)) {
                                        addMark(Pair.of(currWSOffset, JavadocReformattingActionType.ADD_NEW_LINE), marks, state);
                                    }
                                    lastAddedNLOffset = javadocTokens.offset() + javadocTokens.token().length() - offset;
                                    addMark(Pair.of(lastAddedNLOffset, JavadocReformattingActionType.ADD_NEW_LINE), marks, state);
                                    afterText = false;
                                } else if (PRE_TAG.equalsIgnoreCase(tokenText)) {
                                    if (currWSOffset >= 0 && state == JavadocReformattingState.INITIAL_TEXT && (marker == null || marker.first() < currWSOffset)) {
                                        addMark(Pair.of(currWSOffset, JavadocReformattingActionType.ADD_NEW_LINE), marks, state);
                                    }
                                    addMark(Pair.of(javadocTokens.offset() - offset, JavadocReformattingActionType.NO_FORMAT), marks, state);
                                    state = JavadocReformattingState.AFTER_PRE_TAG;
                                } else if (CODE_TAG.equalsIgnoreCase(tokenText)) {
                                    addMark(Pair.of(javadocTokens.offset() - offset, JavadocReformattingActionType.NO_FORMAT), marks, state);
                                } else if (PRE_END_TAG.equalsIgnoreCase(tokenText)) {
                                    state = JavadocReformattingState.INITIAL_TEXT;
                                    addMark(Pair.of(currWSOffset >= 0 ? currWSOffset : javadocTokens.offset() - offset, JavadocReformattingActionType.FORMAT), marks, state);
                                } else if (CODE_END_TAG.equalsIgnoreCase(tokenText)) {
                                    addMark(Pair.of(currWSOffset >= 0 ? currWSOffset : javadocTokens.offset() - offset, JavadocReformattingActionType.FORMAT), marks, state);
                                } else {
                                    if (currWSOffset >= 0 && lastNLOffset >= currWSOffset
                                            && lastAddedNLOffset < currWSOffset && (marker == null || marker.first() < currWSOffset)) {
                                        addMark(Pair.of(currWSOffset, JavadocReformattingActionType.ADD_NEW_LINE), marks, state);
                                    }
                                    addMark(Pair.of(javadocTokens.offset() - offset, JavadocReformattingActionType.NO_FORMAT), marks, state);
                                    addMark(Pair.of(javadocTokens.offset() + javadocTokens.token().length() - offset - 1, JavadocReformattingActionType.FORMAT), marks, state);
                                    nlAdd = Pair.of(javadocTokens.offset() + javadocTokens.token().length() - offset, JavadocReformattingActionType.ADD_NEW_LINE);
                                }
                            } else {
                                cseq = new StringBuilder(tokenText);
                            }
                            marker = null;
                            lastWSOffset = currWSOffset = -1;
                            break;
                        case OTHER_TEXT:
                            lastWSOffset = currWSOffset = -1;
                            if (cseq == null)
                                cseq = new StringBuilder();
                            cseq.append(javadocTokens.token().text());
                            int nlNum = 1;
                            int insideTagEndOffset = -1;
                            boolean addNow = false;
                            boolean nlFollows = false;
                            for (int i = cseq.length(); i >= 0; i--) {
                                if (i == 0) {
                                    if (lastWSOffset < 0)
                                        lastWSOffset = javadocTokens.offset() - offset;
                                    if (currWSOffset < 0 && nlNum >= 0)
                                        currWSOffset = javadocTokens.offset() - offset;
                                } else {
                                    char c = cseq.charAt(i - 1);
                                    if (Character.isWhitespace(c)) {
                                        if (c == '\n') {
                                            nlNum--;
                                            nlFollows = true;
                                            int off = javadocTokens.offset() + i - offset;
                                            if (off > lastNLOffset)
                                                lastNLOffset = off;
                                        }
                                        if (lastWSOffset < 0 && currWSOffset >= 0)
                                            lastWSOffset = -2;
                                    } else {
                                        nlFollows = false;
                                        if (c != '*') {
                                            if (marker != null) {
                                                addMark(marker, marks, state);
                                                marker = null;
                                            } else {
                                                addNow = true;
                                            }
                                            if (insideTag) {
                                                if (c == '{') {
                                                    nestedParenCnt++;
                                                } else if (c == '}') {
                                                    if (nestedParenCnt > 0) {
                                                        nestedParenCnt--;
                                                    } else {
                                                        insideTagEndOffset = javadocTokens.offset() + i - offset - 1;
                                                        insideTag = false;
                                                    }
                                                }
                                            }
                                            if (lastWSOffset == -2)
                                                lastWSOffset = javadocTokens.offset() + i - offset;
                                            if (currWSOffset < 0 && nlNum >= 0)
                                                currWSOffset = javadocTokens.offset() + i - offset;
                                            afterText = true;
                                        }
                                    }
                                }
                            }
                            if (nlFollows && nlAdd != null) {
                                marker = nlAdd;
                            }
                            nlAdd = null;
                            if (identStart >= 0) {
                                int len = javadocTokens.offset() - offset - identStart;
                                for (int i = 0; i <= cseq.length(); i++) {
                                    if (i == cseq.length() || Character.isWhitespace(cseq.charAt(i))) {
                                        len += i;
                                        break;
                                    }
                                }
                                if (state == JavadocReformattingState.AFTER_PARAM_TAG) {
                                    if (len > maxParamNameLength)
                                        maxParamNameLength = len;
                                    if (cs.alignJavadocParameterDescriptions())
                                        marker = Pair.of(identStart + len, JavadocReformattingActionType.ALIGN_PARAMS);
                                    state = JavadocReformattingState.PARAM_DESCRIPTION;
                                } else if (state == JavadocReformattingState.AFTER_THROWS_TAG) {
                                    if (len > maxExcNameLength)
                                        maxExcNameLength = len;
                                    if (cs.alignJavadocExceptionDescriptions())
                                        marker = Pair.of(identStart + len, JavadocReformattingActionType.ALIGN_EXCEPTIONS);
                                    state = JavadocReformattingState.EXCEPTION_DESCRIPTION;
                                }
                                if (addNow && marker != null) {
                                    addMark(marker, marks, state);
                                    marker = null;
                                }
                                identStart = -1;
                            }
                            if (insideTagEndOffset >= 0) {
                                addMark(Pair.of(insideTagEndOffset, JavadocReformattingActionType.FORMAT), marks, state);
                            }
                            cseq = null;
                            break;
                        default:
                            if (marker != null) {
                                addMark(marker, marks, state);
                                marker = null;
                            }
                            nlAdd = null;
                    }
                }
            }
            int markedOffset;
            JavadocReformattingActionType actionType;
            Iterator<Pair<Integer, JavadocReformattingActionType>> marksIterator = marks.iterator();
            if (marksIterator.hasNext()) {
                Pair<Integer, JavadocReformattingActionType> next = marksIterator.next();
                markedOffset = next.first();
                actionType = next.second();
            } else {
                markedOffset = Integer.MAX_VALUE;
                actionType = JavadocReformattingActionType.NONE;
            }
            final String indentString = getIndent();
            final String lineStartString = cs.addLeadingStarInComment() ? indentString + SPACE + LEADING_STAR + SPACE : indentString + SPACE;
            String blankLineString;
            int currNWSPos = -1;
            int lastNWSPos = -1;
            int currWSPos = -1;
            int lastWSPos = -1;
            int lastNewLinePos = -1;
            Diff pendingDiff = null;
            int start = javadocTokens != null ? 3 : 2;
            int end = text.length() - 2;
            col += start;
            boolean preserveNewLines = true;
            boolean firstLine = true;
            boolean enableCommentFormatting = javadocTokens != null ? cs.enableJavadocFormatting() : cs.enableBlockCommentFormatting();
            boolean noFormat = bof;
            int align = -1;
            for (int i = start; i < text.length(); i++) {
                if (i >= initTextEndOffset) {
                    blankLineString = cs.addLeadingStarInComment() ? indentString + SPACE + LEADING_STAR : EMPTY;
                } else if (javadocTokens != null && !noFormat && cs.generateParagraphTagOnBlankLines()) {
                    blankLineString = cs.addLeadingStarInComment() ? indentString + SPACE + LEADING_STAR + SPACE + P_TAG : indentString + SPACE + P_TAG;
                } else {
                    blankLineString = cs.addLeadingStarInComment() ? indentString + SPACE + LEADING_STAR : EMPTY;
                }
                char c = text.charAt(i);
                if (Character.isWhitespace(c)) {
                    if (enableCommentFormatting) {
                        if (currNWSPos >= 0) {
                            lastNWSPos = currNWSPos;
                            currNWSPos = -1;
                        }
                        if (currWSPos < 0) {
                            currWSPos = i;
                            if (noFormat) {
                                col++;
                            } else {
                                if (col > rightMargin && cs.wrapCommentText() && lastWSPos >= 0) {
                                    int endOff = pendingDiff != null ? pendingDiff.getEndOffset() - offset : lastWSPos + 1;
                                    String s = pendingDiff != null && pendingDiff.text != null && pendingDiff.text.charAt(0) == '\n' ? pendingDiff.text : NEWLINE + lineStartString;
                                    col = getCol(lineStartString) + i - endOff;
                                    if (align > 0) {
                                        int num = align - getCol(lineStartString);
                                        if (num > 0) {
                                            s += getSpaces(num);
                                            col += num;
                                        }
                                    }
                                    col++;
                                    if (endOff > lastWSPos && !s.equals(text.substring(lastWSPos, endOff)))
                                        addDiff(new Diff(offset + lastWSPos, offset + endOff, s));
                                } else if (pendingDiff != null) {
                                    String sub = text.substring(pendingDiff.start - offset, pendingDiff.end - offset);
                                    if (!sub.equals(pendingDiff.text)) {
                                        addDiff(pendingDiff);
                                    }
                                    col++;
                                } else {
                                    col++;
                                }
                                pendingDiff = null;
                            }
                        }
                    }
                    if (c == '\n') {
                        if (lastNewLinePos >= 0) {
                            if (enableCommentFormatting) {
                                String subs = text.substring(lastNewLinePos + 1, i);
                                if (!blankLineString.equals(subs)) {
                                    addDiff(new Diff(offset + lastNewLinePos + 1, offset + i, blankLineString));
                                }
                            }
                            preserveNewLines = true;
                            lastNewLinePos = i;
                            align = -1;
                        } else {
                            lastNewLinePos = currWSPos >= 0 ? currWSPos : i;
                        }
                        firstLine = false;
                    }
                    if (i >= markedOffset && actionType == JavadocReformattingActionType.NO_FORMAT) {
                        noFormat = true;
                        align = -1;
                        if (marksIterator.hasNext()) {
                            Pair<Integer, JavadocReformattingActionType> next = marksIterator.next();
                            markedOffset = next.first();
                            actionType = next.second();
                        } else {
                            markedOffset = Integer.MAX_VALUE;
                            actionType = JavadocReformattingActionType.NONE;
                        }
                    }
                } else {
                    if (pendingDiff != null) {
                        String sub = text.substring(pendingDiff.start - offset, pendingDiff.end - offset);
                        if (sub.equals(pendingDiff.text)) {
                            pendingDiff = null;
                        }
                    }
                    if (enableCommentFormatting) {
                        if (currNWSPos < 0) {
                            currNWSPos = i;
                        }
                        if (i >= markedOffset) {
                            noFormat = false;
                            switch (actionType) {
                                case ADD_BLANK_LINE:
                                    pendingDiff = new Diff(currWSPos >= 0 ? offset + currWSPos : offset + i, offset + i, NEWLINE + blankLineString + NEWLINE);
                                    lastNewLinePos = i - 1;
                                    preserveNewLines = true;
                                    align = -1;
                                    break;
                                case ADD_NEW_LINE:
                                    pendingDiff = new Diff(currWSPos >= 0 ? offset + currWSPos : offset + i, offset + i, NEWLINE);
                                    lastNewLinePos = i - 1;
                                    preserveNewLines = true;
                                    align = -1;
                                    break;
                                case ALIGN_PARAMS:
                                    col += (maxParamNameLength + lastNWSPos - currWSPos);
                                    align = col;
                                    currWSPos = -1;
                                    if (lastNewLinePos < 0) {
                                        int num = maxParamNameLength + lastNWSPos + 1 - i;
                                        if (num > 0) {
                                            addDiff(new Diff(offset + i, offset + i, getSpaces(num)));
                                        } else if (num < 0) {
                                            addDiff(new Diff(offset + i + num, offset + i, null));
                                        }
                                    }
                                    break;
                                case ALIGN_RETURN:
                                    align = col;
                                    break;
                                case ALIGN_EXCEPTIONS:
                                    col += (maxExcNameLength + lastNWSPos - currWSPos);
                                    align = col;
                                    currWSPos = -1;
                                    if (lastNewLinePos < 0) {
                                        int num = maxExcNameLength + lastNWSPos + 1 - i;
                                        if (num > 0) {
                                            addDiff(new Diff(offset + i, offset + i, getSpaces(num)));
                                        } else if (num < 0) {
                                            addDiff(new Diff(offset + i + num, offset + i, null));
                                        }
                                    }
                                    break;
                                case NO_FORMAT:
                                    noFormat = true;
                                    if (currWSPos > 0)
                                        lastWSPos = currWSPos;
                                    break;
                                case FORMAT:
                                    preserveNewLines = true;
                                    break;
                            }
                            if (marksIterator.hasNext()) {
                                Pair<Integer, JavadocReformattingActionType> next = marksIterator.next();
                                markedOffset = next.first();
                                actionType = next.second();
                            } else {
                                markedOffset = Integer.MAX_VALUE;
                                actionType = JavadocReformattingActionType.NONE;
                            }
                        }
                    }
                    if (lastNewLinePos >= 0) {
                        if (!preserveNewLines && !noFormat && i < text.length() - 2 && enableCommentFormatting && !cs.preserveNewLinesInComments() && cs.wrapCommentText()) {
                            lastWSPos = lastNewLinePos;
                            if (pendingDiff != null) {
                                pendingDiff.text += SPACE;
                            } else {
                                pendingDiff = new Diff(offset + lastNewLinePos, offset + i, SPACE);
                            }
                            lastNewLinePos = -1;
                            if (c == '*') {
                                int diff = 0;
                                while(++i < text.length()) {
                                    col++;
                                    c = text.charAt(i);
                                    if (c == '\n') {
                                        pendingDiff.text = NEWLINE + blankLineString + NEWLINE;
                                        diff++;
                                        preserveNewLines = true;
                                        lastNewLinePos = i;
                                        align = -1;
                                        break;
                                    } else if (!Character.isWhitespace(c)) {
                                        break;
                                    }
                                }
                                if (pendingDiff != null) {
                                    diff += offset + i - pendingDiff.end;
                                    pendingDiff.end += diff;
                                    col -= diff;
                                }
                            }
                        } else {
                            if (pendingDiff != null) {
                                pendingDiff.text += indentString + SPACE;
                                String subs = text.substring(pendingDiff.start - offset, i);
                                if (pendingDiff.text.equals(subs)) {
                                    lastNewLinePos = pendingDiff.start - offset;
                                    pendingDiff = null;
                                }
                            } else {
                                // do format last line with only whitespaces and end-comment marker, even though
                                // comment formatting is disabled. Do properly indent javadoc, if the line nonblank text
                                // starts with * (as javadoc should)
                                if (enableCommentFormatting || i == end || (javadocTokens != null && c == '*')) {
                                    String s = NEWLINE + indentString + SPACE;
                                    String subs = text.substring(lastNewLinePos, i);
                                    if (!s.equals(subs))
                                        pendingDiff = new Diff(offset + lastNewLinePos, offset + i, s);
                                }
                            }
                            lastWSPos = currWSPos = -1;
                            col = getCol(indentString + SPACE);
                            if (enableCommentFormatting) {
                                if (c == '*') {
                                    col++;
                                    while (++i < text.length()) {
                                        c = text.charAt(i);
                                        if (c == '\n') {
                                            if (!cs.addLeadingStarInComment()) {
                                                String subs = text.substring(lastNewLinePos + 1, i);
                                                if (blankLineString.equals(subs)) {
                                                    pendingDiff = null;
                                                } else {
                                                    if (pendingDiff != null) {
                                                        pendingDiff.end = offset + i;
                                                        pendingDiff.text = NEWLINE + blankLineString;
                                                    } else {
                                                        pendingDiff = new Diff(offset + lastNewLinePos + 1, offset + i, blankLineString);
                                                    }
                                                }
                                            } else if (currWSPos >= 0) {
                                                if (pendingDiff != null) {
                                                    String sub = text.substring(pendingDiff.start - offset, pendingDiff.end - offset);
                                                    if (!sub.equals(pendingDiff.text)) {
                                                        addDiff(pendingDiff);
                                                    }
                                                }
                                                pendingDiff = new Diff(offset + currWSPos, offset + i, javadocTokens != null && lastNWSPos >= 0 && i < initTextEndOffset && !noFormat && cs.generateParagraphTagOnBlankLines() ? SPACE + P_TAG : EMPTY);
                                            } else if (javadocTokens != null && lastNWSPos >= 0 && i < initTextEndOffset && !noFormat && cs.generateParagraphTagOnBlankLines()) {
                                                if (pendingDiff != null) {
                                                    String sub = text.substring(pendingDiff.start - offset, pendingDiff.end - offset);
                                                    if (!sub.equals(pendingDiff.text)) {
                                                        addDiff(pendingDiff);
                                                    }
                                                }
                                                pendingDiff = new Diff(offset + i, offset + i, SPACE + P_TAG);
                                            }
                                            currWSPos = -1;
                                            lastNewLinePos = i;
                                            align = -1;
                                            break;
                                        } else if (Character.isWhitespace(c)) {
                                            if (currWSPos < 0) {
                                                currWSPos = i;
                                                col++;
                                            }
                                        } else if (c == '*' || c == '/') {
                                            col++;
                                            lastNewLinePos = -1;
                                            break;
                                        } else {
                                            if (i >= markedOffset && actionType == JavadocReformattingActionType.FORMAT) {
                                                noFormat = false;
                                                preserveNewLines = true;
                                                if (marksIterator.hasNext()) {
                                                    Pair<Integer, JavadocReformattingActionType> next = marksIterator.next();
                                                    markedOffset = next.first();
                                                    actionType = next.second();
                                                } else {
                                                    markedOffset = Integer.MAX_VALUE;
                                                    actionType = JavadocReformattingActionType.NONE;
                                                }
                                            }
                                            if (!cs.addLeadingStarInComment()) {
                                                if (noFormat) {
                                                    if (pendingDiff != null) {
                                                        pendingDiff.end = currWSPos >= 0 ? offset + currWSPos + 1 : pendingDiff.end + 1;
                                                    } else {
                                                        pendingDiff = new Diff(offset + lastNewLinePos + 1, currWSPos >= 0 ? offset + currWSPos + 1 : offset + i, indentString + SPACE);
                                                    }

                                                } else {
                                                    if (pendingDiff != null) {
                                                        pendingDiff.end = offset + i;
                                                    } else {
                                                        pendingDiff = new Diff(offset + lastNewLinePos + 1, offset + i, indentString + SPACE);
                                                    }
                                                    col = getCol(indentString + SPACE);
                                                }
                                            } else {
                                                if (currWSPos < 0) {
                                                    currWSPos = i;
                                                    col++;
                                                }
                                                String subs = text.substring(currWSPos, i);
                                                String s = getSpaces(align < 0 ? 1 : align - getCol(lineStartString) + 1);
                                                if (!noFormat && !s.equals(subs)) {
                                                    if (pendingDiff != null) {
                                                        String sub = text.substring(pendingDiff.start - offset, pendingDiff.end - offset);
                                                        if (!sub.equals(pendingDiff.text)) {
                                                            addDiff(pendingDiff);
                                                        }
                                                    }
                                                    pendingDiff = new Diff(offset + currWSPos, offset + i, s);
                                                }
                                            }
                                            lastNewLinePos = -1;
                                            currWSPos = -1;
                                            break;
                                        }
                                    }
                                } else {
                                    if (cs.addLeadingStarInComment()) {
                                        int num = Math.max(align - col - 1, 1);
                                        String s = getSpaces(num);
                                        if (pendingDiff != null) {
                                            pendingDiff.text += (LEADING_STAR + s);
                                        } else {
                                            pendingDiff = new Diff(offset + i, offset + i, LEADING_STAR + s);
                                        }
                                        col += (num + 1);
                                    } else if (align > col) {
                                        int num = align - col;
                                        String s = getSpaces(num);
                                        if (pendingDiff != null) {
                                            pendingDiff.text += s;
                                        } else {
                                            pendingDiff = new Diff(offset + i, offset + i, s);
                                        }
                                        col += num;
                                    }
                                    lastNewLinePos = -1;
                                }
                            } else {
                                lastNewLinePos = -1;
                            }
                            if (pendingDiff != null) {
                                String sub = text.substring(pendingDiff.start - offset, pendingDiff.end - offset);
                                if (!sub.equals(pendingDiff.text)) {
                                    addDiff(pendingDiff);
                                }
                                pendingDiff = null;
                            }
                        }
                    } else if (enableCommentFormatting) {
                        if (firstLine) {
                            String s = !noFormat && cs.wrapOneLineComments() ? NEWLINE + lineStartString : SPACE;
                            String sub = currWSPos >= 0 ? text.substring(currWSPos, i) : null;
                            if (!s.equals(sub))
                                addDiff(new Diff(currWSPos >= 0 ? offset + currWSPos : offset + i, offset + i, s));
                            if (!noFormat && cs.wrapOneLineComments())
                                col = getCol(lineStartString);
                            firstLine = false;
                        } else if (currWSPos >= 0) {
                            if (!noFormat) {
                                lastWSPos = currWSPos;
                                if (currWSPos < i - 1)
                                    pendingDiff = new Diff(offset + currWSPos + 1, offset + i, null);
                            }
                        } else if (c != '*') {
                            preserveNewLines = false;
                        }
                    } else if (c != '*') {
                        preserveNewLines = false;
                    }
                    currWSPos = -1;
                    col++;
                }
            }
            if (enableCommentFormatting) {
                for (int i = text.length() - 3; i >= 0; i--) {
                    char c = text.charAt(i);
                    if (c == '\n') {
                        break;
                    } else if (!Character.isWhitespace(c)) {
                        String s = !noFormat && cs.wrapOneLineComments() ? NEWLINE + indentString + SPACE : SPACE;
                        String sub = text.substring(i + 1, text.length() - 2);
                        if (!s.equals(sub))
                            addDiff(new Diff(offset + i + 1, offset + text.length() - 2, s));
                        break;
                    }
                }
            }
        }