@Override
  public List<Object> apply(Object o) {

    if (o instanceof P) {

      currentP = createNode(document, NODE_BLOCK);
      currentSpan = null;
      if (tc.peek() != null) {
        tc.peek().appendChild(currentP);
      } else {
        parentNode.appendChild(currentP);
      }

      pPr = ((P) o).getPPr();
      currentP = handlePPr(conversionContext, pPr, false, currentP);

    } else if (o instanceof org.docx4j.wml.R) {

      if (!conversionContext.isInComplexFieldDefinition()) {
        // Convert run to span
        Element spanEl = createNode(document, NODE_INLINE);
        currentSpan = spanEl;

        rPr = ((R) o).getRPr();
        if (rPr != null) {
          handleRPr(conversionContext, pPr, rPr, currentSpan);
        }

        if (currentP == null) {
          // Hyperlink special case
          parentNode.appendChild(spanEl);
        } else {
          rtlAwareAppendChildToCurrentP(spanEl);
        }

        // To merge nested span (which we could do if there is a single child span),
        // TraversalUtil Callback would need an after walk children
      }

    } else if (o instanceof org.docx4j.wml.FldChar) {
      conversionContext.updateComplexFieldDefinition(((org.docx4j.wml.FldChar) o).getFldCharType());

    } else if (o instanceof org.docx4j.wml.Text) {

      if (!conversionContext.isInComplexFieldDefinition()) {

        if (currentSpan == null) {
          // eg after <br/>
          log.error("null currentSpan! " + ((Text) o).getValue());
          Element spanEl = createNode(document, NODE_INLINE);
          if (currentP == null) {
            // Hyperlink special case
            parentNode.appendChild(spanEl);
          } else {
            currentP.appendChild(spanEl);
          }
          currentSpan = spanEl;
        }

        log.debug(((Text) o).getValue());

        DocumentFragment df =
            (DocumentFragment)
                conversionContext.getRunFontSelector().fontSelector(pPr, rPr, ((Text) o));
        XmlUtils.treeCopy(df, currentSpan);
        // TODO would be more efficient without the treeCopy
        // but fontSelector would need to be refactored a bit

      }

    } else if (o instanceof org.docx4j.wml.R.Tab) {
      convertTabToNode(conversionContext, document);

    } else if (o instanceof org.docx4j.wml.CTSimpleField) {

      convertToNode(
          conversionContext, o, AbstractFldSimpleWriter.WRITER_ID, document, getCurrentParent());

    } else if (o instanceof org.docx4j.wml.P.Hyperlink) {

      convertToNode(
          conversionContext, o, AbstractHyperlinkWriter.WRITER_ID, document, getCurrentParent());

    } else if (o instanceof org.docx4j.wml.CTBookmark) {

      convertToNode(
          conversionContext,
          o,
          AbstractBookmarkStartWriter.WRITER_ID,
          document,
          getCurrentParent());

    } else if (o instanceof org.docx4j.wml.Tbl) {

      convertToNode(
          conversionContext,
          o,
          AbstractTableWriter.WRITER_ID,
          document,
          (currentP != null ? currentP : parentNode));

      currentP = null;
      currentSpan = null;

    } else if (o instanceof org.docx4j.wml.Tr) {

      // done in walkJAXBElements

      //			tr = document.createElementNS(Namespaces.NS_WORD12, "tr");
      //			//parentNode is in this case the DocumentFragment, that get's passed
      //			//to the TableModel/TableModelWriter
      //			parentNode.appendChild(tr);

    } else if (o instanceof org.docx4j.wml.Tc) {

      // done in walkJAXBElements

      //			tc = document.createElementNS(Namespaces.NS_WORD12, "tc");
      //			tr.appendChild(tc);
      //			// now the html p content will go temporarily go in w:tc,
      //			// which is what we need for our existing table model.

      //			System.out.println("#wrapped in w:tc OK");

    } else if (o instanceof org.docx4j.dml.wordprocessingDrawing.Inline
        || o instanceof org.docx4j.dml.wordprocessingDrawing.Anchor) {

      anchorOrInline = o; // keep this until we handle CTBlip

    } else if (o instanceof org.docx4j.dml.CTBlip) {
      /*<w:drawing>
      <wp:inline distT="0" distB="0" distL="0" distR="0">
        <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
          <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
            <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
              <pic:blipFill>
                <a:blip r:embed="rId10" cstate="print"/> */

      DocumentFragment foreignFragment = createImage(IMAGE_E20, conversionContext, anchorOrInline);
      anchorOrInline = null;

      currentP.appendChild(document.importNode(foreignFragment, true));

    } else if (o instanceof org.docx4j.wml.Pict) {
      /*<w:pict>
      <v:shape id="_x0000_i1025" type="#_x0000_t75" style="width:428.25pt;height:321pt">
        <v:imagedata r:id="rId4" o:title=""/>
      </v:shape> */

      org.docx4j.vml.CTTextbox textBox = getTextBox((org.docx4j.wml.Pict) o);

      if (textBox == null) {
        // Assume it contains an image!
        DocumentFragment foreignFragment = createImage(IMAGE_E10, conversionContext, o);
        currentP.appendChild(document.importNode(foreignFragment, true));

      } else {

        convertToNode(
            conversionContext, o, AbstractPictWriter.WRITER_ID, document, getCurrentParent());
      }

    } else if (o instanceof Br) {

      handleBr((Br) o);

    } else if (o instanceof org.docx4j.wml.R.Sym) {

      convertToNode(
          conversionContext, o, AbstractSymbolWriter.WRITER_ID, document, getCurrentParent());

    } else if ((o instanceof org.docx4j.wml.ProofErr)
        || (o instanceof org.docx4j.wml.R.LastRenderedPageBreak)
        || (o instanceof org.docx4j.wml.CTMarkupRange)) {
      // Ignore theese types, they don't need to be outputed/handled
      // CTMarkupRange is the w:bookmarkEnd

    } else {
      getLog().warn("Need to handle " + o.getClass().getName());
      log.debug(XmlUtils.marshaltoString(o));
    }

    return null;
  }