Index: src/main/java/org/apache/tika/parser/microsoft/ExcelParser.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/ExcelParser.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/ExcelParser.java	(working copy)
@@ -33,31 +33,29 @@
         return "application/vnd.ms-excel";
     }
 
-    protected String extractText(POIFSFileSystem filesystem) throws IOException{
-        StringBuilder builder = new StringBuilder();
+    protected void extractText(POIFSFileSystem filesystem, Appendable builder) throws IOException{
         extractText(new HSSFWorkbook(filesystem), builder);
-        return builder.toString();
     }
 
-    private void extractText(HSSFWorkbook book, StringBuilder builder) {
+    private void extractText(HSSFWorkbook book, Appendable builder) throws IOException {
         for (int i = 0; book != null && i < book.getNumberOfSheets(); i++) {
             extractText(book.getSheetAt(i), builder);
         }
     }
 
-    private void extractText(HSSFSheet sheet, StringBuilder builder) {
+    private void extractText(HSSFSheet sheet, Appendable builder) throws IOException {
         for (int i = 0; sheet != null && i <= sheet.getLastRowNum(); i++) {
             extractText(sheet.getRow(i), builder);
         }
     }
 
-    private void extractText(HSSFRow row, StringBuilder builder) {
+    private void extractText(HSSFRow row, Appendable builder) throws IOException {
         for (short i = 0; row != null && i < row.getLastCellNum(); i++) {
             extractText(row.getCell(i), builder);
         }
     }
 
-    private void extractText(HSSFCell cell, StringBuilder builder) {
+    private void extractText(HSSFCell cell, Appendable builder) throws IOException {
         if (cell != null) {
             switch (cell.getCellType()) {
             case HSSFCell.CELL_TYPE_STRING:
@@ -73,14 +71,11 @@
         }
     }
 
-    private void addText(String text, StringBuilder builder) {
+    private void addText(String text, Appendable builder) throws IOException {
         if (text != null) {
             text = text.trim();
             if (text.length() > 0) {
-                if (builder.length() > 0) {
-                    builder.append(' ');
-                }
-                builder.append(text);
+                builder.append(text).append(' ');
             }
         }
     }
Index: src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/OfficeParser.java	(working copy)
@@ -56,7 +56,9 @@
         XHTMLContentHandler xhtml =
             new XHTMLContentHandler(handler, metadata);
         xhtml.startDocument();
-        xhtml.element("p", extractText(filesystem));
+        xhtml.startElement("p");
+        extractText(filesystem, xhtml);
+        xhtml.endElement("p");
         xhtml.endDocument();
     }
 
@@ -70,7 +72,7 @@
     /**
      * Extracts the text content from a Microsoft document input stream.
      */
-    protected abstract String extractText(POIFSFileSystem filesystem)
+    protected abstract void extractText(POIFSFileSystem filesystem, Appendable appendable)
         throws IOException, TikaException;
 
     private void getMetadata(
@@ -177,4 +179,4 @@
         }
     }
 
-}
\ No newline at end of file
+}
Index: src/main/java/org/apache/tika/parser/microsoft/PowerPointExtractor.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/PowerPointExtractor.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/PowerPointExtractor.java	(working copy)
@@ -32,12 +32,12 @@
     static Logger LOG = Logger.getRootLogger();
 
     /** Buffer holding the content of the file */
-    private final StringBuilder builder;
+    private final Appendable builder;
 
     /**
      * Constructs Listener to get content of PowerPoint file.
      */
-    public PowerPointExtractor(StringBuilder builder) {
+    public PowerPointExtractor(Appendable builder) {
         this.builder = builder;
     }
 
Index: src/main/java/org/apache/tika/parser/microsoft/PowerPointParser.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/PowerPointParser.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/PowerPointParser.java	(working copy)
@@ -35,8 +35,7 @@
         return "application/vnd.ms-powerpoint";
     }
 
-    protected String extractText(POIFSFileSystem filesystem) throws IOException {
-        StringBuilder builder = new StringBuilder();
+    protected void extractText(POIFSFileSystem filesystem, Appendable builder) throws IOException {
 
         InputStream stream = filesystem.createDocumentInputStream(POWERPOINT);
         try {
@@ -44,8 +43,6 @@
         } finally {
             stream.close();
         }
-
-        return builder.toString();
     }
 
 }
Index: src/main/java/org/apache/tika/parser/microsoft/Word6Extractor.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/Word6Extractor.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/Word6Extractor.java	(working copy)
@@ -33,8 +33,11 @@
 class Word6Extractor
 {
 
-  public Word6Extractor()
+    private final Appendable appendable;
+
+  public Word6Extractor(Appendable appendable)
   {
+      this.appendable = appendable;
   }
 
   /**
@@ -45,7 +48,7 @@
    * @return The text from the document
    * @throws Exception If there are any unexpected exceptions.
    */
-  public String extractText(byte[] mainStream) throws IOException {
+  public void extractText(byte[] mainStream) throws IOException {
     int fcMin = LittleEndian.getInt(mainStream, 0x18);
     int fcMax = LittleEndian.getInt(mainStream, 0x1C);
 
@@ -58,7 +61,7 @@
     List textRuns = chpTable.getTextRuns();
 
     // iterate through the
-    WordTextBuffer finalTextBuf = new WordTextBuffer();
+    WordTextBuffer finalTextBuf = new WordTextBuffer(appendable);
     Iterator runsIt = textRuns.iterator();
     while(runsIt.hasNext())
     {
@@ -76,8 +79,6 @@
         }
       }
     }
-
-    return finalTextBuf.toString();
   }
 
   /**
Index: src/main/java/org/apache/tika/parser/microsoft/WordParser.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/WordParser.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/WordParser.java	(working copy)
@@ -47,7 +47,7 @@
      *
      * @param in The InputStream representing the Word file.
      */
-    public String extractText(POIFSFileSystem fsys)
+    public void extractText(POIFSFileSystem fsys, Appendable appendable)
             throws IOException, TikaException {
         // load our POIFS document streams.
         DocumentEntry headerProps =
@@ -74,8 +74,8 @@
         case 103:
         case 104:
             // this is a Word 6.0 doc send it to the extractor for that version.
-            Word6Extractor oldExtractor = new Word6Extractor();
-            return oldExtractor.extractText(header);
+            Word6Extractor oldExtractor = new Word6Extractor(appendable);
+            oldExtractor.extractText(header);
         }
 
         //get the location of the piece table
@@ -123,7 +123,7 @@
         int currentTextStart = currentPiece.getStart();
         int currentTextEnd = currentPiece.getEnd();
 
-        WordTextBuffer finalTextBuf = new WordTextBuffer();
+        WordTextBuffer finalTextBuf = new WordTextBuffer(appendable);
 
         // iterate through all text runs extract the text only if they haven't been
         // deleted
@@ -157,7 +157,7 @@
                         runStart = currentTextStart;
                         currentTextEnd = currentPiece.getEnd ();
                     } else {
-                        return finalTextBuf.toString();
+                        return;
                     }
                 }
                 String str = currentPiece.substring(0, runEnd - currentTextStart);
@@ -172,7 +172,6 @@
                 finalTextBuf.append(str);
             }
         }
-        return finalTextBuf.toString();
     }
 
     /**
Index: src/main/java/org/apache/tika/parser/microsoft/WordTextBuffer.java
===================================================================
--- src/main/java/org/apache/tika/parser/microsoft/WordTextBuffer.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/microsoft/WordTextBuffer.java	(working copy)
@@ -22,16 +22,16 @@
  */
 public class WordTextBuffer
 {
-  StringBuffer _buf;
+  Appendable _buf;
   boolean _hold;
 
-  public WordTextBuffer()
+  public WordTextBuffer(Appendable appendable)
   {
-    _buf = new StringBuffer();
+    _buf = appendable;
     _hold = false;
   }
 
-  public void append(String text)
+  public void append(String text) throws java.io.IOException
   {
     char[] letters = text.toCharArray();
     for (int x = 0; x < letters.length; x++)
@@ -57,9 +57,4 @@
     }
   }
 
-  public String toString()
-  {
-    return _buf.toString();
-  }
-
 }
Index: src/main/java/org/apache/tika/parser/opendocument/OpenOfficeParser.java
===================================================================
--- src/main/java/org/apache/tika/parser/opendocument/OpenOfficeParser.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/opendocument/OpenOfficeParser.java	(working copy)
@@ -101,7 +101,9 @@
 
         XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
         xhtml.startDocument();
-        xhtml.element("p", xp.concatOccurrence(xmlDoc, "//*", " "));
+        xhtml.startElement("p");
+        xp.concatOccurrence(xmlDoc, "//*", " ", xhtml);
+        xhtml.endElement("p");
         xhtml.endDocument();
     }
 
Index: src/main/java/org/apache/tika/parser/xml/XMLParser.java
===================================================================
--- src/main/java/org/apache/tika/parser/xml/XMLParser.java	(revision 596536)
+++ src/main/java/org/apache/tika/parser/xml/XMLParser.java	(working copy)
@@ -70,13 +70,14 @@
 
         XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
         xhtml.startDocument();
-        xhtml.element("p", concatOccurrence(xmlDoc, "//*", " "));
+        xhtml.startElement("p");
+        concatOccurrence(xmlDoc, "//*", " ", xhtml);
+        xhtml.endElement("p");
         xhtml.endDocument();
     }
 
-    public String concatOccurrence(Object xmlDoc, String xpath, String concatSep) {
+    public void concatOccurrence(Object xmlDoc, String xpath, String concatSep, Appendable chaineConcat) throws IOException {
 
-        StringBuilder chaineConcat = new StringBuilder();
         try {
             JDOMXPath xp = new JDOMXPath(xpath);
             List ls = xp.selectNodes(xmlDoc);
@@ -108,7 +109,7 @@
                 if (StringUtils.isNotEmpty(text)) {
                     chaineConcat.append(text);
                     if (ls.size() == 1) {
-                        return chaineConcat.toString().trim();
+                        return;
                     } else {
                         if (ls.size() != j) {
                             chaineConcat.append(' ')
@@ -121,7 +122,6 @@
         } catch (JaxenException j) {
             logger.error(j.getMessage());
         }
-        return chaineConcat.toString().trim();
     }
 
     public List getAllDocumentNs(org.jdom.Document doc) {
Index: src/main/java/org/apache/tika/sax/ContentHandlerDecorator.java
===================================================================
--- src/main/java/org/apache/tika/sax/ContentHandlerDecorator.java	(revision 596536)
+++ src/main/java/org/apache/tika/sax/ContentHandlerDecorator.java	(working copy)
@@ -16,6 +16,8 @@
  */
 package org.apache.tika.sax;
 
+import java.io.IOException;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.Locator;
@@ -27,7 +29,7 @@
  * instance. Subclasses can provide extra decoration by overriding one or more
  * of the SAX event methods.
  */
-public class ContentHandlerDecorator implements ContentHandler {
+public class ContentHandlerDecorator implements ContentHandler, Appendable {
 
     /**
      * Decorated SAX event handler.
@@ -35,12 +37,18 @@
     private final ContentHandler handler;
 
     /**
+     * Decorated SAX event handler.
+     */
+    private final Appendable appendable;
+
+    /**
      * Creates a decorator for the given SAX event handler.
      *
      * @param handler SAX event handler to be decorated
      */
     public ContentHandlerDecorator(ContentHandler handler) {
         this.handler = handler;
+        this.appendable = (handler instanceof Appendable ? (Appendable)handler : null);
     }
 
     public void startPrefixMapping(String prefix, String uri)
@@ -93,4 +101,36 @@
         handler.skippedEntity(name);
     }
 
+    public Appendable append(char c) throws IOException {
+        if (appendable != null) {
+            appendable.append(c);
+        } else {
+            append(Character.toString(c));
+        }
+        return this;
+    }
+
+    public Appendable append(CharSequence charSequence, int start, int end) throws IOException {
+        if (charSequence != null) {
+            if (appendable != null) {
+                appendable.append(charSequence, start, end);
+            } else {
+                char[] chars = charSequence.toString().toCharArray();
+                try {
+                    handler.characters(chars, start, (end - start));
+                } catch (SAXException e) {
+                    throw new IOException(e.toString());
+                }
+            }
+        }
+        return this;
+    }
+
+    public Appendable append(CharSequence charSequence) throws IOException {
+        if (charSequence != null) {
+            append(charSequence, 0, charSequence.length());
+        }
+        return this;
+    }
+    
 }
Index: src/main/java/org/apache/tika/sax/WriteOutContentHandler.java
===================================================================
--- src/main/java/org/apache/tika/sax/WriteOutContentHandler.java	(revision 596536)
+++ src/main/java/org/apache/tika/sax/WriteOutContentHandler.java	(working copy)
@@ -26,7 +26,7 @@
  * SAX event handler that writes all character content out to
  * a {@link Writer} character stream.
  */
-public class WriteOutContentHandler extends DefaultHandler {
+public class WriteOutContentHandler extends DefaultHandler implements Appendable {
 
     /**
      * The character stream.
@@ -45,5 +45,19 @@
             throw new SAXException("Error writing out character content", e);
         }
     }
+    public Appendable append(char c) throws IOException {
+        writer.append(c);
+        return this;
+    }
 
+    public Appendable append(CharSequence charSequence, int start, int end) throws IOException {
+        writer.append(charSequence, start, end);
+        return this;
+    }
+
+    public Appendable append(CharSequence charSequence) throws IOException {
+        writer.append(charSequence);
+        return this;
+    }
+
 }
