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

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


The following commit(s) were added to refs/heads/branch_1x by this push:
     new f9722b4  TIKA-2644 improve api for recursiveparserwrapper
f9722b4 is described below

commit f9722b4b7d406caae41f4646ced50695affa2807
Author: tballison <talli...@mitre.org>
AuthorDate: Thu May 17 14:09:36 2018 -0400

    TIKA-2644 improve api for recursiveparserwrapper
---
 .../src/main/java/org/apache/tika/cli/TikaCLI.java |   8 +-
 .../src/main/java/org/apache/tika/gui/TikaGUI.java |  14 +-
 .../tika/cli/TikaCLIBatchIntegrationTest.java      |   3 +-
 .../apache/tika/batch/fs/BasicTikaFSConsumer.java  |  52 +++++---
 .../batch/fs/RecursiveParserWrapperFSConsumer.java |  42 +++---
 .../fs/builders/BasicTikaFSConsumersBuilder.java   |   7 +-
 .../RecursiveParserWrapperFSConsumerTest.java      |  19 ++-
 .../sax/AbstractRecursiveParserWrapperHandler.java | 119 +++++++++++++++++
 .../tika/sax/BasicContentHandlerFactory.java       |  67 +++++-----
 .../org/apache/tika/sax/ContentHandlerFactory.java |   6 +
 .../tika/sax/RecursiveParserWrapperHandler.java    | 120 +++++++++++++++++
 .../java/org/apache/tika/utils/ParserUtils.java    | 142 +++++++++++++++++++++
 .../org/apache/tika/MultiThreadedTikaTest.java     |  36 ++++--
 .../src/test/java/org/apache/tika/TikaTest.java    |  32 +++--
 .../org/apache/tika/eval/AbstractProfiler.java     |  13 +-
 .../java/org/apache/tika/eval/ExtractComparer.java |  11 +-
 .../java/org/apache/tika/eval/ExtractProfiler.java |   3 +-
 .../org/apache/tika/eval/io/ExtractReader.java     |   7 +-
 .../org/apache/tika/eval/SimpleComparerTest.java   |  15 ++-
 .../org/apache/tika/eval/io/ExtractReaderTest.java |  25 ++--
 .../org/apache/tika/example/ParsingExample.java    |  10 +-
 .../apache/tika/parser/html/HtmlParserTest.java    |  13 +-
 .../apache/tika/parser/mbox/MboxParserTest.java    |   5 +-
 .../tika/parser/microsoft/JackcessParserTest.java  |  13 +-
 .../tika/parser/ocr/TesseractOCRParserTest.java    |   3 +-
 .../org/apache/tika/parser/pkg/ZipParserTest.java  |   3 +-
 .../org/apache/tika/parser/rtf/RTFParserTest.java  |  12 +-
 .../serialization/PrettyMetadataKeyComparator.java |   2 +-
 .../server/resource/RecursiveMetadataResource.java |  25 ++--
 .../tika/server/RecursiveMetadataResourceTest.java |  23 ++--
 30 files changed, 662 insertions(+), 188 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 31d18a6..4175f1e 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
@@ -103,6 +103,7 @@ import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.apache.tika.sax.BodyContentHandler;
 import org.apache.tika.sax.ContentHandlerFactory;
 import org.apache.tika.sax.ExpandedTitleContentHandler;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.apache.tika.xmp.XMPMetadata;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -502,14 +503,15 @@ public class TikaCLI {
 
     private void handleRecursiveJson(URL url, OutputStream output) throws 
IOException, SAXException, TikaException {
         Metadata metadata = new Metadata();
-        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(parser, 
getContentHandlerFactory(type));
+        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(parser);
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(getContentHandlerFactory(type), -1);
         try (InputStream input = TikaInputStream.get(url, metadata)) {
-            wrapper.parse(input, null, metadata, context);
+            wrapper.parse(input, handler, metadata, context);
         }
         JsonMetadataList.setPrettyPrinting(prettyPrint);
         Writer writer = getOutputWriter(output, encoding);
         try {
-            JsonMetadataList.toJson(wrapper.getMetadata(), writer);
+            JsonMetadataList.toJson(handler.getMetadataList(), writer);
         } finally {
             writer.flush();
         }
diff --git a/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java 
b/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java
index 5ecc763..257a624 100644
--- a/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java
+++ b/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java
@@ -80,6 +80,7 @@ import org.apache.tika.parser.utils.CommonsDigester;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.apache.tika.sax.BodyContentHandler;
 import org.apache.tika.sax.ContentHandlerDecorator;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.apache.tika.sax.TeeContentHandler;
 import org.apache.tika.sax.XHTMLContentHandler;
 import org.xml.sax.Attributes;
@@ -395,13 +396,16 @@ public class TikaGUI extends JFrame
             );
         }
         if (isReset) {
-            RecursiveParserWrapper wrapper = new RecursiveParserWrapper(parser,
-                    new BasicContentHandlerFactory(
-                            BasicContentHandlerFactory.HANDLER_TYPE.BODY, -1));
-            wrapper.parse(input, null, new Metadata(), new ParseContext());
+            RecursiveParserWrapperHandler recursiveParserWrapperHandler =
+                    new RecursiveParserWrapperHandler(
+                            new BasicContentHandlerFactory(
+                                    
BasicContentHandlerFactory.HANDLER_TYPE.BODY, -1),
+                            -1);
+            RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parser);
+            wrapper.parse(input, recursiveParserWrapperHandler, new 
Metadata(), new ParseContext());
             StringWriter jsonBuffer = new StringWriter();
             JsonMetadataList.setPrettyPrinting(true);
-            JsonMetadataList.toJson(wrapper.getMetadata(), jsonBuffer);
+            
JsonMetadataList.toJson(recursiveParserWrapperHandler.getMetadataList(), 
jsonBuffer);
             setText(json, jsonBuffer.toString());
         }
         layout.show(cards, "metadata");
diff --git 
a/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java 
b/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java
index 1da91db..60c6d6b 100644
--- 
a/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java
+++ 
b/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java
@@ -35,6 +35,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.serialization.JsonMetadataList;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -108,7 +109,7 @@ public class TikaCLIBatchIntegrationTest {
         try (Reader reader = Files.newBufferedReader(jsonFile, UTF_8)) {
             List<Metadata> metadataList = JsonMetadataList.fromJson(reader);
             assertEquals(12, metadataList.size());
-            
assertTrue(metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).contains("human
 events"));
+            
assertTrue(metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).contains("human
 events"));
         }
     }
 
diff --git 
a/tika-batch/src/main/java/org/apache/tika/batch/fs/BasicTikaFSConsumer.java 
b/tika-batch/src/main/java/org/apache/tika/batch/fs/BasicTikaFSConsumer.java
index 087a482..5ccab17 100644
--- a/tika-batch/src/main/java/org/apache/tika/batch/fs/BasicTikaFSConsumer.java
+++ b/tika-batch/src/main/java/org/apache/tika/batch/fs/BasicTikaFSConsumer.java
@@ -22,6 +22,8 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.concurrent.ArrayBlockingQueue;
 
 import org.apache.commons.io.IOUtils;
@@ -45,29 +47,45 @@ import org.xml.sax.ContentHandler;
 public class BasicTikaFSConsumer extends AbstractFSConsumer {
 
     private boolean parseRecursively = true;
-    private final ParserFactory parserFactory;
+    private final Parser parser;
     private final ContentHandlerFactory contentHandlerFactory;
     private final OutputStreamFactory fsOSFactory;
-    private final TikaConfig config;
-    private String outputEncoding = UTF_8.toString();
-
 
+    private Charset outputEncoding = StandardCharsets.UTF_8;
+
+    /**
+     * @param queue
+     * @param parserFactory
+     * @param contentHandlerFactory
+     * @param fsOSFactory
+     * @param tikaConfig
+     *
+     * @deprecated use {@link 
BasicTikaFSConsumer#BasicTikaFSConsumer(ArrayBlockingQueue, Parser, 
ContentHandlerFactory, OutputStreamFactory)}
+     */
+    @Deprecated
     public BasicTikaFSConsumer(ArrayBlockingQueue<FileResource> queue,
                                ParserFactory parserFactory,
                                ContentHandlerFactory contentHandlerFactory,
-                               OutputStreamFactory fsOSFactory,
-                               TikaConfig config) {
+                               OutputStreamFactory fsOSFactory, TikaConfig 
tikaConfig) {
+        super(queue);
+        this.parser = parserFactory.getParser(tikaConfig);
+        this.contentHandlerFactory = contentHandlerFactory;
+        this.fsOSFactory = fsOSFactory;
+    }
+
+    public BasicTikaFSConsumer(ArrayBlockingQueue<FileResource> queue,
+                               Parser parser,
+                               ContentHandlerFactory contentHandlerFactory,
+                               OutputStreamFactory fsOSFactory) {
         super(queue);
-        this.parserFactory = parserFactory;
+        this.parser = parser;
         this.contentHandlerFactory = contentHandlerFactory;
         this.fsOSFactory = fsOSFactory;
-        this.config = config;
     }
 
     @Override
     public boolean processFileResource(FileResource fileResource) {
 
-        Parser parser = parserFactory.getParser(config);
         ParseContext context = new ParseContext();
         if (parseRecursively) {
             context.set(Parser.class, parser);
@@ -87,14 +105,8 @@ public class BasicTikaFSConsumer extends AbstractFSConsumer 
{
             return false;
         }
         ContentHandler handler;
-        try {
-            handler = contentHandlerFactory.getNewContentHandler(os, 
getOutputEncoding());
-        } catch (UnsupportedEncodingException e) {
-            incrementHandledExceptions();
-            LOG.error(getXMLifiedLogMsg("output_encoding_ex", 
fileResource.getResourceId(), e));
-            flushAndClose(os);
-            throw new RuntimeException(e);
-        }
+        handler = contentHandlerFactory.getNewContentHandler(os, 
getOutputEncoding());
+
 
         //now actually call parse!
         Throwable thrown = null;
@@ -115,11 +127,11 @@ public class BasicTikaFSConsumer extends 
AbstractFSConsumer {
         return true;
     }
 
-    public String getOutputEncoding() {
+    public Charset getOutputEncoding() {
         return outputEncoding;
     }
 
-    public void setOutputEncoding(String outputEncoding) {
-        this.outputEncoding = outputEncoding;
+    public void setOutputEncoding(Charset charset) {
+        this.outputEncoding = charset;
     }
 }
diff --git 
a/tika-batch/src/main/java/org/apache/tika/batch/fs/RecursiveParserWrapperFSConsumer.java
 
b/tika-batch/src/main/java/org/apache/tika/batch/fs/RecursiveParserWrapperFSConsumer.java
index f95bcbb..259157f 100644
--- 
a/tika-batch/src/main/java/org/apache/tika/batch/fs/RecursiveParserWrapperFSConsumer.java
+++ 
b/tika-batch/src/main/java/org/apache/tika/batch/fs/RecursiveParserWrapperFSConsumer.java
@@ -37,6 +37,7 @@ import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.ContentHandlerFactory;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.apache.tika.utils.ExceptionUtils;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -49,36 +50,46 @@ import org.xml.sax.helpers.DefaultHandler;
  */
 public class RecursiveParserWrapperFSConsumer extends AbstractFSConsumer {
 
-
-    private final ParserFactory parserFactory;
+    private final Parser parser;
     private final ContentHandlerFactory contentHandlerFactory;
     private final OutputStreamFactory fsOSFactory;
-    private final TikaConfig tikaConfig;
     private String outputEncoding = "UTF-8";
 
 
+    /**
+     * @deprecated use {@link 
RecursiveParserWrapperFSConsumer#RecursiveParserWrapperFSConsumer(ArrayBlockingQueue,
 Parser, ContentHandlerFactory, OutputStreamFactory)}
+     * @param queue
+     * @param parserFactory
+     * @param contentHandlerFactory
+     * @param fsOSFactory
+     * @param config
+     */
     public RecursiveParserWrapperFSConsumer(ArrayBlockingQueue<FileResource> 
queue,
                                             ParserFactory parserFactory,
                                             ContentHandlerFactory 
contentHandlerFactory,
-                                            OutputStreamFactory fsOSFactory, 
TikaConfig tikaConfig) {
+                                            OutputStreamFactory fsOSFactory, 
TikaConfig config) {
         super(queue);
-        this.parserFactory = parserFactory;
         this.contentHandlerFactory = contentHandlerFactory;
         this.fsOSFactory = fsOSFactory;
-        this.tikaConfig = tikaConfig;
+        Parser parserToWrap = parserFactory.getParser(config);
+        this.parser = new RecursiveParserWrapper(parserToWrap, 
contentHandlerFactory);
+    }
+
+    public RecursiveParserWrapperFSConsumer(ArrayBlockingQueue<FileResource> 
queue,
+                                            Parser parserToWrap,
+                                            ContentHandlerFactory 
contentHandlerFactory,
+                                            OutputStreamFactory fsOSFactory) {
+        super(queue);
+        this.contentHandlerFactory = contentHandlerFactory;
+        this.fsOSFactory = fsOSFactory;
+        this.parser = new RecursiveParserWrapper(parserToWrap, 
contentHandlerFactory);
     }
 
     @Override
     public boolean processFileResource(FileResource fileResource) {
 
-        Parser wrapped = parserFactory.getParser(tikaConfig);
-        RecursiveParserWrapper parser = new RecursiveParserWrapper(wrapped, 
contentHandlerFactory);
         ParseContext context = new ParseContext();
 
-//        if (parseRecursively == true) {
-        context.set(Parser.class, parser);
-//        }
-
         //try to open outputstream first
         OutputStream os = getOutputStream(fsOSFactory, fileResource);
 
@@ -100,13 +111,14 @@ public class RecursiveParserWrapperFSConsumer extends 
AbstractFSConsumer {
         Throwable thrown = null;
         List<Metadata> metadataList = null;
         Metadata containerMetadata = fileResource.getMetadata();
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(contentHandlerFactory, -1);
         try {
-            parse(fileResource.getResourceId(), parser, is, new 
DefaultHandler(),
+            parse(fileResource.getResourceId(), parser, is, handler,
                     containerMetadata, context);
-            metadataList = parser.getMetadata();
+            metadataList = handler.getMetadataList();
         } catch (Throwable t) {
             thrown = t;
-            metadataList = parser.getMetadata();
+            metadataList = handler.getMetadataList();
             if (metadataList == null) {
                 metadataList = new LinkedList<>();
             }
diff --git 
a/tika-batch/src/main/java/org/apache/tika/batch/fs/builders/BasicTikaFSConsumersBuilder.java
 
b/tika-batch/src/main/java/org/apache/tika/batch/fs/builders/BasicTikaFSConsumersBuilder.java
index 4879af4..d55f3be 100644
--- 
a/tika-batch/src/main/java/org/apache/tika/batch/fs/builders/BasicTikaFSConsumersBuilder.java
+++ 
b/tika-batch/src/main/java/org/apache/tika/batch/fs/builders/BasicTikaFSConsumersBuilder.java
@@ -41,6 +41,7 @@ import org.apache.tika.batch.fs.FSOutputStreamFactory;
 import org.apache.tika.batch.fs.FSUtil;
 import org.apache.tika.batch.fs.RecursiveParserWrapperFSConsumer;
 import org.apache.tika.config.TikaConfig;
+import org.apache.tika.parser.Parser;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.apache.tika.sax.ContentHandlerFactory;
 import org.apache.tika.util.ClassLoaderUtil;
@@ -129,17 +130,17 @@ public class BasicTikaFSConsumersBuilder extends 
AbstractConsumersBuilder {
         OutputStreamFactory outputStreamFactory = getOutputStreamFactory(
                 outputStreamFactoryNode, runtimeAttributes,
                 contentHandlerFactory, recursiveParserWrapper);
-
+        Parser parser = parserFactory.getParser(config);
         if (recursiveParserWrapper) {
             for (int i = 0; i < numConsumers; i++) {
                 FileResourceConsumer c = new 
RecursiveParserWrapperFSConsumer(queue,
-                        parserFactory, contentHandlerFactory, 
outputStreamFactory, config);
+                        parser, contentHandlerFactory, outputStreamFactory);
                 consumers.add(c);
             }
         } else {
             for (int i = 0; i < numConsumers; i++) {
                 FileResourceConsumer c = new BasicTikaFSConsumer(queue,
-                        parserFactory, contentHandlerFactory, 
outputStreamFactory, config);
+                        parser, contentHandlerFactory, outputStreamFactory);
                 consumers.add(c);
             }
         }
diff --git 
a/tika-batch/src/test/java/org/apache/tika/batch/RecursiveParserWrapperFSConsumerTest.java
 
b/tika-batch/src/test/java/org/apache/tika/batch/RecursiveParserWrapperFSConsumerTest.java
index dd8e7a1..32128b2 100644
--- 
a/tika-batch/src/test/java/org/apache/tika/batch/RecursiveParserWrapperFSConsumerTest.java
+++ 
b/tika-batch/src/test/java/org/apache/tika/batch/RecursiveParserWrapperFSConsumerTest.java
@@ -35,7 +35,10 @@ import org.apache.tika.config.TikaConfig;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.metadata.serialization.JsonMetadataList;
+import org.apache.tika.parser.AutoDetectParser;
+import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.junit.Test;
 
@@ -69,9 +72,10 @@ public class RecursiveParserWrapperFSConsumerTest extends 
TikaTest {
         queue.add(new PoisonFileResource());
 
         MockOSFactory mockOSFactory = new MockOSFactory();
+        Parser p = new AutoDetectParserFactory().getParser(new TikaConfig());
         RecursiveParserWrapperFSConsumer consumer = new 
RecursiveParserWrapperFSConsumer(
-                queue, new AutoDetectParserFactory(), new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1),
-                mockOSFactory, new TikaConfig());
+                queue, p, new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1),
+                mockOSFactory);
 
         IFileProcessorFutureResult result = consumer.call();
         mockOSFactory.getStreams().get(0).flush();
@@ -80,12 +84,12 @@ public class RecursiveParserWrapperFSConsumerTest extends 
TikaTest {
 
         assertEquals(4, results.size());
         assertContains("another null pointer",
-                results.get(2).get(RecursiveParserWrapper.EMBEDDED_EXCEPTION));
+                
results.get(2).get(AbstractRecursiveParserWrapperHandler.EMBEDDED_EXCEPTION));
 
         assertEquals("Nikolai Lobachevsky", results.get(0).get("author"));
         for (int i = 1; i < 4; i++) {
             assertEquals("embeddedAuthor"+i, results.get(i).get("author"));
-            assertContains("some_embedded_content"+i, 
results.get(i).get(RecursiveParserWrapper.TIKA_CONTENT));
+            assertContains("some_embedded_content"+i, 
results.get(i).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
         }
     }
 
@@ -116,9 +120,10 @@ public class RecursiveParserWrapperFSConsumerTest extends 
TikaTest {
         queue.add(new PoisonFileResource());
 
         MockOSFactory mockOSFactory = new MockOSFactory();
+        Parser p = new AutoDetectParserFactory().getParser(new TikaConfig());
         RecursiveParserWrapperFSConsumer consumer = new 
RecursiveParserWrapperFSConsumer(
-                queue, new AutoDetectParserFactory(), new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1),
-                mockOSFactory, new TikaConfig());
+                queue, p, new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1),
+                mockOSFactory);
 
         IFileProcessorFutureResult result = consumer.call();
         mockOSFactory.getStreams().get(0).flush();
@@ -129,7 +134,7 @@ public class RecursiveParserWrapperFSConsumerTest extends 
TikaTest {
                 
results.get(0).get(TikaCoreProperties.TIKA_META_EXCEPTION_PREFIX + "runtime"));
         assertEquals("Nikolai Lobachevsky", results.get(0).get("author"));
         assertEquals("embeddedAuthor", results.get(1).get("author"));
-        assertContains("some_embedded_content", 
results.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
+        assertContains("some_embedded_content", 
results.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
     }
 
 
diff --git 
a/tika-core/src/main/java/org/apache/tika/sax/AbstractRecursiveParserWrapperHandler.java
 
b/tika-core/src/main/java/org/apache/tika/sax/AbstractRecursiveParserWrapperHandler.java
new file mode 100644
index 0000000..58f9ec6
--- /dev/null
+++ 
b/tika-core/src/main/java/org/apache/tika/sax/AbstractRecursiveParserWrapperHandler.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.sax;
+
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.metadata.Property;
+import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.utils.ParserUtils;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+/**
+ * This is a special handler to be used only with the {@link 
org.apache.tika.parser.RecursiveParserWrapper}.
+ * It allows for finer-grained processing of embedded documents than in the 
legacy handlers.
+ * Subclasses can choose how to process individual embedded documents.
+ */
+public abstract class AbstractRecursiveParserWrapperHandler extends 
DefaultHandler {
+
+    public final static Property TIKA_CONTENT = 
Property.internalText(TikaCoreProperties.TIKA_META_PREFIX+"content");
+    public final static Property PARSE_TIME_MILLIS = 
Property.internalText(TikaCoreProperties.TIKA_META_PREFIX + 
"parse_time_millis");
+    public final static Property WRITE_LIMIT_REACHED =
+            
Property.internalBoolean(TikaCoreProperties.TIKA_META_EXCEPTION_PREFIX + 
"write_limit_reached");
+    public final static Property EMBEDDED_RESOURCE_LIMIT_REACHED =
+            
Property.internalBoolean(TikaCoreProperties.TIKA_META_EXCEPTION_PREFIX + 
"embedded_resource_limit_reached");
+
+    public final static Property EMBEDDED_EXCEPTION = 
ParserUtils.EMBEDDED_EXCEPTION;
+
+    public final static Property EMBEDDED_RESOURCE_PATH =
+            
Property.internalText(TikaCoreProperties.TIKA_META_PREFIX+"embedded_resource_path");
+
+    private final ContentHandlerFactory contentHandlerFactory;
+    private final int maxEmbeddedResources;
+    private int embeddedResources = 0;
+
+    public AbstractRecursiveParserWrapperHandler(ContentHandlerFactory 
contentHandlerFactory) {
+        this(contentHandlerFactory, -1);
+    }
+
+    public AbstractRecursiveParserWrapperHandler(ContentHandlerFactory 
contentHandlerFactory, int maxEmbeddedResources) {
+        this.contentHandlerFactory = contentHandlerFactory;
+        this.maxEmbeddedResources = maxEmbeddedResources;
+    }
+
+    public ContentHandler getNewContentHandler() {
+        return contentHandlerFactory.getNewContentHandler();
+    }
+
+    public ContentHandler getNewContentHandler(OutputStream os, Charset 
charset) {
+        return contentHandlerFactory.getNewContentHandler(os, charset);
+    }
+
+    /**
+     * This is called before parsing each embedded document.  Override this
+     * for custom behavior.  Make sure to call this in your custom classes
+     * because this tracks the number of embedded documents.
+     *
+     * @param contentHandler local handler to be used on this embedded document
+     * @param metadata embedded document's metadata
+     */
+    public void startEmbeddedDocument(ContentHandler contentHandler, Metadata 
metadata) throws SAXException {
+        embeddedResources++;
+    }
+    /**
+     * This is called after parsing each embedded document.  Override this
+     * for custom behavior.  This is currently a no-op.
+     *
+     * @param contentHandler content handler that was used on this embedded 
document
+     * @param metadata metadata for this embedded document
+     * @throws SAXException
+     */
+    public void endEmbeddedDocument(ContentHandler contentHandler, Metadata 
metadata) throws SAXException {
+    }
+
+    /**
+     * This is called after the full parse has completed.  Override this
+     * for custom behavior.  Make sure to call this as 
<code>super.endDocument(...)</code>
+     * in subclasses because this adds whether or not the embedded resource
+     * maximum has been hit to the metadata.
+     *
+     * @param contentHandler content handler that was used on the main document
+     * @param metadata metadata that was gathered for the main document
+     * @throws SAXException
+     */
+    public void endDocument(ContentHandler contentHandler, Metadata metadata) 
throws SAXException {
+        if (hasHitMaximumEmbeddedResources()) {
+            metadata.set(EMBEDDED_RESOURCE_LIMIT_REACHED, "true");
+        }
+    }
+
+    /**
+     *
+     * @return whether this handler has hit the maximum embedded resources 
during the parse
+     */
+    public boolean hasHitMaximumEmbeddedResources() {
+        if (maxEmbeddedResources > -1 && embeddedResources > 
maxEmbeddedResources) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git 
a/tika-core/src/main/java/org/apache/tika/sax/BasicContentHandlerFactory.java 
b/tika-core/src/main/java/org/apache/tika/sax/BasicContentHandlerFactory.java
index c611f09..899994e 100644
--- 
a/tika-core/src/main/java/org/apache/tika/sax/BasicContentHandlerFactory.java
+++ 
b/tika-core/src/main/java/org/apache/tika/sax/BasicContentHandlerFactory.java
@@ -19,6 +19,7 @@ package org.apache.tika.sax;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.util.Locale;
 
 import org.xml.sax.ContentHandler;
@@ -116,40 +117,48 @@ public class BasicContentHandlerFactory implements 
ContentHandlerFactory {
 
     @Override
     public ContentHandler getNewContentHandler(OutputStream os, String 
encoding) throws UnsupportedEncodingException {
+        return getNewContentHandler(os, Charset.forName(encoding));
+    }
+
+    @Override
+    public ContentHandler getNewContentHandler(OutputStream os, Charset 
charset) {
 
         if (type == HANDLER_TYPE.IGNORE) {
             return new DefaultHandler();
         }
-
-        if (writeLimit > -1) {
-            switch(type) {
-                case BODY:
-                    return new WriteOutContentHandler(
-                            new BodyContentHandler(
-                                    new OutputStreamWriter(os, encoding)), 
writeLimit);
-                case TEXT:
-                    return new WriteOutContentHandler(new 
ToTextContentHandler(os, encoding), writeLimit);
-                case HTML:
-                    return new WriteOutContentHandler(new 
ToHTMLContentHandler(os, encoding), writeLimit);
-                case XML:
-                    return new WriteOutContentHandler(new 
ToXMLContentHandler(os, encoding), writeLimit);
-                default:
-                    return new WriteOutContentHandler(new 
ToTextContentHandler(os, encoding), writeLimit);
-            }
-        } else {
-            switch (type) {
-                case BODY:
-                    return new BodyContentHandler(new OutputStreamWriter(os, 
encoding));
-                case TEXT:
-                    return new ToTextContentHandler(os, encoding);
-                case HTML:
-                    return new ToHTMLContentHandler(os, encoding);
-                case XML:
-                    return new ToXMLContentHandler(os, encoding);
-                default:
-                    return new ToTextContentHandler(os, encoding);
-
+        try {
+            if (writeLimit > -1) {
+                switch (type) {
+                    case BODY:
+                        return new WriteOutContentHandler(
+                                new BodyContentHandler(
+                                        new OutputStreamWriter(os, charset)), 
writeLimit);
+                    case TEXT:
+                        return new WriteOutContentHandler(new 
ToTextContentHandler(os, charset.name()), writeLimit);
+                    case HTML:
+                        return new WriteOutContentHandler(new 
ToHTMLContentHandler(os, charset.name()), writeLimit);
+                    case XML:
+                        return new WriteOutContentHandler(new 
ToXMLContentHandler(os, charset.name()), writeLimit);
+                    default:
+                        return new WriteOutContentHandler(new 
ToTextContentHandler(os, charset.name()), writeLimit);
+                }
+            } else {
+                switch (type) {
+                    case BODY:
+                        return new BodyContentHandler(new 
OutputStreamWriter(os, charset));
+                    case TEXT:
+                        return new ToTextContentHandler(os, charset.name());
+                    case HTML:
+                        return new ToHTMLContentHandler(os, charset.name());
+                    case XML:
+                        return new ToXMLContentHandler(os, charset.name());
+                    default:
+                        return new ToTextContentHandler(os, charset.name());
+
+                }
             }
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("couldn't find charset for name: 
"+charset);
         }
     }
 
diff --git 
a/tika-core/src/main/java/org/apache/tika/sax/ContentHandlerFactory.java 
b/tika-core/src/main/java/org/apache/tika/sax/ContentHandlerFactory.java
index c69b980..9dd74c4 100644
--- a/tika-core/src/main/java/org/apache/tika/sax/ContentHandlerFactory.java
+++ b/tika-core/src/main/java/org/apache/tika/sax/ContentHandlerFactory.java
@@ -21,12 +21,18 @@ import org.xml.sax.ContentHandler;
 
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 
 /**
  * Interface to allow easier injection of code for getting a new ContentHandler
  */
 public interface ContentHandlerFactory {
     public ContentHandler getNewContentHandler();
+    /**
+     * @deprecated use {@link #getNewContentHandler(OutputStream, Charset)}
+     */
+    @Deprecated
     public ContentHandler getNewContentHandler(OutputStream os, String 
encoding) throws UnsupportedEncodingException;
+    public ContentHandler getNewContentHandler(OutputStream os, Charset 
charset);
 
 }
diff --git 
a/tika-core/src/main/java/org/apache/tika/sax/RecursiveParserWrapperHandler.java
 
b/tika-core/src/main/java/org/apache/tika/sax/RecursiveParserWrapperHandler.java
new file mode 100644
index 0000000..2444a9c
--- /dev/null
+++ 
b/tika-core/src/main/java/org/apache/tika/sax/RecursiveParserWrapperHandler.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.sax;
+
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.utils.ParserUtils;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This is the default implementation of {@link 
AbstractRecursiveParserWrapperHandler}.
+ * See its documentation for more details.
+ *
+ * This caches the a metadata object for each embedded file and for the 
container file.
+ * It places the extracted content in the metadata object, with this key: 
{@link AbstractRecursiveParserWrapperHandler#TIKA_CONTENT}
+ * If memory is a concern, subclass AbstractRecursiveParserWrapperHandler to 
handle each
+ * embedded document.
+ * <p>
+ *     <b>NOTE: This handler must only be used with the {@link 
org.apache.tika.parser.RecursiveParserWrapper}</b>
+ * </p>
+ */
+public class RecursiveParserWrapperHandler extends 
AbstractRecursiveParserWrapperHandler {
+
+    private final List<Metadata> metadataList = new LinkedList<>();
+
+    /**
+     * Create a handler with no limit on the number of embedded resources
+     */
+    public RecursiveParserWrapperHandler(ContentHandlerFactory 
contentHandlerFactory) {
+        super(contentHandlerFactory);
+    }
+
+    /**
+     * Create a handler that limits the number of embedded resources that will 
be
+     * parsed
+     * @param maxEmbeddedResources number of embedded resources that will be 
parsed
+     */
+    public RecursiveParserWrapperHandler(ContentHandlerFactory 
contentHandlerFactory, int maxEmbeddedResources) {
+        super(contentHandlerFactory, maxEmbeddedResources);
+    }
+
+    /**
+     * This is called before parsing an embedded document
+     *
+     * @param contentHandler - local content handler to use on the embedded 
document
+     * @param metadata metadata to use for the embedded document
+     * @throws SAXException
+     */
+    @Override
+    public void startEmbeddedDocument(ContentHandler contentHandler, Metadata 
metadata) throws SAXException {
+        super.startEmbeddedDocument(contentHandler, metadata);
+    }
+
+    /**
+     * This is called after parsing an embedded document.
+     * @param contentHandler local contenthandler used on the embedded document
+     * @param metadata metadata from the embedded document
+     * @throws SAXException
+     */
+    @Override
+    public void endEmbeddedDocument(ContentHandler contentHandler, Metadata 
metadata) throws SAXException {
+        super.endEmbeddedDocument(contentHandler, metadata);
+        addContent(contentHandler, metadata);
+        metadataList.add(ParserUtils.cloneMetadata(metadata));
+    }
+
+    /**
+     *
+     * @param contentHandler content handler used on the main document
+     * @param metadata metadata from the main document
+     * @throws SAXException
+     */
+    @Override
+    public void endDocument(ContentHandler contentHandler, Metadata metadata) 
throws SAXException {
+        super.endDocument(contentHandler, metadata);
+        addContent(contentHandler, metadata);
+
+        metadataList.add(0, ParserUtils.cloneMetadata(metadata));
+    }
+
+    /**
+     *
+     * @return a list of Metadata objects, one for the main document and one 
for each embedded document
+     */
+    public List<Metadata> getMetadataList() {
+        return metadataList;
+    }
+
+    private void addContent(ContentHandler handler, Metadata metadata) {
+
+        if (handler.getClass().equals(DefaultHandler.class)){
+            //no-op: we can't rely on just testing for
+            //empty content because DefaultHandler's toString()
+            //returns e.g. "org.xml.sax.helpers.DefaultHandler@6c8b1edd"
+        } else {
+            String content = handler.toString();
+            if (content != null && content.trim().length() > 0 ) {
+                metadata.add(TIKA_CONTENT, content);
+            }
+        }
+    }
+}
diff --git a/tika-core/src/main/java/org/apache/tika/utils/ParserUtils.java 
b/tika-core/src/main/java/org/apache/tika/utils/ParserUtils.java
new file mode 100644
index 0000000..02958c2
--- /dev/null
+++ b/tika-core/src/main/java/org/apache/tika/utils/ParserUtils.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tika.io.TemporaryResources;
+import org.apache.tika.io.TikaInputStream;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.metadata.Property;
+import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.parser.Parser;
+import org.apache.tika.parser.ParserDecorator;
+
+/**
+ * Helper util methods for Parsers themselves.
+ */
+public class ParserUtils {
+    public final static String X_PARSED_BY = "X-Parsed-By"; 
+    public final static Property EMBEDDED_PARSER =
+            
Property.internalText(TikaCoreProperties.TIKA_META_EXCEPTION_PREFIX + 
"embedded_parser");
+    public final static Property EMBEDDED_EXCEPTION =
+            
Property.internalText(TikaCoreProperties.TIKA_META_EXCEPTION_PREFIX + 
"embedded_exception");
+    
+    /**
+     * Does a deep clone of a Metadata object.
+     */
+    public static Metadata cloneMetadata(Metadata m) {
+        Metadata clone = new Metadata();
+        
+        for (String n : m.names()){
+            if (! m.isMultiValued(n)) {
+                clone.set(n, m.get(n));
+            } else {
+                String[] vals = m.getValues(n);
+                for (int i = 0; i < vals.length; i++) {
+                    clone.add(n, vals[i]);
+                }
+            }
+        }
+        return clone;
+    }
+
+    /**
+     * Identifies the real class name of the {@link Parser}, unwrapping
+     *  any {@link ParserDecorator} decorations on top of it.
+     */
+    public static String getParserClassname(Parser parser) {
+        if (parser instanceof ParserDecorator){
+            return ((ParserDecorator) 
parser).getWrappedParser().getClass().getName();
+        } else {
+            return parser.getClass().getName();
+        }
+    }
+
+    /**
+     * Records details of the {@link Parser} used to the {@link Metadata},
+     *  typically wanted where multiple parsers could be picked between
+     *  or used.
+     */
+    public static void recordParserDetails(Parser parser, Metadata metadata) {
+        metadata.add(X_PARSED_BY, getParserClassname(parser));
+    }
+
+    /**
+     * Records details of a {@link Parser}'s failure to the
+     *  {@link Metadata}, so you can check what went wrong even if the
+     *  {@link Exception} wasn't immediately thrown (eg when several different
+     *  Parsers are used)
+     */
+    public static void recordParserFailure(Parser parser, Exception failure, 
+                                           Metadata metadata) {
+        String trace = ExceptionUtils.getStackTrace(failure);
+        metadata.add(EMBEDDED_EXCEPTION, trace);
+        metadata.add(EMBEDDED_PARSER, getParserClassname(parser));
+    }
+
+    /**
+     * Ensures that the Stream will be able to be re-read, by buffering to
+     *  a temporary file if required.
+     * Streams that are automatically OK include {@link TikaInputStream}s
+     *  created from Files or InputStreamFactories, and {@link 
RereadableInputStream}.
+     */
+    public static InputStream ensureStreamReReadable(InputStream stream, 
TemporaryResources tmp) throws IOException {
+        // If it's re-readable, we're done
+        if (stream instanceof RereadableInputStream) return stream;
+
+        // Make sure it's a TikaInputStream
+        TikaInputStream tstream = TikaInputStream.cast(stream);
+        if (tstream == null) {
+            tstream = TikaInputStream.get(stream, tmp);
+        }
+
+        // If it's factory based, it's ok
+        if (tstream.getInputStreamFactory() != null) return tstream;
+
+        // Ensure it's file based
+        tstream.getFile();
+        // Prepare for future re-reads
+        tstream.mark(-1);
+        return tstream;
+    }
+    /**
+     * Resets the given {@link TikaInputStream} (checked by 
+     *  {@link #ensureStreamReReadable(InputStream, TemporaryResources)})
+     * so that it can be re-read again.
+     */
+    public static InputStream streamResetForReRead(InputStream stream, 
TemporaryResources tmp) throws IOException {
+        // If re-readable, rewind to start
+        if (stream instanceof RereadableInputStream) {
+            ((RereadableInputStream)stream).rewind();
+            return stream;
+        }
+
+        // File or Factory based?
+        TikaInputStream tstream = (TikaInputStream)stream;
+        if (tstream.getInputStreamFactory() != null) {
+            // Just get a fresh one each time from the factory
+            return TikaInputStream.get(tstream.getInputStreamFactory(), tmp);
+        }
+
+        // File based, reset stream to beginning of File
+        tstream.reset();
+        tstream.mark(-1);
+        return tstream;
+    }
+}
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 c0ec98c..bd0f263 100644
--- a/tika-core/src/test/java/org/apache/tika/MultiThreadedTikaTest.java
+++ b/tika-core/src/test/java/org/apache/tika/MultiThreadedTikaTest.java
@@ -22,7 +22,9 @@ import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BasicContentHandlerFactory;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.junit.Test;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -136,8 +138,10 @@ public class MultiThreadedTikaTest extends TikaTest {
 
         //use the same parser in all threads
         Parser parser = new AutoDetectParser();
+        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(parser,
+                new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1));
         for (int i = 0; i < numThreads; i++) {
-            executorCompletionService.submit(new TikaRunner(parser, 
numIterations, testFiles, truth));
+            executorCompletionService.submit(new TikaRunner(wrapper, 
numIterations, testFiles, truth));
         }
 
         int completed = 0;
@@ -184,12 +188,14 @@ public class MultiThreadedTikaTest extends TikaTest {
 
             try {
                 Parser p = new AutoDetectParser();
-                RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p,
-                        new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1));
+                RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p);
+                RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
+                        new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1),
+                        -1);
                 try (InputStream is = Files.newInputStream(f)) {
-                    wrapper.parse(is, new DefaultHandler(), new Metadata(), 
new ParseContext());
+                    wrapper.parse(is, handler, new Metadata(), new 
ParseContext());
                 }
-                List<Metadata> metadataList = wrapper.getMetadata();
+                List<Metadata> metadataList = handler.getMetadataList();
                 baseline.put(f, new Extract(metadataList));
             } catch (Exception e) {
                 //swallow
@@ -198,26 +204,28 @@ public class MultiThreadedTikaTest extends TikaTest {
         return baseline;
     }
 
-    private static List<Metadata> getRecursiveMetadata(InputStream is, Parser 
p) throws Exception {
+    private static List<Metadata> getRecursiveMetadata(InputStream is, 
RecursiveParserWrapper wrapper) throws Exception {
         //different from parent TikaTest in that this extracts text.
         //can't extract xhtml because "tmp" file names wind up in
         //content's metadata and they'll differ by file.
-        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p,
-                new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1));
-        wrapper.parse(is, new DefaultHandler(), new Metadata(), new 
ParseContext());
-        return wrapper.getMetadata();
+
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
+                new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.TEXT, -1),
+                -1);
+        wrapper.parse(is, handler, new Metadata(), new ParseContext());
+        return handler.getMetadataList();
     }
 
     //TODO: make this return something useful besides an integer
     private class TikaRunner implements Callable<Integer> {
-        private final Parser parser;
+        private final RecursiveParserWrapper parser;
         private final int iterations;
         private final Path[] files;
         private final Map<Path, Extract> truth;
 
         private final Random random = new Random();
 
-        private TikaRunner(Parser parser, int iterations, Path[] files, 
Map<Path, Extract> truth) {
+        private TikaRunner(RecursiveParserWrapper parser, int iterations, 
Path[] files, Map<Path, Extract> truth) {
             this.parser = parser;
             this.iterations = iterations;
             this.files = files;
@@ -253,8 +261,8 @@ public class MultiThreadedTikaTest extends TikaTest {
                     extractA.metadataList.get(i).size(), 
extractB.metadataList.get(i).size());
 
             assertEquals("content in attachment: " + i,
-                    
extractA.metadataList.get(i).get(RecursiveParserWrapper.TIKA_CONTENT),
-                    
extractB.metadataList.get(i).get(RecursiveParserWrapper.TIKA_CONTENT));
+                    
extractA.metadataList.get(i).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT),
+                    
extractB.metadataList.get(i).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
         }
     }
 
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 9c827f7..1c4fce9 100644
--- a/tika-core/src/test/java/org/apache/tika/TikaTest.java
+++ b/tika-core/src/test/java/org/apache/tika/TikaTest.java
@@ -44,6 +44,7 @@ import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.apache.tika.sax.BodyContentHandler;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.apache.tika.sax.ToXMLContentHandler;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.helpers.DefaultHandler;
@@ -219,40 +220,47 @@ public abstract class TikaTest {
 
     protected List<Metadata> getRecursiveMetadata(String filePath, 
ParseContext context, Metadata metadata) throws Exception {
         Parser p = new AutoDetectParser();
-        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p,
+        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p);
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
                 new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML, -1));
+
         try (InputStream is = getResourceAsStream("/test-documents/" + 
filePath)) {
-            wrapper.parse(is, new DefaultHandler(), metadata, context);
+            wrapper.parse(is, handler, metadata, context);
         }
-        return wrapper.getMetadata();
+        return handler.getMetadataList();
     }
 
     protected List<Metadata> getRecursiveMetadata(String filePath, 
ParseContext context) throws Exception {
         Parser p = new AutoDetectParser();
-        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p,
+        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p);
+
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
                 new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML, -1));
         try (InputStream is = getResourceAsStream("/test-documents/" + 
filePath)) {
-            wrapper.parse(is, new DefaultHandler(), new Metadata(), context);
+            wrapper.parse(is, handler, new Metadata(), context);
         }
-        return wrapper.getMetadata();
+        return handler.getMetadataList();
     }
 
     protected List<Metadata> getRecursiveMetadata(String filePath, Parser 
parserToWrap) throws Exception {
-        RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parserToWrap,
+        RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parserToWrap);
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
                 new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML, -1));
         try (InputStream is = getResourceAsStream("/test-documents/" + 
filePath)) {
-            wrapper.parse(is, new DefaultHandler(), new Metadata(), new 
ParseContext());
+            wrapper.parse(is, handler, new Metadata(), new ParseContext());
         }
-        return wrapper.getMetadata();
+        return handler.getMetadataList();
     }
 
     protected List<Metadata> getRecursiveMetadata(String filePath, Parser 
parserToWrap, ParseContext parseContext) throws Exception {
-        RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parserToWrap,
+        RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parserToWrap);
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
                 new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML, -1));
+
         try (InputStream is = getResourceAsStream("/test-documents/" + 
filePath)) {
-            wrapper.parse(is, new DefaultHandler(), new Metadata(), 
parseContext);
+            wrapper.parse(is, handler, new Metadata(), parseContext);
         }
-        return wrapper.getMetadata();
+        return handler.getMetadataList();
     }
 
 
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/AbstractProfiler.java 
b/tika-eval/src/main/java/org/apache/tika/eval/AbstractProfiler.java
index 5029ecf..0a67ad0 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/AbstractProfiler.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/AbstractProfiler.java
@@ -61,6 +61,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.PagedText;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.utils.ExceptionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -254,7 +255,7 @@ public abstract class AbstractProfiler extends 
FileResourceConsumer {
             data.put(Cols.FILE_NAME, 
fps.getRelativeSourceFilePath().getFileName().toString());
         } else {
             data.put(Cols.IS_EMBEDDED, TRUE);
-            data.put(Cols.FILE_NAME, 
getFileName(m.get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH)));
+            data.put(Cols.FILE_NAME, 
getFileName(m.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH)));
         }
         String ext = FilenameUtils.getExtension(data.get(Cols.FILE_NAME));
         ext = (ext == null) ? "" : ext.toLowerCase(Locale.US);
@@ -391,7 +392,7 @@ public abstract class AbstractProfiler extends 
FileResourceConsumer {
     String getTime(Metadata m) {
         String elapsed = "-1";
 
-        String v = m.get(RecursiveParserWrapper.PARSE_TIME_MILLIS);
+        String v = 
m.get(AbstractRecursiveParserWrapperHandler.PARSE_TIME_MILLIS);
         if (v != null) {
             return v;
         }
@@ -414,7 +415,7 @@ public abstract class AbstractProfiler extends 
FileResourceConsumer {
         String fullTrace = 
metadata.get(TikaCoreProperties.TIKA_META_EXCEPTION_PREFIX + "runtime");
 
         if (fullTrace == null) {
-            fullTrace = 
metadata.get(RecursiveParserWrapper.EMBEDDED_EXCEPTION);
+            fullTrace = 
metadata.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_EXCEPTION);
         }
 
         if (fullTrace != null) {
@@ -475,7 +476,7 @@ public abstract class AbstractProfiler extends 
FileResourceConsumer {
         if (metadata == null) {
             return "";
         }
-        String c = metadata.get(RecursiveParserWrapper.TIKA_CONTENT);
+        String c = 
metadata.get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT);
         if (c == null) {
             return "";
         }
@@ -723,7 +724,7 @@ public abstract class AbstractProfiler extends 
FileResourceConsumer {
 
         Map<String, Integer> counts = new HashMap<>();
         for (int i = 1; i < list.size(); i++) {
-            String path = 
list.get(i).get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH);
+            String path = 
list.get(i).get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH);
             if (path == null) {
                 //shouldn't ever happen
                 continue;
@@ -745,7 +746,7 @@ public abstract class AbstractProfiler extends 
FileResourceConsumer {
         }
 
         for (int i = 1; i < list.size(); i++) {
-            Integer count = 
counts.get(list.get(i).get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH));
+            Integer count = 
counts.get(list.get(i).get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH));
             if (count == null) {
                 count = 0;
             }
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/ExtractComparer.java 
b/tika-eval/src/main/java/org/apache/tika/eval/ExtractComparer.java
index fd1c382..749b450 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/ExtractComparer.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/ExtractComparer.java
@@ -45,6 +45,7 @@ import org.apache.tika.eval.tokens.TokenIntPair;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 
 public class ExtractComparer extends AbstractProfiler {
 
@@ -352,10 +353,10 @@ public class ExtractComparer extends AbstractProfiler {
         String pathA = null;
         String pathB = null;
         if (mA != null) {
-            pathA = mA.get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH);
+            pathA = 
mA.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH);
         }
         if (mB != null) {
-            pathB = mB.get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH);
+            pathB = 
mB.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH);
         }
         if (pathA != null) {
             Map<Cols, String> d = new HashMap<>();
@@ -390,7 +391,7 @@ public class ExtractComparer extends AbstractProfiler {
 
 
     /**
-     * Try to find the matching metadata based on the 
RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH
+     * Try to find the matching metadata based on the 
AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH
      * If you can't find it, return -1;
      *
      * @param i                index for match in metadataListA
@@ -419,11 +420,11 @@ public class ExtractComparer extends AbstractProfiler {
 
         //assume same embedded resource path.  Not always true!
         Metadata thisMetadata = metadataListA.get(i);
-        String embeddedPath = 
thisMetadata.get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH);
+        String embeddedPath = 
thisMetadata.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH);
         if (embeddedPath != null) {
             for (int j = 0; j < metadataListB.size(); j++) {
                 String thatEmbeddedPath = metadataListB.get(j).get(
-                        RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH);
+                        
AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH);
                 if (embeddedPath.equals(thatEmbeddedPath)) {
                     return j;
                 }
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/ExtractProfiler.java 
b/tika-eval/src/main/java/org/apache/tika/eval/ExtractProfiler.java
index d5f9af3..200bf33 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/ExtractProfiler.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/ExtractProfiler.java
@@ -37,6 +37,7 @@ import org.apache.tika.eval.io.ExtractReaderException;
 import org.apache.tika.eval.io.IDBWriter;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 
 public class ExtractProfiler extends AbstractProfiler {
 
@@ -247,7 +248,7 @@ public class ExtractProfiler extends AbstractProfiler {
         Map<Cols, String> data = new HashMap<>();
         data.put(Cols.ID, fileId);
         data.put(Cols.EMBEDDED_FILE_PATH,
-                m.get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH));
+                
m.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH));
         try {
             writer.writeRow(embeddedFilePathTable, data);
         } catch (IOException e) {
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/io/ExtractReader.java 
b/tika-eval/src/main/java/org/apache/tika/eval/io/ExtractReader.java
index 2a46b84..6f2075c 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/io/ExtractReader.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/io/ExtractReader.java
@@ -23,6 +23,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.serialization.JsonMetadataList;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -148,13 +149,13 @@ public class ExtractReader {
                     Metadata containerMetadata = metadataList.get(0);
                     for (int i = 0; i < metadataList.size(); i++) {
                         Metadata m = metadataList.get(i);
-                        String c = m.get(RecursiveParserWrapper.TIKA_CONTENT);
+                        String c = 
m.get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT);
                         if (c != null) {
                             sb.append(c);
                             sb.append(" ");
                         }
                     }
-                    containerMetadata.set(RecursiveParserWrapper.TIKA_CONTENT, 
sb.toString());
+                    
containerMetadata.set(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT, 
sb.toString());
                     while (metadataList.size() > 1) {
                         metadataList.remove(metadataList.size()-1);
                     }
@@ -178,7 +179,7 @@ public class ExtractReader {
         List<Metadata> metadataList = new ArrayList<>();
         String content = IOUtils.toString(reader);
         Metadata m = new Metadata();
-        m.set(RecursiveParserWrapper.TIKA_CONTENT, content);
+        m.set(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT, content);
         //Let's hope the file name has a suffix that can
         //be used to determine the mime.  Could be wrong or missing,
         //but better than nothing.
diff --git 
a/tika-eval/src/test/java/org/apache/tika/eval/SimpleComparerTest.java 
b/tika-eval/src/test/java/org/apache/tika/eval/SimpleComparerTest.java
index ea516c6..de09fa1 100644
--- a/tika-eval/src/test/java/org/apache/tika/eval/SimpleComparerTest.java
+++ b/tika-eval/src/test/java/org/apache/tika/eval/SimpleComparerTest.java
@@ -41,6 +41,7 @@ import org.apache.tika.eval.io.ExtractReaderException;
 import org.apache.tika.eval.util.LanguageIDWrapper;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -184,7 +185,7 @@ public class SimpleComparerTest extends TikaTest {
     @Test
     public void testGetContent() throws Exception {
         Metadata m = new Metadata();
-        m.add(RecursiveParserWrapper.TIKA_CONTENT, "0123456789");
+        m.add(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT, 
"0123456789");
         Map<Cols, String> data = new HashMap<>();
         String content = getContent(m, 10, data);
         assertEquals(10, content.length());
@@ -233,23 +234,23 @@ public class SimpleComparerTest extends TikaTest {
     public void testAttachmentCounts() {
         List<Metadata> list = new ArrayList<>();
         Metadata m0 = new Metadata();
-        m0.set(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH, 
"dir1/dir2/file.zip");//bad data should be ignored
+        m0.set(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH, 
"dir1/dir2/file.zip");//bad data should be ignored
                                                                                
     //in the first metadata object
         list.add(m0);
         Metadata m1 = new Metadata();
-        m1.set(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/f2.zip/text1.txt");
+        m1.set(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/f2.zip/text1.txt");
         list.add(m1);
         Metadata m2 = new Metadata();
-        m2.set(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/f2.zip/text2.txt");
+        m2.set(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/f2.zip/text2.txt");
         list.add(m2);
         Metadata m3 = new Metadata();
-        m3.set(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/f2.zip");
+        m3.set(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/f2.zip");
         list.add(m3);
         Metadata m4 = new Metadata();
-        m4.set(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH, "/f1.docx");
+        m4.set(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH, 
"/f1.docx");
         list.add(m4);
         Metadata m5 = new Metadata();
-        m5.set(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/text3.txt");
+        m5.set(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH, 
"/f1.docx/text3.txt");
         list.add(m5);
 
         List<Integer> counts = AbstractProfiler.countAttachments(list);
diff --git 
a/tika-eval/src/test/java/org/apache/tika/eval/io/ExtractReaderTest.java 
b/tika-eval/src/test/java/org/apache/tika/eval/io/ExtractReaderTest.java
index f22179a..47d5934 100644
--- a/tika-eval/src/test/java/org/apache/tika/eval/io/ExtractReaderTest.java
+++ b/tika-eval/src/test/java/org/apache/tika/eval/io/ExtractReaderTest.java
@@ -26,6 +26,7 @@ import java.util.List;
 import org.apache.tika.TikaTest;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -47,24 +48,24 @@ public class ExtractReaderTest extends TikaTest {
         List<Metadata> metadataList = extractReader.loadExtract(testJsonFile);
 
         assertEquals(2, metadataList.size());
-        assertEquals(1, 
metadataList.get(0).getValues(RecursiveParserWrapper.TIKA_CONTENT).length);
-        assertEquals(1, 
metadataList.get(1).getValues(RecursiveParserWrapper.TIKA_CONTENT).length);
-        assertContains("fox", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
-        assertContains("attachment", 
metadataList.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
+        assertEquals(1, 
metadataList.get(0).getValues(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).length);
+        assertEquals(1, 
metadataList.get(1).getValues(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).length);
+        assertContains("fox", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
+        assertContains("attachment", 
metadataList.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
 
         extractReader = new 
ExtractReader(ExtractReader.ALTER_METADATA_LIST.FIRST_ONLY);
         metadataList = extractReader.loadExtract(testJsonFile);
         assertEquals(1, metadataList.size());
-        assertEquals(1, 
metadataList.get(0).getValues(RecursiveParserWrapper.TIKA_CONTENT).length);
-        assertContains("fox", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
-        assertNotContained("attachment", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
+        assertEquals(1, 
metadataList.get(0).getValues(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).length);
+        assertContains("fox", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
+        assertNotContained("attachment", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
 
         extractReader = new 
ExtractReader(ExtractReader.ALTER_METADATA_LIST.CONCATENATE_CONTENT_INTO_FIRST);
         metadataList = extractReader.loadExtract(testJsonFile);
         assertEquals(1, metadataList.size());
-        assertEquals(1, 
metadataList.get(0).getValues(RecursiveParserWrapper.TIKA_CONTENT).length);
-        assertContains("fox", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
-        assertContains("attachment", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
+        assertEquals(1, 
metadataList.get(0).getValues(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).length);
+        assertContains("fox", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
+        assertContains("attachment", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
     }
 
     @Test
@@ -73,9 +74,9 @@ public class ExtractReaderTest extends TikaTest {
         List<Metadata> metadataList = extractReader.loadExtract(testTxtFile);
         assertEquals(1, metadataList.size());
         Metadata m = metadataList.get(0);
-        assertEquals(1, 
m.getValues(RecursiveParserWrapper.TIKA_CONTENT).length);
+        assertEquals(1, 
m.getValues(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).length);
         assertEquals("the quick brown fox fox fox jumped over the lazy lazy 
dog\n",
-                m.get(RecursiveParserWrapper.TIKA_CONTENT));
+                m.get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
 
         //test that the mime is inferred from the file extension
         assertEquals("application/msword", m.get(Metadata.CONTENT_TYPE));
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 5e3201f..631099f 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
@@ -39,6 +39,7 @@ import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.apache.tika.sax.BodyContentHandler;
 import org.apache.tika.sax.ContentHandlerFactory;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -163,15 +164,16 @@ public class ParsingExample {
         ContentHandlerFactory factory = new BasicContentHandlerFactory(
                 BasicContentHandlerFactory.HANDLER_TYPE.HTML, -1);
 
-        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p, 
factory);
+        RecursiveParserWrapper wrapper = new RecursiveParserWrapper(p);
         Metadata metadata = new Metadata();
         metadata.set(Metadata.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")) {
-            wrapper.parse(stream, new DefaultHandler(), metadata, context);
+            wrapper.parse(stream, handler, metadata, context);
         }
-        return wrapper.getMetadata();
+
+        return handler.getMetadataList();
     }
 
     /**
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java 
b/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
index ab8e314..f4e630b 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java
@@ -71,6 +71,7 @@ import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BodyContentHandler;
 import org.apache.tika.sax.LinkContentHandler;
 import org.apache.tika.sax.TeeContentHandler;
@@ -1249,8 +1250,8 @@ public class HtmlParserTest extends TikaTest {
         assertEquals(2, metadataList.size());
         assertEquals("MACRO", 
metadataList.get(1).get(TikaCoreProperties.EMBEDDED_RESOURCE_TYPE));
         assertContains("cool",
-                metadataList.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
-        assertNotContained("cool", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
+                
metadataList.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
+        assertNotContained("cool", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
     }
 
     @Test
@@ -1263,8 +1264,8 @@ public class HtmlParserTest extends TikaTest {
         assertEquals(2, metadataList.size());
         assertEquals("MACRO", 
metadataList.get(1).get(TikaCoreProperties.EMBEDDED_RESOURCE_TYPE));
         assertContains("cool",
-                metadataList.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
-        assertNotContained("cool", 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT));
+                
metadataList.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
+        assertNotContained("cool", 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
 
     }
 
@@ -1272,7 +1273,7 @@ public class HtmlParserTest extends TikaTest {
     public void testDataURI() throws Exception {
         List<Metadata> metadataList = 
getRecursiveMetadata("testHTML_embedded_img.html");
         assertEquals(2, metadataList.size());
-        String content = 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT);
+        String content = 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT);
         assertContains("some content", content);
         //make sure that you've truncated the data: value
         assertContains("src=\"data:\"", content);
@@ -1290,7 +1291,7 @@ public class HtmlParserTest extends TikaTest {
         Parser p = new AutoDetectParser(tikaConfig);
         List<Metadata> metadataList = 
getRecursiveMetadata("testHTML_embedded_img_in_js.html", p);
         assertEquals(3, metadataList.size());
-        String content = 
metadataList.get(0).get(RecursiveParserWrapper.TIKA_CONTENT);
+        String content = 
metadataList.get(0).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT);
         assertContains("some content", content);
         Metadata imgMetadata = metadataList.get(1);
         assertEquals("image/jpeg", imgMetadata.get(Metadata.CONTENT_TYPE));
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/mbox/MboxParserTest.java 
b/tika-parsers/src/test/java/org/apache/tika/parser/mbox/MboxParserTest.java
index f1650a9..043261a 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/mbox/MboxParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/mbox/MboxParserTest.java
@@ -30,6 +30,7 @@ import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BodyContentHandler;
 import org.junit.Before;
 import org.junit.Test;
@@ -176,7 +177,7 @@ public class MboxParserTest extends TikaTest {
         assertEquals(2, metadataList.size());
         assertEquals("application/mbox", 
metadataList.get(0).get(Metadata.CONTENT_TYPE));
         assertEquals("message/rfc822", 
metadataList.get(1).get(Metadata.CONTENT_TYPE));
-        assertContains("body 2", 
metadataList.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
-        assertNotContained("body 1", 
metadataList.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
+        assertContains("body 2", 
metadataList.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
+        assertNotContained("body 1", 
metadataList.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
     }
 }
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/JackcessParserTest.java
 
b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/JackcessParserTest.java
index 3825400..e6aef53 100644
--- 
a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/JackcessParserTest.java
+++ 
b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/JackcessParserTest.java
@@ -36,6 +36,7 @@ import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.PasswordProvider;
 import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.BasicContentHandlerFactory;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.junit.Test;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -46,22 +47,24 @@ public class JackcessParserTest extends TikaTest {
 
         Parser p = new AutoDetectParser();
 
-        RecursiveParserWrapper w = new RecursiveParserWrapper(p,
-                new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML, -1));
+        RecursiveParserWrapper w = new RecursiveParserWrapper(p);
 
         for (String fName : new String[]{"testAccess2.accdb", 
"testAccess2_2000.mdb",
                 "testAccess2_2002-2003.mdb"}) {
             InputStream is = null;
+            RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
+                    new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.XML, -1)
+            );
             try {
                 is = this.getResourceAsStream("/test-documents/" + fName);
 
                 Metadata meta = new Metadata();
                 ParseContext c = new ParseContext();
-                w.parse(is, new DefaultHandler(), meta, c);
+                w.parse(is, handler, meta, c);
             } finally {
                 IOUtils.closeQuietly(is);
             }
-            List<Metadata> list = w.getMetadata();
+            List<Metadata> list = handler.getMetadataList();
             assertEquals(4, list.size());
             String mainContent = 
list.get(0).get(RecursiveParserWrapper.TIKA_CONTENT);
 
@@ -83,8 +86,6 @@ public class JackcessParserTest extends TikaTest {
             //test embedded document handling
             assertContains("Test Document with embedded pdf",
                     list.get(3).get(RecursiveParserWrapper.TIKA_CONTENT));
-
-            w.reset();
         }
     }
 
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/ocr/TesseractOCRParserTest.java
 
b/tika-parsers/src/test/java/org/apache/tika/parser/ocr/TesseractOCRParserTest.java
index b4648d1..039adf7 100644
--- 
a/tika-parsers/src/test/java/org/apache/tika/parser/ocr/TesseractOCRParserTest.java
+++ 
b/tika-parsers/src/test/java/org/apache/tika/parser/ocr/TesseractOCRParserTest.java
@@ -37,6 +37,7 @@ import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.parser.external.ExternalParser;
 import org.apache.tika.parser.image.ImageParser;
 import org.apache.tika.parser.pdf.PDFParserConfig;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.junit.Test;
 import org.xml.sax.helpers.DefaultHandler;
@@ -180,7 +181,7 @@ public class TesseractOCRParserTest extends TikaTest {
 
         StringBuilder contents = new StringBuilder();
         for (Metadata m : metadataList) {
-            contents.append(m.get(RecursiveParserWrapper.TIKA_CONTENT));
+            
contents.append(m.get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
         }
  
         for (String needle : nonOCRContains) {
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java 
b/tika-parsers/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
index be0ff9f..106d8df 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/pkg/ZipParserTest.java
@@ -38,6 +38,7 @@ import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BodyContentHandler;
 import org.junit.Test;
 import org.xml.sax.ContentHandler;
@@ -212,7 +213,7 @@ public class ZipParserTest extends AbstractPkgTest {
         assertContains("EncryptedDocumentException: stream (encrypted.txt) is 
encrypted", values[0]);
 
 
-        assertContains("hello world", 
metadataList.get(1).get(RecursiveParserWrapper.TIKA_CONTENT));
+        assertContains("hello world", 
metadataList.get(1).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
     }
 
     @Test
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/rtf/RTFParserTest.java 
b/tika-parsers/src/test/java/org/apache/tika/parser/rtf/RTFParserTest.java
index 8a53153..55c5786 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/rtf/RTFParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/rtf/RTFParserTest.java
@@ -49,8 +49,10 @@ import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BasicContentHandlerFactory;
 import org.apache.tika.sax.BodyContentHandler;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.apache.tika.sax.WriteOutContentHandler;
 import org.junit.Test;
 import org.xml.sax.ContentHandler;
@@ -444,7 +446,7 @@ public class RTFParserTest extends TikaTest {
             //directory: _1457338524/HW.txt
             assertEquals("filename equals ",
                     p.fileName, FilenameUtils.getName(
-                            
metadata.get(RecursiveParserWrapper.EMBEDDED_RESOURCE_PATH)));
+                            
metadata.get(AbstractRecursiveParserWrapperHandler.EMBEDDED_RESOURCE_PATH)));
 
             assertEquals(p.mimeType, metadata.get(Metadata.CONTENT_TYPE));
         }
@@ -457,15 +459,15 @@ public class RTFParserTest extends TikaTest {
     public void testRegularImages() throws Exception {
         Parser base = new AutoDetectParser();
         ParseContext ctx = new ParseContext();
-        RecursiveParserWrapper parser = new RecursiveParserWrapper(base,
-                new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.IGNORE, -1));
-        ContentHandler handler = new BodyContentHandler();
+        RecursiveParserWrapper parser = new RecursiveParserWrapper(base);
+        RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
+                new 
BasicContentHandlerFactory(BasicContentHandlerFactory.HANDLER_TYPE.IGNORE, 
-1),-1);
         Metadata rootMetadata = new Metadata();
         rootMetadata.add(Metadata.RESOURCE_NAME_KEY, 
"testRTFRegularImages.rtf");
         try (TikaInputStream tis = 
TikaInputStream.get(getResourceAsStream("/test-documents/testRTFRegularImages.rtf")))
 {
             parser.parse(tis, handler, rootMetadata, ctx);
         }
-        List<Metadata> metadatas = parser.getMetadata();
+        List<Metadata> metadatas = handler.getMetadataList();
 
         Metadata meta_jpg_exif = 
metadatas.get(1);//("testJPEG_EXIF_\u666E\u6797\u65AF\u987F.jpg");
         Metadata meta_jpg = 
metadatas.get(3);//("testJPEG_\u666E\u6797\u65AF\u987F.jpg");
diff --git 
a/tika-serialization/src/main/java/org/apache/tika/metadata/serialization/PrettyMetadataKeyComparator.java
 
b/tika-serialization/src/main/java/org/apache/tika/metadata/serialization/PrettyMetadataKeyComparator.java
index 9a18a8a..5516c1d 100644
--- 
a/tika-serialization/src/main/java/org/apache/tika/metadata/serialization/PrettyMetadataKeyComparator.java
+++ 
b/tika-serialization/src/main/java/org/apache/tika/metadata/serialization/PrettyMetadataKeyComparator.java
@@ -26,7 +26,7 @@ public class PrettyMetadataKeyComparator implements 
java.util.Comparator<String>
             return -1;
         }
 
-        //this is stinky.  This should reference 
RecursiveParserWrapper.TIKA_CONTENT
+        //this is stinky.  This should reference 
AbstractRecursiveParserWrapperHandler.TIKA_CONTENT
         //but that would require making core a dependency of serialization...
         //do we want to do that?
         if (s1.equals("tika:content")) {
diff --git 
a/tika-server/src/main/java/org/apache/tika/server/resource/RecursiveMetadataResource.java
 
b/tika-server/src/main/java/org/apache/tika/server/resource/RecursiveMetadataResource.java
index 739794c..0658fc4 100644
--- 
a/tika-server/src/main/java/org/apache/tika/server/resource/RecursiveMetadataResource.java
+++ 
b/tika-server/src/main/java/org/apache/tika/server/resource/RecursiveMetadataResource.java
@@ -37,6 +37,7 @@ import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.BasicContentHandlerFactory;
+import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.apache.tika.server.MetadataList;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -128,20 +129,28 @@ public class RecursiveMetadataResource {
                final ParseContext context = new ParseContext();
                Parser parser = TikaResource.createParser();
                // TODO: parameterize choice of max chars/max embedded 
attachments
-               BasicContentHandlerFactory.HANDLER_TYPE type =
-                BasicContentHandlerFactory.parseHandlerType(handlerTypeName, 
DEFAULT_HANDLER_TYPE);
-               RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parser,
-                               new BasicContentHandlerFactory(type, -1));
+               RecursiveParserWrapper wrapper = new 
RecursiveParserWrapper(parser);
+
+
                TikaResource.fillMetadata(parser, metadata, context, 
httpHeaders);
                // no need to add parser to parse recursively
                TikaResource.fillParseContext(context, httpHeaders, null);
                TikaResource.logRequest(LOG, info, metadata);
-               TikaResource.parse(wrapper, LOG, info.getPath(), is,
-                               new LanguageHandler() {
+
+        BasicContentHandlerFactory.HANDLER_TYPE type =
+                BasicContentHandlerFactory.parseHandlerType(handlerTypeName, 
DEFAULT_HANDLER_TYPE);
+               RecursiveParserWrapperHandler handler = new 
RecursiveParserWrapperHandler(
+                       new BasicContentHandlerFactory(type, -1), -1);
+               TikaResource.parse(wrapper, LOG, info.getPath(), is, handler, 
metadata, context);
+               /*
+                   We used to have this non-functional bit of code...refactor 
to add it back and make it work?
+                                               new LanguageHandler() {
                                        public void endDocument() {
                                                metadata.set("language", 
getLanguage().getLanguage());
                                        }
-                               }, metadata, context);
-               return new MetadataList(wrapper.getMetadata());
+                               },
+                */
+               return new MetadataList(handler.getMetadataList());
        }
+
 }
diff --git 
a/tika-server/src/test/java/org/apache/tika/server/RecursiveMetadataResourceTest.java
 
b/tika-server/src/test/java/org/apache/tika/server/RecursiveMetadataResourceTest.java
index 56910a9..0acd02b 100644
--- 
a/tika-server/src/test/java/org/apache/tika/server/RecursiveMetadataResourceTest.java
+++ 
b/tika-server/src/test/java/org/apache/tika/server/RecursiveMetadataResourceTest.java
@@ -38,6 +38,7 @@ import 
org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.serialization.JsonMetadataList;
 import org.apache.tika.parser.RecursiveParserWrapper;
+import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.server.resource.RecursiveMetadataResource;
 import org.apache.tika.server.writer.MetadataListMessageBodyWriter;
 import org.junit.Test;
@@ -128,7 +129,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         Reader reader = new InputStreamReader((InputStream) 
response.getEntity(), UTF_8);
         List<Metadata> metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        String content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        String content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //extra slash
@@ -140,7 +141,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //unparseable
@@ -152,7 +153,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //xml
@@ -164,7 +165,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //text
@@ -176,7 +177,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("embed_3"));
 
         //ignore
@@ -188,7 +189,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        
assertNull(metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT));
+        
assertNull(metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
 
     }
 
@@ -207,7 +208,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         Reader reader = new InputStreamReader((InputStream) 
response.getEntity(), UTF_8);
         List<Metadata> metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        String content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        String content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //unparseable
@@ -223,7 +224,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //xml
@@ -239,7 +240,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("<html 
xmlns=\"http://www.w3.org/1999/xhtml\";>"));
 
         //text
@@ -255,7 +256,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        content = 
metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT).trim();
+        content = 
metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT).trim();
         assertTrue(content.startsWith("embed_3"));
 
         //ignore -- no content
@@ -271,7 +272,7 @@ public class RecursiveMetadataResourceTest extends 
CXFTestBase {
         reader = new InputStreamReader((InputStream) response.getEntity(), 
UTF_8);
         metadataList = JsonMetadataList.fromJson(reader);
         assertEquals(12, metadataList.size());
-        
assertNull(metadataList.get(6).get(RecursiveParserWrapper.TIKA_CONTENT));
+        
assertNull(metadataList.get(6).get(AbstractRecursiveParserWrapperHandler.TIKA_CONTENT));
     }
 
 }

-- 
To stop receiving notification emails like this one, please contact
talli...@apache.org.

Reply via email to