private void add(final StateType stateType) {
        LOGGER.debug(() -> "Adding " + stateType.getDisplayValue() + " to map: " + mapName);
        final Optional<PlanBDoc> optional = writer.getDoc(mapName, this::error);
        optional.ifPresent(doc -> {
            if (stateType.equals(doc.getStateType())) {
                switch (doc.getStateType()) {
                    case STATE -> addState(doc);
                    case TEMPORAL_STATE -> addTemporalState(doc);
                    case RANGED_STATE -> addRangeState(doc);
                    case TEMPORAL_RANGED_STATE -> addTemporalRangeState(doc);
                    case SESSION -> addSession(doc);
                    case HISTOGRAM -> addHistogramValue(doc);
                    case METRIC -> addMetricValue(doc);
                    default -> error("Unexpected Plan B store type: " + doc.getStateType());
                }
            } else {
                error("Unexpected Plan B store type for " + stateType.getDisplayValue() + ": " + doc.getStateType());
            }
        });

        // Set keys to null.
        reset();
    }
This method applies a post processing function if we are currently within
a function element. At this stage we should have details of the function
to apply from the corresponding start element and content to apply it to
from the characters event.

@param uri       The element's Namespace URI, or the empty string.
@param localName The element's local key, or the empty string.
@param qName     The element's qualified (prefixed) key, or the empty string.
@throws SAXException The client may throw an exception during processing.
@see AbstractXMLFilter#endElement(String,
String, String)
stroom-state/stroom-planb-impl/src/main/java/stroom/planb/impl/pipeline/PlanBFilter.java