{
  void reindent(Document doc, Node node, int offset)  {    if (node.hasChildNodes())      {        boolean markupContent = false;        boolean textContent = false;        List children = new LinkedList();        Node ctx = node.getFirstChild();        while (ctx != null)          {            switch (ctx.getNodeType())              {              case Node.ELEMENT_NODE:              case Node.PROCESSING_INSTRUCTION_NODE:              case Node.DOCUMENT_TYPE_NODE:                markupContent = true;                break;              case Node.TEXT_NODE:              case Node.CDATA_SECTION_NODE:              case Node.ENTITY_REFERENCE_NODE:              case Node.COMMENT_NODE:                textContent = true;                break;              }            children.add(ctx);            ctx = ctx.getNextSibling();          }        if (markupContent)          {            if (textContent)              {                // XXX handle mixed content differently?              }            int nodeType = node.getNodeType();            if (nodeType == Node.DOCUMENT_NODE)              {                for (Iterator i = children.iterator(); i.hasNext(); )                  {                    ctx = (Node) i.next();                    reindent(doc, ctx, offset + 1);                  }              }            else              {                StringBuffer buf = new StringBuffer();                buf.append('\n');                for (int i = 0; i < offset + 1; i++)                  {                    buf.append(INDENT_WHITESPACE);                  }                String ws = buf.toString();                for (Iterator i = children.iterator(); i.hasNext(); )                  {                    ctx = (Node) i.next();                    node.insertBefore(doc.createTextNode(ws), ctx);                    reindent(doc, ctx, offset + 1);                  }                buf = new StringBuffer();                buf.append('\n');                ws = buf.toString();                for (int i = 0; i < offset; i++)                  {                    buf.append(INDENT_WHITESPACE);                  }                node.appendChild(doc.createTextNode(ws));              }          }      }  }