@Override
    public void endElement(final String uri, final String localName, final String qName) throws SAXException {
        if (depth == 1) {
            inRoot = false;
        }

        if (!buffer) {
            super.endElement(uri, localName, qName);
        } else if (inRoot || afterRoot == -1) {
            length--;
        }

        if (depth == splitDepth) {
            if (locationHolder != null) {
                // The location reported by the locator held in locationHolder may not be the same as the actual
                // location of the (start|end)Element. It depends on how the parser in question reads the source
                // data and closely tied the locator is to the parser.  For XML parsing it will be accurate. The
                // fragment parser locations are partially messed up by the reading of the entity. The data splitter
                // is ok if DSLocator is used. Json parsing is completely wrong as large chunks of the stream
                // are read at once.
                locationHolder.storeLocation();
            }

            buffer = true;

            if (count == splitCount || afterRoot < 0) {
                // Reset the element count if it equals the split count.
                count = 0;
                // Fire all end events.
                fireEndEvents(length, 0);

                super.endDocument();
            } else {
                // If the count has not yet reached the split count then we only
                // need to fire end SAX events down to the root element.
                fireEndEvents(length, afterRoot);
            }
        }

        // Mark the start location on every end element so when storeLocation is called
        // it will get the range from the end of the element just before this record to the end
        // of this record.  This is because the locator gets the location of '<myElement>'.
        if (depth <= splitDepth) {
            LOGGER.trace("endElement({}), depth: {}", localName, depth);
            if (locationHolder != null) {
                locationHolder.markStartLocation();
            }
        }

        depth--;
    }
<p>
This method outputs an end element if the depth is greater than the split
depth. If the element depth is the same as the split depth then it will
fire all stored start element events as end element events and fire an
end document event. If the depth is less than the split depth then it
will pop a start element from the stack.
<p>

@param uri       The element's Namespace URI, or the empty string.
@param localName The element's local name, or the empty string.
@param qName     The element's qualified (prefixed) name, or the empty string.
@throws org.xml.sax.SAXException The client may throw an exception during processing.
@see stroom.pipeline.filter.AbstractXMLFilter#endElement(java.lang.String,
java.lang.String, java.lang.String)
stroom-pipeline/src/main/java/stroom/pipeline/filter/SplitFilter.java