protected void render(
      FopFactory fopFactory,
      String outputFormat,
      Source foDocumentSrc,
      PlaceholderReplacementHandler.PlaceholderLookup placeholderLookup,
      OutputStream outputStream)
      throws Docx4JException {
    Fop fop = null;
    Result result = null;
    try {
      fop = fopFactory.newFop(outputFormat, outputStream);
      result =
          (placeholderLookup == null
              ?
              // 1 Pass
              new SAXResult(fop.getDefaultHandler())
              :
              // 2 Pass
              new SAXResult(
                  new PlaceholderReplacementHandler(fop.getDefaultHandler(), placeholderLookup)));
    } catch (FOPException e) {
      throw new Docx4JException(
          "Exception setting up result for fo transformation: " + e.getMessage(), e);
    }

    XmlSerializerUtil.serialize(foDocumentSrc, result, false, false);
  }
  /**
   * For first pass of two pass process, invoke org.apache.fop.apps.FormattingResults which can tell
   * us the number of pages in each page sequence, and in the document as a whole.
   *
   * @param fopFactory
   * @param outputFormat
   * @param foDocumentSrc
   * @param placeholderLookup
   * @return
   * @throws Docx4JException
   */
  protected FormattingResults calcResults(
      FopFactory fopFactory,
      String outputFormat,
      Source foDocumentSrc,
      PlaceholderReplacementHandler.PlaceholderLookup placeholderLookup)
      throws Docx4JException {
    Fop fop = null;
    Result result = null;
    try {
      fop = fopFactory.newFop(outputFormat, new NullOutputStream());
      result =
          new SAXResult(
              new PlaceholderReplacementHandler(fop.getDefaultHandler(), placeholderLookup));
    } catch (FOPException e) {
      throw new Docx4JException(
          "Exception setting up result for fo transformation: " + e.getMessage(), e);
    }

    XmlSerializerUtil.serialize(foDocumentSrc, result, false, false);

    return fop.getResults();
  }