private void updateNextTag() {
   // ensures that nextTag is up to date
   while (nextTag != null) {
     if (nextTag.begin >= index) return;
     nextTag = nextTag.findNextTag();
   }
 }
 private void writeTag(final Tag tag, final int depth, final int end) throws IOException {
   // sets index to last position written, guaranteed < end
   // assert index==tag.begin
   // assert index < end
   nextTag = tag.findNextTag();
   final int tagEnd = (tag.end < end) ? tag.end : end;
   // assert index < tagEnd
   if (tag.getTagType() == StartTagType.COMMENT
       || tag.getTagType() == StartTagType.CDATA_SECTION
       || tag.getTagType().isServerTag()) {
     writeTextPreserveIndentation(tagEnd, depth);
   } else if (tidyTags) {
     final String tidyTag = tag.tidy();
     if ((tag instanceof StartTag) && ((StartTag) tag).getAttributes() != null)
       writer.write(tidyTag);
     else writeSpecifiedTextInline(tidyTag, depth);
     index = tagEnd;
   } else {
     writeTextInline(
         tagEnd, depth,
         true); // Write tag keeping linefeeds. This will add an indent to any attribute values
     // containing linefeeds, but the normal situation where line breaks are between
     // attributes will look nice.
   }
   if (end <= tag.end || !(tag instanceof StartTag)) return;
   if ((tag.name == HTMLElementName.SCRIPT && !indentScriptElements)
       || tag.getTagType().isServerTag()) {
     // NOTE SERVER ELEMENTS CONTAINING NON-INLINE TAGS WILL NOT FORMAT PROPERLY. NEED TO
     // INVESTIGATE INCLUDING SUCH SERVER ELEMENTS IN DOCUMENT HIERARCHY.
     // this is a script or server start tag, we may need to write the whole element:
     final Element element = tag.getElement();
     final EndTag endTag = element.getEndTag();
     if (endTag == null) return;
     final int contentEnd = (end < endTag.begin) ? end : endTag.begin;
     boolean singleLineContent = true;
     if (index != contentEnd) {
       // elementContainsMarkup should be made into a TagType property one day.
       // for the time being assume all server element content is code, although this is not true
       // for some Mason elements.
       final boolean elementContainsMarkup = false;
       if (elementContainsMarkup) {
         singleLineContent = writeTextInline(contentEnd, depth + 1, false);
       } else {
         singleLineContent = writeTextPreserveIndentation(contentEnd, depth);
       }
     }
     if (endTag.begin >= end) return;
     if (!singleLineContent) {
       writeEssentialNewLine(); // some server or client side scripting languages might need the
       // final new line
       writeIndent(depth);
     }
     // assert index==endTag.begin
     writeTag(endTag, depth, end);
   }
 }