Index: tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java
===================================================================
--- tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java	(revision 1212405)
+++ tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSLFPowerPointExtractorDecorator.java	(working copy)
@@ -16,10 +16,6 @@
  */
 package org.apache.tika.parser.microsoft.ooxml;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagePartName;
@@ -28,22 +24,30 @@
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.xslf.XSLFSlideShow;
 import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
-import org.apache.poi.xslf.usermodel.DrawingParagraph;
+import org.apache.poi.xslf.usermodel.Placeholder;
 import org.apache.poi.xslf.usermodel.XMLSlideShow;
-import org.apache.poi.xslf.usermodel.XSLFCommonSlideData;
+import org.apache.poi.xslf.usermodel.XSLFComments;
+import org.apache.poi.xslf.usermodel.XSLFGroupShape;
 import org.apache.poi.xslf.usermodel.XSLFRelation;
+import org.apache.poi.xslf.usermodel.XSLFShape;
+import org.apache.poi.xslf.usermodel.XSLFSheet;
 import org.apache.poi.xslf.usermodel.XSLFSlide;
-import org.apache.poi.xslf.usermodel.XSLFSlideMaster;
+import org.apache.poi.xslf.usermodel.XSLFTable;
+import org.apache.poi.xslf.usermodel.XSLFTableCell;
+import org.apache.poi.xslf.usermodel.XSLFTableRow;
+import org.apache.poi.xslf.usermodel.XSLFTextShape;
 import org.apache.tika.exception.TikaException;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.sax.XHTMLContentHandler;
 import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTComment;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTCommentList;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesSlide;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
 import org.xml.sax.SAXException;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
 public class XSLFPowerPointExtractorDecorator extends AbstractOOXMLExtractor {
 
     public XSLFPowerPointExtractorDecorator(ParseContext context, XSLFPowerPointExtractor extractor) {
@@ -54,110 +58,106 @@
      * @see org.apache.poi.xslf.extractor.XSLFPowerPointExtractor#getText()
      */
     @Override
-    protected void buildXHTML(XHTMLContentHandler xhtml) throws SAXException,
-            XmlException, IOException {
+    protected void buildXHTML(XHTMLContentHandler xhtml) throws SAXException, IOException {
         XMLSlideShow slideShow = (XMLSlideShow) extractor.getDocument();
-        XSLFSlideShow rawSlideShow = null;
-        try {
-           rawSlideShow = slideShow._getXSLFSlideShow(); // TODO Avoid this in future
-        } catch(Exception e) {
-           throw new IOException(e.getMessage()); // Shouldn't happen
-        }
 
         XSLFSlide[] slides = slideShow.getSlides();
         for (XSLFSlide slide : slides) {
-           // Find the ID, until we ditch the raw slideshow
-           CTSlideIdListEntry slideId = null;
-           for(CTSlideIdListEntry id : rawSlideShow.getSlideReferences().getSldIdList()) {
-              if(rawSlideShow.getSlidePart(id).getPartName().equals(slide.getPackagePart().getPartName())) {
-                 slideId = id;
-              }
-           }
-           if(slideId == null) {
-              // This shouldn't normally happen
-              continue;
-           }
-           
-            XSLFSlideMaster master = slide.getMasterSheet();
-            CTNotesSlide notes = rawSlideShow.getNotes(slideId);
-            CTCommentList comments = rawSlideShow.getSlideComments(slideId);
+            // slide
+            extractContent(slide.getShapes(), false, xhtml);
 
-            // TODO In POI 3.8 beta 5, improve how we get this
-            xhtml.startElement("div");
-            XSLFCommonSlideData common = new XSLFCommonSlideData(slide.getXmlObject().getCSld());
-            extractShapeContent(common, xhtml);
+            // slide layout which is the master sheet for this slide
+            XSLFSheet slideLayout = slide.getMasterSheet();
+            extractContent(slideLayout.getShapes(), true, xhtml);
 
-            // If there are comments, extract them
+            // slide master which is the master sheet for all text layouts
+            XSLFSheet slideMaster = slideLayout.getMasterSheet();
+            extractContent(slideMaster.getShapes(), true, xhtml);
+
+            // notes (if present)
+            XSLFSheet slideNotes = slide.getNotes();
+            if (slideNotes != null) {
+                extractContent(slideNotes.getShapes(), false, xhtml);
+
+                // master sheet for this notes
+                XSLFSheet notesMaster = slideNotes.getMasterSheet();
+                extractContent(notesMaster.getShapes(), true, xhtml);
+            }
+
+            // comments (if present)
+            XSLFComments comments = slide.getComments();
             if (comments != null) {
-                for (CTComment comment : comments.getCmArray()) {
+                for (CTComment comment : comments.getCTCommentsList().getCmList()) {
                     xhtml.element("p", comment.getText());
                 }
             }
-            
-            // Get text from the master slide
-            // TODO: re-enable this once we fix TIKA-712
-            /*
-            if(master != null) {
-               // TODO In POI 3.8 beta 5, improve how we get this
-               extractShapeContent(new XSLFCommonSlideData(master.getXmlObject().getCSld()), xhtml);
-            }
-            */
-
-            if (notes != null) {
-               // TODO In POI 3.8 beta 5, improve how we get this
-                extractShapeContent(new XSLFCommonSlideData(notes.getCSld()), xhtml);
-            }
-            xhtml.endElement("div");
         }
     }
 
-    private void extractShapeContent(XSLFCommonSlideData data, XHTMLContentHandler xhtml)
+    private void extractContent(XSLFShape[] shapes, boolean skipPlaceholders, XHTMLContentHandler xhtml)
             throws SAXException {
-        for (DrawingParagraph p : data.getText()) {
-            xhtml.element("p", p.getText().toString());
+        for (XSLFShape sh : shapes) {
+            if (sh instanceof XSLFTextShape) {
+                XSLFTextShape txt = (XSLFTextShape) sh;
+                Placeholder ph = txt.getTextType();
+                if (skipPlaceholders && ph != null) {
+                    continue;
+                }
+                xhtml.element("p", txt.getText());
+            } else if (sh instanceof XSLFGroupShape){
+                // recurse into groups of shapes
+                XSLFGroupShape group = (XSLFGroupShape)sh;
+                extractContent(group.getShapes(), skipPlaceholders, xhtml);
+            } else if (sh instanceof XSLFTable){
+                XSLFTable tbl = (XSLFTable)sh;
+                for(XSLFTableRow row : tbl){
+                    List<XSLFTableCell> cells = row.getCells();
+                    extractContent(cells.toArray(new XSLFTableCell[cells.size()]), skipPlaceholders, xhtml);
+                }
+            }
         }
     }
-    
+
     /**
      * In PowerPoint files, slides have things embedded in them,
-     *  and slide drawings which have the images
+     * and slide drawings which have the images
      */
     @Override
     protected List<PackagePart> getMainDocumentParts() throws TikaException {
-       List<PackagePart> parts = new ArrayList<PackagePart>();
-       XMLSlideShow slideShow = (XMLSlideShow) extractor.getDocument();
-       XSLFSlideShow document = null;
-       try {
-          document = slideShow._getXSLFSlideShow(); // TODO Avoid this in future
-       } catch(Exception e) {
-          throw new TikaException(e.getMessage()); // Shouldn't happen
-       }
-       
-       for (CTSlideIdListEntry ctSlide : document.getSlideReferences().getSldIdList()) {
-          // Add the slide
-          PackagePart slidePart;
-          try {
-             slidePart = document.getSlidePart(ctSlide);
-          } catch(IOException e) {
-             throw new TikaException("Broken OOXML file", e);
-          } catch(XmlException xe) {
-             throw new TikaException("Broken OOXML file", xe);
-          }
-          parts.add(slidePart);
-          
-          // If it has drawings, return those too
-          try {
-             for(PackageRelationship rel : slidePart.getRelationshipsByType(XSLFRelation.VML_DRAWING.getRelation())) {
-                if(rel.getTargetMode() == TargetMode.INTERNAL) {
-                   PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
-                   parts.add( rel.getPackage().getPart(relName) );
+        List<PackagePart> parts = new ArrayList<PackagePart>();
+        XMLSlideShow slideShow = (XMLSlideShow) extractor.getDocument();
+        XSLFSlideShow document = null;
+        try {
+            document = slideShow._getXSLFSlideShow(); // TODO Avoid this in future
+        } catch (Exception e) {
+            throw new TikaException(e.getMessage()); // Shouldn't happen
+        }
+
+        for (CTSlideIdListEntry ctSlide : document.getSlideReferences().getSldIdList()) {
+            // Add the slide
+            PackagePart slidePart;
+            try {
+                slidePart = document.getSlidePart(ctSlide);
+            } catch (IOException e) {
+                throw new TikaException("Broken OOXML file", e);
+            } catch (XmlException xe) {
+                throw new TikaException("Broken OOXML file", xe);
+            }
+            parts.add(slidePart);
+
+            // If it has drawings, return those too
+            try {
+                for (PackageRelationship rel : slidePart.getRelationshipsByType(XSLFRelation.VML_DRAWING.getRelation())) {
+                    if (rel.getTargetMode() == TargetMode.INTERNAL) {
+                        PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
+                        parts.add(rel.getPackage().getPart(relName));
+                    }
                 }
-             }
-          } catch(InvalidFormatException e) {
-             throw new TikaException("Broken OOXML file", e);
-          }
-       }
+            } catch (InvalidFormatException e) {
+                throw new TikaException("Broken OOXML file", e);
+            }
+        }
 
-       return parts;
+        return parts;
     }
 }
