@Override
  public void endElement(String uri, String localName, String qName) throws SAXException {
    String elem = localName;
    if (elem.isEmpty()) {
      elem = qName;
    }
    // check doc structure sanity
    if (!elemStack.getFirst().equals(elem)) {
      throw new IllegalStateException(
          String.format("Elem ending expected: %s, but was: %s", elemStack.getFirst(), elem));
    }

    ElementHandler elemHandler = handlerStack.removeFirst();
    if (sb != null) {
      String txt = sb.toString();
      // !
      txt.trim();
      elemHandler.characters(txt);
      sb = null;
    }
    elemHandler.endElement();

    elemStack.removeFirst();
  }