*/
    public synchronized PageText getText() {

        // we only do this once per page
        if (isInited) {
            if (shapes != null && shapes.getPageText() != null) {
                return shapes.getPageText();
            }
        }

        Shapes textBlockShapes = null;
        try {
            /**
             * Finally iterate through the contents vector and concat all of the
             * the resouse streams together so that the contant parser can
             * go to town and build all of the pages shapes.
             */
            if (contents == null) {
                // Get the value of the page's content entry
                initPageContents();
            }

            if (resources == null) {
                // get pages resources
                initPageResources();
            }

            if (contents != null) {
                Vector<InputStream> inputStreamsVec =
                        new Vector<InputStream>(contents.size());
                for (int st = 0, max = contents.size(); st < max; st++) {
                    Stream stream = contents.elementAt(st);
                    InputStream input = stream.getInputStreamForDecodedStreamBytes();
                    inputStreamsVec.add(input);
                }
                SequenceInputStream sis = new SequenceInputStream(inputStreamsVec.iterator());

                // push the library and resources to the content parse
                // and return the the shapes vector for the screen elements
                // for the page/resources in question.
                try {
                    ContentParser cp = new ContentParser(library, resources);
                    // custom parsing for text extraction, should be faster
                    textBlockShapes = cp.parseTextBlocks(sis);
                } catch (Exception e) {
                    logger.log(Level.FINE, "Error getting page text.", e);
                } finally {
                    try {
                        sis.close();
                    } catch (IOException e) {
                        logger.log(Level.FINE, "Error closing page stream.", e);
                    }
                }
            }
        } catch (InterruptedException e) {
            // keeps shapes vector so we can paint what we have but make init state as false
            // so we can try to reparse it later.
            isInited = false;
            logger.log(Level.SEVERE, "Page text extraction thread interrupted.", e);
        }
        if (textBlockShapes != null && textBlockShapes.getPageText() != null) {
            return textBlockShapes.getPageText();
        } else {
            return null;
        }
    }