private void process(final Node parent,
                         final Buffer buffer,
                         final Match parentMatch,
                         final int parentMatchCount,
                         final int level,
                         final MatchOrder matchOrder,
                         final boolean ignoreErrors) throws IOException, SAXException {
        int advance = 1;
        boolean firstPass = true;
        int matchCount = 0;
        Expression expression = null;

        // Reset expression match counts.
        for (final Node node : parent.getChildNodes()) {
            if (node.isExpression()) {
                ((Expression) node).resetMatchCount();
            }
        }

        // Now try and match content with expressions and output data.
        while (advance > 0) {
            advance = 0;

            for (final Node node : parent.getChildNodes()) {
                if (node.isExpression()) {
                    // If the node is an expression and we haven't matched an
                    // expression yet (i.e. advance <= 0) then try and match
                    // this expression. If we are in recovery mode then don't
                    // try and match any other expressions until the next pass.
                    if (advance <= 0 && advance != RECOVERY_MODE) {
                        expression = (Expression) node;
                        advance = processExpression(
                                expression,
                                buffer,
                                parentMatchCount,
                                matchCount,
                                level,
                                matchOrder,
                                ignoreErrors);
                        // If we found a match then increase the match count.
                        if (advance > 0) {
                            matchCount++;
                        }
                    }
                } else if (firstPass) {
                    if (node.getNodeType() == NodeType.GROUP) {
                        storeData((Group) node, buffer, parentMatch, parentMatchCount);
                        processGroup((Group) node, buffer, parentMatch, parentMatchCount, level);
                    } else if (node.getNodeType() == NodeType.DATA) {
                        storeData((Data) node, buffer, parentMatch, parentMatchCount);
                        processData(
                                (Data) node,
                                buffer,
                                parentMatch,
                                parentMatchCount,
                                level,
                                matchOrder,
                                ignoreErrors);
                    } else if (node.getNodeType() == NodeType.VAR) {
                        storeData((Var) node, buffer, parentMatch, parentMatchCount);
                    }
                }
            }

            if (level == 0) {
                // Change the reader location if this is a top level match.
                if (advance == RECOVERY_MODE) {
                    // If we are in recovery mode then set advance to 1 so that
                    // we keep trying to process.
                    advance = 1;
                }

                // Fill up the buffer.
                reader.fillBuffer();

                // End the record if needed.
                endRecord();

                // Change the reader location for error reporting etc.
                reader.changeLocation();
            }

            // Start profiling service if we need to in case it has been turned
            // on since execution start.
            startProfiling();

            firstPass = false;
        }
    }
Parses a flat file and produces SAX events according to the feed
definition.

@param input The flat input source to process.
@throws IOException  Could be thrown reading the stream.
@throws SAXException Not be thrown as we are not reading an XML file just using
                     the XMLReader interface.
@see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
stroom-pipeline/src/main/java/stroom/pipeline/xml/converter/ds3/DS3Parser.java