dr78: rework of stream handling, improve handling of very large streams (prevent loading entire stream into array or string, esp. dumper and VML import), full support of XComponentContext
diff --git a/oox/inc/oox/core/contexthandler.hxx b/oox/inc/oox/core/contexthandler.hxx
index b1f24d0..0242ee0 100644
--- a/oox/inc/oox/core/contexthandler.hxx
+++ b/oox/inc/oox/core/contexthandler.hxx
@@ -57,9 +57,9 @@ typedef ::rtl::Reference< ContextHandler > ContextHandlerRef;
struct FragmentBaseData;
typedef ::boost::shared_ptr< FragmentBaseData > FragmentBaseDataRef;

typedef ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastContextHandler > ContextHandlerImplBase;
typedef ::cppu::WeakImplHelper1< ::com::sun::star::xml::sax::XFastContextHandler > ContextHandler_BASE;

class ContextHandler : public ContextHandlerImplBase
class ContextHandler : public ContextHandler_BASE
{
public:
    explicit            ContextHandler( ContextHandler& rParent );
diff --git a/oox/inc/oox/core/fasttokenhandler.hxx b/oox/inc/oox/core/fasttokenhandler.hxx
index a6c73de..c85bfda 100644
--- a/oox/inc/oox/core/fasttokenhandler.hxx
+++ b/oox/inc/oox/core/fasttokenhandler.hxx
@@ -39,12 +39,12 @@ namespace core {

// ============================================================================

typedef ::cppu::WeakImplHelper2< ::com::sun::star::lang::XServiceInfo, ::com::sun::star::xml::sax::XFastTokenHandler > FastTokenHandlerBase;
typedef ::cppu::WeakImplHelper2< ::com::sun::star::lang::XServiceInfo, ::com::sun::star::xml::sax::XFastTokenHandler > FastTokenHandler_BASE;

/** Wrapper implementing the com.sun.star.xml.sax.XFastTokenHandler API interface
    that provides access to the tokens generated from the internal token name list.
 */
class FastTokenHandler : public FastTokenHandlerBase
class FastTokenHandler : public FastTokenHandler_BASE
{
public:
    explicit            FastTokenHandler();
diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx
index 80dc233..839eec1 100644
--- a/oox/inc/oox/core/filterbase.hxx
+++ b/oox/inc/oox/core/filterbase.hxx
@@ -87,9 +87,9 @@ typedef ::cppu::WeakImplHelper5<
        ::com::sun::star::document::XImporter,
        ::com::sun::star::document::XExporter,
        ::com::sun::star::document::XFilter >
    FilterBaseBase;
    FilterBase_BASE;

class OOX_DLLPUBLIC FilterBase : public FilterBaseBase, public ::cppu::BaseMutex
class OOX_DLLPUBLIC FilterBase : public FilterBase_BASE, public ::cppu::BaseMutex
{
public:
    explicit            FilterBase(
diff --git a/oox/inc/oox/core/fragmenthandler.hxx b/oox/inc/oox/core/fragmenthandler.hxx
index ba3164a..f9c32a8 100644
--- a/oox/inc/oox/core/fragmenthandler.hxx
+++ b/oox/inc/oox/core/fragmenthandler.hxx
@@ -81,9 +81,9 @@ struct RecordInfo

// ============================================================================

typedef ::cppu::ImplInheritanceHelper1< ContextHandler, ::com::sun::star::xml::sax::XFastDocumentHandler > FragmentHandlerImplBase;
typedef ::cppu::ImplInheritanceHelper1< ContextHandler, ::com::sun::star::xml::sax::XFastDocumentHandler > FragmentHandler_BASE;

class FragmentHandler : public FragmentHandlerImplBase
class FragmentHandler : public FragmentHandler_BASE
{
public:
    explicit            FragmentHandler( XmlFilterBase& rFilter, const ::rtl::OUString& rFragmentPath );
diff --git a/oox/inc/oox/drawingml/chart/converterbase.hxx b/oox/inc/oox/drawingml/chart/converterbase.hxx
index aec646d..95affa5 100644
--- a/oox/inc/oox/drawingml/chart/converterbase.hxx
+++ b/oox/inc/oox/drawingml/chart/converterbase.hxx
@@ -34,7 +34,6 @@
namespace com { namespace sun { namespace star {
    namespace awt { struct Rectangle; }
    namespace awt { struct Size; }
    namespace lang { class XMultiServiceFactory; }
    namespace chart2 { class XChartDocument; }
    namespace chart2 { class XTitle; }
    namespace drawing { class XShape; }
diff --git a/oox/inc/oox/dump/biffdumper.hxx b/oox/inc/oox/dump/biffdumper.hxx
index a3bdc4a..8e90e36 100644
--- a/oox/inc/oox/dump/biffdumper.hxx
+++ b/oox/inc/oox/dump/biffdumper.hxx
@@ -530,7 +530,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -554,7 +554,7 @@ public:
    explicit            Dumper( const ::oox::core::FilterBase& rFilter );

    explicit            Dumper(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            const ::rtl::OUString& rSysFileName );

@@ -571,4 +571,3 @@ protected:

#endif
#endif

diff --git a/oox/inc/oox/dump/dffdumper.hxx b/oox/inc/oox/dump/dffdumper.hxx
index f229c19..93868b2 100644
--- a/oox/inc/oox/dump/dffdumper.hxx
+++ b/oox/inc/oox/dump/dffdumper.hxx
@@ -79,4 +79,3 @@ private:

#endif
#endif

diff --git a/oox/inc/oox/dump/dumperbase.hxx b/oox/inc/oox/dump/dumperbase.hxx
index d9acaa1..4b10a1b 100644
--- a/oox/inc/oox/dump/dumperbase.hxx
+++ b/oox/inc/oox/dump/dumperbase.hxx
@@ -49,10 +49,9 @@

namespace com { namespace sun { namespace star {
    namespace io { class XInputStream; }
    namespace io { class XTextInputStream; }
    namespace io { class XOutputStream; }
    namespace io { class XTextOutputStream; }
    namespace lang { class XMultiServiceFactory; }
    namespace uno { class XComponentContext; }
} } }

namespace comphelper {
@@ -124,43 +123,46 @@ public:
    // input streams ----------------------------------------------------------

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
                        getXInputStream( BinaryInputStream& rStrm );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
                        openInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::rtl::OUString& rFileName );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
                        openTextInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            const ::rtl::OUString& rEncoding );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
                        openTextInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::rtl::OUString& rFileName,
                            const ::rtl::OUString& rEncoding );

    // output streams ---------------------------------------------------------

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
                        openOutputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::rtl::OUString& rFileName );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >
                        openTextOutputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rxOutStrm,
                            const ::rtl::OUString& rEncoding );
                            rtl_TextEncoding eTextEnc );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >
                        openTextOutputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::rtl::OUString& rFileName,
                            const ::rtl::OUString& rEncoding );
                            rtl_TextEncoding eTextEnc );
};

// ============================================================================

class BinaryInputStreamRef : public ::oox::BinaryInputStreamRef
{
public:
    inline              BinaryInputStreamRef() {}

    inline /*implicit*/ BinaryInputStreamRef( BinaryInputStream* pInStrm ) :
                            ::oox::BinaryInputStreamRef( pInStrm ) {}

    inline /*implicit*/ BinaryInputStreamRef( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm ) :
                            ::oox::BinaryInputStreamRef( new BinaryXInputStream( rxInStrm, true ) ) {}

    template< typename StreamType >
    inline /*implicit*/ BinaryInputStreamRef( const ::boost::shared_ptr< StreamType >& rxInStrm ) :
                            ::oox::BinaryInputStreamRef( rxInStrm ) {}
};

// ============================================================================
@@ -550,7 +552,9 @@ typedef ::boost::shared_ptr< Base > BaseRef;
            |               |
            |               +---->  BinaryStreamObject
            |               |
            |               +---->  TextStreamObject
            |               +---->  TextStreamObjectBase
            |               |       |
            |               |       +---->  TextStreamObject
            |               |       |
            |               |       +---->  XmlStreamObject
            |               |
@@ -890,14 +894,14 @@ class SharedConfigData : public Base, public ConfigItemBase
public:
    explicit            SharedConfigData(
                            const ::rtl::OUString& rFileName,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const StorageRef& rxRootStrg,
                            const ::rtl::OUString& rSysFileName,
                            ::comphelper::MediaDescriptor& rMediaDesc );

    virtual             ~SharedConfigData();

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getFactory() const { return mxFactory; }
    inline const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& getContext() const { return mxContext; }
    inline const StorageRef& getRootStorage() const { return mxRootStrg; }
    inline const ::rtl::OUString& getSysFileName() const { return maSysFileName; }

@@ -932,7 +936,7 @@ private:
    typedef ::std::map< ::rtl::OUString, ::rtl::OUString >  ConfigDataMap;
    typedef ::std::map< ::rtl::OUString, NameListRef >      NameListMap;

    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxFactory;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext;
    StorageRef          mxRootStrg;
    ::rtl::OUString     maSysFileName;
    ::comphelper::MediaDescriptor& mrMediaDesc;
@@ -977,14 +981,14 @@ public:
                            const ::oox::core::FilterBase& rFilter );
    explicit            Config(
                            const sal_Char* pcEnvVar,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const StorageRef& rxRootStrg,
                            const ::rtl::OUString& rSysFileName,
                            ::comphelper::MediaDescriptor& rMediaDesc );

    virtual             ~Config();

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& getFactory() const { return mxCfgData->getFactory(); }
    inline const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& getContext() const { return mxCfgData->getContext(); }
    inline const StorageRef& getRootStorage() const { return mxCfgData->getRootStorage(); }
    inline const ::rtl::OUString& getSysFileName() const { return mxCfgData->getSysFileName(); }

@@ -1022,7 +1026,7 @@ protected:
                            const ::oox::core::FilterBase& rFilter );
    void                construct(
                            const sal_Char* pcEnvVar,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const StorageRef& rxRootStrg,
                            const ::rtl::OUString& rSysFileName,
                            ::comphelper::MediaDescriptor& rMediaDesc );
@@ -1076,10 +1080,7 @@ class Output : public Base
{
public:
    explicit            Output(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >& rxStrm );

    explicit            Output(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::rtl::OUString& rFileName );

    // ------------------------------------------------------------------------
@@ -1152,8 +1153,6 @@ public:

    // ------------------------------------------------------------------------
protected:
    void                construct( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextOutputStream >& rxStrm );

    virtual bool        implIsValid() const;

private:
@@ -1279,8 +1278,8 @@ class ObjectBase : public Base
public:
    virtual             ~ObjectBase();

    inline const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
                        getFactory() const { return mxConfig->getFactory(); }
    inline const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&
                        getContext() const { return mxConfig->getContext(); }

    void                dump();

@@ -1323,7 +1322,7 @@ protected:
    virtual void        implDump();

    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -1394,7 +1393,6 @@ protected:

    using               ObjectBase::construct;
    void                construct( const ObjectBase& rParent, const ::rtl::OUString& rSysFileName );
    void                construct( const ObjectBase& rParent, const OutputRef& rxOut );
    void                construct( const OutputObjectBase& rParent );

    virtual bool        implIsValid() const;
@@ -1453,6 +1451,7 @@ protected:

protected:
    OutputRef           mxOut;
    ::rtl::OUString     maSysFileName;
};

typedef ::boost::shared_ptr< OutputObjectBase > OutputObjectRef;
@@ -1578,7 +1577,6 @@ protected:

    using               OutputObjectBase::construct;
    void                construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const ::rtl::OUString& rSysFileName );
    void                construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OutputRef& rxOut );
    void                construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm );
    void                construct( const InputObjectBase& rParent );

@@ -1805,33 +1803,63 @@ protected:
};

// ============================================================================
// ============================================================================

class TextStreamObject : public InputObjectBase
class TextStreamObjectBase : public InputObjectBase
{
public:
    explicit            TextStreamObject(
protected:
    inline              TextStreamObjectBase() {}

    using               InputObjectBase::construct;
    void                construct(
                            const ObjectBase& rParent,
                            const BinaryInputStreamRef& rxStrm,
                            rtl_TextEncoding eTextEnc,
                            const ::rtl::OUString& rSysFileName );

    explicit            TextStreamObject(
    void                construct(
                            const OutputObjectBase& rParent,
                            const BinaryInputStreamRef& rxStrm,
                            rtl_TextEncoding eTextEnc );
    void                construct(
                            const InputObjectBase& rParent,
                            rtl_TextEncoding eTextEnc );

protected:
    virtual bool        implIsValid() const;
    virtual void        implDump();
    virtual void        implDumpLine( const ::rtl::OUString& rLine, sal_uInt32 nLine );

    virtual void        implDumpText( TextInputStream& rTextStrm ) = 0;

private:
    void                constructTextStrmObj( rtl_TextEncoding eTextEnc );

protected:
    ::boost::shared_ptr< TextInputStream > mxTextStrm;
};

// ============================================================================

class XmlStreamObject : public TextStreamObject
class TextLineStreamObject : public TextStreamObjectBase
{
public:
    explicit            TextLineStreamObject(
                            const ObjectBase& rParent,
                            const BinaryInputStreamRef& rxStrm,
                            rtl_TextEncoding eTextEnc,
                            const ::rtl::OUString& rSysFileName );

    explicit            TextLineStreamObject(
                            const OutputObjectBase& rParent,
                            const BinaryInputStreamRef& rxStrm,
                            rtl_TextEncoding eTextEnc );

protected:
    virtual void        implDumpText( TextInputStream& rTextStrm );
    virtual void        implDumpLine( const ::rtl::OUString& rLine, sal_uInt32 nLine );
};

// ============================================================================

class XmlStreamObject : public TextStreamObjectBase
{
public:
    explicit            XmlStreamObject(
@@ -1839,12 +1867,12 @@ public:
                            const BinaryInputStreamRef& rxStrm,
                            const ::rtl::OUString& rSysFileName );

protected:
    virtual void        implDump();
    virtual void        implDumpLine( const ::rtl::OUString& rLine, sal_uInt32 nLine );
    explicit            XmlStreamObject(
                            const OutputObjectBase& rParent,
                            const BinaryInputStreamRef& rxStrm );

private:
    ::rtl::OUString     maIncompleteLine;
protected:
    virtual void        implDumpText( TextInputStream& rTextStrm );
};

// ============================================================================
@@ -1976,4 +2004,3 @@ do {                                                \

#endif  // OOX_INCLUDE_DUMPER
#endif

diff --git a/oox/inc/oox/dump/oledumper.hxx b/oox/inc/oox/dump/oledumper.hxx
index 8f706f4..ac59f0e 100644
--- a/oox/inc/oox/dump/oledumper.hxx
+++ b/oox/inc/oox/dump/oledumper.hxx
@@ -180,7 +180,7 @@ protected:
    void                construct( const ObjectBase& rParent );

    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -762,7 +762,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -857,7 +857,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -879,7 +879,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -897,7 +897,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -936,4 +936,3 @@ protected:

#endif
#endif

diff --git a/oox/inc/oox/dump/pptxdumper.hxx b/oox/inc/oox/dump/pptxdumper.hxx
index 535c7cea..acfa082 100644
--- a/oox/inc/oox/dump/pptxdumper.hxx
+++ b/oox/inc/oox/dump/pptxdumper.hxx
@@ -45,7 +45,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -59,7 +59,7 @@ public:
    explicit            Dumper( const ::oox::core::FilterBase& rFilter );

    explicit            Dumper(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            const ::rtl::OUString& rSysFileName );

@@ -75,4 +75,3 @@ protected:

#endif
#endif

diff --git a/oox/inc/oox/dump/xlsbdumper.hxx b/oox/inc/oox/dump/xlsbdumper.hxx
index 6fa1c9b..606af8c 100644
--- a/oox/inc/oox/dump/xlsbdumper.hxx
+++ b/oox/inc/oox/dump/xlsbdumper.hxx
@@ -225,7 +225,7 @@ public:

protected:
    virtual void        implDumpStream(
                            const BinaryInputStreamRef& rxStrm,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxStrm,
                            const ::rtl::OUString& rStrgPath,
                            const ::rtl::OUString& rStrmName,
                            const ::rtl::OUString& rSysFileName );
@@ -239,7 +239,7 @@ public:
    explicit            Dumper( const ::oox::core::FilterBase& rFilter );

    explicit            Dumper(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            const ::rtl::OUString& rSysFileName );

diff --git a/oox/inc/oox/helper/binaryinputstream.hxx b/oox/inc/oox/helper/binaryinputstream.hxx
index 52a3a4d..052c792 100644
--- a/oox/inc/oox/helper/binaryinputstream.hxx
+++ b/oox/inc/oox/helper/binaryinputstream.hxx
@@ -28,10 +28,14 @@
#ifndef OOX_HELPER_BINARYINPUTSTREAM_HXX
#define OOX_HELPER_BINARYINPUTSTREAM_HXX

#include <boost/shared_ptr.hpp>
#include <vector>
#include <com/sun/star/io/XInputStream.hpp>
#include "oox/helper/binarystreambase.hxx"

namespace com { namespace sun { namespace star {
    namespace io { class XInputStream; }
} } }

namespace oox {

class BinaryOutputStream;
@@ -46,24 +50,51 @@ class BinaryInputStream : public virtual BinaryStreamBase
{
public:
    /** Derived classes implement reading nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes ) = 0;
    /** Derived classes implement reading nBytes bytes to the (existing) buffer opMem.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes ) = 0;
        The sequence will be reallocated internally.

        @param nAtomSize
            The size of the elements in the memory block, if available. Derived
            classes may be interested in this information.

        @return
            Number of bytes really read.
     */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;

    /** Derived classes implement reading nBytes bytes to the (preallocated!)
        memory buffer opMem.

        @param nAtomSize
            The size of the elements in the memory block, if available. Derived
            classes may be interested in this information.

        @return
            Number of bytes really read.
     */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;

    /** Derived classes implement seeking the stream forward by the passed
        number of bytes. This should work for non-seekable streams too. */
    virtual void        skip( sal_Int32 nBytes ) = 0;
        number of bytes. This should work for non-seekable streams too.

        @param nAtomSize
            The size of the elements in the memory block, if available. Derived
            classes may be interested in this information.
     */
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;

    /** Reads a value from the stream and converts it to platform byte order.
        Supported types: SAL integers (8 to 64 bit), float, double. */
        All data types supported by the ByteOrderConverter class can be used.
     */
    template< typename Type >
    void                readValue( Type& ornValue );

    /** Reads a value from the stream and converts it to platform byte order.
        Supported types: SAL integers (8 to 64 bit), float, double. */
        All data types supported by the ByteOrderConverter class can be used.
     */
    template< typename Type >
    inline Type         readValue() { Type nValue; readValue( nValue ); return nValue; }
    /** Stream operator for integral and floating-point types. */

    /** Stream operator for all data types supported by the readValue() function. */
    template< typename Type >
    inline BinaryInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }

@@ -78,46 +109,135 @@ public:
    inline float        readFloat() { return readValue< float >(); }
    inline double       readDouble() { return readValue< double >(); }

    /** Reads a NUL-terminated byte character array and returns the string. */
    /** Reads a (preallocated!) C array of values from the stream.

        Converts all values in the array to platform byte order. All data types
        supported by the ByteOrderConverter class can be used.

        @param nElemCount
            Number of array elements to read (NOT byte count).

        @return
            Number of array elements really read (NOT byte count).
     */
    template< typename Type >
    sal_Int32           readArray( Type* opnArray, sal_Int32 nElemCount );

    /** Reads a sequence of values from the stream.

        The sequence will be reallocated internally. Converts all values in the
        array to platform byte order. All data types supported by the
        ByteOrderConverter class can be used.

        @param nElemCount
            Number of elements to put into the sequence (NOT byte count).

        @return
            Number of sequence elements really read (NOT byte count).
     */
    template< typename Type >
    sal_Int32           readArray( ::com::sun::star::uno::Sequence< Type >& orSequence, sal_Int32 nElemCount );

    /** Reads a vector of values from the stream.

        The vector will be resized internally. Converts all values in the
        vector to platform byte order. All data types supported by the
        ByteOrderConverter class can be used.

        @param nElemCount
            Number of elements to put into the vector (NOT byte count).

        @return
            Number of vector elements really read (NOT byte count).
     */
    template< typename Type >
    sal_Int32           readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount );

    /** Skips an array of values of a certain type in the stream.

        All data types supported by the ByteOrderConverter class can be used.

        @param nElemCount
            Number of array elements to skip (NOT byte count).
     */
    template< typename Type >
    void                skipArray( sal_Int32 nElemCount );

    /** Reads a NUL-terminated byte character array and returns the string.
     */
    ::rtl::OString      readNulCharArray();

    /** Reads a NUL-terminated byte character array and returns a Unicode string.
        @param eTextEnc  The text encoding used to create the Unicode string. */

        @param eTextEnc
            The text encoding used to create the Unicode string.
     */
    ::rtl::OUString     readNulCharArrayUC( rtl_TextEncoding eTextEnc );

    /** Reads a NUL-terminated Unicode character array and returns the string. */
    /** Reads a NUL-terminated Unicode character array and returns the string.
     */
    ::rtl::OUString     readNulUnicodeArray();

    /** Reads nChar byte characters and returns the string.
        @param nChars  Number of characters (bytes) to read from the stream.
    /** Reads a byte character array and returns the string.

        @param nChars
            Number of characters (bytes) to read from the stream.

        @param bAllowNulChars
            True = NUL characters are inserted into the imported string.
            False = NUL characters are replaced by question marks (default). */
            False = NUL characters are replaced by question marks (default).
     */
    ::rtl::OString      readCharArray( sal_Int32 nChars, bool bAllowNulChars = false );

    /** Reads nChar byte characters and returns a Unicode string.
        @param nChars  Number of characters (bytes) to read from the stream.
        @param eTextEnc  The text encoding used to create the Unicode string.
    /** Reads a byte character array and returns a Unicode string.

        @param nChars
            Number of characters (bytes) to read from the stream.

        @param eTextEnc
            The text encoding used to create the Unicode string.

        @param bAllowNulChars
            True = NUL characters are inserted into the imported string.
            False = NUL characters are replaced by question marks (default). */
            False = NUL characters are replaced by question marks (default).
     */
    ::rtl::OUString     readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars = false );

    /** Reads nChars Unicode characters and returns the string.
        @param nChars  Number of 16-bit characters to read from the stream.
    /** Reads a Unicode character array and returns the string.

        @param nChars
            Number of 16-bit characters to read from the stream.

        @param bAllowNulChars
            True = NUL characters are inserted into the imported string.
            False = NUL characters are replaced by question marks (default). */
            False = NUL characters are replaced by question marks (default).
     */
    ::rtl::OUString     readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars = false );

    /** Copies nBytes bytes from the current position to the passed output stream. */
    void                copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes = SAL_MAX_INT64 );
    /** Reads a Unicode character array (may be compressed) and returns the
        string.

private:
    /** Used by the readValue() template functions to read built-in types.
        @descr  Derived classes may overwrite this default implementation which
            simply calls readMemory() with something own. */
    virtual void        readAtom( void* opMem, sal_uInt8 nSize );
        @param nChars
            Number of 8-bit or 16-bit characters to read from the stream.

        @param bCompressed
            True = Character array is compressed (stored as 8-bit characters).
            False = Character array is not compressed (stored as 16-bit characters).

        @param bAllowNulChars
            True = NUL characters are inserted into the imported string.
            False = NUL characters are replaced by question marks (default).
     */
    ::rtl::OUString     readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars = false );

    /** Copies nBytes bytes from the current position to the passed output stream.
     */
    void                copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes = SAL_MAX_INT64, sal_Int32 nAtomSize = 1 );

protected:
    /** This dummy default c'tor will never call the c'tor of the virtual base
        class BinaryStreamBase as this class cannot be instanciated directly. */
    inline explicit     BinaryInputStream() : BinaryStreamBase( false ) {}
};

typedef ::boost::shared_ptr< BinaryInputStream > BinaryInputStreamRef;
@@ -127,14 +247,47 @@ typedef ::boost::shared_ptr< BinaryInputStream > BinaryInputStreamRef;
template< typename Type >
void BinaryInputStream::readValue( Type& ornValue )
{
    // can be instanciated for all types supported in class ByteOrderConverter
    readAtom( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ) );
    readMemory( &ornValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) );
    ByteOrderConverter::convertLittleEndian( ornValue );
}

template< typename Type >
sal_Int32 BinaryInputStream::readArray( Type* opnArray, sal_Int32 nElemCount )
{
    sal_Int32 nRet = 0;
    if( !mbEof )
    {
        sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
        nRet = readMemory( opnArray, nReadSize, sizeof( Type ) ) / sizeof( Type );
        ByteOrderConverter::convertLittleEndianArray( opnArray, static_cast< size_t >( nRet ) );
    }
    return nRet;
}

template< typename Type >
sal_Int32 BinaryInputStream::readArray( ::com::sun::star::uno::Sequence< Type >& orSequence, sal_Int32 nElemCount )
{
    orSequence.reallocate( nElemCount );
    return orSequence.hasElements() ? readArray( orSequence.getArray(), nElemCount ) : 0;
}

template< typename Type >
sal_Int32 BinaryInputStream::readArray( ::std::vector< Type >& orVector, sal_Int32 nElemCount )
{
    orVector.resize( static_cast< size_t >( nElemCount ) );
    return orVector.empty() ? 0 : readArray( &orVector.front(), nElemCount );
}

template< typename Type >
void BinaryInputStream::skipArray( sal_Int32 nElemCount )
{
    sal_Int32 nSkipSize = getLimitedValue< sal_Int32 >( nElemCount, 0, SAL_MAX_INT32 / sizeof( Type ) ) * sizeof( Type );
    implSkip( nSkipSize, sizeof( Type ) );
}

// ============================================================================

/** Wraps a com.sun.star.io.XInputStream and provides convenient access functions.
/** Wraps a UNO input stream and provides convenient access functions.

    The binary data in the stream is assumed to be in little-endian format.
 */
@@ -143,10 +296,13 @@ class BinaryXInputStream : public BinaryXSeekableStream, public BinaryInputStrea
public:
    /** Constructs the wrapper object for the passed input stream.

        @param rxInStream  The com.sun.star.io.XInputStream interface of the
            input stream to be wrapped.
        @param bAutoClose  True = automatically close the wrapped input stream
            on destruction of this wrapper.
        @param rxInStream
            The com.sun.star.io.XInputStream interface of the UNO input stream
            to be wrapped.

        @param bAutoClose
            True = automatically close the wrapped input stream on destruction
            of this wrapper or when close() is called.
     */
    explicit            BinaryXInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
@@ -154,26 +310,26 @@ public:

    virtual             ~BinaryXInputStream();

    /** Closes the input stream. Does also close the wrapped UNO input stream
        if bAutoClose has been set to true in the constructor. */
    virtual void        close();

    /** Reads nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes );
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Reads nBytes bytes to the (existing) buffer opMem.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes );
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Seeks the stream forward by the passed number of bytes. This works for
        non-seekable streams too. */
    virtual void        skip( sal_Int32 nBytes );
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for integral and floating-point types. */
    /** Stream operator for all data types supported by the readValue() function. */
    template< typename Type >
    inline BinaryXInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }

    /** Returns the XInputStream interface of the wrapped input stream. */
    inline ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
                        getXInputStream() const { return mxInStrm; }
    /** Closes the wrapped XInputStream. */
    void                close();

private:
    StreamDataSequence  maBuffer;       /// Data buffer used in readMemory() function.
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >
@@ -181,8 +337,6 @@ private:
    bool                mbAutoClose;    /// True = automatically close stream on destruction.
};

typedef ::boost::shared_ptr< BinaryXInputStream > BinaryXInputStreamRef;

// ============================================================================

/** Wraps a StreamDataSequence and provides convenient access functions.
@@ -203,86 +357,97 @@ public:

    /** Reads nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes );
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Reads nBytes bytes to the (existing) buffer opMem.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes );
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Seeks the stream forward by the passed number of bytes. This works for
        non-seekable streams too. */
    virtual void        skip( sal_Int32 nBytes );
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for integral and floating-point types. */
    /** Stream operator for all data types supported by the readValue() function. */
    template< typename Type >
    inline SequenceInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }
};

typedef ::boost::shared_ptr< SequenceInputStream > SequenceInputStreamRef;
private:
    /** Returns the number of bytes available in the sequence for the passed byte count. */
    inline sal_Int32    getMaxBytes( sal_Int32 nBytes ) const
                            { return getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mpData->getLength() - mnPos ); }
};

// ============================================================================

/** Wraps a BinaryInputStream and provides access to a specific part of the
    stream data.

    @descr
        Provides access to the stream data block starting at the current
        position of the stream, and with a specific length. If the wrapped
        stream is seekable, this wrapper will treat the position the wrapped
        has at construction time as position "0" (therefore the class name).
    Provides access to the stream data block starting at the current position
    of the stream, and with a specific length. If the wrapped stream is
    seekable, this wrapper will treat the position of the wrapped stream at
    construction time as position "0" (therefore the class name).

    The passed input stream MUST live at least as long as this stream wrapper.
    The stream MUST NOT be changed from outside as long as this stream wrapper
    is used to read from it.
 */
class RelativeInputStream : public BinaryInputStream
{
public:
    /** Constructs the wrapper object for the passed stream.

        @attention
            The passed input stream MUST live at least as long as this stream
            wrapper. The stream MUST NOT be changed from outside as long as
            this stream wrapper is used to read from it.

        @param nLength
        @param nSize
            If specified, restricts the amount of data that can be read from
            the passed input stream.
     */
    explicit            RelativeInputStream(
                            BinaryInputStream& rInStrm,
                            sal_Int64 nLength = SAL_MAX_INT64 );
                            sal_Int64 nSize = SAL_MAX_INT64 );

    /** Returns whether the wrapped stream is seekable. */
    virtual bool        isSeekable() const;
    /** Returns the size of the data block in the wrapped stream offered by
        this wrapper. */
    virtual sal_Int64   getLength() const;
    virtual sal_Int64   size() const;

    /** Returns the current relative stream position. */
    virtual sal_Int64   tell() const;

    /** Seeks the stream to the passed relative position, if the wrapped stream
        is seekable. */
    virtual void        seek( sal_Int64 nPos );

    /** Closes the input stream but not the wrapped stream. */
    virtual void        close();

    /** Reads nBytes bytes to the passed sequence. Does not read out of the
        data block whose size has been specified on construction.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes );
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Reads nBytes bytes to the (existing) buffer opMem. Does not read out of
        the data block whose size has been specified on construction.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes );
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Seeks the stream forward by the passed number of bytes. This works for
        non-seekable streams too. Does not seek out of the data block. */
    virtual void        skip( sal_Int32 nBytes );
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for integral and floating-point types. */
    /** Stream operator for all data types supported by the readValue() function. */
    template< typename Type >
    inline RelativeInputStream& operator>>( Type& ornValue ) { readValue( ornValue ); return *this; }

private:
    BinaryInputStream&  mrInStrm;
    /** Returns the number of bytes available in the sequence for the passed byte count. */
    inline sal_Int32    getMaxBytes( sal_Int32 nBytes ) const
                            { return getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnSize - mnRelPos ); }

private:
    BinaryInputStream*  mpInStrm;
    sal_Int64           mnStartPos;
    sal_Int64           mnRelPos;
    sal_Int64           mnLength;
    sal_Int64           mnSize;
};

typedef ::boost::shared_ptr< RelativeInputStream > RelativeInputStreamRef;

// ============================================================================

} // namespace oox
diff --git a/oox/inc/oox/helper/binaryoutputstream.hxx b/oox/inc/oox/helper/binaryoutputstream.hxx
index e24777c..362c7fbd 100644
--- a/oox/inc/oox/helper/binaryoutputstream.hxx
+++ b/oox/inc/oox/helper/binaryoutputstream.hxx
@@ -28,10 +28,12 @@
#ifndef OOX_HELPER_BINARYOUTPUTSTREAM_HXX
#define OOX_HELPER_BINARYOUTPUTSTREAM_HXX

#include <boost/shared_ptr.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include "oox/helper/binarystreambase.hxx"

namespace com { namespace sun { namespace star {
    namespace io { class XOutputStream; }
} } }

namespace oox {

// ============================================================================
@@ -43,24 +45,38 @@ namespace oox {
class BinaryOutputStream : public virtual BinaryStreamBase
{
public:
    /** Derived classes implement writing the passed data sequence. */
    virtual void        writeData( const StreamDataSequence& rData ) = 0;
    /** Derived classes implement writing from the (existing) buffer pMem. */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes ) = 0;
    /** Derived classes implement writing the contents of the passed data
        sequence.

        @param nAtomSize
            The size of the elements in the memory block, if available. Derived
            classes may be interested in this information.
     */
    virtual void        writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 ) = 0;

    /** Derived classes implement writing the contents of the (preallocated!)
        memory buffer pMem.

        @param nAtomSize
            The size of the elements in the memory block, if available. Derived
            classes may be interested in this information.
     */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) = 0;

    /** Writes a value to the stream and converts it to platform byte order.
        Supported types: SAL integers (8 to 64 bit), float, double. */
        All data types supported by the ByteOrderConverter class can be used.
     */
    template< typename Type >
    void                writeValue( Type nValue );
    /** Stream operator for integral and floating-point types. */

    /** Stream operator for all data types supported by the writeValue() function. */
    template< typename Type >
    inline BinaryOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }

private:
    /** Used by the writeValue() template function to write built-in types.
        @descr  Derived classes may overwrite this default implementation which
            simply calls writeMemory() with something own. */
    virtual void        writeAtom( const void* pMem, sal_uInt8 nSize );
protected:
    /** This dummy default c'tor will never call the c'tor of the virtual base
        class BinaryStreamBase as this class cannot be instanciated directly. */
    inline explicit     BinaryOutputStream() : BinaryStreamBase( false ) {}
};

typedef ::boost::shared_ptr< BinaryOutputStream > BinaryOutputStreamRef;
@@ -70,14 +86,13 @@ typedef ::boost::shared_ptr< BinaryOutputStream > BinaryOutputStreamRef;
template< typename Type >
void BinaryOutputStream::writeValue( Type nValue )
{
    // can be instanciated for all types supported in class ByteOrderConverter
    ByteOrderConverter::convertLittleEndian( nValue );
    writeMemory( &nValue, static_cast< sal_Int32 >( sizeof( Type ) ) );
    writeMemory( &nValue, static_cast< sal_Int32 >( sizeof( Type ) ), sizeof( Type ) );
}

// ============================================================================

/** Wraps a com.sun.star.io.XOutputStream and provides convenient access functions.
/** Wraps a UNO output stream and provides convenient access functions.

    The binary data in the stream is written in little-endian format.
 */
@@ -86,10 +101,13 @@ class BinaryXOutputStream : public BinaryXSeekableStream, public BinaryOutputStr
public:
    /** Constructs the wrapper object for the passed output stream.

        @param rxOutStream  The com.sun.star.io.XOutputStream interface of the
            output stream to be wrapped.
        @param bAutoClose  True = automatically close the wrapped output stream
            on destruction of this wrapper.
        @param rxOutStream
            The com.sun.star.io.XOutputStream interface of the output stream to
            be wrapped.

        @param bAutoClose
            True = automatically close the wrapped output stream on destruction
            of this wrapper or when close() is called.
     */
    explicit            BinaryXOutputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rxOutStrm,
@@ -97,20 +115,23 @@ public:

    virtual             ~BinaryXOutputStream();

    /** Writes the passed data sequence. */
    virtual void        writeData( const StreamDataSequence& rData );
    /** Write nBytes bytes from the (existing) buffer pMem. */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes );
    /** Flushes and closes the output stream. Does also close the wrapped UNO
        output stream if bAutoClose has been set to true in the constructor. */
    void                close();

    /** Stream operator for integral and floating-point types. */
    /** Writes the passed data sequence. */
    virtual void        writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 );

    /** Write nBytes bytes from the (preallocated!) buffer pMem. */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for all data types supported by the writeValue() function. */
    template< typename Type >
    inline BinaryXOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }

    /** Returns the XOutputStream interface of the wrapped output stream. */
    inline ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >
                        getXOutputStream() const { return mxOutStrm; }
    /** Flushes and closes the wrapped XOutputStream. */
    void                close();

private:
    StreamDataSequence  maBuffer;       /// Data buffer used in writeMemory() function.
@@ -119,8 +140,6 @@ private:
    bool                mbAutoClose;    /// True = automatically close stream on destruction.
};

typedef ::boost::shared_ptr< BinaryXOutputStream > BinaryXOutputStreamRef;

// ============================================================================

/** Wraps a StreamDataSequence and provides convenient access functions.
@@ -142,17 +161,16 @@ public:
    explicit            SequenceOutputStream( StreamDataSequence& rData );

    /** Writes the passed data sequence. */
    virtual void        writeData( const StreamDataSequence& rData );
    /** Write nBytes bytes from the (existing) buffer pMem. */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes );
    virtual void        writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 );

    /** Stream operator for integral and floating-point types. */
    /** Write nBytes bytes from the (preallocated!) buffer pMem. */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for all data types supported by the writeValue() function. */
    template< typename Type >
    inline SequenceOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }
};

typedef ::boost::shared_ptr< SequenceOutputStream > SequenceOutputStreamRef;

// ============================================================================

} // namespace oox
diff --git a/oox/inc/oox/helper/binarystreambase.hxx b/oox/inc/oox/helper/binarystreambase.hxx
index ba0f34b..0088b29 100644
--- a/oox/inc/oox/helper/binarystreambase.hxx
+++ b/oox/inc/oox/helper/binarystreambase.hxx
@@ -29,75 +29,123 @@
#define OOX_HELPER_BINARYSTREAMBASE_HXX

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/io/XSeekable.hpp>
#include <boost/shared_ptr.hpp>
#include "oox/helper/helper.hxx"

namespace com { namespace sun { namespace star {
    namespace io { class XSeekable; }
} } }

namespace oox {

typedef ::com::sun::star::uno::Sequence< sal_Int8 > StreamDataSequence;

// ============================================================================

/** Base interface for binary stream classes. Implemenetations may or may not
    support seeking the stream. */
/** Base class for binary stream classes.
 */
class BinaryStreamBase
{
public:
    virtual             ~BinaryStreamBase();

    /** Derived classes return whether the stream is seekable. Default: false. */
    virtual bool        isSeekable() const;
    /** Derived classes return the size of the stream, if possible,
        otherwise/default: -1. May return something for unseekable streams. */
    virtual sal_Int64   getLength() const;
    /** Derived classes return the current stream position, if possible,
        otherwise/default: -1. May return something for unseekable streams. */
    virtual sal_Int64   tell() const;
    /** Derived classes implement seeking the stream to the passed position, if
        the stream is seekable. */
    virtual void        seek( sal_Int64 nPos );
    /** Implementations return the size of the stream, if possible.

        This function may be implemented for some types of unseekable streams,
        and MUST be implemented for all seekable streams.

        @return
            The size of the stream in bytes, or -1, if not implemented.
     */
    virtual sal_Int64   size() const = 0;

    /** Implementations return the current stream position, if possible.

        This function may be implemented for some types of unseekable streams,
        and MUST be implemented for all seekable streams.

        @return
            The current position in the stream, or -1, if not implemented.
     */
    virtual sal_Int64   tell() const = 0;

    /** Implementations seek the stream to the passed position, if
        the stream is seekable.
     */
    virtual void        seek( sal_Int64 nPos ) = 0;

    /** Implementations close the stream.
     */
    virtual void        close() = 0;

    /** Returns true, if the implementation supports the seek() operation.

        Implementations may still implement size() and tell() even if the
        stream is not seekable.
     */
    inline bool         isSeekable() const { return mbSeekable; }

    /** Returns true, if the stream position is invalid (EOF). This flag turns
        true *after* the first attempt to seek/read beyond the stream end. */
        true *after* the first attempt to seek/read beyond the stream end.
     */
    inline bool         isEof() const { return mbEof; }

    /** Returns the size of the remaining data, if stream is seekable, otherwise -1. */
    /** Returns the size of the remaining data available in the stream, if
        stream supports size() and tell(), otherwise -1.
     */
    sal_Int64           getRemaining() const;
    /** Seeks the stream to the beginning, if stream is seekable. */

    /** Seeks the stream to the beginning, if stream is seekable.
     */
    inline void         seekToStart() { seek( 0 ); }
    /** Seeks the stream to the end, if stream is seekable. */
    inline void         seekToEnd() { seek( getLength() ); }

    /** Seeks the stream to the end, if stream is seekable.
     */
    inline void         seekToEnd() { seek( size() ); }

    /** Seeks the stream forward to a position that is a multiple of the passed
        block size, relative to the passed stream position, if stream is seekable. */
        block size, if stream is seekable.

        @param nBlockSize
            The size of the data blocks the streams needs to be aligned to.

        @param nAnchorPos
            Position in the stream the data blocks are aligned to.
     */
    void                alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos = 0 );

protected:
    inline explicit     BinaryStreamBase() : mbEof( false ) {}
    inline explicit     BinaryStreamBase( bool bSeekable ) : mbEof( false ), mbSeekable( bSeekable ) {}

private:
                        BinaryStreamBase( const BinaryStreamBase& );
    BinaryStreamBase&   operator=( const BinaryStreamBase& );

protected:
    bool                mbEof;
    bool                mbEof;          /// End of stream flag.

private:
    const bool          mbSeekable;     /// True = implementation supports seeking.
};

// ============================================================================

/** Base class for binary input and output streams wrapping an API stream,
/** Base class for binary input and output streams wrapping a UNO stream,
    seekable via the com.sun.star.io.XSeekable interface.
 */
class BinaryXSeekableStream : public virtual BinaryStreamBase
{
public:
    /** Returns true, if the wrapped stream is seekable. */
    virtual bool        isSeekable() const;
    /** Returns the size of the stream, if stream is seekable, otherwise -1. */
    virtual sal_Int64   getLength() const;
    /** Returns the current stream position, if stream is seekable, otherwise -1. */
    virtual             ~BinaryXSeekableStream();

    /** Returns the size of the stream, if wrapped stream is seekable, otherwise -1. */
    virtual sal_Int64   size() const;
    /** Returns the current stream position, if wrapped stream is seekable, otherwise -1. */
    virtual sal_Int64   tell() const;
    /** Seeks the stream to the passed position, if stream is seekable. */
    /** Seeks the stream to the passed position, if wrapped stream is seekable. */
    virtual void        seek( sal_Int64 nPos );
    /** Releases the reference to the UNO XSeekable interface. */
    virtual void        close();

protected:
    explicit            BinaryXSeekableStream(
@@ -111,31 +159,29 @@ private:
// ============================================================================

/** Base class for binary input and output streams wrapping a
    StreamDataSequence, which is always seekable. */
    StreamDataSequence, which is always seekable.

    The wrapped data sequence MUST live at least as long as this stream
    wrapper. The data sequence MUST NOT be changed from outside as long as this
    stream wrapper is used to modify it.
 */
class SequenceSeekableStream : public virtual BinaryStreamBase
{
public:
    /** Returns true (data sequence streams are always seekable). */
    virtual bool        isSeekable() const;
    /** Returns the size of the wrapped data sequence. */
    virtual sal_Int64   getLength() const;
    virtual sal_Int64   size() const;
    /** Returns the current stream position. */
    virtual sal_Int64   tell() const;
    /** Seeks the stream to the passed position. */
    virtual void        seek( sal_Int64 nPos );
    /** Releases the reference to the data sequence. */
    virtual void        close();

protected:
    /** Constructs the wrapper object for the passed data sequence.

        @attention
            The passed data sequence MUST live at least as long as this stream
            wrapper. The data sequence MUST NOT be changed from outside as long
            as this stream wrapper is used to modify it.
     */
    inline explicit     SequenceSeekableStream( const StreamDataSequence& rData ) : mrData( rData ), mnPos( 0 ) {}
    explicit            SequenceSeekableStream( const StreamDataSequence& rData );

protected:
    const StreamDataSequence& mrData;   /// Wrapped data sequence.
    const StreamDataSequence* mpData;   /// Wrapped data sequence.
    sal_Int32           mnPos;          /// Current position in the sequence.
};

diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx
index 96b9fee..d6c9721 100644
--- a/oox/inc/oox/helper/containerhelper.hxx
+++ b/oox/inc/oox/helper/containerhelper.hxx
@@ -40,7 +40,7 @@ namespace com { namespace sun { namespace star {
    namespace container { class XIndexContainer; }
    namespace container { class XNameAccess; }
    namespace container { class XNameContainer; }
    namespace lang { class XMultiServiceFactory; }
    namespace uno { class XComponentContext; }
} } }

namespace oox {
@@ -124,7 +124,7 @@ public:

    /** Creates a new index container object from scratch. */
    static ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >
                        createIndexContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
                        createIndexContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext );

    /** Inserts an object into an indexed container.

@@ -146,7 +146,7 @@ public:

    /** Creates a new name container object from scratch. */
    static ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
                        createNameContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
                        createNameContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext );

    /** Returns a name that is not used in the passed name container.

diff --git a/oox/inc/oox/helper/graphichelper.hxx b/oox/inc/oox/helper/graphichelper.hxx
index b2b9e1c..a854419 100644
--- a/oox/inc/oox/helper/graphichelper.hxx
+++ b/oox/inc/oox/helper/graphichelper.hxx
@@ -157,7 +157,7 @@ private:
    typedef ::std::deque< ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicObject > > GraphicObjectDeque;
    typedef ::std::map< ::rtl::OUString, ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > > EmbeddedGraphicMap;

    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxCompContext;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext;
    ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicProvider > mxGraphicProvider;
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XUnitConversion > mxUnitConversion;
    ::com::sun::star::awt::DeviceInfo maDeviceInfo; /// Current output device info.
diff --git a/oox/inc/oox/helper/helper.hxx b/oox/inc/oox/helper/helper.hxx
index 84c501f..4e5efea 100644
--- a/oox/inc/oox/helper/helper.hxx
+++ b/oox/inc/oox/helper/helper.hxx
@@ -236,9 +236,9 @@ private:
class ByteOrderConverter
{
public:
#ifdef OSL_BIGENDIAN
    inline static void  convertLittleEndian( sal_Int8& ) {}     // present for usage in templates
    inline static void  convertLittleEndian( sal_uInt8& ) {}    // present for usage in templates
#ifdef OSL_BIGENDIAN
    inline static void  convertLittleEndian( sal_Int16& rnValue )  { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
    inline static void  convertLittleEndian( sal_uInt16& rnValue ) { swap2( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
    inline static void  convertLittleEndian( sal_Int32& rnValue )  { swap4( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
@@ -247,15 +247,20 @@ public:
    inline static void  convertLittleEndian( sal_uInt64& rnValue ) { swap8( reinterpret_cast< sal_uInt8* >( &rnValue ) ); }
    inline static void  convertLittleEndian( float& rfValue )      { swap4( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }
    inline static void  convertLittleEndian( double& rfValue )     { swap8( reinterpret_cast< sal_uInt8* >( &rfValue ) ); }

    template< typename Type >
    inline static void  convertLittleEndianArray( Type* pnArray, size_t nElemCount );

    template<> inline static void convertLittleEndianArray( sal_Int8*, size_t ) {}
    template<> inline static void convertLittleEndianArray( sal_uInt8*, size_t ) {}

#else
    inline static void  convertLittleEndian( sal_Int16& ) {}
    inline static void  convertLittleEndian( sal_uInt16& ) {}
    inline static void  convertLittleEndian( sal_Int32& ) {}
    inline static void  convertLittleEndian( sal_uInt32& ) {}
    inline static void  convertLittleEndian( sal_Int64& ) {}
    inline static void  convertLittleEndian( sal_uInt64& ) {}
    inline static void  convertLittleEndian( float& ) {}
    inline static void  convertLittleEndian( double& ) {}
    template< typename Type >
    inline static void  convertLittleEndian( Type& ) {}

    template< typename Type >
    inline static void  convertLittleEndianArray( Type*, size_t ) {}

#endif

    /** Reads a value from memory, assuming memory buffer in little-endian.
@@ -297,6 +302,13 @@ inline void ByteOrderConverter::writeLittleEndian( void* pDstBuffer, Type nValue
}

#ifdef OSL_BIGENDIAN
template< typename Type >
inline void ByteOrderConverter::convertLittleEndianArray( Type* pnArray, size_t nElemCount )
{
    for( Type* pnArrayEnd = pnArray + nElemCount; pnArray != pnArrayEnd; ++pnArray )
        convertLittleEndian( *pnArray );
}

inline void ByteOrderConverter::swap2( sal_uInt8* pnData )
{
    ::std::swap( pnData[ 0 ], pnData[ 1 ] );
diff --git a/oox/inc/oox/helper/modelobjecthelper.hxx b/oox/inc/oox/helper/modelobjecthelper.hxx
index b4eb38c..b25035d 100644
--- a/oox/inc/oox/helper/modelobjecthelper.hxx
+++ b/oox/inc/oox/helper/modelobjecthelper.hxx
@@ -48,7 +48,7 @@ class ObjectContainer
{
public:
    explicit            ObjectContainer(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory,
                            const ::rtl::OUString& rServiceName );
                        ~ObjectContainer();

@@ -68,8 +68,8 @@ private:
    void                createContainer() const;

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        mxFactory;              /// Factory to create the container.
    mutable ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        mxModelFactory;         /// Factory to create the container.
    mutable ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
                        mxContainer;            /// Container for the objects.
    ::rtl::OUString     maServiceName;          /// Service name to create the container.
diff --git a/oox/inc/oox/helper/propertyset.hxx b/oox/inc/oox/helper/propertyset.hxx
index c86de41..8b5b562 100644
--- a/oox/inc/oox/helper/propertyset.hxx
+++ b/oox/inc/oox/helper/propertyset.hxx
@@ -28,8 +28,9 @@
#ifndef OOX_HELPER_PROPERTYSET_HXX
#define OOX_HELPER_PROPERTYSET_HXX

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include "oox/token/properties.hxx"

namespace oox {
@@ -82,6 +83,9 @@ public:
    inline ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                        getXPropertySet() const { return mxPropSet; }

    /** Returns true, if the specified property is supported by the property set. */
    bool                hasProperty( sal_Int32 nPropId ) const;

    // Get properties ---------------------------------------------------------

    /** Gets the specified property from the property set.
@@ -141,6 +145,8 @@ private:
                        mxPropSet;          /// The mandatory property set interface.
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
                        mxMultiPropSet;     /// The optional multi property set interface.
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
                        mxPropSetInfo;      /// Property information.
};

// ============================================================================
diff --git a/oox/inc/oox/helper/textinputstream.hxx b/oox/inc/oox/helper/textinputstream.hxx
index 2e98d3f..1c8ef47 100644
--- a/oox/inc/oox/helper/textinputstream.hxx
+++ b/oox/inc/oox/helper/textinputstream.hxx
@@ -25,29 +25,100 @@
 *
 ************************************************************************/

#ifndef OOX_HELPER_RECORDINPUTSTREAM_HXX
#define OOX_HELPER_RECORDINPUTSTREAM_HXX
#ifndef OOX_HELPER_TEXTINPUTSTREAM_HXX
#define OOX_HELPER_TEXTINPUTSTREAM_HXX

#include "oox/helper/binaryinputstream.hxx"
#include <com/sun/star/uno/Reference.hxx>
#include <rtl/ustring.hxx>

namespace com { namespace sun { namespace star {
    namespace io { class XInputStream; }
    namespace io { class XTextInputStream; }
    namespace uno { class XComponentContext; }
} } }

namespace oox {

class BinaryInputStream;

// ============================================================================

class TextInputStream
{
public:
    explicit            TextInputStream( BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc );
    explicit            TextInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            rtl_TextEncoding eTextEnc );

    /** Returns true, if the wrapped input stream is in EOF state. */
    explicit            TextInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            BinaryInputStream& rInStrm,
                            rtl_TextEncoding eTextEnc );

                        ~TextInputStream();

    /** Returns true, if no more text is available in the stream.
     */
    bool                isEof() const;
    /** Reads a text line from the stream. */

    /** Reads a text line from the stream.

        If the last line in the stream is not terminated with line-end
        character(s), the stream will immediately go into EOF state and return
        the text line. Otherwise, if the last character in the stream is a
        line-end character, the next call to this function will turn the stream
        into EOF state and return an empty string.
     */
    ::rtl::OUString     readLine();

    /** Reads a text portion from the stream until the specified character is
        found.

        If the end of the stream is not terminated with the specified
        character, the stream will immediately go into EOF state and return the
        remaining text portion. Otherwise, if the last character in the stream
        is the specified character (and caller specifies to read and return it,
        see parameter bIncludeChar), the next call to this function will turn
        the stream into EOF state and return an empty string.

        @param cChar
            The separator character to be read to.

        @param bIncludeChar
            True = if found, the specified character will be read from stream
                and included in the returned string.
            False = the specified character will neither be read from the
                stream nor included in the returned string, but will be
                returned as first character in the next call of this function
                or readLine().
     */
    ::rtl::OUString     readToChar( sal_Unicode cChar, bool bIncludeChar );

    // ------------------------------------------------------------------------

    /** Creates a UNO text input stream object from the passed UNO input stream.
     */
    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
                        createXTextInputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            rtl_TextEncoding eTextEnc );

    // ------------------------------------------------------------------------
private:
    BinaryInputStream&  mrInStrm;
    rtl_TextEncoding    meTextEnc;
    sal_Unicode         mcLastEolChar;
    void                init(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm,
                            rtl_TextEncoding eTextEnc );

    /** Adds the pending character in front of the passed string, if existing. */
    ::rtl::OUString     createFinalString( const ::rtl::OUString& rString );

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
                        mxTextStrm;
    sal_Unicode         mcPendingChar;
};

// ============================================================================
diff --git a/oox/inc/oox/helper/zipstorage.hxx b/oox/inc/oox/helper/zipstorage.hxx
index d4bc687..26eeebc 100644
--- a/oox/inc/oox/helper/zipstorage.hxx
+++ b/oox/inc/oox/helper/zipstorage.hxx
@@ -31,7 +31,7 @@
#include "oox/helper/storagebase.hxx"

namespace com { namespace sun { namespace star {
    namespace lang { class XMultiServiceFactory; }
    namespace uno { class XComponentContext; }
} } }

namespace oox {
@@ -43,11 +43,11 @@ class ZipStorage : public StorageBase
{
public:
    explicit            ZipStorage(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream );

    explicit            ZipStorage(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxStream );

    virtual             ~ZipStorage();
diff --git a/oox/inc/oox/ole/axbinaryreader.hxx b/oox/inc/oox/ole/axbinaryreader.hxx
index f26075f..b986fc8 100644
--- a/oox/inc/oox/ole/axbinaryreader.hxx
+++ b/oox/inc/oox/ole/axbinaryreader.hxx
@@ -40,7 +40,7 @@ namespace ole {
/** A wrapper for a binary input stream that supports aligned read operations.

    The implementation does not support seeking back the wrapped stream. All
    seeking operations (tell, seek, align) are performed relative to the
    seeking operations (tell, seekTo, align) are performed relative to the
    position of the wrapped stream at construction time of this wrapper. It is
    possible to construct this wrapper with an unseekable input stream without
    loosing any functionality.
@@ -50,21 +50,26 @@ class AxAlignedInputStream : public BinaryInputStream
public:
    explicit            AxAlignedInputStream( BinaryInputStream& rInStrm );

    /** Returns the size of the data this stream represents, if the wrapped
        stream supports the size() operation. */
    virtual sal_Int64   size() const;
    /** Return the current relative stream position (relative to position of
        the wrapped stream at construction time). */
    virtual sal_Int64   tell() const;
    /** Seeks the stream to the passed relative position, if it is behind the
        current position. */
    virtual void        seek( sal_Int64 nPos );
    /** Closes the input stream but not the wrapped stream. */
    virtual void        close();

    /** Reads nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes );
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
    /** Reads nBytes bytes to the (existing) buffer opMem.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes );
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
    /** Seeks the stream forward by the passed number of bytes. */
    virtual void        skip( sal_Int32 nBytes );
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Aligns the stream to a multiple of the passed size (relative to the
        position of the wrapped stream at construction time). */
@@ -78,8 +83,9 @@ public:
    inline void         skipAligned() { align( sizeof( Type ) ); skip( sizeof( Type ) ); }

private:
    BinaryInputStream&  mrInStrm;           /// The wrapped input stream.
    BinaryInputStream*  mpInStrm;           /// The wrapped input stream.
    sal_Int64           mnStrmPos;          /// Tracks relative position in the stream.
    sal_Int64           mnStrmSize;         /// Size of the wrapped stream data.
};

// ============================================================================
diff --git a/oox/inc/oox/ole/oleobjecthelper.hxx b/oox/inc/oox/ole/oleobjecthelper.hxx
index c3a5821..159384b 100644
--- a/oox/inc/oox/ole/oleobjecthelper.hxx
+++ b/oox/inc/oox/ole/oleobjecthelper.hxx
@@ -63,7 +63,7 @@ class OleObjectHelper
{
public:
    explicit            OleObjectHelper(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory );
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory );
                        ~OleObjectHelper();

    bool                importOleObject(
diff --git a/oox/inc/oox/ole/olestorage.hxx b/oox/inc/oox/ole/olestorage.hxx
index eabcfd4..5ea9d02 100644
--- a/oox/inc/oox/ole/olestorage.hxx
+++ b/oox/inc/oox/ole/olestorage.hxx
@@ -32,7 +32,7 @@

namespace com { namespace sun { namespace star {
    namespace container { class XNameContainer; }
    namespace lang { class XMultiServiceFactory; }
    namespace uno { class XComponentContext; }
} } }

namespace oox {
@@ -45,12 +45,12 @@ class OleStorage : public StorageBase
{
public:
    explicit            OleStorage(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStream,
                            bool bBaseStreamAccess );

    explicit            OleStorage(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream,
                            bool bBaseStreamAccess );

@@ -101,8 +101,8 @@ private:
    virtual void        implCommit() const;

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        mxFactory;          /// Factory for storage/stream creation.
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
                        mxContext;          /// Component context with service manager.
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
                        mxStorage;          /// Access to elements of this sub storage.
    const OleStorage*   mpParentStorage;    /// Parent OLE storage that contains this storage.
diff --git a/oox/inc/oox/ole/vbacontrol.hxx b/oox/inc/oox/ole/vbacontrol.hxx
index 8c4274f..941b7d0 100644
--- a/oox/inc/oox/ole/vbacontrol.hxx
+++ b/oox/inc/oox/ole/vbacontrol.hxx
@@ -206,7 +206,7 @@ public:
                            rtl_TextEncoding eTextEnc );

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxCompContext;
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > mxContext;
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxDocModel;
    ControlConverter    maConverter;
};
diff --git a/oox/inc/oox/ole/vbainputstream.hxx b/oox/inc/oox/ole/vbainputstream.hxx
index 8586985..bc73eb3 100644
--- a/oox/inc/oox/ole/vbainputstream.hxx
+++ b/oox/inc/oox/ole/vbainputstream.hxx
@@ -42,14 +42,23 @@ class VbaInputStream : public BinaryInputStream
public:
    explicit            VbaInputStream( BinaryInputStream& rInStrm );

    /** Returns -1, stream size is not determinable. */
    virtual sal_Int64   size() const;
    /** Returns -1, stream position is not tracked. */
    virtual sal_Int64   tell() const;
    /** Does nothing, stream is not seekable. */
    virtual void        seek( sal_Int64 nPos );
    /** Closes the input stream but not the wrapped stream. */
    virtual void        close();

    /** Reads nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes );
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
    /** Reads nBytes bytes to the (existing) buffer opMem.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes );
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
    /** Seeks the stream forward by the passed number of bytes. */
    virtual void        skip( sal_Int32 nBytes );
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );

private:
    /** If no data left in chunk buffer, reads the next chunk from stream. */
@@ -58,7 +67,7 @@ private:
private:
    typedef ::std::vector< sal_uInt8 > ChunkBuffer;

    BinaryInputStream&  mrInStrm;
    BinaryInputStream*  mpInStrm;
    ChunkBuffer         maChunk;
    size_t              mnChunkPos;
};
diff --git a/oox/inc/oox/ole/vbamodule.hxx b/oox/inc/oox/ole/vbamodule.hxx
index 52b2261..57a1de31 100644
--- a/oox/inc/oox/ole/vbamodule.hxx
+++ b/oox/inc/oox/ole/vbamodule.hxx
@@ -35,6 +35,7 @@ namespace com { namespace sun { namespace star {
    namespace container { class XNameAccess; }
    namespace container { class XNameContainer; }
    namespace frame { class XModel; }
    namespace uno { class XComponentContext; }
} } }

namespace oox {
@@ -51,6 +52,7 @@ class VbaModule
{
public:
    explicit            VbaModule(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
                            const ::rtl::OUString& rName,
                            rtl_TextEncoding eTextEnc,
@@ -90,6 +92,8 @@ private:
                            const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
                        mxContext;          /// Component context with service manager.
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
                        mxDocModel;         /// Document model used to import/export the VBA project.
    ::rtl::OUString     maName;
diff --git a/oox/inc/oox/ole/vbaproject.hxx b/oox/inc/oox/ole/vbaproject.hxx
index 40e81c92..c5446e8 100644
--- a/oox/inc/oox/ole/vbaproject.hxx
+++ b/oox/inc/oox/ole/vbaproject.hxx
@@ -189,7 +189,7 @@ private:
    typedef ::std::map< ::rtl::OUString, sal_Int32 >    DummyModuleMap;

    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
                        mxCompContext;      /// Component context with service manager.
                        mxContext;          /// Component context with service manager.
    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
                        mxDocModel;         /// Document model used to import/export the VBA project.
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
diff --git a/oox/inc/oox/vml/vmlinputstream.hxx b/oox/inc/oox/vml/vmlinputstream.hxx
index a425425..d0121f8 100644
--- a/oox/inc/oox/vml/vmlinputstream.hxx
+++ b/oox/inc/oox/vml/vmlinputstream.hxx
@@ -28,36 +28,72 @@
#ifndef OOX_VML_VMLINPUTSTREAM_HXX
#define OOX_VML_VMLINPUTSTREAM_HXX

#include <comphelper/seqstream.hxx>
#include <com/sun/star/io/XInputStream.hpp>
#include <cppuhelper/implbase1.hxx>
#include <rtl/string.hxx>

namespace com { namespace sun { namespace star {
    namespace io { class XTextInputStream; }
    namespace uno { class XComponentContext; }
} } }

namespace oox {
namespace vml {

// ============================================================================

struct StreamDataContainer
{
    ::comphelper::ByteSequence maDataSeq;
typedef ::cppu::WeakImplHelper1< ::com::sun::star::io::XInputStream > InputStream_BASE;

    explicit            StreamDataContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm );
};
/** An input stream class for VML streams, implementing the UNO interface
    com.sun.star.io.XInputStream needed by the Expat XML parsers.

// ============================================================================
    This stream reads the data from the input stream passed to the constructor,
    and parses all XML elements for features unsupported by the current Expat
    XML parser:

/** An input stream class for VML streams.
    1)  All elements that have the form '<![inst]>' where 'inst' is any string
        not containing the characters '<' and '>' are stripped from the input
        stream.

    This stream reads the entire data from the input stream passed to the
    constructor, and parses all XML elements for features unsupported by the
    current Expat parser.
    2)  Multiple occurences of the same attribute in an element but the last
        are removed.

    All elements that have the form '<![inst]>' where 'inst' is any string not
    containing the characters '<' and '>' are stripped from the input stream.
    3)  Line breaks represented by a single <br> element (without matching
        </br> element) are replaced by a literal LF character.
 */
class InputStream : private StreamDataContainer, public ::comphelper::SequenceInputStream
class InputStream : public InputStream_BASE
{
public:
    explicit            InputStream( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm );
    explicit            InputStream(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rxInStrm );
    virtual             ~InputStream();

    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
                        throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
                        throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
                        throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL available()
                        throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput()
                        throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

private:
    void                updateBuffer() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    ::rtl::OString      readToElementBegin() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    ::rtl::OString      readToElementEnd() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XTextInputStream >
                        mxTextStrm;
    ::com::sun::star::uno::Sequence< sal_Unicode > maOpeningBracket;
    ::com::sun::star::uno::Sequence< sal_Unicode > maClosingBracket;
    const ::rtl::OString maOpeningCData;
    const ::rtl::OString maClosingCData;
    ::rtl::OString      maBuffer;
    sal_Int32           mnBufferPos;
};

// ============================================================================
diff --git a/oox/inc/oox/xls/biffhelper.hxx b/oox/inc/oox/xls/biffhelper.hxx
index 5a65eb0..9fbeee9 100644
--- a/oox/inc/oox/xls/biffhelper.hxx
+++ b/oox/inc/oox/xls/biffhelper.hxx
@@ -621,7 +621,7 @@ public:
    // BIFF12 import ----------------------------------------------------------

    /** Reads a BIFF12 string with leading 16-bit or 32-bit length field. */
    static ::rtl::OUString readString( SequenceInputStream& rStrm, bool b32BitLen = true );
    static ::rtl::OUString readString( SequenceInputStream& rStrm, bool b32BitLen = true, bool bAllowNulChars = false );

    // BIFF2-BIFF8 import -----------------------------------------------------

diff --git a/oox/inc/oox/xls/biffinputstream.hxx b/oox/inc/oox/xls/biffinputstream.hxx
index 003ab28..9f0ffa8 100644
--- a/oox/inc/oox/xls/biffinputstream.hxx
+++ b/oox/inc/oox/xls/biffinputstream.hxx
@@ -242,30 +242,30 @@ public:

    // BinaryStreamBase interface (seeking) -----------------------------------

    /** Returns true, as the BIFF input stream is required to be seekable. */
    virtual bool        isSeekable() const;
    /** Returns the data size of the whole record without record headers. */
    virtual sal_Int64   size() const;
    /** Returns the position inside of the whole record content. */
    virtual sal_Int64   tell() const;
    /** Returns the data size of the whole record without record headers. */
    virtual sal_Int64   getLength() const;
    /** Seeks in record content to the specified position. */
    virtual void        seek( sal_Int64 nRecPos );
    /** Closes the input stream but not the wrapped stream. */
    virtual void        close();

    /** Returns the absolute position in the wrapped binary stream. */
    sal_Int64           tellBase() const;
    /** Returns the total size of the wrapped binary stream. */
    sal_Int64           getBaseLength() const;
    sal_Int64           sizeBase() const;

    // BinaryInputStream interface (stream read access) -----------------------

    /** Reads nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes );
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
    /** Reads nBytes bytes and copies them to the passed buffer opMem.
        @return  Number of bytes really read. */
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes );
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
    /** Seeks forward inside the current record. */
    virtual void        skip( sal_Int32 nBytes );
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for integral and floating-point types. */
    template< typename Type >
@@ -352,9 +352,6 @@ public:

    // ------------------------------------------------------------------------
private:
    /** Forwards calls of readValue() template functions to the record buffer. */
    virtual void        readAtom( void* opMem, sal_uInt8 nSize );

    /** Initializes all members after base stream has been seeked to new record. */
    void                setupRecord();
    /** Restarts the current record from the beginning. */
@@ -383,16 +380,9 @@ private:
        records, stores the length in mnComplRecSize. */
    void                calcRecordLength();

    /** Ensures that reading nBytes bytes is possible with next stream access.
        @descr  Stream must be located at the end of a raw record, and handling
        of CONTINUE records must be enabled.
        @return  True if nBytes can be read from stream. */
    bool                ensureRawReadSize( sal_uInt16 nBytes );
    /** Returns the maximum size of raw data possible to read in one block. */
    sal_uInt16          getMaxRawReadSize( sal_Int32 nBytes ) const;
    sal_uInt16          getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const;

    /** Reads an array of Unicode characters and appends them to the passed buffer. */
    void                appendUnicodeArray( ::rtl::OUStringBuffer& orBuffer, sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars );
    /** Reads the BIFF8 Unicode string header fields. */
    void                readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize );

diff --git a/oox/inc/oox/xls/biffoutputstream.hxx b/oox/inc/oox/xls/biffoutputstream.hxx
index ada646bd..7d03572 100644
--- a/oox/inc/oox/xls/biffoutputstream.hxx
+++ b/oox/inc/oox/xls/biffoutputstream.hxx
@@ -94,9 +94,6 @@ private:
    CONTINUE record, use setPortionSize(). Example: To write a sequence of
    16-bit values where 4 values form a unit and cannot be split, call
    setPortionSize(8) first (4*2 bytes == 8).

    To write unicode character arrays, call writeUnicodeBuffer(). It creates
    CONTINUE records and repeats the unicode string flag byte automatically.
*/
class BiffOutputStream : public BinaryOutputStream
{
@@ -113,47 +110,44 @@ public:
    /** Finishes the current record. Must be called for every started record. */
    void                endRecord();

    /** Sets size of data portion in bytes. 0 means no portions are used. */
    void                setPortionSize( sal_uInt16 nSize );
    /** Sets size of data portion in bytes. 0 or 1 means no portions are used. */
    void                setPortionSize( sal_uInt8 nSize );

    // BinaryStreamBase interface (seeking) -----------------------------------

    /** Returns the absolute position in the wrapped binary stream. */
    sal_Int64           tellBase() const;
    /** Returns the total size of the wrapped binary stream. */
    sal_Int64           getBaseLength() const;
    sal_Int64           sizeBase() const;

    // BinaryOutputStream interface (stream write access) ---------------------

    /** Writes the passed data sequence. */
    virtual void        writeData( const StreamDataSequence& rData );
    virtual void        writeData( const StreamDataSequence& rData, size_t nAtomSize = 1 );
    /** Writes nBytes bytes from the passed buffer pMem. */
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes );
    virtual void        writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Writes a sequence of nBytes bytes with the passed value. */
    void                fill( sal_uInt8 nValue, sal_Int32 nBytes );
    /** Writes a block of memory, ensures that it is not split to a CONTINUE record. */
    void                writeBlock( const void* pMem, sal_uInt16 nBytes );
    void                fill( sal_uInt8 nValue, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Stream operator for integral and floating-point types. */
    /** Stream operator for all data types supported by the writeValue() function. */
    template< typename Type >
    inline BiffOutputStream& operator<<( Type nValue ) { writeValue( nValue ); return *this; }

    // ------------------------------------------------------------------------
private:
    /** Forwards calls of writeValue() template functions to the record buffer. */
    virtual void        writeAtom( const void* pMem, sal_uInt8 nSize );

    /** Checks the remaining size in the current record, creates CONTINUE record if needed. */
    void                ensureRawBlock( sal_uInt16 nSize );
    /** Checks the remaining size in the current record and creates CONTINUE record if needed.

    /** Checks the remaining size in the current record and creates a CONTINUE
        record if needed.
        @return  Maximum size left for writing to current record. */
    sal_uInt16          prepareRawBlock( sal_Int32 nTotalSize );
    sal_uInt16          prepareWriteBlock( sal_Int32 nTotalSize, size_t nAtomSize );

private:
    prv::BiffOutputRecordBuffer maRecBuffer;    /// Raw record data buffer.
    sal_uInt16          mnPortionSize;          /// Size of data portions.
    sal_uInt16          mnPortionPos;           /// Position in current portion.
    sal_uInt8           mnPortionSize;          /// Size of data portions.
    sal_uInt8           mnPortionPos;           /// Position in current portion.
};

// ============================================================================
diff --git a/oox/inc/oox/xls/formulabase.hxx b/oox/inc/oox/xls/formulabase.hxx
index d5336a2..47dac1a 100644
--- a/oox/inc/oox/xls/formulabase.hxx
+++ b/oox/inc/oox/xls/formulabase.hxx
@@ -577,7 +577,7 @@ class OpCodeProvider : public FunctionProvider // not derived from WorkbookHelpe
{
public:
    explicit            OpCodeProvider(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory,
                            FilterType eFilter, BiffType eBiff, bool bImportFilter );
    virtual             ~OpCodeProvider();

@@ -604,7 +604,7 @@ class ApiParserWrapper : public OpCodeProvider
{
public:
    explicit            ApiParserWrapper(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxFactory,
                            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory,
                            const OpCodeProvider& rOpCodeProv );

    /** Returns read/write access to the formula parser property set. */
diff --git a/oox/inc/oox/xls/ooxformulaparser.hxx b/oox/inc/oox/xls/ooxformulaparser.hxx
index 7bc1bbd..f74a6dd 100644
--- a/oox/inc/oox/xls/ooxformulaparser.hxx
+++ b/oox/inc/oox/xls/ooxformulaparser.hxx
@@ -46,10 +46,10 @@ class OOXMLFormulaPrinterImpl;
typedef ::cppu::WeakImplHelper3<
    ::com::sun::star::lang::XServiceInfo,
    ::com::sun::star::lang::XInitialization,
    ::com::sun::star::sheet::XFilterFormulaParser > OOXMLFormulaParserBase;
    ::com::sun::star::sheet::XFilterFormulaParser > OOXMLFormulaParser_BASE;

/** OOXML formula parser/compiler service for usage in ODF filters. */
class OOXMLFormulaParser : public OOXMLFormulaParserBase
class OOXMLFormulaParser : public OOXMLFormulaParser_BASE
{
public:
    explicit            OOXMLFormulaParser();
diff --git a/oox/inc/oox/xls/workbookhelper.hxx b/oox/inc/oox/xls/workbookhelper.hxx
index ecf8240..a67d147 100644
--- a/oox/inc/oox/xls/workbookhelper.hxx
+++ b/oox/inc/oox/xls/workbookhelper.hxx
@@ -133,9 +133,6 @@ public:

    /** Returns the base filter object (base class of all filters). */
    ::oox::core::FilterBase& getBaseFilter() const;
    /** Returns a reference to the global service factory. */
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        getGlobalFactory() const;
    /** Returns the file type of the current filter. */
    FilterType          getFilterType() const;
    /** Returns the filter progress bar. */
@@ -157,9 +154,6 @@ public:
    /** Returns a reference to the source/target spreadsheet document model. */
    ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
                        getDocument() const;
    /** Returns a reference to the service factory of the spreadsheet document model. */
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        getDocumentFactory() const;

    /** Returns a reference to the specified spreadsheet in the document model. */
    ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >
diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx
index 9bebedb..edff8a7 100644
--- a/oox/source/core/binaryfilterbase.cxx
+++ b/oox/source/core/binaryfilterbase.cxx
@@ -55,12 +55,12 @@ BinaryFilterBase::~BinaryFilterBase()

StorageRef BinaryFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
{
    return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxInStream, true ) );
    return StorageRef( new ::oox::ole::OleStorage( getComponentContext(), rxInStream, true ) );
}

StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
{
    return StorageRef( new ::oox::ole::OleStorage( getServiceFactory(), rxOutStream, true ) );
    return StorageRef( new ::oox::ole::OleStorage( getComponentContext(), rxOutStream, true ) );
}

// ============================================================================
diff --git a/oox/source/core/contexthandler.cxx b/oox/source/core/contexthandler.cxx
index 8bf2c4e..1ff793c 100644
--- a/oox/source/core/contexthandler.cxx
+++ b/oox/source/core/contexthandler.cxx
@@ -42,7 +42,7 @@ using ::rtl::OUString;
// ============================================================================

ContextHandler::ContextHandler( ContextHandler& rParent ) :
    ContextHandlerImplBase(),
    ContextHandler_BASE(),
    mxBaseData( rParent.mxBaseData )
{
}
diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx
index cdab111..f836720 100644
--- a/oox/source/core/filterdetect.cxx
+++ b/oox/source/core/filterdetect.cxx
@@ -269,9 +269,9 @@ const sal_uInt32 ENCRYPT_HASH_SHA1          = 0x00008004;

// ----------------------------------------------------------------------------

bool lclIsZipPackage( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm )
bool lclIsZipPackage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm )
{
    ZipStorage aZipStorage( rxFactory, rxInStrm );
    ZipStorage aZipStorage( rxContext, rxInStrm );
    return aZipStorage.isStorage();
}

@@ -499,109 +499,106 @@ PasswordVerifier::PasswordVerifier( const PackageEncryptionInfo& rEncryptInfo ) 

Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescriptor& rMediaDesc ) const
{
    Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY );
    if( xFactory.is() )
    // try the plain input stream
    Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY );
    if( !xInStrm.is() || lclIsZipPackage( mxContext, xInStrm ) )
        return xInStrm;

    // check if a temporary file is passed in the 'ComponentData' property
    Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY );
    if( xDecrypted.is() )
    {
        // try the plain input stream
        Reference< XInputStream > xInStrm( rMediaDesc[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY );
        if( !xInStrm.is() || lclIsZipPackage( xFactory, xInStrm ) )
            return xInStrm;
        Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream();
        if( lclIsZipPackage( mxContext, xDecrInStrm ) )
            return xDecrInStrm;
    }

        // check if a temporary file is passed in the 'ComponentData' property
        Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY );
        if( xDecrypted.is() )
    // try to decrypt an encrypted OLE package
    ::oox::ole::OleStorage aOleStorage( mxContext, xInStrm, false );
    if( aOleStorage.isStorage() ) try
    {
        // open the required input streams in the encrypted package
        Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW );
        Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW );

        // read the encryption info stream
        PackageEncryptionInfo aEncryptInfo;
        BinaryXInputStream aInfoStrm( xEncryptionInfo, true );
        bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm );

        // check flags and agorithm IDs, requiered are AES128 and SHA-1
        bool bImplemented = bValidInfo &&
            getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) &&
            getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) &&
            // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
            ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) &&
            // hash algorithm ID 0 defaults to SHA-1 too
            ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) &&
            (aEncryptInfo.mnVerifierHashSize == 20);

        if( bImplemented )
        {
            Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream();
            if( lclIsZipPackage( xFactory, xDecrInStrm ) )
                return xDecrInStrm;
        }
            /*  "VelvetSweatshop" is the built-in default encryption
                password used by MS Excel for the "workbook protection"
                feature with password. Try this first before prompting the
                user for a password. */
            ::std::vector< OUString > aDefaultPasswords;
            aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );

        // try to decrypt an encrypted OLE package
        ::oox::ole::OleStorage aOleStorage( xFactory, xInStrm, false );
        if( aOleStorage.isStorage() ) try
        {
            // open the required input streams in the encrypted package
            Reference< XInputStream > xEncryptionInfo( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptionInfo" ) ), UNO_SET_THROW );
            Reference< XInputStream > xEncryptedPackage( aOleStorage.openInputStream( CREATE_OUSTRING( "EncryptedPackage" ) ), UNO_SET_THROW );
            /*  Use the comphelper password helper to request a password.
                This helper returns either with the correct password
                (according to the verifier), or with an empty string if
                user has cancelled the password input dialog. */
            PasswordVerifier aVerifier( aEncryptInfo );
            Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
                aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );

            // read the encryption info stream
            PackageEncryptionInfo aEncryptInfo;
            BinaryXInputStream aInfoStrm( xEncryptionInfo, true );
            bool bValidInfo = lclReadEncryptionInfo( aEncryptInfo, aInfoStrm );

            // check flags and agorithm IDs, requiered are AES128 and SHA-1
            bool bImplemented = bValidInfo &&
                getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_CRYPTOAPI ) &&
                getFlag( aEncryptInfo.mnFlags, ENCRYPTINFO_AES ) &&
                // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set
                ((aEncryptInfo.mnAlgorithmId == 0) || (aEncryptInfo.mnAlgorithmId == ENCRYPT_ALGO_AES128)) &&
                // hash algorithm ID 0 defaults to SHA-1 too
                ((aEncryptInfo.mnAlgorithmIdHash == 0) || (aEncryptInfo.mnAlgorithmIdHash == ENCRYPT_HASH_SHA1)) &&
                (aEncryptInfo.mnVerifierHashSize == 20);

            if( bImplemented )
            if( aEncryptionData.getLength() == 0 )
            {
                /*  "VelvetSweatshop" is the built-in default encryption
                    password used by MS Excel for the "workbook protection"
                    feature with password. Try this first before prompting the
                    user for a password. */
                ::std::vector< OUString > aDefaultPasswords;
                aDefaultPasswords.push_back( CREATE_OUSTRING( "VelvetSweatshop" ) );
                rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true;
            }
            else
            {
                // create temporary file for unencrypted package
                Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
                Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
                Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW );
                BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true );
                BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true );

                /*  Use the comphelper password helper to request a password.
                    This helper returns either with the correct password
                    (according to the verifier), or with an empty string if
                    user has cancelled the password input dialog. */
                PasswordVerifier aVerifier( aEncryptInfo );
                Sequence< NamedValue > aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
                    aVerifier, rMediaDesc, ::comphelper::DocPasswordRequestType_MS, &aDefaultPasswords );
                EVP_CIPHER_CTX aes_ctx;
                EVP_CIPHER_CTX_init( &aes_ctx );
                EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 );
                EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );

                if( aEncryptionData.getLength() == 0 )
                sal_uInt8 pnInBuffer[ 1024 ];
                sal_uInt8 pnOutBuffer[ 1024 ];
                sal_Int32 nInLen;
                int nOutLen;
                aEncryptedPackage.skip( 8 ); // decrypted size
                while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 )
                {
                    rMediaDesc[ MediaDescriptor::PROP_ABORTED() ] <<= true;
                }
                else
                {
                    // create temporary file for unencrypted package
                    Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
                    Reference< XOutputStream > xDecryptedPackage( xTempFile->getOutputStream(), UNO_SET_THROW );
                    BinaryXOutputStream aDecryptedPackage( xDecryptedPackage, true );
                    BinaryXInputStream aEncryptedPackage( xEncryptedPackage, true );

                    EVP_CIPHER_CTX aes_ctx;
                    EVP_CIPHER_CTX_init( &aes_ctx );
                    EVP_DecryptInit_ex( &aes_ctx, EVP_aes_128_ecb(), 0, aVerifier.getKey(), 0 );
                    EVP_CIPHER_CTX_set_padding( &aes_ctx, 0 );

                    sal_uInt8 pnInBuffer[ 1024 ];
                    sal_uInt8 pnOutBuffer[ 1024 ];
                    sal_Int32 nInLen;
                    int nOutLen;
                    aEncryptedPackage.skip( 8 ); // decrypted size
                    while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 )
                    {
                        EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen );
                        aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );
                    }
                    EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen );
                    EVP_DecryptUpdate( &aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen );
                    aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );

                    EVP_CIPHER_CTX_cleanup( &aes_ctx );
                    xDecryptedPackage->flush();
                    aDecryptedPackage.seekToStart();

                    // store temp file in media descriptor to keep it alive
                    rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) );

                    Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream();
                    if( lclIsZipPackage( xFactory, xDecrInStrm ) )
                        return xDecrInStrm;
                }
                EVP_DecryptFinal_ex( &aes_ctx, pnOutBuffer, &nOutLen );
                aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen );

                EVP_CIPHER_CTX_cleanup( &aes_ctx );
                xDecryptedPackage->flush();
                aDecryptedPackage.seekToStart();

                // store temp file in media descriptor to keep it alive
                rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) );

                Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream();
                if( lclIsZipPackage( mxContext, xDecrInStrm ) )
                    return xDecrInStrm;
            }
        }
        catch( Exception& )
        {
        }
    }
    catch( Exception& )
    {
    }

    return Reference< XInputStream >();
@@ -633,7 +630,6 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq
{
    OUString aFilterName;
    MediaDescriptor aMediaDesc( rMediaDescSeq );
    Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );

    /*  Check that the user has not choosen to abort detection, e.g. by hitting
        'Cancel' in the password input dialog. This may happen because this
@@ -650,7 +646,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq
        Reference< XInputStream > xInStrm( extractUnencryptedPackage( aMediaDesc ), UNO_SET_THROW );

        // stream must be a ZIP package
        ZipStorage aZipStorage( xFactory, xInStrm );
        ZipStorage aZipStorage( mxContext, xInStrm );
        if( aZipStorage.isStorage() )
        {
            // create the fast parser, register the XML namespaces, set document handler
diff --git a/oox/source/core/fragmenthandler.cxx b/oox/source/core/fragmenthandler.cxx
index a1c42e5..14abe0d 100644
--- a/oox/source/core/fragmenthandler.cxx
+++ b/oox/source/core/fragmenthandler.cxx
@@ -52,12 +52,12 @@ FragmentBaseData::FragmentBaseData( XmlFilterBase& rFilter, const OUString& rFra
// ============================================================================

FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) :
    FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) )
    FragmentHandler_BASE( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, rFilter.importRelations( rFragmentPath ) ) ) )
{
}

FragmentHandler::FragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, RelationsRef xRelations ) :
    FragmentHandlerImplBase( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) )
    FragmentHandler_BASE( FragmentBaseDataRef( new FragmentBaseData( rFilter, rFragmentPath, xRelations ) ) )
{
}

diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx
index fe13d93..a77789e 100644
--- a/oox/source/core/xmlfilterbase.cxx
+++ b/oox/source/core/xmlfilterbase.cxx
@@ -496,12 +496,12 @@ Reference< XInputStream > XmlFilterBase::implGetInputStream( MediaDescriptor& rM

StorageRef XmlFilterBase::implCreateStorage( const Reference< XInputStream >& rxInStream ) const
{
    return StorageRef( new ZipStorage( getServiceFactory(), rxInStream ) );
    return StorageRef( new ZipStorage( getComponentContext(), rxInStream ) );
}

StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutStream ) const
{
    return StorageRef( new ZipStorage( getServiceFactory(), rxOutStream ) );
    return StorageRef( new ZipStorage( getComponentContext(), rxOutStream ) );
}

// ============================================================================
diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx
index 279c9d3..54e1fad 100644
--- a/oox/source/dump/biffdumper.cxx
+++ b/oox/source/dump/biffdumper.cxx
@@ -166,7 +166,7 @@ void BiffCtlsStreamObject::implDump()
        {
            IndentGuard aIndGuard( mxOut );
            mxStrm->seek( mnStartPos );
            RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) );
            BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, mnLength ) );
            FormControlStreamObject( *this, xRelStrm ).dump();
        }
        writeEmptyItem( "CTLS-END" );
@@ -356,7 +356,7 @@ bool BiffObjectBase::implStartRecord( BinaryInputStream&, sal_Int64& ornRecPos, 
        break;
    }

    ornRecSize = mxBiffStrm->getLength();
    ornRecSize = mxBiffStrm->size();
    return bValid;
}

@@ -810,7 +810,7 @@ void FormulaObject::implDump()
    if( mnSize == 0 ) return;

    sal_Int64 nStartPos = mxStrm->tell();
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() );
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() );

    bool bValid = mxTokens.get();
    mxStack.reset( new FormulaStack );
@@ -1603,7 +1603,7 @@ void WorkbookStreamObject::implDumpRecordBody()
{
    BiffInputStream& rStrm = getBiffStream();
    sal_uInt16 nRecId = rStrm.getRecId();
    sal_Int64 nRecSize = rStrm.getLength();
    sal_Int64 nRecSize = rStrm.size();
    BiffType eBiff = getBiff();

    switch( nRecId )
@@ -4524,7 +4524,7 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent )
    addPreferredStream( "Workbook" );
}

void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    if( (rStrgPath.getLength() == 0) && (rStrmName.equalsAscii( "Book" ) || rStrmName.equalsAscii( "Workbook" )) )
        WorkbookStreamObject( *this, rxStrm, rSysFileName ).dump();
@@ -4562,13 +4562,13 @@ Dumper::Dumper( const FilterBase& rFilter )
    DumperBase::construct( xCfg );
}

Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
{
    if( rxFactory.is() && rxInStrm.is() )
    if( rxContext.is() && rxInStrm.is() )
    {
        StorageRef xStrg( new ::oox::ole::OleStorage( rxFactory, rxInStrm, true ) );
        StorageRef xStrg( new ::oox::ole::OleStorage( rxContext, rxInStrm, true ) );
        MediaDescriptor aMediaDesc;
        ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
        ConfigRef xCfg( new Config( DUMP_BIFF_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) );
        DumperBase::construct( xCfg );
    }
}
diff --git a/oox/source/dump/dumperbase.cxx b/oox/source/dump/dumperbase.cxx
index f7c6c61..eeca65e 100644
--- a/oox/source/dump/dumperbase.cxx
+++ b/oox/source/dump/dumperbase.cxx
@@ -29,14 +29,13 @@

#include <algorithm>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XTextInputStream.hpp>
#include <com/sun/star/io/XTextOutputStream.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <comphelper/docpasswordhelper.hxx>
#include <osl/file.hxx>
#include <rtl/math.hxx>
#include <rtl/tencinfo.h>
#include "oox/core/filterbase.hxx"
#include "oox/helper/binaryoutputstream.hxx"
#include "oox/helper/textinputstream.hxx"
@@ -112,20 +111,14 @@ OUString InputOutputHelper::getFileNameExtension( const OUString& rFileUrl )

// input streams --------------------------------------------------------------

Reference< XInputStream > InputOutputHelper::getXInputStream( BinaryInputStream& rStrm )
{
    if( BinaryXInputStream* pXStrm = dynamic_cast< BinaryXInputStream* >( &rStrm ) )
        return pXStrm->getXInputStream();
    return 0;
}

Reference< XInputStream > InputOutputHelper::openInputStream(
        const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName )
        const Reference< XComponentContext >& rxContext, const OUString& rFileName )
{
    Reference< XInputStream > xInStrm;
    if( rxFactory.is() ) try
    if( rxContext.is() ) try
    {
        Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
        xInStrm = xFileAccess->openFileRead( rFileName );
    }
    catch( Exception& )
@@ -134,38 +127,16 @@ Reference< XInputStream > InputOutputHelper::openInputStream(
    return xInStrm;
}

Reference< XTextInputStream > InputOutputHelper::openTextInputStream(
        const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rEncoding )
{
    Reference< XTextInputStream > xTextInStrm;
    if( rxFactory.is() && rxInStrm.is() ) try
    {
        Reference< XActiveDataSink > xDataSink( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW );
        xDataSink->setInputStream( rxInStrm );
        xTextInStrm.set( xDataSink, UNO_QUERY_THROW );
        xTextInStrm->setEncoding( rEncoding );
    }
    catch( Exception& )
    {
    }
    return xTextInStrm;
}

Reference< XTextInputStream > InputOutputHelper::openTextInputStream(
        const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding )
{
    return openTextInputStream( rxFactory, openInputStream( rxFactory, rFileName ), rEncoding );
}

// output streams -------------------------------------------------------------

Reference< XOutputStream > InputOutputHelper::openOutputStream(
        const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName )
        const Reference< XComponentContext >& rxContext, const OUString& rFileName )
{
    Reference< XOutputStream > xOutStrm;
    if( rxFactory.is() ) try
    if( rxContext.is() ) try
    {
        Reference< XSimpleFileAccess > xFileAccess( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
        xOutStrm = xFileAccess->openFileWrite( rFileName );
    }
    catch( Exception& )
@@ -175,15 +146,17 @@ Reference< XOutputStream > InputOutputHelper::openOutputStream(
}

Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream(
        const Reference< XMultiServiceFactory >& rxFactory, const Reference< XOutputStream >& rxOutStrm, const OUString& rEncoding )
        const Reference< XComponentContext >& rxContext, const Reference< XOutputStream >& rxOutStrm, rtl_TextEncoding eTextEnc )
{
    Reference< XTextOutputStream > xTextOutStrm;
    if( rxFactory.is() && rxOutStrm.is() ) try
    const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc );
    if( rxContext.is() && rxOutStrm.is() && pcCharset ) try
    {
        Reference< XActiveDataSource > xDataSource( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XActiveDataSource > xDataSource( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextOutputStream" ) ), UNO_QUERY_THROW );
        xDataSource->setOutputStream( rxOutStrm );
        xTextOutStrm.set( xDataSource, UNO_QUERY_THROW );
        xTextOutStrm->setEncoding( rEncoding );
        xTextOutStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
    }
    catch( Exception& )
    {
@@ -192,9 +165,9 @@ Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream(
}

Reference< XTextOutputStream > InputOutputHelper::openTextOutputStream(
        const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName, const OUString& rEncoding )
        const Reference< XComponentContext >& rxContext, const OUString& rFileName, rtl_TextEncoding eTextEnc )
{
    return openTextOutputStream( rxFactory, openOutputStream( rxFactory, rFileName ), rEncoding );
    return openTextOutputStream( rxContext, openOutputStream( rxContext, rFileName ), eTextEnc );
}

// ============================================================================
@@ -1531,9 +1504,9 @@ NameListRef NameListWrapper::getNameList( const Config& rCfg ) const
// ============================================================================

SharedConfigData::SharedConfigData( const OUString& rFileName,
        const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg,
        const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg,
        const OUString& rSysFileName, MediaDescriptor& rMediaDesc ) :
    mxFactory( rxFactory ),
    mxContext( rxContext ),
    mxRootStrg( rxRootStrg ),
    maSysFileName( rSysFileName ),
    mrMediaDesc( rMediaDesc ),
@@ -1600,7 +1573,7 @@ Sequence< NamedValue > SharedConfigData::requestEncryptionData( ::comphelper::ID

bool SharedConfigData::implIsValid() const
{
    return mbLoaded && mxFactory.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0);
    return mbLoaded && mxContext.is() && mxRootStrg.get() && (maSysFileName.getLength() > 0);
}

void SharedConfigData::implProcessConfigItemStr(
@@ -1629,9 +1602,8 @@ bool SharedConfigData::readConfigFile( const OUString& rFileUrl )
    bool bLoaded = maConfigFiles.count( rFileUrl ) > 0;
    if( !bLoaded )
    {
        Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxFactory, rFileUrl );
        BinaryXInputStream aInStrm( xInStrm, true );
        TextInputStream aTxtStrm( aInStrm, RTL_TEXTENCODING_UTF8 );
        Reference< XInputStream > xInStrm = InputOutputHelper::openInputStream( mxContext, rFileUrl );
        TextInputStream aTxtStrm( mxContext, xInStrm, RTL_TEXTENCODING_UTF8 );
        if( !aTxtStrm.isEof() )
        {
            maConfigFiles.insert( rFileUrl );
@@ -1698,9 +1670,9 @@ Config::Config( const sal_Char* pcEnvVar, const FilterBase& rFilter )
    construct( pcEnvVar, rFilter );
}

Config::Config( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
Config::Config( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
{
    construct( pcEnvVar, rxFactory, rxRootStrg, rSysFileName, rMediaDesc );
    construct( pcEnvVar, rxContext, rxRootStrg, rSysFileName, rMediaDesc );
}

Config::~Config()
@@ -1715,14 +1687,14 @@ void Config::construct( const Config& rParent )
void Config::construct( const sal_Char* pcEnvVar, const FilterBase& rFilter )
{
    if( rFilter.getFileUrl().getLength() > 0 )
        construct( pcEnvVar, rFilter.getServiceFactory(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() );
        construct( pcEnvVar, rFilter.getComponentContext(), rFilter.getStorage(), rFilter.getFileUrl(), rFilter.getMediaDescriptor() );
}

void Config::construct( const sal_Char* pcEnvVar, const Reference< XMultiServiceFactory >& rxFactory, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
void Config::construct( const sal_Char* pcEnvVar, const Reference< XComponentContext >& rxContext, const StorageRef& rxRootStrg, const OUString& rSysFileName, MediaDescriptor& rMediaDesc )
{
    if( pcEnvVar && rxRootStrg.get() && (rSysFileName.getLength() > 0) )
        if( const sal_Char* pcFileName = ::getenv( pcEnvVar ) )
            mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxFactory, rxRootStrg, rSysFileName, rMediaDesc ) );
            mxCfgData.reset( new SharedConfigData( OUString::createFromAscii( pcFileName ), rxContext, rxRootStrg, rSysFileName, rMediaDesc ) );
}

void Config::setStringOption( const String& rKey, const String& rData )
@@ -1795,14 +1767,16 @@ NameListRef Config::implGetNameList( const OUString& rListName ) const
// ============================================================================
// ============================================================================

Output::Output( const Reference< XTextOutputStream >& rxStrm )
Output::Output( const Reference< XComponentContext >& rxContext, const OUString& rFileName ) :
    mxStrm( InputOutputHelper::openTextOutputStream( rxContext, rFileName, RTL_TEXTENCODING_UTF8 ) ),
    mnCol( 0 ),
    mnItemLevel( 0 ),
    mnMultiLevel( 0 ),
    mnItemIdx( 0 ),
    mnLastItem( 0 )
{
    construct( rxStrm );
}

Output::Output( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rFileName )
{
    construct( InputOutputHelper::openTextOutputStream( rxFactory, rFileName, CREATE_OUSTRING( "UTF-8" ) ) );
    if( mxStrm.is() )
        mxStrm->writeString( OUString( OOX_DUMP_BOM ) );
}

// ----------------------------------------------------------------------------
@@ -2084,19 +2058,6 @@ void Output::writeRangeList( const RangeList& rRanges )

// ----------------------------------------------------------------------------

void Output::construct( const Reference< XTextOutputStream >& rxStrm )
{
    mxStrm = rxStrm;
    mnCol = mnItemLevel = mnMultiLevel = 0;
    mnItemIdx = 0;
    mnLastItem = 0;
    if( mxStrm.is() )
    {
        writeChar( OOX_DUMP_BOM );
        newLine();
    }
}

bool Output::implIsValid() const
{
    return mxStrm.is();
@@ -2240,7 +2201,8 @@ void StorageObjectBase::implDump()
    if( bIsRoot ) try
    {
        aSysOutPath += OOX_DUMP_DUMPEXT;
        Reference< XSimpleFileAccess > xFileAccess( getFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( getContext()->getServiceManager(), UNO_QUERY_THROW );
        Reference< XSimpleFileAccess > xFileAccess( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY_THROW );
        xFileAccess->kill( aSysOutPath );
    }
    catch( Exception& )
@@ -2259,7 +2221,7 @@ void StorageObjectBase::implDump()
    }
}

void StorageObjectBase::implDumpStream( const BinaryInputStreamRef&, const OUString&, const OUString&, const OUString& )
void StorageObjectBase::implDumpStream( const Reference< XInputStream >&, const OUString&, const OUString&, const OUString& )
{
}

@@ -2305,12 +2267,12 @@ void StorageObjectBase::extractStream( StorageBase& rStrg, const OUString& rStrg
    BinaryXInputStream aInStrm( rStrg.openInputStream( rStrmName ), true );
    if( !aInStrm.isEof() )
    {
        BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getFactory(), rSysFileName ), true );
        BinaryXOutputStream aOutStrm( InputOutputHelper::openOutputStream( getContext(), rSysFileName ), true );
        if( !aOutStrm.isEof() )
            aInStrm.copyToStream( aOutStrm );
    }
    BinaryXInputStreamRef xDumpStrm( new BinaryXInputStream( InputOutputHelper::openInputStream( getFactory(), rSysFileName ), true ) );
    if( !xDumpStrm->isEof() )
    Reference< XInputStream > xDumpStrm = InputOutputHelper::openInputStream( getContext(), rSysFileName );
    if( xDumpStrm.is() )
        implDumpStream( xDumpStrm, rStrgPath, rStrmName, rSysFileName );
}

@@ -2366,13 +2328,10 @@ void OutputObjectBase::construct( const ObjectBase& rParent, const OUString& rSy
{
    ObjectBase::construct( rParent );
    if( ObjectBase::implIsValid() )
        mxOut.reset( new Output( getFactory(), rSysFileName + OOX_DUMP_DUMPEXT ) );
}

void OutputObjectBase::construct( const ObjectBase& rParent, const OutputRef& rxOut )
{
    ObjectBase::construct( rParent );
    mxOut = rxOut;
    {
        maSysFileName = rSysFileName;
        mxOut.reset( new Output( getContext(), rSysFileName + OOX_DUMP_DUMPEXT ) );
    }
}

void OutputObjectBase::construct( const OutputObjectBase& rParent )
@@ -2551,12 +2510,6 @@ void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStr
    mxStrm = rxStrm;
}

void InputObjectBase::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OutputRef& rxOut )
{
    OutputObjectBase::construct( rParent, rxOut );
    mxStrm = rxStrm;
}

void InputObjectBase::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
{
    OutputObjectBase::construct( rParent );
@@ -2575,7 +2528,7 @@ bool InputObjectBase::implIsValid() const

void InputObjectBase::skipBlock( sal_Int64 nBytes, bool bShowSize )
{
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() );
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() );
    if( mxStrm->tell() < nEndPos )
    {
        if( bShowSize )
@@ -2595,8 +2548,8 @@ void InputObjectBase::dumpRawBinary( sal_Int64 nBytes, bool bShowOffset, bool bS
    sal_Int64 nMaxShowSize = cfg().getIntOption< sal_Int64 >(
        bStream ? "max-binary-stream-size" : "max-binary-data-size", SAL_MAX_INT64 );

    bool bSeekable = mxStrm->getLength() >= 0;
    sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->getLength() ) : 0;
    bool bSeekable = mxStrm->size() >= 0;
    sal_Int64 nEndPos = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nBytes, mxStrm->size() ) : 0;
    sal_Int64 nDumpEnd = bSeekable ? ::std::min< sal_Int64 >( mxStrm->tell() + nMaxShowSize, nEndPos ) : nMaxShowSize;
    sal_Int64 nPos = bSeekable ? mxStrm->tell() : 0;
    bool bLoop = true;
@@ -2671,12 +2624,12 @@ void InputObjectBase::dumpRemainingTo( sal_Int64 nPos )

void InputObjectBase::dumpRemainingStream()
{
    dumpRemainingTo( mxStrm->getLength() );
    dumpRemainingTo( mxStrm->size() );
}

void InputObjectBase::dumpArray( const String& rName, sal_Int32 nBytes, sal_Unicode cSep )
{
    sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nBytes );
    sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nBytes );
    if( nDumpSize > OOX_DUMP_MAXARRAY )
    {
        dumpBinary( rName, nBytes, false );
@@ -2712,7 +2665,7 @@ sal_Unicode InputObjectBase::dumpUnicode( const String& rName )

OUString InputObjectBase::dumpCharArray( const String& rName, sal_Int32 nLen, rtl_TextEncoding eTextEnc, bool bHideTrailingNul )
{
    sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->getLength() - mxStrm->tell(), 0, nLen );
    sal_Int32 nDumpSize = getLimitedValue< sal_Int32, sal_Int64 >( mxStrm->size() - mxStrm->tell(), 0, nLen );
    OUString aString;
    if( nDumpSize > 0 )
    {
@@ -2892,7 +2845,7 @@ BinaryStreamObject::BinaryStreamObject( const OutputObjectBase& rParent, const B
void BinaryStreamObject::dumpBinaryStream( bool bShowOffset )
{
    mxStrm->seekToStart();
    dumpRawBinary( mxStrm->getLength(), bShowOffset, true );
    dumpRawBinary( mxStrm->size(), bShowOffset, true );
    mxOut->emptyLine();
}

@@ -2902,42 +2855,70 @@ void BinaryStreamObject::implDump()
}

// ============================================================================
// ============================================================================

TextStreamObject::TextStreamObject( const ObjectBase& rParent,
void TextStreamObjectBase::construct( const ObjectBase& rParent,
        const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
{
    InputObjectBase::construct( rParent, rxStrm, rSysFileName );
    if( rxStrm.get() )
        mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) );
    constructTextStrmObj( eTextEnc );
}

TextStreamObject::TextStreamObject( const OutputObjectBase& rParent,
void TextStreamObjectBase::construct( const OutputObjectBase& rParent,
        const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
{
    InputObjectBase::construct( rParent, rxStrm );
    if( rxStrm.get() )
        mxTextStrm.reset( new TextInputStream( *rxStrm, eTextEnc ) );
    constructTextStrmObj( eTextEnc );
}

bool TextStreamObject::implIsValid() const
void TextStreamObjectBase::construct( const InputObjectBase& rParent, rtl_TextEncoding eTextEnc )
{
    InputObjectBase::construct( rParent );
    constructTextStrmObj( eTextEnc );
}

bool TextStreamObjectBase::implIsValid() const
{
    return InputObjectBase::implIsValid() && mxTextStrm.get();
}

void TextStreamObject::implDump()
void TextStreamObjectBase::implDump()
{
    OUString aLine;
    sal_uInt32 nLine = 0;
    while( !mxTextStrm->isEof() )
    {
        aLine = mxTextStrm->readLine();
        if( !mxTextStrm->isEof() )
            implDumpLine( aLine, ++nLine );
    }
    mxOut->emptyLine();
    implDumpText( *mxTextStrm );
}

void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )
void TextStreamObjectBase::constructTextStrmObj( rtl_TextEncoding eTextEnc )
{
    if( mxStrm.get() )
        mxTextStrm.reset( new TextInputStream( getContext(), *mxStrm, eTextEnc ) );
}

// ============================================================================

TextLineStreamObject::TextLineStreamObject( const ObjectBase& rParent,
        const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc, const OUString& rSysFileName )
{
    TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc, rSysFileName );
}

TextLineStreamObject::TextLineStreamObject( const OutputObjectBase& rParent,
        const BinaryInputStreamRef& rxStrm, rtl_TextEncoding eTextEnc )
{
    TextStreamObjectBase::construct( rParent, rxStrm, eTextEnc );
}

void TextLineStreamObject::implDumpText( TextInputStream& rTextStrm )
{
    sal_uInt32 nLine = 0;
    while( !rTextStrm.isEof() )
    {
        OUString aLine = rTextStrm.readLine();
        if( !rTextStrm.isEof() || (aLine.getLength() > 0) )
            implDumpLine( aLine, ++nLine );
    }
}

void TextLineStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )
{
    TableGuard aTabGuard( mxOut, 8 );
    mxOut->writeDec( nLine, 6 );
@@ -2948,111 +2929,94 @@ void TextStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 nLine )

// ============================================================================

XmlStreamObject::XmlStreamObject( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) :
    TextStreamObject( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName )
XmlStreamObject::XmlStreamObject( const ObjectBase& rParent,
        const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName )
{
    TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8, rSysFileName );
}

void XmlStreamObject::implDump()
XmlStreamObject::XmlStreamObject( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm )
{
    maIncompleteLine = OUString();
    TextStreamObject::implDump();
    if( maIncompleteLine.getLength() > 0 )
    {
        mxOut->resetIndent();
        mxOut->writeString( maIncompleteLine );
        mxOut->emptyLine();
        writeInfoItem( "stream-state", OOX_DUMP_ERR_STREAM );
    }
    TextStreamObjectBase::construct( rParent, rxStrm, RTL_TEXTENCODING_UTF8 );
}

void XmlStreamObject::implDumpLine( const OUString& rLine, sal_uInt32 )
void XmlStreamObject::implDumpText( TextInputStream& rTextStrm )
{
    // build input line from cached incomplete element and new text data
    OUStringBuffer aLine;
    if( maIncompleteLine.getLength() > 0 )
        aLine.append( maIncompleteLine ).append( sal_Unicode( ' ' ) );
    aLine.append( rLine );
    maIncompleteLine = OUString();
    /*  Buffers a start element and the following element text. Needed to dump
        matching start/end elements and the element text on the same line. */
    OUStringBuffer aOldStartElem;
    // special handling for VML
    bool bIsVml = InputOutputHelper::getFileNameExtension( maSysFileName ).equalsIgnoreAsciiCaseAscii( "vml" );

    if( aLine.getLength() == 0 )
    while( !rTextStrm.isEof() )
    {
        mxOut->newLine();
        return;
    }
        // get the next element and the following element text from text stream
        OUString aElem = rTextStrm.readToChar( '>', true ).trim();
        OUString aText = rTextStrm.readToChar( '<', false );

    const sal_Unicode* pcPos = aLine.getStr();
    const sal_Unicode* pcEnd = pcPos + aLine.getLength();
    while( pcPos < pcEnd )
    {
        OUStringBuffer aOutLine;
        bool bIsStartElement = false;
        bool bIsComplElement = false;
        bool bIsEndElement = false;

        /*  check for start element at beginning of the line - pcEnd and thus (pcPos+1)
            are dereferenceable, because OUStringBuffer::getStr is null-terminated. */
        if( (*pcPos == '<') && (pcPos[ 1 ] != '/') )
        // remove multiple whitespace from element
        sal_Int32 nPos = 0;
        while( nPos < aElem.getLength() )
        {
            const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' );
            if( pcElementEnd == pcEnd )
            while( (nPos < aElem.getLength()) && (aElem[ nPos ] >= 32) ) ++nPos;
            if( nPos < aElem.getLength() )
                aElem = OUStringBuffer( aElem.copy( 0, nPos ) ).append( sal_Unicode( ' ' ) ).append( aElem.copy( nPos ).trim() ).makeStringAndClear();
            ++nPos;
        }

        sal_Int32 nElemLen = aElem.getLength();
        if( (nElemLen >= 2) && (aElem[ 0 ] == '<') && (aElem[ nElemLen - 1 ] == '>') )
        {
            // determine type of the element
            bool bSimpleElem = (aElem[ 1 ] == '!') || (aElem[ 1 ] == '?') || (aElem[ nElemLen - 2 ] == '/') ||
                (bIsVml && (nElemLen == 4) && (aElem[ 1 ] == 'b') && (aElem[ 2 ] == 'r'));
            bool bStartElem = !bSimpleElem && (aElem[ 1 ] != '/');
            bool bEndElem = !bSimpleElem && !bStartElem;

            /*  Start element or simple element: flush old start element and
                its text from previous iteration, and start a new indentation
                level for the new element. Trim whitespace and line breaks from
                the text of the old start element. */
            if( (bSimpleElem || bStartElem) && (aOldStartElem.getLength() > 0) )
            {
                // incomplete start element
                maIncompleteLine = OUString( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) );
                pcPos = pcEnd;
                mxOut->writeString( aOldStartElem.makeStringAndClear().trim() );
                mxOut->newLine();
                mxOut->incIndent();
            }

            /*  Start element: remember it and its text, to be able to print the
                matching end element on the same line in the next iteration. */
            if( bStartElem )
            {
                aOldStartElem.append( aElem ).append( aText );
            }
            else
            {
                bIsComplElement = (pcPos[ 1 ] == '?') || (pcPos[ 1 ] == '!') || (pcElementEnd[ -1 ] == '/');
                bIsStartElement = !bIsComplElement;
                ++pcElementEnd;
                aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) );
                pcPos = pcElementEnd;
            }
        }
                /*  End element: if a start element has been remembered in the
                    previous iteration, write it out here untrimmed, to show
                    all whitespace in the element text, and without trailing
                    line break. Code below will add the end element right after
                    it. Otherwise, return to previous indentation level. */
                if( bEndElem )
                {
                    if( aOldStartElem.getLength() == 0 )
                        mxOut->decIndent();
                    else
                        mxOut->writeString( aOldStartElem.makeStringAndClear() );
                }

        // check for following element text
        if( !bIsComplElement && (pcPos < pcEnd) )
        {
            const sal_Unicode* pcElementStart = ::std::find( pcPos, pcEnd, '<' );
            // append text between elements
            if( pcPos < pcElementStart )
            {
                OUString aText( pcPos, static_cast< sal_Int32 >( pcElementStart - pcPos ) );
                /*  Write the element. Write following element text in a new
                    line, but only, if it does not contain of white space
                    entirely. */
                mxOut->writeString( aElem );
                mxOut->newLine();
                if( aText.trim().getLength() > 0 )
                    aOutLine.append( aText );
                pcPos = pcElementStart;
                {
                    mxOut->writeString( aText );
                    mxOut->newLine();
                }
            }
        }

        // check for stand-alone or following end element
        if( !bIsComplElement && (pcPos < pcEnd) && (pcPos[ 1 ] == '/') )
        {
            const sal_Unicode* pcElementEnd = ::std::find( pcPos, pcEnd, '>' );
            if( pcElementEnd == pcEnd )
            {
                // incomplete end element
                aOutLine.append( pcPos, static_cast< sal_Int32 >( pcEnd - pcPos ) );
                maIncompleteLine = aOutLine.makeStringAndClear();
                pcPos = pcEnd;
            }
            else
            {
                bIsEndElement = true;
                ++pcElementEnd;
                aOutLine.append( pcPos, static_cast< sal_Int32 >( pcElementEnd - pcPos ) );
                pcPos = pcElementEnd;
            }
        }

        // flush output line
        if( maIncompleteLine.getLength() == 0 )
        {
            if( !bIsStartElement && bIsEndElement ) mxOut->decIndent();
            mxOut->writeString( aOutLine.makeStringAndClear() );
            mxOut->newLine();
            if( bIsStartElement && !bIsEndElement ) mxOut->incIndent();
        }
    }
}

@@ -3167,7 +3131,7 @@ bool SequenceRecordObjectBase::implStartRecord( BinaryInputStream& rBaseStrm, sa
    {
        ornRecPos = rBaseStrm.tell();
        // do not try to overread seekable streams, may cause assertions
        bValid = ornRecPos < rBaseStrm.getLength();
        bValid = ornRecPos < rBaseStrm.size();
    }

    // read the record header
diff --git a/oox/source/dump/oledumper.cxx b/oox/source/dump/oledumper.cxx
index bd2a0e0..e0135af 100644
--- a/oox/source/dump/oledumper.cxx
+++ b/oox/source/dump/oledumper.cxx
@@ -469,9 +469,9 @@ void OlePropertyStreamObject::dumpCodePageProperty( sal_uInt32 nStartPos )
        if( nType == OLEPROP_TYPE_INT16 )
        {
            sal_uInt16 nCodePage = dumpDec< sal_uInt16 >( "codepage", "CODEPAGES" );
            rtl_TextEncoding nNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
            if( nNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
                meTextEnc = nNewTextEnc;
            rtl_TextEncoding eNewTextEnc = rtl_getTextEncodingFromWindowsCodePage( nCodePage );
            if( eNewTextEnc != RTL_TEXTENCODING_DONTKNOW )
                meTextEnc = eNewTextEnc;
            mbIsUnicode = nCodePage == CODEPAGE_UNICODE;
        }
        else
@@ -586,15 +586,8 @@ OUString OlePropertyStreamObject::dumpString8( const String& rName )

OUString OlePropertyStreamObject::dumpCharArray8( const String& rName, sal_Int32 nLen )
{
    OUString aData;
    size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 );
    if( nNewLen > 0 )
    {
        ::std::vector< sal_Char > aBuffer( nNewLen + 1 );
        mxStrm->readMemory( &aBuffer.front(), nNewLen );
        aBuffer[ nNewLen ] = 0;
        aData = OStringToOUString( OString( &aBuffer.front() ), meTextEnc );
    }
    sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 );
    OUString aData = mxStrm->readCharArrayUC( nNewLen, meTextEnc );
    writeStringItem( rName, aData );
    return aData;
}
@@ -607,13 +600,8 @@ OUString OlePropertyStreamObject::dumpString16( const String& rName )

OUString OlePropertyStreamObject::dumpCharArray16( const String& rName, sal_Int32 nLen )
{
    size_t nNewLen = getLimitedValue< size_t, sal_Int32 >( nLen, 0, 1024 );
    ::std::vector< sal_Unicode > aBuffer;
    aBuffer.reserve( nNewLen + 1 );
    for( size_t nIdx = 0; nIdx < nNewLen; ++nIdx )
        aBuffer.push_back( static_cast< sal_Unicode >( mxStrm->readuInt16() ) );
    aBuffer.push_back( 0 );
    OUString aData( &aBuffer.front() );
    sal_Int32 nNewLen = getLimitedValue< sal_Int32, sal_Int32 >( nLen, 0, 1024 );
    OUString aData = mxStrm->readUnicodeArray( nNewLen );
    writeStringItem( rName, aData );
    if( nNewLen & 1 ) dumpUnused( 2 ); // always padding to 32bit
    return aData;
@@ -687,7 +675,7 @@ void OleStorageObject::construct( const ObjectBase& rParent )
    StorageObjectBase::construct( rParent );
}

void OleStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName )
void OleStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& /*rStrgPath*/, const OUString& rStrmName, const OUString& rSysFileName )
{
    if( rStrmName.equalsAscii( "\001CompObj" ) )
        OleCompObjObject( *this, rxStrm, rSysFileName ).dump();
@@ -1926,7 +1914,7 @@ void VbaFStreamObject::dumpSiteData()
        sal_uInt32 nSiteCount = dumpDec< sal_uInt32 >( "site-count" );
        sal_uInt32 nSiteLength = dumpDec< sal_uInt32 >( "site-data-size" );
        sal_Int64 nEndPos = mxStrm->tell() + nSiteLength;
        if( ensureValid( nEndPos <= mxStrm->getLength() ) )
        if( ensureValid( nEndPos <= mxStrm->size() ) )
        {
            mxOut->resetItemIndex();
            sal_uInt32 nSiteIdx = 0;
@@ -1984,7 +1972,7 @@ void VbaOStreamObject::implDump()
            writeDecItem( "control-id", aIt->mnId );
            writeInfoItem( "prog-id", aIt->maProgId );
            IndentGuard aIndGuard( mxOut );
            RelativeInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) );
            BinaryInputStreamRef xRelStrm( new RelativeInputStream( *mxStrm, aIt->mnLength ) );
            FormControlStreamObject( *this, xRelStrm, &aIt->maProgId ).dump();
        }
    }
@@ -2068,7 +2056,7 @@ VbaContainerStorageObject::VbaContainerStorageObject( const ObjectBase& rParent,
    addPreferredStream( "f" );
}

void VbaContainerStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void VbaContainerStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    if( rStrmName.equalsAscii( "f" ) )
        VbaFStreamObject( *this, rxStrm, rSysFileName, maFormData ).dump();
@@ -2280,7 +2268,7 @@ void VbaModuleStreamObject::implDump()
    writeEmptyItem( "source-code" );
    IndentGuard aIndGuard( mxOut );
    BinaryInputStreamRef xVbaStrm( new ::oox::ole::VbaInputStream( *mxStrm ) );
    TextStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump();
    TextLineStreamObject( *this, xVbaStrm, mrVbaData.meTextEnc ).dump();
}

// ============================================================================
@@ -2292,7 +2280,7 @@ VbaStorageObject::VbaStorageObject( const ObjectBase& rParent, const StorageRef&
    addPreferredStream( "dir" );
}

void VbaStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void VbaStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "dir" ) )
        VbaDirStreamObject( *this, rxStrm, rSysFileName, mrVbaData ).dump();
@@ -2310,10 +2298,10 @@ VbaFormStorageObject::VbaFormStorageObject( const ObjectBase& rParent, const Sto
{
}

void VbaFormStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void VbaFormStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    if( rStrmName.equalsAscii( "\003VBFrame" ) )
        TextStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump();
        TextLineStreamObject( *this, rxStrm, mrVbaData.meTextEnc, rSysFileName ).dump();
    else
        VbaContainerStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
}
@@ -2326,10 +2314,10 @@ VbaProjectStorageObject::VbaProjectStorageObject( const ObjectBase& rParent, con
    addPreferredStorage( "VBA" );
}

void VbaProjectStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void VbaProjectStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    if( (rStrgPath.getLength() == 0) && rStrmName.equalsAscii( "PROJECT" ) )
        TextStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump();
        TextLineStreamObject( *this, rxStrm, maVbaData.meTextEnc, rSysFileName ).dump();
    else
        OleStorageObject::implDumpStream( rxStrm, rStrgPath, rStrmName, rSysFileName );
}
diff --git a/oox/source/dump/pptxdumper.cxx b/oox/source/dump/pptxdumper.cxx
index 39e0ccc..c98ffac 100644
--- a/oox/source/dump/pptxdumper.cxx
+++ b/oox/source/dump/pptxdumper.cxx
@@ -56,14 +56,13 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent )
    StorageObjectBase::construct( rParent );
}

void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName );
    Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm );
    if( aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "potx" ) )
    {
        Dumper( getFactory(), xInStrm, rSysFileName ).dump();
        Dumper( getContext(), rxStrm, rSysFileName ).dump();
    }
    else if(
        aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) ||
@@ -72,7 +71,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
        aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) )
    {
        ::oox::dump::xlsb::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
        ::oox::dump::xlsb::Dumper( getContext(), rxStrm, rSysFileName ).dump();
    }
    else if(
        aExt.equalsIgnoreAsciiCaseAscii( "xla" ) ||
@@ -82,7 +81,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
        aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) )
    {
        ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
        ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump();
    }
    else if(
        aExt.equalsIgnoreAsciiCaseAscii( "xml" ) ||
@@ -95,17 +94,17 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
    {
        if( rStrgPath.equalsAscii( "ppt" ) && rStrmName.equalsAscii( "vbaProject.bin" ) )
        {
            StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
            StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) );
            VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump();
        }
        else if( rStrgPath.equalsAscii( "ppt/embeddings" ) )
        {
            StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
            StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) );
            OleStorageObject( *this, xStrg, rSysFileName ).dump();
        }
        else if( rStrgPath.equalsAscii( "ppt/activeX" ) )
        {
            StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) );
            StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) );
            ActiveXStorageObject( *this, xStrg, rSysFileName ).dump();
        }
        else
@@ -125,13 +124,13 @@ Dumper::Dumper( const FilterBase& rFilter )
    DumperBase::construct( xCfg );
}

Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
{
    if( rxFactory.is() && rxInStrm.is() )
    if( rxContext.is() && rxInStrm.is() )
    {
        StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) );
        StorageRef xStrg( new ZipStorage( rxContext, rxInStrm ) );
        MediaDescriptor aMediaDesc;
        ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
        ConfigRef xCfg( new Config( DUMP_PPTX_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) );
        DumperBase::construct( xCfg );
    }
}
diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx
index 3dc2974..a5ffab0 100644
--- a/oox/source/dump/xlsbdumper.cxx
+++ b/oox/source/dump/xlsbdumper.cxx
@@ -368,7 +368,7 @@ void FormulaObject::implDump()
    if( mnSize < 0 ) return;

    sal_Int64 nStartPos = mxStrm->tell();
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->getLength() );
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( nStartPos + mnSize, mxStrm->size() );

    bool bValid = mxTokens.get();
    mxStack.reset( new FormulaStack );
@@ -889,8 +889,8 @@ bool FormulaObject::dumpAttrToken()
void FormulaObject::dumpAddTokenData()
{
    mxOut->resetItemIndex();
    sal_Int32 nAddDataSize = (mxStrm->getLength() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0;
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->getLength() );
    sal_Int32 nAddDataSize = (mxStrm->size() - mxStrm->tell() >= 4) ? dumpDec< sal_Int32 >( "add-data-size" ) : 0;
    sal_Int64 nEndPos = ::std::min< sal_Int64 >( mxStrm->tell() + nAddDataSize, mxStrm->size() );
    for( AddDataTypeVec::const_iterator aIt = maAddData.begin(), aEnd = maAddData.end(); (aIt != aEnd) && !mxStrm->isEof() && (mxStrm->tell() < nEndPos); ++aIt )
    {
        AddDataType eType = *aIt;
@@ -2231,10 +2231,9 @@ RootStorageObject::RootStorageObject( const DumperBase& rParent )
    StorageObjectBase::construct( rParent );
}

void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
void RootStorageObject::implDumpStream( const Reference< XInputStream >& rxStrm, const OUString& rStrgPath, const OUString& rStrmName, const OUString& rSysFileName )
{
    OUString aExt = InputOutputHelper::getFileNameExtension( rStrmName );
    Reference< XInputStream > xInStrm = InputOutputHelper::getXInputStream( *rxStrm );
    if(
        aExt.equalsIgnoreAsciiCaseAscii( "xlsb" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "xlsm" ) ||
@@ -2242,7 +2241,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
        aExt.equalsIgnoreAsciiCaseAscii( "xltm" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "xltx" ) )
    {
        Dumper( getFactory(), xInStrm, rSysFileName ).dump();
        Dumper( getContext(), rxStrm, rSysFileName ).dump();
    }
    else if(
        aExt.equalsIgnoreAsciiCaseAscii( "xla" ) ||
@@ -2252,13 +2251,13 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
        aExt.equalsIgnoreAsciiCaseAscii( "xlt" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "xlw" ) )
    {
        ::oox::dump::biff::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
        ::oox::dump::biff::Dumper( getContext(), rxStrm, rSysFileName ).dump();
    }
    else if(
        aExt.equalsIgnoreAsciiCaseAscii( "pptx" ) ||
        aExt.equalsIgnoreAsciiCaseAscii( "potx" ) )
    {
        ::oox::dump::pptx::Dumper( getFactory(), xInStrm, rSysFileName ).dump();
        ::oox::dump::pptx::Dumper( getContext(), rxStrm, rSysFileName ).dump();
    }
    else if(
        aExt.equalsIgnoreAsciiCaseAscii( "xml" ) ||
@@ -2271,12 +2270,12 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
    {
        if( rStrgPath.equalsAscii( "xl" ) && rStrmName.equalsAscii( "vbaProject.bin" ) )
        {
            StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
            StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) );
            VbaProjectStorageObject( *this, xStrg, rSysFileName ).dump();
        }
        else if( rStrgPath.equalsAscii( "xl/embeddings" ) )
        {
            StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, false ) );
            StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, false ) );
            OleStorageObject( *this, xStrg, rSysFileName ).dump();
        }
        else if(
@@ -2295,7 +2294,7 @@ void RootStorageObject::implDumpStream( const BinaryInputStreamRef& rxStrm, cons
        }
        else if( rStrgPath.equalsAscii( "xl/activeX" ) )
        {
            StorageRef xStrg( new ::oox::ole::OleStorage( getFactory(), xInStrm, true ) );
            StorageRef xStrg( new ::oox::ole::OleStorage( getContext(), rxStrm, true ) );
            ActiveXStorageObject( *this, xStrg, rSysFileName ).dump();
        }
        else
@@ -2315,13 +2314,13 @@ Dumper::Dumper( const FilterBase& rFilter )
    DumperBase::construct( xCfg );
}

Dumper::Dumper( const Reference< XMultiServiceFactory >& rxFactory, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
Dumper::Dumper( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, const OUString& rSysFileName )
{
    if( rxFactory.is() && rxInStrm.is() )
    if( rxContext.is() && rxInStrm.is() )
    {
        StorageRef xStrg( new ZipStorage( rxFactory, rxInStrm ) );
        StorageRef xStrg( new ZipStorage( getContext(), rxInStrm ) );
        MediaDescriptor aMediaDesc;
        ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxFactory, xStrg, rSysFileName, aMediaDesc ) );
        ConfigRef xCfg( new Config( DUMP_XLSB_CONFIG_ENVVAR, rxContext, xStrg, rSysFileName, aMediaDesc ) );
        DumperBase::construct( xCfg );
    }
}
diff --git a/oox/source/helper/binaryinputstream.cxx b/oox/source/helper/binaryinputstream.cxx
index 2d547cd..e610006 100644
--- a/oox/source/helper/binaryinputstream.cxx
+++ b/oox/source/helper/binaryinputstream.cxx
@@ -27,6 +27,8 @@

#include "oox/helper/binaryinputstream.hxx"

#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <string.h>
#include <vector>
#include <rtl/strbuf.hxx>
@@ -80,11 +82,16 @@ OString BinaryInputStream::readCharArray( sal_Int32 nChars, bool bAllowNulChars 
    if( nChars <= 0 )
        return OString();

    ::std::vector< sal_Char > aBuffer( static_cast< size_t >( nChars ) );
    size_t nCharsRead = static_cast< size_t >( readMemory( &aBuffer.front(), nChars ) );
    ::std::vector< sal_uInt8 > aBuffer;
    sal_Int32 nCharsRead = readArray( aBuffer, nChars );
    if( nCharsRead <= 0 )
        return OString();

    aBuffer.resize( static_cast< size_t >( nCharsRead ) );
    if( !bAllowNulChars )
        ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' );
    return OString( &aBuffer.front(), nCharsRead );
        ::std::replace( aBuffer.begin(), aBuffer.end(), '\0', '?' );

    return OString( reinterpret_cast< sal_Char* >( &aBuffer.front() ), nCharsRead );
}

OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding eTextEnc, bool bAllowNulChars )
@@ -94,30 +101,44 @@ OUString BinaryInputStream::readCharArrayUC( sal_Int32 nChars, rtl_TextEncoding 

OUString BinaryInputStream::readUnicodeArray( sal_Int32 nChars, bool bAllowNulChars )
{
    OUStringBuffer aBuffer;
    if( nChars > 0 )
    {
        aBuffer.ensureCapacity( nChars );
        sal_uInt16 nChar;
        for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx )
        {
            readValue( nChar );
            aBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) );
        }
    }
    return aBuffer.makeStringAndClear();
    if( nChars <= 0 )
        return OUString();

    ::std::vector< sal_uInt16 > aBuffer;
    sal_Int32 nCharsRead = readArray( aBuffer, nChars );
    if( nCharsRead <= 0 )
        return OUString();

    aBuffer.resize( static_cast< size_t >( nCharsRead ) );
    if( !bAllowNulChars )
        ::std::replace( aBuffer.begin(), aBuffer.begin() + nCharsRead, '\0', '?' );

    OUStringBuffer aStringBuffer;
    aStringBuffer.ensureCapacity( nCharsRead );
    for( ::std::vector< sal_uInt16 >::iterator aIt = aBuffer.begin(), aEnd = aBuffer.end(); aIt != aEnd; ++aIt )
        aStringBuffer.append( static_cast< sal_Unicode >( *aIt ) );
    return aStringBuffer.makeStringAndClear();
}

void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes )
OUString BinaryInputStream::readCompressedUnicodeArray( sal_Int32 nChars, bool bCompressed, bool bAllowNulChars )
{
    return bCompressed ?
         // ISO-8859-1 maps all byte values 0xHH to the same Unicode code point U+00HH
        readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1, bAllowNulChars ) :
        readUnicodeArray( nChars, bAllowNulChars );
}

void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nBytes, sal_Int32 nAtomSize )
{
    if( nBytes > 0 )
    {
        sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, INPUTSTREAM_BUFFERSIZE );
        // make buffer size a multiple of the passed atom size
        sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, (INPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize );
        StreamDataSequence aBuffer( nBufferSize );
        while( nBytes > 0 )
        {
            sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, nBufferSize );
            sal_Int32 nBytesRead = readData( aBuffer, nReadSize );
            sal_Int32 nBytesRead = readData( aBuffer, nReadSize, nAtomSize );
            rOutStrm.writeData( aBuffer );
            if( nReadSize == nBytesRead )
                nBytes -= nReadSize;
@@ -127,14 +148,10 @@ void BinaryInputStream::copyToStream( BinaryOutputStream& rOutStrm, sal_Int64 nB
    }
}

void BinaryInputStream::readAtom( void* opMem, sal_uInt8 nSize )
{
    readMemory( opMem, nSize );
}

// ============================================================================

BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStrm, bool bAutoClose ) :
    BinaryStreamBase( Reference< XSeekable >( rxInStrm, UNO_QUERY ).is() ),
    BinaryXSeekableStream( Reference< XSeekable >( rxInStrm, UNO_QUERY ) ),
    maBuffer( INPUTSTREAM_BUFFERSIZE ),
    mxInStrm( rxInStrm ),
@@ -145,16 +162,29 @@ BinaryXInputStream::BinaryXInputStream( const Reference< XInputStream >& rxInStr

BinaryXInputStream::~BinaryXInputStream()
{
    if( mbAutoClose )
        close();
    close();
}

sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
void BinaryXInputStream::close()
{
    OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::close - invalid call" );
    if( mbAutoClose && mxInStrm.is() ) try
    {
        mxInStrm->closeInput();
    }
    catch( Exception& )
    {
        OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" );
    }
    mxInStrm.clear();
    BinaryXSeekableStream::close();
}

sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    sal_Int32 nRet = 0;
    if( !mbEof && (nBytes > 0) ) try
    {
        OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::readData - invalid call" );
        nRet = mxInStrm->readBytes( orData, nBytes );
        mbEof = nRet != nBytes;
    }
@@ -165,7 +195,7 @@ sal_Int32 BinaryXInputStream::readData( StreamDataSequence& orData, sal_Int32 nB
    return nRet;
}

sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes )
sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nRet = 0;
    if( !mbEof && (nBytes > 0) )
@@ -175,7 +205,7 @@ sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes )
        while( !mbEof && (nBytes > 0) )
        {
            sal_Int32 nReadSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize );
            sal_Int32 nBytesRead = readData( maBuffer, nReadSize );
            sal_Int32 nBytesRead = readData( maBuffer, nReadSize, nAtomSize );
            if( nBytesRead > 0 )
                memcpy( opnMem, maBuffer.getConstArray(), static_cast< size_t >( nBytesRead ) );
            opnMem += nBytesRead;
@@ -186,11 +216,10 @@ sal_Int32 BinaryXInputStream::readMemory( void* opMem, sal_Int32 nBytes )
    return nRet;
}

void BinaryXInputStream::skip( sal_Int32 nBytes )
void BinaryXInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    if( !mbEof ) try
    {
        OSL_ENSURE( mxInStrm.is(), "BinaryXInputStream::skip - invalid call" );
        mxInStrm->skipBytes( nBytes );
    }
    catch( Exception& )
@@ -199,60 +228,48 @@ void BinaryXInputStream::skip( sal_Int32 nBytes )
    }
}

void BinaryXInputStream::close()
{
    if( mxInStrm.is() ) try
    {
        mxInStrm->closeInput();
        mxInStrm.clear();
    }
    catch( Exception& )
    {
        OSL_ENSURE( false, "BinaryXInputStream::close - closing input stream failed" );
    }
}

// ============================================================================

SequenceInputStream::SequenceInputStream( const StreamDataSequence& rData ) :
    BinaryStreamBase( true ),
    SequenceSeekableStream( rData )
{
}

sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
sal_Int32 SequenceInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    sal_Int32 nReadBytes = 0;
    if( !mbEof )
    {
        nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos );
        nReadBytes = getMaxBytes( nBytes );
        orData.realloc( nReadBytes );
        if( nReadBytes > 0 )
            memcpy( orData.getArray(), mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) );
            memcpy( orData.getArray(), mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) );
        mnPos += nReadBytes;
        mbEof = nReadBytes < nBytes;
    }
    return nReadBytes;
}

sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes )
sal_Int32 SequenceInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    sal_Int32 nReadBytes = 0;
    if( !mbEof )
    {
        nReadBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos );
        nReadBytes = getMaxBytes( nBytes );
        if( nReadBytes > 0 )
            memcpy( opMem, mrData.getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) );
            memcpy( opMem, mpData->getConstArray() + mnPos, static_cast< size_t >( nReadBytes ) );
        mnPos += nReadBytes;
        mbEof = nReadBytes < nBytes;
    }
    return nReadBytes;
}

void SequenceInputStream::skip( sal_Int32 nBytes )
void SequenceInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    if( !mbEof )
    {
        sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, mrData.getLength() - mnPos );
        sal_Int32 nSkipBytes = getMaxBytes( nBytes );
        mnPos += nSkipBytes;
        mbEof = nSkipBytes < nBytes;
    }
@@ -260,73 +277,75 @@ void SequenceInputStream::skip( sal_Int32 nBytes )

// ============================================================================

RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nLength ) :
    mrInStrm( rInStrm ),
RelativeInputStream::RelativeInputStream( BinaryInputStream& rInStrm, sal_Int64 nSize ) :
    BinaryStreamBase( rInStrm.isSeekable() ),
    mpInStrm( &rInStrm ),
    mnStartPos( rInStrm.tell() ),
    mnRelPos( 0 )
{
    sal_Int64 nRemaining = rInStrm.getRemaining();
    mnLength = (nRemaining >= 0) ? ::std::min( nLength, nRemaining ) : nLength;
    mbEof = mnLength < 0;
    mnSize = (nRemaining >= 0) ? ::std::min( nSize, nRemaining ) : nSize;
    mbEof = mbEof || rInStrm.isEof() || (mnSize < 0);
}

bool RelativeInputStream::isSeekable() const
sal_Int64 RelativeInputStream::size() const
{
    return mrInStrm.isSeekable();
}

sal_Int64 RelativeInputStream::getLength() const
{
    return mnLength;
    return mpInStrm ? mnSize : -1;
}

sal_Int64 RelativeInputStream::tell() const
{
    return mnRelPos;
    return mpInStrm ? mnRelPos : -1;
}

void RelativeInputStream::seek( sal_Int64 nPos )
{
    if( mrInStrm.isSeekable() && (mnStartPos >= 0) )
    if( mpInStrm && isSeekable() && (mnStartPos >= 0) )
    {
        mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnLength );
        mrInStrm.seek( mnStartPos + mnRelPos );
        mbEof = (mnRelPos != nPos) || mrInStrm.isEof();
        mnRelPos = getLimitedValue< sal_Int64, sal_Int64 >( nPos, 0, mnSize );
        mpInStrm->seek( mnStartPos + mnRelPos );
        mbEof = (mnRelPos != nPos) || mpInStrm->isEof();
    }
}

sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
void RelativeInputStream::close()
{
    mpInStrm = 0;
    mbEof = true;
}

sal_Int32 RelativeInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nReadBytes = 0;
    if( !mbEof )
    {
        sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos );
        nReadBytes = mrInStrm.readData( orData, nRealBytes );
        sal_Int32 nMaxBytes = getMaxBytes( nBytes );
        nReadBytes = mpInStrm->readData( orData, nMaxBytes, nAtomSize );
        mnRelPos += nReadBytes;
        mbEof = (nRealBytes < nBytes) || mrInStrm.isEof();
        mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof();
    }
    return nReadBytes;
}

sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes )
sal_Int32 RelativeInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nReadBytes = 0;
    if( !mbEof )
    {
        sal_Int32 nRealBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos );
        nReadBytes = mrInStrm.readMemory( opMem, nRealBytes );
        sal_Int32 nMaxBytes = getMaxBytes( nBytes );
        nReadBytes = mpInStrm->readMemory( opMem, nMaxBytes, nAtomSize );
        mnRelPos += nReadBytes;
        mbEof = (nRealBytes < nBytes) || mrInStrm.isEof();
        mbEof = (nMaxBytes < nBytes) || mpInStrm->isEof();
    }
    return nReadBytes;
}

void RelativeInputStream::skip( sal_Int32 nBytes )
void RelativeInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
{
    if( !mbEof )
    {
        sal_Int32 nSkipBytes = getLimitedValue< sal_Int32, sal_Int64 >( nBytes, 0, mnLength - mnRelPos );
        mrInStrm.skip( nSkipBytes );
        sal_Int32 nSkipBytes = getMaxBytes( nBytes );
        mpInStrm->skip( nSkipBytes, nAtomSize );
        mnRelPos += nSkipBytes;
        mbEof = nSkipBytes < nBytes;
    }
diff --git a/oox/source/helper/binaryoutputstream.cxx b/oox/source/helper/binaryoutputstream.cxx
index f4ea937..1ae7b15 100644
--- a/oox/source/helper/binaryoutputstream.cxx
+++ b/oox/source/helper/binaryoutputstream.cxx
@@ -27,6 +27,8 @@

#include "oox/helper/binaryoutputstream.hxx"

#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <osl/diagnose.h>
#include <string.h>

@@ -45,14 +47,8 @@ const sal_Int32 OUTPUTSTREAM_BUFFERSIZE     = 0x8000;

// ============================================================================

void BinaryOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize )
{
    writeMemory( pMem, nSize );
}

// ============================================================================

BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOutStrm, bool bAutoClose ) :
    BinaryStreamBase( Reference< XSeekable >( rxOutStrm, UNO_QUERY ).is() ),
    BinaryXSeekableStream( Reference< XSeekable >( rxOutStrm, UNO_QUERY ) ),
    maBuffer( OUTPUTSTREAM_BUFFERSIZE ),
    mxOutStrm( rxOutStrm ),
@@ -63,15 +59,30 @@ BinaryXOutputStream::BinaryXOutputStream( const Reference< XOutputStream >& rxOu

BinaryXOutputStream::~BinaryXOutputStream()
{
    if( mbAutoClose )
        close();
    close();
}

void BinaryXOutputStream::writeData( const StreamDataSequence& rData )
void BinaryXOutputStream::close()
{
    try
    OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::close - invalid call" );
    if( mxOutStrm.is() ) try
    {
        OSL_ENSURE( mxOutStrm.is(), "BinaryXOutputStream::writeData - invalid call" );
        mxOutStrm->flush();
        if( mbAutoClose )
            mxOutStrm->closeOutput();
    }
    catch( Exception& )
    {
        OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" );
    }
    mxOutStrm.clear();
    BinaryXSeekableStream::close();
}

void BinaryXOutputStream::writeData( const StreamDataSequence& rData, size_t /*nAtomSize*/ )
{
    if( mxOutStrm.is() ) try
    {
        mxOutStrm->writeBytes( rData );
    }
    catch( Exception& )
@@ -80,57 +91,45 @@ void BinaryXOutputStream::writeData( const StreamDataSequence& rData )
    }
}

void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
void BinaryXOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize )
{
    if( nBytes > 0 )
    if( mxOutStrm.is() && (nBytes > 0) )
    {
        sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, OUTPUTSTREAM_BUFFERSIZE );
        sal_Int32 nBufferSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, (OUTPUTSTREAM_BUFFERSIZE / nAtomSize) * nAtomSize );
        const sal_uInt8* pnMem = reinterpret_cast< const sal_uInt8* >( pMem );
        while( nBytes > 0 )
        {
            sal_Int32 nWriteSize = getLimitedValue< sal_Int32, sal_Int32 >( nBytes, 0, nBufferSize );
            maBuffer.realloc( nWriteSize );
            memcpy( maBuffer.getArray(), pnMem, static_cast< size_t >( nWriteSize ) );
            writeData( maBuffer );
            writeData( maBuffer, nAtomSize );
            pnMem += nWriteSize;
            nBytes -= nWriteSize;
        }
    }
}

void BinaryXOutputStream::close()
{
    if( mxOutStrm.is() ) try
    {
        mxOutStrm->flush();
        mxOutStrm->closeOutput();
    }
    catch( Exception& )
    {
        OSL_ENSURE( false, "BinaryXOutputStream::close - closing output stream failed" );
    }
}

// ============================================================================

SequenceOutputStream::SequenceOutputStream( StreamDataSequence& rData ) :
    BinaryStreamBase( true ),
    SequenceSeekableStream( rData )
{
}

void SequenceOutputStream::writeData( const StreamDataSequence& rData )
void SequenceOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize )
{
    if( rData.hasElements() )
        writeMemory( rData.getConstArray(), rData.getLength() );
    if( mpData && rData.hasElements() )
        writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize );
}

void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
void SequenceOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    if( nBytes > 0 )
    if( mpData && (nBytes > 0) )
    {
        if( mrData.getLength() - mnPos < nBytes )
            const_cast< StreamDataSequence& >( mrData ).realloc( mnPos + nBytes );
        memcpy( const_cast< StreamDataSequence& >( mrData ).getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) );
        if( mpData->getLength() - mnPos < nBytes )
            const_cast< StreamDataSequence* >( mpData )->realloc( mnPos + nBytes );
        memcpy( const_cast< StreamDataSequence* >( mpData )->getArray() + mnPos, pMem, static_cast< size_t >( nBytes ) );
        mnPos += nBytes;
    }
}
diff --git a/oox/source/helper/binarystreambase.cxx b/oox/source/helper/binarystreambase.cxx
index d1e1185..f189a37 100644
--- a/oox/source/helper/binarystreambase.cxx
+++ b/oox/source/helper/binarystreambase.cxx
@@ -27,6 +27,7 @@

#include "oox/helper/binarystreambase.hxx"

#include <com/sun/star/io/XSeekable.hpp>
#include <osl/diagnose.h>

namespace oox {
@@ -42,30 +43,11 @@ BinaryStreamBase::~BinaryStreamBase()
{
}

bool BinaryStreamBase::isSeekable() const
{
    return false;
}

sal_Int64 BinaryStreamBase::getLength() const
{
    return -1;
}

sal_Int64 BinaryStreamBase::tell() const
{
    return -1;
}

void BinaryStreamBase::seek( sal_Int64 )
{
}

sal_Int64 BinaryStreamBase::getRemaining() const
{
    // do not use isSeekable(), implementations may provide stream position and size even if not seekable
    sal_Int64 nPos = tell();
    sal_Int64 nLen = getLength();
    sal_Int64 nLen = size();
    return ((nPos >= 0) && (nLen >= 0)) ? ::std::max< sal_Int64 >( nLen - nPos, 0 ) : -1;
}

@@ -73,7 +55,7 @@ void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos 
{
    sal_Int64 nStrmPos = tell();
    // nothing to do, if stream is at anchor position
    if( isSeekable() && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) )
    if( mbSeekable && (0 <= nAnchorPos) && (nAnchorPos != nStrmPos) && (nBlockSize > 1) )
    {
        // prevent modulo with negative arguments...
        sal_Int64 nSkipSize = (nAnchorPos < nStrmPos) ?
@@ -86,16 +68,16 @@ void BinaryStreamBase::alignToBlock( sal_Int32 nBlockSize, sal_Int64 nAnchorPos 
// ============================================================================

BinaryXSeekableStream::BinaryXSeekableStream( const Reference< XSeekable >& rxSeekable ) :
    BinaryStreamBase( mxSeekable.is() ),
    mxSeekable( rxSeekable )
{
}

bool BinaryXSeekableStream::isSeekable() const
BinaryXSeekableStream::~BinaryXSeekableStream()
{
    return mxSeekable.is();
}

sal_Int64 BinaryXSeekableStream::getLength() const
sal_Int64 BinaryXSeekableStream::size() const
{
    if( mxSeekable.is() ) try
    {
@@ -103,7 +85,7 @@ sal_Int64 BinaryXSeekableStream::getLength() const
    }
    catch( Exception& )
    {
        OSL_ENSURE( false, "BinaryXSeekableStream::getLength - exception caught" );
        OSL_ENSURE( false, "BinaryXSeekableStream::size - exception caught" );
    }
    return -1;
}
@@ -134,27 +116,44 @@ void BinaryXSeekableStream::seek( sal_Int64 nPos )
    }
}

// ============================================================================

bool SequenceSeekableStream::isSeekable() const
void BinaryXSeekableStream::close()
{
    return true;
    mxSeekable.clear();
    mbEof = true;
}

sal_Int64 SequenceSeekableStream::getLength() const
// ============================================================================

SequenceSeekableStream::SequenceSeekableStream( const StreamDataSequence& rData ) :
    BinaryStreamBase( true ),
    mpData( &rData ),
    mnPos( 0 )
{
    return mrData.getLength();
}

sal_Int64 SequenceSeekableStream::size() const
{
    return mpData ? mpData->getLength() : -1;
}

sal_Int64 SequenceSeekableStream::tell() const
{
    return mnPos;
    return mpData ? mnPos : -1;
}

void SequenceSeekableStream::seek( sal_Int64 nPos )
{
    mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mrData.getLength() );
    mbEof = mnPos != nPos;
    if( mpData )
    {
        mnPos = getLimitedValue< sal_Int32, sal_Int64 >( nPos, 0, mpData->getLength() );
        mbEof = mnPos != nPos;
    }
}

void SequenceSeekableStream::close()
{
    mpData = 0;
    mbEof = true;
}

// ============================================================================
diff --git a/oox/source/helper/containerhelper.cxx b/oox/source/helper/containerhelper.cxx
index e7f322f..4fb0d93 100644
--- a/oox/source/helper/containerhelper.cxx
+++ b/oox/source/helper/containerhelper.cxx
@@ -30,6 +30,7 @@
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <rtl/ustrbuf.hxx>
#include "oox/helper/helper.hxx"

@@ -46,12 +47,13 @@ using ::rtl::OUStringBuffer;

// ============================================================================

Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XMultiServiceFactory >& rxFactory )
Reference< XIndexContainer > ContainerHelper::createIndexContainer( const Reference< XComponentContext >& rxContext )
{
    Reference< XIndexContainer > xContainer;
    if( rxFactory.is() ) try
    if( rxContext.is() ) try
    {
        xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.IndexedPropertyValues" ) ), UNO_QUERY_THROW );
    }
    catch( Exception& )
    {
@@ -78,12 +80,13 @@ bool ContainerHelper::insertByIndex(
    return bRet;
}

Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XMultiServiceFactory >& rxFactory )
Reference< XNameContainer > ContainerHelper::createNameContainer( const Reference< XComponentContext >& rxContext )
{
    Reference< XNameContainer > xContainer;
    if( rxFactory.is() ) try
    if( rxContext.is() ) try
    {
        xContainer.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        xContainer.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.NamedPropertyValues" ) ), UNO_QUERY_THROW );
    }
    catch( Exception& )
    {
diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx
index 2e5a612..aeed032 100755
--- a/oox/source/helper/graphichelper.cxx
+++ b/oox/source/helper/graphichelper.cxx
@@ -69,14 +69,13 @@ inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm 
// ============================================================================

GraphicHelper::GraphicHelper( const Reference< XComponentContext >& rxContext, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) :
    mxCompContext( rxContext ),
    mxContext( rxContext ),
    mxStorage( rxStorage ),
    maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) )
{
    OSL_ENSURE( mxCompContext.is(), "GraphicHelper::GraphicHelper - missing component context" );
    Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW );
    OSL_ENSURE( mxContext.is(), "GraphicHelper::GraphicHelper - missing component context" );
    Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY );
    OSL_ENSURE( xFactory.is(), "GraphicHelper::GraphicHelper - missing service factory" );

    if( xFactory.is() )
        mxGraphicProvider.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY );

@@ -319,9 +318,9 @@ Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStr
OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const
{
    OUString aGraphicObjUrl;
    if( mxCompContext.is() && rxGraphic.is() ) try
    if( mxContext.is() && rxGraphic.is() ) try
    {
        Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxCompContext ), UNO_SET_THROW );
        Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxContext ), UNO_SET_THROW );
        xGraphicObj->setGraphic( rxGraphic );
        maGraphicObjects.push_back( xGraphicObj );
        aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID();
diff --git a/oox/source/helper/modelobjecthelper.cxx b/oox/source/helper/modelobjecthelper.cxx
index f9d8af7..d9c5bdd 100644
--- a/oox/source/helper/modelobjecthelper.cxx
+++ b/oox/source/helper/modelobjecthelper.cxx
@@ -48,12 +48,12 @@ using ::rtl::OUString;

// ============================================================================

ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxFactory, const OUString& rServiceName ) :
    mxFactory( rxFactory ),
ObjectContainer::ObjectContainer( const Reference< XMultiServiceFactory >& rxModelFactory, const OUString& rServiceName ) :
    mxModelFactory( rxModelFactory ),
    maServiceName( rServiceName ),
    mnIndex( 0 )
{
    OSL_ENSURE( mxFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" );
    OSL_ENSURE( mxModelFactory.is(), "ObjectContainer::ObjectContainer - missing service factory" );
}

ObjectContainer::~ObjectContainer()
@@ -94,9 +94,10 @@ OUString ObjectContainer::insertObject( const OUString& rObjName, const Any& rOb

void ObjectContainer::createContainer() const
{
    if( !mxContainer.is() && mxFactory.is() ) try
    if( !mxContainer.is() && mxModelFactory.is() ) try
    {
        mxContainer.set( mxFactory->createInstance( maServiceName ), UNO_QUERY_THROW );
        mxContainer.set( mxModelFactory->createInstance( maServiceName ), UNO_QUERY_THROW );
        mxModelFactory.clear();
    }
    catch( Exception& )
    {
diff --git a/oox/source/helper/propertyset.cxx b/oox/source/helper/propertyset.cxx
index 769bd99..c21b895 100644
--- a/oox/source/helper/propertyset.cxx
+++ b/oox/source/helper/propertyset.cxx
@@ -48,6 +48,26 @@ void PropertySet::set( const Reference< XPropertySet >& rxPropSet )
{
    mxPropSet = rxPropSet;
    mxMultiPropSet.set( mxPropSet, UNO_QUERY );
    if( mxPropSet.is() ) try
    {
        mxPropSetInfo = mxPropSet->getPropertySetInfo();
    }
    catch( Exception& )
    {
    }
}

bool PropertySet::hasProperty( sal_Int32 nPropId ) const
{
    if( mxPropSetInfo.is() ) try
    {
        const OUString& rPropName = PropertyMap::getPropertyName( nPropId );
        return mxPropSetInfo->hasPropertyByName( rPropName );
    }
    catch( Exception& )
    {
    }
    return false;
}

// Get properties -------------------------------------------------------------
diff --git a/oox/source/helper/textinputstream.cxx b/oox/source/helper/textinputstream.cxx
index d590781..9087dea 100644
--- a/oox/source/helper/textinputstream.cxx
+++ b/oox/source/helper/textinputstream.cxx
@@ -27,102 +27,209 @@

#include "oox/helper/textinputstream.hxx"

#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XTextInputStream.hpp>
#include <cppuhelper/implbase1.hxx>
#include <rtl/tencinfo.h>
#include "oox/helper/binaryinputstream.hxx"

namespace oox {

// ============================================================================

using ::rtl::OStringBuffer;
using ::rtl::OStringToOUString;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

// ============================================================================

namespace {

/** Reads a text line from stream. First, tries to skip the second character of
    a two-character line end sequence. Returns the new line-end character. */
template< typename BufferType, typename CharType, typename StreamDataType >
sal_Unicode lclReadLine( BufferType& orBuffer, BinaryInputStream& rInStrm, sal_Unicode cLastEolChar )
{
    // try to skip LF following CR, or CR following LF
    if( !rInStrm.isEof() && (cLastEolChar != 0) )
    {
        CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() );
        // return on EOF after line-end
        if( rInStrm.isEof() )
            return 0;
        // return on sequence of equal line-end characters
        bool bIsEolChar = (cChar == 10) || (cChar == 13);
        if( bIsEolChar && (cChar == cLastEolChar) )
            return cChar;
        // append the character, if it is not the other line-end charcter
        if( !bIsEolChar )
            orBuffer.append( cChar );
    }
typedef ::cppu::WeakImplHelper1< XInputStream > UnoBinaryInputStream_BASE;

    // read chars until EOF or line end character (LF or CR)
    while( true )
    {
        CharType cChar = static_cast< CharType >( rInStrm.readValue< StreamDataType >() );
        if( rInStrm.isEof() )
            return 0;
        if( (cChar == 10) || (cChar == 13) )
            return cChar;
        orBuffer.append( cChar );
    }
/** Implementation of a UNO input stream wrapping a binary input stream.
 */
class UnoBinaryInputStream : public UnoBinaryInputStream_BASE
{
public:
    explicit            UnoBinaryInputStream( BinaryInputStream& rInStrm );

    virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
                        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
    virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
                        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
                        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException);
    virtual sal_Int32 SAL_CALL available()
                        throw (NotConnectedException, IOException, RuntimeException);
    virtual void SAL_CALL closeInput()
                        throw (NotConnectedException, IOException, RuntimeException);

private:
    void                ensureConnected() const throw (NotConnectedException);

private:
    BinaryInputStream*  mpInStrm;
};

// ----------------------------------------------------------------------------

UnoBinaryInputStream::UnoBinaryInputStream( BinaryInputStream& rInStrm ) :
    mpInStrm( &rInStrm )
{
}

sal_Int32 SAL_CALL UnoBinaryInputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    ensureConnected();
    return mpInStrm->readData( rData, nBytesToRead, 1 );
}

sal_Int32 SAL_CALL UnoBinaryInputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    ensureConnected();
    return mpInStrm->readData( rData, nMaxBytesToRead, 1 );
}

void SAL_CALL UnoBinaryInputStream::skipBytes( sal_Int32 nBytesToSkip )
        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    ensureConnected();
    mpInStrm->skip( nBytesToSkip, 1 );
}

sal_Int32 SAL_CALL UnoBinaryInputStream::available() throw (NotConnectedException, IOException, RuntimeException)
{
    ensureConnected();
    throw RuntimeException( CREATE_OUSTRING( "Functionality not supported" ), Reference< XInputStream >() );
}

void SAL_CALL UnoBinaryInputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException)
{
    ensureConnected();
    mpInStrm->close();
    mpInStrm = 0;
}

void UnoBinaryInputStream::ensureConnected() const throw (NotConnectedException)
{
    if( !mpInStrm )
        throw NotConnectedException( CREATE_OUSTRING( "Stream closed" ), Reference< XInterface >() );
}

} // namespace

// ============================================================================

TextInputStream::TextInputStream( BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc ) :
    mrInStrm( rInStrm ),
    meTextEnc( eTextEnc ),
    mcLastEolChar( 0 )
TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
{
    init( rxContext, rxInStrm, eTextEnc );
}

TextInputStream::TextInputStream( const Reference< XComponentContext >& rxContext, BinaryInputStream& rInStrm, rtl_TextEncoding eTextEnc )
{
    init( rxContext, new UnoBinaryInputStream( rInStrm ), eTextEnc );
}

TextInputStream::~TextInputStream()
{
}

bool TextInputStream::isEof() const
{
    // do not return EOF, if last text line missed line-end character (see below)
    return mrInStrm.isEof() && (mcLastEolChar == 0);
    if( mxTextStrm.is() ) try
    {
        return mxTextStrm->isEOF();
    }
    catch( Exception& )
    {
    }
    return true;
}

OUString TextInputStream::readLine()
{
    if( mrInStrm.isEof() )
    if( mxTextStrm.is() ) try
    {
        mcLastEolChar = 0;
        return OUString();
        /*  The function createFinalString() adds a character that may have
            been buffered in the previous call of readToChar() (see below). */
        return createFinalString( mxTextStrm->readLine() );
    }

    OUString aLine;
    if( meTextEnc == RTL_TEXTENCODING_UCS2 )
    catch( Exception& )
    {
        // read 16-bit characters for UCS2 encoding
        OUStringBuffer aBuffer;
        mcLastEolChar = lclReadLine< OUStringBuffer, sal_Unicode, sal_uInt16 >( aBuffer, mrInStrm, mcLastEolChar );
        aLine = aBuffer.makeStringAndClear();
        mxTextStrm.clear();
    }
    else
    return OUString();
}

OUString TextInputStream::readToChar( sal_Unicode cChar, bool bIncludeChar )
{
    if( mxTextStrm.is() ) try
    {
        // otherwise, read 8-bit characters and convert according to text encoding
        OStringBuffer aBuffer;
        mcLastEolChar = lclReadLine< OStringBuffer, sal_Char, sal_uInt8 >( aBuffer, mrInStrm, mcLastEolChar );
        aLine = OStringToOUString( aBuffer.makeStringAndClear(), meTextEnc );
        Sequence< sal_Unicode > aDelimiters( 1 );
        aDelimiters[ 0 ] = cChar;
        /*  Always get the delimiter character from the UNO text input stream.
            In difference to this implementation, it will not return it in the
            next call but silently skip it. If caller specifies to exclude the
            character in this call, it will be returned in the next call of one
            of the own member functions. The function createFinalString() adds
            a character that has been buffered in the previous call. */
        OUString aString = createFinalString( mxTextStrm->readString( aDelimiters, sal_False ) );
        // remove last character from string and remember it for next call
        if( !bIncludeChar && (aString.getLength() > 0) && (aString[ aString.getLength() - 1 ] == cChar) )
        {
            mcPendingChar = cChar;
            aString = aString.copy( 0, aString.getLength() - 1 );
        }
        return aString;
    }
    catch( Exception& )
    {
        mxTextStrm.clear();
    }
    return OUString();
}

    // if last line is not empty but line-end character is missing, do not return EOF
    if( mrInStrm.isEof() && (aLine.getLength() > 0) )
        mcLastEolChar = 10;
/*static*/ Reference< XTextInputStream > TextInputStream::createXTextInputStream(
        const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
{
    Reference< XTextInputStream > xTextStrm;
    const char* pcCharset = rtl_getMimeCharsetFromTextEncoding( eTextEnc );
    OSL_ENSURE( pcCharset, "TextInputStream::createXTextInputStream - unsupported text encoding" );
    if( rxContext.is() && rxInStrm.is() && pcCharset ) try
    {
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XActiveDataSink > xDataSink( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TextInputStream" ) ), UNO_QUERY_THROW );
        xDataSink->setInputStream( rxInStrm );
        xTextStrm.set( xDataSink, UNO_QUERY_THROW );
        xTextStrm->setEncoding( OUString::createFromAscii( pcCharset ) );
    }
    catch( Exception& )
    {
    }
    return xTextStrm;
}

    return aLine;
// private --------------------------------------------------------------------

OUString TextInputStream::createFinalString( const OUString& rString )
{
    if( mcPendingChar == 0 )
        return rString;

    OUString aString = OUString( mcPendingChar ) + rString;
    mcPendingChar = 0;
    return aString;
}

void TextInputStream::init( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm, rtl_TextEncoding eTextEnc )
{
    mcPendingChar = 0;
    mxTextStrm = createXTextInputStream( rxContext, rxInStrm, eTextEnc );
}

// ============================================================================
diff --git a/oox/source/helper/zipstorage.cxx b/oox/source/helper/zipstorage.cxx
index 8145e7c..fc976d8 100644
--- a/oox/source/helper/zipstorage.cxx
+++ b/oox/source/helper/zipstorage.cxx
@@ -33,6 +33,7 @@
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <comphelper/storagehelper.hxx>
#include "oox/helper/helper.hxx"

@@ -50,14 +51,12 @@ using ::rtl::OUString;

// ============================================================================

ZipStorage::ZipStorage(
        const Reference< XMultiServiceFactory >& rxFactory,
        const Reference< XInputStream >& rxInStream ) :
ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStream ) :
    StorageBase( rxInStream, false )
{
    OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" );
    OSL_ENSURE( rxContext.is(), "ZipStorage::ZipStorage - missing component context" );
    // create base storage object
    try
    if( rxContext.is() ) try
    {
        /*  #i105325# ::comphelper::OStorageHelper::GetStorageFromInputStream()
            cannot be used here as it will open a storage with format type
@@ -69,26 +68,26 @@ ZipStorage::ZipStorage(

            TODO: #i105410# switch to 'OFOPXMLFormat' and use its
            implementation of relations handling. */
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
            ZIP_STORAGE_FORMAT_STRING, rxInStream, rxFactory, sal_True );
            ZIP_STORAGE_FORMAT_STRING, rxInStream, xFactory, sal_True );
    }
    catch( Exception& )
    {
    }
}

ZipStorage::ZipStorage(
        const Reference< XMultiServiceFactory >& rxFactory,
        const Reference< XStream >& rxStream ) :
ZipStorage::ZipStorage( const Reference< XComponentContext >& rxContext, const Reference< XStream >& rxStream ) :
    StorageBase( rxStream, false )
{
    OSL_ENSURE( rxFactory.is(), "ZipStorage::ZipStorage - missing service factory" );
    OSL_ENSURE( rxContext.is(), "ZipStorage::ZipStorage - missing component context" );
    // create base storage object
    try
    if( rxContext.is() ) try
    {
        using namespace ::com::sun::star::embed::ElementModes;
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        const sal_Int32 nOpenMode = ElementModes::READWRITE | ElementModes::TRUNCATE;
        mxStorage = ::comphelper::OStorageHelper::GetStorageOfFormatFromStream(
            OFOPXML_STORAGE_FORMAT_STRING, rxStream, READWRITE | TRUNCATE, rxFactory, sal_True );
            OFOPXML_STORAGE_FORMAT_STRING, rxStream, nOpenMode, xFactory, sal_True );
    }
    catch( Exception& )
    {
diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx
index 493d6b6..58610e4 100644
--- a/oox/source/ole/axbinaryreader.cxx
+++ b/oox/source/ole/axbinaryreader.cxx
@@ -48,14 +48,22 @@ const sal_uInt32 AX_STRING_COMPRESSED       = 0x80000000;
// ============================================================================

AxAlignedInputStream::AxAlignedInputStream( BinaryInputStream& rInStrm ) :
    mrInStrm( rInStrm ),
    mnStrmPos( 0 )
    BinaryStreamBase( false ),
    mpInStrm( &rInStrm ),
    mnStrmPos( 0 ),
    mnStrmSize( rInStrm.getRemaining() )
{
    mbEof = mbEof || rInStrm.isEof();
}

sal_Int64 AxAlignedInputStream::size() const
{
    return mpInStrm ? mnStrmSize : -1;
}

sal_Int64 AxAlignedInputStream::tell() const
{
    return mnStrmPos;
    return mpInStrm ? mnStrmPos : -1;
}

void AxAlignedInputStream::seek( sal_Int64 nPos )
@@ -65,24 +73,44 @@ void AxAlignedInputStream::seek( sal_Int64 nPos )
        skip( static_cast< sal_Int32 >( nPos - mnStrmPos ) );
}

sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
void AxAlignedInputStream::close()
{
    sal_Int32 nReadSize = mrInStrm.readData( orData, nBytes );
    mnStrmPos += nReadSize;
    mpInStrm = 0;
    mbEof = true;
}

sal_Int32 AxAlignedInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nReadSize = 0;
    if( !mbEof )
    {
        nReadSize = mpInStrm->readData( orData, nBytes, nAtomSize );
        mnStrmPos += nReadSize;
        mbEof = mpInStrm->isEof();
    }
    return nReadSize;
}

sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes )
sal_Int32 AxAlignedInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nReadSize = mrInStrm.readMemory( opMem, nBytes );
    mnStrmPos += nReadSize;
    sal_Int32 nReadSize = 0;
    if( !mbEof )
    {
        nReadSize = mpInStrm->readMemory( opMem, nBytes, nAtomSize );
        mnStrmPos += nReadSize;
        mbEof = mpInStrm->isEof();
    }
    return nReadSize;
}

void AxAlignedInputStream::skip( sal_Int32 nBytes )
void AxAlignedInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
{
    mrInStrm.skip( nBytes );
    mnStrmPos += nBytes;
    if( !mbEof )
    {
        mpInStrm->skip( nBytes, nAtomSize );
        mnStrmPos += nBytes;
        mbEof = mpInStrm->isEof();
    }
}

void AxAlignedInputStream::align( size_t nSize )
@@ -174,10 +202,7 @@ bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 
    OSL_ENSURE( bValidChars, "lclReadString - string too long" );
    sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2);
    nChars = ::std::min< sal_Int32 >( nChars, 65536 );
    rValue = bCompressed ?
        // ISO-8859-1 maps all byte values xx to the same Unicode code point U+00xx
        rInStrm.readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1 ) :
        rInStrm.readUnicodeArray( nChars );
    rValue = rInStrm.readCompressedUnicodeArray( nChars, bCompressed );
    rInStrm.seek( nEndPos );
    return bValidChars;
}
diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx
index 86cc55d..40dfdf1 100644
--- a/oox/source/ole/axcontrol.cxx
+++ b/oox/source/ole/axcontrol.cxx
@@ -226,11 +226,11 @@ void lclPrepareConverter( PropertySet& rConverter, const Reference< XModel >& rx
{
    if( !rConverter.is() ) try
    {
        Reference< XMultiServiceFactory > xFactory( rxDocModel, UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xModelFactory( rxDocModel, UNO_QUERY_THROW );
        OUString aServiceName = bRange ?
            CREATE_OUSTRING( "com.sun.star.table.CellRangeAddressConversion" ) :
            CREATE_OUSTRING( "com.sun.star.table.CellAddressConversion" );
        rConverter.set( xFactory->createInstance( aServiceName ) );
        rConverter.set( xModelFactory->createInstance( aServiceName ) );
    }
    catch( Exception& )
    {
@@ -344,8 +344,8 @@ void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlMo
        aArgs[ 0 ] <<= aValue;

        // create the CellValueBinding instance and set at the control model
        Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW );
        Reference< XValueBinding > xBinding( xFactory->createInstanceWithArguments(
        Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
        Reference< XValueBinding > xBinding( xModelFactory->createInstanceWithArguments(
            CREATE_OUSTRING( "com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY_THROW );
        xBindable->setValueBinding( xBinding );
    }
@@ -376,8 +376,8 @@ void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlMo
        aArgs[ 0 ] <<= aValue;

        // create the EntrySource instance and set at the control model
        Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW );
        Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
        Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
        Reference< XListEntrySource > xEntrySource( xModelFactory->createInstanceWithArguments(
            CREATE_OUSTRING( "com.sun.star.table.CellRangeListSource"  ), aArgs ), UNO_QUERY_THROW );
        xEntrySink->setListEntrySource( xEntrySource );
    }
diff --git a/oox/source/ole/axcontrolfragment.cxx b/oox/source/ole/axcontrolfragment.cxx
index f45e8e2..a81ae99 100644
--- a/oox/source/ole/axcontrolfragment.cxx
+++ b/oox/source/ole/axcontrolfragment.cxx
@@ -140,7 +140,7 @@ ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const 
                    Reference< XInputStream > xStrgStrm = getFilter().openInputStream( aFragmentPath );
                    if( xStrgStrm.is() )
                    {
                        OleStorage aStorage( getFilter().getServiceFactory(), xStrgStrm, false );
                        OleStorage aStorage( getFilter().getComponentContext(), xStrgStrm, false );
                        BinaryXInputStream aInStrm( aStorage.openInputStream( CREATE_OUSTRING( "f" ) ), true );
                        if( !aInStrm.isEof() )
                            if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModelFromGuid( aClassId ) ) )
diff --git a/oox/source/ole/oleobjecthelper.cxx b/oox/source/ole/oleobjecthelper.cxx
index 396cd6b..5a38d93 100644
--- a/oox/source/ole/oleobjecthelper.cxx
+++ b/oox/source/ole/oleobjecthelper.cxx
@@ -44,6 +44,7 @@ namespace ole {

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::embed;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
@@ -61,12 +62,17 @@ OleObjectInfo::OleObjectInfo() :

// ============================================================================

OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxFactory ) :
OleObjectHelper::OleObjectHelper( const Reference< XMultiServiceFactory >& rxModelFactory ) :
    maEmbeddedObjScheme( CREATE_OUSTRING( "vnd.sun.star.EmbeddedObject:" ) ),
    mnObjectId( 100 )
{
    if( rxFactory.is() )
        mxResolver.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY );
    if( rxModelFactory.is() ) try
    {
        mxResolver.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.document.ImportEmbeddedObjectResolver" ) ), UNO_QUERY );
    }
    catch( Exception& )
    {
    }
}

OleObjectHelper::~OleObjectHelper()
@@ -122,11 +128,7 @@ bool OleObjectHelper::importOleObject( PropertyMap& rPropMap, const OleObjectInf

    if( bRet )
    {
        // aspect mode
        using namespace ::com::sun::star::embed::Aspects;
        sal_Int64 nAspect = rOleObject.mbShowAsIcon ? MSOLE_ICON : MSOLE_CONTENT;
        rPropMap[ PROP_Aspect ] <<= nAspect;
        // visual area
        rPropMap[ PROP_Aspect ] <<= (rOleObject.mbShowAsIcon ? Aspects::MSOLE_ICON : Aspects::MSOLE_CONTENT);
        rPropMap[ PROP_VisualArea ] <<= Rectangle( 0, 0, rObjSize.Width, rObjSize.Height );
    }
    return bRet;
diff --git a/oox/source/ole/olestorage.cxx b/oox/source/ole/olestorage.cxx
index cf55d64..2db4aed 100644
--- a/oox/source/ole/olestorage.cxx
+++ b/oox/source/ole/olestorage.cxx
@@ -35,6 +35,7 @@
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <cppuhelper/implbase2.hxx>
#include "oox/helper/binaryinputstream.hxx"
#include "oox/helper/binaryoutputstream.hxx"
@@ -68,7 +69,7 @@ class OleOutputStream : public OleOutputStreamBase
{
public:
    explicit            OleOutputStream(
                            const Reference< XMultiServiceFactory >& rxFactory,
                            const Reference< XComponentContext >& rxContext,
                            const Reference< XNameContainer >& rxStorage,
                            const OUString& rElementName );
    virtual             ~OleOutputStream();
@@ -95,14 +96,15 @@ private:

// ----------------------------------------------------------------------------

OleOutputStream::OleOutputStream( const Reference< XMultiServiceFactory >& rxFactory,
OleOutputStream::OleOutputStream( const Reference< XComponentContext >& rxContext,
        const Reference< XNameContainer >& rxStorage, const OUString& rElementName ) :
    mxStorage( rxStorage ),
    maElementName( rElementName )
{
    try
    {
        mxTempFile.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( rxContext->getServiceManager(), UNO_QUERY_THROW );
        mxTempFile.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
        mxOutStrm = mxTempFile->getOutputStream();
        mxSeekable.set( mxOutStrm, UNO_QUERY );
    }
@@ -179,49 +181,40 @@ void OleOutputStream::ensureConnected() const throw( NotConnectedException )

// ============================================================================

OleStorage::OleStorage(
        const Reference< XMultiServiceFactory >& rxFactory,
        const Reference< XInputStream >& rxInStream,
        bool bBaseStreamAccess ) :
OleStorage::OleStorage( const Reference< XComponentContext >& rxContext,
        const Reference< XInputStream >& rxInStream, bool bBaseStreamAccess ) :
    StorageBase( rxInStream, bBaseStreamAccess ),
    mxFactory( rxFactory ),
    mxContext( rxContext ),
    mpParentStorage( 0 )
{
    OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" );
    OSL_ENSURE( mxContext.is(), "OleStorage::OleStorage - missing component context" );
    initStorage( rxInStream );
}

OleStorage::OleStorage(
        const Reference< XMultiServiceFactory >& rxFactory,
        const Reference< XStream >& rxOutStream,
        bool bBaseStreamAccess ) :
OleStorage::OleStorage( const Reference< XComponentContext >& rxContext,
        const Reference< XStream >& rxOutStream, bool bBaseStreamAccess ) :
    StorageBase( rxOutStream, bBaseStreamAccess ),
    mxFactory( rxFactory ),
    mxContext( rxContext ),
    mpParentStorage( 0 )
{
    OSL_ENSURE( mxFactory.is(), "OleStorage::OleStorage - missing service factory" );
    OSL_ENSURE( mxContext.is(), "OleStorage::OleStorage - missing component context" );
    initStorage( rxOutStream );
}

OleStorage::OleStorage(
        const OleStorage& rParentStorage,
        const Reference< XNameContainer >& rxStorage,
        const OUString& rElementName,
        bool bReadOnly ) :
OleStorage::OleStorage( const OleStorage& rParentStorage,
        const Reference< XNameContainer >& rxStorage, const OUString& rElementName, bool bReadOnly ) :
    StorageBase( rParentStorage, rElementName, bReadOnly ),
    mxFactory( rParentStorage.mxFactory ),
    mxContext( rParentStorage.mxContext ),
    mxStorage( rxStorage ),
    mpParentStorage( &rParentStorage )
{
    OSL_ENSURE( mxStorage.is(), "OleStorage::OleStorage - missing substorage elements" );
}

OleStorage::OleStorage(
        const OleStorage& rParentStorage,
        const Reference< XStream >& rxOutStream,
        const OUString& rElementName ) :
OleStorage::OleStorage( const OleStorage& rParentStorage,
        const Reference< XStream >& rxOutStream, const OUString& rElementName ) :
    StorageBase( rParentStorage, rElementName, false ),
    mxFactory( rParentStorage.mxFactory ),
    mxContext( rParentStorage.mxContext ),
    mpParentStorage( &rParentStorage )
{
    initStorage( rxOutStream );
@@ -239,7 +232,8 @@ void OleStorage::initStorage( const Reference< XInputStream >& rxInStream )
    Reference< XInputStream > xInStrm = rxInStream;
    if( !Reference< XSeekable >( xInStrm, UNO_QUERY ).is() ) try
    {
        Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
        {
            Reference< XOutputStream > xOutStrm( xTempFile->getOutputStream(), UNO_SET_THROW );
            /*  Pass false to both binary stream objects to keep the UNO
@@ -259,10 +253,11 @@ void OleStorage::initStorage( const Reference< XInputStream >& rxInStream )
    // create base storage object
    if( xInStrm.is() ) try
    {
        Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
        Sequence< Any > aArgs( 2 );
        aArgs[ 0 ] <<= xInStrm;
        aArgs[ 1 ] <<= true;        // true = do not create a copy of the input stream
        mxStorage.set( mxFactory->createInstanceWithArguments(
        mxStorage.set( xFactory->createInstanceWithArguments(
            CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW );
    }
    catch( Exception& )
@@ -275,10 +270,11 @@ void OleStorage::initStorage( const Reference< XStream >& rxOutStream )
    // create base storage object
    if( rxOutStream.is() ) try
    {
        Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
        Sequence< Any > aArgs( 2 );
        aArgs[ 0 ] <<= rxOutStream;
        aArgs[ 1 ] <<= true;        // true = do not create a copy of the stream
        mxStorage.set( mxFactory->createInstanceWithArguments(
        mxStorage.set( xFactory->createInstanceWithArguments(
            CREATE_OUSTRING( "com.sun.star.embed.OLESimpleStorage" ), aArgs ), UNO_QUERY_THROW );
    }
    catch( Exception& )
@@ -347,7 +343,8 @@ StorageRef OleStorage::implOpenSubStorage( const OUString& rElementName, bool bC
        if( !isReadOnly() && (bCreateMissing || xSubStorage.get()) ) try
        {
            // create new storage based on a temp file
            Reference< XStream > xTempFile( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
            Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
            Reference< XStream > xTempFile( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.io.TempFile" ) ), UNO_QUERY_THROW );
            StorageRef xTempStorage( new OleStorage( *this, xTempFile, rElementName ) );
            // copy existing substorage into temp storage
            if( xSubStorage.get() )
@@ -379,7 +376,7 @@ Reference< XOutputStream > OleStorage::implOpenOutputStream( const OUString& rEl
{
    Reference< XOutputStream > xOutStream;
    if( mxStorage.is() && (rElementName.getLength() > 0) )
        xOutStream.set( new OleOutputStream( mxFactory, mxStorage, rElementName ) );
        xOutStream.set( new OleOutputStream( mxContext, mxStorage, rElementName ) );
    return xOutStream;
}

diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx
index 39deb77..45a2b9c 100644
--- a/oox/source/ole/vbacontrol.cxx
+++ b/oox/source/ole/vbacontrol.cxx
@@ -756,11 +756,11 @@ bool lclEatKeyword( OUString& rCodeLine, const OUString& rKeyword )

VbaUserForm::VbaUserForm( const Reference< XComponentContext >& rxContext,
        const Reference< XModel >& rxDocModel, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
    mxCompContext( rxContext ),
    mxContext( rxContext ),
    mxDocModel( rxDocModel ),
    maConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr )
{
    OSL_ENSURE( mxCompContext.is(), "VbaUserForm::VbaUserForm - missing component context" );
    OSL_ENSURE( mxContext.is(), "VbaUserForm::VbaUserForm - missing component context" );
    OSL_ENSURE( mxDocModel.is(), "VbaUserForm::VbaUserForm - missing document model" );
}

@@ -768,7 +768,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
        StorageBase& rVbaFormStrg, const OUString& rModuleName, rtl_TextEncoding eTextEnc )
{
    OSL_ENSURE( rxDialogLib.is(), "VbaUserForm::importForm - missing dialog library" );
    if( !mxCompContext.is() || !mxDocModel.is() || !rxDialogLib.is() )
    if( !mxContext.is() || !mxDocModel.is() || !rxDialogLib.is() )
        return;

    // check that the '03VBFrame' stream exists, this is required for forms
@@ -778,7 +778,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
        return;

    // scan for the line 'Begin {GUID} <FormName>'
    TextInputStream aFrameTextStrm( aInStrm, eTextEnc );
    TextInputStream aFrameTextStrm( mxContext, aInStrm, eTextEnc );
    const OUString aBegin = CREATE_OUSTRING( "Begin" );
    OUString aLine;
    bool bBeginFound = false;
@@ -826,7 +826,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
    {
        // create the dialog model
        OUString aServiceName = mxCtrlModel->getServiceName();
        Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XControlModel > xDialogModel( xFactory->createInstance( aServiceName ), UNO_QUERY_THROW );
        Reference< XNameContainer > xDialogNC( xDialogModel, UNO_QUERY_THROW );

@@ -834,7 +834,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
        if( convertProperties( xDialogModel, maConverter, 0 ) )
        {
            // export the dialog to XML and insert it into the dialog library
            Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxCompContext ), UNO_SET_THROW );
            Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, mxContext ), UNO_SET_THROW );
            OSL_ENSURE( !rxDialogLib->hasByName( aFormName ), "VbaUserForm::importForm - multiple dialogs with equal name" );
            ContainerHelper::insertByName( rxDialogLib, aFormName, Any( xDialogSource ) );
        }
diff --git a/oox/source/ole/vbainputstream.cxx b/oox/source/ole/vbainputstream.cxx
index e56e8b5..7e2c88d 100644
--- a/oox/source/ole/vbainputstream.cxx
+++ b/oox/source/ole/vbainputstream.cxx
@@ -47,17 +47,38 @@ const sal_uInt16 VBACHUNK_LENMASK           = 0x0FFF;
// ============================================================================

VbaInputStream::VbaInputStream( BinaryInputStream& rInStrm ) :
    mrInStrm( rInStrm ),
    BinaryStreamBase( false ),
    mpInStrm( &rInStrm ),
    mnChunkPos( 0 )
{
    maChunk.reserve( 4096 );

    sal_uInt8 nSig = mrInStrm.readuInt8();
    sal_uInt8 nSig = rInStrm.readuInt8();
    OSL_ENSURE( nSig == VBASTREAM_SIGNATURE, "VbaInputStream::VbaInputStream - wrong signature" );
    mbEof = nSig != VBASTREAM_SIGNATURE;
    mbEof = mbEof || rInStrm.isEof() || (nSig != VBASTREAM_SIGNATURE);
}

sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
sal_Int64 VbaInputStream::size() const
{
    return -1;
}

sal_Int64 VbaInputStream::tell() const
{
    return -1;
}

void VbaInputStream::seek( sal_Int64 )
{
}

void VbaInputStream::close()
{
    mpInStrm = 0;
    mbEof = true;
}

sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nRet = 0;
    if( !mbEof )
@@ -65,7 +86,7 @@ sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes
        orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) );
        if( nBytes > 0 )
        {
            nRet = readMemory( orData.getArray(), nBytes );
            nRet = readMemory( orData.getArray(), nBytes, nAtomSize );
            if( nRet < nBytes )
                orData.realloc( nRet );
        }
@@ -73,7 +94,7 @@ sal_Int32 VbaInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes
    return nRet;
}

sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes )
sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    sal_Int32 nRet = 0;
    sal_uInt8* opnMem = reinterpret_cast< sal_uInt8* >( opMem );
@@ -90,7 +111,7 @@ sal_Int32 VbaInputStream::readMemory( void* opMem, sal_Int32 nBytes )
    return nRet;
}

void VbaInputStream::skip( sal_Int32 nBytes )
void VbaInputStream::skip( sal_Int32 nBytes, size_t /*nAtomSize*/ )
{
    while( (nBytes > 0) && updateChunk() )
    {
@@ -108,8 +129,8 @@ bool VbaInputStream::updateChunk()
    if( mbEof || (mnChunkPos < maChunk.size()) ) return !mbEof;

    // try to read next chunk header, this may trigger EOF
    sal_uInt16 nHeader = mrInStrm.readuInt16();
    mbEof = mrInStrm.isEof();
    sal_uInt16 nHeader = mpInStrm->readuInt16();
    mbEof = mpInStrm->isEof();
    if( mbEof ) return false;

    // check header signature
@@ -126,15 +147,15 @@ bool VbaInputStream::updateChunk()
        maChunk.clear();
        sal_uInt8 nBitCount = 4;
        sal_uInt16 nChunkPos = 0;
        while( !mbEof && !mrInStrm.isEof() && (nChunkPos < nChunkLen) )
        while( !mbEof && !mpInStrm->isEof() && (nChunkPos < nChunkLen) )
        {
            sal_uInt8 nTokenFlags = mrInStrm.readuInt8();
            sal_uInt8 nTokenFlags = mpInStrm->readuInt8();
            ++nChunkPos;
            for( int nBit = 0; !mbEof && !mrInStrm.isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 )
            for( int nBit = 0; !mbEof && !mpInStrm->isEof() && (nBit < 8) && (nChunkPos < nChunkLen); ++nBit, nTokenFlags >>= 1 )
            {
                if( nTokenFlags & 1 )
                {
                    sal_uInt16 nCopyToken = mrInStrm.readuInt16();
                    sal_uInt16 nCopyToken = mpInStrm->readuInt16();
                    nChunkPos = nChunkPos + 2;
                    // update bit count used for offset/length in the token
                    while( static_cast< size_t >( 1 << nBitCount ) < maChunk.size() ) ++nBitCount;
@@ -164,7 +185,7 @@ bool VbaInputStream::updateChunk()
                else
                {
                    maChunk.resize( maChunk.size() + 1 );
                    mrInStrm >> maChunk.back();
                    *mpInStrm >> maChunk.back();
                    ++nChunkPos;
                }
            }
@@ -173,7 +194,7 @@ bool VbaInputStream::updateChunk()
    else
    {
        maChunk.resize( nChunkLen );
        mrInStrm.readMemory( &maChunk.front(), nChunkLen );
        mpInStrm->readMemory( &maChunk.front(), nChunkLen );
    }

    mnChunkPos = 0;
diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx
index 2da92b9..628c2ab 100644
--- a/oox/source/ole/vbamodule.cxx
+++ b/oox/source/ole/vbamodule.cxx
@@ -54,7 +54,9 @@ using ::rtl::OUStringBuffer;

// ============================================================================

VbaModule::VbaModule( const Reference< XModel >& rxDocModel, const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) :
VbaModule::VbaModule( const Reference< XComponentContext >& rxContext, const Reference< XModel >& rxDocModel,
        const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) :
    mxContext( rxContext ),
    mxDocModel( rxDocModel ),
    maName( rName ),
    meTextEnc( eTextEnc ),
@@ -161,7 +163,7 @@ OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const
            // decompression starts at current stream position of aInStrm
            VbaInputStream aVbaStrm( aInStrm );
            // load the source code line-by-line, with some more processing
            TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc );
            TextInputStream aVbaTextStrm( mxContext, aVbaStrm, meTextEnc );
            while( !aVbaTextStrm.isEof() )
            {
                OUString aCodeLine = aVbaTextStrm.readLine();
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index 35e6b79..57979f6 100644
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -155,11 +155,11 @@ void VbaMacroAttacherBase::resolveAndAttachMacro( const Reference< XVBAMacroReso
VbaProject::VbaProject( const Reference< XComponentContext >& rxContext,
        const Reference< XModel >& rxDocModel, const OUString& rConfigCompName ) :
    VbaFilterConfig( rxContext, rConfigCompName ),
    mxCompContext( rxContext ),
    mxContext( rxContext ),
    mxDocModel( rxDocModel ),
    maPrjName( CREATE_OUSTRING( "Standard" ) )
{
    OSL_ENSURE( mxCompContext.is(), "VbaProject::VbaProject - missing component context" );
    OSL_ENSURE( mxContext.is(), "VbaProject::VbaProject - missing component context" );
    OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" );
    mxBasicLib = openLibrary( PROP_BasicLibraries, false );
    mxDialogLib = openLibrary( PROP_DialogLibraries, false );
@@ -332,7 +332,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
                OSL_ENSURE( aName.getLength() > 0, "VbaProject::importVba - invalid module name" );
                OSL_ENSURE( !aModules.has( aName ), "VbaProject::importVba - multiple modules with the same name" );
                VbaModuleMap::mapped_type& rxModule = aModules[ aName ];
                rxModule.reset( new VbaModule( mxDocModel, aName, eTextEnc, bExecutable ) );
                rxModule.reset( new VbaModule( mxContext, mxDocModel, aName, eTextEnc, bExecutable ) );
                // read all remaining records until the MODULEEND record
                rxModule->importDirRecords( aDirStrm );
                OSL_ENSURE( !aModulesByStrm.has( rxModule->getStreamName() ), "VbaProject::importVba - multiple modules with the same stream name" );
@@ -369,7 +369,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
    // do not exit if this stream does not exist, but proceed to load the modules below
    if( !aPrjStrm.isEof() )
    {
        TextInputStream aPrjTextStrm( aPrjStrm, eTextEnc );
        TextInputStream aPrjTextStrm( mxContext, aPrjStrm, eTextEnc );
        OUString aKey, aValue;
        bool bExitLoop = false;
        while( !bExitLoop && !aPrjTextStrm.isEof() )
@@ -413,7 +413,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
    {
        OSL_ENSURE( !aModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" );
        VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ];
        rxModule.reset( new VbaModule( mxDocModel, aIt->first, eTextEnc, bExecutable ) );
        rxModule.reset( new VbaModule( mxContext, mxDocModel, aIt->first, eTextEnc, bExecutable ) );
        rxModule->setType( aIt->second );
    }

@@ -489,7 +489,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap

                // create and import the form
                Reference< XNameContainer > xDialogLib( createDialogLibrary(), UNO_SET_THROW );
                VbaUserForm aForm( mxCompContext, mxDocModel, rGraphicHelper, bDefaultColorBgr );
                VbaUserForm aForm( mxContext, mxDocModel, rGraphicHelper, bDefaultColorBgr );
                aForm.importForm( xDialogLib, *xSubStrg, aModuleName, eTextEnc );
            }
            catch( Exception& )
@@ -506,14 +506,14 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap

void VbaProject::attachMacros()
{
    if( !maMacroAttachers.empty() && mxCompContext.is() ) try
    if( !maMacroAttachers.empty() && mxContext.is() ) try
    {
        Reference< XMultiComponentFactory > xFactory( mxCompContext->getServiceManager(), UNO_SET_THROW );
        Reference< XMultiComponentFactory > xFactory( mxContext->getServiceManager(), UNO_SET_THROW );
        Sequence< Any > aArgs( 2 );
        aArgs[ 0 ] <<= mxDocModel;
        aArgs[ 1 ] <<= maPrjName;
        Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext(
            CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxCompContext ), UNO_QUERY_THROW );
            CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs, mxContext ), UNO_QUERY_THROW );
        maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::boost::cref( xResolver ) );
    }
    catch( Exception& )
@@ -523,15 +523,14 @@ void VbaProject::attachMacros()

void VbaProject::copyStorage( StorageBase& rVbaPrjStrg )
{
    if( mxCompContext.is() ) try
    if( mxContext.is() ) try
    {
        Reference< XMultiServiceFactory > xFactory( mxCompContext->getServiceManager(), UNO_QUERY_THROW );
        Reference< XStorageBasedDocument > xStorageBasedDoc( mxDocModel, UNO_QUERY_THROW );
        Reference< XStorage > xDocStorage( xStorageBasedDoc->getDocumentStorage(), UNO_QUERY_THROW );
        {
            using namespace ::com::sun::star::embed::ElementModes;
            Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), SEEKABLE | WRITE | TRUNCATE ), UNO_SET_THROW );
            OleStorage aDestStorage( xFactory, xDocStream, false );
            const sal_Int32 nOpenMode = ElementModes::SEEKABLE | ElementModes::WRITE | ElementModes::TRUNCATE;
            Reference< XStream > xDocStream( xDocStorage->openStreamElement( CREATE_OUSTRING( "_MS_VBA_Macros" ), nOpenMode ), UNO_SET_THROW );
            OleStorage aDestStorage( mxContext, xDocStream, false );
            rVbaPrjStrg.copyStorageToStorage( aDestStorage );
            aDestStorage.commit();
        }
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
index ccf0fe5..44eb810 100644
--- a/oox/source/vml/vmldrawing.cxx
+++ b/oox/source/vml/vmldrawing.cxx
@@ -214,8 +214,8 @@ Reference< XShape > Drawing::createAndInsertXShape( const OUString& rService,
    Reference< XShape > xShape;
    if( (rService.getLength() > 0) && rxShapes.is() ) try
    {
        Reference< XMultiServiceFactory > xFactory( mrFilter.getModelFactory(), UNO_SET_THROW );
        xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xModelFactory( mrFilter.getModelFactory(), UNO_SET_THROW );
        xShape.set( xModelFactory->createInstance( rService ), UNO_QUERY_THROW );
        // insert shape into passed shape collection (maybe drawpage or group shape)
        rxShapes->add( xShape );
        xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) );
diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx
index dc5c825..591e854 100644
--- a/oox/source/vml/vmldrawingfragment.cxx
+++ b/oox/source/vml/vmldrawingfragment.cxx
@@ -27,6 +27,7 @@

#include "oox/vml/vmldrawingfragment.hxx"

#include "oox/core/xmlfilterbase.hxx"
#include "oox/vml/vmldrawing.hxx"
#include "oox/vml/vmlinputstream.hxx"
#include "oox/vml/vmlshapecontext.hxx"
@@ -53,7 +54,7 @@ DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragm
Reference< XInputStream > DrawingFragment::openFragmentStream() const
{
    // #i104719# create an input stream that preprocesses the VML data
    return new InputStream( FragmentHandler2::openFragmentStream() );
    return new InputStream( getFilter().getComponentContext(), FragmentHandler2::openFragmentStream() );
}

ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx
index fb2443a..ef2f408 100644
--- a/oox/source/vml/vmlinputstream.cxx
+++ b/oox/source/vml/vmlinputstream.cxx
@@ -27,10 +27,12 @@

#include "oox/vml/vmlinputstream.hxx"

#include <com/sun/star/io/XTextInputStream.hpp>
#include <map>
#include <rtl/strbuf.hxx>
#include <string.h>
#include <rtl/strbuf.hxx>
#include "oox/helper/helper.hxx"
#include "oox/helper/textinputstream.hxx"

namespace oox {
namespace vml {
@@ -55,7 +57,7 @@ inline const sal_Char* lclFindCharacter( const sal_Char* pcBeg, const sal_Char* 

inline bool lclIsWhiteSpace( sal_Char cChar )
{
    return (cChar == ' ') || (cChar == '\t') || (cChar == '\n') || (cChar == '\r');
    return cChar < 32;
}

const sal_Char* lclFindWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd )
@@ -151,14 +153,78 @@ void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal
        lclAppendToBuffer( rBuffer, pcBeg, pcEnd );
}

void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd )
void lclProcessElement( OStringBuffer& rBuffer, const OString& rElement )
{
    // check that passed string starts and ends with the brackets of an XML element
    sal_Int32 nElementLen = rElement.getLength();
    if( nElementLen == 0 )
        return;

    const sal_Char* pcOpen = rElement.getStr();
    const sal_Char* pcClose = pcOpen + nElementLen - 1;

    // no complete element found
    if( (pcOpen >= pcClose) || (*pcOpen != '<') || (*pcClose != '>') )
    {
        // just append all passed characters
        rBuffer.append( rElement );
    }

    // skip parser instructions: '<![...]>'
    else if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') )
    {
        // do nothing
    }

    // replace '<br>' element with newline
    else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) )
    {
        rBuffer.append( '\n' );
    }

    // check start elements and simple elements for repeated attributes
    else if( pcOpen[ 1 ] != '/' )
    {
        // find positions of text content inside brackets, exclude '/' in '<simpleelement/>'
        const sal_Char* pcContentBeg = pcOpen + 1;
        bool bIsEmptyElement = pcClose[ -1 ] == '/';
        const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose;
        // append opening bracket and element name to buffer
        const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd );
        lclAppendToBuffer( rBuffer, pcOpen, pcWhiteSpace );
        // find begin of attributes, and process all attributes
        const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd );
        if( pcAttribBeg < pcContentEnd )
            lclProcessAttribs( rBuffer, pcAttribBeg, pcContentEnd );
        // close the element
        if( bIsEmptyElement )
            rBuffer.append( '/' );
        rBuffer.append( '>' );
    }

    // append end elements without further processing
    else
    {
        rBuffer.append( rElement );
    }
}

bool lclProcessCharacters( OStringBuffer& rBuffer, const OString& rChars )
{
    /*  MSO has a very weird way to store and handle whitespaces. The stream
        may contain lots of spaces, tabs, and newlines which have to be handled
        as single space character. This will be done in this function.

        If the element text contains a literal line break, it will be stored as
        <br> tag (without matching closing </br> element).
        <br> tag (without matching </br> element). This input stream wrapper
        will replace this element with a literal LF character (see below).

        A single space character for its own is stored as is. Example: The
        element
            <font> </font>
        represents a single space character. The XML parser will ignore this
        space character completely without issuing a 'characters' event. The
        VML import filter implementation has to react on this case manually.

        A single space character following another character is stored
        literally and must not be stipped away here. Example: The element
@@ -167,20 +233,23 @@ void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sa

        Consecutive space characters, or a leading single space character, are
        stored in a <span> element. If there are N space characters (N > 1),
        then the <span> element contains exactly (N-1) NBSP characters
        (non-breaking space), followed by a regular space character. Example:
        then the <span> element contains exactly (N-1) NBSP (non-breaking
        space) characters, followed by a regular space character. Examples:
        The element
            <font><span style='mso-spacerun:yes'>\xA0\xA0\xA0 </span></font>
        represents 4 consecutive space characters. Has to be handled by the
        implementation.

        A single space character for its own is stored in an empty element.
        Example: The element
            <font></font>
        represents a single space character. Has to be handled by the
        implementation.
        implementation. The element
            <font><span style='mso-spacerun:yes'> abc</span></font>
        represents a space characters followed by the letters a, b, c. These
        strings have to be handled by the VML import filter implementation.
     */

    // passed string ends with the leading opening bracket of an XML element
    const sal_Char* pcBeg = rChars.getStr();
    const sal_Char* pcEnd = pcBeg + rChars.getLength();
    bool bHasBracket = (pcBeg < pcEnd) && (pcEnd[ -1 ] == '<');
    if( bHasBracket ) --pcEnd;

    // skip leading whitespace
    const sal_Char* pcContentsBeg = lclFindNonWhiteSpace( pcBeg, pcEnd );
    while( pcContentsBeg < pcEnd )
@@ -191,134 +260,141 @@ void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sa
            rBuffer.append( ' ' );
        pcContentsBeg = lclFindNonWhiteSpace( pcWhitespaceBeg, pcEnd );
    }

    return bHasBracket;
}

} // namespace

// ============================================================================

StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm )
InputStream::InputStream( const Reference< XComponentContext >& rxContext, const Reference< XInputStream >& rxInStrm ) :
    // use single-byte ISO-8859-1 encoding which maps all byte characters to the first 256 Unicode characters
    mxTextStrm( TextInputStream::createXTextInputStream( rxContext, rxInStrm, RTL_TEXTENCODING_ISO_8859_1 ) ),
    maOpeningBracket( 1 ),
    maClosingBracket( 1 ),
    maOpeningCData( CREATE_OSTRING( "<![CDATA[" ) ),
    maClosingCData( CREATE_OSTRING( "]]>" ) ),
    mnBufferPos( 0 )
{
    if( rxInStrm.is() ) try
    {
        // read all bytes we can read
        rxInStrm->readBytes( maDataSeq, SAL_MAX_INT32 );
    }
    catch( Exception& )
    {
    }

    if( maDataSeq.hasElements() )
    {
        const OString aCDataOpen = CREATE_OSTRING( "<![CDATA[" );
        const OString aCDataClose = CREATE_OSTRING( "]]>" );

        OStringBuffer aBuffer;
        aBuffer.ensureCapacity( maDataSeq.getLength() + 256 );
        const sal_Char* pcCurr = reinterpret_cast< const sal_Char* >( maDataSeq.getConstArray() );
        const sal_Char* pcEnd = pcCurr + maDataSeq.getLength();
        while( pcCurr < pcEnd )
        {
            // look for the next opening angle bracket
            const sal_Char* pcOpen = lclFindCharacter( pcCurr, pcEnd, '<' );

            // copy all characters from current position to opening bracket
            lclProcessContents( aBuffer, pcCurr, pcOpen );

            // nothing to do if no opening bracket has been found
            if( pcOpen < pcEnd )
            {
                // string length from opening bracket to end
                sal_Int32 nLengthToEnd = static_cast< sal_Int32 >( pcEnd - pcOpen );

                // check for CDATA part, starting with '<![CDATA['
                if( rtl_str_compare_WithLength( pcOpen, nLengthToEnd, aCDataOpen.getStr(), aCDataOpen.getLength() ) == 0 )
                {
                    // search the position after the end tag ']]>'
                    sal_Int32 nClosePos = rtl_str_indexOfStr_WithLength( pcOpen, nLengthToEnd, aCDataClose.getStr(), aCDataClose.getLength() );
                    pcCurr = (nClosePos < 0) ? pcEnd : (pcOpen + nClosePos + aCDataClose.getLength());
                    // copy the entire CDATA part
                    lclAppendToBuffer( aBuffer, pcOpen, pcCurr );
                }

                // no CDATA part - process the element starting at pcOpen
                else
                {
                    // look for the next closing angle bracket
                    const sal_Char* pcClose = lclFindCharacter( pcOpen + 1, pcEnd, '>' );
                    // complete element found?
                    if( pcClose < pcEnd )
                    {
                        // continue after closing bracket
                        pcCurr = pcClose + 1;
                        // length of entire element with angle brackets
                        sal_Int32 nElementLen = static_cast< sal_Int32 >( pcCurr - pcOpen );

                        // skip parser instructions: '<![...]>'
                        if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') )
                        {
                            // do nothing
                        }

                        // replace '<br>' element with newline
                        else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) )
                        {
                            aBuffer.append( '\n' );
                        }

                        // check start elements and empty elements for repeated attributes
                        else if( pcOpen[ 1 ] != '/' )
                        {
                            // find positions of text content inside brackets, exclude '/' in '<emptyelement/>'
                            const sal_Char* pcContentBeg = pcOpen + 1;
                            bool bIsEmptyElement = pcClose[ -1 ] == '/';
                            const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose;
                            // append element name to buffer
                            const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd );
                            lclAppendToBuffer( aBuffer, pcOpen, pcWhiteSpace );
                            // find begin of attributes, and process all attributes
                            const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd );
                            if( pcAttribBeg < pcContentEnd )
                                lclProcessAttribs( aBuffer, pcAttribBeg, pcContentEnd );
                            // close the element
                            if( bIsEmptyElement )
                                aBuffer.append( '/' );
                            aBuffer.append( '>' );
                        }

                        // append end elements without further processing
                        else
                        {
                            lclAppendToBuffer( aBuffer, pcOpen, pcCurr );
                        }
                    }
                    else
                    {
                        // no complete element found, copy all from opening bracket to end
                        lclAppendToBuffer( aBuffer, pcOpen, pcEnd );
                        pcCurr = pcEnd;
                    }
                }
            }
        }

        // set the final data sequence
        maDataSeq = ::comphelper::ByteSequence( reinterpret_cast< const sal_Int8* >( aBuffer.getStr() ), aBuffer.getLength() );
    }
}

// ============================================================================

InputStream::InputStream( const Reference< XInputStream >& rxInStrm ) :
    StreamDataContainer( rxInStrm ),
    ::comphelper::SequenceInputStream( maDataSeq )
{
    maOpeningBracket[ 0 ] = '<';
    maClosingBracket[ 0 ] = '>';
}

InputStream::~InputStream()
{
}

sal_Int32 SAL_CALL InputStream::readBytes( Sequence< sal_Int8 >& rData, sal_Int32 nBytesToRead )
        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    if( nBytesToRead < 0 )
        throw IOException();

    rData.realloc( nBytesToRead );
    sal_Int8* pcDest = rData.getArray();
    sal_Int32 nRet = 0;
    while( (nBytesToRead > 0) && !mxTextStrm->isEOF() )
    {
        updateBuffer();
        sal_Int32 nReadSize = ::std::min( nBytesToRead, maBuffer.getLength() - mnBufferPos );
        if( nReadSize > 0 )
        {
            memcpy( pcDest + nRet, maBuffer.getStr() + mnBufferPos, static_cast< size_t >( nReadSize ) );
            mnBufferPos += nReadSize;
            nBytesToRead -= nReadSize;
            nRet += nReadSize;
        }
    }
    if( nRet < rData.getLength() )
        rData.realloc( nRet );
    return nRet;
}

sal_Int32 SAL_CALL InputStream::readSomeBytes( Sequence< sal_Int8 >& rData, sal_Int32 nMaxBytesToRead )
        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    return readBytes( rData, nMaxBytesToRead );
}

void SAL_CALL InputStream::skipBytes( sal_Int32 nBytesToSkip )
        throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException)
{
    if( nBytesToSkip < 0 )
        throw IOException();

    while( (nBytesToSkip > 0) && !mxTextStrm->isEOF() )
    {
        updateBuffer();
        sal_Int32 nSkipSize = ::std::min( nBytesToSkip, maBuffer.getLength() - mnBufferPos );
        mnBufferPos += nSkipSize;
        nBytesToSkip -= nSkipSize;
    }
}

sal_Int32 SAL_CALL InputStream::available() throw (NotConnectedException, IOException, RuntimeException)
{
    updateBuffer();
    return maBuffer.getLength() - mnBufferPos;
}

void SAL_CALL InputStream::closeInput() throw (NotConnectedException, IOException, RuntimeException)
{
    mxTextStrm->closeInput();
}

// private --------------------------------------------------------------------

void InputStream::updateBuffer() throw (IOException, RuntimeException)
{
    while( (mnBufferPos >= maBuffer.getLength()) && !mxTextStrm->isEOF() )
    {
        // collect new contents in a string buffer
        OStringBuffer aBuffer;

        // read and process characters until the opening bracket of the next XML element
        OString aChars = readToElementBegin();
        bool bHasOpeningBracket = lclProcessCharacters( aBuffer, aChars );

        // read and process characters until (and including) closing bracket (an XML element)
        OSL_ENSURE( bHasOpeningBracket || mxTextStrm->isEOF(), "InputStream::updateBuffer - missing opening bracket of XML element" );
        if( bHasOpeningBracket && !mxTextStrm->isEOF() )
        {
            // read the element text (add the leading opening bracket manually)
            OString aElement = OString( '<' ) + readToElementEnd();
            // check for CDATA part, starting with '<![CDATA['
            if( aElement.match( maOpeningCData ) )
            {
                // search the end tag ']]>'
                while( ((aElement.getLength() < maClosingCData.getLength()) || !aElement.match( maClosingCData, aElement.getLength() - maClosingCData.getLength() )) && !mxTextStrm->isEOF() )
                    aElement += readToElementEnd();
                // copy the entire CDATA part
                aBuffer.append( aElement );
            }
            else
            {
                // no CDATA part - process the contents of the element
                lclProcessElement( aBuffer, aElement );
            }
        }

        maBuffer = aBuffer.makeStringAndClear();
        mnBufferPos = 0;
    }
}

OString InputStream::readToElementBegin() throw (IOException, RuntimeException)
{
    return OUStringToOString( mxTextStrm->readString( maOpeningBracket, sal_False ), RTL_TEXTENCODING_ISO_8859_1 );
}

OString InputStream::readToElementEnd() throw (IOException, RuntimeException)
{
    OString aText = OUStringToOString( mxTextStrm->readString( maClosingBracket, sal_False ), RTL_TEXTENCODING_ISO_8859_1 );
    OSL_ENSURE( (aText.getLength() > 0) && (aText[ aText.getLength() - 1 ] == '>'), "InputStream::readToElementEnd - missing closing bracket of XML element" );
    return aText;
}

// ============================================================================

} // namespace vml
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index d266e05..5e1a9a8 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -274,9 +274,10 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS
            xShape = implConvertAndInsert( rxShapes, aShapeRect );
            if( xShape.is() )
            {
                // set shape name (imported or generated)
                // set imported or generated shape name (not supported by form controls)
                PropertySet aShapeProp( xShape );
                aShapeProp.setProperty( PROP_Name, getShapeName() );
                if( aShapeProp.hasProperty( PROP_Name ) )
                    aShapeProp.setProperty( PROP_Name, getShapeName() );

                /*  Notify the drawing that a new shape has been inserted. For
                    convenience, pass the rectangle that contains position and
diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx
index 4b57656..6feae68 100755
--- a/oox/source/vml/vmltextboxcontext.cxx
+++ b/oox/source/vml/vmltextboxcontext.cxx
@@ -75,6 +75,8 @@ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent,
            OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" );
            maFont.mobStrikeout = true;
        break;
        case XML_span:
        break;
        default:
            OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" );
    }
@@ -92,7 +94,7 @@ void TextPortionContext::onCharacters( const OUString& rChars )
    {
        case XML_span:
            // replace all NBSP characters with SP
            mrTextBox.appendPortion( maFont, rChars.replace( 160, ' ' ) );
            mrTextBox.appendPortion( maFont, rChars.replace( 0xA0, ' ' ) );
        break;
        default:
            mrTextBox.appendPortion( maFont, rChars );
@@ -101,19 +103,23 @@ void TextPortionContext::onCharacters( const OUString& rChars )

void TextPortionContext::onEndElement()
{
    /*  An empty child element without own child elements represents a single
        space character, for example:
    /*  A child element without own child elements may contain a single space
        character, for example:

            <font>
              <i>abc</i>
              <font></font>
              <b>def</b>
            </font>
          <div>
            <font><i>abc</i></font>
            <font> </font>
            <font><b>def</b></font>
          </div>

        represents the italic text 'abc', an unformatted space character, and
        the bold text 'def'.
        the bold text 'def'. Unfortunately, the XML parser skips the space
        character without issuing a 'characters' event. The class member
        'mnInitialPortions' contains the number of text portions existing when
        this context has been constructed. If no text has been added in the
        meantime, the space character has to be added manually.
     */
    if( (mnInitialPortions > 0) && (mrTextBox.getPortionCount() == mnInitialPortions) )
    if( mrTextBox.getPortionCount() == mnInitialPortions )
        mrTextBox.appendPortion( maFont, OUString( sal_Unicode( ' ' ) ) );
}

@@ -143,4 +149,3 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att

} // namespace vml
} // namespace oox

diff --git a/oox/source/xls/addressconverter.cxx b/oox/source/xls/addressconverter.cxx
index 6d53be0..ca216bb 100644
--- a/oox/source/xls/addressconverter.cxx
+++ b/oox/source/xls/addressconverter.cxx
@@ -98,12 +98,12 @@ const sal_Unicode BIFF_DCON_ENCODED = '\x01';       /// First character of an en
const sal_Unicode BIFF_DCON_INTERN  = '\x02';       /// First character of an encoded sheet name from DCON* records.


inline sal_uInt16 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit )
inline sal_uInt8 lclGetBiffAddressSize( bool bCol16Bit, bool bRow32Bit )
{
    return (bCol16Bit ? 2 : 1) + (bRow32Bit ? 4 : 2);
}

inline sal_uInt16 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit )
inline sal_uInt8 lclGetBiffRangeSize( bool bCol16Bit, bool bRow32Bit )
{
    return 2 * lclGetBiffAddressSize( bCol16Bit, bRow32Bit );
}
diff --git a/oox/source/xls/biffdetector.cxx b/oox/source/xls/biffdetector.cxx
index 038d7d7..9c8267f 100644
--- a/oox/source/xls/biffdetector.cxx
+++ b/oox/source/xls/biffdetector.cxx
@@ -82,14 +82,14 @@ BiffDetector::~BiffDetector()
/*static*/ BiffType BiffDetector::detectStreamBiffVersion( BinaryInputStream& rInStream )
{
    BiffType eBiff = BIFF_UNKNOWN;
    if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.getLength() > 4) )
    if( !rInStream.isEof() && rInStream.isSeekable() && (rInStream.size() > 4) )
    {
        sal_Int64 nOldPos = rInStream.tell();
        rInStream.seekToStart();
        sal_uInt16 nBofId, nBofSize;
        rInStream >> nBofId >> nBofSize;

        if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.getLength()) )
        if( (4 <= nBofSize) && (nBofSize <= 16) && (rInStream.tell() + nBofSize <= rInStream.size()) )
        {
            switch( nBofId )
            {
@@ -207,9 +207,8 @@ OUString SAL_CALL BiffDetector::detect( Sequence< PropertyValue >& rDescriptor )
    MediaDescriptor aDescriptor( rDescriptor );
    aDescriptor.addInputStream();

    Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY_THROW );
    Reference< XInputStream > xInStrm( aDescriptor[ MediaDescriptor::PROP_INPUTSTREAM() ], UNO_QUERY_THROW );
    StorageRef xStorage( new ::oox::ole::OleStorage( xFactory, xInStrm, true ) );
    StorageRef xStorage( new ::oox::ole::OleStorage( mxContext, xInStrm, true ) );

    OUString aWorkbookName;
    switch( detectStorageBiffVersion( aWorkbookName, xStorage ) )
diff --git a/oox/source/xls/biffhelper.cxx b/oox/source/xls/biffhelper.cxx
index 5583904..b4a3a98 100644
--- a/oox/source/xls/biffhelper.cxx
+++ b/oox/source/xls/biffhelper.cxx
@@ -269,7 +269,7 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm,

// BIFF12 import --------------------------------------------------------------

/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen )
/*static*/ OUString BiffHelper::readString( SequenceInputStream& rStrm, bool b32BitLen, bool bAllowNulChars )
{
    OUString aString;
    if( !rStrm.isEof() )
@@ -279,16 +279,9 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm,
        OSL_ENSURE( !rStrm.isEof() && (nCharCount >= -1), "BiffHelper::readString - invalid string length" );
        if( !rStrm.isEof() && (nCharCount > 0) )
        {
            ::std::vector< sal_Unicode > aBuffer;
            aBuffer.reserve( getLimitedValue< size_t, sal_Int32 >( nCharCount + 1, 0, 0xFFFF ) );
            for( sal_Int32 nCharIdx = 0; !rStrm.isEof() && (nCharIdx < nCharCount); ++nCharIdx )
            {
                sal_uInt16 nChar;
                rStrm.readValue( nChar );
                aBuffer.push_back( static_cast< sal_Unicode >( nChar ) );
            }
            aBuffer.push_back( 0 );
            aString = OUString( &aBuffer.front() );
            // SequenceInputStream always supports getRemaining()
            nCharCount = ::std::min( nCharCount, static_cast< sal_Int32 >( rStrm.getRemaining() / 2 ) );
            aString = rStrm.readUnicodeArray( nCharCount, bAllowNulChars );
        }
    }
    return aString;
diff --git a/oox/source/xls/biffinputstream.cxx b/oox/source/xls/biffinputstream.cxx
index 6dfa8f7..b11137a 100644
--- a/oox/source/xls/biffinputstream.cxx
+++ b/oox/source/xls/biffinputstream.cxx
@@ -87,7 +87,7 @@ void BiffInputRecordBuffer::enableDecoder( bool bEnable )

bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos )
{
    mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.getLength());
    mbValidHeader = (0 <= nHeaderPos) && (nHeaderPos + 4 <= mrInStrm.size());
    if( mbValidHeader )
    {
        mnHeaderPos = nHeaderPos;
@@ -95,7 +95,7 @@ bool BiffInputRecordBuffer::startRecord( sal_Int64 nHeaderPos )
        mrInStrm >> mnRecId >> mnRecSize;
        mnBodyPos = mrInStrm.tell();
        mnNextHeaderPos = mnBodyPos + mnRecSize;
        mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.getLength());
        mbValidHeader = !mrInStrm.isEof() && (mnNextHeaderPos <= mrInStrm.size());
    }
    if( !mbValidHeader )
    {
@@ -116,7 +116,7 @@ bool BiffInputRecordBuffer::startNextRecord()
sal_uInt16 BiffInputRecordBuffer::getNextRecId()
{
    sal_uInt16 nRecId = BIFF_ID_UNKNOWN;
    if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.getLength()) )
    if( mbValidHeader && (mnNextHeaderPos + 4 <= mrInStrm.size()) )
    {
        mrInStrm.seek( mnNextHeaderPos );
        mrInStrm >> nRecId;
@@ -169,6 +169,7 @@ void BiffInputRecordBuffer::updateDecoded()
// ============================================================================

BiffInputStream::BiffInputStream( BinaryInputStream& rInStream, bool bContLookup ) :
    BinaryStreamBase( true ),
    maRecBuffer( rInStream ),
    mnRecHandle( -1 ),
    mnRecId( BIFF_ID_UNKNOWN ),
@@ -257,9 +258,11 @@ sal_uInt16 BiffInputStream::getNextRecId()

// BinaryStreamBase interface (seeking) ---------------------------------------

bool BiffInputStream::isSeekable() const
sal_Int64 BiffInputStream::size() const
{
    return true;
    if( !mbHasComplRec )
        const_cast< BiffInputStream* >( this )->calcRecordLength();
    return mnComplRecSize;
}

sal_Int64 BiffInputStream::tell() const
@@ -267,13 +270,6 @@ sal_Int64 BiffInputStream::tell() const
    return mbEof ? -1 : (mnCurrRecSize - maRecBuffer.getRecLeft());
}

sal_Int64 BiffInputStream::getLength() const
{
    if( !mbHasComplRec )
        const_cast< BiffInputStream* >( this )->calcRecordLength();
    return mnComplRecSize;
}

void BiffInputStream::seek( sal_Int64 nRecPos )
{
    if( isInRecord() )
@@ -285,35 +281,35 @@ void BiffInputStream::seek( sal_Int64 nRecPos )
    }
}

void BiffInputStream::close()
{
}

sal_Int64 BiffInputStream::tellBase() const
{
    return maRecBuffer.getBaseStream().tell();
}

sal_Int64 BiffInputStream::getBaseLength() const
sal_Int64 BiffInputStream::sizeBase() const
{
    return maRecBuffer.getBaseStream().getLength();
    return maRecBuffer.getBaseStream().size();
}

// BinaryInputStream interface (stream read access) ---------------------------

sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes )
sal_Int32 BiffInputStream::readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nRet = 0;
    if( !mbEof )
    {
        orData.realloc( ::std::max< sal_Int32 >( nBytes, 0 ) );
        if( nBytes > 0 )
        {
            nRet = readMemory( orData.getArray(), nBytes );
            if( nRet < nBytes )
                orData.realloc( nRet );
        }
            nRet = readMemory( orData.getArray(), nBytes, nAtomSize );
    }
    return nRet;
}

sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes )
sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nRet = 0;
    if( !mbEof && opMem && (nBytes > 0) )
@@ -323,7 +319,7 @@ sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes )

        while( !mbEof && (nBytesLeft > 0) )
        {
            sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft );
            sal_uInt16 nReadSize = getMaxRawReadSize( nBytesLeft, nAtomSize );
            // check nReadSize, stream may already be located at end of a raw record
            if( nReadSize > 0 )
            {
@@ -340,12 +336,12 @@ sal_Int32 BiffInputStream::readMemory( void* opMem, sal_Int32 nBytes )
    return nRet;
}

void BiffInputStream::skip( sal_Int32 nBytes )
void BiffInputStream::skip( sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nBytesLeft = nBytes;
    while( !mbEof && (nBytesLeft > 0) )
    {
        sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft );
        sal_uInt16 nSkipSize = getMaxRawReadSize( nBytesLeft, nAtomSize );
        // check nSkipSize, stream may already be located at end of a raw record
        if( nSkipSize > 0 )
        {
@@ -383,28 +379,22 @@ OUString BiffInputStream::readUniStringChars( sal_uInt16 nChars, bool b16BitChar
    OUStringBuffer aBuffer;
    aBuffer.ensureCapacity( nChars );

    /*  This function has to react on CONTINUE records to read the repeated
        flags field, so readUnicodeArray() cannot be used here. */
    sal_uInt16 nCharsLeft = nChars;
    /*  This function has to react on CONTINUE records which repeat the flags
        field in their first byte and may change the 8bit/16bit character mode,
        thus a plain call to readCompressedUnicodeArray() cannot be used here. */
    sal_Int32 nCharsLeft = nChars;
    while( !mbEof && (nCharsLeft > 0) )
    {
        sal_uInt16 nPortionCount = 0;
        if( b16BitChars )
        {
            nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 );
            OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0),
                "BiffInputStream::readUniStringChars - missing a byte" );
        }
        else
        {
            nPortionCount = getMaxRawReadSize( nCharsLeft );
        }
        /*  Read the character array from the remaining part of the current raw
            record. First, calculate the maximum number of characters that can
            be read without triggering to start a following CONTINUE record. */
        sal_Int32 nRawChars = b16BitChars ? (getMaxRawReadSize( nCharsLeft * 2, 2 ) / 2) : getMaxRawReadSize( nCharsLeft, 1 );
        aBuffer.append( readCompressedUnicodeArray( nRawChars, !b16BitChars, bAllowNulChars ) );

        // read the character array
        appendUnicodeArray( aBuffer, nPortionCount, b16BitChars, bAllowNulChars );

        // prepare for next CONTINUE record
        nCharsLeft = nCharsLeft - nPortionCount;
        /*  Prepare for next CONTINUE record. Calling jumpToNextStringContinue()
            reads the leading byte in the following CONTINUE record and updates
            the b16BitChars flag. */
        nCharsLeft -= nRawChars;
        if( nCharsLeft > 0 )
            jumpToNextStringContinue( b16BitChars );
    }
@@ -429,25 +419,15 @@ OUString BiffInputStream::readUniString( bool bAllowNulChars )

void BiffInputStream::skipUniStringChars( sal_uInt16 nChars, bool b16BitChars )
{
    sal_uInt16 nCharsLeft = nChars;
    sal_Int32 nCharsLeft = nChars;
    while( !mbEof && (nCharsLeft > 0) )
    {
        sal_uInt16 nPortionCount;
        if( b16BitChars )
        {
            nPortionCount = ::std::min< sal_uInt16 >( nCharsLeft, maRecBuffer.getRecLeft() / 2 );
            OSL_ENSURE( (nPortionCount <= nCharsLeft) || ((maRecBuffer.getRecLeft() & 1) == 0),
                "BiffInputStream::skipUniStringChars - missing a byte" );
            skip( 2 * nPortionCount );
        }
        else
        {
            nPortionCount = getMaxRawReadSize( nCharsLeft );
            skip( nPortionCount );
        }
        // skip the character array
        sal_Int32 nSkipSize = b16BitChars ? getMaxRawReadSize( 2 * nCharsLeft, 2 ) : getMaxRawReadSize( nCharsLeft, 1 );
        skip( nSkipSize );

        // prepare for next CONTINUE record
        nCharsLeft = nCharsLeft - nPortionCount;
        nCharsLeft -= (b16BitChars ? (nSkipSize / 2) : nSkipSize);
        if( nCharsLeft > 0 )
            jumpToNextStringContinue( b16BitChars );
    }
@@ -469,13 +449,6 @@ void BiffInputStream::skipUniString()

// private --------------------------------------------------------------------

void BiffInputStream::readAtom( void* opMem, sal_uInt8 nSize )
{
    // byte swapping is done in calling BinaryInputStream::readValue() template function
    if( ensureRawReadSize( nSize ) )
        maRecBuffer.read( opMem, nSize );
}

void BiffInputStream::setupRecord()
{
    // initialize class members
@@ -529,7 +502,7 @@ bool BiffInputStream::jumpToNextContinue()

bool BiffInputStream::jumpToNextStringContinue( bool& rb16BitChars )
{
    OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - unexpected garbage" );
    OSL_ENSURE( maRecBuffer.getRecLeft() == 0, "BiffInputStream::jumpToNextStringContinue - alignment error" );

    if( mbCont && (getRemaining() > 0) )
    {
@@ -561,31 +534,17 @@ void BiffInputStream::calcRecordLength()
    seek( nCurrPos );                       // restore position, seek() resets old mbValid state
}

bool BiffInputStream::ensureRawReadSize( sal_uInt16 nBytes )
sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes, size_t nAtomSize ) const
{
    if( !mbEof && (nBytes > 0) )
    sal_uInt16 nMaxSize = getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() );
    if( (0 < nMaxSize) && (nMaxSize < nBytes) && (nAtomSize > 1) )
    {
        while( !mbEof && (maRecBuffer.getRecLeft() == 0) ) jumpToNextContinue();
        mbEof = mbEof || (nBytes > maRecBuffer.getRecLeft());
        OSL_ENSURE( !mbEof, "BiffInputStream::ensureRawReadSize - record overread" );
        // check that remaining data in record buffer is a multiple of the passed atom size
        sal_uInt16 nPadding = static_cast< sal_uInt16 >( nMaxSize % nAtomSize );
        OSL_ENSURE( nPadding == 0, "BiffInputStream::getMaxRawReadSize - alignment error" );
        nMaxSize = nMaxSize - nPadding;
    }
    return !mbEof;
}

sal_uInt16 BiffInputStream::getMaxRawReadSize( sal_Int32 nBytes ) const
{
    return getLimitedValue< sal_uInt16, sal_Int32 >( nBytes, 0, maRecBuffer.getRecLeft() );
}

void BiffInputStream::appendUnicodeArray( OUStringBuffer& orBuffer, sal_uInt16 nChars, bool b16BitChars, bool bAllowNulChars )
{
    orBuffer.ensureCapacity( orBuffer.getLength() + nChars );
    sal_uInt16 nChar;
    for( sal_uInt16 nCharIdx = 0; !mbEof && (nCharIdx < nChars); ++nCharIdx )
    {
        if( b16BitChars ) readValue( nChar ); else nChar = readuInt8();
        orBuffer.append( static_cast< sal_Unicode >( (!bAllowNulChars && (nChar == 0)) ? '?' : nChar ) );
    }
    return nMaxSize;
}

void BiffInputStream::readUniStringHeader( bool& orb16BitChars, sal_Int32& ornAddSize )
diff --git a/oox/source/xls/biffoutputstream.cxx b/oox/source/xls/biffoutputstream.cxx
index ba59f50..1460841 100644
--- a/oox/source/xls/biffoutputstream.cxx
+++ b/oox/source/xls/biffoutputstream.cxx
@@ -85,6 +85,7 @@ void BiffOutputRecordBuffer::fill( sal_uInt8 nValue, sal_uInt16 nBytes )
// ============================================================================

BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 nMaxRecSize ) :
    BinaryStreamBase( true ),
    maRecBuffer( rOutStream, nMaxRecSize ),
    mnPortionSize( 0 ),
    mnPortionPos( 0 )
@@ -96,19 +97,19 @@ BiffOutputStream::BiffOutputStream( BinaryOutputStream& rOutStream, sal_uInt16 n
void BiffOutputStream::startRecord( sal_uInt16 nRecId )
{
    maRecBuffer.startRecord( nRecId );
    setPortionSize( 0 );
    setPortionSize( 1 );
}

void BiffOutputStream::endRecord()
{
    setPortionSize( 0 );
    setPortionSize( 1 );
    maRecBuffer.endRecord();
}

void BiffOutputStream::setPortionSize( sal_uInt16 nSize )
void BiffOutputStream::setPortionSize( sal_uInt8 nSize )
{
    OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::setPortionSize - block operation inside portion" );
    mnPortionSize = nSize;
    mnPortionSize = ::std::max< sal_uInt8 >( nSize, 1 );
    mnPortionPos = 0;
}

@@ -119,20 +120,20 @@ sal_Int64 BiffOutputStream::tellBase() const
    return maRecBuffer.getBaseStream().tell();
}

sal_Int64 BiffOutputStream::getBaseLength() const
sal_Int64 BiffOutputStream::sizeBase() const
{
    return maRecBuffer.getBaseStream().getLength();
    return maRecBuffer.getBaseStream().size();
}

// BinaryOutputStream interface (stream write access) -------------------------

void BiffOutputStream::writeData( const StreamDataSequence& rData )
void BiffOutputStream::writeData( const StreamDataSequence& rData, size_t nAtomSize )
{
    if( rData.hasElements() )
        writeMemory( rData.getConstArray(), rData.getLength() );
        writeMemory( rData.getConstArray(), rData.getLength(), nAtomSize );
}

void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize )
{
    if( pMem && (nBytes > 0) )
    {
@@ -140,7 +141,7 @@ void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
        sal_Int32 nBytesLeft = nBytes;
        while( nBytesLeft > 0 )
        {
            sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft );
            sal_uInt16 nBlockSize = prepareWriteBlock( nBytesLeft, nAtomSize );
            maRecBuffer.write( pnBuffer, nBlockSize );
            pnBuffer += nBlockSize;
            nBytesLeft -= nBlockSize;
@@ -148,59 +149,60 @@ void BiffOutputStream::writeMemory( const void* pMem, sal_Int32 nBytes )
    }
}

void BiffOutputStream::fill( sal_uInt8 nValue, sal_Int32 nBytes )
void BiffOutputStream::fill( sal_uInt8 nValue, sal_Int32 nBytes, size_t nAtomSize )
{
    sal_Int32 nBytesLeft = nBytes;
    while( nBytesLeft > 0 )
    {
        sal_uInt16 nBlockSize = prepareRawBlock( nBytesLeft );
        sal_uInt16 nBlockSize = prepareWriteBlock( nBytesLeft, nAtomSize );
        maRecBuffer.fill( nValue, nBlockSize );
        nBytesLeft -= nBlockSize;
    }
}

void BiffOutputStream::writeBlock( const void* pMem, sal_uInt16 nBytes )
{
    ensureRawBlock( nBytes );
    maRecBuffer.write( pMem, nBytes );
}

// private --------------------------------------------------------------------

void BiffOutputStream::writeAtom( const void* pMem, sal_uInt8 nSize )
{
    // byte swapping is done in calling BinaryOutputStream::writeValue() template function
    writeBlock( pMem, nSize );
}

void BiffOutputStream::ensureRawBlock( sal_uInt16 nSize )
{
    if( (maRecBuffer.getRecLeft() < nSize) ||
        ((mnPortionSize > 0) && (mnPortionPos == 0) && (maRecBuffer.getRecLeft() < mnPortionSize)) )
    {
        maRecBuffer.endRecord();
        maRecBuffer.startRecord( BIFF_ID_CONT );
    }
    if( mnPortionSize > 0 )
    {
        OSL_ENSURE( mnPortionPos + nSize <= mnPortionSize, "BiffOutputStream::ensureRawBlock - portion overflow" );
        mnPortionPos = (mnPortionPos + nSize) % mnPortionSize;  // prevent compiler warning, do not use operator+=, operator%=
    }
}

sal_uInt16 BiffOutputStream::prepareRawBlock( sal_Int32 nTotalSize )
sal_uInt16 BiffOutputStream::prepareWriteBlock( sal_Int32 nTotalSize, size_t nAtomSize )
{
    sal_uInt16 nRecLeft = maRecBuffer.getRecLeft();
    if( mnPortionSize > 0 )
    if( mnPortionSize <= 1 )
    {
        OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareRawBlock - block operation inside portion" );
        OSL_ENSURE( nTotalSize % mnPortionSize == 0, "BiffOutputStream::prepareRawBlock - portion size does not match block size" );
        nRecLeft = (nRecLeft / mnPortionSize) * mnPortionSize;
        // no portions: restrict remaining record size to entire atoms
        nRecLeft = static_cast< sal_uInt16 >( (nRecLeft / nAtomSize) * nAtomSize );
    }
    sal_uInt16 nSize = getLimitedValue< sal_uInt16, sal_Int32 >( nTotalSize, 0, nRecLeft );
    ensureRawBlock( nSize );
    return nSize;
    else
    {
        sal_Int32 nPortionLeft = mnPortionSize - mnPortionPos;
        if( nTotalSize <= nPortionLeft )
        {
            // block fits into the current portion
            OSL_ENSURE( nPortionLeft <= nRecLeft, "BiffOutputStream::prepareWriteBlock - portion exceeds record" );
            mnPortionPos = static_cast< sal_uInt8 >( (mnPortionPos + nTotalSize) % mnPortionSize );
        }
        else
        {
            // restrict remaining record size to entire portions
            OSL_ENSURE( mnPortionPos == 0, "BiffOutputStream::prepareWriteBlock - writing over multiple portions starts inside portion" );
            mnPortionPos = 0;
            // check that atom size matches portion size
            OSL_ENSURE( mnPortionSize % nAtomSize == 0, "BiffOutputStream::prepareWriteBlock - atom size does not match portion size" );
            sal_uInt8 nPortionSize = static_cast< sal_uInt8 >( (mnPortionSize / nAtomSize) * nAtomSize );
            // restrict remaining record size to entire portions
            nRecLeft = (nRecLeft / nPortionSize) * nPortionSize;
        }
    }

    // current record has space for some data: return size of available space
    if( nRecLeft > 0 )
        return getLimitedValue< sal_uInt16, sal_Int32 >( nTotalSize, 0, nRecLeft );

    // finish current record and start a new CONTINUE record
    maRecBuffer.endRecord();
    maRecBuffer.startRecord( BIFF_ID_CONT );
    mnPortionPos = 0;
    return prepareWriteBlock( nTotalSize, nAtomSize );
}

// ============================================================================

} // namespace xls
diff --git a/oox/source/xls/drawingmanager.cxx b/oox/source/xls/drawingmanager.cxx
index 3ee5c45..efba682 100755
--- a/oox/source/xls/drawingmanager.cxx
+++ b/oox/source/xls/drawingmanager.cxx
@@ -1374,8 +1374,7 @@ Reference< XShape > BiffDrawingBase::createAndInsertXShape( const OUString& rSer
    Reference< XShape > xShape;
    if( (rService.getLength() > 0) && rxShapes.is() ) try
    {
        Reference< XMultiServiceFactory > xFactory( getDocumentFactory(), UNO_SET_THROW );
        xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW );
        xShape.set( getBaseFilter().getModelFactory()->createInstance( rService ), UNO_QUERY_THROW );
        // insert shape into passed shape collection (maybe drawpage or group shape)
        rxShapes->add( xShape );
        xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) );
diff --git a/oox/source/xls/excelchartconverter.cxx b/oox/source/xls/excelchartconverter.cxx
index 53c0a3b..702a12f 100644
--- a/oox/source/xls/excelchartconverter.cxx
+++ b/oox/source/xls/excelchartconverter.cxx
@@ -30,6 +30,7 @@
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/chart2/data/XDataProvider.hpp>
#include <com/sun/star/chart2/data/XDataReceiver.hpp>
#include "oox/core/filterbase.hxx"
#include "oox/drawingml/chart/datasourcemodel.hxx"
#include "oox/helper/containerhelper.hxx"
#include "oox/xls/formulaparser.hxx"
@@ -64,8 +65,7 @@ void ExcelChartConverter::createDataProvider( const Reference< XChartDocument >&
    try
    {
        Reference< XDataReceiver > xDataRec( rxChartDoc, UNO_QUERY_THROW );
        Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
        Reference< XDataProvider > xDataProv( xFactory->createInstance(
        Reference< XDataProvider > xDataProv( getBaseFilter().getModelFactory()->createInstance(
            CREATE_OUSTRING( "com.sun.star.chart2.data.DataProvider" ) ), UNO_QUERY_THROW );
        xDataRec->attachDataProvider( xDataProv );
    }
diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx
index f097dec..58049f48 100755
--- a/oox/source/xls/formulabase.cxx
+++ b/oox/source/xls/formulabase.cxx
@@ -1025,7 +1025,7 @@ struct OpCodeProviderImpl : public ApiOpCodes

    explicit            OpCodeProviderImpl(
                            const FunctionInfoVector& rFuncInfos,
                            const Reference< XMultiServiceFactory >& rxFactory );
                            const Reference< XMultiServiceFactory >& rxModelFactory );

private:
    typedef ::std::map< OUString, ApiToken >    ApiTokenMap;
@@ -1047,11 +1047,11 @@ private:
// ----------------------------------------------------------------------------

OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos,
        const Reference< XMultiServiceFactory >& rxFactory )
        const Reference< XMultiServiceFactory >& rxModelFactory )
{
    if( rxFactory.is() ) try
    if( rxModelFactory.is() ) try
    {
        Reference< XFormulaOpCodeMapper > xMapper( rxFactory->createInstance(
        Reference< XFormulaOpCodeMapper > xMapper( rxModelFactory->createInstance(
            CREATE_OUSTRING( "com.sun.star.sheet.FormulaOpCodeMapper" ) ), UNO_QUERY_THROW );

        // op-codes provided as attributes
@@ -1297,10 +1297,10 @@ bool OpCodeProviderImpl::initFuncOpCodes( const ApiTokenMap& rIntFuncTokenMap, c

// ----------------------------------------------------------------------------

OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxFactory,
OpCodeProvider::OpCodeProvider( const Reference< XMultiServiceFactory >& rxModelFactory,
        FilterType eFilter, BiffType eBiff, bool bImportFilter ) :
    FunctionProvider( eFilter, eBiff, bImportFilter ),
    mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxFactory ) )
    mxOpCodeImpl( new OpCodeProviderImpl( getFuncs(), rxModelFactory ) )
{
}

@@ -1335,12 +1335,12 @@ Sequence< FormulaOpCodeMapEntry > OpCodeProvider::getOoxParserMap() const
// API formula parser wrapper =================================================

ApiParserWrapper::ApiParserWrapper(
        const Reference< XMultiServiceFactory >& rxFactory, const OpCodeProvider& rOpCodeProv ) :
        const Reference< XMultiServiceFactory >& rxModelFactory, const OpCodeProvider& rOpCodeProv ) :
    OpCodeProvider( rOpCodeProv )
{
    if( rxFactory.is() ) try
    if( rxModelFactory.is() ) try
    {
        mxParser.set( rxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW );
        mxParser.set( rxModelFactory->createInstance( CREATE_OUSTRING( "com.sun.star.sheet.FormulaParser" ) ), UNO_QUERY_THROW );
    }
    catch( Exception& )
    {
@@ -1483,7 +1483,7 @@ TokenToRangeListState lclProcessClose( sal_Int32& ornParenLevel )
// ----------------------------------------------------------------------------

FormulaProcessorBase::FormulaProcessorBase( const WorkbookHelper& rHelper ) :
    OpCodeProvider( rHelper.getDocumentFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ),
    OpCodeProvider( rHelper.getBaseFilter().getModelFactory(), rHelper.getFilterType(), rHelper.getBiff(), rHelper.getBaseFilter().isImportFilter() ),
    ApiOpCodes( getOpCodes() ),
    WorkbookHelper( rHelper )
{
diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx
index 26bf669..d7eb91a 100644
--- a/oox/source/xls/formulaparser.cxx
+++ b/oox/source/xls/formulaparser.cxx
@@ -1313,7 +1313,7 @@ private:

OoxFormulaParserImpl::OoxFormulaParserImpl( const FormulaParser& rParent ) :
    FormulaParserImpl( rParent ),
    maApiParser( rParent.getDocumentFactory(), rParent ),
    maApiParser( rParent.getBaseFilter().getModelFactory(), rParent ),
    mnAddDataPos( 0 ),
    mbNeedExtRefs( true )
{
diff --git a/oox/source/xls/numberformatsbuffer.cxx b/oox/source/xls/numberformatsbuffer.cxx
index c77381b..782c138 100644
--- a/oox/source/xls/numberformatsbuffer.cxx
+++ b/oox/source/xls/numberformatsbuffer.cxx
@@ -1950,7 +1950,7 @@ NumberFormatsBuffer::NumberFormatsBuffer( const WorkbookHelper& rHelper ) :
    // get the current locale
    try
    {
        Reference< XMultiServiceFactory > xConfigProv( getGlobalFactory()->createInstance(
        Reference< XMultiServiceFactory > xConfigProv( getBaseFilter().getServiceFactory()->createInstance(
            CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationProvider" ) ), UNO_QUERY_THROW );

        // try user-defined locale setting
diff --git a/oox/source/xls/ooxformulaparser.cxx b/oox/source/xls/ooxformulaparser.cxx
index efa69ab..a8860a8 100644
--- a/oox/source/xls/ooxformulaparser.cxx
+++ b/oox/source/xls/ooxformulaparser.cxx
@@ -47,7 +47,7 @@ using ::rtl::OUString;
class OOXMLFormulaParserImpl : private FormulaFinalizer
{
public:
    explicit            OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory );
    explicit            OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory );

    Sequence< FormulaToken > parseFormula( const OUString& rFormula, const CellAddress& rReferencePos );

@@ -60,9 +60,9 @@ private:

// ----------------------------------------------------------------------------

OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
    FormulaFinalizer( OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ),
    maApiParser( rxFactory, *this )
OOXMLFormulaParserImpl::OOXMLFormulaParserImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) :
    FormulaFinalizer( OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, true ) ),
    maApiParser( rxModelFactory, *this )
{
}

@@ -115,7 +115,7 @@ const FunctionInfo* OOXMLFormulaParserImpl::resolveBadFuncName( const OUString& 
class OOXMLFormulaPrinterImpl : public OpCodeProvider
{
public:
    explicit            OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory );
    explicit            OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory );

private:
    ApiParserWrapper    maApiParser;
@@ -123,9 +123,9 @@ private:

// ----------------------------------------------------------------------------

OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxFactory ) :
    OpCodeProvider( rxFactory, FILTER_OOXML, BIFF_UNKNOWN, false ),
    maApiParser( rxFactory, *this )
OOXMLFormulaPrinterImpl::OOXMLFormulaPrinterImpl( const Reference< XMultiServiceFactory >& rxModelFactory ) :
    OpCodeProvider( rxModelFactory, FILTER_OOXML, BIFF_UNKNOWN, false ),
    maApiParser( rxModelFactory, *this )
{
}

@@ -202,8 +202,8 @@ Sequence< FormulaToken > SAL_CALL OOXMLFormulaParser::parseFormula(
{
    if( !mxParserImpl )
    {
        Reference< XMultiServiceFactory > xFactory( mxComponent, UNO_QUERY_THROW );
        mxParserImpl.reset( new OOXMLFormulaParserImpl( xFactory ) );
        Reference< XMultiServiceFactory > xModelFactory( mxComponent, UNO_QUERY_THROW );
        mxParserImpl.reset( new OOXMLFormulaParserImpl( xModelFactory ) );
    }
    return mxParserImpl->parseFormula( rFormula, rReferencePos );
}
diff --git a/oox/source/xls/pagesettings.cxx b/oox/source/xls/pagesettings.cxx
index 188bf78..5c1770b 100644
--- a/oox/source/xls/pagesettings.cxx
+++ b/oox/source/xls/pagesettings.cxx
@@ -903,8 +903,7 @@ Reference< XTextContent > HeaderFooterParser::createField( const OUString& rServ
    Reference< XTextContent > xContent;
    try
    {
        Reference< XMultiServiceFactory > xFactory( getDocument(), UNO_QUERY_THROW );
        xContent.set( xFactory->createInstance( rServiceName ), UNO_QUERY_THROW );
        xContent.set( getBaseFilter().getModelFactory()->createInstance( rServiceName ), UNO_QUERY_THROW );
    }
    catch( Exception& )
    {
diff --git a/oox/source/xls/pivotcachebuffer.cxx b/oox/source/xls/pivotcachebuffer.cxx
index e8ca353..5e5e5ef 100644
--- a/oox/source/xls/pivotcachebuffer.cxx
+++ b/oox/source/xls/pivotcachebuffer.cxx
@@ -737,7 +737,7 @@ void PivotCacheField::importPCDFRangePr( BiffInputStream& rStrm )

void PivotCacheField::importPCDFDiscretePr( BiffInputStream& rStrm )
{
    sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.getLength() / 2 );
    sal_Int32 nCount = static_cast< sal_Int32 >( rStrm.size() / 2 );
    for( sal_Int32 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex )
        maDiscreteItems.push_back( rStrm.readuInt16() );
}
diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx
index c9658dd..e23273b 100644
--- a/oox/source/xls/viewsettings.cxx
+++ b/oox/source/xls/viewsettings.cxx
@@ -734,7 +734,7 @@ void ViewSettings::finalizeImport()
    sal_Int16 nShowMode = getWorkbookSettings().getApiShowObjectMode();

    // view settings for all sheets
    Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getGlobalFactory() );
    Reference< XNameContainer > xSheetsNC = ContainerHelper::createNameContainer( getBaseFilter().getComponentContext() );
    if( !xSheetsNC.is() ) return;
    for( SheetPropertiesMap::const_iterator aIt = maSheetProps.begin(), aEnd = maSheetProps.end(); aIt != aEnd; ++aIt )
        ContainerHelper::insertByName( xSheetsNC, rWorksheets.getCalcSheetName( aIt->first ), aIt->second );
@@ -746,7 +746,7 @@ void ViewSettings::finalizeImport()
    if( !rxActiveSheetView )
        rxActiveSheetView.reset( new SheetViewModel );

    Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getGlobalFactory() );
    Reference< XIndexContainer > xContainer = ContainerHelper::createIndexContainer( getBaseFilter().getComponentContext() );
    if( xContainer.is() ) try
    {
        PropertyMap aPropMap;
diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx
index 69daca1..843bfd6 100644
--- a/oox/source/xls/workbookfragment.cxx
+++ b/oox/source/xls/workbookfragment.cxx
@@ -289,7 +289,7 @@ void WorkbookFragment::finalizeImport()
    {
        Reference< XInputStream > xInStrm = getBaseFilter().openInputStream( aVbaFragmentPath );
        if( xInStrm.is() )
            setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getGlobalFactory(), xInStrm, false ) ) );
            setVbaProjectStorage( StorageRef( new ::oox::ole::OleStorage( getBaseFilter().getComponentContext(), xInStrm, false ) ) );
    }

    // final conversions, e.g. calculation settings and view settings
diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx
index 8cd2748..6adb795 100644
--- a/oox/source/xls/workbookhelper.cxx
+++ b/oox/source/xls/workbookhelper.cxx
@@ -595,11 +595,6 @@ FilterBase& WorkbookHelper::getBaseFilter() const
    return mrBookData.getBaseFilter();
}

Reference< XMultiServiceFactory > WorkbookHelper::getGlobalFactory() const
{
    return mrBookData.getBaseFilter().getServiceFactory();
}

FilterType WorkbookHelper::getFilterType() const
{
    return mrBookData.getFilterType();
@@ -666,11 +661,6 @@ Reference< XSpreadsheetDocument > WorkbookHelper::getDocument() const
    return mrBookData.getDocument();
}

Reference< XMultiServiceFactory > WorkbookHelper::getDocumentFactory() const
{
    return mrBookData.getBaseFilter().getModelFactory();
}

Reference< XSpreadsheet > WorkbookHelper::getSheetFromDoc( sal_Int16 nSheet ) const
{
    Reference< XSpreadsheet > xSheet;
diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx
index 6889d42..2645559 100644
--- a/oox/source/xls/workbooksettings.cxx
+++ b/oox/source/xls/workbooksettings.cxx
@@ -299,7 +299,7 @@ void WorkbookSettings::finalizeImport()
    {
        getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true;

        Reference< XPropertySet > xDocumentSettings( getDocumentFactory()->createInstance(
        Reference< XPropertySet > xDocumentSettings( getBaseFilter().getModelFactory()->createInstance(
            CREATE_OUSTRING( "com.sun.star.document.Settings" ) ), UNO_QUERY_THROW );
        PropertySet aSettingsProp( xDocumentSettings );
        if( maFileSharing.mbRecommendReadOnly )
diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx
index 124fdac..00f65f9 100644
--- a/oox/source/xls/worksheethelper.cxx
+++ b/oox/source/xls/worksheethelper.cxx
@@ -681,7 +681,7 @@ Reference< XSheetCellRanges > WorksheetData::getCellRangeList( const ApiCellRang
    Reference< XSheetCellRanges > xRanges;
    if( mxSheet.is() && !rRanges.empty() ) try
    {
        xRanges.set( getDocumentFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW );
        xRanges.set( getBaseFilter().getModelFactory()->createInstance( maSheetCellRanges ), UNO_QUERY_THROW );
        Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW );
        xRangeCont->addRangeAddresses( ContainerHelper::vectorToSequence( rRanges ), sal_False );
    }
@@ -1359,7 +1359,7 @@ void WorksheetData::insertHyperlink( const CellAddress& rAddress, const OUString
            if( xText.is() )
            {
                // create a URL field object and set its properties
                Reference< XTextContent > xUrlField( getDocumentFactory()->createInstance( maUrlTextField ), UNO_QUERY );
                Reference< XTextContent > xUrlField( getBaseFilter().getModelFactory()->createInstance( maUrlTextField ), UNO_QUERY );
                OSL_ENSURE( xUrlField.is(), "WorksheetData::insertHyperlink - cannot create text field" );
                if( xUrlField.is() )
                {