private void tagExited(final XmlTag tag) {
    if (!myStack.isEmpty() && myStack.peek().getTag() == tag) {
      assert false;
    }
    else if (!myStack.isEmpty() && isHeader(tag)) {
      // do nothing
    }
    else if (!myStack.isEmpty() && isSectioningContentElement(tag)) {
      final SectionHolder exitedSectioningContent = myCurrentOutlinee;
      assert exitedSectioningContent.getTag() == tag;

      myCurrentOutlinee = myStack.pop();
      myCurrentSection = myCurrentOutlinee.getChildren().getLast();

      for (Section section : exitedSectioningContent.getChildren()) {
        myCurrentSection.addChildSection(section);
      }
    }
    else if (!myStack.isEmpty() && isSectioningRootElement(tag)) {
      final SectionHolder exitedSectioningRoot = myCurrentOutlinee;
      assert exitedSectioningRoot.getTag() == tag;
      myRootSectionHolders.add(exitedSectioningRoot);

      myCurrentOutlinee = myStack.pop();

      myCurrentSection = myCurrentOutlinee.getChildren().getLast();
      while (!myCurrentSection.getChildren().isEmpty()) {
        myCurrentSection = myCurrentSection.getChildren().getLast();
      }
    }
    else if (isSectioningContentElement(tag) || isSectioningRootElement(tag)) {
      assert myStack.isEmpty();

      assert myCurrentOutlinee.getTag() == tag;
      myRootSectionHolders.add(myCurrentOutlinee);

      // reset algorithm
      myCurrentOutlinee = null;
      myCurrentSection = null;
    }
  }
private void tagExited(final XmlTag tag)