/*************************************************************************
 *
 *  $RCSfile: xmlimp.cxx,v $
 *
 *  $Revision: 1.89 $
 *
 *  last change: $Author: obo $ $Date: 2005-09-05 14:52:38 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#endif

#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT
#include <tools/debug.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#include <rtl/uuid.h>
#include <rtl/memory.h>

#ifndef _SVARRAY_HXX
#include <svtools/svarray.hxx>
#endif

#ifndef __COMPHELPER_UNOINTERFACETOUNIQUEIDENTIFIERMAPPER__
#include "unointerfacetouniqueidentifiermapper.hxx"
#endif

#ifndef _XMLOFF_NMSPMAP_HXX
#include "nmspmap.hxx"
#endif
#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif

#ifndef _XMLOFF_XMLKYWD_HXX
#include "xmlkywd.hxx"
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif
#ifndef _XMLOFF_XMLFONTSTYLESCONTEXT_HXX_
#include "XMLFontStylesContext.hxx"
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

#ifndef _XMLOFF_XMLIMP_HXX
#include "xmlimp.hxx"
#endif
#ifndef _XMLOFF_XMLNUMFI_HXX
#include "xmlnumfi.hxx"
#endif
#ifndef _XMLOFF_XMLEVENTIMPORTHELPER_HXX
#include "XMLEventImportHelper.hxx"
#endif
#ifndef _XMLOFF_XMLSTARBASICCONTEXTFACTORY_HXX
#include "XMLStarBasicContextFactory.hxx"
#endif
#ifndef _XMLOFF_XMLSCRIPTCONTEXTFACTORY_HXX
#include "XMLScriptContextFactory.hxx"
#endif
#ifndef _XMLOFF_STYLEMAP_HXX
#include "StyleMap.hxx"
#endif

#ifndef _XMLOFF_PROGRESSBARHELPER_HXX
#include "ProgressBarHelper.hxx"
#endif

#ifndef _XMLOFF_XMLTOKEN_HXX
#include "xmltoken.hxx"
#endif

#ifndef _XMLOFF_XMLERROR_HXX
#include "xmlerror.hxx"
#endif

#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_SERVICENOTREGISTEREDEXCEPTION_HPP_
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
#include <com/sun/star/io/XOutputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XBINARYSTREAMRESOLVER_HPP_
#include <com/sun/star/document/XBinaryStreamResolver.hpp>
#endif
#ifndef _COM_SUN_STAR_XML_SAX_XLOCATOR_HPP_
#include <com/sun/star/xml/sax/XLocator.hpp>
#endif

#ifndef _COMPHELPER_NAMECONTAINER_HXX_
#include <comphelper/namecontainer.hxx>
#endif

#ifndef _RTL_LOGFILE_HXX_
#include <rtl/logfile.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx> // used in StartElement for logging
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifdef CONV_STAR_FONTS
#ifndef _VCL_FONTCVT_HXX
#include <vcl/fontcvt.hxx>
#endif
#endif

#define LOGFILE_AUTHOR "unknown"

using ::com::sun::star::beans::XPropertySetInfo;

using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using namespace ::xmloff::token;

sal_Char __READONLY_DATA sXML_np__office[] = "_office";
sal_Char __READONLY_DATA sXML_np__ooo[] = "_ooo";
sal_Char __READONLY_DATA sXML_np__ooow[] = "_ooow";
sal_Char __READONLY_DATA sXML_np__oooc[] = "_oooc";
sal_Char __READONLY_DATA sXML_np__style[] = "_style";
sal_Char __READONLY_DATA sXML_np__text[] = "_text";
sal_Char __READONLY_DATA sXML_np__table[] = "_table";
sal_Char __READONLY_DATA sXML_np__draw[] = "_draw";
sal_Char __READONLY_DATA sXML_np__dr3d[] = "_dr3d";
sal_Char __READONLY_DATA sXML_np__fo[] = "_fo";
sal_Char __READONLY_DATA sXML_np__xlink[] = "_xlink";
sal_Char __READONLY_DATA sXML_np__dc[] = "_dc";
sal_Char __READONLY_DATA sXML_np__dom[] = "_dom";
sal_Char __READONLY_DATA sXML_np__meta[] = "_meta";
sal_Char __READONLY_DATA sXML_np__number[] = "_number";
sal_Char __READONLY_DATA sXML_np__svg[] = "_svg";
sal_Char __READONLY_DATA sXML_np__chart[] = "_chart";
sal_Char __READONLY_DATA sXML_np__math[] = "_math";
sal_Char __READONLY_DATA sXML_np__script[] = "_script";
sal_Char __READONLY_DATA sXML_np__config[] = "_config";
sal_Char __READONLY_DATA sXML_np__db[] = "_db";
sal_Char __READONLY_DATA sXML_np__xforms[] = "_xforms";
sal_Char __READONLY_DATA sXML_np__xsd[] = "_xsd";
sal_Char __READONLY_DATA sXML_np__xsi[] = "_xsi";

sal_Char __READONLY_DATA sXML_np__fo_old[] = "__fo";
sal_Char __READONLY_DATA sXML_np__xlink_old[] = "__xlink";
sal_Char __READONLY_DATA sXML_np__office_old[] = "__office";
sal_Char __READONLY_DATA sXML_np__style_old[] = "__style";
sal_Char __READONLY_DATA sXML_np__text_old[] = "__text";
sal_Char __READONLY_DATA sXML_np__table_old[] = "__table";
sal_Char __READONLY_DATA sXML_np__meta_old[] = "__meta";



class SvXMLImportEventListener : public cppu::WeakImplHelper1<
                            com::sun::star::lang::XEventListener >
{
private:
    SvXMLImport*    pImport;

public:
                            SvXMLImportEventListener(SvXMLImport* pImport);
    virtual                 ~SvXMLImportEventListener();

                            // XEventListener
    virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) throw(::com::sun::star::uno::RuntimeException);
};

SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport)
    : pImport(pTempImport)
{
}

SvXMLImportEventListener::~SvXMLImportEventListener()
{
}

// XEventListener
void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& rEventObject )
    throw(uno::RuntimeException)
{
    if (pImport)
    {
        pImport->DisposingModel();
        pImport = NULL;
    }
}

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

class SvXMLImport_Impl
{
public:
#ifdef CONV_STAR_FONTS
    FontToSubsFontConverter hBatsFontConv;
    FontToSubsFontConverter hMathFontConv;
#endif

    bool mbOwnGraphicResolver;
    bool mbOwnEmbeddedResolver;
    INetURLObject aBaseURL;
    INetURLObject aDocBase;
    // --> OD 2004-08-10 #i28749# - boolean, indicating that position attributes
    // of shapes are given in horizontal left-to-right layout. This is the case
    // for the OpenOffice.org file format.
    sal_Bool mbShapePositionInHoriL2R;
    // <--

    SvXMLImport_Impl() :
#ifdef CONV_STAR_FONTS
        hBatsFontConv( 0 ), hMathFontConv( 0 ),
#endif
        mbOwnGraphicResolver( false ),
        mbOwnEmbeddedResolver( false ),
        // --> OD 2004-08-11 #i28749#
        mbShapePositionInHoriL2R( sal_False )
        // <--
    {}
    ~SvXMLImport_Impl()
    {
#ifdef CONV_STAR_FONTS
        if( hBatsFontConv )
            DestroyFontToSubsFontConverter( hBatsFontConv );
        if( hMathFontConv )
            DestroyFontToSubsFontConverter( hMathFontConv );
#endif
    }

    ::comphelper::UnoInterfaceToUniqueIdentifierMapper  maInterfaceToIdentifierMapper;
};

typedef SvXMLImportContext *SvXMLImportContextPtr;
SV_DECL_PTRARR( SvXMLImportContexts_Impl, SvXMLImportContextPtr, 20, 5 )
SV_IMPL_PTRARR( SvXMLImportContexts_Impl, SvXMLImportContextPtr )

SvXMLImportContext *SvXMLImport::CreateContext( USHORT nPrefix,
                                         const OUString& rLocalName,
                                         const uno::Reference< xml::sax::XAttributeList >& xAttrList )
{
    return new SvXMLImportContext( *this, nPrefix, rLocalName );
}

void SvXMLImport::_InitCtor()
{
    if( mnImportFlags != 0 )
    {
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__office ) ),
                            GetXMLToken(XML_N_OFFICE),
                            XML_NAMESPACE_OFFICE );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__ooo ) ), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__style) ),
                            GetXMLToken(XML_N_STYLE),
                            XML_NAMESPACE_STYLE );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__text) ),
                            GetXMLToken(XML_N_TEXT),
                            XML_NAMESPACE_TEXT );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__table ) ),
                            GetXMLToken(XML_N_TABLE),
                            XML_NAMESPACE_TABLE );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__draw ) ),
                            GetXMLToken(XML_N_DRAW),
                            XML_NAMESPACE_DRAW );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM (sXML_np__dr3d ) ),
                            GetXMLToken(XML_N_DR3D),
                            XML_NAMESPACE_DR3D );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__fo) ),
                            GetXMLToken(XML_N_FO_COMPAT),
                            XML_NAMESPACE_FO );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__xlink) ),
                            GetXMLToken(XML_N_XLINK),
                            XML_NAMESPACE_XLINK );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__dc) ),
                            GetXMLToken(XML_N_DC),
                            XML_NAMESPACE_DC );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__dom ) ),
                            GetXMLToken(XML_N_DOM),
                            XML_NAMESPACE_DOM );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__meta) ),
                            GetXMLToken(XML_N_META),
                            XML_NAMESPACE_META );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__number) ),
                            GetXMLToken(XML_N_NUMBER),
                            XML_NAMESPACE_NUMBER );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__svg) ),
                            GetXMLToken(XML_N_SVG_COMPAT),
                            XML_NAMESPACE_SVG );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__chart) ),
                            GetXMLToken(XML_N_CHART),
                            XML_NAMESPACE_CHART );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__math) ),
                            GetXMLToken(XML_N_MATH),
                            XML_NAMESPACE_MATH );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_namespace_form) ),
                            GetXMLToken(XML_N_FORM),
                            XML_NAMESPACE_FORM );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__script) ),
                            GetXMLToken(XML_N_SCRIPT),
                            XML_NAMESPACE_SCRIPT );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__config) ),
                            GetXMLToken(XML_N_CONFIG),
                            XML_NAMESPACE_CONFIG );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__xforms) ),
                            GetXMLToken(XML_N_XFORMS_1_0),
                            XML_NAMESPACE_XFORMS );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__xsd) ),
                            GetXMLToken(XML_N_XSD),
                            XML_NAMESPACE_XSD );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__xsi) ),
                            GetXMLToken(XML_N_XSI),
                            XML_NAMESPACE_XFORMS );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__ooow ) ), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
        pNamespaceMap->Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__oooc ) ), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
    }

    sPackageProtocol = OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package:" ) );

    if (xNumberFormatsSupplier.is())
        pNumImport = new SvXMLNumFmtHelper(xNumberFormatsSupplier, getServiceFactory());

    if (xModel.is() && !xEventListener.is())
    {
        xEventListener.set(new SvXMLImportEventListener(this));
        xModel->addEventListener(xEventListener);
    }

        ::comphelper::UnoInterfaceToUniqueIdentifierMapper  maInterfaceToIdentifierMapper;

}

// #110680#
SvXMLImport::SvXMLImport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
    sal_uInt16 nImportFlags ) throw ()
:   pImpl( new SvXMLImport_Impl() ),
    // #110680#
    mxServiceFactory(xServiceFactory),
    pNamespaceMap( new SvXMLNamespaceMap ),

    // #110680#
    // pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, MAP_100TH_MM ) ),
    pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, MAP_100TH_MM, getServiceFactory() ) ),

    pContexts( new SvXMLImportContexts_Impl ),
    pNumImport( NULL ),
    pProgressBarHelper( NULL ),
    pEventImportHelper( NULL ),
    pXMLErrors( NULL ),
    pStyleMap(0),
    mnImportFlags( nImportFlags ),
    mbIsFormsSupported( sal_True )
{
    DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
    _InitCtor();
}

// #110680#
SvXMLImport::SvXMLImport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
    const Reference< XModel > & rModel ) throw ()
:   pImpl( new SvXMLImport_Impl() ),
    // #110680#
    mxServiceFactory(xServiceFactory),
    pNamespaceMap( new SvXMLNamespaceMap ),

    // #110680#
    // pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, MAP_100TH_MM ) ),
    pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, MAP_100TH_MM, getServiceFactory() ) ),

    pContexts( new SvXMLImportContexts_Impl ),
    pNumImport( NULL ),
    xModel( rModel ),
    xNumberFormatsSupplier (rModel, uno::UNO_QUERY),
    pProgressBarHelper( NULL ),
    pEventImportHelper( NULL ),
    pXMLErrors( NULL ),
    pStyleMap(0),
    mnImportFlags( IMPORT_ALL ),
    mbIsFormsSupported( sal_True )
{
    DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
    _InitCtor();
}

// #110680#
SvXMLImport::SvXMLImport(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
    const Reference< XModel > & rModel,
    const ::com::sun::star::uno::Reference< ::com::sun::star::document::XGraphicObjectResolver > & rGraphicObjects ) throw ()
:   pImpl( new SvXMLImport_Impl() ),
    // #110680#
    mxServiceFactory(xServiceFactory),
    pNamespaceMap( new SvXMLNamespaceMap ),

    // #110680#
    // pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, MAP_100TH_MM ) ),
    pUnitConv( new SvXMLUnitConverter( MAP_100TH_MM, MAP_100TH_MM, getServiceFactory() ) ),

    pContexts( new SvXMLImportContexts_Impl ),
    pNumImport( NULL ),
    xModel( rModel ),
    xGraphicResolver( rGraphicObjects ),
    xNumberFormatsSupplier (rModel, uno::UNO_QUERY),
    pProgressBarHelper( NULL ),
    pEventImportHelper( NULL ),
    pXMLErrors( NULL ),
    pStyleMap(0),
    mnImportFlags( IMPORT_ALL ),
    mbIsFormsSupported( sal_True )
{
    DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
    _InitCtor();
}

SvXMLImport::~SvXMLImport() throw ()
{
    delete pXMLErrors;
    delete pNamespaceMap;
    delete pUnitConv;
    delete pContexts;
    delete pEventImportHelper;
//  delete pImageMapImportHelper;

    //  #i9518# the import component might not be deleted until after the document has been closed,
    //  so the stuff that accesses the document has been moved to endDocument.

    //  pNumImport is allocated in the ctor, so it must also be deleted here in case the component
    //  is created and deleted without actually importing.
    delete pNumImport;
    delete pProgressBarHelper;

    xmloff::token::ResetTokens();

    if( pImpl )
        delete pImpl;

    if (xEventListener.is() && xModel.is())
        xModel->removeEventListener(xEventListener);
}

// XUnoTunnel & co
const uno::Sequence< sal_Int8 > & SvXMLImport::getUnoTunnelId() throw()
{
    static uno::Sequence< sal_Int8 > * pSeq = 0;
    if( !pSeq )
    {
        Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
        if( !pSeq )
        {
            static uno::Sequence< sal_Int8 > aSeq( 16 );
            rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
            pSeq = &aSeq;
        }
    }
    return *pSeq;
}

SvXMLImport* SvXMLImport::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
{
    uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
    if( xUT.is() )
        return (SvXMLImport*)xUT->getSomething( SvXMLImport::getUnoTunnelId() );
    else
        return NULL;
}

// XUnoTunnel
sal_Int64 SAL_CALL SvXMLImport::getSomething( const uno::Sequence< sal_Int8 >& rId )
    throw( uno::RuntimeException )
{
    if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
                                                         rId.getConstArray(), 16 ) )
    {
        return (sal_Int64)this;
    }
    return 0;
}

void SAL_CALL SvXMLImport::startDocument( void )
    throw( xml::sax::SAXException, uno::RuntimeException )
{
    RTL_LOGFILE_TRACE_AUTHOR( "xmloff", LOGFILE_AUTHOR, "{ SvXMLImport::startDocument" );

    if( !xGraphicResolver.is() || !xEmbeddedResolver.is() )
    {
        Reference< lang::XMultiServiceFactory > xFactory( xModel,   UNO_QUERY );
        if( xFactory.is() )
        {
            try
            {
                if( !xGraphicResolver.is() )
                {
                    xGraphicResolver = Reference< XGraphicObjectResolver >::query(
                        xFactory->createInstance(
                            OUString(RTL_CONSTASCII_USTRINGPARAM(
                                // #99870# Import... instead of Export...
                                "com.sun.star.document.ImportGraphicObjectResolver"))));
                    pImpl->mbOwnGraphicResolver = xGraphicResolver.is();
                }

                if( !xEmbeddedResolver.is() )
                {
                    xEmbeddedResolver = Reference< XEmbeddedObjectResolver >::query(
                        xFactory->createInstance(
                            OUString(RTL_CONSTASCII_USTRINGPARAM(
                                // #99870# Import... instead of Export...
                                "com.sun.star.document.ImportEmbeddedObjectResolver"))));
                    pImpl->mbOwnEmbeddedResolver = xEmbeddedResolver.is();
                }
            }
            catch( com::sun::star::uno::Exception& )
            {
            }
        }
    }
}

void SAL_CALL SvXMLImport::endDocument( void )
    throw( xml::sax::SAXException, uno::RuntimeException)
{
    RTL_LOGFILE_TRACE_AUTHOR( "xmloff", LOGFILE_AUTHOR, "} SvXMLImport::startDocument" );

    //  #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
    //  because the SvXMLImport dtor might not be called until after the document has been closed.

    if (pNumImport)
    {
        delete pNumImport;
        pNumImport = NULL;
    }
    if (xImportInfo.is())
    {
        uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
        if (xPropertySetInfo.is())
        {
            if (pProgressBarHelper)
            {
                OUString sProgressMax(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSMAX));
                OUString sProgressCurrent(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSCURRENT));
                OUString sRepeat(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSREPEAT));
                if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
                    xPropertySetInfo->hasPropertyByName(sProgressCurrent))
                {
                    sal_Int32 nProgressMax(pProgressBarHelper->GetReference());
                    sal_Int32 nProgressCurrent(pProgressBarHelper->GetValue());
                    uno::Any aAny;
                    aAny <<= nProgressMax;
                    xImportInfo->setPropertyValue(sProgressMax, aAny);
                    aAny <<= nProgressCurrent;
                    xImportInfo->setPropertyValue(sProgressCurrent, aAny);
                }
                if (xPropertySetInfo->hasPropertyByName(sRepeat))
                    xImportInfo->setPropertyValue(sRepeat, cppu::bool2any(pProgressBarHelper->GetRepeat()));
                // pProgressBarHelper is deleted in dtor
            }
            OUString sNumberStyles(RTL_CONSTASCII_USTRINGPARAM(XML_NUMBERSTYLES));
            if (xNumberStyles.is() && xPropertySetInfo->hasPropertyByName(sNumberStyles))
            {
                uno::Any aAny;
                aAny <<= xNumberStyles;
                xImportInfo->setPropertyValue(sNumberStyles, aAny);
            }
        }
    }

    if( xFontDecls.Is() )
        ((SvXMLStylesContext *)&xFontDecls)->Clear();
    if( xStyles.Is() )
        ((SvXMLStylesContext *)&xStyles)->Clear();
    if( xAutoStyles.Is() )
        ((SvXMLStylesContext *)&xAutoStyles)->Clear();
    if( xMasterStyles.Is() )
        ((SvXMLStylesContext *)&xMasterStyles)->Clear();

    // possible form-layer related knittings which can only be done when
    // the whole document exists
    if ( mxFormImport.is() )
        mxFormImport->documentDone();

    //  The shape import helper does the z-order sorting in the dtor,
    //  so it must be deleted here, too.
    mxShapeImport = NULL;

    if( pImpl->mbOwnGraphicResolver )
    {
        Reference< lang::XComponent > xComp( xGraphicResolver, UNO_QUERY );
        xComp->dispose();
    }

    if( pImpl->mbOwnEmbeddedResolver )
    {
        Reference< lang::XComponent > xComp( xEmbeddedResolver, UNO_QUERY );
        xComp->dispose();
    }
    if( pStyleMap )
    {
        pStyleMap->release();
        pStyleMap = 0;
    }

    if ( pXMLErrors != NULL )
    {
        pXMLErrors->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE );
    }
}

void SAL_CALL SvXMLImport::startElement( const OUString& rName,
                                         const uno::Reference< xml::sax::XAttributeList >& xAttrList )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
    SvXMLNamespaceMap *pRewindMap = 0;

    // Process namespace attributes. This must happen before creating the
    // context, because namespace decaration apply to the element name itself.
    INT16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    for( INT16 i=0; i < nAttrCount; i++ )
    {
        const OUString& rAttrName = xAttrList->getNameByIndex( i );
        if( ( rAttrName.getLength() >= 5 ) &&
            ( rAttrName.compareToAscii( sXML_xmlns, 5 ) == 0 ) &&
            ( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
        {
            if( !pRewindMap )
            {
                pRewindMap = pNamespaceMap;
                pNamespaceMap = new SvXMLNamespaceMap( *pNamespaceMap );
            }
            const OUString& rAttrValue = xAttrList->getValueByIndex( i );

            OUString aPrefix( ( rAttrName.getLength() == 5 )
                                 ? OUString()
                                 : rAttrName.copy( 6 ) );
            // Add namespace, but only if it is known.
            sal_uInt16 nKey = pNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
            // If namespace is unknwon, try to match a name with similar
            // TC Id an version
            if( XML_NAMESPACE_UNKNOWN == nKey  )
            {
                OUString aTestName( rAttrValue );
                if( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
                    nKey = pNamespaceMap->AddIfKnown( aPrefix, aTestName );
            }
            // If that namespace is not known, too, add it as unknown
            if( XML_NAMESPACE_UNKNOWN == nKey  )
                pNamespaceMap->Add( aPrefix, rAttrValue );

        }
    }

    // Get element's namespace and local name.
    OUString aLocalName;
    USHORT nPrefix =
        pNamespaceMap->GetKeyByAttrName( rName, &aLocalName );

    // If there are contexts already, call a CreateChildContext at the topmost
    // context. Otherwise, create a default context.
    SvXMLImportContext *pContext;
    USHORT nCount = pContexts->Count();
    if( nCount > 0 )
    {
        pContext = (*pContexts)[nCount - 1]->CreateChildContext( nPrefix,
                                                                 aLocalName,
                                                                 xAttrList );
    }
    else
    {
#ifdef TIMELOG
        // If we do profiling, we want a trace message for the first element
        // in order to identify the stream.
        ByteString aString( (String)rName, RTL_TEXTENCODING_ASCII_US );
        RTL_LOGFILE_TRACE_AUTHOR1( "xmloff", LOGFILE_AUTHOR,
                                   "SvXMLImport::StartElement( \"%s\", ... )",
                                   aString.GetBuffer() );
#endif

        pContext = CreateContext( nPrefix, aLocalName, xAttrList );
        if( (nPrefix & XML_NAMESPACE_UNKNOWN_FLAG) != 0 &&
            IS_TYPE( SvXMLImportContext, pContext ) )
        {
            OUString aMsg( RTL_CONSTASCII_USTRINGPARAM( "Root element unknown" ) );
            Reference<xml::sax::XLocator> xDummyLocator;
            Sequence < OUString > aParams(1);
            aParams.getArray()[0] = rName;

            SetError( XMLERROR_FLAG_SEVERE|XMLERROR_UNKNWON_ROOT,
                      aParams, aMsg, xDummyLocator );
        }
    }

    DBG_ASSERT( pContext, "SvXMLImport::startElement: missing context" );
    if( !pContext )
        pContext = new SvXMLImportContext( *this, nPrefix, aLocalName );

    pContext->AddRef();

    // Remeber old namespace map.
    if( pRewindMap )
        pContext->SetRewindMap( pRewindMap );

    // Call a startElement at the new context.
    pContext->StartElement( xAttrList );

    // Push context on stack.
    pContexts->Insert( pContext, nCount );
}

void SAL_CALL SvXMLImport::endElement( const OUString& rName )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
    USHORT nCount = pContexts->Count();
    DBG_ASSERT( nCount, "SvXMLImport::endElement: no context left" );
    if( nCount > 0 )
    {
        // Get topmost context and remove it from the stack.
        SvXMLImportContext *pContext = (*pContexts)[nCount-1];
        pContexts->Remove( nCount-1, 1 );

#ifndef PRODUCT
        // Non product only: check if endElement call matches startELement call.
        OUString aLocalName;
        USHORT nPrefix =
            pNamespaceMap->GetKeyByAttrName( rName, &aLocalName );
        DBG_ASSERT( pContext->GetPrefix() == nPrefix,
                "SvXMLImport::endElement: popped context has wrong prefix" );
        DBG_ASSERT( pContext->GetLocalName() == aLocalName,
                "SvXMLImport::endElement: popped context has wrong lname" );
#endif

        // Call a EndElement at the current context.
        pContext->EndElement();

        // Get a namespace map to rewind.
        SvXMLNamespaceMap *pRewindMap = pContext->GetRewindMap();

        // Delete the current context.
        pContext->ReleaseRef();
        pContext = 0;

        // Rewind a namespace map.
        if( pRewindMap )
        {
            delete pNamespaceMap;
            pNamespaceMap = pRewindMap;
        }
    }
}

void SAL_CALL SvXMLImport::characters( const OUString& rChars )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
    USHORT nCount = pContexts->Count();
    if( nCount > 0 )
    {
        (*pContexts)[nCount - 1]->Characters( rChars );
    }
}

void SAL_CALL SvXMLImport::ignorableWhitespace( const OUString& rWhitespaces )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
}

void SAL_CALL SvXMLImport::processingInstruction( const OUString& rTarget,
                                       const OUString& rData )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
}

void SAL_CALL SvXMLImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
    xLocator = rLocator;
}

// XExtendedDocumentHandler
void SAL_CALL SvXMLImport::startCDATA( void ) throw(xml::sax::SAXException, uno::RuntimeException)
{
}

void SAL_CALL SvXMLImport::endCDATA( void ) throw(uno::RuntimeException)
{
}

void SAL_CALL SvXMLImport::comment( const OUString& rComment )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
}

void SAL_CALL SvXMLImport::allowLineBreak( void )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
}

void SAL_CALL SvXMLImport::unknown( const OUString& sString )
    throw(xml::sax::SAXException, uno::RuntimeException)
{
}

void SvXMLImport::SetStatisticAttributes(const uno::Reference< xml::sax::XAttributeList > & xAttribs)
{
    GetProgressBarHelper()->SetRepeat(sal_False);
    GetProgressBarHelper()->SetReference(0);
}

///////////////////////////////////////////////////////////////////////

// XImporter
void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
    throw(lang::IllegalArgumentException, uno::RuntimeException)
{
    xModel = uno::Reference< frame::XModel >::query( xDoc );
    if( !xModel.is() )
        throw lang::IllegalArgumentException();
    if (xModel.is() && !xEventListener.is())
    {
        xEventListener.set(new SvXMLImportEventListener(this));
        xModel->addEventListener(xEventListener);
    }

    DBG_ASSERT( !pNumImport, "number format import already exists." );
    if( pNumImport )
    {
        delete pNumImport;
        pNumImport = 0;
    }
}

// XFilter
sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
    throw (uno::RuntimeException)
{
    return sal_False;
}

void SAL_CALL SvXMLImport::cancel(  )
    throw (uno::RuntimeException)
{
}

// XInitialize
void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
    throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
    const sal_Int32 nAnyCount = aArguments.getLength();
    const uno::Any* pAny = aArguments.getConstArray();

    for( sal_Int32 nIndex = 0; nIndex < nAnyCount; nIndex++, pAny++ )
    {
        Reference<XInterface> xValue;
        *pAny >>= xValue;

        uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
            xValue, UNO_QUERY );
        if( xTmpStatusIndicator.is() )
            mxStatusIndicator = xTmpStatusIndicator;

        uno::Reference<document::XGraphicObjectResolver> xTmpGraphicResolver(
            xValue, UNO_QUERY );
        if( xTmpGraphicResolver.is() )
            xGraphicResolver = xTmpGraphicResolver;

        uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
            xValue, UNO_QUERY );
        if( xTmpObjectResolver.is() )
            xEmbeddedResolver = xTmpObjectResolver;

        uno::Reference<beans::XPropertySet> xTmpPropSet( xValue, UNO_QUERY );
        if( xTmpPropSet.is() )
        {
            xImportInfo = xTmpPropSet;
            uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
            if (xPropertySetInfo.is())
            {
                OUString sPropName(RTL_CONSTASCII_USTRINGPARAM(XML_NUMBERSTYLES));
                if (xPropertySetInfo->hasPropertyByName(sPropName))
                {
                    uno::Any aAny = xImportInfo->getPropertyValue(sPropName);
                    aAny >>= xNumberStyles;
                }

                sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("PrivateData" ) );
                if (xPropertySetInfo->hasPropertyByName(sPropName))
                {
                    Reference < XInterface > xIfc;
                    uno::Any aAny = xImportInfo->getPropertyValue(sPropName);
                    aAny >>= xIfc;

                    StyleMap *pSMap = StyleMap::getImplementation( xIfc );
                    if( pSMap )
                    {
                        pStyleMap = pSMap;
                        pStyleMap->acquire();
                    }
                }
                OUString sBaseURI;
                sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("BaseURI" ) );
                if (xPropertySetInfo->hasPropertyByName(sPropName))
                {
                    uno::Any aAny = xImportInfo->getPropertyValue(sPropName);
                    aAny >>= sBaseURI;
                    pImpl->aBaseURL.SetURL( sBaseURI );
                    pImpl->aDocBase.SetURL( sBaseURI );
                }
                OUString sRelPath;
                sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("StreamRelPath" ) );
                if( xPropertySetInfo->hasPropertyByName(sPropName) )
                {
                    uno::Any aAny = xImportInfo->getPropertyValue(sPropName);
                    aAny >>= sRelPath;
                }
                OUString sName;
                sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("StreamName" ) );
                if( xPropertySetInfo->hasPropertyByName(sPropName) )
                {
                    uno::Any aAny = xImportInfo->getPropertyValue(sPropName);
                    aAny >>= sName;
                }
                if( sBaseURI.getLength() && sName.getLength() )
                {
                    if( sRelPath.getLength() )
                        pImpl->aBaseURL.insertName( sRelPath );
                    pImpl->aBaseURL.insertName( sName );
                }
                // --> OD 2004-08-10 #i28749# - retrieve property <ShapePositionInHoriL2R>
                sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("ShapePositionInHoriL2R" ) );
                if( xPropertySetInfo->hasPropertyByName(sPropName) )
                {
                    uno::Any aAny = xImportInfo->getPropertyValue(sPropName);
                    aAny >>= (pImpl->mbShapePositionInHoriL2R);
                }
                // <--
            }
        }
    }
}

// XServiceInfo
OUString SAL_CALL SvXMLImport::getImplementationName()
    throw(uno::RuntimeException)
{
    OUString aStr;
    return aStr;
}

sal_Bool SAL_CALL SvXMLImport::supportsService( const OUString& rServiceName )
    throw(::com::sun::star::uno::RuntimeException)
{
    return
        rServiceName.equalsAsciiL(
            "com.sun.star.document.ImportFilter",
            sizeof("com.sun.star.document.ImportFilter")-1 ) ||
        rServiceName.equalsAsciiL(
            "com.sun.star.xml.XMLImportFilter",
            sizeof("com.sun.star.xml.XMLImportFilter")-1);
}

uno::Sequence< OUString > SAL_CALL SvXMLImport::getSupportedServiceNames(  )
    throw(uno::RuntimeException)
{
    uno::Sequence<OUString> aSeq(2);
    OUString* pSeq = aSeq.getArray();
    aSeq[0] = OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.ImportFilter"));
    aSeq[1] = OUString(
        RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLImportFilter"));
    return aSeq;
}

///////////////////////////////////////////////////////////////////////

XMLTextImportHelper* SvXMLImport::CreateTextImport()
{
    return new XMLTextImportHelper( xModel, *this );
}

XMLShapeImportHelper* SvXMLImport::CreateShapeImport()
{
    return new XMLShapeImportHelper( *this, xModel );
}

#ifndef SVX_LIGHT
SchXMLImportHelper* SvXMLImport::CreateChartImport()
{
    return new SchXMLImportHelper();
}
#endif

#ifndef SVX_LIGHT
#if SUPD>615 || defined(PRIV_DEBUG)
::xmloff::OFormLayerXMLImport* SvXMLImport::CreateFormImport()
{
    return new ::xmloff::OFormLayerXMLImport(*this);
}
#endif
#endif // #ifndef SVX_LIGHT


///////////////////////////////////////////////////////////////////////////////
//
// Get or create fill/line/lineend-style-helper
//

const Reference< container::XNameContainer > & SvXMLImport::GetGradientHelper()
{
    if( !xGradientHelper.is() )
    {
        if( xModel.is() )
        {
            Reference< lang::XMultiServiceFactory > xServiceFact( xModel, UNO_QUERY);
            if( xServiceFact.is() )
            {
                try
                {
                    xGradientHelper =  Reference< container::XNameContainer >( xServiceFact->createInstance(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GradientTable" ) ) ), UNO_QUERY);
                }
                catch( lang::ServiceNotRegisteredException& )
                {}
            }
        }
    }

    return xGradientHelper;
}

const Reference< container::XNameContainer > & SvXMLImport::GetHatchHelper()
{
    if( !xHatchHelper.is() )
    {
        if( xModel.is() )
        {
            Reference< lang::XMultiServiceFactory > xServiceFact( xModel, UNO_QUERY);
            if( xServiceFact.is() )
            {
                try
                {
                    xHatchHelper =  Reference< container::XNameContainer >( xServiceFact->createInstance(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.HatchTable" ) ) ), UNO_QUERY);
                }
                catch( lang::ServiceNotRegisteredException& )
                {}
            }
        }
    }

    return xHatchHelper;
}

const Reference< container::XNameContainer > & SvXMLImport::GetBitmapHelper()
{
    if( !xBitmapHelper.is() )
    {
        if( xModel.is() )
        {
            Reference< lang::XMultiServiceFactory > xServiceFact( xModel, UNO_QUERY);
            if( xServiceFact.is() )
            {
                try
                {
                    xBitmapHelper =  Reference< container::XNameContainer >( xServiceFact->createInstance(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.BitmapTable" ) ) ), UNO_QUERY);
                }
                catch( lang::ServiceNotRegisteredException& )
                {}
            }
        }
    }

    return xBitmapHelper;
}

const Reference< container::XNameContainer > & SvXMLImport::GetTransGradientHelper()
{
    if( !xTransGradientHelper.is() )
    {
        if( xModel.is() )
        {
            Reference< lang::XMultiServiceFactory > xServiceFact( xModel, UNO_QUERY);
            if( xServiceFact.is() )
            {
                try
                {
                    xTransGradientHelper =  Reference< container::XNameContainer >( xServiceFact->createInstance(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.TransparencyGradientTable" ) ) ), UNO_QUERY);
                }
                catch( lang::ServiceNotRegisteredException& )
                {}
            }
        }
    }

    return xTransGradientHelper;
}

const Reference< container::XNameContainer > & SvXMLImport::GetMarkerHelper()
{
    if( !xMarkerHelper.is() )
    {
        if( xModel.is() )
        {
            Reference< lang::XMultiServiceFactory > xServiceFact( xModel, UNO_QUERY);
            if( xServiceFact.is() )
            {
                try
                {
                    xMarkerHelper =  Reference< container::XNameContainer >( xServiceFact->createInstance(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.MarkerTable" ) ) ), UNO_QUERY);
                }
                catch( lang::ServiceNotRegisteredException& )
                {}
            }
        }
    }

    return xMarkerHelper;
}

const Reference< container::XNameContainer > & SvXMLImport::GetDashHelper()
{
    if( !xDashHelper.is() )
    {
        if( xModel.is() )
        {
            Reference< lang::XMultiServiceFactory > xServiceFact( xModel, UNO_QUERY);
            if( xServiceFact.is() )
            {
                try
                {
                    xDashHelper =  Reference< container::XNameContainer >( xServiceFact->createInstance(
                        OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DashTable" ) ) ), UNO_QUERY);
                }
                catch( lang::ServiceNotRegisteredException& )
                {}
            }
        }
    }

    return xDashHelper;
}

sal_Bool SvXMLImport::IsPackageURL( const ::rtl::OUString& rURL ) const
{

    // if, and only if, only parts are imported, then we're in a package
    const sal_uInt32 nTest = IMPORT_META|IMPORT_STYLES|IMPORT_CONTENT|IMPORT_SETTINGS;
    if( (mnImportFlags & nTest) == nTest )
        return sal_False;

    // Some quick tests: Some may rely on the package structure!
    sal_Int32 nLen = rURL.getLength();
    if( (nLen > 0 && '/' == rURL[0]) )
        // RFC2396 net_path or abs_path
        return sal_False;
    else if( nLen > 1 && '.' == rURL[0] )
    {
        if( '.' == rURL[1] )
            // ../: We are never going up one level, so we know
            // it's not an external URI
            return sal_False;
        else if( '/' == rURL[1] )
            // we are remaining on a level, so it's an package URI
            return sal_True;
    }

    // Now check for a RFC2396 schema
    sal_Int32 nPos = 1;
    while( nPos < nLen )
    {
        switch( rURL[nPos] )
        {
        case '/':
            // a relative path segement
            return sal_True;
        case ':':
            // a schema
            return sal_False;
        default:
            break;
            // we don't care about any other characters
        }
        ++nPos;
    }

    return sal_True;
}

::rtl::OUString SvXMLImport::ResolveGraphicObjectURL( const ::rtl::OUString& rURL,
                                                      sal_Bool bLoadOnDemand )
{
    ::rtl::OUString sRet;

    if( IsPackageURL( rURL ) )
    {
        if( !bLoadOnDemand && xGraphicResolver.is() )
        {
            ::rtl::OUString     aTmp( sPackageProtocol );
            aTmp += rURL;
            sRet = xGraphicResolver->resolveGraphicObjectURL( aTmp );
        }

        if( !sRet.getLength() )
        {
            sRet = sPackageProtocol;
            sRet += rURL;
        }
    }

    if( !sRet.getLength() )
        sRet = GetAbsoluteReference( rURL );

    return sRet;
}

Reference< XOutputStream > SvXMLImport::GetStreamForGraphicObjectURLFromBase64()
{
    Reference< XOutputStream > xOStm;
    Reference< document::XBinaryStreamResolver > xStmResolver( xGraphicResolver, UNO_QUERY );

    if( xStmResolver.is() )
        xOStm = xStmResolver->createOutputStream();

    return xOStm;
}

::rtl::OUString SvXMLImport::ResolveGraphicObjectURLFromBase64(
                                 const Reference < XOutputStream >& rOut )
{
    OUString sURL;
    Reference< document::XBinaryStreamResolver > xStmResolver( xGraphicResolver, UNO_QUERY );
    if( xStmResolver.is() )
        sURL = xStmResolver->resolveOutputStream( rOut );

    return sURL;
}

::rtl::OUString SvXMLImport::ResolveEmbeddedObjectURL(
                                    const ::rtl::OUString& rURL,
                                    const ::rtl::OUString& rClassId )
{
    ::rtl::OUString sRet;

    if( IsPackageURL( rURL ) )
    {
        if ( xEmbeddedResolver.is() )
        {
            OUString sURL( rURL );
            if( rClassId.getLength() )
            {
                sURL += OUString( sal_Unicode('!') );
                sURL += rClassId;
            }
            sRet = xEmbeddedResolver->resolveEmbeddedObjectURL( sURL );
        }
    }
    else
        sRet = GetAbsoluteReference( rURL );

    return sRet;
}

Reference < XOutputStream >
        SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64()
{
    Reference < XOutputStream > xOLEStream;

    if( xEmbeddedResolver.is() )
    {
        Reference< XNameAccess > xNA( xEmbeddedResolver, UNO_QUERY );
        if( xNA.is() )
        {
            OUString aURL( RTL_CONSTASCII_USTRINGPARAM( "Obj12345678" ) );
            Any aAny = xNA->getByName( aURL );
            aAny >>= xOLEStream;
        }
    }

    return xOLEStream;
}

::rtl::OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
{
    ::rtl::OUString sRet;

    if( xEmbeddedResolver.is() )
    {
        OUString aURL( RTL_CONSTASCII_USTRINGPARAM( "Obj12345678" ) );
        sRet = xEmbeddedResolver->resolveEmbeddedObjectURL( aURL );
    }

    return sRet;
}

void SvXMLImport::AddStyleDisplayName( sal_uInt16 nFamily,
                                       const OUString& rName,
                                       const OUString& rDisplayName )
{
    if( !pStyleMap )
    {
        pStyleMap = new StyleMap;
        pStyleMap->acquire();
        if( xImportInfo.is() )
        {
            OUString sPrivateData(
                    RTL_CONSTASCII_USTRINGPARAM("PrivateData" ) );
            Reference< beans::XPropertySetInfo > xPropertySetInfo =
                xImportInfo->getPropertySetInfo();
            if( xPropertySetInfo.is() &&
                xPropertySetInfo->hasPropertyByName(sPrivateData) )
            {
                Reference < XInterface > xIfc(
                        static_cast< XUnoTunnel *>( pStyleMap ) );
                Any aAny;
                aAny <<= xIfc;
                xImportInfo->setPropertyValue( sPrivateData, aAny );
            }
        }
    }

    StyleMap::key_type aKey( nFamily, rName );
    StyleMap::value_type aValue( aKey, rDisplayName );
    ::std::pair<StyleMap::iterator,bool> aRes( pStyleMap->insert( aValue ) );
    OSL_ENSURE( aRes.second, "duplicate style name" );

}

OUString SvXMLImport::GetStyleDisplayName( sal_uInt16 nFamily,
                                           const OUString& rName )
{
    OUString sName( rName );
    if( pStyleMap && rName.getLength() )
    {
        StyleMap::key_type aKey( nFamily, rName );
        StyleMap::const_iterator aIter = pStyleMap->find( aKey );
        if( aIter != pStyleMap->end() )
            sName = (*aIter).second;
    }
    return sName;
}

void SvXMLImport::SetViewSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aViewProps)
{
}

void SvXMLImport::SetConfigurationSettings(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& aConfigProps)
{
}

ProgressBarHelper*  SvXMLImport::GetProgressBarHelper()
{
    if (!pProgressBarHelper)
    {
        pProgressBarHelper = new ProgressBarHelper(mxStatusIndicator, sal_False);

        if (pProgressBarHelper && xImportInfo.is())
        {
            uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
            if (xPropertySetInfo.is())
            {
                OUString sProgressRange(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSRANGE));
                OUString sProgressMax(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSMAX));
                OUString sProgressCurrent(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSCURRENT));
                OUString sRepeat(RTL_CONSTASCII_USTRINGPARAM(XML_PROGRESSREPEAT));
                if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
                    xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
                    xPropertySetInfo->hasPropertyByName(sProgressRange))
                {
                    uno::Any aAny;
                    sal_Int32 nProgressMax(0);
                    sal_Int32 nProgressCurrent(0);
                    sal_Int32 nProgressRange(0);
                    aAny = xImportInfo->getPropertyValue(sProgressRange);
                    if (aAny >>= nProgressRange)
                        pProgressBarHelper->SetRange(nProgressRange);
                    aAny = xImportInfo->getPropertyValue(sProgressMax);
                    if (aAny >>= nProgressMax)
                        pProgressBarHelper->SetReference(nProgressMax);
                    aAny = xImportInfo->getPropertyValue(sProgressCurrent);
                    if (aAny >>= nProgressCurrent)
                        pProgressBarHelper->SetValue(nProgressCurrent);
                }
                if (xPropertySetInfo->hasPropertyByName(sRepeat))
                {
                    uno::Any aAny = xImportInfo->getPropertyValue(sRepeat);
                    if (aAny.getValueType() == getBooleanCppuType())
                        pProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
                    else
                        DBG_ERRORFILE("why is it no boolean?");
                }
            }
        }
    }
    return pProgressBarHelper;
}

void SvXMLImport::AddNumberStyle(sal_Int32 nKey, const OUString& rName)
{
    if (!xNumberStyles.is())
        xNumberStyles = uno::Reference< container::XNameContainer >( comphelper::NameContainer_createInstance( ::getCppuType((const sal_Int32*)0)) );
    if (xNumberStyles.is())
    {
        uno::Any aAny;
        aAny <<= nKey;
        try
        {
            xNumberStyles->insertByName(rName, aAny);
        }
        catch ( uno::Exception& )
        {
            DBG_ERROR("Numberformat could not be inserted");
        }
    }
    else
        DBG_ERROR("not possible to create NameContainer");
}

XMLEventImportHelper& SvXMLImport::GetEventImport()
{
#ifndef SVX_LIGHT
    if (!pEventImportHelper)
    {
        // construct event helper and register StarBasic handler and standard
        // event tables
        pEventImportHelper = new XMLEventImportHelper();
        OUString sStarBasic(GetXMLToken(XML_STARBASIC));
        pEventImportHelper->RegisterFactory(sStarBasic,
                                            new XMLStarBasicContextFactory());
        OUString sScript(GetXMLToken(XML_SCRIPT));
        pEventImportHelper->RegisterFactory(sScript,
                                            new XMLScriptContextFactory());
        pEventImportHelper->AddTranslationTable(aStandardEventTable);

        // register StarBasic event handler with capitalized spelling
        OUString sStarBasicCap(RTL_CONSTASCII_USTRINGPARAM("StarBasic"));
        pEventImportHelper->RegisterFactory(sStarBasicCap,
                                            new XMLStarBasicContextFactory());
    }
#endif

    return *pEventImportHelper;
}

void SvXMLImport::SetFontDecls( XMLFontStylesContext *pFontDecls )
{
    xFontDecls = pFontDecls;
    GetTextImport()->SetFontDecls( pFontDecls );
}

void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
{
    xStyles = pStyles;
}

void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
{
    if (pAutoStyles && xNumberStyles.is() && (mnImportFlags & IMPORT_CONTENT) )
    {
        uno::Reference<xml::sax::XAttributeList> xAttrList;
        uno::Sequence< ::rtl::OUString > aNames = xNumberStyles->getElementNames();
        sal_uInt32 nCount(aNames.getLength());
        if (nCount)
        {
            const OUString* pNames = aNames.getConstArray();
            if ( pNames )
            {
                SvXMLStyleContext* pContext;
                uno::Any aAny;
                sal_Int32 nKey(0);
                for (sal_uInt32 i = 0; i < nCount; i++, pNames++)
                {
                    aAny = xNumberStyles->getByName(*pNames);
                    if (aAny >>= nKey)
                    {
                        pContext = new SvXMLNumFormatContext( *this, XML_NAMESPACE_NUMBER,
                                    *pNames, xAttrList, nKey, *pAutoStyles );
                        pAutoStyles->AddStyle(*pContext);
                    }
                }
            }
        }
    }
    xAutoStyles = pAutoStyles;
    GetTextImport()->SetAutoStyles( pAutoStyles );
    GetShapeImport()->SetAutoStylesContext( pAutoStyles );
#ifndef SVX_LIGHT
    GetChartImport()->SetAutoStylesContext( pAutoStyles );
    GetFormImport()->setAutoStyleContext( pAutoStyles );
#endif
}

void SvXMLImport::SetMasterStyles( SvXMLStylesContext *pMasterStyles )
{
    xMasterStyles = pMasterStyles;
}

XMLFontStylesContext *SvXMLImport::GetFontDecls()
{
    return (XMLFontStylesContext *)&xFontDecls;
}

SvXMLStylesContext *SvXMLImport::GetStyles()
{
    return (SvXMLStylesContext *)&xStyles;
}

SvXMLStylesContext *SvXMLImport::GetAutoStyles()
{
    return (SvXMLStylesContext *)&xAutoStyles;
}

SvXMLStylesContext *SvXMLImport::GetMasterStyles()
{
    return (SvXMLStylesContext *)&xMasterStyles;
}

const XMLFontStylesContext *SvXMLImport::GetFontDecls() const
{
    return (const XMLFontStylesContext *)&xFontDecls;
}

const SvXMLStylesContext *SvXMLImport::GetStyles() const
{
    return (const SvXMLStylesContext *)&xStyles;
}

const SvXMLStylesContext *SvXMLImport::GetAutoStyles() const
{
    return (const SvXMLStylesContext *)&xAutoStyles;
}

const SvXMLStylesContext *SvXMLImport::GetMasterStyles() const
{
    return (const SvXMLStylesContext *)&xMasterStyles;
}

OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue)
{
    if( rValue.getLength() == 0 || rValue[0] == '#' )
        return rValue;

    INetURLObject aAbsURL;
    if( pImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
        return aAbsURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
    else
        return rValue;
}

void SvXMLImport::_CreateNumberFormatsSupplier()
{
    DBG_ASSERT( !xNumberFormatsSupplier.is(),
                "number formats supplier already exists!" );
    if(xModel.is())
        xNumberFormatsSupplier =
            uno::Reference< util::XNumberFormatsSupplier> (xModel, uno::UNO_QUERY);
}


void SvXMLImport::_CreateDataStylesImport()
{
    DBG_ASSERT( pNumImport == NULL, "data styles import already exists!" );
    uno::Reference<util::XNumberFormatsSupplier> xNum =
        GetNumberFormatsSupplier();
    if ( xNum.is() )
        pNumImport = new SvXMLNumFmtHelper(xNum, getServiceFactory());
}


#ifdef CONV_STAR_FONTS
sal_Unicode SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c )
{
    sal_Unicode cNew = c;
    if( !pImpl->hBatsFontConv )
    {
        OUString sStarBats( RTL_CONSTASCII_USTRINGPARAM( "StarBats" ) );
        pImpl->hBatsFontConv = CreateFontToSubsFontConverter( sStarBats,
                 FONTTOSUBSFONT_IMPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
        OSL_ENSURE( pImpl->hBatsFontConv, "Got no symbol font converter" );
    }
    if( pImpl->hBatsFontConv )
    {
        cNew = ConvertFontToSubsFontChar( pImpl->hBatsFontConv, c );
    }

    return cNew;
}

sal_Unicode SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c )
{
    sal_Unicode cNew = c;
    if( !pImpl->hMathFontConv )
    {
        OUString sStarMath( RTL_CONSTASCII_USTRINGPARAM( "StarMath" ) );
        pImpl->hMathFontConv = CreateFontToSubsFontConverter( sStarMath,
                 FONTTOSUBSFONT_IMPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
        OSL_ENSURE( pImpl->hMathFontConv, "Got no symbol font converter" );
    }
    if( pImpl->hMathFontConv )
    {
        cNew = ConvertFontToSubsFontChar( pImpl->hMathFontConv, c );
    }

    return cNew;
}
#endif



void SvXMLImport::SetError(
    sal_Int32 nId,
    const Sequence<OUString>& rMsgParams,
    const OUString& rExceptionMessage,
    const Reference<xml::sax::XLocator>& rLocator )
{
    // maintain error flags
    if ( ( nId & XMLERROR_FLAG_ERROR ) != 0 )
        mnErrorFlags |= ERROR_ERROR_OCCURED;
    if ( ( nId & XMLERROR_FLAG_WARNING ) != 0 )
        mnErrorFlags |= ERROR_WARNING_OCCURED;
    if ( ( nId & XMLERROR_FLAG_SEVERE ) != 0 )
        mnErrorFlags |= ERROR_DO_NOTHING;

    // create error list on demand
    if ( pXMLErrors == NULL )
        pXMLErrors = new XMLErrors();

    // save error information
    // use document locator (if none supplied)
    pXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage,
                           rLocator.is() ? rLocator : xLocator );
}

void SvXMLImport::SetError(
    sal_Int32 nId,
    const Sequence<OUString>& rMsgParams)
{
    OUString sEmpty;
    SetError( nId, rMsgParams, sEmpty, NULL );
}

void SvXMLImport::SetError(
    sal_Int32 nId)
{
    Sequence<OUString> aSeq(0);
    SetError( nId, aSeq );
}

void SvXMLImport::SetError(
    sal_Int32 nId,
    const OUString& rMsg1)
{
    Sequence<OUString> aSeq(1);
    OUString* pSeq = aSeq.getArray();
    pSeq[0] = rMsg1;
    SetError( nId, aSeq );
}

void SvXMLImport::SetError(
    sal_Int32 nId,
    const OUString& rMsg1,
    const OUString& rMsg2)
{
    Sequence<OUString> aSeq(2);
    OUString* pSeq = aSeq.getArray();
    pSeq[0] = rMsg1;
    pSeq[1] = rMsg2;
    SetError( nId, aSeq );
}

void SvXMLImport::SetError(
    sal_Int32 nId,
    const OUString& rMsg1,
    const OUString& rMsg2,
    const OUString& rMsg3)
{
    Sequence<OUString> aSeq(3);
    OUString* pSeq = aSeq.getArray();
    pSeq[0] = rMsg1;
    pSeq[1] = rMsg2;
    pSeq[2] = rMsg3;
    SetError( nId, aSeq );
}

void SvXMLImport::SetError(
    sal_Int32 nId,
    const OUString& rMsg1,
    const OUString& rMsg2,
    const OUString& rMsg3,
    const OUString& rMsg4)
{
    Sequence<OUString> aSeq(4);
    OUString* pSeq = aSeq.getArray();
    pSeq[0] = rMsg1;
    pSeq[1] = rMsg2;
    pSeq[2] = rMsg3;
    pSeq[3] = rMsg4;
    SetError( nId, aSeq );
}

XMLErrors* SvXMLImport::GetErrors()
{
    return pXMLErrors;
}

void SvXMLImport::DisposingModel()
{
    if( xFontDecls.Is() )
        ((SvXMLStylesContext *)&xFontDecls)->Clear();
    if( xStyles.Is() )
        ((SvXMLStylesContext *)&xStyles)->Clear();
    if( xAutoStyles.Is() )
        ((SvXMLStylesContext *)&xAutoStyles)->Clear();
    if( xMasterStyles.Is() )
        ((SvXMLStylesContext *)&xMasterStyles)->Clear();

    xModel.set(0);
    xEventListener.set(NULL);
}

::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLImport::getInterfaceToIdentifierMapper()
{
    return pImpl->maInterfaceToIdentifierMapper;
}

::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > SvXMLImport::getServiceFactory()
{
    // #110680#
    return mxServiceFactory;
}
String SvXMLImport::GetBaseURL() const
{
    return pImpl->aBaseURL.GetMainURL( INetURLObject::NO_DECODE );
}

String SvXMLImport::GetDocumentBase() const
{
    return pImpl->aDocBase.GetMainURL( INetURLObject::NO_DECODE );
}

// --> OD 2004-08-10 #i28749#
sal_Bool SvXMLImport::IsShapePositionInHoriL2R() const
{
    return pImpl->mbShapePositionInHoriL2R;
}
// <--

void SvXMLImport::initXForms()
{
    // dummy method; to be implemented by derived classes supporting XForms
}

bool SvXMLImport::getBuildIds( sal_Int32& rMaster, sal_Int32& rMinor) const
{
    bool bRet = false;
    if( xImportInfo.is() ) try
    {
        const OUString aPropName(RTL_CONSTASCII_USTRINGPARAM("BuildId"));
        Reference< XPropertySetInfo > xSetInfo( xImportInfo->getPropertySetInfo() );
        if( xSetInfo.is() && xSetInfo->hasPropertyByName( aPropName ) )
        {
            OUString aBuildId;
            xImportInfo->getPropertyValue( aPropName ) >>= aBuildId;
            if( aBuildId.getLength() )
            {
                sal_Int32 nIndex = aBuildId.indexOf('m');
                if( nIndex != -1 )
                {
                    rMaster = aBuildId.copy( 0, nIndex ).toInt32();
                    rMinor = aBuildId.copy( nIndex+1 ).toInt32();
                    bRet = true;
                }
            }
        }
    }
    catch( Exception& e )
    {
    }
    return bRet;
}

