@Override
 public void endDocument() throws SAXException {
   assertSAX(!myParseStack.isEmpty());
   for (int i = myParseStack.size() - 1; i >= 0; --i) {
     ElementHandlerBase current = myParseStack.get(i);
     current.postEffect(myDataCallback);
   }
   myParseStack.clear();
 }
  @Override
  public void startElement(String uri, String localName, String qName, Attributes attributes)
      throws SAXException {
    assertSAX(!myParseStack.isEmpty());
    ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1);
    if (mySb.length() > 0) {
      current.characters(mySb.toString().trim(), myPending, myLockBuilder);
      mySb.setLength(0);
    }

    while (true) {
      final boolean createNewChild = current.startElement(uri, localName, qName, attributes);
      if (createNewChild) {
        assertSAX(myElementsMap.containsKey(qName));
        final ElementHandlerBase newChild = myElementsMap.get(qName).get();
        newChild.preAttributesEffect(myDataCallback);
        newChild.updateStatus(attributes, myPending, myLockBuilder);
        newChild.preEffect(myDataCallback);
        myParseStack.add(newChild);
        return;
      } else {
        // go up
        current.postEffect(myDataCallback);
        myParseStack.remove(myParseStack.size() - 1);
        assertSAX(!myParseStack.isEmpty());
        current = myParseStack.get(myParseStack.size() - 1);
      }
    }
  }