private Catalogue readCatalogue(ByteArrayInputStream inputStream) throws XmlException, IOException {
        final Catalogue catalogue = new Catalogue();
        try {
            SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
            saxParser.parse(inputStream, new DefaultHandler() {
                @Override
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                    if (qName.equalsIgnoreCase(DataConstants.CATALOGUE_TAG)) {
                        catalogue.setId(attributes.getValue(DataConstants.ID_ATTRIBUTE));
                        catalogue.setGameSystemId(attributes.getValue(DataConstants.GAME_SYSTEM_ID_ATTRIBUTE));
                        catalogue.setBattleScribeVersion(attributes.getValue(DataConstants.BATTLESCRIBE_VERSION_ATTRIBUTE));
                        catalogue.setRevision(Integer.parseInt(attributes.getValue(DataConstants.REVISION_ATTRIBUTE)));
                        catalogue.setName(attributes.getValue(DataConstants.NAME_ATTRIBUTE));
                        catalogue.setAuthorName(attributes.getValue(DataConstants.AUTHOR_NAME_ATTRIBUTE));
                        catalogue.setAuthorContact(attributes.getValue(DataConstants.AUTHOR_CONTACT_ATTRIBUTE));
                        catalogue.setAuthorUrl(attributes.getValue(DataConstants.AUTHOR_URL_ATTRIBUTE));
                        throw new SAXParseCompleteException("DONE");
                    }
                }
            });
        }
        catch (ParserConfigurationException e) {
            throw new IllegalStateException(e);
        }
        catch (SAXParseCompleteException e) {
            return catalogue;
        }
        catch (SAXException ex) {
            throw new XmlException(ex);
        }
        throw new XmlException("Invalid catalogue XML");
    }