@Override
    public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
                      ParseContext context) throws IOException, SAXException, TikaException {
        TikaInputStream tis = TikaInputStream.get(stream);
        Database db = null;
        XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
        xhtml.startDocument();

        String password = null;
        PasswordProvider passwordProvider = context.get(PasswordProvider.class);
        if (passwordProvider != null) {
            password = passwordProvider.getPassword(metadata);
        }
        try {
            if (password == null) {
                //do this to ensure encryption/wrong password exception vs. more generic
                //"need right codec" error message.
                db = new DatabaseBuilder(tis.getFile()).setCodecProvider(new CryptCodecProvider())
                        .setReadOnly(true).open();
            } else {
                db = new DatabaseBuilder(tis.getFile())
                        .setCodecProvider(new CryptCodecProvider(password)).setReadOnly(true)
                        .open();
            }
            db.setLinkResolver(IGNORE_LINK_RESOLVER);//just in case
            JackcessExtractor ex = new JackcessExtractor(metadata, context, locale);
            ex.parse(db, xhtml);
        } catch (IOException e) {
            //TIKA-3849
            if (e.getMessage() != null && e.getMessage().contains("Unrecognized map type: 75")) {
                throw new UnsupportedFormatException(
                        "Jackcess doesn't process mdb versions before v97");
            }
            throw e;
        } catch (IllegalStateException e) {
            if (e.getMessage() != null && e.getMessage().contains("Incorrect password")) {
                throw new EncryptedDocumentException(e);
            }
            throw e;
        } finally {
            if (db != null) {
                try {
                    db.close();
                } catch (IOException e) {
                    //swallow = silent close
                }
            }
        }
        xhtml.endDocument();
    }
@Test
    public void testBasic() throws Exception {

        RecursiveParserWrapper w = new RecursiveParserWrapper(AUTO_DETECT_PARSER);

        for (String fName : new String[]{"testAccess2.accdb", "testAccess2_2000.mdb",
                "testAccess2_2002-2003.mdb"}) {
            InputStream is = null;
            RecursiveParserWrapperHandler handler = new RecursiveParserWrapperHandler(
                    new BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML,
                            -1));
            try {
                is = this.getResourceAsStream("/test-documents/" + fName);

                Metadata meta = new Metadata();
                ParseContext c = new ParseContext();
                w.parse(is, handler, meta, c);
            } finally {
                IOUtils.closeQuietly(is);
            }
            List<Metadata> list = handler.getMetadataList();
            assertEquals(4, list.size());
            String mainContent = list.get(0).get(TikaCoreProperties.TIKA_CONTENT);

            //make sure there's a thead and tbody
            assertContains("</thead><tbody>", mainContent);

            //assert table header
            assertContains("<th>ShortTextField</th>", mainContent);

            //test date format
            //java 8 is 6/24/15 ...java 10 is 2015-06-24
            assertTrue(mainContent.contains("6/24/15") || mainContent.contains("2015-06-24"));

            //test that markup is stripped
            assertContains("over the bold italic dog", mainContent);

            //test unicode
            assertContains("\u666E\u6797\u65AF\u987F\u5927\u5B66", mainContent);

            //test embedded document handling
            assertContains("Test Document with embedded pdf",
                    list.get(3).get(TikaCoreProperties.TIKA_CONTENT));
        }
    }