You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2025/12/16 12:52:16 UTC

(tika) branch main updated: TIKA-4569 add parsecontext to detectors and embedded document extractors

This is an automated email from the ASF dual-hosted git repository.

tallison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/main by this push:
     new 77f5593ae TIKA-4569 add parsecontext to detectors and embedded document extractors
77f5593ae is described below

commit 77f5593ae8fc3d4bfe560987868aa0cc155abb72
Author: Tim Allison <ta...@apache.org>
AuthorDate: Tue Dec 16 07:52:11 2025 -0500

    TIKA-4569 add parsecontext to detectors and embedded document extractors
    
    Generated-by: Claude Opus 4.5 (model ID: claude-opus-4-5-20251101)
    
    With significant human direction and manual review.
---
 .../src/main/java/org/apache/tika/cli/TikaCLI.java |   7 +-
 .../test/java/org/apache/tika/bundle/BundleIT.java |   6 +-
 tika-core/src/main/java/org/apache/tika/Tika.java  |   4 +-
 .../org/apache/tika/detect/AutoDetectReader.java   |   3 +-
 .../org/apache/tika/detect/CompositeDetector.java  |   6 +-
 .../tika/detect/CompositeEncodingDetector.java     |   5 +-
 .../main/java/org/apache/tika/detect/Detector.java |   5 +-
 .../java/org/apache/tika/detect/EmptyDetector.java |   4 +-
 .../org/apache/tika/detect/EncodingDetector.java   |   5 +-
 .../apache/tika/detect/FileCommandDetector.java    |   4 +-
 .../java/org/apache/tika/detect/MagicDetector.java | 147 +++++++++++++++------
 .../java/org/apache/tika/detect/NameDetector.java  |   4 +-
 .../org/apache/tika/detect/OverrideDetector.java   |   4 +-
 .../tika/detect/OverrideEncodingDetector.java      |   3 +-
 .../java/org/apache/tika/detect/TextDetector.java  |   4 +-
 .../apache/tika/detect/TrainedModelDetector.java   |   4 +-
 .../java/org/apache/tika/detect/TypeDetector.java  |   5 +-
 .../apache/tika/detect/ZeroSizeFileDetector.java   |   5 +-
 .../apache/tika/extractor/ContainerExtractor.java  |   9 +-
 .../tika/extractor/EmbeddedDocumentExtractor.java  |  18 +--
 .../tika/extractor/EmbeddedDocumentUtil.java       |   4 +-
 .../tika/extractor/EmbeddedResourceHandler.java    |  10 +-
 .../tika/extractor/ParserContainerExtractor.java   |  27 ++--
 .../ParsingEmbeddedDocumentExtractor.java          |   2 +-
 .../apache/tika/extractor/RUnpackExtractor.java    |   2 +-
 .../main/java/org/apache/tika/mime/MagicMatch.java |  12 +-
 .../main/java/org/apache/tika/mime/MimeTypes.java  |   6 +-
 .../mime/ProbabilisticMimeDetectionSelector.java   |   4 +-
 .../org/apache/tika/parser/AutoDetectParser.java   |   2 +-
 .../org/apache/custom/detect/MyCustomDetector.java |   3 +-
 .../org/apache/tika/MultiThreadedTikaTest.java     |   6 +-
 .../src/test/java/org/apache/tika/TikaTest.java    |  10 +-
 .../tika/detect/FileCommandDetectorTest.java       |  11 +-
 .../org/apache/tika/detect/MagicDetectorTest.java  |  11 +-
 .../tika/detect/MimeDetectionWithNNTest.java       |   7 +-
 .../org/apache/tika/detect/NameDetectorTest.java   |   5 +-
 .../org/apache/tika/detect/TextDetectorTest.java   |   7 +-
 .../org/apache/tika/detect/TypeDetectorTest.java   |   5 +-
 .../tika/detect/ZeroSizeFileDetectorTest.java      |   3 +-
 .../org/apache/tika/mime/MimeDetectionTest.java    |  31 ++---
 .../org/apache/tika/mime/MimeTypesReaderTest.java  |  14 +-
 .../tika/mime/ProbabilisticMimeDetectionTest.java  |  27 ++--
 .../org/apache/tika/mime/RFC822DetectionTest.java  |   3 +-
 .../org/apache/tika/parser/mock/MockParser.java    |   2 +-
 .../apache/tika/detect/magika/MagikaDetector.java  |   3 +-
 .../tika/detect/siegfried/SiegfriedDetector.java   |   5 +-
 .../org/apache/tika/eval/app/io/ExtractReader.java |   3 +-
 .../apache/tika/example/AdvancedTypeDetector.java  |   3 +-
 .../apache/tika/example/ContentHandlerExample.java |  16 +--
 .../org/apache/tika/example/DirListParser.java     |   4 +-
 .../apache/tika/example/DisplayMetInstance.java    |   4 +-
 .../example/EncryptedPrescriptionDetector.java     |   3 +-
 .../apache/tika/example/ExtractEmbeddedFiles.java  |   5 +-
 .../org/apache/tika/example/ImportContextImpl.java |   3 +-
 .../java/org/apache/tika/example/MyFirstTika.java  |  43 +++---
 .../org/apache/tika/example/ParsingExample.java    |  17 +--
 .../org/apache/tika/parser/hdf/HDFParserTest.java  |   2 +-
 .../apache/tika/mime/TestMimeTypesExtended.java    |   3 +-
 .../tika/parser/sqlite3/SQLite3ParserTest.java     |  10 +-
 .../tika/parser/journal/JournalParserTest.java     |   3 +-
 .../apache/tika/detect/apple/BPListDetector.java   |   3 +-
 .../tika/parser/apple/AppleSingleFileParser.java   |   2 +-
 .../org/apache/tika/parser/apple/PListParser.java  |   2 +-
 .../parser/iwork/iwana/IWork13PackageParser.java   |   4 +-
 .../apache/tika/parser/iwork/IWorkParserTest.java  |   2 +-
 .../org/apache/tika/detect/MatroskaDetector.java   |   3 +-
 .../org/apache/tika/detect/ogg/OggDetector.java    |   3 +-
 .../java/org/apache/tika/parser/mp4/MP4Parser.java |   3 +-
 .../apache/tika/detect/MatroskaDetectorTest.java   |  17 ++-
 .../org/apache/tika/parser/dgn/DGN8Parser.java     |   3 +-
 .../executable/UniversalExecutableParser.java      |   8 +-
 .../org/apache/tika/parser/crypto/TSDParser.java   |   2 +-
 .../tika/parser/html/HtmlEncodingDetector.java     |   3 +-
 .../org/apache/tika/parser/html/HtmlHandler.java   |   8 +-
 .../org/apache/tika/parser/html/JSoupParser.java   |   2 +-
 .../StandardHtmlEncodingDetector.java              |   3 +-
 .../tika/parser/html/HtmlEncodingDetectorTest.java |   6 +-
 .../apache/tika/parser/html/HtmlParserTest.java    |   2 +-
 .../html/StandardHtmlEncodingDetectorTest.java     |   3 +-
 .../tika/parser/mail/MailContentHandler.java       |   4 +-
 .../org/apache/tika/parser/mbox/MboxParser.java    |   2 +-
 .../apache/tika/parser/mail/RFC822ParserTest.java  |   5 +-
 .../detect/microsoft/POIFSContainerDetector.java   |   8 +-
 .../parser/microsoft/AbstractPOIFSExtractor.java   |   4 +-
 .../apache/tika/parser/microsoft/EMFParser.java    |  19 +--
 .../tika/parser/microsoft/HSLFExtractor.java       |   2 +-
 .../apache/tika/parser/microsoft/OfficeParser.java |   4 +-
 .../tika/parser/microsoft/OutlookExtractor.java    |   2 +-
 .../apache/tika/parser/microsoft/TNEFParser.java   |   9 +-
 .../tika/parser/microsoft/libpst/EmailVisitor.java |   2 +-
 .../microsoft/onenote/OneNoteTreeWalker.java       |   3 +-
 .../microsoft/ooxml/AbstractOOXMLExtractor.java    |  10 +-
 .../ooxml/xwpf/ml2006/BinaryDataHandler.java       |   2 +-
 .../parser/microsoft/pst/OutlookPSTParser.java     |   2 +-
 .../parser/microsoft/pst/PSTMailItemParser.java    |  10 +-
 .../tika/parser/microsoft/xml/WordMLParser.java    |   8 +-
 .../microsoft/POIFSContainerDetectorTest.java      |   3 +-
 .../AbstractPOIContainerExtractionTest.java        |   8 +-
 .../tika/parser/microsoft/ExcelParserTest.java     |   4 +-
 .../tika/parser/microsoft/OldExcelParserTest.java  |   2 +-
 .../tika/parser/microsoft/TNEFParserTest.java      |   2 +-
 .../parser/microsoft/ooxml/OOXMLParserTest.java    |   2 +-
 .../tika/parser/microsoft/rtf/RTFParserTest.java   |  15 ++-
 .../apache/tika/detect/ole/MiscOLEDetector.java    |   3 +-
 .../java/org/apache/tika/parser/dbf/DBFParser.java |   6 +-
 .../java/org/apache/tika/parser/dif/DIFParser.java |   3 +-
 .../org/apache/tika/parser/epub/EpubParser.java    |   8 +-
 .../parser/odf/FlatOpenDocumentMacroHandler.java   |   2 +-
 .../tika/parser/odf/OpenDocumentBodyHandler.java   |   2 +-
 .../apache/tika/parser/odf/OpenDocumentParser.java |   9 +-
 .../apache/tika/parser/pdf/AbstractPDF2XHTML.java  |  10 +-
 .../java/org/apache/tika/parser/pdf/PDF2XHTML.java |   2 +-
 .../java/org/apache/tika/parser/pdf/PDFParser.java |   3 +-
 .../tika/parser/pdf/image/ImageGraphicsEngine.java |   5 +-
 .../detect/gzip/GZipSpecializationDetector.java    |   3 +-
 .../apache/tika/parser/pkg/CompressorParser.java   |   2 +-
 .../org/apache/tika/parser/pkg/PackageParser.java  |  44 +++---
 .../java/org/apache/tika/parser/pkg/RarParser.java |   2 +-
 .../org/apache/tika/parser/pkg/UnrarParser.java    |   2 +-
 .../apache/tika/parser/strings/StringsParser.java  |   2 +-
 .../org/apache/tika/parser/txt/BOMDetector.java    |   3 +-
 .../tika/parser/txt/Icu4jEncodingDetector.java     |   3 +-
 .../tika/parser/txt/UniversalEncodingDetector.java |   3 +-
 .../apache/tika/parser/txt/BOMDetectorTest.java    |   5 +-
 .../org/apache/tika/parser/txt/TXTParserTest.java  |   2 +
 .../org/apache/tika/parser/http/HttpParser.java    |   2 +-
 .../org/apache/tika/parser/wacz/WACZParser.java    |   2 +-
 .../org/apache/tika/parser/warc/WARCParser.java    |   2 +-
 .../apache/tika/parser/xml/FictionBookParser.java  |   8 +-
 .../detect/zip/DefaultZipContainerDetector.java    |  13 +-
 .../DeprecatedStreamingZipContainerDetector.java   |   3 +-
 .../detect/zip/StreamingZipContainerDetector.java  |   3 +-
 .../apache/tika/detect/zip/ZipDetectionTest.java   |   3 +-
 .../apache/tika/config/TikaDetectorConfigTest.java |   5 +-
 .../tika/detect/TestContainerAwareDetector.java    |  29 ++--
 .../org/apache/tika/detect/TestZipDetector.java    |   9 +-
 .../java/org/apache/tika/mime/TestMimeTypes.java   |  13 +-
 .../apache/tika/parser/AutoDetectParserTest.java   |   2 +-
 .../parser/fork/ForkParserIntegrationTest.java     |   2 +-
 .../apache/tika/parser/mail/MboxParserTest.java    |   5 +-
 .../parser/microsoft/ooxml/TruncatedOOXMLTest.java |   5 +-
 .../org/apache/tika/parser/pdf/PDFParserTest.java  |   9 +-
 .../pkg/CompositeZipContainerDetectorTest.java     |  23 ++--
 .../org/apache/tika/parser/pkg/ZipParserTest.java  |   2 +-
 .../tika/parser/xml/FictionBookParserTest.java     |   7 +-
 .../tika/pipes/core/server/ParseHandler.java       |   2 +-
 .../apache/tika/pipes/core/CrashingDetector.java   |   3 +-
 .../server/core/resource/DetectorResource.java     |   2 +-
 .../server/core/resource/UnpackerResource.java     |   2 +-
 .../tika/server/standard/UnpackerResourceTest.java |   3 +-
 .../standard/UnpackerResourceWithConfigTest.java   |   5 +-
 151 files changed, 627 insertions(+), 465 deletions(-)

diff --git a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
index 0e6dbf035..a92972137 100644
--- a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
+++ b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
@@ -193,7 +193,7 @@ public class TikaCLI {
         public void process(TikaInputStream tis, OutputStream output, Metadata metadata) throws Exception {
             PrintWriter writer = new PrintWriter(getOutputWriter(output, encoding));
             writer.println(detector
-                    .detect(tis, metadata)
+                    .detect(tis, metadata, context)
                     .toString());
             writer.flush();
         }
@@ -1144,10 +1144,11 @@ public class TikaCLI {
         }
 
         @Override
-        public void parseEmbedded(TikaInputStream tis, ContentHandler contentHandler, Metadata metadata, boolean outputHtml) throws SAXException, IOException {
+        public void parseEmbedded(TikaInputStream tis, ContentHandler contentHandler, Metadata metadata,
+                                  ParseContext parseContext, boolean outputHtml) throws SAXException, IOException {
             String contentType = metadata.get(Metadata.CONTENT_TYPE);
             if (StringUtils.isBlank(contentType)) {
-                MediaType mediaType = detector.detect(tis, metadata);
+                MediaType mediaType = detector.detect(tis, metadata, new ParseContext());
                 if (mediaType == null) {
                     mediaType = MediaType.OCTET_STREAM;
                 }
diff --git a/tika-bundles/tika-bundle-standard/src/test/java/org/apache/tika/bundle/BundleIT.java b/tika-bundles/tika-bundle-standard/src/test/java/org/apache/tika/bundle/BundleIT.java
index 8704ed6f5..b82e040d9 100644
--- a/tika-bundles/tika-bundle-standard/src/test/java/org/apache/tika/bundle/BundleIT.java
+++ b/tika-bundles/tika-bundle-standard/src/test/java/org/apache/tika/bundle/BundleIT.java
@@ -149,8 +149,8 @@ public class BundleIT {
         metadataPDF.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.pdf");
 
         // Simple type detection
-        assertEquals(MediaType.TEXT_PLAIN, contentTypeDetector.detect(null, metadataTXT));
-        assertEquals(MediaType.application("pdf"), contentTypeDetector.detect(null, metadataPDF));
+        assertEquals(MediaType.TEXT_PLAIN, contentTypeDetector.detect(null, metadataTXT, new ParseContext()));
+        assertEquals(MediaType.application("pdf"), contentTypeDetector.detect(null, metadataPDF, new ParseContext()));
     }
 
     @Test
@@ -162,7 +162,7 @@ public class BundleIT {
                 Writer writer = new StringWriter();
                 ContentHandler contentHandler = new BodyContentHandler(writer);
                 Metadata metadata = new Metadata();
-                MediaType type = contentTypeDetector.detect(tis, metadata);
+                MediaType type = contentTypeDetector.detect(tis, metadata, new ParseContext());
                 assertEquals(type.toString(), "text/html");
                 metadata.add(Metadata.CONTENT_TYPE, type.toString());
                 ParseContext parseCtx = new ParseContext();
diff --git a/tika-core/src/main/java/org/apache/tika/Tika.java b/tika-core/src/main/java/org/apache/tika/Tika.java
index d02343745..959200b31 100644
--- a/tika-core/src/main/java/org/apache/tika/Tika.java
+++ b/tika-core/src/main/java/org/apache/tika/Tika.java
@@ -146,10 +146,10 @@ public class Tika {
      */
     public String detect(InputStream stream, Metadata metadata) throws IOException {
         if (stream == null) {
-            return detector.detect(null, metadata).toString();
+            return detector.detect(null, metadata, new ParseContext()).toString();
         }
         try (TikaInputStream tis = TikaInputStream.get(stream)) {
-            return detector.detect(tis, metadata).toString();
+            return detector.detect(tis, metadata, new ParseContext()).toString();
         }
     }
 
diff --git a/tika-core/src/main/java/org/apache/tika/detect/AutoDetectReader.java b/tika-core/src/main/java/org/apache/tika/detect/AutoDetectReader.java
index cd3a9b124..d8e89653f 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/AutoDetectReader.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/AutoDetectReader.java
@@ -30,6 +30,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.utils.CharsetUtils;
 
 /**
@@ -87,7 +88,7 @@ public class AutoDetectReader extends BufferedReader {
                                   EncodingDetector detector)
             throws IOException, TikaException {
         // Ask all given detectors for the character encoding
-        Charset charset = detector.detect(tis, metadata);
+        Charset charset = detector.detect(tis, metadata, new ParseContext());
         if (charset != null) {
             return charset;
         }
diff --git a/tika-core/src/main/java/org/apache/tika/detect/CompositeDetector.java b/tika-core/src/main/java/org/apache/tika/detect/CompositeDetector.java
index 99ca74a8b..027b6f4c6 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/CompositeDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/CompositeDetector.java
@@ -28,6 +28,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MediaTypeRegistry;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.utils.StringUtils;
 
 /**
@@ -71,7 +72,8 @@ public class CompositeDetector implements Detector {
         this(Arrays.asList(detectors));
     }
 
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         MediaType override = detectOverrides(metadata);
         if (override != null) {
             return override;
@@ -81,7 +83,7 @@ public class CompositeDetector implements Detector {
         //we have to iterate through all detectors because the override detector may
         //be within a CompositeDetector
         for (Detector detector : getDetectors()) {
-            MediaType detected = detector.detect(tis, metadata);
+            MediaType detected = detector.detect(tis, metadata, parseContext);
             if (registry.isSpecializationOf(detected, type)) {
                 type = detected;
             }
diff --git a/tika-core/src/main/java/org/apache/tika/detect/CompositeEncodingDetector.java b/tika-core/src/main/java/org/apache/tika/detect/CompositeEncodingDetector.java
index eaf1abfd0..e5c6152e6 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/CompositeEncodingDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/CompositeEncodingDetector.java
@@ -27,6 +27,7 @@ import java.util.List;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 public class CompositeEncodingDetector implements EncodingDetector, Serializable {
 
@@ -61,9 +62,9 @@ public class CompositeEncodingDetector implements EncodingDetector, Serializable
      * @throws IOException
      */
     @Override
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         for (EncodingDetector detector : getDetectors()) {
-            Charset detected = detector.detect(tis, metadata);
+            Charset detected = detector.detect(tis, metadata, parseContext);
             if (detected != null) {
                 metadata.set(TikaCoreProperties.DETECTED_ENCODING, detected.name());
                 //if this has been set by a leaf detector, do not overwrite
diff --git a/tika-core/src/main/java/org/apache/tika/detect/Detector.java b/tika-core/src/main/java/org/apache/tika/detect/Detector.java
index 991efe9d8..1ed49b7c4 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/Detector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/Detector.java
@@ -23,6 +23,7 @@ import org.apache.tika.config.SelfConfiguring;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Content type detector. Implementations of this interface use various
@@ -49,9 +50,11 @@ public interface Detector extends Serializable, SelfConfiguring {
      *
      * @param tis      document input stream, or <code>null</code>
      * @param metadata input metadata for the document
+     * @param parseContext the parse context
      * @return detected media type, or <code>application/octet-stream</code>
      * @throws IOException if the document input stream could not be read
      */
-    MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException;
+    MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException;
 
 }
diff --git a/tika-core/src/main/java/org/apache/tika/detect/EmptyDetector.java b/tika-core/src/main/java/org/apache/tika/detect/EmptyDetector.java
index 06504900e..f84c854d0 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/EmptyDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/EmptyDetector.java
@@ -22,6 +22,7 @@ import org.apache.tika.config.TikaComponent;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Dummy detector that returns application/octet-stream for all documents.
@@ -34,7 +35,8 @@ public class EmptyDetector implements Detector {
      */
     public static final EmptyDetector INSTANCE = new EmptyDetector();
 
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         return MediaType.OCTET_STREAM;
     }
 
diff --git a/tika-core/src/main/java/org/apache/tika/detect/EncodingDetector.java b/tika-core/src/main/java/org/apache/tika/detect/EncodingDetector.java
index 7e99648e3..9d4587907 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/EncodingDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/EncodingDetector.java
@@ -23,6 +23,7 @@ import java.nio.charset.Charset;
 import org.apache.tika.config.SelfConfiguring;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Character encoding detector. Implementations of this interface use
@@ -51,9 +52,11 @@ public interface EncodingDetector extends Serializable, SelfConfiguring {
      *
      * @param tis      text document input stream, or <code>null</code>
      * @param metadata input metadata for the document
+     * @param parseContext the parse context
      * @return detected character encoding, or <code>null</code>
      * @throws IOException if the document input stream could not be read
      */
-    Charset detect(TikaInputStream tis, Metadata metadata) throws IOException;
+    Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException;
 
 }
diff --git a/tika-core/src/main/java/org/apache/tika/detect/FileCommandDetector.java b/tika-core/src/main/java/org/apache/tika/detect/FileCommandDetector.java
index e9aedf4c0..83182eafc 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/FileCommandDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/FileCommandDetector.java
@@ -28,6 +28,7 @@ import org.apache.tika.metadata.ExternalProcess;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.Property;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.external.ExternalParser;
 import org.apache.tika.utils.FileProcessResult;
 import org.apache.tika.utils.ProcessUtils;
@@ -79,11 +80,12 @@ public class FileCommandDetector implements Detector {
     /**
      * @param tis      document input stream, or <code>null</code>
      * @param metadata input metadata for the document
+     * @param parseContext the parse context
      * @return mime as identified by the file command or application/octet-stream otherwise
      * @throws IOException
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (hasFileCommand == null) {
             hasFileCommand = checkHasFile(this.fileCommandPath);
         }
diff --git a/tika-core/src/main/java/org/apache/tika/detect/MagicDetector.java b/tika-core/src/main/java/org/apache/tika/detect/MagicDetector.java
index e75840b03..a933ace78 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/MagicDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/MagicDetector.java
@@ -32,6 +32,7 @@ import org.apache.tika.config.TikaComponent;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Content type detection based on magic bytes, i.e. type-specific patterns
@@ -338,8 +339,10 @@ public class MagicDetector implements Detector {
     /**
      * @param tis      document input stream, or <code>null</code>
      * @param metadata ignored
+     * @param parseContext the parse context
      */
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         if (tis == null) {
             return MediaType.OCTET_STREAM;
         }
@@ -375,46 +378,14 @@ public class MagicDetector implements Detector {
                 }
             }
 
-            if (this.isRegex) {
-                int flags = 0;
-                if (this.isStringIgnoreCase) {
-                    flags = Pattern.CASE_INSENSITIVE;
-                }
-
-                Pattern p = Pattern.compile(new String(this.pattern, UTF_8), flags);
-
-                ByteBuffer bb = ByteBuffer.wrap(buffer);
-                CharBuffer result = ISO_8859_1.decode(bb);
-                Matcher m = p.matcher(result);
+            // For non-regex, verify we have enough data
+            if (!isRegex && offset < offsetRangeBegin + length) {
+                return MediaType.OCTET_STREAM;
+            }
 
-                boolean match = false;
-                // Loop until we've covered the entire offset range
-                for (int i = 0; i <= offsetRangeEnd - offsetRangeBegin; i++) {
-                    m.region(i, length + i);
-                    match = m.lookingAt(); // match regex from start of region
-                    if (match) {
-                        return type;
-                    }
-                }
-            } else {
-                if (offset < offsetRangeBegin + length) {
-                    return MediaType.OCTET_STREAM;
-                }
-                // Loop until we've covered the entire offset range
-                for (int i = 0; i <= offsetRangeEnd - offsetRangeBegin; i++) {
-                    boolean match = true;
-                    int masked;
-                    for (int j = 0; match && j < length; j++) {
-                        masked = (buffer[i + j] & mask[j]);
-                        if (this.isStringIgnoreCase) {
-                            masked = Character.toLowerCase(masked);
-                        }
-                        match = (masked == pattern[j]);
-                    }
-                    if (match) {
-                        return type;
-                    }
-                }
+            // Buffer starts at offsetRangeBegin, so search from 0 to (offsetRangeEnd - offsetRangeBegin)
+            if (matchesBuffer(buffer, 0, offsetRangeEnd - offsetRangeBegin)) {
+                return type;
             }
 
             return MediaType.OCTET_STREAM;
@@ -427,6 +398,102 @@ public class MagicDetector implements Detector {
         return this.patternLength;
     }
 
+    /**
+     * Checks if the given byte array matches this magic pattern.
+     * This is a more efficient alternative to {@link #detect(TikaInputStream, Metadata, ParseContext)}
+     * when you already have the bytes in memory.
+     *
+     * @param data the byte array to check
+     * @return true if the data matches this magic pattern, false otherwise
+     */
+    public boolean matches(byte[] data) {
+        if (data == null) {
+            return false;
+        }
+
+        // For non-regex, we need at least patternLength bytes starting at offsetRangeBegin.
+        // For regex, we can match with less data since the pattern may be shorter than the buffer.
+        if (!isRegex) {
+            int requiredLength = offsetRangeBegin + length;
+            if (data.length < requiredLength) {
+                return false;
+            }
+            // For non-regex, we need enough data after the start position for the pattern
+            int maxOffset = Math.min(offsetRangeEnd, data.length - length);
+            return matchesBuffer(data, offsetRangeBegin, maxOffset);
+        } else {
+            // For regex, just need data to reach offsetRangeBegin
+            if (data.length <= offsetRangeBegin) {
+                return false;
+            }
+            // For regex, try all positions up to min(offsetRangeEnd, data.length - 1)
+            // The regex pattern can match even at the last byte position
+            int maxOffset = Math.min(offsetRangeEnd, data.length - 1);
+            return matchesBuffer(data, offsetRangeBegin, maxOffset);
+        }
+    }
+
+    /**
+     * Core matching logic that checks if the pattern matches anywhere in the buffer
+     * within the specified offset range.
+     *
+     * @param buffer the byte array to search in
+     * @param startOffset the first position in the buffer to start matching (inclusive)
+     * @param endOffset the last position in the buffer to start matching (inclusive)
+     * @return true if a match is found, false otherwise
+     */
+    private boolean matchesBuffer(byte[] buffer, int startOffset, int endOffset) {
+        if (this.isRegex) {
+            int flags = 0;
+            if (this.isStringIgnoreCase) {
+                flags = Pattern.CASE_INSENSITIVE;
+            }
+
+            Pattern p = Pattern.compile(new String(this.pattern, UTF_8), flags);
+
+            int bufferLen = Math.min(buffer.length - startOffset, length + (endOffset - startOffset));
+            if (bufferLen <= 0) {
+                return false;
+            }
+            ByteBuffer bb = ByteBuffer.wrap(buffer, startOffset, bufferLen);
+            CharBuffer result = ISO_8859_1.decode(bb);
+            Matcher m = p.matcher(result);
+
+            // Loop until we've covered the entire offset range
+            for (int i = 0; i <= endOffset - startOffset; i++) {
+                // For regex, use available data length, not the fixed 8KB buffer size
+                int regionEnd = Math.min(length + i, result.length());
+                if (i < regionEnd) {
+                    m.region(i, regionEnd);
+                    if (m.lookingAt()) {
+                        return true;
+                    }
+                }
+            }
+        } else {
+            // Loop until we've covered the entire offset range
+            for (int i = startOffset; i <= endOffset; i++) {
+                if (i + length > buffer.length) {
+                    break;
+                }
+                boolean match = true;
+                int masked;
+                for (int j = 0; match && j < length; j++) {
+                    masked = (buffer[i + j] & mask[j]);
+                    if (this.isStringIgnoreCase) {
+                        masked = Character.toLowerCase(masked);
+                    }
+                    match = (masked == pattern[j]);
+                }
+                if (match) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Returns a string representation of the Detection Rule.
      * Should sort nicely by type and details, as we sometimes
diff --git a/tika-core/src/main/java/org/apache/tika/detect/NameDetector.java b/tika-core/src/main/java/org/apache/tika/detect/NameDetector.java
index e394f01ae..c6df71078 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/NameDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/NameDetector.java
@@ -27,6 +27,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Content type detection based on the resource name. An instance of this
@@ -92,9 +93,10 @@ public class NameDetector implements Detector {
      *
      * @param tis      ignored
      * @param metadata input metadata, possibly with a RESOURCE_NAME_KEY value
+     * @param parseContext the parse context
      * @return detected media type, or <code>application/octet-stream</code>
      */
-    public MediaType detect(TikaInputStream tis, Metadata metadata) {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) {
         // Look for a resource name in the input metadata
         String name = metadata.get(TikaCoreProperties.RESOURCE_NAME_KEY);
         if (name != null) {
diff --git a/tika-core/src/main/java/org/apache/tika/detect/OverrideDetector.java b/tika-core/src/main/java/org/apache/tika/detect/OverrideDetector.java
index 7bd6dfc27..2cfdb0567 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/OverrideDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/OverrideDetector.java
@@ -22,6 +22,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Use this to force a content type detection via the
@@ -36,7 +37,8 @@ import org.apache.tika.mime.MediaType;
 public class OverrideDetector implements Detector {
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         String type = metadata.get(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE);
         if (type != null) {
             return MediaType.parse(type);
diff --git a/tika-core/src/main/java/org/apache/tika/detect/OverrideEncodingDetector.java b/tika-core/src/main/java/org/apache/tika/detect/OverrideEncodingDetector.java
index 3565ebe8a..778198e54 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/OverrideEncodingDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/OverrideEncodingDetector.java
@@ -25,6 +25,7 @@ import org.apache.tika.config.JsonConfig;
 import org.apache.tika.config.TikaComponent;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Always returns the charset passed in via the initializer
@@ -81,7 +82,7 @@ public class OverrideEncodingDetector implements EncodingDetector {
     }
 
     @Override
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         return charset;
     }
 
diff --git a/tika-core/src/main/java/org/apache/tika/detect/TextDetector.java b/tika-core/src/main/java/org/apache/tika/detect/TextDetector.java
index 4392d0059..ce987db95 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/TextDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/TextDetector.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Content type detection of plain text documents. This detector looks at the
@@ -107,10 +108,11 @@ public class TextDetector implements Detector {
      *
      * @param tis      document input stream, or <code>null</code>
      * @param metadata ignored
+     * @param context the parse context
      * @return "text/plain" if the input stream suggest a text document,
      * "application/octet-stream" otherwise
      */
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext context) throws IOException {
         if (tis == null) {
             return MediaType.OCTET_STREAM;
         }
diff --git a/tika-core/src/main/java/org/apache/tika/detect/TrainedModelDetector.java b/tika-core/src/main/java/org/apache/tika/detect/TrainedModelDetector.java
index f1d88968d..a73ec8e65 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/TrainedModelDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/TrainedModelDetector.java
@@ -35,6 +35,7 @@ import org.apache.tika.io.TemporaryResources;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public abstract class TrainedModelDetector implements Detector {
     private static final long serialVersionUID = 1L;
@@ -48,7 +49,8 @@ public abstract class TrainedModelDetector implements Detector {
         return Integer.MAX_VALUE;
     }
 
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         // convert to byte-histogram
         if (tis != null) {
             tis.mark(getMinLength());
diff --git a/tika-core/src/main/java/org/apache/tika/detect/TypeDetector.java b/tika-core/src/main/java/org/apache/tika/detect/TypeDetector.java
index aa8d7e719..c443eaab3 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/TypeDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/TypeDetector.java
@@ -19,6 +19,7 @@ package org.apache.tika.detect;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Content type detection based on a content type hint. This detector simply
@@ -38,9 +39,11 @@ public class TypeDetector implements Detector {
      *
      * @param tis      ignored
      * @param metadata input metadata, possibly with a CONTENT_TYPE value
+     * @param context the parse context
      * @return detected media type, or <code>application/octet-stream</code>
      */
-    public MediaType detect(TikaInputStream tis, Metadata metadata) {
+    @Override
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext context) {
         // Look for a type hint in the input metadata
         String hint = metadata.get(Metadata.CONTENT_TYPE);
         if (hint != null) {
diff --git a/tika-core/src/main/java/org/apache/tika/detect/ZeroSizeFileDetector.java b/tika-core/src/main/java/org/apache/tika/detect/ZeroSizeFileDetector.java
index 11d6701a2..08cafc6e9 100644
--- a/tika-core/src/main/java/org/apache/tika/detect/ZeroSizeFileDetector.java
+++ b/tika-core/src/main/java/org/apache/tika/detect/ZeroSizeFileDetector.java
@@ -21,12 +21,15 @@ import java.io.IOException;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Detector to identify zero length files as application/x-zerovalue
  */
 public class ZeroSizeFileDetector implements Detector {
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    @Override
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         if (tis != null) {
             try {
                 tis.mark(1);
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/ContainerExtractor.java b/tika-core/src/main/java/org/apache/tika/extractor/ContainerExtractor.java
index cfc70b5f3..a0e435dd7 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/ContainerExtractor.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/ContainerExtractor.java
@@ -21,6 +21,7 @@ import java.io.Serializable;
 
 import org.apache.tika.exception.TikaException;
 import org.apache.tika.io.TikaInputStream;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Tika container extractor interface.
@@ -32,9 +33,11 @@ public interface ContainerExtractor extends Serializable {
      * Is this Container Extractor able to process the
      * supplied container?
      *
+     * @param input the input stream
+     * @param parseContext the parse context
      * @since Apache Tika 0.8
      */
-    boolean isSupported(TikaInputStream input) throws IOException;
+    boolean isSupported(TikaInputStream input, ParseContext parseContext) throws IOException;
 
     /**
      * Processes a container file, and extracts all the embedded
@@ -55,10 +58,12 @@ public interface ContainerExtractor extends Serializable {
      * @param stream           the document stream (input)
      * @param recurseExtractor the extractor to use on any embedded containers
      * @param handler          handler for the embedded files (output)
+     * @param parseContext     the parse context
      * @throws IOException   if the document stream could not be read
      * @throws TikaException if the container could not be parsed
      * @since Apache Tika 0.8
      */
     void extract(TikaInputStream stream, ContainerExtractor recurseExtractor,
-                 EmbeddedResourceHandler handler) throws IOException, TikaException;
+            EmbeddedResourceHandler handler, ParseContext parseContext)
+            throws IOException, TikaException;
 }
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentExtractor.java b/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentExtractor.java
index 51abe6b9c..46d16919b 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentExtractor.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentExtractor.java
@@ -23,21 +23,23 @@ import org.xml.sax.SAXException;
 
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 public interface EmbeddedDocumentExtractor {
     boolean shouldParseEmbedded(Metadata metadata);
 
     /**
      * Processes the supplied embedded resource, calling the delegating
-     *  parser with the appropriate details.
-     * @param stream The embedded resource
-     * @param handler The handler to use
-     * @param metadata The metadata for the embedded resource
-     * @param outputHtml Should we output HTML for this resource, or has the parser already done so?
+     * parser with the appropriate details.
+     *
+     * @param stream       The embedded resource
+     * @param handler      The handler to use
+     * @param metadata     The metadata for the embedded resource
+     * @param parseContext The parse context
+     * @param outputHtml   Should we output HTML for this resource, or has the parser already done so?
      * @throws org.xml.sax.SAXException
      * @throws java.io.IOException
      */
-    void parseEmbedded(
-            TikaInputStream stream, ContentHandler handler, Metadata metadata, boolean outputHtml)
-            throws SAXException, IOException;
+    void parseEmbedded(TikaInputStream stream, ContentHandler handler, Metadata metadata, ParseContext parseContext,
+                       boolean outputHtml) throws SAXException, IOException;
 }
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentUtil.java b/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentUtil.java
index db1d0370d..741a14f58 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentUtil.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedDocumentUtil.java
@@ -159,7 +159,7 @@ public class EmbeddedDocumentUtil implements Serializable {
         }
         if (mimeType == null) {
             try {
-                MediaType mediaType = getDetector().detect(is, metadata);
+                MediaType mediaType = getDetector().detect(is, metadata, context);
                 mimeType = localMimeTypes.forName(mediaType.toString());
                 detected = true;
                 is.reset();
@@ -197,7 +197,7 @@ public class EmbeddedDocumentUtil implements Serializable {
 
     public void parseEmbedded(TikaInputStream tis, ContentHandler handler, Metadata metadata,
                               boolean outputHtml) throws IOException, SAXException {
-        embeddedDocumentExtractor.parseEmbedded(tis, handler, metadata, outputHtml);
+        embeddedDocumentExtractor.parseEmbedded(tis, handler, metadata, context, outputHtml);
     }
 
     /**
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedResourceHandler.java b/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedResourceHandler.java
index 23d00635d..10d1189e0 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedResourceHandler.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/EmbeddedResourceHandler.java
@@ -16,9 +16,9 @@
  */
 package org.apache.tika.extractor;
 
-import java.io.InputStream;
-
+import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Tika container extractor callback interface.
@@ -31,11 +31,13 @@ public interface EmbeddedResourceHandler {
      * This will be called once per embedded resource within the
      *  container, along with whatever details are available on
      *  the embedded resource.
-     *  
+     *
      * @since Apache Tika 0.8
      * @param filename The filename of the embedded resource, if known
      * @param mediaType The media type of the embedded resource, if known
      * @param stream The contents of the embedded resource
+     * @param parseContext The parse context
      */
-    void handle(String filename, MediaType mediaType, InputStream stream);
+    void handle(String filename, MediaType mediaType, TikaInputStream stream,
+            ParseContext parseContext);
 }
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/ParserContainerExtractor.java b/tika-core/src/main/java/org/apache/tika/extractor/ParserContainerExtractor.java
index 9e8f74c78..81f16824c 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/ParserContainerExtractor.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/ParserContainerExtractor.java
@@ -62,20 +62,19 @@ public class ParserContainerExtractor implements ContainerExtractor {
     }
 
     @Override
-    public boolean isSupported(TikaInputStream input) throws IOException {
-        MediaType type = detector.detect(input, new Metadata());
-        return parser.getSupportedTypes(new ParseContext()).contains(type);
+    public boolean isSupported(TikaInputStream input, ParseContext parseContext) throws IOException {
+        MediaType type = detector.detect(input, new Metadata(), parseContext);
+        return parser.getSupportedTypes(parseContext).contains(type);
     }
 
     @Override
     public void extract(
             TikaInputStream stream, ContainerExtractor recurseExtractor,
-            EmbeddedResourceHandler handler)
+            EmbeddedResourceHandler handler, ParseContext parseContext)
             throws IOException, TikaException {
-        ParseContext context = new ParseContext();
-        context.set(Parser.class, new RecursiveParser(parser, recurseExtractor, handler));
+        parseContext.set(Parser.class, new RecursiveParser(parser, recurseExtractor, handler, parseContext));
         try {
-            parser.parse(stream, new DefaultHandler(), new Metadata(), context);
+            parser.parse(stream, new DefaultHandler(), new Metadata(), parseContext);
         } catch (SAXException e) {
             throw new TikaException("Unexpected SAX exception", e);
         }
@@ -87,12 +86,16 @@ public class ParserContainerExtractor implements ContainerExtractor {
 
         private final EmbeddedResourceHandler handler;
 
+        private final ParseContext parseContext;
+
         private RecursiveParser(Parser statelessParser,
                 ContainerExtractor extractor,
-                EmbeddedResourceHandler handler) {
+                EmbeddedResourceHandler handler,
+                ParseContext parseContext) {
             super(statelessParser);
             this.extractor = extractor;
             this.handler = handler;
+            this.parseContext = parseContext;
         }
 
         @Override
@@ -107,22 +110,22 @@ public class ParserContainerExtractor implements ContainerExtractor {
                 throws IOException, SAXException, TikaException {
             // Figure out what we have to process
             String filename = metadata.get(TikaCoreProperties.RESOURCE_NAME_KEY);
-            MediaType type = detector.detect(stream, metadata);
+            MediaType type = detector.detect(stream, metadata, parseContext);
 
             if (extractor == null) {
                 // Let the handler process the embedded resource
-                handler.handle(filename, type, stream);
+                handler.handle(filename, type, stream, parseContext);
             } else {
                 // Use a temporary file to process the stream twice
                 File file = stream.getFile();
 
                 // Let the handler process the embedded resource
                 try (TikaInputStream tis = TikaInputStream.get(file.toPath())) {
-                    handler.handle(filename, type, tis);
+                    handler.handle(filename, type, tis, parseContext);
                 }
 
                 // Recurse
-                extractor.extract(stream, extractor, handler);
+                extractor.extract(stream, extractor, handler, parseContext);
             }
         }
 
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/ParsingEmbeddedDocumentExtractor.java b/tika-core/src/main/java/org/apache/tika/extractor/ParsingEmbeddedDocumentExtractor.java
index 21117b33b..b6112cf09 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/ParsingEmbeddedDocumentExtractor.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/ParsingEmbeddedDocumentExtractor.java
@@ -79,7 +79,7 @@ public class ParsingEmbeddedDocumentExtractor implements EmbeddedDocumentExtract
 
     @Override
     public void parseEmbedded(
-            TikaInputStream tis, ContentHandler handler, Metadata metadata, boolean outputHtml)
+            TikaInputStream tis, ContentHandler handler, Metadata metadata, ParseContext parseContext, boolean outputHtml)
             throws SAXException, IOException {
         if (outputHtml) {
             AttributesImpl attributes = new AttributesImpl();
diff --git a/tika-core/src/main/java/org/apache/tika/extractor/RUnpackExtractor.java b/tika-core/src/main/java/org/apache/tika/extractor/RUnpackExtractor.java
index 851f24d90..8c5074843 100644
--- a/tika-core/src/main/java/org/apache/tika/extractor/RUnpackExtractor.java
+++ b/tika-core/src/main/java/org/apache/tika/extractor/RUnpackExtractor.java
@@ -68,7 +68,7 @@ public class RUnpackExtractor extends ParsingEmbeddedDocumentExtractor {
 
     @Override
     public void parseEmbedded(
-            TikaInputStream tis, ContentHandler handler, Metadata metadata, boolean outputHtml)
+            TikaInputStream tis, ContentHandler handler, Metadata metadata, ParseContext parseContext, boolean outputHtml)
             throws SAXException, IOException {
         if (outputHtml) {
             AttributesImpl attributes = new AttributesImpl();
diff --git a/tika-core/src/main/java/org/apache/tika/mime/MagicMatch.java b/tika-core/src/main/java/org/apache/tika/mime/MagicMatch.java
index 152c95a71..835d4b90c 100644
--- a/tika-core/src/main/java/org/apache/tika/mime/MagicMatch.java
+++ b/tika-core/src/main/java/org/apache/tika/mime/MagicMatch.java
@@ -16,11 +16,7 @@
  */
 package org.apache.tika.mime;
 
-import java.io.IOException;
-
 import org.apache.tika.detect.MagicDetector;
-import org.apache.tika.io.TikaInputStream;
-import org.apache.tika.metadata.Metadata;
 
 /**
  * Defines a magic match.
@@ -55,13 +51,7 @@ class MagicMatch implements Clause {
     }
 
     public boolean eval(byte[] data) {
-        try (TikaInputStream tis = TikaInputStream.get(data)) {
-            return getDetector().detect(tis, new Metadata()) !=
-                    MediaType.OCTET_STREAM;
-        } catch (IOException e) {
-            // Should never happen with a ByteArrayInputStream
-            return false;
-        }
+        return getDetector().matches(data);
     }
 
     public int size() {
diff --git a/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java b/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java
index 70f565065..55d33bfb6 100644
--- a/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java
+++ b/tika-core/src/main/java/org/apache/tika/mime/MimeTypes.java
@@ -40,6 +40,7 @@ import org.apache.tika.detect.XmlRootExtractor;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * This class is a MimeType repository. It gathers a set of MimeTypes and
@@ -294,7 +295,7 @@ public final class MimeTypes implements Detector, Serializable {
         try {
             TextDetector detector = new TextDetector(getMinLength());
             try (TikaInputStream tis = TikaInputStream.get(data)) {
-                MimeType type = forName(detector.detect(tis, new Metadata()).toString());
+                MimeType type = forName(detector.detect(tis, new Metadata(), new ParseContext()).toString());
                 return Collections.singletonList(type);
             }
         } catch (Exception e) {
@@ -517,7 +518,8 @@ public final class MimeTypes implements Detector, Serializable {
      * @throws IOException if the document stream could not be read
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         List<MimeType> possibleTypes = null;
 
         // Get type based on magic prefix
diff --git a/tika-core/src/main/java/org/apache/tika/mime/ProbabilisticMimeDetectionSelector.java b/tika-core/src/main/java/org/apache/tika/mime/ProbabilisticMimeDetectionSelector.java
index b54b61a0f..dbe63a4e2 100644
--- a/tika-core/src/main/java/org/apache/tika/mime/ProbabilisticMimeDetectionSelector.java
+++ b/tika-core/src/main/java/org/apache/tika/mime/ProbabilisticMimeDetectionSelector.java
@@ -26,6 +26,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Selector for combining different mime detection results
@@ -121,7 +122,8 @@ public class ProbabilisticMimeDetectionSelector implements Detector {
         threshold = 0.5001f;
     }
 
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
 
         List<MimeType> possibleTypes = new ArrayList<>();
 
diff --git a/tika-core/src/main/java/org/apache/tika/parser/AutoDetectParser.java b/tika-core/src/main/java/org/apache/tika/parser/AutoDetectParser.java
index 3c5cd236f..da423e8e1 100644
--- a/tika-core/src/main/java/org/apache/tika/parser/AutoDetectParser.java
+++ b/tika-core/src/main/java/org/apache/tika/parser/AutoDetectParser.java
@@ -161,7 +161,7 @@ public class AutoDetectParser extends CompositeParser {
                 metadata, context);
 
         // Automatically detect the MIME type of the document
-        MediaType type = detector.detect(tis, metadata);
+        MediaType type = detector.detect(tis, metadata, context);
         //update CONTENT_TYPE as long as it wasn't set by parser override
         if (metadata.get(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE) == null ||
                 !metadata.get(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE)
diff --git a/tika-core/src/test/java/org/apache/custom/detect/MyCustomDetector.java b/tika-core/src/test/java/org/apache/custom/detect/MyCustomDetector.java
index 603cec592..655f66111 100644
--- a/tika-core/src/test/java/org/apache/custom/detect/MyCustomDetector.java
+++ b/tika-core/src/test/java/org/apache/custom/detect/MyCustomDetector.java
@@ -22,10 +22,11 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class MyCustomDetector implements Detector {
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         return MediaType.OCTET_STREAM;
     }
 }
diff --git a/tika-core/src/test/java/org/apache/tika/MultiThreadedTikaTest.java b/tika-core/src/test/java/org/apache/tika/MultiThreadedTikaTest.java
index c36d8b56c..289dc6ddf 100644
--- a/tika-core/src/test/java/org/apache/tika/MultiThreadedTikaTest.java
+++ b/tika-core/src/test/java/org/apache/tika/MultiThreadedTikaTest.java
@@ -87,8 +87,8 @@ public class MultiThreadedTikaTest extends TikaTest {
         for (Path f : files) {
             Metadata metadata = new Metadata();
             try (TikaInputStream tis = TikaInputStream.get(f, metadata)) {
-                baseline.put(f, detector.detect(tis, metadata));
-                baseline.put(f, detector.detect(tis, metadata));
+                baseline.put(f, detector.detect(tis, metadata, new ParseContext()));
+                baseline.put(f, detector.detect(tis, metadata, new ParseContext()));
             } catch (IOException e) {
                 e.printStackTrace();
             }
@@ -423,7 +423,7 @@ public class MultiThreadedTikaTest extends TikaTest {
                 Path testFile = files[randIndex];
                 Metadata metadata = new Metadata();
                 try (TikaInputStream tis = TikaInputStream.get(testFile, metadata)) {
-                    MediaType mediaType = detector.detect(tis, metadata);
+                    MediaType mediaType = detector.detect(tis, metadata, new ParseContext());
                     assertEquals(truth.get(testFile), mediaType,
                             "failed on: " + testFile.getFileName());
                 }
diff --git a/tika-core/src/test/java/org/apache/tika/TikaTest.java b/tika-core/src/test/java/org/apache/tika/TikaTest.java
index 9749272bc..87971c99b 100644
--- a/tika-core/src/test/java/org/apache/tika/TikaTest.java
+++ b/tika-core/src/test/java/org/apache/tika/TikaTest.java
@@ -26,7 +26,6 @@ import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -656,7 +655,8 @@ public abstract class TikaTest {
         }
 
         @Override
-        public void handle(String filename, MediaType mediaType, InputStream stream) {
+        public void handle(String filename, MediaType mediaType, TikaInputStream stream,
+                           ParseContext parseContext) {
             if (skipTypes.contains(mediaType)) {
                 return;
             }
@@ -673,11 +673,9 @@ public abstract class TikaTest {
         public List<byte[]> bytes = new ArrayList<>();
 
         @Override
-        public void handle(String filename, MediaType mediaType, InputStream stream) {
+        public void handle(String filename, MediaType mediaType, TikaInputStream stream,
+                           ParseContext parseContext) {
             ByteArrayOutputStream os = new ByteArrayOutputStream();
-            if (!stream.markSupported()) {
-                stream = TikaInputStream.get(stream);
-            }
             stream.mark(0);
             try {
                 IOUtils.copy(stream, os);
diff --git a/tika-core/src/test/java/org/apache/tika/detect/FileCommandDetectorTest.java b/tika-core/src/test/java/org/apache/tika/detect/FileCommandDetectorTest.java
index f3c976403..5f7e5362d 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/FileCommandDetectorTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/FileCommandDetectorTest.java
@@ -28,6 +28,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MimeTypes;
+import org.apache.tika.parser.ParseContext;
 
 public class FileCommandDetectorTest extends TikaTest {
 
@@ -46,11 +47,12 @@ public class FileCommandDetectorTest extends TikaTest {
                 MimeTypes.getDefaultMimeTypes().getMediaTypeRegistry(),
                 Arrays.asList(fileDetector, defaultDetector));
 
-        try (TikaInputStream tis = getResourceAsStream(TEST_FILE)) {
+        try (TikaInputStream tis = TikaInputStream.get(getClass()
+                .getResourceAsStream(TEST_FILE))) {
             //run more than once to ensure that the input stream is reset
             for (int i = 0; i < 2; i++) {
                 Metadata metadata = new Metadata();
-                MediaType answer = detector.detect(tis, metadata);
+                MediaType answer = detector.detect(tis, metadata, new ParseContext());
                 String fileMime = metadata.get(FileCommandDetector.FILE_MIME);
                 assertTrue(MediaType.text("xml").equals(answer) ||
                         MediaType.application("xml").equals(answer),
@@ -62,10 +64,11 @@ public class FileCommandDetectorTest extends TikaTest {
         }
 
         //now try with TikaInputStream
-        try (TikaInputStream tis = getResourceAsStream(TEST_FILE)) {
+        try (TikaInputStream tis = TikaInputStream
+                .get(getClass().getResourceAsStream(TEST_FILE))) {
             //run more than once to ensure that the input stream is reset
             for (int i = 0; i < 2; i++) {
-                MediaType answer = detector.detect(tis, new Metadata());
+                MediaType answer = detector.detect(tis, new Metadata(), new ParseContext());
                 assertTrue(MediaType.text("xml").equals(answer) ||
                         MediaType.application("xml").equals(answer),
                         "Expected text/xml or application/xml but got: " + answer);
diff --git a/tika-core/src/test/java/org/apache/tika/detect/MagicDetectorTest.java b/tika-core/src/test/java/org/apache/tika/detect/MagicDetectorTest.java
index 61a87ae0a..402392306 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/MagicDetectorTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/MagicDetectorTest.java
@@ -33,6 +33,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Test cases for the {@link MagicDetector} class.
@@ -43,7 +44,7 @@ public class MagicDetectorTest extends TikaTest {
     public void testDetectNull() throws Exception {
         MediaType html = new MediaType("text", "html");
         Detector detector = new MagicDetector(html, "<html".getBytes(US_ASCII));
-        assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata()));
+        assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata(), new ParseContext()));
     }
 
     @Test
@@ -166,7 +167,7 @@ public class MagicDetectorTest extends TikaTest {
         // Deliberately prevent InputStream.read(...) from reading the entire
         // buffer in one go
         try (TikaInputStream tis = TikaInputStream.get(new RestrictiveInputStream(data))) {
-            assertEquals(testMT, detector.detect(tis, new Metadata()));
+            assertEquals(testMT, detector.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -179,7 +180,7 @@ public class MagicDetectorTest extends TikaTest {
         // Deliberately prevent InputStream.read(...) from reading the entire
         // buffer in one go
         try (TikaInputStream tis = TikaInputStream.get(new RestrictiveInputStream(data))) {
-            assertEquals(testMT, detector.detect(tis, new Metadata()));
+            assertEquals(testMT, detector.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -214,7 +215,7 @@ public class MagicDetectorTest extends TikaTest {
     private void assertDetect(Detector detector, MediaType type, byte[] bytes) {
         try {
             TikaInputStream tis = TikaInputStream.get(bytes);
-            assertEquals(type, detector.detect(tis, new Metadata()));
+            assertEquals(type, detector.detect(tis, new Metadata(), new ParseContext()));
 
             // Test that the stream has been reset
             for (byte aByte : bytes) {
@@ -261,7 +262,7 @@ public class MagicDetectorTest extends TikaTest {
 
     private String detect(Detector detector, String bz2Name) throws IOException  {
         try (TikaInputStream tis = getResourceAsStream("/test-documents/bz2/" + bz2Name)) {
-            return detector.detect(tis, new Metadata()).toString();
+            return detector.detect(tis, new Metadata(), new ParseContext()).toString();
         }
     }
 }
diff --git a/tika-core/src/test/java/org/apache/tika/detect/MimeDetectionWithNNTest.java b/tika-core/src/test/java/org/apache/tika/detect/MimeDetectionWithNNTest.java
index d65cc9863..665fd6239 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/MimeDetectionWithNNTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/MimeDetectionWithNNTest.java
@@ -28,6 +28,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class MimeDetectionWithNNTest extends TikaTest {
 
@@ -103,13 +104,13 @@ public class MimeDetectionWithNNTest extends TikaTest {
         assertNotNull(in, "Test stream: [" + urlOrFileName + "] is null!");
         try {
             Metadata metadata = new Metadata();
-            String mime = this.detector.detect(in, metadata).toString();
+            String mime = this.detector.detect(in, metadata, new ParseContext()).toString();
             assertEquals(expected, mime,
                     urlOrFileName + " is not properly detected: detected.");
 
             // Add resource name and test again
             // metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, urlOrFileName);
-            mime = this.detector.detect(in, metadata).toString();
+            mime = this.detector.detect(in, metadata, new ParseContext()).toString();
             assertEquals(expected, mime,
                     urlOrFileName + " is not properly detected after adding resource name.");
         } finally {
@@ -124,7 +125,7 @@ public class MimeDetectionWithNNTest extends TikaTest {
     public void testEmptyDocument() throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.OCTET_STREAM,
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
         }
 
     }
diff --git a/tika-core/src/test/java/org/apache/tika/detect/NameDetectorTest.java b/tika-core/src/test/java/org/apache/tika/detect/NameDetectorTest.java
index dc15299af..0a38936ac 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/NameDetectorTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/NameDetectorTest.java
@@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Test cases for the {@link NameDetector} class.
@@ -90,7 +91,7 @@ public class NameDetectorTest {
         assertDetect(MediaType.OCTET_STREAM, "");
         assertDetect(MediaType.OCTET_STREAM, null);
         try {
-            assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata()));
+            assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata(), new ParseContext()));
         } catch (IOException e) {
             fail("NameDetector should never throw an IOException");
         }
@@ -100,7 +101,7 @@ public class NameDetectorTest {
         Metadata metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, name);
         try {
-            assertEquals(type, detector.detect(null, metadata));
+            assertEquals(type, detector.detect(null, metadata, new ParseContext()));
         } catch (IOException e) {
             fail("NameDetector should never throw an IOException");
         }
diff --git a/tika-core/src/test/java/org/apache/tika/detect/TextDetectorTest.java b/tika-core/src/test/java/org/apache/tika/detect/TextDetectorTest.java
index 1b804d820..c7fe2435b 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/TextDetectorTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/TextDetectorTest.java
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Test cases for the {@link TextDetector} class.
@@ -38,7 +39,7 @@ public class TextDetectorTest {
 
     @Test
     public void testDetectNull() throws Exception {
-        assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata()));
+        assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata(), new ParseContext()));
     }
 
     /**
@@ -84,7 +85,7 @@ public class TextDetectorTest {
     private void assertText(byte[] data) {
         try {
             TikaInputStream tis = TikaInputStream.get(data);
-            assertEquals(MediaType.TEXT_PLAIN, detector.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, detector.detect(tis, new Metadata(), new ParseContext()));
 
             // Test that the stream has been reset
             for (byte aByte : data) {
@@ -99,7 +100,7 @@ public class TextDetectorTest {
     private void assertNotText(byte[] data) {
         try (TikaInputStream tis = TikaInputStream.get(data)) {
             assertEquals(MediaType.OCTET_STREAM,
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
         } catch (IOException e) {
             fail("Unexpected exception from TextDetector");
         }
diff --git a/tika-core/src/test/java/org/apache/tika/detect/TypeDetectorTest.java b/tika-core/src/test/java/org/apache/tika/detect/TypeDetectorTest.java
index d79e9b7e5..d35776de4 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/TypeDetectorTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/TypeDetectorTest.java
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test;
 
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Test cases for the {@link TypeDetector} class.
@@ -58,7 +59,7 @@ public class TypeDetectorTest {
         assertDetect(MediaType.OCTET_STREAM, "");
         assertDetect(MediaType.OCTET_STREAM, null);
         try {
-            assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata()));
+            assertEquals(MediaType.OCTET_STREAM, detector.detect(null, new Metadata(), new ParseContext()));
         } catch (IOException e) {
             fail("TypeDetector should never throw an IOException");
         }
@@ -68,7 +69,7 @@ public class TypeDetectorTest {
         Metadata metadata = new Metadata();
         metadata.set(Metadata.CONTENT_TYPE, name);
         try {
-            assertEquals(type, detector.detect(null, metadata));
+            assertEquals(type, detector.detect(null, metadata, new ParseContext()));
         } catch (IOException e) {
             fail("TypeDetector should never throw an IOException");
         }
diff --git a/tika-core/src/test/java/org/apache/tika/detect/ZeroSizeFileDetectorTest.java b/tika-core/src/test/java/org/apache/tika/detect/ZeroSizeFileDetectorTest.java
index 685fe441d..14414855b 100644
--- a/tika-core/src/test/java/org/apache/tika/detect/ZeroSizeFileDetectorTest.java
+++ b/tika-core/src/test/java/org/apache/tika/detect/ZeroSizeFileDetectorTest.java
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class ZeroSizeFileDetectorTest {
 
@@ -53,7 +54,7 @@ public class ZeroSizeFileDetectorTest {
     private void detect(byte[] data, MediaType type) {
         try {
             TikaInputStream tis = TikaInputStream.get(data);
-            assertEquals(type, detector.detect(tis, new Metadata()));
+            assertEquals(type, detector.detect(tis, new Metadata(), new ParseContext()));
         } catch (IOException e) {
             fail("Unexpected exception from ZeroSizeFileDetector");
         }
diff --git a/tika-core/src/test/java/org/apache/tika/mime/MimeDetectionTest.java b/tika-core/src/test/java/org/apache/tika/mime/MimeDetectionTest.java
index 263dbdbf1..76268b5fe 100644
--- a/tika-core/src/test/java/org/apache/tika/mime/MimeDetectionTest.java
+++ b/tika-core/src/test/java/org/apache/tika/mime/MimeDetectionTest.java
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 public class MimeDetectionTest {
 
@@ -104,13 +105,13 @@ public class MimeDetectionTest {
     @Test
     public void testByteOrderMark() throws Exception {
         try (TikaInputStream tis = TikaInputStream.get("\ufefftest".getBytes(UTF_16LE))) {
-            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
         try (TikaInputStream tis = TikaInputStream.get("\ufefftest".getBytes(UTF_16BE))) {
-            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
         try (TikaInputStream tis = TikaInputStream.get("\ufefftest".getBytes(UTF_8))) {
-            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -121,7 +122,7 @@ public class MimeDetectionTest {
                 "Subject: Received\r\n";
         MediaType rfc822 = MediaType.parse("message/rfc822");
         try (TikaInputStream tis = TikaInputStream.get(header.getBytes(UTF_8))) {
-            assertEquals(rfc822, MIME_TYPES.detect(tis, new Metadata()));
+            assertEquals(rfc822, MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
 
         int utfLength = ByteOrderMark.UTF_8.length();
@@ -129,7 +130,7 @@ public class MimeDetectionTest {
         System.arraycopy(ByteOrderMark.UTF_8.getBytes(), 0, bytes, 0, utfLength);
         System.arraycopy(header.getBytes(UTF_8), 0, bytes, 3, header.getBytes(UTF_8).length);
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
-            assertEquals(rfc822, MIME_TYPES.detect(tis, new Metadata()));
+            assertEquals(rfc822, MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -171,7 +172,7 @@ public class MimeDetectionTest {
     private void testUrlWithoutContent(String expected, String url) throws IOException {
         Metadata metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, url);
-        String mime = this.MIME_TYPES.detect(null, metadata).toString();
+        String mime = this.MIME_TYPES.detect(null, metadata, new ParseContext()).toString();
         assertEquals(expected, mime,
                 url + " is not properly detected using only resource name");
     }
@@ -193,13 +194,13 @@ public class MimeDetectionTest {
         assertNotNull(in, "Test stream: [" + urlOrFileName + "] is null!");
         try (TikaInputStream tis = TikaInputStream.get(in)) {
             Metadata metadata = new Metadata();
-            String mime = this.MIME_TYPES.detect(tis, metadata).toString();
+            String mime = this.MIME_TYPES.detect(tis, metadata, new ParseContext()).toString();
             assertEquals(expected, mime,
                     urlOrFileName + " is not properly detected: detected.");
 
             //Add resource name and test again
             metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, urlOrFileName);
-            mime = this.MIME_TYPES.detect(tis, metadata).toString();
+            mime = this.MIME_TYPES.detect(tis, metadata, new ParseContext()).toString();
             assertEquals(expected, mime,
                     urlOrFileName + " is not properly detected after adding resource name.");
         }
@@ -214,21 +215,21 @@ public class MimeDetectionTest {
     public void testEmptyDocument() throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.OCTET_STREAM,
-                    MIME_TYPES.detect(tis, new Metadata()));
+                    MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
 
         Metadata namehint = new Metadata();
         namehint.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.txt");
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.TEXT_PLAIN,
-                    MIME_TYPES.detect(tis, namehint));
+                    MIME_TYPES.detect(tis, namehint, new ParseContext()));
         }
 
         Metadata typehint = new Metadata();
         typehint.set(Metadata.CONTENT_TYPE, "text/plain");
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.TEXT_PLAIN,
-                    MIME_TYPES.detect(tis, typehint));
+                    MIME_TYPES.detect(tis, typehint, new ParseContext()));
         }
 
     }
@@ -242,7 +243,7 @@ public class MimeDetectionTest {
     @Test
     public void testNotXML() throws IOException {
         try (TikaInputStream tis = TikaInputStream.get("<!-- test -->".getBytes(UTF_8))) {
-            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, MIME_TYPES.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -275,20 +276,20 @@ public class MimeDetectionTest {
         metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.hello.world");
         try (TikaInputStream tis = TikaInputStream.get(helloWorld)) {
-            assertEquals(helloType, MIME_TYPES.detect(tis, metadata));
+            assertEquals(helloType, MIME_TYPES.detect(tis, metadata, new ParseContext()));
         }
 
         metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.x-hello-world");
         try (TikaInputStream tis = TikaInputStream.get(helloWorld)) {
-            assertEquals(helloXType, MIME_TYPES.detect(tis, metadata));
+            assertEquals(helloXType, MIME_TYPES.detect(tis, metadata, new ParseContext()));
         }
 
         // Without, goes for the one that sorts last
         metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "testingTESTINGtesting");
         try (TikaInputStream tis = TikaInputStream.get(helloWorld)) {
-            assertEquals(helloXType, MIME_TYPES.detect(tis, metadata));
+            assertEquals(helloXType, MIME_TYPES.detect(tis, metadata, new ParseContext()));
         }
     }
 
diff --git a/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java b/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
index 691bdf6ff..cecd419e7 100644
--- a/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
+++ b/tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
@@ -40,6 +40,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * These tests try to ensure that the MimeTypesReader
@@ -66,7 +67,7 @@ public class MimeTypesReaderTest {
     private static String getTypeAsString(MimeTypes mimeTypes, String text, Metadata metadata)
             throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)))) {
-            return mimeTypes.detect(tis, metadata).toString();
+            return mimeTypes.detect(tis, metadata, new ParseContext()).toString();
         }
 
     }
@@ -244,16 +245,17 @@ public class MimeTypesReaderTest {
             // By name
             Metadata m = new Metadata();
             m.add(TikaCoreProperties.RESOURCE_NAME_KEY, "test.hello.world");
-            assertEquals(hwf.toString(), this.mimeTypes.detect(null, m).toString());
+            assertEquals(hwf.toString(), this.mimeTypes.detect(null, m, new ParseContext()).toString());
 
             m = new Metadata();
             m.add(TikaCoreProperties.RESOURCE_NAME_KEY, "test.x-hello-world");
-            assertEquals(hxw.toString(), this.mimeTypes.detect(null, m).toString());
+            assertEquals(hxw.toString(), this.mimeTypes.detect(null, m, new ParseContext()).toString());
 
             // By contents - picks the x one as that sorts later
             m = new Metadata();
-            TikaInputStream s = TikaInputStream.get("Hello, World!".getBytes(US_ASCII));
-            assertEquals(hxw.toString(), this.mimeTypes.detect(s, m).toString());
+            try (TikaInputStream tis = TikaInputStream.get("Hello, World!".getBytes(US_ASCII))) {
+                assertEquals(hxw.toString(), this.mimeTypes.detect(tis, m, new ParseContext()).toString());
+            }
         } catch (Exception e) {
             fail(e.getMessage());
         }
@@ -269,7 +271,7 @@ public class MimeTypesReaderTest {
         MimeTypes mimeTypes = MimeTypes.getDefaultMimeTypes(new CustomClassLoader());
         Metadata m = new Metadata();
         m.add(TikaCoreProperties.RESOURCE_NAME_KEY, "test.external.mime.type");
-        assertEquals("external/mime-type", mimeTypes.detect(null, m).toString());
+        assertEquals("external/mime-type", mimeTypes.detect(null, m, new ParseContext()).toString());
     }
 
     @Test
diff --git a/tika-core/src/test/java/org/apache/tika/mime/ProbabilisticMimeDetectionTest.java b/tika-core/src/test/java/org/apache/tika/mime/ProbabilisticMimeDetectionTest.java
index 520be8a87..25b2ddcf2 100644
--- a/tika-core/src/test/java/org/apache/tika/mime/ProbabilisticMimeDetectionTest.java
+++ b/tika-core/src/test/java/org/apache/tika/mime/ProbabilisticMimeDetectionTest.java
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 public class ProbabilisticMimeDetectionTest {
 
@@ -82,14 +83,14 @@ public class ProbabilisticMimeDetectionTest {
     @Test
     public void testByteOrderMark() throws Exception {
         try (TikaInputStream tis = TikaInputStream.get("\ufefftest".getBytes(UTF_16LE))) {
-            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata(), new ParseContext()));
         }
         try (TikaInputStream tis = TikaInputStream.get("\ufefftest".getBytes(UTF_16BE))) {
-            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata(), new ParseContext()));
         }
 
         try (TikaInputStream tis = TikaInputStream.get("\ufefftest".getBytes(UTF_8))) {
-            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -142,13 +143,13 @@ public class ProbabilisticMimeDetectionTest {
         assertNotNull(in, "Test stream: [" + urlOrFileName + "] is null!");
         try (TikaInputStream tis = TikaInputStream.get(in)) {
             Metadata metadata = new Metadata();
-            String mime = this.proDetector.detect(tis, metadata).toString();
+            String mime = this.proDetector.detect(tis, metadata, new ParseContext()).toString();
             assertEquals(expected, mime,
                     urlOrFileName + " is not properly detected: detected.");
 
             // Add resource name and test again
             metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, urlOrFileName);
-            mime = this.proDetector.detect(tis, metadata).toString();
+            mime = this.proDetector.detect(tis, metadata, new ParseContext()).toString();
             assertEquals(expected, mime,
                     urlOrFileName + " is not properly detected after adding resource name.");
         }
@@ -164,21 +165,21 @@ public class ProbabilisticMimeDetectionTest {
     public void testEmptyDocument() throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.OCTET_STREAM,
-                    proDetector.detect(tis, new Metadata()));
+                    proDetector.detect(tis, new Metadata(), new ParseContext()));
         }
 
         Metadata namehint = new Metadata();
         namehint.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.txt");
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.TEXT_PLAIN,
-                    proDetector.detect(tis, namehint));
+                    proDetector.detect(tis, namehint, new ParseContext()));
         }
 
         Metadata typehint = new Metadata();
         typehint.set(Metadata.CONTENT_TYPE, "text/plain");
         try (TikaInputStream tis = TikaInputStream.get(new byte[0])) {
             assertEquals(MediaType.TEXT_PLAIN,
-                    proDetector.detect(tis, typehint));
+                    proDetector.detect(tis, typehint, new ParseContext()));
         }
 
     }
@@ -193,7 +194,7 @@ public class ProbabilisticMimeDetectionTest {
     @Test
     public void testNotXML() throws IOException {
         try (TikaInputStream tis = TikaInputStream.get("<!-- test -->".getBytes(UTF_8))) {
-            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata()));
+            assertEquals(MediaType.TEXT_PLAIN, proDetector.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
@@ -225,20 +226,20 @@ public class ProbabilisticMimeDetectionTest {
         metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.hello.world");
         try (TikaInputStream tis = TikaInputStream.get(helloWorld)) {
-            assertEquals(helloType, proDetector.detect(tis, metadata));
+            assertEquals(helloType, proDetector.detect(tis, metadata, new ParseContext()));
         }
 
         metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test.x-hello-world");
         try (TikaInputStream tis = TikaInputStream.get(helloWorld)) {
-            assertEquals(helloXType, proDetector.detect(tis, metadata));
+            assertEquals(helloXType, proDetector.detect(tis, metadata, new ParseContext()));
         }
 
         // Without, goes for the one that sorts last
         metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "testingTESTINGtesting");
         try (TikaInputStream tis = TikaInputStream.get(helloWorld)) {
-            assertEquals(helloXType, proDetector.detect(tis, metadata));
+            assertEquals(helloXType, proDetector.detect(tis, metadata, new ParseContext()));
         }
     }
 
@@ -250,7 +251,7 @@ public class ProbabilisticMimeDetectionTest {
                 ("function() {};\n" + "try {\n" + "    window.location = 'index.html';\n" +
                         "} catch (e) {\n" + "    console.log(e);\n" + "}")
                         .getBytes(StandardCharsets.UTF_8));
-        MediaType detect = new ProbabilisticMimeDetectionSelector().detect(tis, metadata);
+        MediaType detect = new ProbabilisticMimeDetectionSelector().detect(tis, metadata, new ParseContext());
         assertEquals(MediaType.text("javascript"), detect);
     }
 }
diff --git a/tika-core/src/test/java/org/apache/tika/mime/RFC822DetectionTest.java b/tika-core/src/test/java/org/apache/tika/mime/RFC822DetectionTest.java
index 5523772e6..c749e4d57 100644
--- a/tika-core/src/test/java/org/apache/tika/mime/RFC822DetectionTest.java
+++ b/tika-core/src/test/java/org/apache/tika/mime/RFC822DetectionTest.java
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
 
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 public class RFC822DetectionTest {
 
@@ -71,7 +72,7 @@ public class RFC822DetectionTest {
     private void assertMime(String expected, String txt) throws IOException {
 
         try (TikaInputStream tis = TikaInputStream.get(txt.getBytes(StandardCharsets.UTF_8))) {
-            MediaType mediaType = MIME_TYPES.detect(tis, new Metadata());
+            MediaType mediaType = MIME_TYPES.detect(tis, new Metadata(), new ParseContext());
             assertEquals(expected, mediaType.toString(), txt);
         }
     }
diff --git a/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java b/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java
index 75c3840a5..edd93611f 100644
--- a/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java
+++ b/tika-core/src/test/java/org/apache/tika/parser/mock/MockParser.java
@@ -267,7 +267,7 @@ public class MockParser implements Parser {
             m.set(Metadata.CONTENT_TYPE, contentType);
         }
         try (TikaInputStream tis = TikaInputStream.get(embeddedText.getBytes(UTF_8))) {
-            extractor.parseEmbedded(tis, new EmbeddedContentHandler(handler), m, true);
+            extractor.parseEmbedded(tis, new EmbeddedContentHandler(handler), m, context, true);
         }
     }
 
diff --git a/tika-detectors/tika-detector-magika/src/main/java/org/apache/tika/detect/magika/MagikaDetector.java b/tika-detectors/tika-detector-magika/src/main/java/org/apache/tika/detect/magika/MagikaDetector.java
index f8fe118b4..4688b3e57 100644
--- a/tika-detectors/tika-detector-magika/src/main/java/org/apache/tika/detect/magika/MagikaDetector.java
+++ b/tika-detectors/tika-detector-magika/src/main/java/org/apache/tika/detect/magika/MagikaDetector.java
@@ -36,6 +36,7 @@ import org.apache.tika.metadata.ExternalProcess;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.Property;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.utils.FileProcessResult;
 import org.apache.tika.utils.ProcessUtils;
 import org.apache.tika.utils.StringUtils;
@@ -155,7 +156,7 @@ public class MagikaDetector implements Detector {
      * @throws IOException
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (hasMagika == null) {
             hasMagika = checkHasMagika(this.config.magikaPath);
         }
diff --git a/tika-detectors/tika-detector-siegfried/src/main/java/org/apache/tika/detect/siegfried/SiegfriedDetector.java b/tika-detectors/tika-detector-siegfried/src/main/java/org/apache/tika/detect/siegfried/SiegfriedDetector.java
index 3397a848b..5c67a011a 100644
--- a/tika-detectors/tika-detector-siegfried/src/main/java/org/apache/tika/detect/siegfried/SiegfriedDetector.java
+++ b/tika-detectors/tika-detector-siegfried/src/main/java/org/apache/tika/detect/siegfried/SiegfriedDetector.java
@@ -34,6 +34,7 @@ import org.apache.tika.metadata.ExternalProcess;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.Property;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.external.ExternalParser;
 import org.apache.tika.utils.FileProcessResult;
 import org.apache.tika.utils.ProcessUtils;
@@ -125,11 +126,13 @@ public class SiegfriedDetector implements Detector {
     /**
      * @param tis      document input stream, or <code>null</code>
      * @param metadata input metadata for the document
+     * @param parseContext the parse context
      * @return mime as identified by the file command or application/octet-stream otherwise
      * @throws IOException
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
+            throws IOException {
         if (hasSiegfriedCommand == null) {
             hasSiegfriedCommand = checkHasSiegfried(this.config.siegfriedPath);
         }
diff --git a/tika-eval/tika-eval-app/src/main/java/org/apache/tika/eval/app/io/ExtractReader.java b/tika-eval/tika-eval-app/src/main/java/org/apache/tika/eval/app/io/ExtractReader.java
index 3bac1a849..26ff7f22c 100644
--- a/tika-eval/tika-eval-app/src/main/java/org/apache/tika/eval/app/io/ExtractReader.java
+++ b/tika-eval/tika-eval-app/src/main/java/org/apache/tika/eval/app/io/ExtractReader.java
@@ -41,6 +41,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MimeTypes;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.sax.ToTextContentHandler;
 import org.apache.tika.sax.ToXMLContentHandler;
 import org.apache.tika.serialization.JsonMetadataList;
@@ -204,7 +205,7 @@ public class ExtractReader {
         //but better than nothing.
         m.set(TikaCoreProperties.RESOURCE_NAME_KEY, fileSuffixes.originalFileName);
 
-        MediaType mimeType = mimeTypes.detect(null, m);
+        MediaType mimeType = mimeTypes.detect(null, m, new ParseContext());
         if (mimeType != null) {
             m.set(Metadata.CONTENT_TYPE, mimeType.toString());
         }
diff --git a/tika-example/src/main/java/org/apache/tika/example/AdvancedTypeDetector.java b/tika-example/src/main/java/org/apache/tika/example/AdvancedTypeDetector.java
index e9716e824..c03186741 100755
--- a/tika-example/src/main/java/org/apache/tika/example/AdvancedTypeDetector.java
+++ b/tika-example/src/main/java/org/apache/tika/example/AdvancedTypeDetector.java
@@ -23,6 +23,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MimeTypesFactory;
+import org.apache.tika.parser.ParseContext;
 
 public class AdvancedTypeDetector {
     public static String detectWithCustomConfig(String name) throws Exception {
@@ -38,7 +39,7 @@ public class AdvancedTypeDetector {
         Detector custom = new Detector() {
             private static final long serialVersionUID = -5420638839201540749L;
 
-            public MediaType detect(TikaInputStream tis, Metadata metadata) {
+            public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) {
                 String type = metadata.get("my-custom-type-override");
                 if (type != null) {
                     return MediaType.parse(type);
diff --git a/tika-example/src/main/java/org/apache/tika/example/ContentHandlerExample.java b/tika-example/src/main/java/org/apache/tika/example/ContentHandlerExample.java
index 33a3c5868..5dcb6031b 100644
--- a/tika-example/src/main/java/org/apache/tika/example/ContentHandlerExample.java
+++ b/tika-example/src/main/java/org/apache/tika/example/ContentHandlerExample.java
@@ -17,7 +17,6 @@
 package org.apache.tika.example;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -52,8 +51,7 @@ public class ContentHandlerExample {
 
         AutoDetectParser parser = new AutoDetectParser();
         Metadata metadata = new Metadata();
-        try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test.doc");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ContentHandlerExample.class.getResourceAsStream("test.doc"))) {
             parser.parse(tis, handler, metadata);
             return handler.toString();
         }
@@ -67,8 +65,7 @@ public class ContentHandlerExample {
 
         AutoDetectParser parser = new AutoDetectParser();
         Metadata metadata = new Metadata();
-        try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test.doc");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ContentHandlerExample.class.getResourceAsStream("test.doc"))) {
             parser.parse(tis, handler, metadata);
             return handler.toString();
         }
@@ -83,8 +80,7 @@ public class ContentHandlerExample {
 
         AutoDetectParser parser = new AutoDetectParser();
         Metadata metadata = new Metadata();
-        try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test.doc");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ContentHandlerExample.class.getResourceAsStream("test.doc"))) {
             parser.parse(tis, handler, metadata);
             return handler.toString();
         }
@@ -102,8 +98,7 @@ public class ContentHandlerExample {
 
         AutoDetectParser parser = new AutoDetectParser();
         Metadata metadata = new Metadata();
-        try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test2.doc");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ContentHandlerExample.class.getResourceAsStream("test2.doc"))) {
             parser.parse(tis, handler, metadata);
             return handler.toString();
         }
@@ -132,8 +127,7 @@ public class ContentHandlerExample {
 
         AutoDetectParser parser = new AutoDetectParser();
         Metadata metadata = new Metadata();
-        try (InputStream stream = ContentHandlerExample.class.getResourceAsStream("test2.doc");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ContentHandlerExample.class.getResourceAsStream("test2.doc"))) {
             parser.parse(tis, handler, metadata);
             return chunks;
         }
diff --git a/tika-example/src/main/java/org/apache/tika/example/DirListParser.java b/tika-example/src/main/java/org/apache/tika/example/DirListParser.java
index fd63009cf..a94ff0ea1 100755
--- a/tika-example/src/main/java/org/apache/tika/example/DirListParser.java
+++ b/tika-example/src/main/java/org/apache/tika/example/DirListParser.java
@@ -49,9 +49,7 @@ public class DirListParser implements Parser {
     public static void main(String[] args) throws IOException, SAXException, TikaException {
         DirListParser parser = new DirListParser();
         Metadata met = new Metadata();
-        try (TikaInputStream tis = TikaInputStream.get(System.in)) {
-            parser.parse(tis, new BodyContentHandler(), met);
-        }
+        parser.parse(TikaInputStream.get(System.in), new BodyContentHandler(), met);
 
         System.out.println("Num files: " + met.getValues("Filename").length);
         System.out.println("Num executables: " + met.get("NumExecutables"));
diff --git a/tika-example/src/main/java/org/apache/tika/example/DisplayMetInstance.java b/tika-example/src/main/java/org/apache/tika/example/DisplayMetInstance.java
index 10e0c885c..2005beca3 100755
--- a/tika-example/src/main/java/org/apache/tika/example/DisplayMetInstance.java
+++ b/tika-example/src/main/java/org/apache/tika/example/DisplayMetInstance.java
@@ -35,9 +35,7 @@ public class DisplayMetInstance {
     public static Metadata getMet(URL url) throws IOException, SAXException, TikaException {
         Metadata met = new Metadata();
         PDFParser parser = new PDFParser();
-        try (TikaInputStream tis = TikaInputStream.get(url.openStream())) {
-            parser.parse(tis, new BodyContentHandler(), met, new ParseContext());
-        }
+        parser.parse(TikaInputStream.get(url, met), new BodyContentHandler(), met, new ParseContext());
         return met;
     }
 
diff --git a/tika-example/src/main/java/org/apache/tika/example/EncryptedPrescriptionDetector.java b/tika-example/src/main/java/org/apache/tika/example/EncryptedPrescriptionDetector.java
index 3339a3cd9..503bf71d4 100755
--- a/tika-example/src/main/java/org/apache/tika/example/EncryptedPrescriptionDetector.java
+++ b/tika-example/src/main/java/org/apache/tika/example/EncryptedPrescriptionDetector.java
@@ -30,11 +30,12 @@ import org.apache.tika.io.LookaheadInputStream;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class EncryptedPrescriptionDetector implements Detector {
     private static final long serialVersionUID = -1709652690773421147L;
 
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         Key key = Pharmacy.getKey();
         MediaType type = MediaType.OCTET_STREAM;
 
diff --git a/tika-example/src/main/java/org/apache/tika/example/ExtractEmbeddedFiles.java b/tika-example/src/main/java/org/apache/tika/example/ExtractEmbeddedFiles.java
index ee14226a3..48fc84894 100644
--- a/tika-example/src/main/java/org/apache/tika/example/ExtractEmbeddedFiles.java
+++ b/tika-example/src/main/java/org/apache/tika/example/ExtractEmbeddedFiles.java
@@ -76,7 +76,8 @@ public class ExtractEmbeddedFiles {
         }
 
         @Override
-        public void parseEmbedded(TikaInputStream stream, ContentHandler handler, Metadata metadata, boolean outputHtml) throws SAXException, IOException {
+        public void parseEmbedded(TikaInputStream stream, ContentHandler handler, Metadata metadata,
+                                  ParseContext parseContext, boolean outputHtml) throws SAXException, IOException {
 
             //try to get the name of the embedded file from the metadata
             String name = metadata.get(TikaCoreProperties.RESOURCE_NAME_KEY);
@@ -96,7 +97,7 @@ public class ExtractEmbeddedFiles {
             }
 
             //now try to figure out the right extension for the embedded file
-            MediaType contentType = detector.detect(stream, metadata);
+            MediaType contentType = detector.detect(stream, metadata, context);
 
             if (name.indexOf('.') == -1 && contentType != null) {
                 try {
diff --git a/tika-example/src/main/java/org/apache/tika/example/ImportContextImpl.java b/tika-example/src/main/java/org/apache/tika/example/ImportContextImpl.java
index 1d40ee985..a60ef6022 100755
--- a/tika-example/src/main/java/org/apache/tika/example/ImportContextImpl.java
+++ b/tika-example/src/main/java/org/apache/tika/example/ImportContextImpl.java
@@ -37,6 +37,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * <code>ImportContextImpl</code>...
@@ -85,7 +86,7 @@ public class ImportContextImpl implements ImportContext {
             stream = new BufferedInputStream(stream);
         }
         try (TikaInputStream tis = TikaInputStream.get(stream)) {
-            type = detector.detect(tis, metadata);
+            type = detector.detect(tis, metadata, new ParseContext());
             this.inputFile = IOUtil.getTempFile(tis);
         }
     }
diff --git a/tika-example/src/main/java/org/apache/tika/example/MyFirstTika.java b/tika-example/src/main/java/org/apache/tika/example/MyFirstTika.java
index d37e7d5da..66766793c 100755
--- a/tika-example/src/main/java/org/apache/tika/example/MyFirstTika.java
+++ b/tika-example/src/main/java/org/apache/tika/example/MyFirstTika.java
@@ -84,29 +84,30 @@ public class MyFirstTika {
         System.out.println("Examining: [" + filename + "]");
 
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, filename);
-        System.out.println("The MIME type (based on filename) is: [" + mimeRegistry.detect(null, metadata) + "]");
+        System.out.println("The MIME type (based on filename) is: [" + mimeRegistry.detect(null, metadata, new ParseContext()) + "]");
 
-        TikaInputStream tis = TikaInputStream.get(Paths.get(filename));
-        System.out.println("The MIME type (based on MAGIC) is: [" + mimeRegistry.detect(tis, metadata) + "]");
+        try (TikaInputStream tis = TikaInputStream.get(Paths.get(filename))) {
+            System.out.println("The MIME type (based on MAGIC) is: [" + mimeRegistry.detect(tis, metadata, new ParseContext()) + "]");
+        }
 
-        tis = TikaInputStream.get(Paths.get(filename));
         Detector detector = tikaLoader.loadDetectors();
-        System.out.println("The MIME type (based on the Detector interface) is: [" + detector.detect(tis, metadata) + "]");
-
-        LanguageDetector langDetector = new OptimaizeLangDetector().loadModels();
-        LanguageResult lang = langDetector.detect(FileUtils.readFileToString(new File(filename), UTF_8));
-
-        System.out.println("The language of this content is: [" + lang.getLanguage() + "]");
-
-        // Get a non-detecting parser that handles all the types it can
-        Parser parser = tikaLoader.loadParsers();
-        // Tell it what we think the content is
-        MediaType type = detector.detect(tis, metadata);
-        metadata.set(Metadata.CONTENT_TYPE, type.toString());
-        // Have the file parsed to get the content and metadata
-        ContentHandler handler = new BodyContentHandler();
-        parser.parse(tis, handler, metadata, new ParseContext());
-
-        return handler.toString();
+        try (TikaInputStream tis = TikaInputStream.get(Paths.get(filename))) {
+            System.out.println("The MIME type (based on the Detector interface) is: [" + detector.detect(tis, metadata, new ParseContext()) + "]");
+
+            LanguageDetector langDetector = new OptimaizeLangDetector().loadModels();
+            LanguageResult lang = langDetector.detect(FileUtils.readFileToString(new File(filename), UTF_8));
+
+            System.out.println("The language of this content is: [" + lang.getLanguage() + "]");
+
+            // Get a non-detecting parser that handles all the types it can
+            Parser parser = tikaLoader.loadParsers();
+            // Tell it what we think the content is
+            MediaType type = detector.detect(tis, metadata, new ParseContext());
+            metadata.set(Metadata.CONTENT_TYPE, type.toString());
+            // Have the file parsed to get the content and metadata
+            ContentHandler handler = new BodyContentHandler();
+            parser.parse(tis, handler, metadata, new ParseContext());
+            return handler.toString();
+        }
     }
 }
diff --git a/tika-example/src/main/java/org/apache/tika/example/ParsingExample.java b/tika-example/src/main/java/org/apache/tika/example/ParsingExample.java
index a0b95e3cd..78239c340 100644
--- a/tika-example/src/main/java/org/apache/tika/example/ParsingExample.java
+++ b/tika-example/src/main/java/org/apache/tika/example/ParsingExample.java
@@ -89,9 +89,8 @@ public class ParsingExample {
         AutoDetectParser parser = new AutoDetectParser();
         BodyContentHandler handler = new BodyContentHandler();
         Metadata metadata = new Metadata();
-        try (InputStream stream = ParsingExample.class.getResourceAsStream("test.doc");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
-            parser.parse(tis, handler, metadata);
+        try (TikaInputStream tis = TikaInputStream.get(ParsingExample.class.getResourceAsStream("test.doc"))) {
+            parser.parse(tis, handler, metadata, new ParseContext());
             return handler.toString();
         }
     }
@@ -109,11 +108,11 @@ public class ParsingExample {
         Metadata metadata = new Metadata();
         ParseContext parseContext = new ParseContext();
         parseContext.set(Parser.class, new EmptyParser());
-        try (InputStream stream = ParsingExample.class.getResourceAsStream("test_recursive_embedded.docx");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ParsingExample.class.getResourceAsStream("test_recursive_embedded.docx"))) {
             parser.parse(tis, handler, metadata, parseContext);
             return handler.toString();
         }
+
     }
 
 
@@ -132,8 +131,7 @@ public class ParsingExample {
         Metadata metadata = new Metadata();
         ParseContext context = new ParseContext();
         context.set(Parser.class, parser);
-        try (InputStream stream = ParsingExample.class.getResourceAsStream("test_recursive_embedded.docx");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ParsingExample.class.getResourceAsStream("test_recursive_embedded.docx"))) {
             parser.parse(tis, handler, metadata, context);
             return handler.toString();
         }
@@ -150,7 +148,7 @@ public class ParsingExample {
      * MSPowerPoint, RTF, PDF, MSG and several others.
      * <p>
      * The "content" format is determined by the ContentHandlerFactory, and
-     * the content is stored in {@link org.apache.tika.parser.RecursiveParserWrapper#TIKA_CONTENT}
+     * the content is stored in {@link org.apache.tika.metadata.TikaCoreProperties#TIKA_CONTENT}
      * <p>
      * The drawback to the RecursiveParserWrapper is that it caches metadata and contents
      * in memory.  This should not be used on files whose contents are too big to be handled
@@ -170,8 +168,7 @@ public class ParsingExample {
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, "test_recursive_embedded.docx");
         ParseContext context = new ParseContext();
         RecursiveParserWrapperHandler handler = new RecursiveParserWrapperHandler(factory, -1);
-        try (InputStream stream = ParsingExample.class.getResourceAsStream("test_recursive_embedded.docx");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = TikaInputStream.get(ParsingExample.class.getResourceAsStream("test_recursive_embedded.docx"))) {
             wrapper.parse(tis, handler, metadata, context);
         }
 
diff --git a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/hdf/HDFParserTest.java b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/hdf/HDFParserTest.java
index ce8fb6093..5f5f2c16c 100644
--- a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/hdf/HDFParserTest.java
+++ b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/test/java/org/apache/tika/parser/hdf/HDFParserTest.java
@@ -50,7 +50,7 @@ public class HDFParserTest extends TikaTest {
          * ftp://acdisc.gsfc.nasa.gov/data/s4pa///Aura_MLS_Level2/ML2O3.002//2009
          * /MLS-Aura_L2GP-O3_v02-23-c01_2009d122.he5
          */
-        try (TikaInputStream tis = getResourceAsStream("/test-documents/test.he5")) {
+        try (TikaInputStream tis = TikaInputStream.get(HDFParser.class.getResourceAsStream("/test-documents/test.he5"))) {
             parser.parse(tis, handler, metadata, new ParseContext());
         }
 
diff --git a/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypesExtended.java b/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypesExtended.java
index b0313bc3d..88d3b513e 100644
--- a/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypesExtended.java
+++ b/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/mime/TestMimeTypesExtended.java
@@ -28,6 +28,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.config.loader.TikaLoader;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 public class TestMimeTypesExtended extends TikaTest {
 
@@ -47,7 +48,7 @@ public class TestMimeTypesExtended extends TikaTest {
         try (TikaInputStream tis = getResourceAsStream("/test-documents/" + filename)) {
             assertNotNull(tis, "Test file not found: " + filename);
             Metadata metadata = new Metadata();
-            assertEquals(expected, repo.detect(tis, metadata).toString());
+            assertEquals(expected, repo.detect(tis, metadata, new ParseContext()).toString());
         }
     }
 }
diff --git a/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java b/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
index 9a53c85b2..5519ddbcc 100644
--- a/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
+++ b/tika-parsers/tika-parsers-extended/tika-parsers-extended-integration-tests/src/test/java/org/apache/tika/parser/sqlite3/SQLite3ParserTest.java
@@ -21,7 +21,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -173,9 +172,10 @@ public class SQLite3ParserTest extends TikaTest {
         ParserContainerExtractor ex = new ParserContainerExtractor();
         ByteCopyingHandler byteCopier = new ByteCopyingHandler();
         Metadata metadata = new Metadata();
+        ParseContext context = new ParseContext();
         try (TikaInputStream tis = TikaInputStream.get(getResourceAsStream(TEST_FILE1))) {
             metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, TEST_FILE_NAME);
-            ex.extract(tis, ex, byteCopier);
+            ex.extract(tis, ex, byteCopier, context);
         }
         assertEquals(4, byteCopier.bytes.size());
         String[] strings = new String[4];
@@ -207,10 +207,11 @@ public class SQLite3ParserTest extends TikaTest {
         ParserContainerExtractor ex = new ParserContainerExtractor();
         InputStreamResettingHandler byteCopier = new InputStreamResettingHandler();
         Metadata metadata = new Metadata();
+        ParseContext context = new ParseContext();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, TEST_FILE_NAME);
         try (TikaInputStream outer = TikaInputStream.get(getResourceAsStream(TEST_FILE1))) {
             try (TikaInputStream tis = TikaInputStream.get(outer.getPath())) {
-                ex.extract(tis, ex, byteCopier);
+                ex.extract(tis, ex, byteCopier, context);
                 tis.reset();
             }
         }
@@ -223,7 +224,8 @@ public class SQLite3ParserTest extends TikaTest {
         public List<byte[]> bytes = new ArrayList<>();
 
         @Override
-        public void handle(String filename, MediaType mediaType, InputStream stream) {
+        public void handle(String filename, MediaType mediaType, TikaInputStream stream,
+                           ParseContext parseContext) {
             ByteArrayOutputStream os = new ByteArrayOutputStream();
             if (!stream.markSupported()) {
                 stream = TikaInputStream.get(stream);
diff --git a/tika-parsers/tika-parsers-ml/tika-parser-nlp-module/src/test/java/org/apache/tika/parser/journal/JournalParserTest.java b/tika-parsers/tika-parsers-ml/tika-parser-nlp-module/src/test/java/org/apache/tika/parser/journal/JournalParserTest.java
index 5942c7b4f..7968d405e 100644
--- a/tika-parsers/tika-parsers-ml/tika-parser-nlp-module/src/test/java/org/apache/tika/parser/journal/JournalParserTest.java
+++ b/tika-parsers/tika-parsers-ml/tika-parser-nlp-module/src/test/java/org/apache/tika/parser/journal/JournalParserTest.java
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
 import org.xml.sax.ContentHandler;
 
 import org.apache.tika.TikaTest;
+import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.sax.BodyContentHandler;
@@ -40,7 +41,7 @@ public class JournalParserTest extends TikaTest {
         assumeTrue(canRun());
 
         JournalParser jParser = new JournalParser();
-        try {
+        try (TikaInputStream tis = getResourceAsStream(path)) {
             jParser.parse(getResourceAsStream(path), handler, metadata, new ParseContext());
         } catch (Exception e) {
             e.printStackTrace();
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/detect/apple/BPListDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/detect/apple/BPListDetector.java
index 6bfe007cf..ade9d6a02 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/detect/apple/BPListDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/detect/apple/BPListDetector.java
@@ -35,6 +35,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Detector for BPList with utility functions for PList.
@@ -96,7 +97,7 @@ public class BPListDetector implements Detector {
      * @throws IOException
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (tis == null) {
             return MediaType.OCTET_STREAM;
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/AppleSingleFileParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/AppleSingleFileParser.java
index 008d19f64..b7e675251 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/AppleSingleFileParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/AppleSingleFileParser.java
@@ -101,7 +101,7 @@ public class AppleSingleFileParser implements Parser {
                 // TODO: we should probably add a readlimiting wrapper around this
                 // stream to ensure that not more than contentFieldInfo.length bytes
                 // are read
-                ex.parseEmbedded(tis, xhtml, embeddedMetadata, true);
+                ex.parseEmbedded(tis, xhtml, embeddedMetadata, context, true);
             }
         }
         xhtml.endDocument();
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/PListParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/PListParser.java
index b60eca34a..3dfed491c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/PListParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/apple/PListParser.java
@@ -198,7 +198,7 @@ public class PListParser implements Parser {
 
         try (TikaInputStream tis = TikaInputStream.get(value.bytes())) {
             state.embeddedDocumentExtractor
-                    .parseEmbedded(tis, state.xhtml, embeddedMetadata, true);
+                    .parseEmbedded(tis, state.xhtml, embeddedMetadata, new ParseContext(), true);
         }
     }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/iwork/iwana/IWork13PackageParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/iwork/iwana/IWork13PackageParser.java
index 4c6dd1c80..3dee6fdc7 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/iwork/iwana/IWork13PackageParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/main/java/org/apache/tika/parser/iwork/iwana/IWork13PackageParser.java
@@ -209,7 +209,7 @@ public class IWork13PackageParser implements Parser {
                                 EmbeddedDocumentExtractor embeddedDocumentExtractor)
             throws IOException, SAXException {
         if (embeddedDocumentExtractor.shouldParseEmbedded(embeddedMetadata)) {
-            embeddedDocumentExtractor.parseEmbedded(tis, xhtml, embeddedMetadata, true);
+            embeddedDocumentExtractor.parseEmbedded(tis, xhtml, embeddedMetadata, new ParseContext(), true);
         }
     }
 
@@ -316,7 +316,7 @@ public class IWork13PackageParser implements Parser {
 
             // Is it the main document?
             if (name.equals(IWORK13_MAIN_ENTRY)) {
-                // TODO Decode the snappy stream, and check for the Message Type
+                // TODO Decode the snappy tis, and check for the Message Type
                 // =     2 (TN::SheetArchive), it is a numbers file;
                 // = 10000 (TP::DocumentArchive), that's a pages file
                 return null;
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/test/java/org/apache/tika/parser/iwork/IWorkParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/test/java/org/apache/tika/parser/iwork/IWorkParserTest.java
index bbccdeb42..2d24d5455 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/test/java/org/apache/tika/parser/iwork/IWorkParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-apple-module/src/test/java/org/apache/tika/parser/iwork/IWorkParserTest.java
@@ -430,7 +430,7 @@ public class IWorkParserTest extends TikaTest {
         try (InputStream is = this.getClass()
                 .getResourceAsStream("/test-documents/testIWorksNPEDetector.zip");
              TikaInputStream tis = TikaInputStream.get(is)) {
-            MediaType mt = d.detect(tis, new Metadata());
+            MediaType mt = d.detect(tis, new Metadata(), new ParseContext());
             assertEquals(MediaType.application("zip"), mt);
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/MatroskaDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/MatroskaDetector.java
index 35a8e6b65..3f589c9fc 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/MatroskaDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/MatroskaDetector.java
@@ -24,6 +24,7 @@ import org.apache.tika.config.TikaComponent;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Detector for Matroska (MKV and WEBM) files based on the EBML header.
@@ -52,7 +53,7 @@ public class MatroskaDetector implements Detector {
      * @throws IOException if an I/O error occurs
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (tis == null) {
             return MediaType.OCTET_STREAM;
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/ogg/OggDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/ogg/OggDetector.java
index e05e707de..8c7b4b573 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/ogg/OggDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/detect/ogg/OggDetector.java
@@ -37,6 +37,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Detector for identifying specific file types stored
@@ -55,7 +56,7 @@ public class OggDetector implements Detector {
     public static final MediaType OGG_VIDEO = MediaType.video("ogg");
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata)
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext)
             throws IOException {
         // Check if we have access to the document
         if (tis == null) {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/MP4Parser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/MP4Parser.java
index 6e54afdbd..687276f6c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/MP4Parser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/MP4Parser.java
@@ -93,7 +93,8 @@ public class MP4Parser implements Parser {
         return SUPPORTED_TYPES;
     }
 
-    public void parse(TikaInputStream tis, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException {
+    public void parse(TikaInputStream tis, ContentHandler handler, Metadata metadata,
+                      ParseContext context) throws IOException, SAXException, TikaException {
 
 
         XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/test/java/org/apache/tika/detect/MatroskaDetectorTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/test/java/org/apache/tika/detect/MatroskaDetectorTest.java
index 9ab8f5869..a4e96ff10 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/test/java/org/apache/tika/detect/MatroskaDetectorTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/test/java/org/apache/tika/detect/MatroskaDetectorTest.java
@@ -27,20 +27,25 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class MatroskaDetectorTest extends TikaTest {
 
     private final MatroskaDetector detector = new MatroskaDetector();
 
+    public TikaInputStream getResourceAsStream(String resourcePath) {
+        return TikaInputStream.get(this.getClass().getResourceAsStream(resourcePath));
+    }
+
     @Test
     public void testDetectMKV() throws IOException {
         assertEquals(MediaType.application("x-matroska"),
                 detector.detect(getResourceAsStream("/test-documents/sample-mkv.noext"),
-                        new Metadata()));
+                        new Metadata(), new ParseContext()));
 
         assertEquals(MediaType.application("x-matroska"),
                 detector.detect(getResourceAsStream("/test-documents/testMKV.mkv"),
-                        new Metadata()));
+                        new Metadata(), new ParseContext()));
 
 
     }
@@ -49,24 +54,24 @@ public class MatroskaDetectorTest extends TikaTest {
     public void testDetectWEBM() throws IOException {
         assertEquals(MediaType.video("webm"),
                 detector.detect(getResourceAsStream("/test-documents/sample-webm.noext"),
-                        new Metadata()));
+                        new Metadata(), new ParseContext()));
     }
 
     @Test
     public void testNullAndShort() throws Exception {
         assertEquals(MediaType.OCTET_STREAM,
-                detector.detect(null, new Metadata()));
+                detector.detect(null, new Metadata(), new ParseContext()));
 
         byte[] bytes = new byte[10];
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals(MediaType.OCTET_STREAM,
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
         }
 
         bytes = new byte[0];
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals(MediaType.OCTET_STREAM,
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
         }
 
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-cad-module/src/main/java/org/apache/tika/parser/dgn/DGN8Parser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-cad-module/src/main/java/org/apache/tika/parser/dgn/DGN8Parser.java
index 6984476cb..b23533568 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-cad-module/src/main/java/org/apache/tika/parser/dgn/DGN8Parser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-cad-module/src/main/java/org/apache/tika/parser/dgn/DGN8Parser.java
@@ -49,7 +49,8 @@ public class DGN8Parser implements Parser {
     }
 
     @Override
-    public void parse(TikaInputStream tis, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException {
+    public void parse(TikaInputStream tis, ContentHandler handler, Metadata metadata,
+                      ParseContext context) throws IOException, SAXException, TikaException {
         XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
         xhtml.startDocument();
         SummaryExtractor summaryExtractor = new SummaryExtractor(metadata);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-code-module/src/main/java/org/apache/tika/parser/executable/UniversalExecutableParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-code-module/src/main/java/org/apache/tika/parser/executable/UniversalExecutableParser.java
index ae8882563..afc25c177 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-code-module/src/main/java/org/apache/tika/parser/executable/UniversalExecutableParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-code-module/src/main/java/org/apache/tika/parser/executable/UniversalExecutableParser.java
@@ -74,11 +74,11 @@ public class UniversalExecutableParser implements Parser {
 
         if ((first4[0] == (byte) 0xBF || first4[0] == (byte) 0xBE) &&
                 first4[1] == (byte) 0xBA && first4[2] == (byte) 0xFE && first4[3] == (byte) 0xCA) {
-            parseMachO(xhtml, extractor, metadata, tis, first4);
+            parseMachO(xhtml, extractor, metadata, tis, first4, context);
         } else if (first4[0] == (byte) 0xCA && first4[1] == (byte) 0xFE &&
                 first4[2] == (byte) 0xBA &&
                 (first4[3] == (byte) 0xBF || first4[3] == (byte) 0xBE)) {
-            parseMachO(xhtml, extractor, metadata, tis, first4);
+            parseMachO(xhtml, extractor, metadata, tis, first4, context);
         } else {
             throw new UnsupportedFormatException("Not a universal executable file");
         }
@@ -91,7 +91,7 @@ public class UniversalExecutableParser implements Parser {
      */
     public void parseMachO(XHTMLContentHandler xhtml, EmbeddedDocumentExtractor extractor,
                            Metadata metadata, InputStream tis,
-                           byte[] first4)
+                           byte[] first4, ParseContext context)
             throws IOException, SAXException, TikaException {
         var currentOffset = (long) first4.length;
         var isLE = first4[3] == (byte) 0xCA;
@@ -160,7 +160,7 @@ public class UniversalExecutableParser implements Parser {
             var perArchMetadata = new Metadata();
             var tikaInputStream = TikaInputStream.get(perArchMachO, perArchMetadata);
             if (extractor.shouldParseEmbedded(perArchMetadata)) {
-                extractor.parseEmbedded(tikaInputStream, xhtml, perArchMetadata, true);
+                extractor.parseEmbedded(tikaInputStream, xhtml, perArchMetadata, context, true);
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/TSDParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/TSDParser.java
index 8319c0de9..3be79458f 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/TSDParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-crypto-module/src/main/java/org/apache/tika/parser/crypto/TSDParser.java
@@ -174,7 +174,7 @@ public class TSDParser implements Parser {
                 cmsTimeStampedDataParser = new CMSTimeStampedDataParser(stream);
 
                 try (TikaInputStream inner = TikaInputStream.get(cmsTimeStampedDataParser.getContent())) {
-                    edx.parseEmbedded(inner, handler, metadata, true);
+                    edx.parseEmbedded(inner, handler, metadata, context, true);
                 }
 
             } catch (SecurityException e) {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlEncodingDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlEncodingDetector.java
index e50110012..de1bb36c6 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlEncodingDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlEncodingDetector.java
@@ -36,6 +36,7 @@ import org.apache.tika.config.TikaComponent;
 import org.apache.tika.detect.EncodingDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.utils.CharsetUtils;
 
 /**
@@ -134,7 +135,7 @@ public class HtmlEncodingDetector implements EncodingDetector {
         this(ConfigDeserializer.buildConfig(jsonConfig, Config.class));
     }
 
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (tis == null) {
             return null;
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlHandler.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlHandler.java
index b613f3939..e71267e10 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlHandler.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/HtmlHandler.java
@@ -341,7 +341,7 @@ class HtmlHandler extends TextContentHandler {
                 EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context);
         if (embeddedDocumentExtractor.shouldParseEmbedded(m)) {
             try (TikaInputStream tis = TikaInputStream.get(string.getBytes(StandardCharsets.UTF_8))) {
-                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, context, true);
             } catch (IOException e) {
                 EmbeddedDocumentUtil.recordEmbeddedStreamException(e, metadata);
             }
@@ -368,7 +368,7 @@ class HtmlHandler extends TextContentHandler {
                 EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context);
         if (embeddedDocumentExtractor.shouldParseEmbedded(m)) {
             try (TikaInputStream tis = TikaInputStream.get(dataURIScheme.getInputStream())) {
-                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, context, true);
             } catch (IOException e) {
                 EmbeddedDocumentUtil.recordEmbeddedStreamException(e, metadata);
             }
@@ -402,7 +402,7 @@ class HtmlHandler extends TextContentHandler {
             if (embeddedDocumentExtractor.shouldParseEmbedded(dataUriMetadata)) {
                 try (TikaInputStream tis = TikaInputStream.get(dataURIScheme.getInputStream())) {
                     embeddedDocumentExtractor
-                            .parseEmbedded(tis, xhtml, dataUriMetadata, true);
+                            .parseEmbedded(tis, xhtml, dataUriMetadata, context, true);
                 } catch (IOException e) {
                     //swallow
                 }
@@ -410,7 +410,7 @@ class HtmlHandler extends TextContentHandler {
         }
 
         try (TikaInputStream tis = TikaInputStream.get(script.toString().getBytes(StandardCharsets.UTF_8))) {
-            embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, true);
+            embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, context, true);
         } catch (IOException e) {
             //shouldn't ever happen
         } finally {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
index c985bf401..ac93a8f73 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/JSoupParser.java
@@ -158,7 +158,7 @@ public class JSoupParser extends AbstractEncodingDetectorParser {
                       ParseContext context) throws IOException, SAXException, TikaException {
 
         EncodingDetector encodingDetector = getEncodingDetector(context);
-        Charset charset = encodingDetector.detect(tis, metadata);
+        Charset charset = encodingDetector.detect(tis, metadata, context);
         charset = charset == null ? DEFAULT_CHARSET : charset;
         String previous = metadata.get(Metadata.CONTENT_TYPE);
         MediaType contentType = null;
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/charsetdetector/StandardHtmlEncodingDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/charsetdetector/StandardHtmlEncodingDetector.java
index ec1f9e3cf..d29cd2a27 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/charsetdetector/StandardHtmlEncodingDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/main/java/org/apache/tika/parser/html/charsetdetector/StandardHtmlEncodingDetector.java
@@ -29,6 +29,7 @@ import org.apache.tika.detect.EncodingDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * An encoding detector that tries to respect the spirit of the HTML spec
@@ -75,7 +76,7 @@ public final class StandardHtmlEncodingDetector implements EncodingDetector {
     }
 
     @Override
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext context) throws IOException {
         int limit = getMarkLimit();
         tis.mark(limit);
         // Never read more than the first META_TAG_BUFFER_SIZE bytes
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlEncodingDetectorTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlEncodingDetectorTest.java
index 8ed468904..ee30f75d3 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlEncodingDetectorTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlEncodingDetectorTest.java
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
 
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 public class HtmlEncodingDetectorTest {
 
@@ -131,7 +132,8 @@ public class HtmlEncodingDetectorTest {
 
     private Charset detectCharset(String test) throws IOException {
         Metadata metadata = new Metadata();
-        TikaInputStream inStream = TikaInputStream.get(test.getBytes(StandardCharsets.UTF_8));
-        return new HtmlEncodingDetector().detect(inStream, metadata);
+        try (TikaInputStream tis = TikaInputStream.get(test.getBytes(StandardCharsets.UTF_8))) {
+            return new HtmlEncodingDetector().detect(tis, metadata, new ParseContext());
+        }
     }
 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
index 080cba748..af5fd2aed 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
@@ -1252,7 +1252,7 @@ public class HtmlParserTest extends TikaTest {
 
     public String getEncoding(EncodingDetector detector, Path p) throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(p)) {
-            Charset charset = detector.detect(tis, new Metadata());
+            Charset charset = detector.detect(tis, new Metadata(), new ParseContext());
             if (charset == null) {
                 return "NULL";
             } else {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/StandardHtmlEncodingDetectorTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/StandardHtmlEncodingDetectorTest.java
index cf668af5e..636ffcef0 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/StandardHtmlEncodingDetectorTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-html-module/src/test/java/org/apache/tika/parser/html/StandardHtmlEncodingDetectorTest.java
@@ -31,6 +31,7 @@ import org.junit.jupiter.api.Test;
 
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.html.charsetdetector.StandardHtmlEncodingDetector;
 import org.apache.tika.parser.html.charsetdetector.charsets.ReplacementCharset;
 
@@ -357,7 +358,7 @@ public class StandardHtmlEncodingDetectorTest {
     private Charset detectCharset(InputStream inStream) throws IOException {
         TikaInputStream tis = (inStream instanceof TikaInputStream) ?
                 (TikaInputStream) inStream : TikaInputStream.get(inStream);
-        return new StandardHtmlEncodingDetector().detect(tis, metadata);
+        return new StandardHtmlEncodingDetector().detect(tis, metadata, new ParseContext());
     }
 
     private InputStream throwAfter(String html) {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mail/MailContentHandler.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mail/MailContentHandler.java
index 9af23d004..2a138ed6c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mail/MailContentHandler.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mail/MailContentHandler.java
@@ -220,7 +220,7 @@ class MailContentHandler implements ContentHandler {
         }
 
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
-            MediaType mediaType = detector.detect(tis, submd);
+            MediaType mediaType = detector.detect(tis, submd, parseContext);
             if (mediaType != null) {
                 //detect only once
                 submd.set(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE, mediaType.toString());
@@ -246,7 +246,7 @@ class MailContentHandler implements ContentHandler {
             if (extractor.shouldParseEmbedded(metadata)) {
                 // Wrap the InputStream before passing on, as the James provided
                 //  one misses many features we might want eg mark/reset
-                extractor.parseEmbedded(tis, handler, metadata, false);
+                extractor.parseEmbedded(tis, handler, metadata, parseContext, false);
             }
         } catch (SAXException e) {
             throw new MimeException(e);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mbox/MboxParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mbox/MboxParser.java
index 8ea036307..64464383a 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mbox/MboxParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/main/java/org/apache/tika/parser/mbox/MboxParser.java
@@ -143,7 +143,7 @@ public class MboxParser implements Parser {
                     message = null;
 
                     if (extractor.shouldParseEmbedded(mailMetadata)) {
-                        extractor.parseEmbedded(msgStream, xhtml, mailMetadata, true);
+                        extractor.parseEmbedded(msgStream, xhtml, mailMetadata, context, true);
                     }
 
                     if (tracking) {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/test/java/org/apache/tika/parser/mail/RFC822ParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/test/java/org/apache/tika/parser/mail/RFC822ParserTest.java
index 4fa3126bb..42454957f 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/test/java/org/apache/tika/parser/mail/RFC822ParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-mail-module/src/test/java/org/apache/tika/parser/mail/RFC822ParserTest.java
@@ -326,12 +326,13 @@ public class RFC822ParserTest extends TikaTest {
     @Test
     public void testGetAttachmentsAsEmbeddedResources() throws Exception {
         TrackingHandler tracker = new TrackingHandler();
+        ParseContext context = new ParseContext();
         ContainerExtractor ex = new ParserContainerExtractor(
                 EXTRACT_ALL_ALTERNATIVES_PARSER, ((AutoDetectParser)EXTRACT_ALL_ALTERNATIVES_PARSER).getDetector());
         try (TikaInputStream tis = TikaInputStream
                 .get(getStream("test-documents/testRFC822-multipart"))) {
-            assertEquals(true, ex.isSupported(tis));
-            ex.extract(tis, ex, tracker);
+            assertEquals(true, ex.isSupported(tis, context));
+            ex.extract(tis, ex, tracker, context);
         }
 
         // Check we found all 3 parts
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/detect/microsoft/POIFSContainerDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/detect/microsoft/POIFSContainerDetector.java
index ffe950911..d8876dfa0 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/detect/microsoft/POIFSContainerDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/detect/microsoft/POIFSContainerDetector.java
@@ -49,6 +49,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.microsoft.OfficeParser;
 
 /**
@@ -582,15 +583,12 @@ public class POIFSContainerDetector implements Detector {
     }
 
     /**
-     * If a TikaInputStream is passed in to {@link #detect(InputStream, Metadata)},
+     * If a TikaInputStream is passed in to {@link #detect(InputStream, Metadata, ParseContext)},
      * and there is not an underlying file, this detector will spool up to {@link #markLimit}
      * to disk.  If the stream was read in entirety (e.g. the spooled file is not truncated),
      * this detector will open the file with POI and perform detection.
      * If the spooled file is truncated, the detector will return {@link #OLE} (or
      * {@link MediaType#OCTET_STREAM} if there's no OLE header).
-     * <p>
-     * As of Tika 1.21, this detector respects the legacy behavior of not performing detection
-     * on a non-TikaInputStream.
      *
      * @param markLimit
      */
@@ -631,7 +629,7 @@ public class POIFSContainerDetector implements Detector {
         }
     }
 
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         // Check if we have access to the document
         if (tis == null) {
             return MediaType.OCTET_STREAM;
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/AbstractPOIFSExtractor.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/AbstractPOIFSExtractor.java
index ab7274819..d53fb36c1 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/AbstractPOIFSExtractor.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/AbstractPOIFSExtractor.java
@@ -174,7 +174,7 @@ abstract class AbstractPOIFSExtractor {
                 Detector detector = new DefaultZipContainerDetector();
                 MediaType type = null;
                 try {
-                    type = detector.detect(tis, metadata);
+                    type = detector.detect(tis, metadata, context);
                 } catch (SecurityException e) {
                     throw e;
                 } catch (Exception e) {
@@ -306,7 +306,7 @@ abstract class AbstractPOIFSExtractor {
         }
         try (TikaInputStream tis = TikaInputStream.get(inp)) {
             // Try to work out what it is
-            MediaType mediaType = getDetector().detect(tis, metadata);
+            MediaType mediaType = getDetector().detect(tis, metadata, context);
             String extension = type.getExtension();
             try {
                 MimeType mimeType =
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/EMFParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/EMFParser.java
index 689a83d9b..be7b252ca 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/EMFParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/EMFParser.java
@@ -76,13 +76,12 @@ public class EMFParser implements Parser {
 
     private static void handleEmbedded(byte[] data,
                                        EmbeddedDocumentExtractor embeddedDocumentExtractor,
-                                       ContentHandler handler) throws TikaException, SAXException {
+                                       ContentHandler handler, ParseContext context) throws TikaException, SAXException {
         try (TikaInputStream tis = TikaInputStream.get(data)) {
             Metadata embeddedMetadata = new Metadata();
             if (embeddedDocumentExtractor.shouldParseEmbedded(embeddedMetadata)) {
                 embeddedDocumentExtractor
-                        .parseEmbedded(tis, new EmbeddedContentHandler(handler), embeddedMetadata,
-                                true);
+                        .parseEmbedded(tis, new EmbeddedContentHandler(handler), embeddedMetadata, context, true);
             }
         } catch (IOException e) {
             //swallow
@@ -213,14 +212,14 @@ public class EMFParser implements Parser {
                         EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context);
             }
             handleMultiFormats((HemfComment.EmfCommentDataMultiformats) commentData,
-                    xhtml, parseState.extractor);
+                    xhtml, parseState.extractor, context);
         } else if (commentData instanceof HemfComment.EmfCommentDataWMF) {
             if (parseState.extractor == null) {
                 parseState.extractor =
                         EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context);
             }
             handleWMF(((HemfComment.EmfCommentDataWMF) commentData).getWMFData(), xhtml,
-                    parseState.extractor);
+                    parseState.extractor, context);
         } else if (commentData instanceof HemfComment.EmfCommentDataGeneric) {
             String val =
                     tryToReadAsString((((HemfComment.EmfCommentDataGeneric) commentData).getPrivateData()));
@@ -250,7 +249,8 @@ public class EMFParser implements Parser {
     }
 
     private void handleWMF(byte[] bytes, ContentHandler contentHandler,
-                           EmbeddedDocumentExtractor embeddedDocumentExtractor)
+                           EmbeddedDocumentExtractor embeddedDocumentExtractor,
+                           ParseContext context)
             throws IOException, SAXException, TikaException {
         Metadata embeddedMetadata = new Metadata();
         embeddedMetadata.set(Metadata.CONTENT_TYPE, WMF_MEDIA_TYPE.toString());
@@ -258,7 +258,7 @@ public class EMFParser implements Parser {
             try (TikaInputStream tis = TikaInputStream.get(bytes)) {
                 embeddedDocumentExtractor
                         .parseEmbedded(tis, new EmbeddedContentHandler(contentHandler),
-                                embeddedMetadata, true);
+                                embeddedMetadata, context, true);
 
             }
 
@@ -268,12 +268,13 @@ public class EMFParser implements Parser {
 
     private void handleMultiFormats(HemfComment.EmfCommentDataMultiformats commentData,
                                     ContentHandler handler,
-                                    EmbeddedDocumentExtractor embeddedDocumentExtractor)
+                                    EmbeddedDocumentExtractor embeddedDocumentExtractor,
+                                    ParseContext context)
             throws IOException, TikaException, SAXException {
 
         for (HemfComment.EmfCommentDataFormat dataFormat : commentData.getFormats()) {
             //is this right?!
-            handleEmbedded(dataFormat.getRawData(), embeddedDocumentExtractor, handler);
+            handleEmbedded(dataFormat.getRawData(), embeddedDocumentExtractor, handler, context);
         }
     }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java
index c86608f13..b58c7c07b 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/HSLFExtractor.java
@@ -622,7 +622,7 @@ public class HSLFExtractor extends AbstractPOIFSExtractor {
             if ("Excel.Chart.8".equals(progId)) {
                 mediaType = "application/vnd.ms-excel";
             } else {
-                MediaType mt = getDetector().detect(tis, new Metadata());
+                MediaType mt = getDetector().detect(tis, new Metadata(), context);
                 mediaType = mt.toString();
             }
             if (mediaType
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java
index bd97c025c..a29465eb1 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java
@@ -129,7 +129,7 @@ public class OfficeParser extends AbstractOfficeParser {
             if (embeddedDocumentExtractor.shouldParseEmbedded(m)) {
                 embeddedDocumentExtractor.parseEmbedded(
                         //pass in space character so that we don't trigger a zero-byte exception
-                        TikaInputStream.get(new byte[]{'\u0020'}), xhtml, m, true);
+                        TikaInputStream.get(new byte[]{'\u0020'}), xhtml, m, new ParseContext(), true);
             }
             return;
         }
@@ -143,7 +143,7 @@ public class OfficeParser extends AbstractOfficeParser {
             }
             if (embeddedDocumentExtractor.shouldParseEmbedded(m)) {
                 try (TikaInputStream tis = TikaInputStream.get(e.getValue().getBytes(StandardCharsets.UTF_8))) {
-                    embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, true);
+                    embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, new ParseContext(), true);
                 }
             }
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OutlookExtractor.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OutlookExtractor.java
index 35e56be0f..f8631d513 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OutlookExtractor.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/OutlookExtractor.java
@@ -814,7 +814,7 @@ public class OutlookExtractor extends AbstractPOIFSExtractor {
             if (html != null && html.length() > 0) {
                 Charset charset = null;
                 try (TikaInputStream tis = TikaInputStream.get(html.getBytes(UTF_8))) {
-                    charset = detector.detect(tis, EMPTY_METADATA);
+                    charset = detector.detect(tis, EMPTY_METADATA, context);
                 } catch (IOException e) {
                     //swallow
                 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/TNEFParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/TNEFParser.java
index 014206fd7..f7bc1730b 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/TNEFParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/TNEFParser.java
@@ -85,7 +85,7 @@ public class TNEFParser implements Parser {
         if (attr != null && attr instanceof MAPIRtfAttribute) {
             MAPIRtfAttribute rtf = (MAPIRtfAttribute) attr;
             handleEmbedded("message.rtf", "application/rtf", rtf.getData(), embeddedExtractor,
-                    xhtml);
+                    xhtml, context);
         }
 
         // Recurse into each attachment in turn
@@ -100,13 +100,14 @@ public class TNEFParser implements Parser {
                     name = "unknown" + ext;
                 }
             }
-            handleEmbedded(name, null, attachment.getContents(), embeddedExtractor, xhtml);
+            handleEmbedded(name, null, attachment.getContents(), embeddedExtractor, xhtml, context);
         }
         xhtml.endDocument();
     }
 
     private void handleEmbedded(String name, String type, byte[] contents,
-                                EmbeddedDocumentExtractor embeddedExtractor, ContentHandler handler)
+                                EmbeddedDocumentExtractor embeddedExtractor, ContentHandler handler,
+                                ParseContext context)
             throws IOException, SAXException, TikaException {
         Metadata metadata = new Metadata();
         if (name != null) {
@@ -118,7 +119,7 @@ public class TNEFParser implements Parser {
 
         if (embeddedExtractor.shouldParseEmbedded(metadata)) {
             embeddedExtractor.parseEmbedded(TikaInputStream.get(contents),
-                    new EmbeddedContentHandler(handler), metadata, true);
+                    new EmbeddedContentHandler(handler), metadata, context, true);
         }
     }
 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/libpst/EmailVisitor.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/libpst/EmailVisitor.java
index d9cb6b9d2..30070bc23 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/libpst/EmailVisitor.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/libpst/EmailVisitor.java
@@ -79,7 +79,7 @@ public class EmailVisitor implements FileVisitor<Path> {
         emailMetadata.set(PST.PST_FOLDER_PATH, pstPath);
         try (TikaInputStream tis = TikaInputStream.get(file)) {
             try {
-                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, emailMetadata, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, emailMetadata, new ParseContext(), true);
             } catch (SAXException e) {
                 throw new IOException(e);
             }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/OneNoteTreeWalker.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/OneNoteTreeWalker.java
index 8d19ce055..2ca1ef25d 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/OneNoteTreeWalker.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/OneNoteTreeWalker.java
@@ -352,6 +352,7 @@ class OneNoteTreeWalker {
             return;
         }
         Metadata embeddedMetadata = new Metadata();
+        ParseContext parseContext = new ParseContext();
         try {
             AttributesImpl attributes = new AttributesImpl();
             attributes.addAttribute("", "class", "class", "CDATA", "embedded");
@@ -359,7 +360,7 @@ class OneNoteTreeWalker {
             xhtml.endElement("div");
             tis = TikaInputStream.get(buf.array());
             embeddedDocumentExtractor.parseEmbedded(tis, new EmbeddedContentHandler(xhtml),
-                    embeddedMetadata, false);
+                    embeddedMetadata, parseContext, false);
         } finally {
             IOUtils.closeQuietly(tis);
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java
index 6ed24e600..8d885a4c5 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/AbstractOOXMLExtractor.java
@@ -199,7 +199,7 @@ public abstract class AbstractOOXMLExtractor implements OOXMLExtractor {
 
                     if (embeddedExtractor.shouldParseEmbedded(thumbnailMetadata)) {
                         embeddedExtractor.parseEmbedded(TikaInputStream.get(tStream),
-                                new EmbeddedContentHandler(handler), thumbnailMetadata, false);
+                                new EmbeddedContentHandler(handler), thumbnailMetadata, context, false);
                     }
                 }
             }
@@ -364,8 +364,7 @@ public abstract class AbstractOOXMLExtractor implements OOXMLExtractor {
                 tis = TikaInputStream.get(fs.createDocumentInputStream(packageEntryName));
                 if (embeddedExtractor.shouldParseEmbedded(metadata)) {
                     embeddedExtractor
-                            .parseEmbedded(tis, xhtml, metadata,
-                                    true);
+                            .parseEmbedded(tis, xhtml, metadata, context, true);
                 }
             } else if (POIFSDocumentType.OLE10_NATIVE == type) {
                 // TIKA-704: OLE 1.0 embedded document
@@ -386,8 +385,7 @@ public abstract class AbstractOOXMLExtractor implements OOXMLExtractor {
 
                 if (tis != null && embeddedExtractor.shouldParseEmbedded(metadata)) {
                     embeddedExtractor
-                            .parseEmbedded(tis, xhtml, metadata,
-                                    true);
+                            .parseEmbedded(tis, xhtml, metadata, context, true);
                 }
             } else {
                 handleEmbeddedFile(part, xhtml, rel, embeddedPartMetadata,
@@ -465,7 +463,7 @@ public abstract class AbstractOOXMLExtractor implements OOXMLExtractor {
         if (embeddedExtractor.shouldParseEmbedded(metadata)) {
             try (TikaInputStream tis = TikaInputStream.get(part.getInputStream())) {
                 embeddedExtractor
-                        .parseEmbedded(tis, xhtml, metadata, true);
+                        .parseEmbedded(tis, xhtml, metadata, context, true);
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/BinaryDataHandler.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/BinaryDataHandler.java
index 284770ce2..79d757863 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/BinaryDataHandler.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/xwpf/ml2006/BinaryDataHandler.java
@@ -66,7 +66,7 @@ class BinaryDataHandler extends AbstractPartHandler {
                     EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(parseContext);
             Metadata embeddedMetadata = new Metadata();
             try (TikaInputStream tis = TikaInputStream.get(getInputStream())) {
-                embeddedDocumentExtractor.parseEmbedded(tis, handler, embeddedMetadata, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, handler, embeddedMetadata, parseContext, true);
             } catch (IOException e) {
                 throw new TikaException("error in finishing part", e);
             }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/OutlookPSTParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/OutlookPSTParser.java
index 628ba7e00..44d470cd3 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/OutlookPSTParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/OutlookPSTParser.java
@@ -120,7 +120,7 @@ public class OutlookPSTParser implements Parser {
                 metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, pstMail.getSubject() + ".msg");
                 long length = estimateSize(pstMail);
                 try (TikaInputStream tis = TikaInputStream.getFromContainer(pstMail, length, metadata)) {
-                    embeddedExtractor.parseEmbedded(tis, handler, metadata, true);
+                    embeddedExtractor.parseEmbedded(tis, handler, metadata, new ParseContext(), true);
                 }
                 pstMail = (PSTMessage) pstFolder.getNextChild();
             }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/PSTMailItemParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/PSTMailItemParser.java
index c1c5f09d0..66cf4f767 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/PSTMailItemParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/pst/PSTMailItemParser.java
@@ -210,7 +210,7 @@ public class PSTMailItemParser implements Parser {
         for (int i = 0; i < numberOfAttachments; i++) {
             try {
                 PSTAttachment attachment = email.getAttachment(i);
-                parseMailAttachment(xhtml, attachment, metadata, embeddedExtractor);
+                parseMailAttachment(xhtml, attachment, metadata, embeddedExtractor, context);
             } catch (Exception e) {
                 EmbeddedDocumentUtil.recordEmbeddedStreamException(e, metadata);
             }
@@ -218,8 +218,8 @@ public class PSTMailItemParser implements Parser {
     }
 
     private void parseMailAttachment(XHTMLContentHandler xhtml, PSTAttachment attachment, Metadata metadata,
-                                     EmbeddedDocumentExtractor embeddedExtractor) throws PSTException, IOException,
-            TikaException, SAXException {
+                                     EmbeddedDocumentExtractor embeddedExtractor, ParseContext context)
+            throws PSTException, IOException, TikaException, SAXException {
 
         PSTMessage attachedEmail = attachment.getEmbeddedPSTMessage();
         //check for whether this is a binary attachment or an embedded pst msg
@@ -230,7 +230,7 @@ public class PSTMailItemParser implements Parser {
                 attachMetadata.set(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE, PSTMailItemParser.PST_MAIL_ITEM_STRING);
                 attachMetadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, attachedEmail.getSubject() + ".msg");
                 attachMetadata.set(TikaCoreProperties.EMBEDDED_RESOURCE_TYPE, TikaCoreProperties.EmbeddedResourceType.ATTACHMENT.name());
-                embeddedExtractor.parseEmbedded(tis, xhtml, attachMetadata, true);
+                embeddedExtractor.parseEmbedded(tis, xhtml, attachMetadata, context, true);
             }
             return;
         }
@@ -262,7 +262,7 @@ public class PSTMailItemParser implements Parser {
             }
 
             try {
-                embeddedExtractor.parseEmbedded(tis, xhtml, attachMeta, false);
+                embeddedExtractor.parseEmbedded(tis, xhtml, attachMeta, context, false);
             } finally {
                 tis.close();
             }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/xml/WordMLParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/xml/WordMLParser.java
index dc623a0c1..f18b09636 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/xml/WordMLParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/xml/WordMLParser.java
@@ -83,7 +83,7 @@ public class WordMLParser extends AbstractXML2003Parser {
 
         return new TeeContentHandler(super.getContentHandler(ch, metadata, context),
                 new WordMLHandler(ch), new HyperlinkHandler(ch, WORD_ML_URL),
-                new PictHandler(ch, metadata,
+                new PictHandler(ch, metadata, context,
                         EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context)));
     }
 
@@ -181,16 +181,18 @@ public class WordMLParser extends AbstractXML2003Parser {
         final ContentHandler handler;
         final Base64 base64 = new Base64();
         byte[] rawBytes = null;
+        final ParseContext parseContext;
         EmbeddedDocumentExtractor embeddedDocumentExtractor;
         boolean inPict = false;
         boolean inBin = false;
         String pictName = null;
         String pictSource = null;
 
-        public PictHandler(ContentHandler handler, Metadata metadata,
+        public PictHandler(ContentHandler handler, Metadata metadata, ParseContext parseContext,
                            EmbeddedDocumentExtractor embeddedDocumentExtractor) {
             this.handler = handler;
             this.parentMetadata = metadata;
+            this.parseContext = parseContext;
             this.embeddedDocumentExtractor = embeddedDocumentExtractor;
         }
 
@@ -287,7 +289,7 @@ public class WordMLParser extends AbstractXML2003Parser {
                         metadata.set(TikaCoreProperties.ORIGINAL_RESOURCE_NAME, pictSource);
                     }
                     if (embeddedDocumentExtractor.shouldParseEmbedded(metadata)) {
-                        embeddedDocumentExtractor.parseEmbedded(tis, handler, metadata, outputHtml);
+                        embeddedDocumentExtractor.parseEmbedded(tis, handler, metadata, parseContext, outputHtml);
                     }
                 } catch (IOException e) {
                     //log
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/detect/microsoft/POIFSContainerDetectorTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/detect/microsoft/POIFSContainerDetectorTest.java
index a9d3923fb..564b113d6 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/detect/microsoft/POIFSContainerDetectorTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/detect/microsoft/POIFSContainerDetectorTest.java
@@ -29,6 +29,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class POIFSContainerDetectorTest extends TikaTest {
 
@@ -78,7 +79,7 @@ public class POIFSContainerDetectorTest extends TikaTest {
     }
 
     private void assertExpected(Detector detector, TikaInputStream tis, String expectedMime, String expectedDigest) throws IOException {
-        MediaType mt = detector.detect(tis, new Metadata());
+        MediaType mt = detector.detect(tis, new Metadata(), new ParseContext());
         assertEquals(expectedMime, mt.toString());
         assertEquals(expectedDigest, digest(tis));
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/AbstractPOIContainerExtractionTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/AbstractPOIContainerExtractionTest.java
index a65e6822d..cde05890d 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/AbstractPOIContainerExtractionTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/AbstractPOIContainerExtractionTest.java
@@ -25,6 +25,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.extractor.ContainerExtractor;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Parent class of tests that the various POI powered parsers are
@@ -61,15 +62,16 @@ public abstract class AbstractPOIContainerExtractionTest extends TikaTest {
 
     protected TrackingHandler process(String filename, ContainerExtractor extractor,
                                       boolean recurse) throws Exception {
+        ParseContext context = new ParseContext();
         try (TikaInputStream tis = getTestFile(filename)) {
-            assertEquals(true, extractor.isSupported(tis));
+            assertEquals(true, extractor.isSupported(tis, context));
 
             // Process it
             TrackingHandler handler = new TrackingHandler();
             if (recurse) {
-                extractor.extract(tis, extractor, handler);
+                extractor.extract(tis, extractor, handler, context);
             } else {
-                extractor.extract(tis, null, handler);
+                extractor.extract(tis, null, handler, context);
             }
 
             // So they can check what happened
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ExcelParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ExcelParserTest.java
index 255bf4d02..211d05b27 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ExcelParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ExcelParserTest.java
@@ -288,7 +288,7 @@ public class ExcelParserTest extends TikaTest {
         m = new Metadata();
         m.add(TikaCoreProperties.RESOURCE_NAME_KEY, "excel_5.xls");
         try (TikaInputStream tis = getResourceAsStream("/test-documents/testEXCEL_5.xls")) {
-            type = detector.detect(tis, m);
+            type = detector.detect(tis, m, new ParseContext());
             assertEquals("application/vnd.ms-excel", type.toString());
         }
 
@@ -296,7 +296,7 @@ public class ExcelParserTest extends TikaTest {
         m = new Metadata();
         m.add(TikaCoreProperties.RESOURCE_NAME_KEY, "excel_95.xls");
         try (TikaInputStream tis = getResourceAsStream("/test-documents/testEXCEL_95.xls")) {
-            type = detector.detect(tis, m);
+            type = detector.detect(tis, m, new ParseContext());
             assertEquals("application/vnd.ms-excel", type.toString());
         }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/OldExcelParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/OldExcelParserTest.java
index d66f7789a..83bf179ff 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/OldExcelParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/OldExcelParserTest.java
@@ -44,7 +44,7 @@ public class OldExcelParserTest extends TikaTest {
         Detector detector = new DefaultDetector();
         try (TikaInputStream tis = getTestFile(file)) {
             assertEquals(MediaType.application("vnd.ms-excel.sheet.4"),
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/TNEFParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/TNEFParserTest.java
index cf16d83da..1ca031c17 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/TNEFParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/TNEFParserTest.java
@@ -43,7 +43,7 @@ public class TNEFParserTest extends AbstractPOIContainerExtractionTest {
         Detector detector = new DefaultDetector();
         try (TikaInputStream tis = getTestFile(file)) {
             assertEquals(MediaType.application("vnd.ms-tnef"),
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
         }
     }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java
index add6b9ea9..1b7b08db5 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/ooxml/OOXMLParserTest.java
@@ -1465,7 +1465,7 @@ public class OOXMLParserTest extends MultiThreadedTikaTest {
         // Should be detected correctly
         MediaType type;
         try (TikaInputStream tis = getResourceAsStream("/test-documents/testEXCEL.xlsb")) {
-            type = detector.detect(tis, m);
+            type = detector.detect(tis, m, new ParseContext());
             assertEquals("application/vnd.ms-excel.sheet.binary.macroenabled.12", type.toString());
         }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/rtf/RTFParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/rtf/RTFParserTest.java
index e214d8050..33243c963 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/rtf/RTFParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/test/java/org/apache/tika/parser/microsoft/rtf/RTFParserTest.java
@@ -40,6 +40,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.Office;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 
 /**
@@ -364,11 +365,12 @@ public class RTFParserTest extends TikaTest {
     @Test
     public void testBinControlWord() throws Exception {
         ByteCopyingHandler embHandler = new ByteCopyingHandler();
+        ParseContext context = new ParseContext();
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsStream("/test-documents/testBinControlWord.rtf"))) {
             ContainerExtractor ex = new ParserContainerExtractor();
-            assertEquals(true, ex.isSupported(tis));
-            ex.extract(tis, ex, embHandler);
+            assertEquals(true, ex.isSupported(tis, context));
+            ex.extract(tis, ex, embHandler, context);
         }
         assertEquals(1, embHandler.bytes.size());
 
@@ -420,12 +422,13 @@ public class RTFParserTest extends TikaTest {
         skipTypes.add(MediaType.parse("image/emf"));
         skipTypes.add(MediaType.parse("image/wmf"));
 
+        ParseContext context = new ParseContext();
         TrackingHandler tracker = new TrackingHandler(skipTypes);
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsStream("/test-documents/testRTFEmbeddedLink.rtf"))) {
             ContainerExtractor ex = new ParserContainerExtractor();
-            assertEquals(true, ex.isSupported(tis));
-            ex.extract(tis, ex, tracker);
+            assertEquals(true, ex.isSupported(tis, context));
+            ex.extract(tis, ex, tracker, context);
         }
         //should gracefully skip link and not throw NPE, IOEx, etc
         assertEquals(0, tracker.filenames.size());
@@ -434,8 +437,8 @@ public class RTFParserTest extends TikaTest {
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsStream("/test-documents/testRTFEmbeddedLink.rtf"))) {
             ContainerExtractor ex = new ParserContainerExtractor();
-            assertEquals(true, ex.isSupported(tis));
-            ex.extract(tis, ex, tracker);
+            assertEquals(true, ex.isSupported(tis, context));
+            ex.extract(tis, ex, tracker, context);
         }
         //should gracefully skip link and not throw NPE, IOEx, etc
         assertEquals(2, tracker.filenames.size());
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/detect/ole/MiscOLEDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/detect/ole/MiscOLEDetector.java
index d125b0960..dc297bccc 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/detect/ole/MiscOLEDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/detect/ole/MiscOLEDetector.java
@@ -34,6 +34,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 /**
  * TODO: refactor this copy/paste from POIFSContainerDetector
  */
@@ -163,7 +164,7 @@ public class MiscOLEDetector implements Detector {
     }
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         // Check if we have access to the document
         if (tis == null) {
             return MediaType.OCTET_STREAM;
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dbf/DBFParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dbf/DBFParser.java
index 29f534133..eceec3d22 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dbf/DBFParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dbf/DBFParser.java
@@ -86,7 +86,7 @@ public class DBFParser implements Parser {
             row = reader.next();
         }
 
-        Charset charset = getCharset(firstRows, header);
+        Charset charset = getCharset(firstRows, header, context);
         metadata.set(Metadata.CONTENT_ENCODING, charset.toString());
 
         XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
@@ -118,7 +118,7 @@ public class DBFParser implements Parser {
         xhtml.endDocument();
     }
 
-    private Charset getCharset(List<DBFRow> firstRows, DBFFileHeader header)
+    private Charset getCharset(List<DBFRow> firstRows, DBFFileHeader header, ParseContext parseContext)
             throws IOException, TikaException {
         //TODO: potentially use codepage info in the header
         Charset charset = DEFAULT_CHARSET;
@@ -138,7 +138,7 @@ public class DBFParser implements Parser {
         if (bytes.length > 20) {
             EncodingDetector detector = new Icu4jEncodingDetector();
             try (TikaInputStream tis = TikaInputStream.get(bytes)) {
-                charset = detector.detect(tis, new Metadata());
+                charset = detector.detect(TikaInputStream.get(bytes), new Metadata(), parseContext);
             }
         }
         return charset;
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dif/DIFParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dif/DIFParser.java
index 9e4926346..c8059f7c7 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dif/DIFParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/dif/DIFParser.java
@@ -21,6 +21,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.commons.io.input.CloseShieldInputStream;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
@@ -62,7 +63,7 @@ public class DIFParser implements Parser {
         TaggedContentHandler tagged = new TaggedContentHandler(handler);
         tis.setCloseShield();
         try {
-            XMLReaderUtils.parseSAX(tis,
+            XMLReaderUtils.parseSAX(CloseShieldInputStream.wrap(tis),
                             new EmbeddedContentHandler(
                                     getContentHandler(tagged, metadata, context)),
                     context);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/epub/EpubParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/epub/EpubParser.java
index 225ea94b1..dc01d344d 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/epub/EpubParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/epub/EpubParser.java
@@ -284,7 +284,7 @@ public class EpubParser implements Parser {
                 }
                 if (shouldHandleEmbedded(hRefMediaPair.media)) {
                     handleEmbedded(zipFile, relativePath, hRefMediaPair, embeddedDocumentExtractor,
-                            xhtml, metadata);
+                            xhtml, metadata, context);
                 }
             }
         }
@@ -354,7 +354,8 @@ public class EpubParser implements Parser {
 
     private void handleEmbedded(ZipFile zipFile, String relativePath, HRefMediaPair hRefMediaPair,
                                 EmbeddedDocumentExtractor embeddedDocumentExtractor,
-                                XHTMLContentHandler xhtml, Metadata parentMetadata)
+                                XHTMLContentHandler xhtml, Metadata parentMetadata,
+                                ParseContext context)
             throws IOException, SAXException {
         if (hRefMediaPair.href == null) {
             return;
@@ -390,8 +391,7 @@ public class EpubParser implements Parser {
                 outputHtml = false;
             }
             embeddedDocumentExtractor
-                    .parseEmbedded(tis, new EmbeddedContentHandler(xhtml), embeddedMetadata,
-                            outputHtml);
+                    .parseEmbedded(tis, new EmbeddedContentHandler(xhtml), embeddedMetadata, context, outputHtml);
 
         } finally {
             IOUtils.closeQuietly(tis);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/FlatOpenDocumentMacroHandler.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/FlatOpenDocumentMacroHandler.java
index 4688cda1a..92d95a9d3 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/FlatOpenDocumentMacroHandler.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/FlatOpenDocumentMacroHandler.java
@@ -109,7 +109,7 @@ class FlatOpenDocumentMacroHandler extends ContentHandlerDecorator {
         if (embeddedDocumentExtractor.shouldParseEmbedded(embeddedMetadata)) {
             try (TikaInputStream tis = TikaInputStream.get(bytes)) {
                 embeddedDocumentExtractor
-                        .parseEmbedded(tis, contentHandler, embeddedMetadata, true);
+                        .parseEmbedded(tis, contentHandler, embeddedMetadata, parseContext, true);
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentBodyHandler.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentBodyHandler.java
index 0fbe29a74..03197f669 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentBodyHandler.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentBodyHandler.java
@@ -529,7 +529,7 @@ class OpenDocumentBodyHandler extends ElementMappingContentHandler {
         Metadata embeddedMetadata = new Metadata();
         if (embeddedDocumentExtractor.shouldParseEmbedded(embeddedMetadata)) {
             try (TikaInputStream tis = TikaInputStream.get(bytes)) {
-                embeddedDocumentExtractor.parseEmbedded(tis, handler, embeddedMetadata, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, handler, embeddedMetadata, parseContext, true);
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java
index 7b8198b94..e6f192ee0 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-miscoffice-module/src/main/java/org/apache/tika/parser/odf/OpenDocumentParser.java
@@ -278,16 +278,17 @@ public class OpenDocumentParser implements Parser {
                         tisZip.getFile();
                         MediaType embeddedMimeType = embeddedDocumentUtil
                                 .getDetector()
-                                .detect(tisZip, embeddedMetadata);
+                                .detect(tisZip, embeddedMetadata, context);
                         if (embeddedMimeType != null) {
                             embeddedMetadata.set(Metadata.CONTENT_TYPE, embeddedMimeType.toString());
                         }
                         tisZip.reset();
                     }
 
-                    if (embeddedDocumentUtil.shouldParseEmbedded(embeddedMetadata)) {
-                        embeddedDocumentUtil.parseEmbedded(tisZip, new EmbeddedContentHandler(handler), embeddedMetadata, false);
-                    }
+                if (embeddedDocumentUtil.shouldParseEmbedded(embeddedMetadata)) {
+                    embeddedDocumentUtil.parseEmbedded(tisZip, new EmbeddedContentHandler(handler),
+                            embeddedMetadata, false);
+                }
             } else if (extractMacros && embeddedName.contains("Basic/")) {
                 //process all files under Basic/; let maybeHandleMacro figure
                 //out if it is a macro or not
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/AbstractPDF2XHTML.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/AbstractPDF2XHTML.java
index 275e13204..3e1bcc398 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/AbstractPDF2XHTML.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/AbstractPDF2XHTML.java
@@ -334,7 +334,7 @@ class AbstractPDF2XHTML extends PDFTextStripper {
             throws IOException, SAXException {
         try {
             embeddedDocumentExtractor.parseEmbedded(tis, new EmbeddedContentHandler(xhtml),
-                    embeddedMetadata, true);
+                    embeddedMetadata, context, true);
         } catch (IOException e) {
             handleCatchableIOE(e);
         }
@@ -503,7 +503,7 @@ class AbstractPDF2XHTML extends PDFTextStripper {
 
         try {
             embeddedDocumentExtractor.parseEmbedded(tis, new EmbeddedContentHandler(xhtml),
-                    embeddedMetadata, false);
+                    embeddedMetadata, context, false);
         } finally {
             IOUtils.closeQuietly(tis);
         }
@@ -863,7 +863,7 @@ class AbstractPDF2XHTML extends PDFTextStripper {
         Metadata m = getJavascriptMetadata("3DD_ON_INSTANTIATE", null, null);
         if (embeddedDocumentExtractor.shouldParseEmbedded(m)) {
             try (TikaInputStream tis = TikaInputStream.get(stream.createInputStream())) {
-                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, context, true);
             }
         }
         AttributesImpl attrs = new AttributesImpl();
@@ -1056,7 +1056,7 @@ class AbstractPDF2XHTML extends PDFTextStripper {
         js = (js == null) ? "" : js;
         if (embeddedDocumentExtractor.shouldParseEmbedded(m)) {
             try (TikaInputStream tis = TikaInputStream.get(js.getBytes(StandardCharsets.UTF_8))) {
-                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, m, context, true);
             }
         };
         addNonNullAttribute("class", "javascript", attrs);
@@ -1202,7 +1202,7 @@ class AbstractPDF2XHTML extends PDFTextStripper {
             if (embeddedDocumentExtractor.shouldParseEmbedded(updateMetadata)) {
                 try (TikaInputStream tis = TikaInputStream.get(update)) {
                     context.set(IsIncrementalUpdate.class, IsIncrementalUpdate.IS_INCREMENTAL_UPDATE);
-                    embeddedDocumentExtractor.parseEmbedded(tis, xhtml, updateMetadata, false);
+                    embeddedDocumentExtractor.parseEmbedded(tis, xhtml, updateMetadata, context, false);
                 }
             }
         } finally {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDF2XHTML.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDF2XHTML.java
index 3456a8791..037ac2695 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDF2XHTML.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDF2XHTML.java
@@ -177,7 +177,7 @@ class PDF2XHTML extends AbstractPDF2XHTML {
                         try (TikaInputStream resultInputStream = result.getInputStream()) {
                             //TODO: add markup here?
                             embeddedDocumentExtractor.parseEmbedded(resultInputStream, xhtml,
-                                    result.getMetadata(), true);
+                                    result.getMetadata(), context, true);
                         }
                     }
                 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
index 682134187..f2f61a264 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
@@ -464,8 +464,7 @@ public class PDFParser implements Parser, RenderingParser {
             if (result.getStatus() == RenderResult.STATUS.SUCCESS) {
                 if (embeddedDocumentExtractor.shouldParseEmbedded(result.getMetadata())) {
                     try (TikaInputStream tis = result.getInputStream()) {
-                        embeddedDocumentExtractor.parseEmbedded(tis, xhtml, result.getMetadata(),
-                                false);
+                        embeddedDocumentExtractor.parseEmbedded(tis, xhtml, result.getMetadata(), context, false);
                     } catch (SecurityException e) {
                         throw e;
                     } catch (Exception e) {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/image/ImageGraphicsEngine.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/image/ImageGraphicsEngine.java
index 7a441e3fc..17b802d14 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/image/ImageGraphicsEngine.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/image/ImageGraphicsEngine.java
@@ -431,8 +431,7 @@ public class ImageGraphicsEngine extends PDFGraphicsStreamEngine {
                     tis.setOpenContainer(bufferedImage);
                 }
                 embeddedDocumentExtractor
-                        .parseEmbedded(tis, new EmbeddedContentHandler(xhtml), metadata,
-                                false);
+                        .parseEmbedded(tis, new EmbeddedContentHandler(xhtml), metadata, parseContext, false);
             }
         }
 
@@ -453,7 +452,7 @@ public class ImageGraphicsEngine extends PDFGraphicsStreamEngine {
             parseContext.set(ZeroByteFileException.IgnoreZeroByteFileException.class,
                     ZeroByteFileException.IGNORE_ZERO_BYTE_FILE_EXCEPTION);
             embeddedDocumentExtractor.parseEmbedded(TikaInputStream.get(new byte[0]),
-                    new EmbeddedContentHandler(xhtml), metadata, false);
+                    new EmbeddedContentHandler(xhtml), metadata, parseContext, false);
         } finally {
             //replace whatever was there before
             parseContext.set(ZeroByteFileException.IgnoreZeroByteFileException.class, before);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/detect/gzip/GZipSpecializationDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/detect/gzip/GZipSpecializationDetector.java
index 3f24bf63a..aa54735ac 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/detect/gzip/GZipSpecializationDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/detect/gzip/GZipSpecializationDetector.java
@@ -31,6 +31,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * This is designed to detect commonly gzipped file types such as warc.gz.
@@ -44,7 +45,7 @@ public class GZipSpecializationDetector implements Detector {
     public static MediaType ARC_GZ = MediaType.application("arc+gz");
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (tis == null) {
             return MediaType.OCTET_STREAM;
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/CompressorParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/CompressorParser.java
index 338f8cde6..03be853bb 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/CompressorParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/CompressorParser.java
@@ -257,7 +257,7 @@ public class CompressorParser implements Parser {
                     EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context);
             if (extractor.shouldParseEmbedded(entrydata)) {
                 try (TikaInputStream inner = TikaInputStream.get(cis)) {
-                    extractor.parseEmbedded(inner, xhtml, entrydata, true);
+                    extractor.parseEmbedded(inner, xhtml, entrydata, context, true);
                 }
             }
         } finally {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
index a65b39d48..3e49db3b2 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/PackageParser.java
@@ -51,7 +51,6 @@ import org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException;
 import org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException.Feature;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
-import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
@@ -244,20 +243,24 @@ public class PackageParser extends AbstractEncodingDetectorParser {
         return SUPPORTED_TYPES;
     }
 
-
     public void parse(TikaInputStream tis, ContentHandler handler, Metadata metadata,
-                ParseContext context)
-            throws TikaException, IOException, SAXException {
+                      ParseContext context) throws IOException, SAXException, TikaException {
+
+        // TikaInputStream always supports mark
+
+        TemporaryResources tmp = new TemporaryResources();
+        // Shield the TikaInputStream from being closed when we close archive streams.
+        // This allows us to reset and re-read the stream for data descriptor handling.
         tis.setCloseShield();
         try {
-            _parseInternal(tis, handler, metadata, context);
+            _parse(tis, handler, metadata, context, tmp);
         } finally {
             tis.removeCloseShield();
         }
     }
 
-    private void _parseInternal(TikaInputStream tis, ContentHandler handler, Metadata metadata,
-                ParseContext context)
+    private void _parse(TikaInputStream tis, ContentHandler handler, Metadata metadata,
+                ParseContext context, TemporaryResources tmp)
             throws TikaException, IOException, SAXException {
         ArchiveInputStream ais = null;
         String encoding = null;
@@ -324,7 +327,7 @@ public class PackageParser extends AbstractEncodingDetectorParser {
         //this keeps track of how many entries were processed.
         AtomicInteger entryCnt = new AtomicInteger();
         try {
-            parseEntries(ais, metadata, extractor, xhtml, false, entryCnt);
+            parseEntries(ais, metadata, extractor, xhtml, false, entryCnt, context);
         } catch (UnsupportedZipFeatureException zfe) {
             // If this is a zip archive which requires a data descriptor, parse it again
             if (zfe.getFeature() == Feature.DATA_DESCRIPTOR) {
@@ -332,9 +335,8 @@ public class PackageParser extends AbstractEncodingDetectorParser {
                 ais.close();
                 // An exception would be thrown if MARK_LIMIT is not big enough
                 tis.reset();
-                ais = new ZipArchiveInputStream(tis, encoding, true,
-                        true);
-                parseEntries(ais, metadata, extractor, xhtml, true, entryCnt);
+                ais = new ZipArchiveInputStream(tis, encoding, true, true);
+                parseEntries(ais, metadata, extractor, xhtml, true, entryCnt, context);
             }
         } finally {
             ais.close();
@@ -357,7 +359,8 @@ public class PackageParser extends AbstractEncodingDetectorParser {
      */
     private void parseEntries(ArchiveInputStream ais, Metadata metadata,
                               EmbeddedDocumentExtractor extractor, XHTMLContentHandler xhtml,
-                              boolean shouldUseDataDescriptor, AtomicInteger entryCnt)
+                              boolean shouldUseDataDescriptor, AtomicInteger entryCnt,
+                              ParseContext context)
             throws TikaException, IOException, SAXException {
         try {
             ArchiveEntry entry = ais.getNextEntry();
@@ -373,7 +376,7 @@ public class PackageParser extends AbstractEncodingDetectorParser {
                 }
 
                 if (!entry.isDirectory()) {
-                    parseEntry(ais, entry, extractor, metadata, xhtml);
+                    parseEntry(ais, entry, extractor, metadata, xhtml, context);
                 }
 
                 if (!shouldUseDataDescriptor) {
@@ -429,7 +432,7 @@ public class PackageParser extends AbstractEncodingDetectorParser {
 
     private void parseEntry(ArchiveInputStream archive, ArchiveEntry entry,
                             EmbeddedDocumentExtractor extractor, Metadata parentMetadata,
-                            XHTMLContentHandler xhtml)
+                            XHTMLContentHandler xhtml, ParseContext context)
             throws SAXException, IOException, TikaException {
         String name = entry.getName();
         
@@ -446,12 +449,11 @@ public class PackageParser extends AbstractEncodingDetectorParser {
                 }
             }
 
-            Charset candidate =
-                    getEncodingDetector().detect(
-                            TikaInputStream.get(UnsynchronizedByteArrayInputStream.builder().setByteArray(extendedEntryName).get()),
-                            parentMetadata);
-            if (candidate != null) {
-                name = new String(((ZipArchiveEntry) entry).getRawName(), candidate);
+            try (TikaInputStream tis = TikaInputStream.get(extendedEntryName)) {
+                Charset candidate = getEncodingDetector().detect(tis, parentMetadata, context);
+                if (candidate != null) {
+                    name = new String(((ZipArchiveEntry) entry).getRawName(), candidate);
+                }
             }
         }
         
@@ -468,7 +470,7 @@ public class PackageParser extends AbstractEncodingDetectorParser {
                 TemporaryResources tmp = new TemporaryResources();
                 try {
                     TikaInputStream tis = TikaInputStream.get(archive, tmp, entrydata);
-                    extractor.parseEmbedded(tis, xhtml, entrydata, true);
+                    extractor.parseEmbedded(tis, xhtml, entrydata, new ParseContext(), true);
                 } finally {
                     tmp.dispose();
                 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/RarParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/RarParser.java
index 86f0d8726..e5fe82aeb 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/RarParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/RarParser.java
@@ -88,7 +88,7 @@ public class RarParser implements Parser {
                             xhtml);
                     try (TikaInputStream rarTis = TikaInputStream.get(rar.getInputStream(header))) {
                         if (extractor.shouldParseEmbedded(entrydata)) {
-                            extractor.parseEmbedded(rarTis, handler, entrydata, true);
+                            extractor.parseEmbedded(rarTis, handler, entrydata, context, true);
                         }
                     }
                 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/UnrarParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/UnrarParser.java
index b799f9614..cc0f96008 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/UnrarParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pkg-module/src/main/java/org/apache/tika/parser/pkg/UnrarParser.java
@@ -134,7 +134,7 @@ public class UnrarParser implements Parser {
         metadata.set(TikaCoreProperties.ORIGINAL_RESOURCE_NAME, relPath);
         if (extractor.shouldParseEmbedded(metadata)) {
             try (TikaInputStream tis = TikaInputStream.get(embeddedFile)) {
-                extractor.parseEmbedded(tis, xhtml, metadata, true);
+                extractor.parseEmbedded(tis, xhtml, metadata, context, true);
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/strings/StringsParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/strings/StringsParser.java
index 8f222264e..427eabbeb 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/strings/StringsParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/strings/StringsParser.java
@@ -122,7 +122,7 @@ public class StringsParser implements Parser, Initializable {
 
     private String doFile(TikaInputStream tis) throws IOException {
         Metadata tmpMetadata = new Metadata();
-        fileCommandDetector.detect(tis, tmpMetadata);
+        fileCommandDetector.detect(tis, tmpMetadata, new ParseContext());
         return tmpMetadata.get(Metadata.CONTENT_TYPE);
     }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/BOMDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/BOMDetector.java
index 9de408c8c..a952724db 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/BOMDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/BOMDetector.java
@@ -27,6 +27,7 @@ import org.apache.tika.config.TikaComponent;
 import org.apache.tika.detect.EncodingDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 /*
  This is an optional detector that is not loaded automatically by SPI. You need to configure it.
@@ -58,7 +59,7 @@ public class BOMDetector implements EncodingDetector {
         }
     }
     @Override
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         tis.mark(MAX_BYTES);
         byte[] bytes = new byte[MAX_BYTES];
         try {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/Icu4jEncodingDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/Icu4jEncodingDetector.java
index 90ee92fe7..57da40152 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/Icu4jEncodingDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/Icu4jEncodingDetector.java
@@ -29,6 +29,7 @@ import org.apache.tika.detect.EncodingDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.utils.CharsetUtils;
 
 @TikaComponent(spi = false, name = "icu4j-encoding-detector")
@@ -96,7 +97,7 @@ public class Icu4jEncodingDetector implements EncodingDetector {
 
 
     @Override
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (tis == null) {
             return null;
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/UniversalEncodingDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/UniversalEncodingDetector.java
index 56a6da35c..a26c4f486 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/UniversalEncodingDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/main/java/org/apache/tika/parser/txt/UniversalEncodingDetector.java
@@ -26,6 +26,7 @@ import org.apache.tika.config.TikaComponent;
 import org.apache.tika.detect.EncodingDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 @TikaComponent(spi = false)
 public class UniversalEncodingDetector implements EncodingDetector {
@@ -68,7 +69,7 @@ public class UniversalEncodingDetector implements EncodingDetector {
         this(ConfigDeserializer.buildConfig(jsonConfig, Config.class));
     }
 
-    public Charset detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public Charset detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         if (tis == null) {
             return null;
         }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/BOMDetectorTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/BOMDetectorTest.java
index 851365c77..a18dcb460 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/BOMDetectorTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/BOMDetectorTest.java
@@ -33,6 +33,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.detect.EncodingDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 public class BOMDetectorTest extends TikaTest {
     @Test
@@ -51,7 +52,7 @@ public class BOMDetectorTest extends TikaTest {
                 assertEquals(bom, bomInputStream.getBOM());
             }
             try (TikaInputStream tis = TikaInputStream.get(bos.toByteArray())) {
-                assertEquals(Charset.forName(bom.getCharsetName()), detector.detect(tis, new Metadata()));
+                assertEquals(Charset.forName(bom.getCharsetName()), detector.detect(tis, new Metadata(), new ParseContext()));
                 int cnt = 0;
                 int c = tis.read();
                 while (c > -1) {
@@ -75,7 +76,7 @@ public class BOMDetectorTest extends TikaTest {
             bytes[1] = (byte)32;
             bytes[2] = (byte)32;
             try (TikaInputStream tis = TikaInputStream.get(bytes)) {
-                assertNull(detector.detect(tis, new Metadata()));
+                assertNull(detector.detect(tis, new Metadata(), new ParseContext()));
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/TXTParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/TXTParserTest.java
index 90247b974..128f65321 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/TXTParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-text-module/src/test/java/org/apache/tika/parser/txt/TXTParserTest.java
@@ -183,6 +183,8 @@ public class TXTParserTest extends TikaTest {
         try (TikaInputStream tis = TikaInputStream.get(test2.getBytes(ISO_8859_1))) {
             parser.parse(tis, new BodyContentHandler(), metadata, new ParseContext());
         }
+        parser.parse(TikaInputStream.get(test2.getBytes(ISO_8859_1)), new BodyContentHandler(),
+                metadata, new ParseContext());
         assertEquals("text/plain; charset=ISO-8859-1", metadata.get(Metadata.CONTENT_TYPE));
         assertEquals("ISO-8859-1", metadata.get(Metadata.CONTENT_ENCODING)); // deprecated
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/http/HttpParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/http/HttpParser.java
index a1b3804e0..156c5a73b 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/http/HttpParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/http/HttpParser.java
@@ -94,7 +94,7 @@ public class HttpParser implements Parser {
                               ParseContext context) throws IOException, SAXException {
         EmbeddedDocumentExtractor ex = EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context);
         if (ex.shouldParseEmbedded(metadata)) {
-            ex.parseEmbedded(tis, handler, metadata, true);
+            ex.parseEmbedded(tis, handler, metadata, context, true);
         }
     }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/wacz/WACZParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/wacz/WACZParser.java
index 6b2e250cf..838ce3f5b 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/wacz/WACZParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/wacz/WACZParser.java
@@ -117,7 +117,7 @@ public class WACZParser implements Parser {
         metadata.set(Metadata.CONTENT_LENGTH, Long.toString(zae.getSize()));
         try (TikaInputStream tis = TikaInputStream.get(getMaybeGzipInputStream(TikaInputStream.get(zais)))) {
             if (ex.shouldParseEmbedded(metadata)) {
-                ex.parseEmbedded(tis, xhtml, metadata, true);
+                ex.parseEmbedded(tis, xhtml, metadata, new ParseContext(), true);
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/warc/WARCParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/warc/WARCParser.java
index 12f69fdd4..0d43f7df0 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/warc/WARCParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-webarchive-module/src/main/java/org/apache/tika/parser/warc/WARCParser.java
@@ -150,7 +150,7 @@ public class WARCParser implements Parser {
             //TODO check Content-Encoding on the warcResponse.http.headers and wrap the tis.
             //May need to sniff first few bytes to confirm accuracy, e.g. gzip compression ?
             try (TikaInputStream tis = TikaInputStream.get(payload.body().stream())) {
-                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, metadata, true);
+                embeddedDocumentExtractor.parseEmbedded(tis, xhtml, metadata, context, true);
             }
         }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-xml-module/src/main/java/org/apache/tika/parser/xml/FictionBookParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-xml-module/src/main/java/org/apache/tika/parser/xml/FictionBookParser.java
index 46300a1a7..76c97fc1c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-xml-module/src/main/java/org/apache/tika/parser/xml/FictionBookParser.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-xml-module/src/main/java/org/apache/tika/parser/xml/FictionBookParser.java
@@ -51,7 +51,7 @@ public class FictionBookParser extends XMLParser {
     protected ContentHandler getContentHandler(ContentHandler handler, Metadata metadata,
                                                ParseContext context) {
         return new BinaryElementsDataHandler(
-                EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context), handler);
+                EmbeddedDocumentUtil.getEmbeddedDocumentExtractor(context), handler, context);
     }
 
     private static class BinaryElementsDataHandler extends DefaultHandler {
@@ -60,14 +60,16 @@ public class FictionBookParser extends XMLParser {
         private static final String ATTRIBUTE_CONTENT_TYPE = "content-type";
         private final EmbeddedDocumentExtractor partExtractor;
         private final ContentHandler handler;
+        private final ParseContext context;
         private final StringBuilder binaryData = new StringBuilder();
         private boolean binaryMode = false;
         private Metadata metadata;
 
         private BinaryElementsDataHandler(EmbeddedDocumentExtractor partExtractor,
-                                          ContentHandler handler) {
+                                          ContentHandler handler, ParseContext context) {
             this.partExtractor = partExtractor;
             this.handler = handler;
+            this.context = context;
         }
 
         @Override
@@ -89,7 +91,7 @@ public class FictionBookParser extends XMLParser {
             if (binaryMode) {
                 try (TikaInputStream tis = TikaInputStream.get(Base64.decodeBase64(binaryData.toString()))) {
                     partExtractor.parseEmbedded(
-                            tis, handler, metadata, true);
+                            tis, handler, metadata, context, true);
                 } catch (IOException e) {
                     throw new SAXException("IOException in parseEmbedded", e);
                 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DefaultZipContainerDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DefaultZipContainerDetector.java
index 7b063af7c..b665b2afc 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DefaultZipContainerDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DefaultZipContainerDetector.java
@@ -46,6 +46,7 @@ import org.apache.tika.io.BoundedInputStream;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * This class is designed to detect subtypes of zip-based file formats.
@@ -191,7 +192,7 @@ public class DefaultZipContainerDetector implements Detector {
     }
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         // Check if we have access to the document
         if (tis == null) {
             return MediaType.OCTET_STREAM;
@@ -212,9 +213,9 @@ public class DefaultZipContainerDetector implements Detector {
             return TIFF;
         } else if (isZipArchive(type)) {
             if (markLimit < 1 || tis.hasFile()) {
-                return detectZipFormatOnFile(tis, metadata);
+                return detectZipFormatOnFile(tis, metadata, parseContext);
             } else {
-                return tryStreamingOnTikaInputStream(tis, metadata);
+                return tryStreamingOnTikaInputStream(tis, metadata, parseContext);
             }
         } else if (!type.equals(MediaType.OCTET_STREAM)) {
             return type;
@@ -223,7 +224,7 @@ public class DefaultZipContainerDetector implements Detector {
         }
     }
 
-    private MediaType tryStreamingOnTikaInputStream(TikaInputStream tis, Metadata metadata) throws IOException {
+    private MediaType tryStreamingOnTikaInputStream(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         BoundedInputStream boundedInputStream = new BoundedInputStream(markLimit, tis);
         boundedInputStream.mark(markLimit);
         //try streaming detect
@@ -236,7 +237,7 @@ public class DefaultZipContainerDetector implements Detector {
             boundedInputStream.reset();
         }
         //spool to disk
-        return detectZipFormatOnFile(tis, metadata);
+        return detectZipFormatOnFile(tis, metadata, parseContext);
     }
 
     /**
@@ -247,7 +248,7 @@ public class DefaultZipContainerDetector implements Detector {
      * @param tis
      * @return
      */
-    private MediaType detectZipFormatOnFile(TikaInputStream tis, Metadata metadata) {
+    private MediaType detectZipFormatOnFile(TikaInputStream tis, Metadata metadata, ParseContext parseContext) {
         ZipFile zip = null;
         try {
             zip = ZipFile.builder().setFile(tis.getFile()).get();
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DeprecatedStreamingZipContainerDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DeprecatedStreamingZipContainerDetector.java
index 65df2bb42..3f1d13fc1 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DeprecatedStreamingZipContainerDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/DeprecatedStreamingZipContainerDetector.java
@@ -20,6 +20,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class DeprecatedStreamingZipContainerDetector extends ZipContainerDetectorBase
         implements Detector {
@@ -38,7 +39,7 @@ public class DeprecatedStreamingZipContainerDetector extends ZipContainerDetecto
      * @return
      */
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) {
 /*
         Set<String> fileNames = new HashSet<>();
         Set<String> directoryNames = new HashSet<>();
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/StreamingZipContainerDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/StreamingZipContainerDetector.java
index a321c147f..4c064942d 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/StreamingZipContainerDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/main/java/org/apache/tika/detect/zip/StreamingZipContainerDetector.java
@@ -27,6 +27,7 @@ import org.apache.tika.io.BoundedInputStream;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Currently only used in tests.  Unlike {@link DefaultZipContainerDetector},
@@ -58,7 +59,7 @@ public class StreamingZipContainerDetector extends DefaultZipContainerDetector {
 
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         // Check if we have access to the document
         if (tis == null) {
             return MediaType.OCTET_STREAM;
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/test/java/org/apache/tika/detect/zip/ZipDetectionTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/test/java/org/apache/tika/detect/zip/ZipDetectionTest.java
index 64699fc71..be053cdf6 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/test/java/org/apache/tika/detect/zip/ZipDetectionTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-zip-commons/src/test/java/org/apache/tika/detect/zip/ZipDetectionTest.java
@@ -33,6 +33,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.HttpHeaders;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Test cases for detecting zip-based files.
@@ -115,7 +116,7 @@ public class ZipDetectionTest extends TikaTest {
 
     private void assertExpected(Detector detector, InputStream is, String expectedMime, String expectedDigest) throws IOException {
         TikaInputStream tis = TikaInputStream.get(is);
-        MediaType mt = detector.detect(tis, new Metadata());
+        MediaType mt = detector.detect(tis, new Metadata(), new ParseContext());
         assertEquals(expectedMime, mt.toString());
         assertEquals(expectedDigest, digest(tis));
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/config/TikaDetectorConfigTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/config/TikaDetectorConfigTest.java
index d965dda5c..60efea055 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/config/TikaDetectorConfigTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/config/TikaDetectorConfigTest.java
@@ -34,6 +34,7 @@ import org.apache.tika.detect.microsoft.POIFSContainerDetector;
 import org.apache.tika.detect.zip.DefaultZipContainerDetector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.microsoft.pst.OutlookPSTParser;
 
 /**
@@ -103,9 +104,9 @@ public class TikaDetectorConfigTest extends TikaTest {
                 .get(getResourceAsStream("/test-documents/testPST.pst"))) {
             try (TikaInputStream tis = TikaInputStream.get(outer.getPath())) {
                 assertEquals(OutlookPSTParser.MS_OUTLOOK_PST_MIMETYPE,
-                        detectorWX.detect(tis, new Metadata()));
+                        detectorWX.detect(tis, new Metadata(), new ParseContext()));
                 assertEquals(OutlookPSTParser.MS_OUTLOOK_PST_MIMETYPE,
-                        detectorCL.detect(tis, new Metadata()));
+                        detectorCL.detect(tis, new Metadata(), new ParseContext()));
             }
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java
index 7433f6fd8..4c13ceda1 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestContainerAwareDetector.java
@@ -53,6 +53,7 @@ import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MediaTypeRegistry;
 import org.apache.tika.mime.MimeTypes;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.iwork.iwana.IWork13PackageParser;
 import org.apache.tika.parser.iwork.iwana.IWork18PackageParser;
 import org.apache.tika.utils.XMLReaderUtils;
@@ -106,17 +107,17 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
 
             // Mime Magic version is likely to be less precise
             if (typeFromMagic != null) {
-                assertEquals(MediaType.parse(typeFromMagic), mimeTypes.detect(tis, m));
+                assertEquals(MediaType.parse(typeFromMagic), mimeTypes.detect(tis, m, new ParseContext()));
             }
 
             MediaType expected = MediaType.parse(typeFromDetector);
             // All being well, the detector should get it perfect
-            assertEquals(expected, detector.detect(tis, m));
+            assertEquals(expected, detector.detect(tis, m, new ParseContext()));
 
             if (mediaTypeRegistry.isSpecializationOf(expected, MediaType.APPLICATION_ZIP) &&
                     !expected.toString().contains("tika-ooxml-protected")) {
 
-                assertEquals(expected, streamingZipDetector.detect(tis, m),
+                assertEquals(expected, streamingZipDetector.detect(tis, m, new ParseContext()),
                         "streaming zip detector failed");
             }
         }
@@ -239,7 +240,7 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
                 .get(getResourceAsUrl("/test-documents/testPPT.ppt"))) {
             assertNull(tis.getOpenContainer());
             assertEquals(MediaType.parse("application/vnd.ms-powerpoint"),
-                    detector.detect(tis, new Metadata()));
+                    detector.detect(tis, new Metadata(), new ParseContext()));
             assertTrue(tis.getOpenContainer() instanceof POIFSFileSystem);
         }
     }
@@ -284,7 +285,7 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
                 getResourceAsStream("/test-documents/testODFwithOOo3.odt"))) {
             //force underlying file to test the proper behavior with the underlying zipfile
             tis.getFile();
-            MediaType mt = zipContainerDetector.detect(tis, new Metadata());
+            MediaType mt = zipContainerDetector.detect(tis, new Metadata(), new ParseContext());
             assertEquals("application/vnd.oasis.opendocument.text", mt.toString());
             assertNotNull(tis.getOpenContainer());
             assertEquals("org.apache.commons.compress.archivers.zip.ZipFile",
@@ -412,7 +413,7 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
 
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsUrl("/test-documents/" + fileName))) {
-            detector.detect(tis, new Metadata());
+            detector.detect(tis, new Metadata(), new ParseContext());
         }
 
         assertEquals(numberOfTempFiles, countTemporaryFiles());
@@ -530,7 +531,7 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
         // With only the data supplied, the best we can do is the container
         Metadata m = new Metadata();
         try (TikaInputStream xlsx = getTruncatedFile("testEXCEL.xlsx", 300)) {
-            assertEquals(MediaType.application("x-tika-ooxml"), detector.detect(xlsx, m));
+            assertEquals(MediaType.application("x-tika-ooxml"), detector.detect(xlsx, m, new ParseContext()));
         }
 
         // With truncated data + filename, we can use the filename to specialise
@@ -539,20 +540,20 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
         try (TikaInputStream xlsx = getTruncatedFile("testEXCEL.xlsx", 300)) {
             assertEquals(
                     MediaType.application("vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
-                    detector.detect(xlsx, m));
+                    detector.detect(xlsx, m, new ParseContext()));
         }
 
         // Now a truncated OLE2 file 
         m = new Metadata();
         try (TikaInputStream xls = getTruncatedFile("testEXCEL.xls", 400)) {
-            assertEquals(MediaType.application("x-tika-msoffice"), detector.detect(xls, m));
+            assertEquals(MediaType.application("x-tika-msoffice"), detector.detect(xls, m, new ParseContext()));
         }
 
         // Finally a truncated OLE2 file, with a filename available
         m = new Metadata();
         m.add(TikaCoreProperties.RESOURCE_NAME_KEY, "testEXCEL.xls");
         try (TikaInputStream xls = getTruncatedFile("testEXCEL.xls", 400)) {
-            assertEquals(MediaType.application("vnd.ms-excel"), detector.detect(xls, m));
+            assertEquals(MediaType.application("vnd.ms-excel"), detector.detect(xls, m, new ParseContext()));
         }
     }
 
@@ -622,28 +623,28 @@ public class TestContainerAwareDetector extends MultiThreadedTikaTest {
         Detector detector = TikaLoader.loadDefault().loadDetectors();
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals("application/msword",
-                    detector.detect(tis, new Metadata()).toString());
+                    detector.detect(tis, new Metadata(), new ParseContext()).toString());
             assertEquals(len, countBytes(tis));
         }
 
         detector = loadDetector("tika-4441-neg1.json");
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals("application/msword",
-                    detector.detect(tis, new Metadata()).toString());
+                    detector.detect(tis, new Metadata(), new ParseContext()).toString());
             assertEquals(len, countBytes(tis));
         }
 
         detector = loadDetector("tika-4441-120.json");
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals("application/x-tika-msoffice",
-                    detector.detect(tis, new Metadata()).toString());
+                    detector.detect(tis, new Metadata(), new ParseContext()).toString());
             assertEquals(len, countBytes(tis));
         }
 
         detector = loadDetector("tika-4441-12000000.json");
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals("application/msword",
-                    detector.detect(tis, new Metadata()).toString());
+                    detector.detect(tis, new Metadata(), new ParseContext()).toString());
             assertEquals(len, countBytes(tis));
         }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestZipDetector.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestZipDetector.java
index 44e36a36b..98141b712 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestZipDetector.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/detect/TestZipDetector.java
@@ -35,6 +35,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.config.loader.TikaLoader;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 
 public class TestZipDetector extends TikaTest {
 
@@ -63,7 +64,7 @@ public class TestZipDetector extends TikaTest {
         Metadata metadata = new Metadata();
         try (TikaInputStream tis = TikaInputStream.get(p, metadata)) {
             assertEquals(expectedMime, DETECTOR
-                    .detect(tis, metadata)
+                    .detect(tis, metadata, new ParseContext())
                     .toString());
         }
 
@@ -71,7 +72,7 @@ public class TestZipDetector extends TikaTest {
         metadata = new Metadata();
         try (TikaInputStream tis = TikaInputStream.get(bytes)) {
             assertEquals(expectedMime, DETECTOR
-                    .detect(tis, metadata)
+                    .detect(tis, metadata, new ParseContext())
                     .toString());
         }
 
@@ -79,7 +80,7 @@ public class TestZipDetector extends TikaTest {
         try (InputStream is = new BufferedInputStream(Files.newInputStream(p));
              TikaInputStream tis = TikaInputStream.get(is)) {
             assertEquals(expectedMime, DETECTOR
-                    .detect(tis, metadata)
+                    .detect(tis, metadata, new ParseContext())
                     .toString());
         }
 
@@ -87,7 +88,7 @@ public class TestZipDetector extends TikaTest {
         try (InputStream is = new ByteArrayInputStream(bytes);
              TikaInputStream tis = TikaInputStream.get(is)) {
             assertEquals(expectedMime, DETECTOR
-                    .detect(tis, metadata)
+                    .detect(tis, metadata, new ParseContext())
                     .toString());
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/mime/TestMimeTypes.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/mime/TestMimeTypes.java
index 0c83d3d38..25bb8347f 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/mime/TestMimeTypes.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/mime/TestMimeTypes.java
@@ -36,6 +36,7 @@ import org.apache.tika.config.loader.TikaLoader;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Test Suite for the {@link MimeTypes} repository.
@@ -1394,7 +1395,7 @@ public class TestMimeTypes {
 
     private void assertMagic(String expected, byte[] prefix) throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(prefix)) {
-            MediaType type = repo.detect(tis, new Metadata());
+            MediaType type = repo.detect(tis, new Metadata(), new ParseContext());
             assertNotNull(type);
             assertEquals(expected, type.toString());
         }
@@ -1406,14 +1407,14 @@ public class TestMimeTypes {
             assertNotNull(tis, "Test file not found: " + filename);
             Metadata metadata = new Metadata();
             metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, filename);
-            assertEquals(expected, repo.detect(tis, metadata).toString());
+            assertEquals(expected, repo.detect(tis, metadata, new ParseContext()).toString());
         }
     }
 
     private void assertTypeByName(String expected, String filename) throws IOException {
         Metadata metadata = new Metadata();
         metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, filename);
-        assertEquals(expected, repo.detect(null, metadata).toString());
+        assertEquals(expected, repo.detect(null, metadata, new ParseContext()).toString());
     }
 
     private void assertTypeByData(String expected, String filename) throws IOException {
@@ -1421,14 +1422,14 @@ public class TestMimeTypes {
                 .get(TestMimeTypes.class.getResourceAsStream("/test-documents/" + filename))) {
             assertNotNull(tis, "Test file not found: " + filename);
             Metadata metadata = new Metadata();
-            assertEquals(expected, repo.detect(tis, metadata).toString());
+            assertEquals(expected, repo.detect(tis, metadata, new ParseContext()).toString());
         }
     }
 
     private void assertTypeByData(String expected, byte[] data) throws IOException {
         try (TikaInputStream tis = TikaInputStream.get(data)) {
             Metadata metadata = new Metadata();
-            assertEquals(expected, repo.detect(tis, metadata).toString());
+            assertEquals(expected, repo.detect(tis, metadata, new ParseContext()).toString());
         }
     }
 
@@ -1453,7 +1454,7 @@ public class TestMimeTypes {
             assertNotNull(tis, "Test document not found: " + filename);
             Metadata metadata = new Metadata();
             metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, filename);
-            return repo.detect(tis, metadata);
+            return repo.detect(tis, metadata, new ParseContext());
         }
     }
 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/AutoDetectParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/AutoDetectParserTest.java
index 8dc8a1fd3..17a57934d 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/AutoDetectParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/AutoDetectParserTest.java
@@ -497,7 +497,7 @@ public class AutoDetectParserTest extends TikaTest {
      */
     @SuppressWarnings("serial")
     private static class MyDetector implements Detector {
-        public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+        public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
             return MY_MEDIA_TYPE;
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/fork/ForkParserIntegrationTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/fork/ForkParserIntegrationTest.java
index e60c9e0ab..f6826ac3c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/fork/ForkParserIntegrationTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/fork/ForkParserIntegrationTest.java
@@ -131,7 +131,7 @@ public class ForkParserIntegrationTest extends MultiThreadedTikaTest {
 
         ParseContext context = new ParseContext();
         context.set(Detector.class, new Detector() {
-            public MediaType detect(TikaInputStream input, Metadata metadata) {
+            public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) {
                 return MediaType.OCTET_STREAM;
             }
         });
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/mail/MboxParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/mail/MboxParserTest.java
index 04461e800..ff1340160 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/mail/MboxParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/mail/MboxParserTest.java
@@ -18,8 +18,6 @@ package org.apache.tika.parser.mail;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import java.io.InputStream;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.xml.sax.ContentHandler;
@@ -58,8 +56,7 @@ public class MboxParserTest extends TikaTest {
         Metadata metadata = new Metadata();
         ParseContext context = new ParseContext();
 
-        try (InputStream stream = getResourceAsStream("/test-documents/single_mail.mbox");
-             TikaInputStream tis = TikaInputStream.get(stream)) {
+        try (TikaInputStream tis = getResourceAsStream("/test-documents/single_mail.mbox")) {
             mboxParser.parse(tis, handler, metadata, context);
         }
 
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/microsoft/ooxml/TruncatedOOXMLTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/microsoft/ooxml/TruncatedOOXMLTest.java
index 918e2b64f..9b8a90452 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/microsoft/ooxml/TruncatedOOXMLTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/microsoft/ooxml/TruncatedOOXMLTest.java
@@ -31,6 +31,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 public class TruncatedOOXMLTest extends TikaTest {
 
@@ -71,7 +72,7 @@ public class TruncatedOOXMLTest extends TikaTest {
         try (InputStream is = new BufferedInputStream(TruncatedOOXMLTest.class.getResourceAsStream(
                 "/test-documents/testWORD_truncated.docx"));
              TikaInputStream tis = TikaInputStream.get(is)) {
-            MediaType mediaType = detector.detect(tis, metadata);
+            MediaType mediaType = detector.detect(tis, metadata, new ParseContext());
             assertEquals(MediaType.application("vnd.openxmlformats-officedocument.wordprocessingml.document"),
                     mediaType);
         }
@@ -84,7 +85,7 @@ public class TruncatedOOXMLTest extends TikaTest {
         try (TikaInputStream tis = getResourceAsStream(
                 "/test-documents/testWORD_truncated.docx")) {
             tis.getPath();
-            MediaType mediaType = detector.detect(tis, metadata);
+            MediaType mediaType = detector.detect(tis, metadata, new ParseContext());
             assertEquals(
                     MediaType.application("vnd.openxmlformats-officedocument.wordprocessingml.document"),
                     mediaType);
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
index 7bfd3a44a..a0b69ee48 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
@@ -202,11 +202,11 @@ public class PDFParserTest extends TikaTest {
         assertTrue(needle > pdfHaystack && pdfHaystack > outerHaystack);
 
         TrackingHandler tracker = new TrackingHandler();
-
+        ParseContext context = new ParseContext();
         ContainerExtractor ex = new ParserContainerExtractor();
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsStream("/test-documents/testPDFEmbeddingAndEmbedded.docx"))) {
-            ex.extract(tis, ex, tracker);
+            ex.extract(tis, ex, tracker, context);
         }
 
         assertEquals(3, tracker.filenames.size());
@@ -682,12 +682,11 @@ public class PDFParserTest extends TikaTest {
         }
 
         @Override
-        public void parseEmbedded(TikaInputStream tis, ContentHandler handler, Metadata metadata,
-                                  boolean outputHtml) throws SAXException, IOException {
+        public void parseEmbedded(TikaInputStream tis, ContentHandler handler, Metadata metadata, ParseContext parseContext, boolean outputHtml) throws SAXException, IOException {
 
             byte[] bytes = Files.readAllBytes(tis.getPath());
             embedded.put(count++, bytes);
-            super.parseEmbedded(tis, handler, metadata, outputHtml);
+            super.parseEmbedded(tis, handler, metadata, parseContext, outputHtml);
         }
 
         public Map<Integer, byte[]> getEmbedded() {
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/CompositeZipContainerDetectorTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/CompositeZipContainerDetectorTest.java
index 8f2e631b5..423695f3c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/CompositeZipContainerDetectorTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/CompositeZipContainerDetectorTest.java
@@ -40,6 +40,7 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MediaTypeRegistry;
+import org.apache.tika.parser.ParseContext;
 
 public class CompositeZipContainerDetectorTest extends TikaTest {
     private static MediaType ODT_TEXT = MediaType.application("vnd.oasis.opendocument.text");
@@ -54,13 +55,13 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
         Metadata metadata = new Metadata();
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsStream("/test-documents/testTIFF.tif"))) {
-            MediaType mt = compositeZipContainerDetector.detect(tis, metadata);
+            MediaType mt = compositeZipContainerDetector.detect(tis, metadata, new ParseContext());
             assertEquals(TIFF, mt);
         }
         metadata = new Metadata();
         try (TikaInputStream tis = TikaInputStream
                 .get(getResourceAsStream("/test-documents/testTIFF_multipage.tif"))) {
-            MediaType mt = compositeZipContainerDetector.detect(tis, metadata);
+            MediaType mt = compositeZipContainerDetector.detect(tis, metadata, new ParseContext());
             assertEquals(TIFF, mt);
         }
     }
@@ -72,7 +73,7 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
             try (InputStream input = ODFParserTest.class.getResourceAsStream(
                     "/test-documents/testODFwithOOo3.odt")) {
                 Metadata metadata = new Metadata();
-                MediaType mt = zipContainerDetector.detect(input, metadata);
+                MediaType mt = zipContainerDetector.detect(input, metadata, new ParseContext());
                 assertEquals(ODT_TEXT, mt);
             }
         }
@@ -83,7 +84,7 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
             try (InputStream input = ODFParserTest.class.getResourceAsStream(
                     "/test-documents/testPages.pages")) {
                 Metadata metadata = new Metadata();
-                MediaType mt = zipContainerDetector.detect(input, metadata);
+                MediaType mt = zipContainerDetector.detect(input, metadata, new ParseContext());
                 assertEquals("application/vnd.apple.pages", mt.toString());
             }
 
@@ -94,7 +95,7 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
             try (InputStream input = ODFParserTest.class.getResourceAsStream(
                     "/test-documents/testPages.pages")) {
                 Metadata metadata = new Metadata();
-                MediaType mt = tikaConfig.getDetector().detect(input, metadata);
+                MediaType mt = tikaConfig.getDetector().detect(input, metadata, new ParseContext());
                 assertEquals("application/zip", mt.toString());
             }
         }
@@ -105,13 +106,13 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
                 long start = System.currentTimeMillis();
                 try (InputStream input = ODFParserTest.class.getResourceAsStream(
                         "/test-documents/" + file)) {
-                    MediaType mediaType = streamingZipDetector.detect(input, new Metadata());
+                    MediaType mediaType = streamingZipDetector.detect(input, new Metadata(), new ParseContext());
                     assertEquals(ZipContainerDetectorBase.XPS, mediaType);
                 }
                 try (TikaInputStream tis = TikaInputStream.get(
                 Paths.get(ODFParserTest.class.getResource(
                         "/test-documents/" + file).toURI()))) {
-                    MediaType mediaType = zipContainerDetector.detect(tis, new Metadata());
+                    MediaType mediaType = zipContainerDetector.detect(input, new Metadata(), new ParseContext());
                     assertEquals(ZipContainerDetectorBase.XPS, mediaType);
                 }
             }
@@ -134,7 +135,7 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
             for (File z : zips) {
                 long start = System.currentTimeMillis();
                 try (TikaInputStream tis = TikaInputStream.get(new BufferedInputStream(new FileInputStream(z)))) {
-                    MediaType mt = detector.detect(tis, new Metadata());
+                    MediaType mt = detector.detect(tis, new Metadata(), new ParseContext());
                     mediaTypeSet.add(mt);
                 }
                 nonTikaStream += System.currentTimeMillis() - start;
@@ -142,14 +143,14 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
                 start = System.currentTimeMillis();
                 try (TikaInputStream tis = TikaInputStream
                         .get(new BufferedInputStream(new FileInputStream(z)))) {
-                    MediaType mt = detector.detect(tis, new Metadata());
+                    MediaType mt = detector.detect(tis, new Metadata(), new ParseContext());
                     mediaTypeSet.add(mt);
                 }
                 tikaStream += System.currentTimeMillis() - start;
 
                 start = System.currentTimeMillis();
                 try (TikaInputStream tis = TikaInputStream.get(z.toPath())) {
-                    MediaType mt = detector.detect(tis, new Metadata());
+                    MediaType mt = detector.detect(tis, new Metadata(), new ParseContext());
                     mediaTypeSet.add(mt);
                 }
                 tikaStreamWFile += System.currentTimeMillis() - start;
@@ -206,7 +207,7 @@ public class CompositeZipContainerDetectorTest extends TikaTest {
         List<File> zips = new ArrayList<>();
         for (File f : Paths.get(getResourceAsUri("/test-documents")).toFile().listFiles()) {
             try (TikaInputStream tis = TikaInputStream.get(f.toPath())) {
-                MediaType mt = detector.detect(tis, new Metadata());
+                MediaType mt = detector.detect(tis, new Metadata(), new ParseContext());
                 if (registry.isSpecializationOf(mt, MediaType.APPLICATION_ZIP)) {
                     zips.add(f);
                 }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
index 4f3eed194..04a00c502 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
@@ -135,7 +135,7 @@ public class ZipParserTest extends AbstractPkgTest {
         }
 
         public void parseEmbedded(TikaInputStream inputStream, ContentHandler contentHandler,
-                                  Metadata metadata, boolean outputHtml) {
+                                  Metadata metadata, ParseContext parseContext, boolean outputHtml) {
             throw new UnsupportedOperationException("should never be called");
         }
     }
diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/xml/FictionBookParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/xml/FictionBookParserTest.java
index 3207c83fc..1d8f5715c 100644
--- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/xml/FictionBookParserTest.java
+++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-package/src/test/java/org/apache/tika/parser/xml/FictionBookParserTest.java
@@ -26,6 +26,7 @@ import org.apache.tika.TikaTest;
 import org.apache.tika.extractor.ContainerExtractor;
 import org.apache.tika.extractor.ParserContainerExtractor;
 import org.apache.tika.io.TikaInputStream;
+import org.apache.tika.parser.ParseContext;
 
 public class FictionBookParserTest {
 
@@ -35,12 +36,12 @@ public class FictionBookParserTest {
                 .getResourceAsStream("/test-documents/test.fb2")) {
             ContainerExtractor extractor = new ParserContainerExtractor();
             TikaInputStream tis = TikaInputStream.get(input);
-
-            assertEquals(true, extractor.isSupported(tis));
+            ParseContext parseContext = new ParseContext();
+            assertEquals(true, extractor.isSupported(tis, parseContext));
 
             // Process it
             TikaTest.TrackingHandler handler = new TikaTest.TrackingHandler();
-            extractor.extract(tis, null, handler);
+            extractor.extract(tis, null, handler, parseContext);
 
             assertEquals(2, handler.filenames.size());
         }
diff --git a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/server/ParseHandler.java b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/server/ParseHandler.java
index f6edfc627..7e670c63a 100644
--- a/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/server/ParseHandler.java
+++ b/tika-pipes/tika-pipes-core/src/main/java/org/apache/tika/pipes/core/server/ParseHandler.java
@@ -108,7 +108,7 @@ class ParseHandler {
             }
         }
         try {
-            MediaType mt = detector.detect(tis, metadata);
+            MediaType mt = detector.detect(tis, metadata, parseContext);
             metadata.set(Metadata.CONTENT_TYPE, mt.toString());
             metadata.set(TikaCoreProperties.CONTENT_TYPE_PARSER_OVERRIDE, mt.toString());
         } catch (IOException e) {
diff --git a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/CrashingDetector.java b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/CrashingDetector.java
index 0e3aa08ec..0304b6540 100644
--- a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/CrashingDetector.java
+++ b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/CrashingDetector.java
@@ -22,6 +22,7 @@ import org.apache.tika.detect.Detector;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.mime.MediaType;
+import org.apache.tika.parser.ParseContext;
 
 /**
  * Detector that crashes with SystemExit
@@ -30,7 +31,7 @@ import org.apache.tika.mime.MediaType;
 public class CrashingDetector implements Detector {
 
     @Override
-    public MediaType detect(TikaInputStream tis, Metadata metadata) throws IOException {
+    public MediaType detect(TikaInputStream tis, Metadata metadata, ParseContext parseContext) throws IOException {
         System.exit(1);
         return null;
     }
diff --git a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/DetectorResource.java b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/DetectorResource.java
index 6f884b165..8caac3f44 100644
--- a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/DetectorResource.java
+++ b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/DetectorResource.java
@@ -64,7 +64,7 @@ public class DetectorResource {
             return TikaResource
                     .getTikaLoader()
                     .loadDetectors()
-                    .detect(tis, met)
+                    .detect(tis, met, parseContext)
                     .toString();
         } catch (IOException | TikaConfigException e) {
             LOG.warn("Unable to detect MIME type for file. Reason: {} ({})", e.getMessage(), filename, e);
diff --git a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/UnpackerResource.java b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/UnpackerResource.java
index 53b559eeb..0384eae4b 100644
--- a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/UnpackerResource.java
+++ b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/UnpackerResource.java
@@ -264,7 +264,7 @@ public class UnpackerResource {
         }
 
         @Override
-        public void parseEmbedded(TikaInputStream tis, ContentHandler contentHandler, Metadata metadata, boolean b) throws SAXException, IOException {
+        public void parseEmbedded(TikaInputStream tis, ContentHandler contentHandler, Metadata metadata, ParseContext parseContext, boolean b) throws SAXException, IOException {
             UnsynchronizedByteArrayOutputStream bos = UnsynchronizedByteArrayOutputStream
                     .builder()
                     .get();
diff --git a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceTest.java b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceTest.java
index f4cce96fb..4e29f432a 100644
--- a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceTest.java
+++ b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceTest.java
@@ -45,6 +45,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.config.loader.TikaLoader;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.ocr.TesseractOCRParser;
 import org.apache.tika.server.core.CXFTestBase;
 import org.apache.tika.server.core.TikaServerParseExceptionMapper;
@@ -328,7 +329,7 @@ public class UnpackerResourceTest extends CXFTestBase {
             assertEquals("image/png", TikaLoader
                     .loadDefault()
                     .loadDetectors()
-                    .detect(tis, new Metadata())
+                    .detect(tis, new Metadata(), new ParseContext())
                     .toString());
         }
 
diff --git a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceWithConfigTest.java b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceWithConfigTest.java
index 2c81acf2d..6870db429 100644
--- a/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceWithConfigTest.java
+++ b/tika-server/tika-server-standard/src/test/java/org/apache/tika/server/standard/UnpackerResourceWithConfigTest.java
@@ -42,6 +42,7 @@ import org.junit.jupiter.api.Test;
 import org.apache.tika.config.loader.TikaLoader;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
 import org.apache.tika.server.core.CXFTestBase;
 import org.apache.tika.server.core.TikaServerParseExceptionMapper;
 import org.apache.tika.server.core.resource.UnpackerResource;
@@ -113,7 +114,7 @@ public class UnpackerResourceWithConfigTest extends CXFTestBase {
             assertEquals("image/tiff", TikaLoader
                     .loadDefault()
                     .loadDetectors()
-                    .detect(tis, new Metadata())
+                    .detect(tis, new Metadata(), new ParseContext())
                     .toString());
         }
 
@@ -178,7 +179,7 @@ public class UnpackerResourceWithConfigTest extends CXFTestBase {
             assertEquals("image/jpeg", TikaLoader
                     .loadDefault()
                     .loadDetectors()
-                    .detect(tis, new Metadata())
+                    .detect(tis, new Metadata(), new ParseContext())
                     .toString());
         }