class SxmpParser {

    public Operation parse(InputStream in) throws SxmpParsingException, IOException, SAXException, ParserConfigurationException {
        // create a new SAX parser
        SAXParserFactory factory = SAXParserFactory.newInstance();

        SAXParser parser = factory.newSAXParser();
        parser.getXMLReader().setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        parser.getXMLReader().setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);
        parser.getXMLReader().setFeature("http://xml.org/sax/features/external-general-entities", false);
        parser.getXMLReader().setFeature("http://xml.org/sax/features/external-parameter-entities"	, false);
        parser.getXMLReader().setFeature("http://xml.org/sax/features/namespaces", true);
        parser.getXMLReader().setFeature("http://xml.org/sax/features/namespace-prefixes", true);
        parser.getXMLReader().setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);

        //_dtd=null;
        Handler handler = new Handler();
        XMLReader reader = parser.getXMLReader();
        reader.setContentHandler(handler);
        reader.setErrorHandler(handler);
        reader.setEntityResolver(handler);

        // try parsing (may throw an SxmpParsingException in the handler)
        try {
            parser.parse(new InputSource(in), handler);
        } catch (com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException e) {
            throw new SxmpParsingException(SxmpErrorCode.INVALID_XML, "XML encoding mismatch", null);
        }

        // check if there was an error
        if (handler.error != null) {
            throw handler.error;
        }

        // check to see if an operation was actually parsed
        if (handler.getOperation() == null) {
            throw new SxmpParsingException(SxmpErrorCode.MISSING_REQUIRED_ELEMENT, "The operation type [" + handler.operationType.getValue() + "] requires a request element", new PartialOperation(handler.operationType));
        }

        // if we got here, an operation was parsed -- now we need to validate it
        // to make sure that it has all required elements
        try {
            handler.getOperation().validate();
        } catch (SxmpErrorException e) {
            throw new SxmpParsingException(e.getErrorCode(), e.getErrorMessage(), handler.getOperation());
        }

        return handler.getOperation();
    }

    public  SxmpParser();
    public  SxmpParser(final String version);

}