/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbmm.hxx"

#include "dbmm_global.hrc"
#include "dbmm_module.hxx"
#include "dbmm_types.hxx"
#include "docinteraction.hxx"
#include "migrationengine.hxx"
#include "migrationerror.hxx"
#include "migrationprogress.hxx"
#include "migrationlog.hxx"
#include "progresscapture.hxx"
#include "progressmixer.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/embed/XComponentSupplier.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/embed/XEmbedPersist.hpp>
#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/uri/UriReferenceFactory.hpp>
#include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
#include <com/sun/star/form/XFormsSupplier.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/script/XEventAttacherManager.hpp>
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
#include <com/sun/star/io/WrongFormatException.hpp>
#include <com/sun/star/script/XScriptEventsSupplier.hpp>
#include <com/sun/star/io/XInputStreamProvider.hpp>
/** === end UNO includes === **/

#include <comphelper/documentinfo.hxx>
#include <comphelper/interaction.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/string.hxx>
#include <comphelper/types.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <tools/string.hxx>
#include <tools/diagnose_ex.h>
#include <rtl/ustrbuf.hxx>
#include <rtl/ref.hxx>
#include <unotools/sharedunocomponent.hxx>
#include <xmlscript/xmldlg_imexp.hxx>

#include <vector>
#include <set>

#define DEFAULT_DOC_PROGRESS_RANGE  100000

//........................................................................
namespace dbmm
{
//........................................................................

	/** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::sdb::XOfficeDatabaseDocument;
    using ::com::sun::star::sdb::XFormDocumentsSupplier;
    using ::com::sun::star::sdb::XReportDocumentsSupplier;
    using ::com::sun::star::container::XNameAccess;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::util::XCloseable;
    using ::com::sun::star::util::CloseVetoException;
    using ::com::sun::star::lang::XComponent;
    using ::com::sun::star::frame::XModel;
    using ::com::sun::star::frame::XComponentLoader;
    using ::com::sun::star::ucb::XCommandProcessor;
    using ::com::sun::star::ucb::XContent;
    using ::com::sun::star::ucb::Command;
    using ::com::sun::star::embed::XComponentSupplier;
    using ::com::sun::star::task::XStatusIndicator;
    using ::com::sun::star::embed::XStorage;
    using ::com::sun::star::document::XStorageBasedDocument;
    using ::com::sun::star::embed::XTransactedObject;
    using ::com::sun::star::frame::XStorable;
    using ::com::sun::star::embed::XEmbedPersist;
    using ::com::sun::star::script::DocumentDialogLibraryContainer;
    using ::com::sun::star::script::DocumentScriptLibraryContainer;
    using ::com::sun::star::script::XStorageBasedLibraryContainer;
    using ::com::sun::star::document::XEmbeddedScripts;
    using ::com::sun::star::container::XNameContainer;
    using ::com::sun::star::document::XEventsSupplier;
    using ::com::sun::star::container::XNameReplace;
    using com::sun::star::uri::UriReferenceFactory;
    using com::sun::star::uri::XUriReferenceFactory;
    using com::sun::star::uri::XVndSunStarScriptUrlReference;
    using ::com::sun::star::form::XFormsSupplier;
    using ::com::sun::star::drawing::XDrawPageSupplier;
    using ::com::sun::star::drawing::XDrawPagesSupplier;
    using ::com::sun::star::drawing::XDrawPage;
    using ::com::sun::star::drawing::XDrawPages;
    using ::com::sun::star::container::XIndexAccess;
    using ::com::sun::star::script::XEventAttacherManager;
    using ::com::sun::star::script::ScriptEventDescriptor;
    using ::com::sun::star::script::XLibraryContainerPassword;
    using ::com::sun::star::io::WrongFormatException;
    using ::com::sun::star::script::XScriptEventsSupplier;
    using ::com::sun::star::io::XInputStreamProvider;
    using ::com::sun::star::io::XInputStream;
    /** === end UNO using === **/
    namespace ElementModes = ::com::sun::star::embed::ElementModes;

// migration phases whose progresses are to be mixed into one progress
#define PHASE_JAVASCRIPT    1
#define PHASE_BEANSHELL     2
#define PHASE_PYTHON        3
#define PHASE_JAVA          4
#define PHASE_BASIC         5
#define PHASE_DIALOGS       6

    //====================================================================
    //= SubDocument
    //====================================================================
    struct SubDocument
    {
        Reference< XCommandProcessor >  xCommandProcessor;
        Reference< XModel >             xDocument;          // valid only temporarily
        ::rtl::OUString                 sHierarchicalName;
        SubDocumentType                 eType;
        size_t                          nNumber;

        SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName,
                const SubDocumentType _eType, const size_t _nNumber )
            :xCommandProcessor( _rxCommandProcessor )
            ,xDocument()
            ,sHierarchicalName( _rName )
            ,eType( _eType )
            ,nNumber( _nNumber )
        {
        }
    };

    typedef ::std::vector< SubDocument >    SubDocuments;

    //====================================================================
	//= helper
	//====================================================================
    //--------------------------------------------------------------------
    typedef ::utl::SharedUNOComponent< XStorage >   SharedStorage;

    namespace
    {
	    //----------------------------------------------------------------
        static const ::rtl::OUString& lcl_getScriptsStorageName()
        {
            static const ::rtl::OUString s_sScriptsStorageName( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) );
            return s_sScriptsStorageName;
        }

	    //----------------------------------------------------------------
        static const ::rtl::OUString& lcl_getScriptsSubStorageName( const ScriptType _eType )
        {
            static const ::rtl::OUString s_sBeanShell ( RTL_CONSTASCII_USTRINGPARAM( "beanshell" ) );
            static const ::rtl::OUString s_sJavaScript( RTL_CONSTASCII_USTRINGPARAM( "javascript" ) );
            static const ::rtl::OUString s_sPython    ( RTL_CONSTASCII_USTRINGPARAM( "python" ) );      // TODO: is this correct?
            static const ::rtl::OUString s_sJava      ( RTL_CONSTASCII_USTRINGPARAM( "java" ) );

            switch ( _eType )
            {
            case eBeanShell:    return s_sBeanShell;
            case eJavaScript:   return s_sJavaScript;
            case ePython:       return s_sPython;
            case eJava:         return s_sJava;
            default:
                break;
            }

            OSL_ENSURE( false, "lcl_getScriptsSubStorageName: illegal type!" );
            static ::rtl::OUString s_sEmpty;
            return s_sEmpty;
        }

	    //----------------------------------------------------------------
        static bool lcl_getScriptTypeFromLanguage( const ::rtl::OUString& _rLanguage, ScriptType& _out_rScriptType )
        {
            struct LanguageMapping
            {
                const sal_Char*     pAsciiLanguage;
                const ScriptType    eScriptType;

                LanguageMapping( const sal_Char* _pAsciiLanguage, const ScriptType _eScriptType )
                    :pAsciiLanguage( _pAsciiLanguage )
                    ,eScriptType( _eScriptType )
                {
                }
            }
            aLanguageMapping[] =
            {
                LanguageMapping( "JavaScript", eJavaScript ),
                LanguageMapping( "BeanShell",  eBeanShell ),
                LanguageMapping( "Java",       eJava ),
                LanguageMapping( "Python",     ePython ),          // TODO: is this correct?
                LanguageMapping( "Basic",      eBasic )
            };
            for ( size_t i=0; i < sizeof( aLanguageMapping ) / sizeof( aLanguageMapping[0] ); ++i )
            {
                if ( _rLanguage.equalsAscii( aLanguageMapping[i].pAsciiLanguage ) )
                {
                    _out_rScriptType = aLanguageMapping[i].eScriptType;
                    return true;
                }
            }
            OSL_ENSURE( false, "lcl_getScriptTypeFromLanguage: unknown language!" );
            return false;
        }

        //----------------------------------------------------------------
        ::rtl::OUString lcl_getSubDocumentDescription( const SubDocument& _rDocument )
        {
            ::rtl::OUString sObjectName = String( MacroMigrationResId( _rDocument.eType == eForm ? STR_FORM : STR_REPORT ) );
            ::comphelper::string::searchAndReplaceAsciiI( sObjectName, "$name$", _rDocument.sHierarchicalName );
            return sObjectName;
        }

        //----------------------------------------------------------------
        static Any lcl_executeCommand_throw( const Reference< XCommandProcessor >& _rxCommandProc,
            const sal_Char* _pAsciiCommand )
        {
            OSL_PRECOND( _rxCommandProc.is(), "lcl_executeCommand_throw: illegal object!" );
            if ( !_rxCommandProc.is() )
                return Any();

            Command aCommand;
            aCommand.Name = ::rtl::OUString::createFromAscii( _pAsciiCommand );
            return _rxCommandProc->execute(
                aCommand, _rxCommandProc->createCommandIdentifier(), NULL );
        }

        //----------------------------------------------------------------
        ::rtl::OUString lcl_getMimeType_nothrow( const Reference< XCommandProcessor >& _rxContent )
        {
            ::rtl::OUString sMimeType;
            try
            {
                Reference< XContent > xContent( _rxContent, UNO_QUERY_THROW );
                sMimeType = xContent->getContentType();
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
            return sMimeType;
        }

        //----------------------------------------------------------------
        enum OpenDocResult
        {
            eOpenedDoc,
            eIgnoreDoc,
            eFailure
        };

        //----------------------------------------------------------------
        static OpenDocResult lcl_loadSubDocument_nothrow( SubDocument& _rDocument,
            const Reference< XStatusIndicator >& _rxProgress, MigrationLog& _rLogger )
        {
            OSL_PRECOND( !_rDocument.xDocument.is(), "lcl_loadSubDocument_nothrow: already loaded!" );

            try
            {
                ::comphelper::NamedValueCollection aLoadArgs;
                aLoadArgs.put( "Hidden", (sal_Bool)sal_True );
                aLoadArgs.put( "StatusIndicator", _rxProgress );

                Reference< XCommandProcessor > xCommandProcessor( _rDocument.xCommandProcessor, UNO_SET_THROW );
                Command aCommand;
                aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
                aCommand.Argument <<= aLoadArgs.getPropertyValues();
                Reference< XComponent > xDocComponent(
                    xCommandProcessor->execute(
                        aCommand, xCommandProcessor->createCommandIdentifier(), NULL
                    ),
                    UNO_QUERY
                );
                OSL_ENSURE( xDocComponent.is(), "lcl_loadSubDocument_nothrow: no component loaded!" );

                _rDocument.xDocument.set( xDocComponent, UNO_QUERY_THROW );
            }
            catch( const Exception& )
            {
                Any aError( ::cppu::getCaughtException() );

                bool bCausedByNewStyleReport =
                        ( _rDocument.eType == eReport )
                    &&  ( aError.isExtractableTo( ::cppu::UnoType< WrongFormatException >::get() ) )
                    &&  ( lcl_getMimeType_nothrow( _rDocument.xCommandProcessor ).equalsAscii( "application/vnd.sun.xml.report" ) );

                if ( bCausedByNewStyleReport )
                {
                    _rLogger.logRecoverable( MigrationError(
                        ERR_NEW_STYLE_REPORT,
                        lcl_getSubDocumentDescription( _rDocument )
                    ) );
                    return eIgnoreDoc;
                }
                else
                {
                    _rLogger.logFailure( MigrationError(
                        ERR_OPENING_SUB_DOCUMENT_FAILED,
                        lcl_getSubDocumentDescription( _rDocument ),
                        aError
                    ) );
                }
            }
            return _rDocument.xDocument.is() ? eOpenedDoc : eFailure;
        }

	    //----------------------------------------------------------------
        static bool lcl_unloadSubDocument_nothrow( SubDocument& _rDocument, MigrationLog& _rLogger )
        {
            bool bSuccess = false;
            Any aException;
            try
            {
                OSL_VERIFY( lcl_executeCommand_throw( _rDocument.xCommandProcessor, "close" ) >>= bSuccess );
            }
            catch( const Exception& )
            {
                aException = ::cppu::getCaughtException();
            }

            // log the failure, if any
            if ( !bSuccess )
            {
                _rLogger.logFailure( MigrationError(
                    ERR_CLOSING_SUB_DOCUMENT_FAILED,
                    lcl_getSubDocumentDescription( _rDocument ),
                    aException
                ) );
            }

            _rDocument.xDocument.clear();
            return bSuccess;
        }

        //----------------------------------------------------------------
        bool lcl_commitStorage_nothrow( const Reference< XStorage >& _rxStorage )
        {
            try
            {
                Reference< XTransactedObject > xTrans( _rxStorage, UNO_QUERY_THROW );
                xTrans->commit();
            }
            catch( const Exception& )
            {
            	return false;
            }
            return true;
        }

        //----------------------------------------------------------------
        bool lcl_commitDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
        {
            bool bSuccess = false;
            Any aException;
            try
            {
                Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
                Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
                bSuccess = lcl_commitStorage_nothrow( xDocStorage );
            }
            catch( const Exception& )
            {
                aException = ::cppu::getCaughtException();
            }

            // log the failure, if any
            if ( !bSuccess )
            {
                _rLogger.logFailure( MigrationError(
                    ERR_STORAGE_COMMIT_FAILED,
                    ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
                    aException
                ) );
            }
        	return bSuccess;
        }

        //----------------------------------------------------------------
        bool lcl_storeDocument_nothrow( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
        {
            bool bSuccess = false;
            Any aException;
            try
            {
                Reference< XStorable > xStorable( _rxDocument, UNO_QUERY_THROW );
                xStorable->store();
                bSuccess = true;
            }
            catch( const Exception& )
            {
                aException = ::cppu::getCaughtException();
            }

            // log the failure, if any
            if ( !bSuccess )
            {
                _rLogger.logFailure( MigrationError(
                    ERR_STORING_DATABASEDOC_FAILED,
                    aException
                ) );
            }
        	return bSuccess;
        }

        //----------------------------------------------------------------
        bool lcl_storeEmbeddedDocument_nothrow( const SubDocument& _rDocument )
        {
            try
            {
                lcl_executeCommand_throw( _rDocument.xCommandProcessor, "store" );
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
                return false;
            }
            return true;
        }
    }

    //====================================================================
	//= DrawPageIterator
	//====================================================================
    class DrawPageIterator
    {
    public:
        DrawPageIterator( const Reference< XModel >& _rxDocument )
            :m_xDocument( _rxDocument )
            ,m_nPageCount( 0 )
            ,m_nCurrentPage( 0 )
        {
            Reference< XDrawPageSupplier > xSingle( _rxDocument, UNO_QUERY );
            Reference< XDrawPagesSupplier > xMulti( _rxDocument, UNO_QUERY );
            if ( xSingle.is() )
            {
                m_xSinglePage.set( xSingle->getDrawPage(), UNO_SET_THROW );
                m_nPageCount = 1;
            }
            else if ( xMulti.is() )
            {
                m_xMultiPages.set( xMulti->getDrawPages(), UNO_SET_THROW );
                m_nPageCount = m_xMultiPages->getCount();
            }
        }

        bool hasMore() const
        {
            return m_nCurrentPage < m_nPageCount;
        }

        Reference< XDrawPage > next()
        {
            Reference< XDrawPage > xNextPage;

            if ( m_xSinglePage.is() )
            {
                xNextPage = m_xSinglePage;
            }
            else if ( m_xMultiPages.is() )
            {
                xNextPage.set( m_xMultiPages->getByIndex( m_nCurrentPage ), UNO_QUERY_THROW );
            }
            ++m_nCurrentPage;
            return xNextPage;
        }

    private:
        const Reference< XModel >   m_xDocument;
        Reference< XDrawPage >      m_xSinglePage;
        Reference< XDrawPages >     m_xMultiPages;
        sal_Int32                   m_nPageCount;
        sal_Int32                   m_nCurrentPage;
    };

    //====================================================================
	//= FormComponentScripts
	//====================================================================
    class FormComponentScripts
    {
    public:
        FormComponentScripts(
                const Reference< XInterface >& _rxComponent,
                const Reference< XEventAttacherManager >& _rxManager,
                const sal_Int32 _nIndex
            )
            :m_xComponent( _rxComponent, UNO_SET_THROW )
            ,m_xManager( _rxManager, UNO_SET_THROW )
            ,m_nIndex( _nIndex )
        {
        }

        Sequence< ScriptEventDescriptor > getEvents() const
        {
            return m_xManager->getScriptEvents( m_nIndex );
        }

        void setEvents( const Sequence< ScriptEventDescriptor >& _rEvents  ) const
        {
            m_xManager->registerScriptEvents( m_nIndex, _rEvents );
        }

        const Reference< XInterface >& getComponent() const
        {
            return m_xComponent;
        }

    private:
        const Reference< XInterface >               m_xComponent;
        const Reference< XEventAttacherManager >    m_xManager;
        const sal_Int32                             m_nIndex;
    };

    //====================================================================
	//= FormComponentIterator
	//====================================================================
    class FormComponentIterator
    {
    public:
        FormComponentIterator( const Reference< XIndexAccess >& _rxContainer )
            :m_xContainer( _rxContainer, UNO_SET_THROW )
            ,m_xEventManager( _rxContainer, UNO_QUERY_THROW )
            ,m_nElementCount( _rxContainer->getCount() )
            ,m_nCurrentElement( 0 )
        {
        }

        bool hasMore() const
        {
            return m_nCurrentElement < m_nElementCount;
        }

        FormComponentScripts next()
        {
            FormComponentScripts aComponent(
                Reference< XInterface >( m_xContainer->getByIndex( m_nCurrentElement ), UNO_QUERY_THROW ),
                m_xEventManager,
                m_nCurrentElement
            );
            ++m_nCurrentElement;
            return aComponent;
        }

    private:
        const Reference< XIndexAccess >             m_xContainer;
        const Reference< XEventAttacherManager >    m_xEventManager;
        const sal_Int32                             m_nElementCount;
        sal_Int32                                   m_nCurrentElement;

    };

    //====================================================================
	//= ScriptsStorage - declaration
	//====================================================================
    /** a helper class which encapsulates access to the storages for Java/Script, BeanShell, and Python scripts,
        i.e. all script types which can be manipulated on storage level.
    */
    class ScriptsStorage
    {
    public:
        ScriptsStorage( MigrationLog& _rLogger );
        ScriptsStorage( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger );
        ~ScriptsStorage();

        /** determines whether the instance is valid, i.e. refers to a valid root storage
            for reading/storing scripts
        */
        inline bool isValid() const { return m_xScriptsStorage.is(); }

        /** binds the instance to a new document. Only to be called when the instance is not yet
            bound (i.e. isValid returns <FALSE/>).
        */
        void    bind( const Reference< XModel >& _rxDocument );

        /// determines whether scripts of the given type are present
        bool    hasScripts( const ScriptType _eType ) const;

        /// returns the root storage for the scripts of the given type
        SharedStorage
                getScriptsRoot( const ScriptType _eType ) const;

        /** returns the names of the elements in the "Scripts" storage
        */
        ::std::set< ::rtl::OUString >
                getElementNames() const;

        /** removes the sub storage for a given script type
            @precond
                the respective storage is empty
            @precond
                the ScriptsStorage instance was opened for writing
        */
        void    removeScriptTypeStorage( const ScriptType _eType ) const;

        /** commits the changes at our XStorage object
        */
        bool    commit();

        /** removes the "Scripts" sub storage from the given document's root storage
            @precond
                the "Scripts" storage is empty
        */
        static bool
                removeFromDocument( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger );

    private:
        MigrationLog&   m_rLogger;
        SharedStorage   m_xScriptsStorage;
    };

    //====================================================================
	//= ScriptsStorage - implementation
	//====================================================================
	//--------------------------------------------------------------------
    ScriptsStorage::ScriptsStorage( MigrationLog& _rLogger )
        :m_rLogger( _rLogger )
        ,m_xScriptsStorage()
    {
    }

	//--------------------------------------------------------------------
    ScriptsStorage::ScriptsStorage( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
        :m_rLogger( _rLogger )
        ,m_xScriptsStorage()
    {
        bind( _rxDocument );
    }

	//--------------------------------------------------------------------
    ScriptsStorage::~ScriptsStorage()
    {
    }

    //--------------------------------------------------------------------
    bool ScriptsStorage::commit()
    {
        return lcl_commitStorage_nothrow( m_xScriptsStorage );
    }

	//--------------------------------------------------------------------
    void ScriptsStorage::bind( const Reference< XModel >& _rxDocument )
    {
        OSL_PRECOND( !isValid(), "ScriptsStorage:bind: did not bother, yet, to check whether this is allowed!" );
        try
        {
            Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
            Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );

            // the the "Scripts" storage exist, or if it does not (yet) exist and we are in write mode
            // => open the storage
            if  (   (   xDocStorage->hasByName( lcl_getScriptsStorageName() )
                    &&  xDocStorage->isStorageElement( lcl_getScriptsStorageName() )
                    )
                ||  !xDocStorage->hasByName( lcl_getScriptsStorageName() )
                )
            {
                m_xScriptsStorage.set(
                    xDocStorage->openStorageElement(
                        lcl_getScriptsStorageName(), ElementModes::READWRITE
                    ),
                    UNO_QUERY_THROW
                );
            }
        }
        catch( const Exception& )
        {
            m_rLogger.logFailure( MigrationError(
                ERR_BIND_SCRIPT_STORAGE_FAILED,
                ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
                ::cppu::getCaughtException()
            ) );
        }
    }

    //--------------------------------------------------------------------
    bool ScriptsStorage::hasScripts( const ScriptType _eType ) const
    {
        OSL_PRECOND( isValid(), "ScriptsStorage::hasScripts: illegal call!" );
        if ( !isValid() )
            return false;

        const ::rtl::OUString& rSubStorageName( lcl_getScriptsSubStorageName( _eType ) );
        return  m_xScriptsStorage->hasByName( rSubStorageName )
            &&  m_xScriptsStorage->isStorageElement( rSubStorageName );
    }

    //--------------------------------------------------------------------
    SharedStorage ScriptsStorage::getScriptsRoot( const ScriptType _eType ) const
    {
        SharedStorage xStorage;
        if ( isValid() )
        {
            xStorage.reset( m_xScriptsStorage->openStorageElement(
                lcl_getScriptsSubStorageName( _eType ), ElementModes::READWRITE
            ) );
        }
        return xStorage;
    }

    //--------------------------------------------------------------------
    ::std::set< ::rtl::OUString > ScriptsStorage::getElementNames() const
    {
        Sequence< ::rtl::OUString > aElementNames;
        if ( isValid() )
            aElementNames = m_xScriptsStorage->getElementNames();

        ::std::set< ::rtl::OUString > aNames;
        ::std::copy(
            aElementNames.getConstArray(),
            aElementNames.getConstArray() + aElementNames.getLength(),
            ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aNames, aNames.end() )
        );
        return aNames;
    }

    //--------------------------------------------------------------------
    void ScriptsStorage::removeScriptTypeStorage( const ScriptType _eType ) const
    {
        ::rtl::OUString sSubStorageName( lcl_getScriptsSubStorageName( _eType ) );
        if ( m_xScriptsStorage->hasByName( sSubStorageName ) )
            m_xScriptsStorage->removeElement( sSubStorageName );
    }

    //--------------------------------------------------------------------
    bool ScriptsStorage::removeFromDocument( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
    {
        try
        {
            Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
            Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
            xDocStorage->removeElement( lcl_getScriptsStorageName() );
        }
        catch( const Exception& )
        {
            _rLogger.logFailure( MigrationError(
                ERR_REMOVE_SCRIPTS_STORAGE_FAILED,
                ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
                ::cppu::getCaughtException()
            ) ) ;
            return false;
        }
        return true;
    }

    //====================================================================
    //= ProgressDelegator
    //====================================================================
    class ProgressDelegator : public IProgressConsumer
    {
    public:
        ProgressDelegator(  IMigrationProgress& _rDelegator,
                            const ::rtl::OUString& _rObjectName,
                            const ::rtl::OUString& _rAction
                          )
            :m_rDelegator( _rDelegator )
            ,m_sObjectName( _rObjectName )
            ,m_sAction( _rAction )
        {
        }
        virtual ~ProgressDelegator()
        {
        }

        // IProgressConsumer
        virtual void    start( sal_uInt32 _nRange )
        {
            m_rDelegator.startObject( m_sObjectName, m_sAction, _nRange );
        }
        virtual void    advance( sal_uInt32 _nValue )
        {
            m_rDelegator.setObjectProgressValue( _nValue );
        }
        virtual void    end()
        {
            m_rDelegator.endObject();
        }

    private:
        IMigrationProgress& m_rDelegator;
        ::rtl::OUString     m_sObjectName;
        ::rtl::OUString     m_sAction;
    };

	//====================================================================
	//= PhaseGuard
	//====================================================================
    class PhaseGuard
    {
    public:
        PhaseGuard( ProgressMixer& _rMixer )
            :m_rMixer( _rMixer )
        {
        }

        PhaseGuard( ProgressMixer& _rMixer, const PhaseID _nID, const sal_uInt32 _nPhaseRange )
            :m_rMixer( _rMixer )
        {
            start( _nID, _nPhaseRange );
        }

        ~PhaseGuard()
        {
            m_rMixer.endPhase();
        }

        void start( const PhaseID _nID, const sal_uInt32 _nPhaseRange )
        {
            m_rMixer.startPhase( _nID, _nPhaseRange );
        }

    private:
        ProgressMixer&  m_rMixer;
    };

	//====================================================================
	//= MigrationEngine_Impl - declaration
	//====================================================================
    class MigrationEngine_Impl
    {
    public:
        MigrationEngine_Impl(
            const ::comphelper::ComponentContext& _rContext,
            const Reference< XOfficeDatabaseDocument >& _rxDocument,
            IMigrationProgress& _rProgress,
            MigrationLog& _rLogger
        );
        ~MigrationEngine_Impl();

        inline  size_t      getFormCount() const    { return m_nFormCount; }
        inline  size_t      getReportCount()const   { return m_nReportCount; }
        bool    migrateAll();

    private:
        ::comphelper::ComponentContext              m_aContext;
        const Reference< XOfficeDatabaseDocument >  m_xDocument;
        const Reference< XModel >                   m_xDocumentModel;
        IMigrationProgress&                         m_rProgress;
        MigrationLog&                               m_rLogger;
        mutable DocumentID                          m_nCurrentDocumentID;
        SubDocuments                                m_aSubDocs;
        size_t                                      m_nFormCount;
        size_t                                      m_nReportCount;

    private:
        /** collects a description of all sub documents of our database document

            @return
                <TRUE/> if and only if collecting the documents was successful
        */
        bool    impl_collectSubDocuments_nothrow();

        /** migrates the macros/scripts of the given sub document
        */
        bool    impl_handleDocument_nothrow( const SubDocument& _rDocument ) const;

        /** checks the structure of the 'Scripts' folder of a sub document
            for unknown elements

            @return
                <TRUE/> if and only if the 'Scripts' folder contains known elements only.
        */
        bool    impl_checkScriptStorageStructure_nothrow( const SubDocument& _rDocument ) const;

        /** migrates the scripts of the given "storage-based" script type
        */
        bool    impl_migrateScriptStorage_nothrow(
                    const SubDocument& _rDocument,
                    const ScriptType _eScriptType,
                    ProgressMixer& _rProgress,
                    const PhaseID _nPhaseID
                ) const;

        /** migrates the content of the given "container based" libraries (Basic/Dialogs)
        */
        bool    impl_migrateContainerLibraries_nothrow(
                    const SubDocument& _rDocument,
                    const ScriptType _eScriptType,
                    ProgressMixer& _rProgress,
                    const PhaseID _nPhaseID
                ) const;

        /** adjusts the events for the given dialog/element, taking into account the new names
            of the moved libraries
        */
        void    impl_adjustDialogElementEvents_throw(
                    const Reference< XInterface >& _rxElement
                ) const;

        /** adjusts the events in the given dialog, and its controls, taking into account the new names
            of the moved libraries
        */
        bool    impl_adjustDialogEvents_nothrow(
                    Any& _inout_rDialogLibraryElement,
                    const ::rtl::OUString& _rDocName,
                    const ::rtl::OUString& _rDialogLibName,
                    const ::rtl::OUString& _rDialogName
                ) const;

        /** adjust the document-events which refer to macros/scripts in the document, taking into
            account the new names of the moved libraries
        */
        bool    impl_adjustDocumentEvents_nothrow(
                    const SubDocument& _rDocument
                ) const;

        /** adjusts the script references bound to form component events
        */
        bool    impl_adjustFormComponentEvents_nothrow(
                    const SubDocument& _rDocument
                ) const;

        /** adjusts the script references for the elements of the given form component container
        */
        void    impl_adjustFormComponentEvents_throw(
                    const Reference< XIndexAccess >& _rxComponentContainer
                ) const;

        /** adjusts the library name in the given script URL, so that it reflects
            the new name of the library

            @return <TRUE/>
                if and only if adjustments to the script code have been made
        */
        bool    impl_adjustScriptLibrary_nothrow(
                    const ::rtl::OUString& _rScriptType,
                    ::rtl::OUString& _inout_rScriptCode
                ) const;

        bool    impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const;
        bool    impl_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const;

        /** asks the user for a password for the given library, and unprotects the library

            @return <TRUE/>
                if and only if the library could be successfully unprotected
        */
        bool    impl_unprotectPasswordLibrary_throw(
                    const Reference< XLibraryContainerPassword >& _rxPasswordManager,
                    const ScriptType _eScriptType,
                    const ::rtl::OUString& _rLibraryName
                ) const;
    };

	//====================================================================
	//= MigrationEngine_Impl - implementation
	//====================================================================
	//--------------------------------------------------------------------
    MigrationEngine_Impl::MigrationEngine_Impl( const ::comphelper::ComponentContext& _rContext,
            const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress, MigrationLog& _rLogger )
        :m_aContext( _rContext )
        ,m_xDocument( _rxDocument )
        ,m_xDocumentModel( _rxDocument, UNO_QUERY_THROW )
        ,m_rProgress( _rProgress )
        ,m_rLogger( _rLogger )
        ,m_nCurrentDocumentID( - 1 )
        ,m_aSubDocs()
        ,m_nFormCount( 0 )
        ,m_nReportCount( 0 )
    {
        OSL_VERIFY( impl_collectSubDocuments_nothrow() );
    }

	//--------------------------------------------------------------------
    MigrationEngine_Impl::~MigrationEngine_Impl()
    {
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::migrateAll()
    {
        if  ( m_aSubDocs.empty() )
        {
            OSL_ENSURE( false, "MigrationEngine_Impl::migrateAll: no forms/reports found!" );
            // The whole migration wizard is not expected to be called when there are no forms/reports
            // with macros, not to mention when there are no forms/reports at all.
            return false;
        }

        // initialize global progress
        sal_Int32 nOverallRange( m_aSubDocs.size() );
        String sProgressSkeleton = String( MacroMigrationResId( STR_OVERALL_PROGRESS ) );
        sProgressSkeleton.SearchAndReplaceAscii( "$overall$", String::CreateFromInt32( nOverallRange ) );

        m_rProgress.start( nOverallRange );

        for (   SubDocuments::const_iterator doc = m_aSubDocs.begin();
                doc != m_aSubDocs.end();
                ++doc
            )
        {
            sal_Int32 nOverallProgressValue( doc - m_aSubDocs.begin() + 1 );
            // update overall progress text
            ::rtl::OUString sOverallProgress( sProgressSkeleton );
            ::comphelper::string::searchAndReplaceAsciiI( sOverallProgress, "$current$", ::rtl::OUString::valueOf( nOverallProgressValue ) );
            m_rProgress.setOverallProgressText( sOverallProgress );

            // migrate document
            if ( !impl_handleDocument_nothrow( *doc ) )
                return false;

            // update overall progress vallue
            m_rProgress.setOverallProgressValue( nOverallProgressValue );
        }

        // commit the root storage of the database document, for all changes made so far to take effect
        if ( !lcl_commitDocumentStorage_nothrow( m_xDocumentModel, m_rLogger ) )
            return false;

        // save the document
        if ( !lcl_storeDocument_nothrow( m_xDocumentModel, m_rLogger ) )
            return false;

        return true;
    }

	//--------------------------------------------------------------------
    namespace
    {
        void lcl_collectHierarchicalElementNames_throw(
            const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rContainerLoc,
            SubDocuments& _out_rDocs, const SubDocumentType _eType, size_t& _io_counter )
        {
            const ::rtl::OUString sHierarhicalBase(
                _rContainerLoc.getLength()  ?   ::rtl::OUStringBuffer( _rContainerLoc ).appendAscii( "/" ).makeStringAndClear()
                                            :   ::rtl::OUString() );

            Sequence< ::rtl::OUString > aElementNames( _rxContainer->getElementNames() );
            for (   const ::rtl::OUString* elementName = aElementNames.getConstArray();
                    elementName != aElementNames.getConstArray() + aElementNames.getLength();
                    ++elementName
                )
            {
                Any aElement( _rxContainer->getByName( *elementName ) );
                ::rtl::OUString sElementName( ::rtl::OUStringBuffer( sHierarhicalBase ).append( *elementName ) );

                Reference< XNameAccess > xSubContainer( aElement, UNO_QUERY );
                if ( xSubContainer.is() )
                {
                    lcl_collectHierarchicalElementNames_throw( xSubContainer, sElementName, _out_rDocs, _eType, _io_counter );
                }
                else
                {
                    Reference< XCommandProcessor > xCommandProcessor( aElement, UNO_QUERY );
                    OSL_ENSURE( xCommandProcessor.is(), "lcl_collectHierarchicalElementNames_throw: no container, and no comand processor? What *is* it, then?!" );
                    if ( xCommandProcessor.is() )
                    {
                        _out_rDocs.push_back( SubDocument( xCommandProcessor, sElementName, _eType, ++_io_counter ) );
                    }
                }
            }
        }
    }

    //--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_collectSubDocuments_nothrow()
    {
        OSL_PRECOND( m_xDocument.is(), "MigrationEngine_Impl::impl_collectSubDocuments_nothrow: invalid document!" );
        if ( !m_xDocument.is() )
            return false;

        try
        {
            Reference< XNameAccess > xDocContainer( m_xDocument->getFormDocuments(), UNO_SET_THROW );
            m_nFormCount = 0;
            lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eForm, m_nFormCount );

            xDocContainer.set( m_xDocument->getReportDocuments(), UNO_SET_THROW );
            m_nReportCount = 0;
            lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eReport, m_nReportCount );
        }
        catch( const Exception& )
        {
            m_rLogger.logFailure( MigrationError(
                ERR_COLLECTING_DOCUMENTS_FAILED,
                ::cppu::getCaughtException()
            ) );
            return false;
        }
        return true;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& _rDocument ) const
    {
        OSL_ENSURE( m_nCurrentDocumentID == -1,
            "MigrationEngine_Impl::impl_handleDocument_nothrow: there already is a current document!"); 
        m_nCurrentDocumentID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName );

        // start the progress
        ::rtl::OUString sObjectName( lcl_getSubDocumentDescription( _rDocument ) );
        m_rProgress.startObject( sObjectName, ::rtl::OUString(), DEFAULT_DOC_PROGRESS_RANGE );

        // -----------------
        // load the document
        ::rtl::Reference< ProgressCapture > pStatusIndicator( new ProgressCapture( sObjectName, m_rProgress ) );
        SubDocument aSubDocument( _rDocument );
        OpenDocResult eResult = lcl_loadSubDocument_nothrow( aSubDocument, pStatusIndicator.get(), m_rLogger );
        if ( eResult != eOpenedDoc )
        {
            pStatusIndicator->dispose();
            m_rProgress.endObject();
            m_rLogger.finishedDocument( m_nCurrentDocumentID );
			m_nCurrentDocumentID = -1;
            return ( eResult == eIgnoreDoc );
        }

        // -----------------
        // migrate the libraries
        ProgressDelegator aDelegator( m_rProgress, sObjectName, String( MacroMigrationResId( STR_MIGRATING_LIBS ) ) );
        ProgressMixer aProgressMixer( aDelegator );
        aProgressMixer.registerPhase( PHASE_JAVASCRIPT, 1 );
        aProgressMixer.registerPhase( PHASE_BEANSHELL, 1 );
        aProgressMixer.registerPhase( PHASE_PYTHON, 1 );
        aProgressMixer.registerPhase( PHASE_JAVA, 1 );
        aProgressMixer.registerPhase( PHASE_BASIC, 5 );
            // more weight than then others, assuming that usually, there are much more Basic macros than any other scripts
        aProgressMixer.registerPhase( PHASE_DIALOGS, 1 );

        bool bSuccess = impl_checkScriptStorageStructure_nothrow( aSubDocument );

        // migrate storage-based script libraries (which can be handled by mere storage operations)
        bSuccess = bSuccess
            &&  impl_migrateScriptStorage_nothrow( aSubDocument, eJavaScript, aProgressMixer, PHASE_JAVASCRIPT )
            &&  impl_migrateScriptStorage_nothrow( aSubDocument, eBeanShell, aProgressMixer, PHASE_BEANSHELL )
            &&  impl_migrateScriptStorage_nothrow( aSubDocument, ePython, aProgressMixer, PHASE_PYTHON )
            &&  impl_migrateScriptStorage_nothrow( aSubDocument, eJava, aProgressMixer, PHASE_JAVA );

        // migrate Basic and dialog libraries
        bSuccess =  bSuccess
                &&  impl_migrateContainerLibraries_nothrow( aSubDocument, eBasic, aProgressMixer, PHASE_BASIC )
                &&  impl_migrateContainerLibraries_nothrow( aSubDocument, eDialog, aProgressMixer, PHASE_DIALOGS );
                // order matters: First Basic scripts, then dialogs. So we can adjust references from the latter
                // to the former

        // adjust the events in the document
        // (note that errors are ignored here - failure to convert a script reference
        // is not considered a critical error)
        if ( bSuccess )
        {
            impl_adjustDocumentEvents_nothrow( aSubDocument );
            impl_adjustFormComponentEvents_nothrow( aSubDocument );
        }

        // -----------------
        // clean up
        // store the sub document, including removal of the (now obsolete) "Scripts" sub folder
        if ( m_rLogger.movedAnyLibrary( m_nCurrentDocumentID ) )
        {
            bSuccess =  bSuccess
                    &&  ScriptsStorage::removeFromDocument( aSubDocument.xDocument, m_rLogger )
                    &&  lcl_commitDocumentStorage_nothrow( aSubDocument.xDocument, m_rLogger )
                    &&  lcl_storeEmbeddedDocument_nothrow( aSubDocument );
        }

        // unload in any case, even if we were not successful
        bSuccess =  lcl_unloadSubDocument_nothrow( aSubDocument, m_rLogger )
                &&  bSuccess;

        pStatusIndicator->dispose();

        // end the progress, just in case the ProgressCapture didn't receive the XStatusIndicator::end event
        m_rProgress.endObject();

        m_rLogger.finishedDocument( m_nCurrentDocumentID );
        m_nCurrentDocumentID = -1;
        return bSuccess;
    }

	//--------------------------------------------------------------------
    namespace
    {
        static ::rtl::OUString lcl_createTargetLibName( const SubDocument& _rDocument,
            const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetContainer )
        {
            // The new library name is composed from the prefix, the base name, and the old library name.
            const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( _rDocument.eType == eForm ? "Form_" : "Report_" ) );

            ::rtl::OUString sBaseName( _rDocument.sHierarchicalName.copy(
                _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) );
            // Normalize this name. In our current storage implementation (and script containers in a document
            // are finally mapped to sub storages of the document storage), not all characters are allowed.
            // The bug requesting to change this is #i95409#.
            // Unfortunately, the storage implementation does not complain if you use invalid characters/names, but instead
            // it silently accepts them, and produces garbage in the file (#i95408).
            // So, until especially the former is fixed, we need to strip the name from all invalid characters.
            // #i95865# / 2008-11-06 / frank.schoenheit@sun.com

            // The general idea is to replace invalid characters with '_'. However, since "valid" essentially means
            // ASCII only, this implies that for a lot of languages, we would simply replace everything with '_',
            // which of course is not desired.
            // So, we use a heuristics: If the name contains at most 3 invalid characters, and as many valid as invalid
            // characters, then we use the replacement. Otherwise, we just use a unambiguous number for the sub document.
            sal_Int32 nValid=0, nInvalid=0;
            const sal_Unicode* pBaseName = sBaseName.getStr();
            const sal_Int32 nBaseNameLen = sBaseName.getLength();
            for ( sal_Int32 i=0; i<nBaseNameLen; ++i )
            {
                if ( ::comphelper::OStorageHelper::IsValidZipEntryFileName( pBaseName + i, 1, sal_False ) )
                    ++nValid;
                else
                    ++nInvalid;
            }
            if ( ( nInvalid <= 3 ) && ( nInvalid * 2 <= nValid ) )
            {   // not "too many" invalid => replace them
                ::rtl::OUStringBuffer aReplacement;
                aReplacement.ensureCapacity( nBaseNameLen );
                aReplacement.append( sBaseName );
                const sal_Unicode* pReplacement = aReplacement.getStr();
                for ( sal_Int32 i=0; i<nBaseNameLen; ++i )
                {
                    if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( pReplacement + i, 1, sal_False ) )
                        aReplacement.setCharAt( i, '_' );
                }
                sBaseName = aReplacement.makeStringAndClear();

                ::rtl::OUStringBuffer aNewLibNameAttempt;
                aNewLibNameAttempt.append( sPrefix );
                aNewLibNameAttempt.append( sBaseName );
                aNewLibNameAttempt.appendAscii( "_" );
                aNewLibNameAttempt.append( _rSourceLibName );
                ::rtl::OUString sTargetName( aNewLibNameAttempt.makeStringAndClear() );
                if ( !_rxTargetContainer->hasByName( sTargetName ) )
                    return sTargetName;
            }

            // "too many" invalid characters, or the name composed with the base name was already used.
            // (The latter is valid, since there can be multiple sub documents with the same base name,
            // in different levels in the hierarchy.)
            // In this case, just use the umambiguous sub document number.
            ::rtl::OUStringBuffer aNewLibName;
            aNewLibName.append( sPrefix );
            aNewLibName.append( ::rtl::OUString::valueOf( sal_Int64( _rDocument.nNumber ) ) );
            aNewLibName.appendAscii( "_" );
            aNewLibName.append( _rSourceLibName );
            return aNewLibName.makeStringAndClear();
        }
    }

    //--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_checkScriptStorageStructure_nothrow( const SubDocument& _rDocument ) const
    {
        OSL_PRECOND( _rDocument.xDocument.is(), "MigrationEngine_Impl::impl_checkScriptStorageStructure_nothrow: invalid document!" );
        if ( !_rDocument.xDocument.is() )
            return false;

        try
        {
            // the root storage of the document whose scripts are to be migrated
            ScriptsStorage aDocStorage( _rDocument.xDocument, m_rLogger );
            if  ( !aDocStorage.isValid() )
            {   // no scripts at all, or no scripts of the given type
                return !m_rLogger.hadFailure();
            }
            ::std::set< ::rtl::OUString > aElementNames( aDocStorage.getElementNames() );

            ScriptType aKnownStorageBasedTypes[] = {
                eBeanShell, eJavaScript, ePython, eJava
            };
            for ( size_t i=0; i<sizeof( aKnownStorageBasedTypes ) / sizeof( aKnownStorageBasedTypes[0] ); ++i )
                aElementNames.erase( lcl_getScriptsSubStorageName( aKnownStorageBasedTypes[i] ) );

            if ( !aElementNames.empty() )
            {
                m_rLogger.logFailure( MigrationError(
                    ERR_UNKNOWN_SCRIPT_FOLDER,
                    lcl_getSubDocumentDescription( _rDocument ),
                    *aElementNames.begin()
                ) );
                return false;
            }
        }
        catch( const Exception& )
        {
            m_rLogger.logFailure( MigrationError(
                ERR_EXAMINING_SCRIPTS_FOLDER_FAILED,
                lcl_getSubDocumentDescription( _rDocument ),
                ::cppu::getCaughtException()
            ) );
            return false;
        }
        return true;
    }

    //--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_migrateScriptStorage_nothrow( const SubDocument& _rDocument,
        const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
    {
        OSL_PRECOND( _rDocument.xDocument.is(), "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: invalid document!" );
        if ( !_rDocument.xDocument.is() )
            return false;

        ScriptsStorage aDatabaseScripts( m_rLogger );
            // the scripts of our complete database document - created on demand only
        SharedStorage xTargetStorage;
            // the target for moving the scripts storages - created on demand only

        PhaseGuard aPhase( _rProgress );
        bool bSuccess = false;
        Any aException;
        try
        {
            // the root storage of the document whose scripts are to be migrated
            ScriptsStorage aDocStorage( _rDocument.xDocument, m_rLogger );
            if  (   !aDocStorage.isValid()
                ||  !aDocStorage.hasScripts( _eScriptType )
                )
            {
                // no scripts at all, or no scripts of the given type
                _rProgress.startPhase( _nPhaseID, 1 );
                _rProgress.endPhase();
                return !m_rLogger.hadFailure();
            }

            SharedStorage xScriptsRoot( aDocStorage.getScriptsRoot( _eScriptType ) );
            if ( !xScriptsRoot.is() )
                throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "internal error" ) ), NULL );

            // loop through the script libraries
            Sequence< ::rtl::OUString > aStorageElements( xScriptsRoot->getElementNames() );
            aPhase.start( _nPhaseID, aStorageElements.getLength() );

            for (   const ::rtl::OUString* element = aStorageElements.getConstArray();
                    element != aStorageElements.getConstArray() + aStorageElements.getLength();
                    ++element
                )
            {
                bool bIsScriptLibrary = xScriptsRoot->isStorageElement( *element );
                OSL_ENSURE( bIsScriptLibrary,
                    "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: warning: unknown scripts storage structure!" );
                    // we cannot handle this. We would need to copy this stream to the respective scripts storage
                    // of the database document, but we cannot guarantee that the name is not used, yet, and we cannot
                    // simply rename the thing.
                if ( !bIsScriptLibrary )
                {
                    m_rLogger.logFailure( MigrationError(
                        ERR_UNEXPECTED_LIBSTORAGE_ELEMENT,
                        lcl_getSubDocumentDescription( _rDocument ),
                        getScriptTypeDisplayName( _eScriptType ),
                        *element
                    ) );
                    return false;
                }

                // ensure we have access to the DBDoc's scripts storage
                if ( !aDatabaseScripts.isValid() )
                {   // not needed 'til now
                    aDatabaseScripts.bind( m_xDocumentModel );
                    if ( aDatabaseScripts.isValid() )
                        xTargetStorage = aDatabaseScripts.getScriptsRoot( _eScriptType );

                    if ( !xTargetStorage.is() )
                    {
                        m_rLogger.logFailure( MigrationError(
                            ERR_CREATING_DBDOC_SCRIPT_STORAGE_FAILED,
                            getScriptTypeDisplayName( _eScriptType )
                        ) );
                        return false;
                    }
                }

                // move the library to the DBDoc's scripts library, under the new name
                ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *element, xTargetStorage.getTyped().get() ) );
                xScriptsRoot->moveElementTo( *element, xTargetStorage, sNewLibName );

                // log the fact that we moved the library
                m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *element, sNewLibName );

                // progress
                _rProgress.advancePhase( element - aStorageElements.getConstArray() );
            }

            // commit the storages, so the changes we made persist
            if  (   !lcl_commitStorage_nothrow( xScriptsRoot )
                ||  ( xTargetStorage.is() && !lcl_commitStorage_nothrow( xTargetStorage ) )
                )
            {
                m_rLogger.logFailure( MigrationError(
                    ERR_COMMITTING_SCRIPT_STORAGES_FAILED,
                    getScriptTypeDisplayName( _eScriptType ),
                    lcl_getSubDocumentDescription( _rDocument )
                ) );
                return false;
            }

            // now that the concrete scripts storage does not have any elements anymore,
            // remove it
            xScriptsRoot.reset( NULL ); // need to reset the storage to be allowed to remove it
            aDocStorage.removeScriptTypeStorage( _eScriptType );

            // done so far
            bSuccess =  aDocStorage.commit()
                    &&  aDatabaseScripts.commit();
        }
        catch( const Exception& )
        {
            aException = ::cppu::getCaughtException();
            bSuccess = false;
        }

        // log the error, if any
        if ( !bSuccess )
        {
            m_rLogger.logFailure( MigrationError(
                ERR_GENERAL_SCRIPT_MIGRATION_FAILURE,
                getScriptTypeDisplayName( _eScriptType ),
                lcl_getSubDocumentDescription( _rDocument ),
                aException
            ) );
        }

        return bSuccess;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow( const SubDocument& _rDocument,
            const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
    {
		OSL_PRECOND( ( _eScriptType == eBasic ) || ( _eScriptType == eDialog ),
            "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: illegal script type!" );

        bool bSuccess = false;
        PhaseGuard aPhase( _rProgress );
        Any aException;
        do  // artificial loop for flow control only
        {
        try
        {
            // access library container of the sub document
            Reference< XEmbeddedScripts > xSubDocScripts( _rDocument.xDocument, UNO_QUERY );
            if ( !xSubDocScripts.is() )
            {   // no script support in the sub document -> nothing to migrate
                // (though ... this is suspicious, at least ...)
                bSuccess = true;
                break;
            }

            Reference< XStorageBasedLibraryContainer > xSourceLibraries(
                _eScriptType == eBasic ? xSubDocScripts->getBasicLibraries() : xSubDocScripts->getDialogLibraries(),
                UNO_QUERY_THROW
            );
            Reference< XLibraryContainerPassword > xSourcePasswords( xSourceLibraries, UNO_QUERY );
            OSL_ENSURE( xSourcePasswords.is(),
                "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: suspicious: no password management for the source libraries!" );

            Sequence< ::rtl::OUString > aSourceLibNames( xSourceLibraries->getElementNames() );
            aPhase.start( _nPhaseID, aSourceLibNames.getLength() );

            if ( !xSourceLibraries->hasElements() )
            {
                bSuccess = true;
                break;
            }

            // create library containers for the document - those will be the target for the migration
            Reference< XStorageBasedDocument > xStorageDoc( m_xDocument, UNO_QUERY_THROW );
            Reference< XStorageBasedLibraryContainer > xTargetLibraries;
            if ( _eScriptType == eBasic )
            {
                xTargetLibraries.set( DocumentScriptLibraryContainer::create(
                    m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW );
            }
            else
            {
                xTargetLibraries.set( DocumentDialogLibraryContainer::create(
                    m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW );
            }

            // copy all libs to the target, with potentially renaming them
            const ::rtl::OUString* pSourceLibBegin = aSourceLibNames.getConstArray();
            const ::rtl::OUString* pSourceLibEnd = pSourceLibBegin + aSourceLibNames.getLength();
            for (   const ::rtl::OUString* pSourceLibName = pSourceLibBegin;
                    pSourceLibName != pSourceLibEnd;
                    ++pSourceLibName
                )
            {
                // if the library is password-protected, ask the user to unprotect it
                if  (   xSourcePasswords.is()
                    &&  xSourcePasswords->isLibraryPasswordProtected( *pSourceLibName )
                    &&  !xSourcePasswords->isLibraryPasswordVerified( *pSourceLibName )
                    )
                {
                    if ( !impl_unprotectPasswordLibrary_throw( xSourcePasswords, _eScriptType, *pSourceLibName ) )
                    {
                        m_rLogger.logFailure( MigrationError(
                            ERR_PASSWORD_VERIFICATION_FAILED,
                            _rDocument.sHierarchicalName,
                            getScriptTypeDisplayName( _eScriptType ),
                            *pSourceLibName
                        ) );
                        return false;
                    }
                }

                ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *pSourceLibName, xTargetLibraries.get() ) );

                if ( xSourceLibraries->isLibraryLink( *pSourceLibName ) )
                {
                    // just re-create the link in the target library
                    xTargetLibraries->createLibraryLink(
                        sNewLibName,
                        xSourceLibraries->getLibraryLinkURL( *pSourceLibName ),
                        xSourceLibraries->isLibraryReadOnly( *pSourceLibName )
                    );
                }
                else
                {
                    if ( !xSourceLibraries->isLibraryLoaded( *pSourceLibName ) )
                        xSourceLibraries->loadLibrary( *pSourceLibName );

                    // copy the content of this particular libary
                    Reference< XNameAccess > xSourceLib( xSourceLibraries->getByName( *pSourceLibName ), UNO_QUERY_THROW );
                    Reference< XNameContainer > xTargetLib( xTargetLibraries->createLibrary( sNewLibName ), UNO_QUERY_THROW );

                    Sequence< ::rtl::OUString > aLibElementNames( xSourceLib->getElementNames() );
                    for (   const ::rtl::OUString* pSourceElementName = aLibElementNames.getConstArray();
                            pSourceElementName != aLibElementNames.getConstArray() + aLibElementNames.getLength();
                            ++pSourceElementName
                        )
                    {
                        Any aElement = xSourceLib->getByName( *pSourceElementName );
                        OSL_ENSURE( aElement.hasValue(),
                            "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: invalid (empty) lib element!" );

                        // if this is a dialog, adjust the references to scripts
                        if ( _eScriptType == eDialog )
                        {
                            impl_adjustDialogEvents_nothrow( aElement, lcl_getSubDocumentDescription( _rDocument ),
                                *pSourceLibName, *pSourceElementName );
                        }

                        xTargetLib->insertByName( *pSourceElementName, aElement );
                    }

                    // transfer the read-only flag
                    xTargetLibraries->setLibraryReadOnly(
                        sNewLibName, xSourceLibraries->isLibraryReadOnly( *pSourceLibName ) );
                }

                // remove the source lib
                xSourceLibraries->removeLibrary( *pSourceLibName );

                // tell the logger
                m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *pSourceLibName, sNewLibName );

                // tell the progress
                _rProgress.advancePhase( pSourceLibName - pSourceLibBegin );
            }

            // clean up
            xSourceLibraries->storeLibraries();

            xTargetLibraries->storeLibraries();
            Reference< XStorage > xTargetRoot( xTargetLibraries->getRootLocation(), UNO_QUERY_THROW );
            bSuccess = lcl_commitStorage_nothrow( xTargetRoot );
        }
        catch( const Exception& )
        {
            aException = ::cppu::getCaughtException();
            bSuccess = false;
        }
        } while ( false );

        // log the error, if any
        if ( !bSuccess )
        {
            m_rLogger.logFailure( MigrationError(
                ERR_GENERAL_MACRO_MIGRATION_FAILURE,
                lcl_getSubDocumentDescription( _rDocument ),
                aException
            ) );
        }

        return bSuccess;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( const ::rtl::OUString& _rScriptType,
            ::rtl::OUString& _inout_rScriptCode ) const
    {
        OSL_PRECOND( _inout_rScriptCode.getLength(), "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: invalid script!" );
        if ( !_inout_rScriptCode.getLength() )
            return false;

        bool bSuccess = false;
        Any aException;
        try
        {
            if  (   !_rScriptType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Script" ) )
                ||  !_rScriptType.getLength()
                )
            {
                OSL_ENSURE( false,
                    "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: no or unknown script type!" );
                m_rLogger.logRecoverable( MigrationError(
                    ERR_UNKNOWN_SCRIPT_TYPE,
                    _rScriptType
                ) );
                return false;
            }

            // analyze the script URI
            Reference< XUriReferenceFactory > xUriRefFac = UriReferenceFactory::create( m_aContext.getUNOContext() );
            Reference< XVndSunStarScriptUrlReference > xUri( xUriRefFac->parse( _inout_rScriptCode ), UNO_QUERY_THROW );

            ::rtl::OUString sScriptLanguage = xUri->getParameter(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "language" ) ) );
            ScriptType eScriptType = eBasic;
            if ( !lcl_getScriptTypeFromLanguage( sScriptLanguage, eScriptType ) )
            {
                OSL_ENSURE( false,
                    "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: unknown script language!" );
                m_rLogger.logRecoverable( MigrationError(
                    ERR_UNKNOWN_SCRIPT_LANGUAGE,
                    sScriptLanguage
                ) );
                return false;
            }

            ::rtl::OUString sLocation = xUri->getParameter(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "location" ) ) );
            if ( !sLocation.equalsAscii( "document" ) )
            {
                // only document libraries must be migrated, of course
                return false;
            }

            ::rtl::OUString sScriptName = xUri->getName();
            sal_Int32 nLibModuleSeparator = sScriptName.indexOf( '.' );
            if ( nLibModuleSeparator < 0 )
            {
                OSL_ENSURE( false,
                    "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: invalid/unknown location format!" );
                m_rLogger.logRecoverable( MigrationError(
                    ERR_UNKNOWN_SCRIPT_NAME_FORMAT,
                    sScriptName
                ) );
                return false;
            }

            // replace the library name
            ::rtl::OUString sLibrary = sScriptName.copy( 0, nLibModuleSeparator );
            ::rtl::OUString sNewLibName = m_rLogger.getNewLibraryName(
                m_nCurrentDocumentID, eScriptType, sLibrary );
            OSL_ENSURE( sLibrary != sNewLibName,
                "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: a library which has not been migrated?" );

            ::rtl::OUStringBuffer aNewLocation;
            aNewLocation.append( sNewLibName );
            aNewLocation.append( sScriptName.copy( nLibModuleSeparator ) );
            xUri->setName( aNewLocation.makeStringAndClear() );

            // update the new script URL
            _inout_rScriptCode = xUri->getUriReference();
            bSuccess = true;
        }
        catch( const Exception& )
        {
            aException = ::cppu::getCaughtException();
            bSuccess = false;
        }

        // log the failure, if any
        if ( !bSuccess )
        {
            m_rLogger.logRecoverable( MigrationError(
                ERR_SCRIPT_TRANSLATION_FAILURE,
                _rScriptType,
                _inout_rScriptCode,
                aException
            ) );
        }

        return bSuccess;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const
    {
        if ( _inout_rScriptEvent.ScriptType.getLength() && _inout_rScriptEvent.ScriptCode.getLength() )
            return impl_adjustScriptLibrary_nothrow( _inout_rScriptEvent.ScriptType, _inout_rScriptEvent.ScriptCode );
        return false;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const
    {
        ::comphelper::NamedValueCollection aScriptDesc( _inout_rScriptDescriptor );

        ::rtl::OUString sScriptType;
        ::rtl::OUString sScript;
        try
        {
            OSL_VERIFY( aScriptDesc.get_ensureType( "EventType", sScriptType ) );
            OSL_VERIFY( aScriptDesc.get_ensureType( "Script", sScript ) );
        }
        catch( const Exception& )
        {
            m_rLogger.logRecoverable( MigrationError(
                ERR_INVALID_SCRIPT_DESCRIPTOR_FORMAT,
                ::cppu::getCaughtException()
            ) );
        }

        if ( sScriptType.getLength() && sScript.getLength() )
            if ( !impl_adjustScriptLibrary_nothrow( sScriptType, sScript ) )
                return false;

        aScriptDesc.put( "Script", sScript );
        _inout_rScriptDescriptor <<= aScriptDesc.getPropertyValues();
        return true;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_adjustDocumentEvents_nothrow( const SubDocument& _rDocument ) const
    {
        try
        {
            Reference< XEventsSupplier > xSuppEvents( _rDocument.xDocument, UNO_QUERY );
            if ( !xSuppEvents.is() )
                // this is allowed. E.g. new-style reports currently do not support this
                return true;

            Reference< XNameReplace > xEvents( xSuppEvents->getEvents(), UNO_SET_THROW );
            Sequence< ::rtl::OUString > aEventNames = xEvents->getElementNames();

            Any aEvent;
            for (   const ::rtl::OUString* eventName = aEventNames.getConstArray();
                    eventName != aEventNames.getConstArray() + aEventNames.getLength();
                    ++eventName
                )
            {
                aEvent = xEvents->getByName( *eventName );
                if ( !aEvent.hasValue() )
                    continue;

                // translate
                if ( !impl_adjustScriptLibrary_nothrow( aEvent ) )
                    continue;

                // put back
                xEvents->replaceByName( *eventName, aEvent );
            }
        }
        catch( const Exception& )
        {
            m_rLogger.logRecoverable( MigrationError(
                ERR_ADJUSTING_DOCUMENT_EVENTS_FAILED,
                lcl_getSubDocumentDescription( _rDocument ),
                ::cppu::getCaughtException()
            ) );
            return false;
        }
        return true;
    }

	//--------------------------------------------------------------------
    void MigrationEngine_Impl::impl_adjustDialogElementEvents_throw( const Reference< XInterface >& _rxElement ) const
    {
        Reference< XScriptEventsSupplier > xEventsSupplier( _rxElement, UNO_QUERY_THROW );
        Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_QUERY_THROW );
        Sequence< ::rtl::OUString > aEventNames( xEvents->getElementNames() );

        const ::rtl::OUString* eventName = aEventNames.getArray();
        const ::rtl::OUString* eventNamesEnd = eventName + aEventNames.getLength();

        ScriptEventDescriptor aScriptEvent;
        for ( ; eventName != eventNamesEnd; ++eventName )
        {
            OSL_VERIFY( xEvents->getByName( *eventName ) >>= aScriptEvent );

            if ( !impl_adjustScriptLibrary_nothrow( aScriptEvent ) )
                continue;

            xEvents->replaceByName( *eventName, makeAny( aScriptEvent ) );
        }
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_adjustDialogEvents_nothrow( Any& _inout_rDialogLibraryElement,
        const ::rtl::OUString& _rDocName, const ::rtl::OUString& _rDialogLibName, const ::rtl::OUString& _rDialogName ) const
    {
        try
        {
            // load a dialog model from the stream describing it
            Reference< XInputStreamProvider > xISP( _inout_rDialogLibraryElement, UNO_QUERY_THROW );
            Reference< XInputStream > xInput( xISP->createInputStream(), UNO_QUERY_THROW );

            Reference< XNameContainer > xDialogModel( m_aContext.createComponent( "com.sun.star.awt.UnoControlDialogModel" ), UNO_QUERY_THROW );
            ::xmlscript::importDialogModel( xInput, xDialogModel, m_aContext.getUNOContext() );

            // adjust the events of the dialog
            impl_adjustDialogElementEvents_throw( xDialogModel );

            // adjust the events of the controls
            Sequence< ::rtl::OUString > aControlNames( xDialogModel->getElementNames() );
            const ::rtl::OUString* controlName = aControlNames.getConstArray();
            const ::rtl::OUString* controlNamesEnd = controlName + aControlNames.getLength();
            for ( ; controlName != controlNamesEnd; ++controlName )
            {
                impl_adjustDialogElementEvents_throw( Reference< XInterface >( xDialogModel->getByName( *controlName ), UNO_QUERY ) );
            }

            // export dialog model
            xISP = ::xmlscript::exportDialogModel( xDialogModel, m_aContext.getUNOContext() );
            _inout_rDialogLibraryElement <<= xISP;
        }
        catch( const Exception& )
        {
            m_rLogger.logRecoverable( MigrationError(
                ERR_ADJUSTING_DIALOG_EVENTS_FAILED,
                _rDocName,
                _rDialogLibName,
                _rDialogName,
                ::cppu::getCaughtException()
            ) );
            return false;
        }
        return true;
    }

	//--------------------------------------------------------------------
    void MigrationEngine_Impl::impl_adjustFormComponentEvents_throw( const Reference< XIndexAccess >& _rxComponentContainer ) const
    {
        FormComponentIterator aCompIter( _rxComponentContainer );
        while ( aCompIter.hasMore() )
        {
            // 1. adjust the component's scripts of the current component
            FormComponentScripts aComponent( aCompIter.next() );
            Sequence< ScriptEventDescriptor > aEvents( aComponent.getEvents() );

            bool bChangedComponentEvents = false;
            for (   ScriptEventDescriptor* scriptEvent = aEvents.getArray();
                    scriptEvent != aEvents.getArray() + aEvents.getLength();
                    ++scriptEvent
                )
            {
                if ( !impl_adjustScriptLibrary_nothrow( *scriptEvent ) )
                    continue;

                bChangedComponentEvents = true;
            }

            if ( bChangedComponentEvents )
                aComponent.setEvents( aEvents );

            // 2. step down if the component is a container itself
            Reference< XIndexAccess > xContainer( aComponent.getComponent(), UNO_QUERY );
            if ( xContainer.is() )
                impl_adjustFormComponentEvents_throw( xContainer );
        }
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_adjustFormComponentEvents_nothrow( const SubDocument& _rDocument ) const
    {
        try
        {
            DrawPageIterator aPageIter( _rDocument.xDocument );
            while ( aPageIter.hasMore() )
            {
                Reference< XFormsSupplier > xSuppForms( aPageIter.next(), UNO_QUERY_THROW );
                Reference< XIndexAccess > xForms( xSuppForms->getForms(), UNO_QUERY_THROW );
                impl_adjustFormComponentEvents_throw( xForms );
            }
        }
        catch( const Exception& )
        {
            m_rLogger.logRecoverable( MigrationError(
                ERR_ADJUSTING_FORMCOMP_EVENTS_FAILED,
                lcl_getSubDocumentDescription( _rDocument ),
                ::cppu::getCaughtException()
            ) );
            return false;
        }
        return true;
    }

	//--------------------------------------------------------------------
    bool MigrationEngine_Impl::impl_unprotectPasswordLibrary_throw( const Reference< XLibraryContainerPassword >& _rxPasswordManager,
            const ScriptType _eScriptType, const ::rtl::OUString& _rLibraryName ) const
    {
        // a human-readable description of the affected library
        ::rtl::OUString sLibraryDescription( String(
            MacroMigrationResId( STR_LIBRARY_TYPE_AND_NAME ) ) );
        ::comphelper::string::searchAndReplaceAsciiI( sLibraryDescription, "$type$",
            getScriptTypeDisplayName( _eScriptType ) );
        ::comphelper::string::searchAndReplaceAsciiI( sLibraryDescription, "$library$",
            _rLibraryName );

        InteractionHandler aHandler( m_aContext, m_xDocumentModel );
        ::rtl::OUString sPassword;
        while ( true )
        {
            if ( !aHandler.requestDocumentPassword( sLibraryDescription, sPassword ) )
                // aborted by the user
                return false;

            bool bSuccessVerification = _rxPasswordManager->verifyLibraryPassword( _rLibraryName, sPassword );
            if ( bSuccessVerification )
                return true;
        }

    }

	//====================================================================
	//= MigrationEngine
	//====================================================================
	//--------------------------------------------------------------------
    MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& _rContext,
            const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress,
            MigrationLog& _rLogger )
        :m_pImpl( new MigrationEngine_Impl( _rContext, _rxDocument, _rProgress, _rLogger ) )
    {
    }

	//--------------------------------------------------------------------
    MigrationEngine::~MigrationEngine()
    {
    }

	//--------------------------------------------------------------------
    sal_Int32 MigrationEngine::getFormCount() const
    {
        return m_pImpl->getFormCount();
    }

	//--------------------------------------------------------------------
    sal_Int32 MigrationEngine::getReportCount() const
    {
        return m_pImpl->getReportCount();
    }

	//--------------------------------------------------------------------
    bool MigrationEngine::migrateAll()
    {
        return m_pImpl->migrateAll();
    }

//........................................................................
} // namespace dbmm
//........................................................................
