private void writeLineKeepWhiteSpace(final int end, final int depth) throws IOException {
   // Writes the first line from the source text starting from index, ending at the specified end
   // position.
   // The line break characters are not written.
   // Sets index to the position following the first line break character(s), or end if the text
   // contains no line breaks. index is guaranteed <= end.
   // Any tags encountered are written using the writeTag method, whose output may include line
   // breaks.
   // assert index < end
   updateNextTag();
   while (true) {
     while (nextTag != null && index == nextTag.begin) {
       writeTag(nextTag, depth, end);
       if (index == end) return;
     }
     final char ch = sourceText.charAt(index);
     if (ch == '\r') {
       final int nextindex = index + 1;
       if (nextindex < end && sourceText.charAt(nextindex) == '\n') {
         index += 2;
         return;
       }
     }
     if (ch == '\n') {
       index++;
       return;
     }
     writer.write(ch);
     if (++index == end) return;
   }
 }
 private void writeTextCollapseWhiteSpace(final int end, final int depth) throws IOException {
   // sets index to end
   // assert index < end
   boolean lastWasWhiteSpace = false;
   updateNextTag();
   while (index < end) {
     while (nextTag != null && index == nextTag.begin) {
       if (lastWasWhiteSpace) {
         writer.write(' ');
         lastWasWhiteSpace = false;
       }
       writeTag(nextTag, depth, end);
       if (index == end) return;
     }
     final char ch = sourceText.charAt(index++);
     if (Segment.isWhiteSpace(ch)) {
       lastWasWhiteSpace = true;
     } else {
       if (lastWasWhiteSpace) {
         writer.write(' ');
         lastWasWhiteSpace = false;
       }
       writer.write(ch);
     }
   }
   if (lastWasWhiteSpace) writer.write(' ');
 }
 private int writeSpecifiedLine(final CharSequence text, int i) throws IOException {
   // Writes the first line from the specified text starting from the specified position.
   // The line break characters are not written.
   // Returns the position following the first line break character(s), or text.length() if the
   // text contains no line breaks.
   final int textLength = text.length();
   while (true) {
     final char ch = text.charAt(i);
     if (ch == '\r') {
       final int nexti = i + 1;
       if (nexti < textLength && text.charAt(nexti) == '\n') return i + 2;
     }
     if (ch == '\n') return i + 1;
     writer.write(ch);
     if (++i >= textLength) return i;
   }
 }
 private void writeContentPreformatted(final int end, final int depth) throws IOException {
   // sets index to end
   // assert index < end
   updateNextTag();
   do {
     while (nextTag != null && index == nextTag.begin) {
       writeTag(nextTag, depth, end);
       if (index == end) return;
     }
     writer.write(sourceText.charAt(index));
   } while (++index < end);
 }
 private void writeText(final int end, int depth) throws IOException {
   // sets index to end
   if (index == end) return;
   while (Segment.isWhiteSpace(sourceText.charAt(index)))
     if (++index == end) return; // trim whitespace.
   writeIndent(depth);
   if (collapseWhiteSpace) {
     writeTextCollapseWhiteSpace(end, depth);
   } else {
     writeTextInline(end, depth, false);
   }
   writeFormattingNewLine();
 }
 private void writeSpecifiedTextInline(final CharSequence text, int depth) throws IOException {
   final int textLength = text.length();
   int i = writeSpecifiedLine(text, 0);
   if (i < textLength) {
     final int subsequentLineDepth = depth + 1;
     do {
       while (Segment.isWhiteSpace(text.charAt(i)))
         if (++i >= textLength) return; // trim whitespace.
       writeEssentialNewLine();
       writeIndent(subsequentLineDepth);
       i = writeSpecifiedLine(text, i);
     } while (i < textLength);
   }
 }
 private int getStartOfLinePos(final int end, final boolean atStartOfLine) {
   // returns the starting position of the next complete line containing text, or -1 if texts
   // starts on the current line (hence not a complete line).
   // sets index to the start of the text following the returned position, or end, whichever
   // comes first.
   int startOfLinePos = atStartOfLine ? index : -1;
   while (true) {
     final char ch = sourceText.charAt(index);
     if (ch == '\n' || ch == '\r') {
       startOfLinePos = index + 1;
     } else if (!(ch == ' ' || ch == '\t')) break;
     if (++index == end) break;
   }
   return startOfLinePos;
 }
 private boolean writeTextRemoveIndentation(final int end) throws IOException {
   // assert index < end
   // sets index to end
   writeLineKeepWhiteSpace(end, 0);
   if (index == end) return true;
   while (index != end) {
     // Skip over the original indent:
     while (true) {
       final char ch = sourceText.charAt(index);
       if (!(ch == ' ' || ch == '\t')) break;
       if (++index == end) return false;
     }
     writeEssentialNewLine();
     // Write the rest of the line including any indent greater than the first line's indent:
     writeLineKeepWhiteSpace(end, 0);
   }
   return false;
 }
 private boolean writeTextInline(
     final int end, int depth, final boolean increaseIndentAfterFirstLineBreak)
     throws IOException {
   // returns true if all text was on one line, otherwise false
   // sets index to end
   // assert index < end
   writeLineKeepWhiteSpace(end, depth);
   if (index == end) return true;
   final int subsequentLineDepth = increaseIndentAfterFirstLineBreak ? depth + 1 : depth;
   do {
     while (Segment.isWhiteSpace(sourceText.charAt(index)))
       if (++index == end) return false; // trim whitespace.
     writeEssentialNewLine(); // essential because we might be inside a tag attribute value.  If
     // new lines in normal text aren't required this method wouldn't
     // have been called.
     writeIndent(subsequentLineDepth);
     writeLineKeepWhiteSpace(end, subsequentLineDepth);
   } while (index < end);
   return false;
 }
 private void writeTextPreserveIndentation(
     final int end, final int depth, final int originalIndentLength) throws IOException {
   // assert index < end
   // sets index to end
   writeIndent(depth);
   writeLineKeepWhiteSpace(end, depth);
   while (index != end) {
     // Skip over the original indent:
     for (int x = 0; x < originalIndentLength; x++) {
       final char ch = sourceText.charAt(index);
       if (!(ch == ' ' || ch == '\t')) break;
       if (++index == end) return;
     }
     writeEssentialNewLine();
     // Insert our indent:
     writeIndent(depth);
     // Write the rest of the line including any indent greater than the first line's indent:
     writeLineKeepWhiteSpace(end, depth);
   }
 }