@Override
    public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
                      ParseContext context) throws IOException, SAXException, TikaException {
        TextAndCSVConfig textAndCSVConfig = context.get(TextAndCSVConfig.class, defaultTextAndCSVConfig);

        CSVParams params = getOverride(metadata, textAndCSVConfig);
        Reader reader;
        Charset charset;
        if (!params.isComplete()) {
            reader = detect(params, textAndCSVConfig, stream, metadata, context);
            if (params.getCharset() != null) {
                charset = params.getCharset();
            } else {
                charset = ((AutoDetectReader) reader).getCharset();
            }
        } else {
            reader = new BufferedReader(new InputStreamReader(stream, params.getCharset()));
            charset = params.getCharset();
        }

        updateMetadata(params, metadata, textAndCSVConfig);

        //if text or a non-csv/tsv category of text
        //treat this as text and be done
        //TODO -- if it was detected as a non-csv subtype of text
        if (!params.getMediaType().getBaseType().equals(CSV) &&
                !params.getMediaType().getBaseType().equals(TSV)) {
            handleText(reader, charset, handler, metadata);
            return;
        }

        CSVFormat csvFormat = CSVFormat.EXCEL.builder().setDelimiter(params.getDelimiter()).get();
        metadata.set(DELIMITER_PROPERTY, textAndCSVConfig.getDelimiterToNameMap().get(csvFormat.getDelimiterString().charAt(0)));

        XHTMLContentHandler xhtmlContentHandler = new XHTMLContentHandler(handler, metadata);
        int totalRows = 0;
        try (CSVParser commonsParser = CSVParser.builder().setReader(reader).setFormat(csvFormat).get()) {
            xhtmlContentHandler.startDocument();
            xhtmlContentHandler.startElement(TABLE);
            int firstRowColCount = 0;
            try {
                for (CSVRecord row : commonsParser) {
                    xhtmlContentHandler.startElement(TR);
                    for (String cell : row) {
                        if (totalRows == 0) {
                            firstRowColCount++;
                        }
                        xhtmlContentHandler.startElement(TD);
                        xhtmlContentHandler.characters(cell);
                        xhtmlContentHandler.endElement(TD);
                    }
                    xhtmlContentHandler.endElement(TR);
                    if (totalRows == 0) {
                        metadata.set(NUM_COLUMNS, firstRowColCount);
                    }
                    totalRows++;
                }
                metadata.set(NUM_ROWS, totalRows);
            } catch (UncheckedIOException e) {
                if (e.getCause() != null && e.getCause().getMessage() != null &&
                        e.getCause().getMessage().contains("encapsulated")) {
                    //if there's a parse exception
                    //try to get the rest of the content...treat it as text for now
                    //There will be some content lost because of buffering.
                    //TODO -- figure out how to improve this
                    xhtmlContentHandler.endElement(TABLE);
                    xhtmlContentHandler.startElement("div", "name", "after exception");
                    handleText(reader, xhtmlContentHandler);
                    xhtmlContentHandler.endElement("div");
                    xhtmlContentHandler.endDocument();
                    //TODO -- consider dumping what's left in the reader as text
                    throw new TikaException("exception parsing the csv", e);
                } else {
                    if (e.getCause() != null) {
                        throw new TikaException("exception parsing the csv", e.getCause());
                    } else {
                        throw new TikaException("exception parsing the csv", e);
                    }
                }
            }

            xhtmlContentHandler.endElement(TABLE);
            xhtmlContentHandler.endDocument();
        }
    }
minimum confidence score that there's enough
evidence to determine csv/tsv vs. txt
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/csv/TextAndCSVParser.java