private void parseChildren(SafeXmlPullParser parser, D doc, E element) {
    boolean done = false;
    do {
      N child = null;
      parser.next();

      switch (parser.getCurrentType()) {
        case TEXT:
          child = parseText(parser, doc, element);
          break;
        case START_ELEMENT:
          child = parseElement(parser, doc, element);
          break;
        case END_ELEMENT:
          done = true;
          break;
      }
      if (child != null) {
        doc.insertBefore(element, child, null);
      }
      // This is a bit of judgment call. If this happens, the document is
      // invalid, since the closing tag is missing. By exiting the loop when
      // parser is out of tokens we're silently repairing the invalid doc.
    } while (!done && parser.hasNext());
  }
 /**
  * Parses an element.
  *
  * @param parser tokenizer
  * @param parentElement the parent element to attach the parsed node to
  * @return a new element.
  */
 private E parseElement(SafeXmlPullParser parser, D doc, E parentElement) {
   E element =
       doc.createElement(
           parser.getTagName(),
           CollectionUtils.newJavaMap(parser.getAttributes()),
           parentElement,
           null);
   parseChildren(parser, doc, element);
   return element;
 }
 /**
  * Parses a text node.
  *
  * @param parser tokenizer
  * @param parentElement the parent element to attach the parsed node to
  * @return a new text node.
  */
 private T parseText(SafeXmlPullParser parser, D doc, E parentElement) {
   String text = parser.getText();
   T child = null;
   if (text.length() > 0) {
     child = doc.createTextNode(text, parentElement, null);
   }
   return child;
 }
  /**
   * @param xmlString
   * @return parsed string
   */
  public D parse(String xmlString) {
    SafeXmlPullParser parser;
    try {
      parser = XmlParserFactory.buffered(xmlString);
    } catch (XmlParseException e) {
      throw new RuntimeException("Cannot parse xml: " + xmlString, e);
    }
    // TODO(ohler): This can be an infinite loop.  Fix that.
    while (parser.getCurrentType() != ItemType.START_ELEMENT) {
      parser.next();
    }

    D document =
        factory.create(parser.getTagName(), CollectionUtils.newJavaMap(parser.getAttributes()));
    parseChildren(parser, document, document.getDocumentElement());

    return document;
  }