protected static List<ConversionSectionWrapper> processComplete(
      WordprocessingMLPackage wmlPackage,
      Document document,
      RelationshipsPart rels,
      BooleanDefaultTrue evenAndOddHeaders,
      boolean dummyPageNumbering) {
    List<ConversionSectionWrapper> conversionSections = new ArrayList<ConversionSectionWrapper>();
    List<Object> sectionContent = new ArrayList<Object>();
    ConversionSectionWrapper currentSectionWrapper = null;
    HeaderFooterPolicy previousHF = null;
    int conversionSectionIndex = 0;

    // According to the ECMA-376 2ed, if type is not specified, read it as next page
    // However Word 2007 sometimes treats it as continuous, and sometimes doesn't??
    // 20130216 Review above comment: !  In the Word UI, the Word "continuous" is shown where it is
    // effective.
    // In the XML, it is stored in the next following sectPr.

    // First, remove content controls,
    // since the P could be in a content control.
    // (It is easier to remove content controls, than
    //  to make the code below TraversalUtil based)
    // RemovalHandler is an XSLT-based way of doing this,
    // but here we avoid introducing a dependency on
    // XSLT (Xalan) for PDF output.
    SdtBlockFinder sbr = new SdtBlockFinder();
    new TraversalUtil(document.getContent(), sbr);
    for (int i = sbr.sdtBlocks.size() - 1; i >= 0; i--) {
      // Have to process in reverse order
      // so that parentList is correct for nested sdt

      SdtBlock sdtBlock = sbr.sdtBlocks.get(i);
      List<Object> parentList = null;
      if (sdtBlock.getParent() instanceof ArrayList) {
        parentList = (ArrayList) sdtBlock.getParent();
      } else {
        log.error("Handle " + sdtBlock.getParent().getClass().getName());
      }
      int index = parentList.indexOf(sdtBlock);
      parentList.remove(index);
      parentList.addAll(index, sdtBlock.getSdtContent().getContent());
    }

    //		if (log.isDebugEnabled()) {
    //			log.debug(XmlUtils.marshaltoString(document, true, true));
    //		}

    // Make a list, so it is easy to look at the following sectPr,
    // which we need to do to handle continuous sections properly
    List<SectPr> sectPrs = new ArrayList<SectPr>();
    for (Object o : document.getBody().getContent()) {

      if (o instanceof org.docx4j.wml.P) {
        if (((org.docx4j.wml.P) o).getPPr() != null) {
          org.docx4j.wml.PPr ppr = ((org.docx4j.wml.P) o).getPPr();
          if (ppr.getSectPr() != null) {
            sectPrs.add(ppr.getSectPr());
          }
        }
      }
    }

    if (document.getBody().getSectPr() != null) {
      // usual case
      sectPrs.add(document.getBody().getSectPr());

    } else {
      log.debug("No body level sectPr in document");

      // OK if the last object is w:p and it contains a sectPr.
      List<Object> all = document.getBody().getContent();
      Object last = all.get(all.size() - 1);
      if (last instanceof P
          && ((P) last).getPPr() != null
          && ((P) last).getPPr().getSectPr() != null) {
        // ok
        log.debug(
            ".. but last p contains sectPr .. move it"); // so our assumption later about there
                                                         // being a following section is correct

        SectPr thisSectPr = ((P) last).getPPr().getSectPr();
        document.getBody().setSectPr(thisSectPr);
        ((P) last).getPPr().setSectPr(null);
        sectPrs.remove(thisSectPr);

      } else {
        document.getBody().setSectPr(Context.getWmlObjectFactory().createSectPr());
        sectPrs.add(document.getBody().getSectPr());
      }
    }

    int sectPrIndex = 0; // includes continuous ones
    for (Object o : document.getBody().getContent()) {

      if (o instanceof org.docx4j.wml.P) {

        if (((org.docx4j.wml.P) o).getPPr() != null) {

          org.docx4j.wml.PPr ppr = ((org.docx4j.wml.P) o).getPPr();
          if (ppr.getSectPr() != null) {

            // If the *following* section is continuous, don't add *this* section
            boolean ignoreThisSection = false;
            SectPr followingSectPr = sectPrs.get(++sectPrIndex);
            if (followingSectPr.getType() != null
                && followingSectPr.getType().getVal().equals("continuous")) {

              ignoreThisSection = true;

              // If the w:pgSz on the two sections differs,
              // then Word inserts a page break (ie doesn't treat it as continuous).
              // If no w:pgSz element is present, then Word defaults
              // (presumably to Legal? TODO CHECK. There is no default setting in the docx).
              // Word always inserts a w:pgSz element?

              PgSz pgSzThis = ppr.getSectPr().getPgSz();
              PgSz pgSzNext = followingSectPr.getPgSz();

              if (pgSzThis != null && pgSzNext != null) {

                if (pgSzThis.getH().compareTo(pgSzNext.getH()) != 0) {
                  ignoreThisSection = false;
                }
                if (pgSzThis.getW().compareTo(pgSzNext.getW()) != 0) {
                  ignoreThisSection = false;
                }

                // Orientation:default is portrait
                boolean portraitThis = true;
                if (pgSzThis.getOrient() != null) {
                  portraitThis = pgSzThis.getOrient().equals(STPageOrientation.PORTRAIT);
                }
                boolean portraitNext = true;
                if (pgSzNext.getOrient() != null) {
                  portraitNext = pgSzNext.getOrient().equals(STPageOrientation.PORTRAIT);
                }
                if (portraitThis != portraitNext) {
                  ignoreThisSection = false;
                }
              }
              // TODO: handle cases where one or both pgSz elements are missing,
              // or H or W is missing.
              // Treat pgSz element missing as Legal size?
            }

            if (ignoreThisSection) {
              // In case there are some headers/footers that get inherited by the next section
              previousHF =
                  new HeaderFooterPolicy(ppr.getSectPr(), previousHF, rels, evenAndOddHeaders);

            } else {
              currentSectionWrapper =
                  createSectionWrapper(
                      ppr.getSectPr(),
                      previousHF,
                      rels,
                      evenAndOddHeaders,
                      ++conversionSectionIndex,
                      sectionContent,
                      dummyPageNumbering);
              conversionSections.add(currentSectionWrapper);
              previousHF = currentSectionWrapper.getHeaderFooterPolicy();
              sectionContent = new ArrayList<Object>();
            }
          }
        }
      }
      sectionContent.add(o);
      //			System.out.println(XmlUtils.marshaltoString(o, true));
    }

    currentSectionWrapper =
        createSectionWrapper(
            document.getBody().getSectPr(),
            previousHF,
            rels,
            evenAndOddHeaders,
            ++conversionSectionIndex,
            sectionContent,
            dummyPageNumbering);
    conversionSections.add(currentSectionWrapper);
    return conversionSections;
  }
    @Override
    public List<Object> apply(Object o) {

      // NB: the tests in this method have to be comprehensive,
      // so if support for glow etc is introduced, tests for those
      // will need to be added

      if (o instanceof org.docx4j.wml.P) {
        P p = (P) o;

        // W14?
        if (p.getParaId() != null) {
          needW14 = true;
        }
        // W15?
        if (!needW15) {
          PPr ppr = p.getPPr();
          if (ppr != null) {
            if (ppr.getCollapsed() != null) {
              needW15 = true;
            }

            if (ppr.getSectPr() != null && ppr.getSectPr().getFootnoteColumns() != null) {
              needW15 = true;
            }
          }
        }

      } else if (o instanceof SdtElement) {
        SdtPr sdtPr = ((SdtElement) o).getSdtPr();
        if (sdtPr != null) {
          if (contains(
              sdtPr.getRPrOrAliasOrLock(),
              "http://schemas.microsoft.com/office/word/2010/wordml",
              w14SdtPrNames)) {
            needW14 = true;
          }
          if (contains(
              sdtPr.getRPrOrAliasOrLock(),
              "http://schemas.microsoft.com/office/word/2012/wordml",
              w15SdtPrNames)) {
            needW15 = true;
          }
        }
      } else if (o instanceof Tr) { // TODO does this need to be unwrapped?
        if (((Tr) o).getParaId() != null) {
          needW14 = true;
        }
      } else if (o instanceof CTObject) {
        if (((CTObject) o).getAnchorId() != null) {
          needW14 = true;
        }
      } else if (o instanceof Pict) {
        if (((Pict) o).getAnchorId() != null) {
          needW14 = true;
        }
      }

      return null;
    }