class EpubModule extends ModuleBase {

    @Override
    public int parse(InputStream stream, RepInfo info, int parseIndex) throws IOException {

        initParse();

        info.setModule(this);
        info.setFormat(_format[0]);
        info.setWellFormed(false);
        info.setValid(false);

        _propList = new LinkedList<>();
        _metadata = new Property(PROPNAME_EPUB_METADATA, PropertyType.PROPERTY, PropertyArity.LIST, _propList);

        // loads stream to _dstream so it can be checksummed when flag enabled
        _ckSummer = null;
        setupDataStream(stream, info);

        //Call tool and calculate stats
        try {
            JhoveRepInfoReport report = new JhoveRepInfoReport(info.getUri());
            EpubCheck epubCheck = new EpubCheck(_dstream, report, info.getUri());
            epubCheck.doValidate();

            info.setCreated(report.getCreationDate());
            info.setLastModified(report.getLastModifiedDate());
            info.setVersion(report.getVersion());

            List<CheckMessage> epubMessages = report.getAllMessages();

            // check if any of the messages are on the customized not-well-formed
            // list of errors
            int notWellFormedErrors = epubMessages.stream().filter(c -> triggerNotWellFormed(c))
                    .collect(Collectors.toSet()).size();

            info.setWellFormed(report.getFatalErrorCount() == 0 && notWellFormedErrors == 0);
            info.setValid(info.getWellFormed() == RepInfo.TRUE && report.getErrorCount() == 0);

            Set<Message> msgs = new TreeSet<Message>(new MessageComparator());
            for (CheckMessage msg : report.getAllMessages()) {
                msgs.addAll(toJhoveMessages(msg));
            }
            msgs.forEach(jhoveMsg -> info.setMessage(jhoveMsg));

            info.setMimeType(report.getFormat());

            generateProperties(report).forEach(prop -> _propList.add(prop));

        } catch (Exception f) {
            f.printStackTrace();
            if (f.getMessage() != null) {
                info.setMessage(new ErrorMessage(f.getMessage()));
            } else {
                info.setMessage(new ErrorMessage(MessageConstants.ERR_UNKNOWN));
            }
            info.setWellFormed(false); // may not be the file's fault
            return 0;
        }

        // Check if user has aborted
        if (_je != null && _je.getAbort()) {
            return 0;
        }

        // We parsed it.  Now assemble the properties.
        info.setProperty(_metadata);

        setChecksums(_ckSummer, info);

        return 0;
    }

    public  EpubModule();
    public  EpubModule(String name, String release, int[] date,
            String[] format, String coverage,
            String[] mimetype, String wellformedNote,
            String validityNote, String repinfoNote, String note,
            String rights, boolean isRandomAccess, Agent moduleAgent);

}