class XMLChangeLogSAXHandler extends DefaultHandler {

    private final ChangeFactory changeFactory;
    private final PreconditionFactory preconditionFactory;
    private final SqlVisitorFactory sqlVisitorFactory;
    private final ChangeLogParserFactory changeLogParserFactory;

    protected Logger log;

	private final DatabaseChangeLog databaseChangeLog;
	private final ResourceAccessor resourceAccessor;
	private final ChangeLogParameters changeLogParameters;
    private final Stack<ParsedNode> nodeStack = new Stack<>();
    private final Stack<StringBuilder> textStack = new Stack<>();
    private ParsedNode databaseChangeLogTree;


    protected XMLChangeLogSAXHandler(String physicalChangeLogLocation, ResourceAccessor resourceAccessor, ChangeLogParameters changeLogParameters) {
		log = Scope.getCurrentScope().getLog(getClass());
		this.resourceAccessor = resourceAccessor;

		databaseChangeLog = new DatabaseChangeLog();
		databaseChangeLog.setPhysicalFilePath(physicalChangeLogLocation);
		databaseChangeLog.setChangeLogParameters(changeLogParameters);

        if (changeLogParameters == null) {
            this.changeLogParameters = new ChangeLogParameters();
        } else {
            this.changeLogParameters = changeLogParameters;
        }

        changeFactory = Scope.getCurrentScope().getSingleton(ChangeFactory.class);
        preconditionFactory = PreconditionFactory.getInstance();
        sqlVisitorFactory = SqlVisitorFactory.getInstance();
        changeLogParserFactory = ChangeLogParserFactory.getInstance();
    }

	public DatabaseChangeLog getDatabaseChangeLog() {
		return databaseChangeLog;
	}

    public ParsedNode getDatabaseChangeLogTree() {
        return databaseChangeLogTree;
    }

    @Override
    public void characters(char ch[], int start, int length) {
        textStack.peek().append(new String(ch, start, length));
    }


    @Override
    public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) throws SAXException {<FILL_FUNCTION_BODY>}

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        ParsedNode node = nodeStack.pop();
        try {
            String seenText = this.textStack.pop().toString();
            if (!"".equals(StringUtil.trimToEmpty(seenText))) {
                node.setValue(seenText.trim());
            }
        } catch (ParsedNodeException e) {
            throw new SAXException(e);
        }
    }
}

        ParsedNode node = new ParsedNode(null, localName);
        try {
            if (attributes != null) {
                for (int i=0; i< attributes.getLength(); i++) {
                    try {
                        node.addChild(null, attributes.getLocalName(i), attributes.getValue(i));
                    } catch (NullPointerException e) {
                        throw e;
                    }
                }
            }
            if (!nodeStack.isEmpty()) {
                nodeStack.peek().addChild(node);
            }
            if (nodeStack.isEmpty()) {
                databaseChangeLogTree = node;
            }
            nodeStack.push(node);
            textStack.push(new StringBuilder());
        } catch (ParsedNodeException e) {
            throw new SAXException(e);
        }
    
<methods>public void <init>() ,public void characters(char[], int, int) throws org.xml.sax.SAXException,public void endDocument() throws org.xml.sax.SAXException,public void endElement(java.lang.String, java.lang.String, java.lang.String) throws org.xml.sax.SAXException,public void endPrefixMapping(java.lang.String) throws org.xml.sax.SAXException,public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException,public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException,public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException,public void notationDecl(java.lang.String, java.lang.String, java.lang.String) throws org.xml.sax.SAXException,public void processingInstruction(java.lang.String, java.lang.String) throws org.xml.sax.SAXException,public org.xml.sax.InputSource resolveEntity(java.lang.String, java.lang.String) throws java.io.IOException, org.xml.sax.SAXException,public void setDocumentLocator(org.xml.sax.Locator) ,public void skippedEntity(java.lang.String) throws org.xml.sax.SAXException,public void startDocument() throws org.xml.sax.SAXException,public void startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) throws org.xml.sax.SAXException,public void startPrefixMapping(java.lang.String, java.lang.String) throws org.xml.sax.SAXException,public void unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String) throws org.xml.sax.SAXException,public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException<variables>