Moving XSAXDocumentBuilder2 to use XFastDocumentHandler:

This is used in parsing of meta Contexts across different
modules. This also involved moving to XFastParser for
parsing xml filters in sw, sd, starmath.

Change-Id: Ic663aaac6cb20ee8ce5b97cae87c93220f5a2929
Reviewed-on: https://gerrit.libreoffice.org/42989
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins <ci@libreoffice.org>
diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx
index 3644116..77b620a 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -55,6 +55,8 @@
#include <xmloff/formlayerimport.hxx>
#include <comphelper/attributelist.hxx>
#include <sax/fastattribs.hxx>
#include <rtl/ustring.hxx>
#include <unordered_map>

#include <com/sun/star/beans/NamedValue.hpp>

@@ -225,6 +227,7 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper<
    css::uno::Reference< css::xml::sax::XFastDocumentHandler > mxFastDocumentHandler;
    static css::uno::Reference< css::xml::sax::XFastTokenHandler > xTokenHandler;
    static std::unordered_map< sal_Int32, std::pair< OUString, OUString > > aNamespaceMap;
    static std::unordered_map< OUString, OUString, OUStringHash > aNamespaceURIPrefixMap;
    static bool bIsNSMapsInitialized;

    static void initializeNamespaceMaps();
@@ -378,6 +381,8 @@ public:

    static const OUString getNameFromToken( sal_Int32 nToken );
    static const OUString getNamespacePrefixFromToken( sal_Int32 nToken );
    static const OUString getNamespaceURIFromToken( sal_Int32 nToken );
    static const OUString getNamespacePrefixFromURI( const OUString& rURI );

    SvXMLNamespaceMap& GetNamespaceMap() { return *mpNamespaceMap; }
    const SvXMLNamespaceMap& GetNamespaceMap() const { return *mpNamespaceMap; }
diff --git a/include/xmloff/xmlmetai.hxx b/include/xmloff/xmlmetai.hxx
index 2b91602..9b9f59d 100644
--- a/include/xmloff/xmlmetai.hxx
+++ b/include/xmloff/xmlmetai.hxx
@@ -40,22 +40,20 @@ private:
    css::uno::Reference< css::xml::dom::XSAXDocumentBuilder2> mxDocBuilder;

public:
    SvXMLMetaDocumentContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
        const OUString& rLName,
        const css::uno::Reference< css::document::XDocumentProperties>& xDocProps);

    SvXMLMetaDocumentContext(SvXMLImport& rImport,
        const css::uno::Reference< css::document::XDocumentProperties>& xDocProps);

    virtual ~SvXMLMetaDocumentContext() override;

    virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList ) override;
    virtual void SAL_CALL characters( const OUString& aChars ) override;

    virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;
    virtual void SAL_CALL startFastElement( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual void EndElement() override;
    virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

public:
    static void setBuildId(const OUString & rGenerator,
diff --git a/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl b/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl
index be15146..37560fd 100644
--- a/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl
+++ b/offapi/com/sun/star/xml/dom/XSAXDocumentBuilder2.idl
@@ -20,7 +20,7 @@
#ifndef __com_sun_star_xml_dom_XSAXDocumentBuilder2_idl
#define __com_sun_star_xml_dom_XSAXDocumentBuilder2_idl

#include <com/sun/star/xml/sax/XDocumentHandler.idl>
#include <com/sun/star/xml/sax/XFastDocumentHandler.idl>
#include <com/sun/star/xml/dom/XSAXDocumentBuilder.idl>

module com {  module sun {  module star {  module xml { module dom {
@@ -33,7 +33,7 @@ module com {  module sun {  module star {  module xml { module dom {
interface XSAXDocumentBuilder2
{
    interface XSAXDocumentBuilder;
    interface com::sun::star::xml::sax::XDocumentHandler;
    interface com::sun::star::xml::sax::XFastDocumentHandler;
};

};};};};};
diff --git a/reportdesign/source/filter/xml/xmlfilter.cxx b/reportdesign/source/filter/xml/xmlfilter.cxx
index bf24612..054e9b2 100644
--- a/reportdesign/source/filter/xml/xmlfilter.cxx
+++ b/reportdesign/source/filter/xml/xmlfilter.cxx
@@ -745,10 +745,6 @@ SvXMLImportContext* ORptFilter::CreateDocumentContext( sal_uInt16 nPrefix,
        case XML_TOK_DOC_CONTENT:
            pContext = new RptXMLDocumentContentContext(*this, nPrefix, rLocalName);
            break;
        case XML_TOK_DOC_META:
            GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
            pContext = CreateMetaContext( rLocalName );
            break;
        default:
            break;
    }
@@ -759,6 +755,23 @@ SvXMLImportContext* ORptFilter::CreateDocumentContext( sal_uInt16 nPrefix,
    return pContext;
}

SvXMLImportContext *ORptFilter::CreateFastContext( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    SvXMLImportContext *pContext = nullptr;

    switch (nElement)
    {
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
            GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
            pContext = CreateMetaContext( nElement );
            break;
        default:
            pContext = new SvXMLImportContext(*this);
    }
    return pContext;
}

const SvXMLTokenMap& ORptFilter::GetDocElemTokenMap() const
{
    if ( !m_pDocElemTokenMap.get() )
@@ -1102,14 +1115,14 @@ void ORptFilter::insertFunction(const css::uno::Reference< css::report::XFunctio
    m_aFunctions.emplace(_xFunction->getName(),_xFunction);
}

SvXMLImportContext* ORptFilter::CreateMetaContext(const OUString& rLocalName)
SvXMLImportContext* ORptFilter::CreateMetaContext(const sal_Int32 /*nElement*/)
{
    SvXMLImportContext* pContext = nullptr;

    if ( getImportFlags() & SvXMLImportFlags::META )
    {
        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW);
        pContext = new SvXMLMetaDocumentContext(*this,XML_NAMESPACE_OFFICE, rLocalName,xDPS->getDocumentProperties());
        pContext = new SvXMLMetaDocumentContext(*this, xDPS->getDocumentProperties());
    }
    return pContext;
}
diff --git a/reportdesign/source/filter/xml/xmlfilter.hxx b/reportdesign/source/filter/xml/xmlfilter.hxx
index eacb74e..6ecf8f0 100644
--- a/reportdesign/source/filter/xml/xmlfilter.hxx
+++ b/reportdesign/source/filter/xml/xmlfilter.hxx
@@ -99,7 +99,7 @@ public:
    using SvXMLImport::SetMasterStyles;
    SvXMLImportContext* CreateStylesContext(const OUString& rLocalName,
                                            const Reference< XAttributeList>& xAttrList, bool bIsAutoStyle );
    SvXMLImportContext* CreateMetaContext(const OUString& rLocalName);
    SvXMLImportContext* CreateMetaContext(const sal_Int32 nElement);
    SvXMLImportContext* CreateFontDeclsContext(const OUString& rLocalName,
            const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList );
protected:
@@ -108,6 +108,9 @@ protected:
            const OUString& rLocalName,
            const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;

    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual XMLShapeImportHelper* CreateShapeImport() override;

    virtual ~ORptFilter()  throw() override;
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 4e2c3bb..c85589ac 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -234,10 +234,6 @@ protected:
    ScXMLImport& GetScImport() { return static_cast<ScXMLImport&>(GetImport()); }

public:
    ScXMLDocContext_Impl( ScXMLImport& rImport,
        sal_uInt16 nPrfx,
        const OUString& rLName );

    ScXMLDocContext_Impl( ScXMLImport& rImport );

    virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
@@ -256,13 +252,6 @@ public:
    virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
};

ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx,
                                           const OUString& rLName ) :
SvXMLImportContext( rImport, nPrfx, rLName )
{

}

ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport ) :
SvXMLImportContext( rImport )
{
@@ -273,38 +262,23 @@ class ScXMLFlatDocContext_Impl
    : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
{
public:
    ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps);

    ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps);

    virtual SvXMLImportContextRef CreateChildContext(
        sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
        const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override;

    virtual void SAL_CALL startFastElement (sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override;

    virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;

    virtual void SAL_CALL characters( const OUString& aChars ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
        createFastChildContext( sal_Int32 nElement,
        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
};

ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
                                                   sal_uInt16 i_nPrefix, const OUString & i_rLName,
                                                   const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
ScXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName),
SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
                         i_xDocProps)
{
}

ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
                                                   const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
SvXMLImportContext(i_rImport),
ScXMLDocContext_Impl(i_rImport),
@@ -312,29 +286,14 @@ SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
{
}

SvXMLImportContextRef ScXMLFlatDocContext_Impl::CreateChildContext(
    sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
    const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
{
    // behave like meta base class iff we encounter office:meta
    const SvXMLTokenMap& rTokenMap = GetScImport().GetDocElemTokenMap();
    if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) {
        return SvXMLMetaDocumentContext::CreateChildContext(
            i_nPrefix, i_rLocalName, i_xAttrList );
    } else {
        return ScXMLDocContext_Impl::CreateChildContext(
            i_nPrefix, i_rLocalName, i_xAttrList );
    }
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
    ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement,
    const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
{
    if ( nElement != XML_ELEMENT( OFFICE, XML_META ) )
        return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList );
    if ( nElement == XML_ELEMENT( OFFICE, XML_META ) )
        return SvXMLMetaDocumentContext::createFastChildContext( nElement, xAttrList );
    else
        return new SvXMLImportContext( GetImport() );
        return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList );
}

void SAL_CALL ScXMLFlatDocContext_Impl::startFastElement(sal_Int32 nElement,
@@ -348,6 +307,11 @@ void SAL_CALL ScXMLFlatDocContext_Impl::endFastElement(sal_Int32 nElement)
    SvXMLMetaDocumentContext::endFastElement( nElement );
}

void SAL_CALL ScXMLFlatDocContext_Impl::characters(const OUString& rChars)
{
    SvXMLMetaDocumentContext::characters(rChars);
}

class ScXMLBodyContext_Impl : public ScXMLImportContext
{
public:
@@ -659,29 +623,6 @@ sc::PivotTableSources& ScXMLImport::GetPivotTableSources()
    return *mpPivotSources;
}

SvXMLImportContext *ScXMLImport::CreateDocumentContext( sal_uInt16 nPrefix,
                                               const OUString& rLocalName,
                                               const uno::Reference<xml::sax::XAttributeList>& xAttrList )
{
    SvXMLImportContext *pContext = nullptr;

    if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
        ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) {
            pContext = CreateMetaContext(rLocalName);
    } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
        ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) {
            uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
                GetModel(), uno::UNO_QUERY_THROW);
            // flat OpenDocument file format
            pContext = new ScXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
                xDPS->getDocumentProperties());
    }
    else
        pContext = SvXMLImport::CreateDocumentContext( nPrefix, rLocalName, xAttrList );

    return pContext;
}

SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
@@ -695,6 +636,10 @@ SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement,
        pContext = new ScXMLDocContext_Impl( *this );
        break;

    case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
        pContext = CreateMetaContext(nElement);
        break;

    case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
    {
        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
@@ -847,7 +792,7 @@ SvXMLImportContext *ScXMLImport::CreateBodyContext(const rtl::Reference<sax_fast
}

SvXMLImportContext *ScXMLImport::CreateMetaContext(
    const OUString& rLocalName )
    const sal_Int32 /*nElement*/ )
{
    SvXMLImportContext* pContext = nullptr;

@@ -857,14 +802,11 @@ SvXMLImportContext *ScXMLImport::CreateMetaContext(
            GetModel(), uno::UNO_QUERY_THROW);
        uno::Reference<document::XDocumentProperties> const xDocProps(
            (IsStylesOnlyMode()) ? nullptr : xDPS->getDocumentProperties());
        pContext = new SvXMLMetaDocumentContext(*this,
            XML_NAMESPACE_OFFICE, rLocalName,
            xDocProps);
        pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
    }

    if( !pContext )
        pContext = new SvXMLImportContext( *this,
        XML_NAMESPACE_OFFICE, rLocalName );
        pContext = new SvXMLImportContext( *this );

    return pContext;
}
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 1639c32..ed7df03 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -299,10 +299,8 @@ class ScXMLImport: public SvXMLImport

protected:

    virtual SvXMLImportContext *CreateDocumentContext(sal_uInt16 nPrefix,
                                      const OUString& rLocalName,
                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override;

    // This method is called after the namespace map has been updated, but
    // before a context for the current element has been pushed.
    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;

@@ -322,7 +320,7 @@ public:
    // NB: in contrast to other CreateFooContexts, this particular one handles
    //     the root element (i.e. office:document-meta)
    SvXMLImportContext *CreateMetaContext(
                                    const OUString& rLocalName );
                                    const sal_Int32 nElement );
    SvXMLImportContext *CreateFontDeclsContext(const sal_uInt16 nPrefix, const OUString& rLocalName,
                                     const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList);
    SvXMLImportContext *CreateScriptContext(
diff --git a/sd/source/filter/xml/sdxmlwrp.cxx b/sd/source/filter/xml/sdxmlwrp.cxx
index da0c95b..3f8ad2f 100644
--- a/sd/source/filter/xml/sdxmlwrp.cxx
+++ b/sd/source/filter/xml/sdxmlwrp.cxx
@@ -41,6 +41,7 @@
#include <strmname.h>
#include <svx/xmleohlp.hxx>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/document/XFilter.hpp>
#include <com/sun/star/document/XImporter.hpp>
#include <com/sun/star/document/XExporter.hpp>
@@ -216,11 +217,18 @@ ErrCode ReadThroughComponent(
    // connect model and filter
    Reference < XImporter > xImporter( xFilter, UNO_QUERY );
    xImporter->setTargetDocument( xModelComponent );

    uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast<
                            xml::sax::XFastParser* >( xFilter.get() );

    // finally, parser the stream
    SAL_INFO( "sd.filter", "parsing stream" );
    try
    {
        xParser->parseStream( aParserInput );
        if( xFastParser.is() )
            xFastParser->parseStream( aParserInput );
        else
            xParser->parseStream( aParserInput );
    }
    catch (const xml::sax::SAXParseException& r)
    {
diff --git a/sdext/CppunitTest_sdext_pdfimport.mk b/sdext/CppunitTest_sdext_pdfimport.mk
index 83f3131..f5fc546 100644
--- a/sdext/CppunitTest_sdext_pdfimport.mk
+++ b/sdext/CppunitTest_sdext_pdfimport.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sdext_pdfimport,\
    sal \
    test \
    unotest \
    xo \
))

$(eval $(call gb_CppunitTest_use_library_objects,sdext_pdfimport,pdfimport))
diff --git a/sdext/Executable_pdf2xml.mk b/sdext/Executable_pdf2xml.mk
index 373f40d..c0f7fe6 100644
--- a/sdext/Executable_pdf2xml.mk
+++ b/sdext/Executable_pdf2xml.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_Executable_use_libraries,pdf2xml,\
    unotest \
    cppuhelper \
    sal \
    xo \
))

$(eval $(call gb_Executable_use_library_objects,pdf2xml,pdfimport))
diff --git a/sdext/Executable_pdfunzip.mk b/sdext/Executable_pdfunzip.mk
index 74b1a96..006f8e5 100644
--- a/sdext/Executable_pdfunzip.mk
+++ b/sdext/Executable_pdfunzip.mk
@@ -28,6 +28,7 @@ $(eval $(call gb_Executable_use_libraries,pdfunzip,\
    cppuhelper \
    sal \
    vcl \
    xo \
))

$(eval $(call gb_Executable_use_library_objects,pdfunzip,pdfimport))
diff --git a/sdext/Library_pdfimport.mk b/sdext/Library_pdfimport.mk
index 7c11d36..465a406 100644
--- a/sdext/Library_pdfimport.mk
+++ b/sdext/Library_pdfimport.mk
@@ -27,6 +27,7 @@ $(eval $(call gb_Library_use_libraries,pdfimport,\
    cppu \
    cppuhelper \
    sal \
    xo \
))

$(eval $(call gb_Library_use_externals,pdfimport,\
diff --git a/sdext/source/pdfimport/sax/emitcontext.cxx b/sdext/source/pdfimport/sax/emitcontext.cxx
index 7559d1e..f21b17e 100644
--- a/sdext/source/pdfimport/sax/emitcontext.cxx
+++ b/sdext/source/pdfimport/sax/emitcontext.cxx
@@ -27,6 +27,7 @@
#include <cppuhelper/exc_hlp.hxx>
#include <com/sun/star/xml/sax/SAXException.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <xmloff/xmlimp.hxx>

#if OSL_DEBUG_LEVEL > 0
#include <osl/file.hxx>
@@ -43,6 +44,8 @@ SaxEmitter::SaxEmitter( const uno::Reference< xml::sax::XDocumentHandler >& xDoc
    m_xDocHdl( xDocHdl )
{
    OSL_PRECOND(m_xDocHdl.is(), "SaxEmitter(): invalid doc handler");
    if (SvXMLImport *pFastHandler = dynamic_cast<SvXMLImport*>(m_xDocHdl.get()))
        m_xDocHdl.set( new SvXMLLegacyToFastDocHandler( pFastHandler ) );
    try
    {
        m_xDocHdl->startDocument();
diff --git a/sfx2/source/doc/SfxDocumentMetaData.cxx b/sfx2/source/doc/SfxDocumentMetaData.cxx
index a15ea43..7e69612 100644
--- a/sfx2/source/doc/SfxDocumentMetaData.cxx
+++ b/sfx2/source/doc/SfxDocumentMetaData.cxx
@@ -48,6 +48,7 @@
#include <com/sun/star/document/XFilter.hpp>
#include <com/sun/star/xml/sax/Parser.hpp>
#include <com/sun/star/xml/sax/Writer.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/xml/dom/DOMException.hpp>
#include <com/sun/star/xml/dom/XDocument.hpp>
#include <com/sun/star/xml/dom/XElement.hpp>
@@ -1770,8 +1771,13 @@ SfxDocumentMetaData::loadFromStorage(
        css::uno::UNO_QUERY_THROW);
    xImp->setTargetDocument(css::uno::Reference<css::lang::XComponent>(this));
    xParser->setDocumentHandler(xDocHandler);
    css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast<
                            css::xml::sax::XFastParser* >( xDocHandler.get() );
    try {
        xParser->parseStream(input);
        if( xFastParser.is() )
            xFastParser->parseStream(input);
        else
            xParser->parseStream(input);
    } catch (const css::xml::sax::SAXException &) {
        throw css::io::WrongFormatException(
                "SfxDocumentMetaData::loadFromStorage:"
diff --git a/starmath/source/mathmlimport.cxx b/starmath/source/mathmlimport.cxx
index 59b4257..a531412 100644
--- a/starmath/source/mathmlimport.cxx
+++ b/starmath/source/mathmlimport.cxx
@@ -24,6 +24,7 @@ one go*/

#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/xml/sax/Parser.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/packages/WrongPasswordException.hpp>
@@ -286,10 +287,16 @@ ErrCode SmXMLImportWrapper::ReadThroughComponent(
    Reference < XImporter > xImporter( xFilter, UNO_QUERY );
    xImporter->setTargetDocument( xModelComponent );

    uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast<
                            xml::sax::XFastParser* >( xFilter.get() );

    // finally, parser the stream
    try
    {
        xParser->parseStream( aParserInput );
        if( xFastParser.is() )
            xFastParser->parseStream( aParserInput );
        else
            xParser->parseStream( aParserInput );

        uno::Reference<lang::XUnoTunnel> xFilterTunnel( xFilter, uno::UNO_QUERY );
        SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >(
@@ -1935,11 +1942,20 @@ public:
class SmXMLOfficeContext_Impl : public virtual SvXMLImportContext
{
public:
    SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
        const OUString& rLName)
        : SvXMLImportContext(rImport,nPrfx,rLName) {}
    SmXMLOfficeContext_Impl( SmXMLImport &rImport )
        : SvXMLImportContext(rImport) {}

    virtual void SAL_CALL characters( const OUString& /*aChars*/ ) override {}

    virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override {}

    virtual void SAL_CALL endFastElement( sal_Int32 /*nElement*/ ) override {}

    virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

SvXMLImportContextRef SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix,
@@ -1965,6 +1981,12 @@ SvXMLImportContextRef SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPr
    return pContext;
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SmXMLOfficeContext_Impl::createFastChildContext(
    sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    return new SvXMLImportContext( GetImport() );
}


// context for flat file xml format
class SmXMLFlatDocContext_Impl
@@ -1972,41 +1994,59 @@ class SmXMLFlatDocContext_Impl
{
public:
    SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps);

    virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 i_nPrefix, const OUString& i_rLocalName, const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override;
    virtual void SAL_CALL characters( const OUString& aChars ) override;

    virtual void SAL_CALL startFastElement( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

SmXMLFlatDocContext_Impl::SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
    SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
    SmXMLOfficeContext_Impl(i_rImport, i_nPrefix, i_rLName),
    SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
        i_xDocProps)
    SvXMLImportContext(i_rImport),
    SmXMLOfficeContext_Impl(i_rImport),
    SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
{
}

SvXMLImportContextRef SmXMLFlatDocContext_Impl::CreateChildContext(
    sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
    const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
void SAL_CALL SmXMLFlatDocContext_Impl::startFastElement( sal_Int32 nElement,
    const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    SvXMLMetaDocumentContext::startFastElement(nElement, xAttrList);
}

void SAL_CALL SmXMLFlatDocContext_Impl::endFastElement( sal_Int32 nElement )
{
    SvXMLMetaDocumentContext::endFastElement(nElement);
}

void SAL_CALL SmXMLFlatDocContext_Impl::characters( const OUString& rChars )
{
    SvXMLMetaDocumentContext::characters(rChars);
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SmXMLFlatDocContext_Impl::createFastChildContext(
    sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    // behave like meta base class iff we encounter office:meta
    if ( XML_NAMESPACE_OFFICE == i_nPrefix &&
            i_rLocalName == GetXMLToken(XML_META) )
    if ( nElement == XML_ELEMENT(OFFICE, XML_META) )
    {
        return SvXMLMetaDocumentContext::CreateChildContext(
                    i_nPrefix, i_rLocalName, i_xAttrList );
        return SvXMLMetaDocumentContext::createFastChildContext(
                    nElement, xAttrList );
    }
    else
    {
        return SmXMLOfficeContext_Impl::CreateChildContext(
                    i_nPrefix, i_rLocalName, i_xAttrList );
        return SmXMLOfficeContext_Impl::createFastChildContext(
                    nElement, xAttrList );
    }
}


static const SvXMLTokenMapEntry aPresLayoutElemTokenMap[] =
{
    { XML_NAMESPACE_MATH,   XML_SEMANTICS, XML_TOK_SEMANTICS },
@@ -2823,28 +2863,40 @@ SvXMLImportContext *SmXMLImport::CreateDocumentContext(sal_uInt16 nPrefix,
    const OUString &rLocalName,
    const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
{
    if ( XML_NAMESPACE_OFFICE == nPrefix )
    SvXMLImportContext *pContext = nullptr;
    if ( XML_NAMESPACE_OFFICE != nPrefix )
        pContext = new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);

    return pContext;
}

SvXMLImportContext *SmXMLImport::CreateFastContext(sal_Int32 nElement,
    const uno::Reference <xml::sax::XFastAttributeList> & /*xAttrList*/)
{
    SvXMLImportContext *pContext = nullptr;

    switch (nElement)
    {
        if ( IsXMLToken(rLocalName, XML_DOCUMENT) ||
             IsXMLToken(rLocalName, XML_DOCUMENT_META) )
        case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
        {
            uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
                GetModel(), uno::UNO_QUERY_THROW);
            return IsXMLToken(rLocalName, XML_DOCUMENT_META)
                ? new SvXMLMetaDocumentContext(*this,
                        XML_NAMESPACE_OFFICE, rLocalName,
                        xDPS->getDocumentProperties())
            pContext = ( (nElement & TOKEN_MASK) == XML_DOCUMENT_META )
                ? new SvXMLMetaDocumentContext( *this,
                        xDPS->getDocumentProperties() )
                // flat OpenDocument file format -- this has not been tested...
                : new SmXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
                            xDPS->getDocumentProperties());
                : new SmXMLFlatDocContext_Impl( *this,
                            xDPS->getDocumentProperties() );
        }
        else
        {
            return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName);
        }
        break;
        default:
            if ((nElement & NMSP_MASK) == NAMESPACE_TOKEN(XML_NAMESPACE_OFFICE))
                pContext = new SmXMLOfficeContext_Impl(*this);
            else
                pContext = new SvXMLImportContext(*this);
    }
    else
        return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);
    return pContext;
}

SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix,
diff --git a/starmath/source/mathmlimport.hxx b/starmath/source/mathmlimport.hxx
index a0d2c62..b91a51b 100644
--- a/starmath/source/mathmlimport.hxx
+++ b/starmath/source/mathmlimport.hxx
@@ -99,6 +99,9 @@ public:
        const OUString &rLocalName,
        const css::uno::Reference <
        css::xml::sax::XAttributeList> &xAttrList) override;
    SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const css::uno::Reference<
        css::xml::sax::XFastAttributeList >& xAttrList ) override;
    SvXMLImportContext *CreateRowContext(sal_uInt16 nPrefix,
        const OUString &rLocalName);
    SvXMLImportContext *CreateEncloseContext(sal_uInt16 nPrefix,
diff --git a/sw/source/filter/xml/swxml.cxx b/sw/source/filter/xml/swxml.cxx
index a96433f..cb5b122 100644
--- a/sw/source/filter/xml/swxml.cxx
+++ b/sw/source/filter/xml/swxml.cxx
@@ -34,6 +34,7 @@
#include <com/sun/star/packages/zip/ZipIOException.hpp>
#include <com/sun/star/packages/WrongPasswordException.hpp>
#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp>
#include <o3tl/any.hxx>
#include <vcl/errinf.hxx>
#include <sfx2/docfile.hxx>
@@ -168,11 +169,16 @@ ErrCode ReadThroughComponent(
    // connect model and filter
    uno::Reference < XImporter > xImporter( xFilter, UNO_QUERY );
    xImporter->setTargetDocument( xModelComponent );
    uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast<
                            xml::sax::XFastParser* >( xFilter.get() );

    // finally, parser the stream
    try
    {
        xParser->parseStream( aParserInput );
        if( xFastParser.is() )
            xFastParser->parseStream( aParserInput );
        else
            xParser->parseStream( aParserInput );
    }
    catch( xml::sax::SAXParseException& r )
    {
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index 01460f6..1a49883 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -196,9 +196,14 @@ public:
    SwXMLDocContext_Impl( SwXMLImport& rImport, sal_uInt16 nPrfx,
                const OUString& rLName );

    SwXMLDocContext_Impl( SwXMLImport& rImport );

    virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
                const OUString& rLocalName,
                const Reference< xml::sax::XAttributeList > & xAttrList ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport,
@@ -207,6 +212,17 @@ SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport,
{
}

SwXMLDocContext_Impl::SwXMLDocContext_Impl( SwXMLImport& rImport ) :
    SvXMLImportContext( rImport )
{
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SwXMLDocContext_Impl::createFastChildContext(
    sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    return new SvXMLImportContext( GetImport() );
}

SvXMLImportContextRef SwXMLDocContext_Impl::CreateChildContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
@@ -271,51 +287,41 @@ class SwXMLOfficeDocContext_Impl :
public:

    SwXMLOfficeDocContext_Impl( SwXMLImport& rImport,
                sal_uInt16 nPrfx,
                const OUString& rLName,
                const Reference< document::XDocumentProperties >& xDocProps);

    virtual SvXMLImportContextRef CreateChildContext(
                sal_uInt16 nPrefix,
                const OUString& rLocalName,
                const Reference< xml::sax::XAttributeList > & xAttrList ) override;
    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
};

SwXMLOfficeDocContext_Impl::SwXMLOfficeDocContext_Impl(
                SwXMLImport& rImport,
                sal_uInt16 nPrfx,
                const OUString& rLName,
                const Reference< document::XDocumentProperties >& xDocProps) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    SwXMLDocContext_Impl( rImport, nPrfx, rLName ),
    SvXMLMetaDocumentContext( rImport, nPrfx, rLName, xDocProps)
    SvXMLImportContext( rImport ),
    SwXMLDocContext_Impl( rImport ),
    SvXMLMetaDocumentContext( rImport, xDocProps )
{
}

SvXMLImportContextRef SwXMLOfficeDocContext_Impl::CreateChildContext(
                sal_uInt16 nPrefix,
                const OUString& rLocalName,
                const Reference< xml::sax::XAttributeList > & xAttrList )
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SwXMLOfficeDocContext_Impl::createFastChildContext(
    sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    const SvXMLTokenMap& rTokenMap = GetSwImport().GetDocElemTokenMap();

    // assign paragraph styles to list levels of outline style after all styles
    // are imported and finished. This is the case, when <office:body> starts
    // in flat OpenDocument file format.
    {
        if ( rTokenMap.Get( nPrefix, rLocalName ) == XML_TOK_DOC_BODY )
        if( nElement == XML_ELEMENT( OFFICE, XML_BODY ) )
        {
            GetImport().GetTextImport()->SetOutlineStyles( true );
        }
    }

    // behave like meta base class iff we encounter office:meta
    if ( XML_TOK_DOC_META == rTokenMap.Get( nPrefix, rLocalName ) ) {
        return SvXMLMetaDocumentContext::CreateChildContext(
                    nPrefix, rLocalName, xAttrList );
    if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) {
        return SvXMLMetaDocumentContext::createFastChildContext(
                    nElement, xAttrList );
    } else {
        return SwXMLDocContext_Impl::CreateChildContext(
                    nPrefix, rLocalName, xAttrList );
        return SwXMLDocContext_Impl::createFastChildContext(
                    nElement, xAttrList );
    }
}

@@ -370,30 +376,40 @@ SvXMLImportContext *SwXMLImport::CreateDocumentContext(
          IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT ) ))
        pContext = new SwXMLDocContext_Impl( *this, nPrefix, rLocalName );
    else if ( XML_NAMESPACE_OFFICE==nPrefix &&
              IsXMLToken( rLocalName, XML_DOCUMENT_META ) )
    {
        pContext = CreateMetaContext(rLocalName);
    }
    else if ( XML_NAMESPACE_OFFICE==nPrefix &&
              IsXMLToken( rLocalName, XML_DOCUMENT_STYLES ) )
    {
        pContext = new SwXMLDocStylesContext_Impl( *this, nPrefix, rLocalName );
    }
    else if ( XML_NAMESPACE_OFFICE==nPrefix &&
              IsXMLToken( rLocalName, XML_DOCUMENT ) )
    {
        uno::Reference<document::XDocumentProperties> const xDocProps(
            GetDocumentProperties());
        // flat OpenDocument file format
        pContext = new SwXMLOfficeDocContext_Impl( *this, nPrefix, rLocalName,
                        xDocProps);
    }
    else
        pContext = SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList);

    return pContext;
}

SvXMLImportContext *SwXMLImport::CreateFastContext( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    SvXMLImportContext *pContext = nullptr;

    switch (nElement)
    {
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
            pContext = CreateMetaContext(nElement);
        break;
        case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
        {
            uno::Reference<document::XDocumentProperties> const xDocProps(
                GetDocumentProperties());
            // flat OpenDocument file format
            pContext = new SwXMLOfficeDocContext_Impl( *this, xDocProps );
        }
        break;
        default:
            pContext = new SvXMLImportContext( *this );
    }
    return pContext;
}

SwXMLImport::SwXMLImport(
    const uno::Reference< uno::XComponentContext >& rContext,
    OUString const & implementationName, SvXMLImportFlags nImportFlags)
diff --git a/sw/source/filter/xml/xmlimp.hxx b/sw/source/filter/xml/xmlimp.hxx
index 8907970..cd399ea 100644
--- a/sw/source/filter/xml/xmlimp.hxx
+++ b/sw/source/filter/xml/xmlimp.hxx
@@ -107,6 +107,9 @@ protected:
                  const OUString& rLocalName,
                  const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList ) override;

    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual XMLTextImportHelper* CreateTextImport() override;

    virtual XMLShapeImportHelper* CreateShapeImport() override;
@@ -136,7 +139,7 @@ public:

    // NB: in contrast to other CreateFooContexts, this particular one handles
    //     the root element (i.e. office:document-meta)
    SvXMLImportContext *CreateMetaContext( const OUString& rLocalName );
    SvXMLImportContext *CreateMetaContext( const sal_Int32 nElement );
    SvXMLImportContext *CreateScriptContext( const OUString& rLocalName );
    SvXMLImportContext *CreateStylesContext(
                const OUString& rLocalName,
diff --git a/sw/source/filter/xml/xmlmeta.cxx b/sw/source/filter/xml/xmlmeta.cxx
index ddc37f10..3dcf810 100644
--- a/sw/source/filter/xml/xmlmeta.cxx
+++ b/sw/source/filter/xml/xmlmeta.cxx
@@ -53,7 +53,7 @@ SwXMLImport::GetDocumentProperties() const
}

SvXMLImportContext *SwXMLImport::CreateMetaContext(
                                       const OUString& rLocalName )
                                       const sal_Int32 /*nElement*/ )
{
    SvXMLImportContext *pContext = nullptr;

@@ -61,13 +61,11 @@ SvXMLImportContext *SwXMLImport::CreateMetaContext(
    {
        uno::Reference<document::XDocumentProperties> const xDocProps(
                GetDocumentProperties());
        pContext = new SvXMLMetaDocumentContext(*this,
                    XML_NAMESPACE_OFFICE, rLocalName, xDocProps);
        pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
    }

    if( !pContext )
        pContext = new SvXMLImportContext( *this,
                        XML_NAMESPACE_OFFICE, rLocalName );
        pContext = new SvXMLImportContext( *this );

    return pContext;
}
diff --git a/unoxml/Library_unoxml.mk b/unoxml/Library_unoxml.mk
index c55e4d6..335bf10 100644
--- a/unoxml/Library_unoxml.mk
+++ b/unoxml/Library_unoxml.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_Library_use_libraries,unoxml,\
    cppuhelper \
    cppu \
    sal \
    xo \
))

$(eval $(call gb_Library_use_externals,unoxml,\
diff --git a/unoxml/source/dom/saxbuilder.cxx b/unoxml/source/dom/saxbuilder.cxx
index 626293a..698d923 100644
--- a/unoxml/source/dom/saxbuilder.cxx
+++ b/unoxml/source/dom/saxbuilder.cxx
@@ -23,6 +23,8 @@
#include <com/sun/star/xml/sax/SAXException.hpp>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <sax/fastattribs.hxx>
#include <xmloff/xmlimp.hxx>

using namespace css::lang;
using namespace css::uno;
@@ -90,7 +92,6 @@ namespace DOM
        m_aDocument.clear();
        m_aFragment.clear();
        while (!m_aNodeStack.empty()) m_aNodeStack.pop();
        while (!m_aNSStack.empty()) m_aNSStack.pop();
        m_aState = SAXDocumentBuilderState_READY;
    }

@@ -144,9 +145,8 @@ namespace DOM
        m_aState = SAXDocumentBuilderState_FRAGMENT_FINISHED;
    }

    // document handler

    void SAL_CALL  CSAXDocumentBuilder::startDocument()
    //XFastDocumentHandler
    void SAL_CALL CSAXDocumentBuilder::startDocument()
    {
        ::osl::MutexGuard g(m_Mutex);

@@ -177,7 +177,29 @@ namespace DOM
        m_aState = SAXDocumentBuilderState_DOCUMENT_FINISHED;
    }

    void SAL_CALL CSAXDocumentBuilder::startElement(const OUString& aName, const Reference< XAttributeList>& attribs)
    void SAL_CALL CSAXDocumentBuilder::processingInstruction( const OUString& rTarget, const OUString& rData )
    {
        ::osl::MutexGuard g(m_Mutex);

        //  append PI node to the current top
        if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT &&
             m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT)
            throw SAXException();

        Reference< XProcessingInstruction > aInstruction = m_aDocument->createProcessingInstruction(
                rTarget, rData);
        m_aNodeStack.top()->appendChild(aInstruction);
    }

    void SAL_CALL CSAXDocumentBuilder::setDocumentLocator( const Reference< XLocator >& xLocator )
    {
        ::osl::MutexGuard g(m_Mutex);

        // set the document locator...
        m_aLocator = xLocator;
    }

    void SAL_CALL CSAXDocumentBuilder::startFastElement( sal_Int32 nElement , const Reference< XFastAttributeList >& xAttribs  )
    {
        ::osl::MutexGuard g(m_Mutex);

@@ -187,97 +209,114 @@ namespace DOM
            throw SAXException();
        }

        // start with mappings in effect for last level
        NSMap aNSMap;
        if (!m_aNSStack.empty())
            aNSMap = NSMap(m_aNSStack.top());

        // handle xmlns: attributes and add to mappings
        OUString attr_qname;
        OUString attr_value;
        OUString newprefix;
        AttrMap aAttrMap;
        sal_Int32 idx=-1;
        sal_Int16 nAttributes = attribs->getLength();
        for (sal_Int16 i=0; i<nAttributes; i++)
        {
            attr_qname = attribs->getNameByIndex(i);
            attr_value = attribs->getValueByIndex(i);
            // new prefix mapping
            if (attr_qname.startsWith("xmlns:"))
            {
                newprefix = attr_qname.copy(attr_qname.indexOf(':')+1);
                aNSMap.emplace(newprefix, attr_value);
            }
            else if ( attr_qname == "xmlns" )
            {
                // new default prefix
                aNSMap.emplace(OUString(), attr_value);
            }
            else
            {
                aAttrMap.emplace(attr_qname, attr_value);
            }
        }

        // does the element have a prefix?
        OUString aPrefix;
        OUString aURI;
        Reference< XElement > aElement;
        idx = aName.indexOf(':');
        if (idx != -1)
        {
            aPrefix = aName.copy(0, idx);
        }
        else
            aPrefix.clear();
        const OUString& aPrefix( SvXMLImport::getNamespacePrefixFromToken( nElement ) );
        const OUString& aURI( SvXMLImport::getNamespaceURIFromToken( nElement ) );
        OUString aQualifiedName( SvXMLImport::getNameFromToken( nElement ) );
        if( !aPrefix.isEmpty() )
            aQualifiedName = aPrefix + SvXMLImport::aNamespaceSeparator + aQualifiedName;

        NSMap::const_iterator result = aNSMap.find(aPrefix);
        if ( result != aNSMap.end())
        if ( !aURI.isEmpty() )
        {
            // found a URI for prefix
            // qualified name
            aElement = m_aDocument->createElementNS( result->second, aName);
            aElement = m_aDocument->createElementNS( aURI, aQualifiedName );
        }
        else
        {
            // no URI for prefix
            aElement = m_aDocument->createElement(aName);
            aElement = m_aDocument->createElement( aQualifiedName );
        }
        aElement.set( m_aNodeStack.top()->appendChild(aElement), UNO_QUERY);
        m_aNodeStack.push(aElement);

        // set non xmlns attributes
        aPrefix.clear();
        aURI.clear();
        AttrMap::const_iterator a = aAttrMap.begin();
        while (a != aAttrMap.end())
        {
            attr_qname = a->first;
            attr_value = a->second;
            idx = attr_qname.indexOf(':');
            if (idx != -1)
                aPrefix = attr_qname.copy(0, idx);
            else
                aPrefix.clear();

            result = aNSMap.find(aPrefix);
            if (result != aNSMap.end())
            {
                // set attribute with namespace
                aElement->setAttributeNS(result->second, attr_qname, attr_value);
            }
            else
            {
                // set attribute without namespace
                aElement->setAttribute(attr_qname, attr_value);
            }
            ++a;
        }
        m_aNSStack.push(aNSMap);
        if (xAttribs.is())
            setElementFastAttributes(aElement, xAttribs);
    }

    void SAL_CALL CSAXDocumentBuilder::endElement(const OUString& aName)
    // For arbitrary meta elements
    void SAL_CALL CSAXDocumentBuilder::startUnknownElement( const OUString& rNamespace, const OUString& rName, const Reference< XFastAttributeList >& xAttribs )
    {
        ::osl::MutexGuard g(m_Mutex);

        if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT &&
             m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT)
        {
            throw SAXException();
        }

        Reference< XElement > aElement;
        if ( !rNamespace.isEmpty() )
            aElement = m_aDocument->createElementNS( rNamespace, rName );
        else
            aElement = m_aDocument->createElement( rName );

        aElement.set( m_aNodeStack.top()->appendChild(aElement), UNO_QUERY);
        m_aNodeStack.push(aElement);

        if (xAttribs.is())
        {
            setElementFastAttributes(aElement, xAttribs);
            Sequence< css::xml::Attribute > unknownAttribs = xAttribs->getUnknownAttributes();
            sal_Int32 len = unknownAttribs.getLength();
            for ( sal_Int32 i = 0; i < len; i++ )
            {
                const OUString& rAttrValue = unknownAttribs[i].Value;
                const OUString& rAttrName = unknownAttribs[i].Name;
                const OUString& rAttrNamespace = unknownAttribs[i].NamespaceURL;
                if ( !rAttrNamespace.isEmpty() )
                    aElement->setAttributeNS( rAttrNamespace, rAttrName, rAttrValue );
                else
                    aElement->setAttribute( rAttrName, rAttrValue );
            }
        }
    }

    void CSAXDocumentBuilder::setElementFastAttributes(const Reference< XElement >& aElement, const Reference< XFastAttributeList >& xAttribs)
    {
        sax_fastparser::FastAttributeList *pAttribList =
            sax_fastparser::FastAttributeList::castToFastAttributeList( xAttribs );

        for (auto &it : *pAttribList)
        {
            sal_Int32 nAttrToken = it.getToken();
            const OUString& aAttrPrefix( SvXMLImport::getNamespacePrefixFromToken( nAttrToken ) );
            const OUString& aAttrURI( SvXMLImport::getNamespaceURIFromToken( nAttrToken ) );
            OUString aAttrQualifiedName( SvXMLImport::getNameFromToken( nAttrToken ) );
            if( !aAttrPrefix.isEmpty() )
                aAttrQualifiedName = aAttrPrefix + SvXMLImport::aNamespaceSeparator + aAttrQualifiedName;

            if ( !aAttrURI.isEmpty() )
                aElement->setAttributeNS( aAttrURI, aAttrQualifiedName, it.toString() );
            else
                aElement->setAttribute( aAttrQualifiedName, it.toString() );
        }
    }

    void SAL_CALL CSAXDocumentBuilder::endFastElement( sal_Int32 nElement )
    {
        ::osl::MutexGuard g(m_Mutex);

        // pop the current element from the stack
        if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT &&
             m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT)
            throw SAXException();

        Reference< XNode > aNode(m_aNodeStack.top());
        if (aNode->getNodeType() != NodeType_ELEMENT_NODE)
            throw SAXException();

        Reference< XElement > aElement(aNode, UNO_QUERY);
        if( aElement->getPrefix() != SvXMLImport::getNamespacePrefixFromToken( nElement ) ||
            aElement->getTagName() != SvXMLImport::getNameFromToken( nElement ) ) // consistency check
            throw SAXException();

        // pop it
        m_aNodeStack.pop();
    }


    void SAL_CALL CSAXDocumentBuilder::endUnknownElement( const OUString& /*rNamespace*/, const OUString& rName )
    {
        ::osl::MutexGuard g(m_Mutex);

@@ -292,20 +331,30 @@ namespace DOM

        Reference< XElement > aElement(aNode, UNO_QUERY);
        OUString aRefName;
        OUString aPrefix = aElement->getPrefix();
        const OUString& aPrefix = aElement->getPrefix();
        if (!aPrefix.isEmpty())
            aRefName = aPrefix + ":" + aElement->getTagName();
            aRefName = aPrefix + SvXMLImport::aNamespaceSeparator + aElement->getTagName();
        else
            aRefName = aElement->getTagName();
        if (aRefName != aName) // consistency check
        if (aRefName != rName) // consistency check
            throw SAXException();

        // pop it
        m_aNodeStack.pop();
        m_aNSStack.pop();
    }

    void SAL_CALL CSAXDocumentBuilder::characters(const OUString& aChars)
    Reference< XFastContextHandler > SAL_CALL CSAXDocumentBuilder::createFastChildContext( sal_Int32/* nElement */, const Reference< XFastAttributeList >&/* xAttribs */ )
    {
        return nullptr;
    }


    Reference< XFastContextHandler > SAL_CALL CSAXDocumentBuilder::createUnknownChildContext( const OUString&/* rNamespace */, const OUString&/* rName */, const Reference< XFastAttributeList >&/* xAttribs */ )
    {
        return nullptr;
    }

    void SAL_CALL CSAXDocumentBuilder::characters( const OUString& rChars )
    {
        ::osl::MutexGuard g(m_Mutex);

@@ -314,41 +363,9 @@ namespace DOM
             m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT)
            throw SAXException();

         Reference< XText > aText = m_aDocument->createTextNode(aChars);
         Reference< XText > aText = m_aDocument->createTextNode(rChars);
         m_aNodeStack.top()->appendChild(aText);
    }

    void SAL_CALL CSAXDocumentBuilder::ignorableWhitespace(const OUString& )
    {
        ::osl::MutexGuard g(m_Mutex);

        //  ignore ignorable whitespace
        if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT &&
             m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT)
            throw SAXException();
    }

    void SAL_CALL CSAXDocumentBuilder::processingInstruction(const OUString& aTarget, const OUString& aData)
    {
        ::osl::MutexGuard g(m_Mutex);

        //  append PI node to the current top
        if ( m_aState != SAXDocumentBuilderState_BUILDING_DOCUMENT &&
             m_aState != SAXDocumentBuilderState_BUILDING_FRAGMENT)
            throw SAXException();

        Reference< XProcessingInstruction > aInstruction = m_aDocument->createProcessingInstruction(
                aTarget, aData);
        m_aNodeStack.top()->appendChild(aInstruction);
    }

    void SAL_CALL CSAXDocumentBuilder::setDocumentLocator(const Reference< XLocator >& aLocator)
    {
        ::osl::MutexGuard g(m_Mutex);

        // set the document locator...
        m_aLocator = aLocator;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unoxml/source/dom/saxbuilder.hxx b/unoxml/source/dom/saxbuilder.hxx
index dd23314..6f2ab24 100644
--- a/unoxml/source/dom/saxbuilder.hxx
+++ b/unoxml/source/dom/saxbuilder.hxx
@@ -43,10 +43,6 @@

namespace DOM
{

    typedef std::map< OUString, OUString > NSMap;
    typedef std::map< OUString, OUString > AttrMap;

    class  CSAXDocumentBuilder
        : public ::cppu::WeakImplHelper< css::xml::dom::XSAXDocumentBuilder2, css::lang::XServiceInfo >
    {
@@ -57,7 +53,6 @@ namespace DOM

        css::xml::dom::SAXDocumentBuilderState m_aState;
        std::stack< css::uno::Reference< css::xml::dom::XNode > > m_aNodeStack;
        std::stack< NSMap > m_aNSStack;

        css::uno::Reference< css::xml::dom::XDocument > m_aDocument;
        css::uno::Reference< css::xml::dom::XDocumentFragment > m_aFragment;
@@ -73,24 +68,28 @@ namespace DOM
        static css::uno::Reference< XInterface > _getInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMgr);

        explicit CSAXDocumentBuilder(const css::uno::Reference< css::lang::XMultiServiceFactory >& mgr);
        void setElementFastAttributes(const css::uno::Reference< css::xml::dom::XElement >& aElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttribs);


        // XServiceInfo
        virtual OUString SAL_CALL getImplementationName() override;
        virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
        virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames () override;

        // XDocumentHandler
        // XFastDocumentHandler
        virtual void SAL_CALL startDocument() override;
        virtual void SAL_CALL endDocument() override;
        virtual void SAL_CALL startElement( const OUString& aName,
             const css::uno::Reference< css::xml::sax::XAttributeList >& xAttribs ) override;
        virtual void SAL_CALL endElement( const OUString& aName ) override;
        virtual void SAL_CALL characters( const OUString& aChars ) override;
        virtual void SAL_CALL ignorableWhitespace( const OUString& aWhitespaces ) override;
        virtual void SAL_CALL processingInstruction( const OUString& aTarget,
             const OUString& aData ) override;
        virtual void SAL_CALL processingInstruction( const OUString& rTarget, const OUString& rData ) override;
        virtual void SAL_CALL setDocumentLocator( const css::uno::Reference< css::xml::sax::XLocator >& xLocator ) override;

        // XFastContextHandler
        virtual void SAL_CALL startFastElement( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
        virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
        virtual void SAL_CALL endFastElement( sal_Int32 Element ) override;
        virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) override;
        virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
        virtual css::uno::Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& Namespace, const OUString& Name, const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;
        virtual void SAL_CALL characters( const OUString& aChars ) override;

        // XSAXDocumentBuilder
        virtual css::xml::dom::SAXDocumentBuilderState SAL_CALL getState() override;
diff --git a/xmloff/inc/SchXMLImport.hxx b/xmloff/inc/SchXMLImport.hxx
index 3248d4c..5b9db7b 100644
--- a/xmloff/inc/SchXMLImport.hxx
+++ b/xmloff/inc/SchXMLImport.hxx
@@ -159,6 +159,9 @@ protected:
        const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;

    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;

public:
    SchXMLImport(
        const css::uno::Reference< css::uno::XComponentContext >& xContext,
diff --git a/xmloff/source/chart/SchXMLImport.cxx b/xmloff/source/chart/SchXMLImport.cxx
index eab97676..c1cdfc9 100644
--- a/xmloff/source/chart/SchXMLImport.cxx
+++ b/xmloff/source/chart/SchXMLImport.cxx
@@ -528,16 +528,7 @@ SvXMLImportContext *SchXMLImport::CreateDocumentContext(sal_uInt16 const nPrefix
        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
            GetModel(), uno::UNO_QUERY);
        // mst@: right now, this seems to be not supported, so it is untested
        if (xDPS.is()) {
            pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META))
                ? new SvXMLMetaDocumentContext(*this,
                            XML_NAMESPACE_OFFICE, rLocalName,
                            xDPS->getDocumentProperties())
                // flat OpenDocument file format
                : new SchXMLFlatDocContext_Impl(
                            *maImportHelper.get(), *this, nPrefix, rLocalName,
                            xDPS->getDocumentProperties());
        } else {
        if (!xDPS.is()) {
            pContext = (IsXMLToken(rLocalName, XML_DOCUMENT_META))
                ? SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList)
                : new SchXMLDocContext( *maImportHelper.get(), *this,
@@ -550,6 +541,36 @@ SvXMLImportContext *SchXMLImport::CreateDocumentContext(sal_uInt16 const nPrefix
    return pContext;
}

SvXMLImportContext *SchXMLImport::CreateFastContext( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    SvXMLImportContext* pContext = nullptr;

    switch (nElement)
    {
        case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
        {
            uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
                GetModel(), uno::UNO_QUERY);
            // mst@: right now, this seems to be not supported, so it is untested
            if (xDPS.is()) {
                pContext = (nElement == XML_ELEMENT( OFFICE, XML_DOCUMENT_META ))
                    ? new SvXMLMetaDocumentContext(*this,
                                xDPS->getDocumentProperties())
                    // flat OpenDocument file format
                    : new SchXMLFlatDocContext_Impl(
                                *maImportHelper.get(), *this, nElement,
                                xDPS->getDocumentProperties());
            }
        }
        break;
        default:
            pContext = new SvXMLImportContext( *this );
    }
    return pContext;
}

SvXMLImportContext* SchXMLImport::CreateStylesContext(
    const OUString& rLocalName,
    const Reference<xml::sax::XAttributeList>& xAttrList )
diff --git a/xmloff/source/chart/contexts.cxx b/xmloff/source/chart/contexts.cxx
index 2ddb503..ebba9ad 100644
--- a/xmloff/source/chart/contexts.cxx
+++ b/xmloff/source/chart/contexts.cxx
@@ -77,6 +77,18 @@ SchXMLDocContext::SchXMLDocContext( SchXMLImportHelper& rImpHelper,
          !IsXMLToken( rLName, XML_DOCUMENT_CONTENT) ), "xmloff.chart", "SchXMLDocContext instantiated with no <office:document> element" );
}

SchXMLDocContext::SchXMLDocContext( SchXMLImportHelper& rImpHelper,
                                    SvXMLImport& rImport,
                                    sal_Int32 nElement ) :
        SvXMLImportContext( rImport ),
        mrImportHelper( rImpHelper )
{
    SAL_WARN_IF(( nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT ) &&
          nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT_META ) &&
          nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ) &&
          nElement != XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ) ), "xmloff.chart", "SchXMLDocContext instantiated with no <office:document> element" );
}

SchXMLDocContext::~SchXMLDocContext()
{}

@@ -122,31 +134,33 @@ SvXMLImportContextRef SchXMLDocContext::CreateChildContext(
    return xContext;
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SchXMLDocContext::createFastChildContext(
    sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    return new SvXMLImportContext( GetImport() );
}

SchXMLFlatDocContext_Impl::SchXMLFlatDocContext_Impl(
        SchXMLImportHelper& i_rImpHelper,
        SchXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        sal_Int32 i_nElement,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
    SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
    SchXMLDocContext(i_rImpHelper, i_rImport, i_nPrefix, i_rLName),
    SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
        i_xDocProps)
    SvXMLImportContext(i_rImport),
    SchXMLDocContext(i_rImpHelper, i_rImport, i_nElement),
    SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
{
}

SvXMLImportContextRef SchXMLFlatDocContext_Impl::CreateChildContext(
    sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
    const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SchXMLFlatDocContext_Impl::createFastChildContext(
    sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    // behave like meta base class iff we encounter office:meta
    const SvXMLTokenMap& rTokenMap =
        mrImportHelper.GetDocElemTokenMap();
    if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) {
        return SvXMLMetaDocumentContext::CreateChildContext(
                    i_nPrefix, i_rLocalName, i_xAttrList );
    if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) {
        return SvXMLMetaDocumentContext::createFastChildContext(
                    nElement, xAttrList );
    } else {
        return SchXMLDocContext::CreateChildContext(
                    i_nPrefix, i_rLocalName, i_xAttrList );
        return SchXMLDocContext::createFastChildContext(
                    nElement, xAttrList );
    }
}

diff --git a/xmloff/source/chart/contexts.hxx b/xmloff/source/chart/contexts.hxx
index 9820cd3..c2980d8 100644
--- a/xmloff/source/chart/contexts.hxx
+++ b/xmloff/source/chart/contexts.hxx
@@ -47,13 +47,21 @@ public:
        SvXMLImport& rImport,
        sal_uInt16 nPrefix,
        const OUString& rLName );
    virtual ~SchXMLDocContext() override;

    SchXMLDocContext(
        SchXMLImportHelper& rImpHelper,
        SvXMLImport& rImport,
        sal_Int32 nElement );

    virtual ~SchXMLDocContext() override;

    virtual SvXMLImportContextRef CreateChildContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

// context for flat file xml format
@@ -64,12 +72,11 @@ public:
    SchXMLFlatDocContext_Impl(
        SchXMLImportHelper& i_rImpHelper,
        SchXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        sal_Int32 i_nElement,
        const css::uno::Reference<css::document::XDocumentProperties>& i_xDocProps);

    virtual SvXMLImportContextRef CreateChildContext(
        sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
        const css::uno::Reference<css::xml::sax::XAttributeList>& i_xAttrList) override;
    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

class SchXMLBodyContext : public SvXMLImportContext
diff --git a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx
index a90ec6b..bfa9023 100644
--- a/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx
+++ b/xmloff/source/core/XMLEmbeddedObjectImportContext.cxx
@@ -116,6 +116,9 @@ void XMLEmbeddedObjectImportContext::SetComponent( Reference< XComponent > const
    if( !xHandler.is() )
        return;

    if (SvXMLImport *pFastHandler = dynamic_cast<SvXMLImport*>(xHandler.get()))
        xHandler.set( new SvXMLLegacyToFastDocHandler( pFastHandler ) );

    try
    {
        Reference < XModifiable2 > xModifiable2( rComp, UNO_QUERY_THROW );
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index b92d5ed..ba656fe 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -80,6 +80,7 @@ using namespace ::xmloff::token;

css::uno::Reference< css::xml::sax::XFastTokenHandler > SvXMLImport::xTokenHandler( new FastTokenHandler() );
std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap;
std::unordered_map< OUString, OUString, OUStringHash > SvXMLImport::aNamespaceURIPrefixMap;
const OUString SvXMLImport::aDefaultNamespace = OUString("");
const OUString SvXMLImport::aNamespaceSeparator = OUString(":");
bool SvXMLImport::bIsNSMapsInitialized = false;
@@ -1125,6 +1126,11 @@ void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArgumen
            }
        }
    }

    uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW);
    uno::Sequence<uno::Any> args(1);
    args[0] <<= OUString("IgnoreMissingNSDecl");
    xInit->initialize( args );
}

// XServiceInfo
@@ -2062,14 +2068,35 @@ const OUString SvXMLImport::getNamespacePrefixFromToken( sal_Int32 nToken )
        return OUString();
}

const OUString SvXMLImport::getNamespaceURIFromToken( sal_Int32 nToken )
{
    sal_Int32 nNamespaceToken = ( nToken & NMSP_MASK ) >> NMSP_SHIFT;
    auto aIter( aNamespaceMap.find( nNamespaceToken ) );
    if( aIter != aNamespaceMap.end() )
        return (*aIter).second.second;
    else
        return OUString();
}

const OUString SvXMLImport::getNamespacePrefixFromURI( const OUString& rURI )
{
    auto aIter( aNamespaceURIPrefixMap.find(rURI) );
    if( aIter != aNamespaceURIPrefixMap.end() )
        return (*aIter).second;
    else
        return OUString();
}

void SvXMLImport::initializeNamespaceMaps()
{
    auto mapTokenToNamespace = [&]( sal_Int32 nToken, sal_Int32 nPrefix, sal_Int32 nNamespace )
    {
        if ( nToken >= 0 )
        {
            aNamespaceMap[ nToken + 1 ] = std::make_pair( GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) ),
                                                      GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) ) );
            const OUString& sNamespace = GetXMLToken( static_cast<XMLTokenEnum>( nNamespace ) );
            const OUString& sPrefix = GetXMLToken( static_cast<XMLTokenEnum>( nPrefix ) );
            aNamespaceMap[ nToken + 1 ] = std::make_pair( sPrefix, sNamespace );
            aNamespaceURIPrefixMap.emplace( sNamespace, sPrefix );
        }
    };

@@ -2180,6 +2207,12 @@ void SvXMLImportFastNamespaceHandler::addNSDeclAttributes( rtl::Reference < comp

void SvXMLImportFastNamespaceHandler::registerNamespace( const OUString& rNamespacePrefix, const OUString& rNamespaceURI )
{
    // Elements with default namespace parsed by FastParser have namepsace prefix.
    // A default namespace needs to be registered with the prefix, to maintan the compatibility.
    if ( rNamespacePrefix.isEmpty() )
        m_aNamespaceDefines.push_back( o3tl::make_unique<NamespaceDefine>(
                                    SvXMLImport::getNamespacePrefixFromURI( rNamespaceURI ), rNamespaceURI) );

    m_aNamespaceDefines.push_back( o3tl::make_unique<NamespaceDefine>(
                                    rNamespacePrefix, rNamespaceURI) );
}
diff --git a/xmloff/source/draw/sdxmlimp.cxx b/xmloff/source/draw/sdxmlimp.cxx
index 3d5e91e..2430ff3 100644
--- a/xmloff/source/draw/sdxmlimp.cxx
+++ b/xmloff/source/draw/sdxmlimp.cxx
@@ -90,23 +90,26 @@ protected:
    SdXMLImport& GetSdImport() { return static_cast<SdXMLImport&>(GetImport()); }

public:
    SdXMLDocContext_Impl(
        SdXMLImport& rImport,
        sal_uInt16 nPrfx,
        const OUString& rLName,
        const uno::Reference<xml::sax::XAttributeList>& xAttrList);
    SdXMLDocContext_Impl( SdXMLImport& rImport );

    virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const uno::Reference<xml::sax::XAttributeList>& xAttrList) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual void SAL_CALL characters( const OUString& /*aChars*/ ) override {}

    virtual void SAL_CALL startFastElement( sal_Int32 /*nElement*/,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override {}

    virtual void SAL_CALL endFastElement( sal_Int32 /*nElement*/ ) override {}
};

SdXMLDocContext_Impl::SdXMLDocContext_Impl(
    SdXMLImport& rImport,
    sal_uInt16 nPrfx,
    const OUString& rLName,
    const uno::Reference<xml::sax::XAttributeList>&)
:   SvXMLImportContext(rImport, nPrfx, rLName)
    SdXMLImport& rImport )
:   SvXMLImportContext(rImport)
{
}

@@ -193,44 +196,65 @@ SvXMLImportContextRef SdXMLDocContext_Impl::CreateChildContext(
    return xContext;
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SdXMLDocContext_Impl::createFastChildContext(
    sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
    return new SvXMLImportContext( GetImport() );
}

// context for flat file xml format
class SdXMLFlatDocContext_Impl
    : public SdXMLDocContext_Impl, public SvXMLMetaDocumentContext
{
public:
    SdXMLFlatDocContext_Impl( SdXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps);
        const uno::Reference<document::XDocumentProperties>& i_xDocProps );

    virtual SvXMLImportContextRef CreateChildContext(
        sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
        const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override;
    virtual void SAL_CALL startFastElement( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;

    virtual void SAL_CALL characters( const OUString& aChars ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};

SdXMLFlatDocContext_Impl::SdXMLFlatDocContext_Impl( SdXMLImport& i_rImport,
        sal_uInt16 i_nPrefix, const OUString & i_rLName,
        const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
        const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
    SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
    SdXMLDocContext_Impl(i_rImport, i_nPrefix, i_rLName, i_xAttrList),
    SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
        i_xDocProps)
    SvXMLImportContext(i_rImport),
    SdXMLDocContext_Impl(i_rImport),
    SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
{
}

SvXMLImportContextRef SdXMLFlatDocContext_Impl::CreateChildContext(
    sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
    const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
void SAL_CALL SdXMLFlatDocContext_Impl::startFastElement( sal_Int32 nElement,
    const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    SvXMLMetaDocumentContext::startFastElement(nElement, xAttrList);
}

void SAL_CALL SdXMLFlatDocContext_Impl::endFastElement( sal_Int32 nElement )
{
    SvXMLMetaDocumentContext::endFastElement(nElement);
}

void SAL_CALL SdXMLFlatDocContext_Impl::characters( const OUString& rChars )
{
    SvXMLMetaDocumentContext::characters(rChars);
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SdXMLFlatDocContext_Impl::createFastChildContext(
    sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    // behave like meta base class iff we encounter office:meta
    const SvXMLTokenMap& rTokenMap = GetSdImport().GetDocElemTokenMap();
    if ( XML_TOK_DOC_META == rTokenMap.Get( i_nPrefix, i_rLocalName ) ) {
        return SvXMLMetaDocumentContext::CreateChildContext(
                    i_nPrefix, i_rLocalName, i_xAttrList );
    if ( nElement == XML_ELEMENT( OFFICE, XML_META ) ) {
        return SvXMLMetaDocumentContext::createFastChildContext(
                    nElement, xAttrList );
    } else {
        return SdXMLDocContext_Impl::CreateChildContext(
                    i_nPrefix, i_rLocalName, i_xAttrList );
        return SdXMLDocContext_Impl::createFastChildContext(
                    nElement, xAttrList );
    }
}

@@ -584,37 +608,37 @@ const SvXMLTokenMap& SdXMLImport::GetPresentationPlaceholderAttrTokenMap()
    return *mpPresentationPlaceholderAttrTokenMap;
}

SvXMLImportContext *SdXMLImport::CreateDocumentContext(sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const uno::Reference<xml::sax::XAttributeList>& xAttrList)
SvXMLImportContext *SdXMLImport::CreateFastContext( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    SvXMLImportContext* pContext = nullptr;

    if(XML_NAMESPACE_OFFICE == nPrefix &&
        ( IsXMLToken( rLocalName, XML_DOCUMENT_STYLES ) ||
          IsXMLToken( rLocalName, XML_DOCUMENT_CONTENT ) ||
          IsXMLToken( rLocalName, XML_DOCUMENT_SETTINGS )   ))
    switch (nElement)
    {
         pContext = new SdXMLDocContext_Impl(*this, nPrefix, rLocalName, xAttrList);
    } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
                ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) {
        pContext = CreateMetaContext(rLocalName, xAttrList);
    } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
                ( IsXMLToken(rLocalName, XML_DOCUMENT)) ) {
        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
            GetModel(), uno::UNO_QUERY_THROW);
        // flat OpenDocument file format
        pContext = new SdXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
                        xAttrList, xDPS->getDocumentProperties());
    } else {
        pContext = SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList);
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ):
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ):
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ):
            pContext = new SdXMLDocContext_Impl(*this);
        break;
        case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
            pContext = CreateMetaContext(nElement, xAttrList);
        break;
        case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
        {
            uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
                GetModel(), uno::UNO_QUERY_THROW);
            // flat OpenDocument file format
            pContext = new SdXMLFlatDocContext_Impl( *this, xDPS->getDocumentProperties());
        }
        break;
        default:
            pContext = SvXMLImport::CreateFastContext(nElement, xAttrList);
    }

    return pContext;
}

SvXMLImportContext *SdXMLImport::CreateMetaContext(const OUString& rLocalName,
    const uno::Reference<xml::sax::XAttributeList>&)
SvXMLImportContext *SdXMLImport::CreateMetaContext(const sal_Int32 /*nElement*/,
    const uno::Reference<xml::sax::XFastAttributeList>&)
{
    SvXMLImportContext* pContext = nullptr;

@@ -624,14 +648,12 @@ SvXMLImportContext *SdXMLImport::CreateMetaContext(const OUString& rLocalName,
            GetModel(), uno::UNO_QUERY_THROW);
        uno::Reference<document::XDocumentProperties> const xDocProps(
            !mbLoadDoc ? nullptr : xDPS->getDocumentProperties());
        pContext = new SvXMLMetaDocumentContext(*this,
                        XML_NAMESPACE_OFFICE, rLocalName,
                        xDocProps);
        pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
    }

    if(!pContext)
    {
        pContext = new SvXMLImportContext(*this, XML_NAMESPACE_OFFICE, rLocalName);
        pContext = new SvXMLImportContext(*this);
    }

    return pContext;
diff --git a/xmloff/source/draw/sdxmlimp_impl.hxx b/xmloff/source/draw/sdxmlimp_impl.hxx
index 3900aa0..7b02989 100644
--- a/xmloff/source/draw/sdxmlimp_impl.hxx
+++ b/xmloff/source/draw/sdxmlimp_impl.hxx
@@ -176,9 +176,10 @@ class SdXMLImport: public SvXMLImport

protected:

    virtual SvXMLImportContext *CreateDocumentContext(sal_uInt16 nPrefix,
      const OUString& rLocalName,
      const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList) override;
    // This method is called after the namespace map has been updated, but
    // before a context for the current element has been pushed.
    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;

public:
    SdXMLImport(
@@ -198,8 +199,8 @@ public:
    // namespace office
    // NB: in contrast to other CreateFooContexts, this particular one handles
    //     the root element (i.e. office:document-meta)
    SvXMLImportContext* CreateMetaContext(const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList);
    SvXMLImportContext* CreateMetaContext(const sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList);
    SvXMLImportContext* CreateScriptContext( const OUString& rLocalName );
    SvXMLImportContext* CreateBodyContext(const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList);
diff --git a/xmloff/source/meta/MetaImportComponent.cxx b/xmloff/source/meta/MetaImportComponent.cxx
index d10d9c8..6f5d7c0 100644
--- a/xmloff/source/meta/MetaImportComponent.cxx
+++ b/xmloff/source/meta/MetaImportComponent.cxx
@@ -43,10 +43,8 @@ public:

protected:

    virtual SvXMLImportContext* CreateDocumentContext(
        sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList ) override;
    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;

    // XImporter
    virtual void SAL_CALL setTargetDocument( const css::uno::Reference< css::lang::XComponent >& xDoc ) override;
@@ -68,25 +66,22 @@ XMLMetaImportComponent::XMLMetaImportComponent(
{
}

SvXMLImportContext* XMLMetaImportComponent::CreateDocumentContext(
    sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const uno::Reference<xml::sax::XAttributeList > & xAttrList )
SvXMLImportContext *XMLMetaImportComponent::CreateFastContext( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    if (  (XML_NAMESPACE_OFFICE == nPrefix) &&
         IsXMLToken(rLocalName, XML_DOCUMENT_META) )
    if (nElement == XML_ELEMENT( OFFICE, XML_DOCUMENT_META ))
    {
        if (!mxDocProps.is()) {
            throw uno::RuntimeException(
                "XMLMetaImportComponent::CreateContext: setTargetDocument "
                "XMLMetaImportComponent::CreateFastContext: setTargetDocument "
                "has not been called", *this);
        }
        return new SvXMLMetaDocumentContext(
                        *this, nPrefix, rLocalName, mxDocProps);
                        *this, mxDocProps);
    }
    else
    {
        return SvXMLImport::CreateDocumentContext(nPrefix, rLocalName, xAttrList);
        return SvXMLImport::CreateFastContext(nElement, xAttrList);
    }
}

diff --git a/xmloff/source/meta/xmlmetai.cxx b/xmloff/source/meta/xmlmetai.cxx
index 1f9a1b9..10f60b7 100644
--- a/xmloff/source/meta/xmlmetai.cxx
+++ b/xmloff/source/meta/xmlmetai.cxx
@@ -41,57 +41,66 @@ private:
    css::uno::Reference< css::xml::dom::XSAXDocumentBuilder2> mxDocBuilder;

public:
    XMLDocumentBuilderContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
        const OUString& rLName,
        const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
    XMLDocumentBuilderContext(SvXMLImport& rImport, sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
        const css::uno::Reference< css::xml::dom::XSAXDocumentBuilder2>& rDocBuilder);

    virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
        const OUString& rLocalName,
        const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList ) override;
    virtual void SAL_CALL characters( const OUString& aChars ) override;

    virtual void StartElement( const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList ) override;
    virtual void SAL_CALL startFastElement( sal_Int32 nElement,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

    virtual void Characters( const OUString& rChars ) override;
    virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override;

    virtual void EndElement() override;
    virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name,
        const css::uno::Reference< css::xml::sax::XFastAttributeList >& Attribs ) override;

    virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) override;

    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
        sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;

};

XMLDocumentBuilderContext::XMLDocumentBuilderContext(SvXMLImport& rImport,
        sal_uInt16 nPrfx, const OUString& rLName,
        const uno::Reference<xml::sax::XAttributeList>&,
        sal_Int32 /*nElement*/, const uno::Reference<xml::sax::XFastAttributeList>&,
        const uno::Reference<xml::dom::XSAXDocumentBuilder2>& rDocBuilder) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    SvXMLImportContext( rImport ),
    mxDocBuilder(rDocBuilder)
{
}

SvXMLImportContextRef
XMLDocumentBuilderContext::CreateChildContext( sal_uInt16 nPrefix,
    const OUString& rLocalName,
    const uno::Reference< xml::sax::XAttributeList>& rAttrs)
void SAL_CALL XMLDocumentBuilderContext::startFastElement( sal_Int32 nElement,
        const uno::Reference< xml::sax::XFastAttributeList >& xAttribs )
{
    return new XMLDocumentBuilderContext(
                GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder);
    mxDocBuilder->startFastElement(nElement, xAttribs);
}

void XMLDocumentBuilderContext::StartElement(
    const uno::Reference< xml::sax::XAttributeList >& xAttrList )
void SAL_CALL XMLDocumentBuilderContext::endFastElement( sal_Int32 nElement )
{
    mxDocBuilder->startElement(
      GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()),
      xAttrList);
    mxDocBuilder->endFastElement(nElement);
}

void XMLDocumentBuilderContext::Characters( const OUString& rChars )
void SAL_CALL XMLDocumentBuilderContext::startUnknownElement( const OUString& rNamespace,
        const OUString& rName, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    mxDocBuilder->startUnknownElement(rNamespace, rName, xAttrList);
}

void SAL_CALL XMLDocumentBuilderContext::endUnknownElement( const OUString& rNamespace, const OUString& rName )
{
    mxDocBuilder->endUnknownElement(rNamespace, rName);
}

void SAL_CALL XMLDocumentBuilderContext::characters( const OUString& rChars )
{
    mxDocBuilder->characters(rChars);
}

void XMLDocumentBuilderContext::EndElement()
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL XMLDocumentBuilderContext::createFastChildContext(
    sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    mxDocBuilder->endElement(
      GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(), GetLocalName()));
    return new XMLDocumentBuilderContext( GetImport(), nElement, xAttrList, mxDocBuilder );
}

static void
@@ -150,19 +159,6 @@ lcl_initGenerator(SvXMLImport & rImport,
}

SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport,
            sal_uInt16 nPrfx, const OUString& rLName,
            const uno::Reference<document::XDocumentProperties>& xDocProps) :
    SvXMLImportContext( rImport, nPrfx, rLName ),
    mxDocProps(xDocProps),
    mxDocBuilder(
        xml::dom::SAXDocumentBuilder::create(
            comphelper::getProcessComponentContext()))
{
// #i103539#: must always read meta.xml for generator, xDocProps unwanted then
//    OSL_ENSURE(xDocProps.is(), "SvXMLMetaDocumentContext: no document props");
}

SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport,
            const uno::Reference<document::XDocumentProperties>& xDocProps) :
    SvXMLImportContext( rImport ),
    mxDocProps(xDocProps),
@@ -178,39 +174,18 @@ SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext()
{
}

SvXMLImportContextRef SvXMLMetaDocumentContext::CreateChildContext(
             sal_uInt16 nPrefix, const OUString& rLocalName,
             const uno::Reference<xml::sax::XAttributeList>& rAttrs)
{
    if (  (XML_NAMESPACE_OFFICE == nPrefix) &&
         IsXMLToken(rLocalName, XML_META) )
    {
        return new XMLDocumentBuilderContext(
                GetImport(), nPrefix, rLocalName, rAttrs, mxDocBuilder);
    }
    else
    {
        return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    }
}

void SvXMLMetaDocumentContext::StartElement(
    const uno::Reference< xml::sax::XAttributeList >& xAttrList )
void SAL_CALL SvXMLMetaDocumentContext::startFastElement( sal_Int32 nElement,
            const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    mxDocBuilder->startDocument();
    // hardcode office:document-meta (necessary in case of flat file ODF)
    mxDocBuilder->startElement(
        GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
            GetXMLToken(XML_DOCUMENT_META)), xAttrList);

    mxDocBuilder->startFastElement( ( nElement & NMSP_MASK ) | XML_DOCUMENT_META, xAttrList );
}

void SvXMLMetaDocumentContext::EndElement()
void SAL_CALL SvXMLMetaDocumentContext::endFastElement( sal_Int32 nElement )
{
    // hardcode office:document-meta (necessary in case of flat file ODF)
    mxDocBuilder->endElement(
        GetImport().GetNamespaceMap().GetQNameByKey(GetPrefix(),
            GetXMLToken(XML_DOCUMENT_META)));
    mxDocBuilder->endFastElement( ( nElement & NMSP_MASK ) | XML_DOCUMENT_META );
    mxDocBuilder->endDocument();
    if (mxDocProps.is())
    {
@@ -222,6 +197,20 @@ void SvXMLMetaDocumentContext::EndElement()
    }
}

void SAL_CALL SvXMLMetaDocumentContext::characters( const OUString& /*rChars*/ )
{
}

uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SvXMLMetaDocumentContext::createFastChildContext(
    sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
{
    if ( nElement == ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_META ) )
        return new XMLDocumentBuilderContext(
                GetImport(), nElement, xAttrList, mxDocBuilder);
    else
        return new SvXMLImportContext( GetImport() );
}

void SvXMLMetaDocumentContext::setBuildId(OUString const& i_rBuildId, const uno::Reference<beans::XPropertySet>& xImportInfo )
{
    OUString sBuildId;