/**************************************************************
 * 
 * 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_basic.hxx"
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
#include <tools/errinf.hxx>
#include <osl/mutex.hxx>
#include <vos/diagnose.hxx>
#include <rtl/uri.hxx>
#include <rtl/strbuf.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/anytostring.hxx>

#include "namecont.hxx"
#include <basic/basicmanagerrepository.hxx>
#include <tools/diagnose_ex.h>
#include <tools/urlobj.hxx>
#include <unotools/streamwrap.hxx>
#include <unotools/pathoptions.hxx>
#include <svtools/sfxecode.hxx>
#include <svtools/ehdl.hxx>
#include <basic/basmgr.hxx>
#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/uno/DeploymentException.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/script/LibraryNotLoadedException.hpp>
#include <com/sun/star/script/vba/VBAScriptEventId.hpp>
#include <com/sun/star/deployment/ExtensionManager.hpp>
#include <comphelper/storagehelper.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <basic/sbmod.hxx>

namespace basic
{

using namespace com::sun::star::document;
using namespace com::sun::star::container;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::io;
using namespace com::sun::star::ucb;
using namespace com::sun::star::script;
using namespace com::sun::star::beans;
using namespace com::sun::star::xml::sax;
using namespace com::sun::star::util;
using namespace com::sun::star::task;
using namespace com::sun::star::embed;
using namespace com::sun::star::frame;
using namespace com::sun::star::deployment;
using namespace com::sun::star;
using namespace cppu;
using namespace rtl;
using namespace osl;

using com::sun::star::uno::Reference;

// #i34411: Flag for error handling during migration
static bool GbMigrationSuppressErrors = false;

//============================================================================
// Implementation class NameContainer

// Methods XElementAccess
Type NameContainer::getElementType()
	throw(RuntimeException)
{
	return mType;
}

sal_Bool NameContainer::hasElements()
	throw(RuntimeException)
{
	sal_Bool bRet = (mnElementCount > 0);
	return bRet;
}

// Methods XNameAccess
Any NameContainer::getByName( const OUString& aName )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
    NameContainerNameMap::iterator aIt = mHashMap.find( aName );
	if( aIt == mHashMap.end() )
	{
		throw NoSuchElementException();
	}
	sal_Int32 iHashResult = (*aIt).second;
	Any aRetAny = mValues.getConstArray()[ iHashResult ];
	return aRetAny;
}

Sequence< OUString > NameContainer::getElementNames()
	throw(RuntimeException)
{
	return mNames;
}

sal_Bool NameContainer::hasByName( const OUString& aName )
	throw(RuntimeException)
{
	NameContainerNameMap::iterator aIt = mHashMap.find( aName );
	sal_Bool bRet = ( aIt != mHashMap.end() );
	return bRet;
}


// Methods XNameReplace
void NameContainer::replaceByName( const OUString& aName, const Any& aElement )
	throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
{
	Type aAnyType = aElement.getValueType();
    if( mType != aAnyType )
		throw IllegalArgumentException();

	NameContainerNameMap::iterator aIt = mHashMap.find( aName );
	if( aIt == mHashMap.end() )
	{
		throw NoSuchElementException();
	}
	sal_Int32 iHashResult = (*aIt).second;
	Any aOldElement = mValues.getConstArray()[ iHashResult ];
	mValues.getArray()[ iHashResult ] = aElement;


	// Fire event
	if( maContainerListeners.getLength() > 0 )
	{
    	ContainerEvent aEvent;
    	aEvent.Source = mpxEventSource;
    	aEvent.Accessor <<= aName;
    	aEvent.Element = aElement;
    	aEvent.ReplacedElement = aOldElement;
        maContainerListeners.notifyEach( &XContainerListener::elementReplaced, aEvent );
    }

    /*  After the container event has been fired (one listener will update the
        core Basic manager), fire change event. Listeners can rely that the
        Basic source code of the core Basic manager is up-to-date. */
    if( maChangesListeners.getLength() > 0 )
    {
        ChangesEvent aEvent;
        aEvent.Source = mpxEventSource;
        aEvent.Base <<= aEvent.Source;
        aEvent.Changes.realloc( 1 );
        aEvent.Changes[ 0 ].Accessor <<= aName;
        aEvent.Changes[ 0 ].Element <<= aElement;
    	aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
        maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
    }
}


// Methods XNameContainer
void NameContainer::insertByName( const OUString& aName, const Any& aElement )
	throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
{
	Type aAnyType = aElement.getValueType();
    if( mType != aAnyType )
		throw IllegalArgumentException();

	NameContainerNameMap::iterator aIt = mHashMap.find( aName );
	if( aIt != mHashMap.end() )
	{
		throw ElementExistException();
	}

	sal_Int32 nCount = mNames.getLength();
	mNames.realloc( nCount + 1 );
	mValues.realloc( nCount + 1 );
	mNames.getArray()[ nCount ] = aName;
	mValues.getArray()[ nCount ] = aElement;

	mHashMap[ aName ] = nCount;
	mnElementCount++;

	// Fire event
	if( maContainerListeners.getLength() > 0 )
	{
    	ContainerEvent aEvent;
    	aEvent.Source = mpxEventSource;
    	aEvent.Accessor <<= aName;
    	aEvent.Element = aElement;
        maContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
	}

    /*  After the container event has been fired (one listener will update the
        core Basic manager), fire change event. Listeners can rely that the
        Basic source code of the core Basic manager is up-to-date. */
    if( maChangesListeners.getLength() > 0 )
    {
        ChangesEvent aEvent;
        aEvent.Source = mpxEventSource;
        aEvent.Base <<= aEvent.Source;
        aEvent.Changes.realloc( 1 );
        aEvent.Changes[ 0 ].Accessor <<= aName;
        aEvent.Changes[ 0 ].Element <<= aElement;
        maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
    }
}

void NameContainer::removeByName( const OUString& aName )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	NameContainerNameMap::iterator aIt = mHashMap.find( aName );
	if( aIt == mHashMap.end() )
	{
		throw NoSuchElementException();
	}

	sal_Int32 iHashResult = (*aIt).second;
	Any aOldElement = mValues.getConstArray()[ iHashResult ];
	mHashMap.erase( aIt );
	sal_Int32 iLast = mNames.getLength() - 1;
	if( iLast != iHashResult )
	{
		OUString* pNames = mNames.getArray();
		Any* pValues = mValues.getArray();
		pNames[ iHashResult ] = pNames[ iLast ];
		pValues[ iHashResult ] = pValues[ iLast ];
		mHashMap[ pNames[ iHashResult ] ] = iHashResult;
	}
	mNames.realloc( iLast );
	mValues.realloc( iLast );
	mnElementCount--;

	// Fire event
	if( maContainerListeners.getLength() > 0 )
	{
    	ContainerEvent aEvent;
    	aEvent.Source = mpxEventSource;
    	aEvent.Accessor <<= aName;
    	aEvent.Element = aOldElement;
        maContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
	}

    /*  After the container event has been fired (one listener will update the
        core Basic manager), fire change event. Listeners can rely that the
        Basic source code of the core Basic manager is up-to-date. */
    if( maChangesListeners.getLength() > 0 )
    {
        ChangesEvent aEvent;
        aEvent.Source = mpxEventSource;
        aEvent.Base <<= aEvent.Source;
        aEvent.Changes.realloc( 1 );
        aEvent.Changes[ 0 ].Accessor <<= aName;
        // aEvent.Changes[ 0 ].Element remains empty (meaning "replaced with nothing")
        aEvent.Changes[ 0 ].ReplacedElement = aOldElement;
        maChangesListeners.notifyEach( &XChangesListener::changesOccurred, aEvent );
    }
}


// Methods XContainer
void SAL_CALL NameContainer::addContainerListener( const Reference< XContainerListener >& xListener )
	throw (RuntimeException)
{
	if( !xListener.is() )
		throw RuntimeException();
	Reference< XInterface > xIface( xListener, UNO_QUERY );
	maContainerListeners.addInterface( xIface );
}

void SAL_CALL NameContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
	throw (RuntimeException)
{
	if( !xListener.is() )
		throw RuntimeException();
	Reference< XInterface > xIface( xListener, UNO_QUERY );
	maContainerListeners.removeInterface( xIface );
}

// Methods XChangesNotifier
void SAL_CALL NameContainer::addChangesListener( const Reference< XChangesListener >& xListener )
    throw (RuntimeException)
{
	if( !xListener.is() )
		throw RuntimeException();
	Reference< XInterface > xIface( xListener, UNO_QUERY );
	maChangesListeners.addInterface( xIface );
}

void SAL_CALL NameContainer::removeChangesListener( const Reference< XChangesListener >& xListener )
    throw (RuntimeException)
{
	if( !xListener.is() )
		throw RuntimeException();
	Reference< XInterface > xIface( xListener, UNO_QUERY );
	maChangesListeners.removeInterface( xIface );
}

//============================================================================
// ModifiableHelper

void ModifiableHelper::setModified( sal_Bool _bModified )
{
    if ( _bModified == mbModified )
        return;
    mbModified = _bModified;

    if ( m_aModifyListeners.getLength() == 0 )
        return;

    EventObject aModifyEvent( m_rEventSource );
    m_aModifyListeners.notifyEach( &XModifyListener::modified, aModifyEvent );
}

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

VBAScriptListenerContainer::VBAScriptListenerContainer( ::osl::Mutex& rMutex ) :
    VBAScriptListenerContainer_BASE( rMutex )
{
}

bool VBAScriptListenerContainer::implTypedNotify( const Reference< vba::XVBAScriptListener >& rxListener, const vba::VBAScriptEvent& rEvent ) throw (Exception)
{
    rxListener->notifyVBAScriptEvent( rEvent );
    return true;    // notify all other listeners too
}

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

// Implementation class SfxLibraryContainer
DBG_NAME( SfxLibraryContainer )

// Ctor
SfxLibraryContainer::SfxLibraryContainer( void )
	: SfxLibraryContainer_BASE( maMutex )

    , maVBAScriptListeners( maMutex )
    , mnRunningVBAScripts( 0 )
    , mbVBACompat( sal_False )
    , maModifiable( *this, maMutex )
    , maNameContainer( getCppuType( (Reference< XNameAccess >*) NULL ) )
    , mbOldInfoFormat( sal_False )
    , mbOasis2OOoFormat( sal_False )
    , mpBasMgr( NULL )
    , mbOwnBasMgr( sal_False )
{
    DBG_CTOR( SfxLibraryContainer, NULL );

	mxMSF = comphelper::getProcessServiceFactory();
	if( !mxMSF.is() )
	{
		OSL_ENSURE( 0, "### couln't get ProcessServiceFactory\n" );
	}

	mxSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
		( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
	if( !mxSFI.is() )
	{
		OSL_ENSURE( 0, "### couln't create SimpleFileAccess component\n" );
	}

	mxStringSubstitution = Reference< XStringSubstitution >( mxMSF->createInstance
		( OUString::createFromAscii( "com.sun.star.util.PathSubstitution" ) ), UNO_QUERY );
	if( !mxStringSubstitution.is() )
	{
		OSL_ENSURE( 0, "### couln't create PathSubstitution component\n" );
	}
}

SfxLibraryContainer::~SfxLibraryContainer()
{
    if( mbOwnBasMgr )
        BasicManager::LegacyDeleteBasicManager( mpBasMgr );
    DBG_DTOR( SfxLibraryContainer, NULL );
}

void SfxLibraryContainer::checkDisposed() const
{
    if ( isDisposed() )
        throw DisposedException( ::rtl::OUString(), *const_cast< SfxLibraryContainer* >( this ) );
}

void SfxLibraryContainer::enterMethod()
{
    maMutex.acquire();
    checkDisposed();
}

void SfxLibraryContainer::leaveMethod()
{
    maMutex.release();
}

BasicManager* SfxLibraryContainer::getBasicManager( void )
{
    if ( mpBasMgr )
        return mpBasMgr;

    Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
    OSL_ENSURE( xDocument.is(), "SfxLibraryContainer::getBasicManager: cannot obtain a BasicManager without document!" );
    if ( xDocument.is() )
        mpBasMgr = BasicManagerRepository::getDocumentBasicManager( xDocument );

    return mpBasMgr;
}

// Methods XStorageBasedLibraryContainer
Reference< XStorage > SAL_CALL SfxLibraryContainer::getRootStorage() throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    return mxStorage;
}

void SAL_CALL SfxLibraryContainer::setRootStorage( const Reference< XStorage >& _rxRootStorage ) throw (IllegalArgumentException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    if ( !_rxRootStorage.is() )
        throw IllegalArgumentException();

	mxStorage = _rxRootStorage;
	onNewRootStorage();
}

void SAL_CALL SfxLibraryContainer::storeLibrariesToStorage( const Reference< XStorage >& _rxRootStorage ) throw (IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    if ( !_rxRootStorage.is() )
        throw IllegalArgumentException();

    try
    {
        storeLibraries_Impl( _rxRootStorage, sal_True );
    }
    catch( const Exception& )
    {
        throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
    }
}


// Methods XModifiable
sal_Bool SfxLibraryContainer::isModified() throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	if ( maModifiable.isModified() )
		return sal_True;

	// the library container is not modified, go through the libraries and check whether they are modified
	Sequence< OUString > aNames = maNameContainer.getElementNames();
	const OUString* pNames = aNames.getConstArray();
	sal_Int32 nNameCount = aNames.getLength();

	for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
	{
		OUString aName = pNames[ i ];
        SfxLibrary* pImplLib = getImplLib( aName );
		if( pImplLib->isModified() )
		{
			if ( aName.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ) ) )
			{
				// this is a workaround that has to be implemented because
				// empty standard library should stay marked as modified
				// but should not be treated as modified while it is empty
				if ( pImplLib->hasElements() )
					return sal_True;
			}
			else
				return sal_True;
		}
	}

	return sal_False;
}

void SAL_CALL SfxLibraryContainer::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    maModifiable.setModified( _bModified );
}

void SAL_CALL SfxLibraryContainer::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    maModifiable.addModifyListener( _rxListener );
}

void SAL_CALL SfxLibraryContainer::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    maModifiable.removeModifyListener( _rxListener );
}

// Methods XPersistentLibraryContainer
Any SAL_CALL SfxLibraryContainer::getRootLocation() throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    return makeAny( getRootStorage() );
}

::rtl::OUString SAL_CALL SfxLibraryContainer::getContainerLocationName() throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    return maLibrariesDir;
}

void SAL_CALL SfxLibraryContainer::storeLibraries(  ) throw (WrappedTargetException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    try
    {
	    storeLibraries_Impl( mxStorage, mxStorage.is()  );
        // we need to store *all* libraries if and only if we are based on a storage:
        // in this case, storeLibraries_Impl will remove the source storage, after loading
        // all libraries, so we need to force them to be stored, again
    }
    catch( const Exception& )
    {
        throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
    }
}

static void checkAndCopyFileImpl( const INetURLObject& rSourceFolderInetObj,
								  const INetURLObject& rTargetFolderInetObj,
								  const OUString& rCheckFileName,
								  const OUString& rCheckExtension,
								  Reference< XSimpleFileAccess > xSFI )
{
	INetURLObject aTargetFolderInetObj( rTargetFolderInetObj );
	aTargetFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
									 sal_True, INetURLObject::ENCODE_ALL );
	aTargetFolderInetObj.setExtension( rCheckExtension );
	OUString aTargetFile = aTargetFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
	if( !xSFI->exists( aTargetFile ) )
	{
		INetURLObject aSourceFolderInetObj( rSourceFolderInetObj );
		aSourceFolderInetObj.insertName( rCheckFileName, sal_True, INetURLObject::LAST_SEGMENT,
										 sal_True, INetURLObject::ENCODE_ALL );
		aSourceFolderInetObj.setExtension( rCheckExtension );
		OUString aSourceFile = aSourceFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );
		xSFI->copy( aSourceFile, aTargetFile );
	}
}

static void createVariableURL( OUString& rStr, const OUString& rLibName,
							   const OUString& rInfoFileName, bool bUser )
{
	if( bUser )
		rStr = OUString::createFromAscii( "$(USER)/basic/" );
	else
		rStr = OUString::createFromAscii( "$(INST)/share/basic/" );

	rStr += rLibName;
	rStr += OUString::createFromAscii( "/" );
	rStr += rInfoFileName;
	rStr += OUString::createFromAscii( ".xlb/" );
}

sal_Bool SfxLibraryContainer::init( const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
{
    // this might be called from within the ctor, and the impl_init might (indirectly) create
    // an UNO reference to ourself.
    // Ensure that we're not destroyed while we're in here
    osl_incrementInterlockedCount( &m_refCount );
    sal_Bool bSuccess = init_Impl( rInitialDocumentURL, rxInitialStorage );
    osl_decrementInterlockedCount( &m_refCount );

    return bSuccess;
}

sal_Bool SfxLibraryContainer::init_Impl(
    const OUString& rInitialDocumentURL, const uno::Reference< embed::XStorage >& rxInitialStorage )
{
	uno::Reference< embed::XStorage > xStorage = rxInitialStorage;

    maInitialDocumentURL = rInitialDocumentURL;
    maInfoFileName = OUString::createFromAscii( getInfoFileName() );
	maOldInfoFileName = OUString::createFromAscii( getOldInfoFileName() );
	maLibElementFileExtension = OUString::createFromAscii( getLibElementFileExtension() );
	maLibrariesDir = OUString::createFromAscii( getLibrariesDir() );

    meInitMode = DEFAULT;
    INetURLObject aInitUrlInetObj( maInitialDocumentURL );
    OUString aInitFileName = aInitUrlInetObj.GetMainURL( INetURLObject::NO_DECODE );
    if( !aInitFileName.isEmpty() )
    {
        // We need a BasicManager to avoid problems
        StarBASIC* pBas = new StarBASIC();
        mpBasMgr = new BasicManager( pBas );
        mbOwnBasMgr = sal_True;

        OUString aExtension = aInitUrlInetObj.getExtension();
        if( aExtension.compareToAscii( "xlc" ) == COMPARE_EQUAL )
        {
            meInitMode = CONTAINER_INIT_FILE;
	        INetURLObject aLibPathInetObj( aInitUrlInetObj );
			aLibPathInetObj.removeSegment();
	        maLibraryPath = aLibPathInetObj.GetMainURL( INetURLObject::NO_DECODE );
        }
        else if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
        {
            meInitMode = LIBRARY_INIT_FILE;
        	uno::Reference< embed::XStorage > xDummyStor;
            ::xmlscript::LibDescriptor aLibDesc;
            sal_Bool bReadIndexFile = implLoadLibraryIndexFile( NULL, aLibDesc, xDummyStor, aInitFileName );
           	return bReadIndexFile;
        }
        else
        {
            // Decide between old and new document
            sal_Bool bOldStorage = SotStorage::IsOLEStorage( aInitFileName );
            if ( bOldStorage )
            {
                meInitMode = OLD_BASIC_STORAGE;
                importFromOldStorage( aInitFileName );
                return sal_True;
            }
            else
            {
                meInitMode = OFFICE_DOCUMENT;
                try
                {
                    xStorage = ::comphelper::OStorageHelper::GetStorageFromURL( aInitFileName, embed::ElementModes::READ );
                }
                catch ( uno::Exception& )
                {
                    // TODO: error handling
                }
            }
        }
    }
    else
    {
        // Default paths
        maLibraryPath = SvtPathOptions().GetBasicPath();
    }

	Reference< XParser > xParser( mxMSF->createInstance(
		OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
	if( !xParser.is() )
	{
		OSL_ENSURE( 0, "### couln't create sax parser component\n" );
		return sal_False;
	}

	uno::Reference< io::XInputStream > xInput;

	mxStorage = xStorage;
	sal_Bool bStorage = mxStorage.is();


	// #110009: Scope to force the StorageRefs to be destructed and
	// so the streams to be closed before the preload operation
	{
	// #110009

	uno::Reference< embed::XStorage > xLibrariesStor;
	String aFileName;

	int nPassCount = 1;
	if( !bStorage && meInitMode == DEFAULT )
		nPassCount = 2;
	for( int nPass = 0 ; nPass < nPassCount ; nPass++ )
	{
		if( bStorage )
		{
			OSL_ENSURE( meInitMode == DEFAULT || meInitMode == OFFICE_DOCUMENT,
				"### Wrong InitMode for document\n" );
			try
			{
				uno::Reference< io::XStream > xStream;
				xLibrariesStor = xStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
                //if ( !xLibrariesStor.is() )
                    // TODO: the method must either return a storage or throw an exception
                    //throw uno::RuntimeException();

                if ( xLibrariesStor.is() )
                {
                    aFileName = maInfoFileName;
                    aFileName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );

                    try
                    {
                        xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
                    }
                    catch( uno::Exception& )
                    {}

                    if( !xStream.is() )
                    {
                        mbOldInfoFormat = true;

                        // Check old version
                        aFileName = maOldInfoFileName;
                        aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );

                        try
                        {
                            xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
                        }
                        catch( uno::Exception& )
                        {}

                        if( !xStream.is() )
                        {
                            // Check for EA2 document version with wrong extensions
                            aFileName = maOldInfoFileName;
                            aFileName += String( RTL_CONSTASCII_USTRINGPARAM(".xli") );
                            xStream = xLibrariesStor->openStreamElement( aFileName, embed::ElementModes::READ );
                        }
                    }
				}

				if ( xStream.is() )
					xInput = xStream->getInputStream();
			}
			catch( uno::Exception& )
			{
                // TODO: error handling?
			}
		}
		else
		{
			INetURLObject* pLibInfoInetObj = NULL;
			if( meInitMode == CONTAINER_INIT_FILE )
			{
				aFileName = aInitFileName;
			}
			else
			{
				if( nPass == 1 )
					pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(0) );
				else
					pLibInfoInetObj = new INetURLObject( String(maLibraryPath).GetToken(1) );
				pLibInfoInetObj->insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				pLibInfoInetObj->setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
				aFileName = pLibInfoInetObj->GetMainURL( INetURLObject::NO_DECODE );
			}

			try
			{
				xInput = mxSFI->openFileRead( aFileName );
			}
			catch( Exception& )
			{
				xInput.clear();
                if( nPass == 0 )
                {
		            SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
                    sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
                    ErrorHandler::HandleError( nErrorCode );
                }
			}

			// Old variant?
			if( !xInput.is() && nPass == 0 )
			{
				INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
				aLibInfoInetObj.insertName( maOldInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xli") ) );
				aFileName = aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );

				try
				{
					xInput = mxSFI->openFileRead( aFileName );
					mbOldInfoFormat = true;
				}
				catch( Exception& )
				{
    				xInput.clear();
		            SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aFileName );
                    sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
                    ErrorHandler::HandleError( nErrorCode );
				}
			}

			delete pLibInfoInetObj;
		}

		if( xInput.is() )
        {
		    InputSource source;
		    source.aInputStream = xInput;
		    source.sSystemId 	= aFileName;

		    // start parsing
		    ::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray();

            try
            {
                xParser->setDocumentHandler( ::xmlscript::importLibraryContainer( pLibArray ) );
                xParser->parseStream( source );
            }
            catch ( xml::sax::SAXException& e )
            {
                (void) e; // avoid warning
                OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
                return sal_False;
            }
            catch ( io::IOException& e )
            {
                (void) e; // avoid warning
                OSL_ENSURE( 0, OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
                return sal_False;
            }

		    sal_Int32 nLibCount = pLibArray->mnLibCount;
		    for( sal_Int32 i = 0 ; i < nLibCount ; i++ )
		    {
			    ::xmlscript::LibDescriptor& rLib = pLibArray->mpLibs[i];

			    // Check storage URL
			    OUString aStorageURL = rLib.aStorageURL;
			    if( !bStorage && aStorageURL.isEmpty() && nPass == 0 )
			    {
					String aLibraryPath;
					if( meInitMode == CONTAINER_INIT_FILE )
						aLibraryPath = maLibraryPath;
					else
						aLibraryPath = String(maLibraryPath).GetToken(1);
					INetURLObject aInetObj( aLibraryPath );

				    aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
					    sal_True, INetURLObject::ENCODE_ALL );
				    OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
				    if( mxSFI->isFolder( aLibDirPath ) )
				    {
						createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, true );
                        maModifiable.setModified( sal_True );
				    }
				    else if( rLib.bLink )
				    {
					    // Check "share" path
					    INetURLObject aShareInetObj( String(maLibraryPath).GetToken(0) );
					    aShareInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT,
						    sal_True, INetURLObject::ENCODE_ALL );
					    OUString aShareLibDirPath = aShareInetObj.GetMainURL( INetURLObject::NO_DECODE );
					    if( mxSFI->isFolder( aShareLibDirPath ) )
					    {
							createVariableURL( rLib.aStorageURL, rLib.aName, maInfoFileName, false );
                            maModifiable.setModified( sal_True );
					    }
						else
						{
							// #i25537: Ignore lib if library folder does not really exist
							continue;
						}
				    }
			    }

			    OUString aLibName = rLib.aName;

			    // If the same library name is used by the shared and the
			    // user lib container index files the user file wins
			    if( nPass == 1 && hasByName( aLibName ) )
				    continue;

			    SfxLibrary* pImplLib;
			    if( rLib.bLink )
			    {
				    Reference< XNameAccess > xLib =
					    createLibraryLink( aLibName, rLib.aStorageURL, rLib.bReadOnly );
				    pImplLib = static_cast< SfxLibrary* >( xLib.get() );
			    }
			    else
			    {
				    Reference< XNameContainer > xLib = createLibrary( aLibName );
				    pImplLib = static_cast< SfxLibrary* >( xLib.get() );
				    pImplLib->mbLoaded = sal_False;
				    pImplLib->mbReadOnly = rLib.bReadOnly;
				    if( !bStorage )
					    checkStorageURL( rLib.aStorageURL, pImplLib->maLibInfoFileURL,
                            pImplLib->maStorageURL, pImplLib->maUnexpandedStorageURL );
			    }
				maModifiable.setModified( sal_False );

			    // Read library info files
			    if( !mbOldInfoFormat )
			    {
        		    uno::Reference< embed::XStorage > xLibraryStor;
          		    if( !pImplLib->mbInitialised && bStorage )
				    {
						try {
							xLibraryStor = xLibrariesStor->openStorageElement( rLib.aName,
																				embed::ElementModes::READ );
						}
						catch( uno::Exception& )
						{
                        #if OSL_DEBUG_LEVEL > 0
                            Any aError( ::cppu::getCaughtException() );
                            ::rtl::OStringBuffer aMessage;
                            aMessage.append( "couln't open sub storage for library '" );
                            aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
                            aMessage.append( "'.\n\nException:" );
                            aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
			                OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
                        #endif
						}
				    }

				    // Link is already initialised in createLibraryLink()
				    if( !pImplLib->mbInitialised && (!bStorage || xLibraryStor.is()) )
				    {
					    OUString aIndexFileName;
					    sal_Bool bLoaded = implLoadLibraryIndexFile( pImplLib, rLib, xLibraryStor, aIndexFileName );
					    if( bLoaded && aLibName != rLib.aName )
					    {
						    OSL_ENSURE( 0, "Different library names in library"
							    " container and library info files!\n" );
					    }
						if( GbMigrationSuppressErrors && !bLoaded )
							removeLibrary( aLibName );
				    }
			    }
			    else if( !bStorage )
			    {
				    // Write new index file immediately because otherwise
				    // the library elements will be lost when storing into
				    // the new info format
				    uno::Reference< embed::XStorage > xTmpStorage;
				    implStoreLibraryIndexFile( pImplLib, rLib, xTmpStorage );
			    }

			    implImportLibDescriptor( pImplLib, rLib );

			    if( nPass == 1 )
			    {
				    pImplLib->mbSharedIndexFile = sal_True;
				    pImplLib->mbReadOnly = sal_True;
			    }
		    }

		    // Keep flag for documents to force writing the new index files
		    if( !bStorage )
			    mbOldInfoFormat = sal_False;

		    delete pLibArray;
        }
		// Only in the first pass it's an error when no index file is found
		else if( nPass == 0 )
		{
			return sal_False;
		}
	}

	// #110009: END Scope to force the StorageRefs to be destructed
	}
	// #110009

	if( !bStorage && meInitMode == DEFAULT )
    {
        try
        {
            implScanExtensions();
        }
        catch( uno::Exception& )
        {
            // TODO: error handling?
            OSL_ASSERT( "Cannot access extensions!" );
        }
    }

	// #110009 Preload?
    {
	    Sequence< OUString > aNames = maNameContainer.getElementNames();
	    const OUString* pNames = aNames.getConstArray();
	    sal_Int32 nNameCount = aNames.getLength();
	    for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
	    {
		    OUString aName = pNames[ i ];
            SfxLibrary* pImplLib = getImplLib( aName );
		    if( pImplLib->mbPreload )
			    loadLibrary( aName );
	    }
    }

	// #118803# upgrade installation 7.0 -> 8.0
	if( meInitMode == DEFAULT )
	{
		INetURLObject aUserBasicInetObj( String(maLibraryPath).GetToken(1) );
		OUString aStandardStr( RTL_CONSTASCII_USTRINGPARAM("Standard") );

		static char strPrevFolderName_1[] = "__basic_80";
		static char strPrevFolderName_2[] = "__basic_80_2";
		INetURLObject aPrevUserBasicInetObj_1( aUserBasicInetObj );
		aPrevUserBasicInetObj_1.removeSegment();
		INetURLObject aPrevUserBasicInetObj_2 = aPrevUserBasicInetObj_1;
		aPrevUserBasicInetObj_1.Append( strPrevFolderName_1 );
		aPrevUserBasicInetObj_2.Append( strPrevFolderName_2 );

		// #i93163
		bool bCleanUp = false;
		try
		{
			INetURLObject aPrevUserBasicInetObj = aPrevUserBasicInetObj_1;
			String aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
			bool bSecondTime = false;
			if( mxSFI->isFolder( aPrevFolder ) )
			{
				// #110101 Check if Standard folder exists and is complete
				INetURLObject aUserBasicStandardInetObj( aUserBasicInetObj );
				aUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
													  sal_True, INetURLObject::ENCODE_ALL );
				INetURLObject aPrevUserBasicStandardInetObj( aPrevUserBasicInetObj );
				aPrevUserBasicStandardInetObj.insertName( aStandardStr, sal_True, INetURLObject::LAST_SEGMENT,
														sal_True, INetURLObject::ENCODE_ALL );
				OUString aPrevStandardFolder = aPrevUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
				if( mxSFI->isFolder( aPrevStandardFolder ) )
				{
					OUString aXlbExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
					OUString aCheckFileName;

					// Check if script.xlb exists
					aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("script") );
					checkAndCopyFileImpl( aUserBasicStandardInetObj,
										  aPrevUserBasicStandardInetObj,
										  aCheckFileName, aXlbExtension, mxSFI );

					// Check if dialog.xlb exists
					aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("dialog") );
					checkAndCopyFileImpl( aUserBasicStandardInetObj,
										  aPrevUserBasicStandardInetObj,
										  aCheckFileName, aXlbExtension, mxSFI );

					// Check if module1.xba exists
					OUString aXbaExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xba") ) );
					aCheckFileName = OUString( RTL_CONSTASCII_USTRINGPARAM("Module1") );
					checkAndCopyFileImpl( aUserBasicStandardInetObj,
										  aPrevUserBasicStandardInetObj,
										  aCheckFileName, aXbaExtension, mxSFI );
				}
				else
				{
					String aStandardFolder = aUserBasicStandardInetObj.GetMainURL( INetURLObject::NO_DECODE );
					mxSFI->copy( aStandardFolder, aPrevStandardFolder );
				}

				String aPrevCopyToFolder = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
				mxSFI->copy( aPrevFolder, aPrevCopyToFolder );
			}
			else
			{
				bSecondTime = true;
				aPrevUserBasicInetObj = aPrevUserBasicInetObj_2;
				aPrevFolder = aPrevUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
			}
			if( mxSFI->isFolder( aPrevFolder ) )
			{
				SfxLibraryContainer* pPrevCont = createInstanceImpl();
				Reference< XInterface > xRef = static_cast< XInterface* >( static_cast< OWeakObject* >(pPrevCont) );

				// Rename previous basic folder to make storage URLs correct during initialisation
				String aFolderUserBasic = aUserBasicInetObj.GetMainURL( INetURLObject::NO_DECODE );
				INetURLObject aUserBasicTmpInetObj( aUserBasicInetObj );
				aUserBasicTmpInetObj.removeSegment();
				aUserBasicTmpInetObj.Append( "__basic_tmp" );
				String aFolderTmp = aUserBasicTmpInetObj.GetMainURL( INetURLObject::NO_DECODE );

				mxSFI->move( aFolderUserBasic, aFolderTmp );
				try
				{
					mxSFI->move( aPrevFolder, aFolderUserBasic );
				}
				catch( Exception& )
				{
					// Move back user/basic folder
					try
					{
           				mxSFI->kill( aFolderUserBasic );
					}
					catch( Exception& )
					{}
					mxSFI->move( aFolderTmp, aFolderUserBasic );
					throw;
				}

				INetURLObject aPrevUserBasicLibInfoInetObj( aUserBasicInetObj );
				aPrevUserBasicLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT,
													sal_True, INetURLObject::ENCODE_ALL );
				aPrevUserBasicLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
				OUString aLibInfoFileName = aPrevUserBasicLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE );
				Sequence<Any> aInitSeq( 1 );
				aInitSeq.getArray()[0] <<= aLibInfoFileName;
				GbMigrationSuppressErrors = true;
				pPrevCont->initialize( aInitSeq );
				GbMigrationSuppressErrors = false;

				// Rename folders back
				mxSFI->move( aFolderUserBasic, aPrevFolder );
				mxSFI->move( aFolderTmp, aFolderUserBasic );

				OUString aUserSearchStr   = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
				OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
            	OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
				OUString aInstSearchStr   = OUString::createFromAscii( "$(INST)" );

				Sequence< OUString > aNames = pPrevCont->getElementNames();
				const OUString* pNames = aNames.getConstArray();
				sal_Int32 nNameCount = aNames.getLength();

				for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
				{
					OUString aLibName = pNames[ i ];
					if( hasByName( aLibName ) )
					{
						if( aLibName == aStandardStr )
						{
							SfxLibrary* pImplLib = getImplLib( aStandardStr );
							INetURLObject aStandardFolderInetObj( pImplLib->maStorageURL );
							String aStandardFolder = pImplLib->maStorageURL;
            				mxSFI->kill( aStandardFolder );
						}
						else
						{
							continue;
						}
					}

					SfxLibrary* pImplLib = pPrevCont->getImplLib( aLibName );
					if( pImplLib->mbLink )
					{
						OUString aStorageURL = pImplLib->maUnexpandedStorageURL;
						bool bCreateLink = true;
						if( aStorageURL.indexOf( aUserSearchStr   ) != -1 ||
							aStorageURL.indexOf( aSharedSearchStr ) != -1 ||
							aStorageURL.indexOf( aBundledSearchStr ) != -1 ||
							aStorageURL.indexOf( aInstSearchStr   ) != -1 )
						{
							bCreateLink = false;
						}
						if( bCreateLink )
							createLibraryLink( aLibName, pImplLib->maStorageURL, pImplLib->mbReadOnly );
					}
					else
					{
						// Move folder if not already done
						INetURLObject aUserBasicLibFolderInetObj( aUserBasicInetObj );
    					aUserBasicLibFolderInetObj.Append( aLibName );
						String aLibFolder = aUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );

						INetURLObject aPrevUserBasicLibFolderInetObj( aPrevUserBasicInetObj );
    					aPrevUserBasicLibFolderInetObj.Append( aLibName );
						String aPrevLibFolder = aPrevUserBasicLibFolderInetObj.GetMainURL( INetURLObject::NO_DECODE );

						if( mxSFI->isFolder( aPrevLibFolder ) && !mxSFI->isFolder( aLibFolder ) )
							mxSFI->move( aPrevLibFolder, aLibFolder );

						if( aLibName == aStandardStr )
                   			maNameContainer.removeByName( aLibName );

						// Create library
						Reference< XNameContainer > xLib = createLibrary( aLibName );
           				SfxLibrary* pNewLib = static_cast< SfxLibrary* >( xLib.get() );
						pNewLib->mbLoaded = false;
						pNewLib->implSetModified( sal_False );
						checkStorageURL( aLibFolder, pNewLib->maLibInfoFileURL,
							pNewLib->maStorageURL, pNewLib->maUnexpandedStorageURL );

						uno::Reference< embed::XStorage > xDummyStor;
						::xmlscript::LibDescriptor aLibDesc;
						/*sal_Bool bReadIndexFile =*/ implLoadLibraryIndexFile
							( pNewLib, aLibDesc, xDummyStor, pNewLib->maLibInfoFileURL );
						implImportLibDescriptor( pNewLib, aLibDesc );
					}
				}
				mxSFI->kill( aPrevFolder );
			}
		}
		catch( Exception& )
		{
			bCleanUp = true;
		}

		// #i93163
		if( bCleanUp )
		{
			DBG_ERROR( "Upgrade of Basic installation failed somehow" );

			static char strErrorSavFolderName[] = "__basic_80_err";
			INetURLObject aPrevUserBasicInetObj_Err( aUserBasicInetObj );
			aPrevUserBasicInetObj_Err.removeSegment();
			aPrevUserBasicInetObj_Err.Append( strErrorSavFolderName );
			String aPrevFolder_Err = aPrevUserBasicInetObj_Err.GetMainURL( INetURLObject::NO_DECODE );

			bool bSaved = false;
			try
			{
				String aPrevFolder_1 = aPrevUserBasicInetObj_1.GetMainURL( INetURLObject::NO_DECODE );
				if( mxSFI->isFolder( aPrevFolder_1 ) )
				{
					mxSFI->move( aPrevFolder_1, aPrevFolder_Err );
					bSaved = true;
				}
			}
			catch( Exception& )
			{}
			try
			{
				String aPrevFolder_2 = aPrevUserBasicInetObj_2.GetMainURL( INetURLObject::NO_DECODE );
				if( !bSaved && mxSFI->isFolder( aPrevFolder_2 ) )
					mxSFI->move( aPrevFolder_2, aPrevFolder_Err );
				else
					mxSFI->kill( aPrevFolder_2 );
			}
			catch( Exception& )
			{}
		}
	}

	return sal_True;
}

void SfxLibraryContainer::implScanExtensions( void )
{
	ScriptExtensionIterator aScriptIt;
	rtl::OUString aLibURL;

	bool bPureDialogLib = false;
	while( (aLibURL = aScriptIt.nextBasicOrDialogLibrary( bPureDialogLib )).isEmpty() == false )
	{
		if( bPureDialogLib && maInfoFileName.equalsAscii( "script" ) )
			continue;

		// Extract lib name
		sal_Int32 nLen = aLibURL.getLength();
		sal_Int32 indexLastSlash = aLibURL.lastIndexOf( '/' );
		sal_Int32 nReduceCopy = 0;
		if( indexLastSlash == nLen - 1 )
		{
			nReduceCopy = 1;
			indexLastSlash = aLibURL.lastIndexOf( '/', nLen - 1 );
		}

		OUString aLibName = aLibURL.copy( indexLastSlash + 1, nLen - indexLastSlash - nReduceCopy - 1 );

	    // If a library of the same exists the existing library wins
	    if( hasByName( aLibName ) )
		    continue;

		// Add index file to URL
		OUString aIndexFileURL = aLibURL;
		if( nReduceCopy == 0 )
			aIndexFileURL += OUString::createFromAscii( "/" );
		aIndexFileURL += maInfoFileName;
		aIndexFileURL += OUString::createFromAscii( ".xlb" );

		// Create link
		const bool bReadOnly = false;
	    Reference< XNameAccess > xLib =
		    createLibraryLink( aLibName, aIndexFileURL, bReadOnly );
    }
}

// Handle maLibInfoFileURL and maStorageURL correctly
void SfxLibraryContainer::checkStorageURL( const OUString& aSourceURL,
    OUString& aLibInfoFileURL, OUString& aStorageURL, OUString& aUnexpandedStorageURL )
{
    OUString aExpandedSourceURL = expand_url( aSourceURL );
    if( aExpandedSourceURL != aSourceURL )
        aUnexpandedStorageURL = aSourceURL;

	INetURLObject aInetObj( aExpandedSourceURL );
    OUString aExtension = aInetObj.getExtension();
    if( aExtension.compareToAscii( "xlb" ) == COMPARE_EQUAL )
    {
        // URL to xlb file
		aLibInfoFileURL = aExpandedSourceURL;
        aInetObj.removeSegment();
		aStorageURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
    }
    else
    {
        // URL to library folder
        aStorageURL = aExpandedSourceURL;
		aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
		aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
		aLibInfoFileURL = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
    }
}

SfxLibrary* SfxLibraryContainer::getImplLib( const String& rLibraryName )
{
	Any aLibAny = maNameContainer.getByName( rLibraryName ) ;
	Reference< XNameAccess > xNameAccess;
	aLibAny >>= xNameAccess;
	SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
    return pImplLib;
}


// Storing with password encryption

// Empty implementation, avoids unnecessary implementation in dlgcont.cxx
sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
    SfxLibrary*,
    const OUString&,
    const uno::Reference< embed::XStorage >&, const uno::Reference< task::XInteractionHandler >&  )
{
    return sal_False;
}

sal_Bool SfxLibraryContainer::implStorePasswordLibrary(
    SfxLibrary* /*pLib*/,
    const ::rtl::OUString& /*aName*/,
    const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& /*xStorage*/,
    const ::rtl::OUString& /*aTargetURL*/,
    const Reference< XSimpleFileAccess > /*xToUseSFI*/,
    const uno::Reference< task::XInteractionHandler >&  )
{
    return sal_False;
}

sal_Bool SfxLibraryContainer::implLoadPasswordLibrary(
    SfxLibrary* /*pLib*/,
    const OUString& /*Name*/,
    sal_Bool /*bVerifyPasswordOnly*/ )
throw(WrappedTargetException, RuntimeException)
{
    return sal_True;
}



#define EXPAND_PROTOCOL "vnd.sun.star.expand"
#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )

OUString SfxLibraryContainer::createAppLibraryFolder
    ( SfxLibrary* pLib, const OUString& aName )
{
	OUString aLibDirPath = pLib->maStorageURL;
	if( aLibDirPath.isEmpty() )
    {
		INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
		aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
        checkStorageURL( aInetObj.GetMainURL( INetURLObject::NO_DECODE ), pLib->maLibInfoFileURL,
            pLib->maStorageURL, pLib->maUnexpandedStorageURL );
		aLibDirPath = pLib->maStorageURL;
    }

	if( !mxSFI->isFolder( aLibDirPath ) )
    {
	    try
	    {
		    mxSFI->createFolder( aLibDirPath );
        }
        catch( Exception& )
        {}
    }

    return aLibDirPath;
}

// Storing
void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
	const OUString& aName, const uno::Reference< embed::XStorage >& xStorage )
{
	OUString aDummyLocation;
	Reference< XSimpleFileAccess > xDummySFA;
	Reference< XInteractionHandler > xDummyHandler;
	implStoreLibrary( pLib, aName, xStorage, aDummyLocation, xDummySFA, xDummyHandler );
}

// New variant for library export
void SfxLibraryContainer::implStoreLibrary( SfxLibrary* pLib,
	const OUString& aName, const uno::Reference< embed::XStorage >& xStorage,
	const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI,
	const Reference< XInteractionHandler >& xHandler )
{
	sal_Bool bLink = pLib->mbLink;
	sal_Bool bStorage = xStorage.is() && !bLink;

	Sequence< OUString > aElementNames = pLib->getElementNames();
	sal_Int32 nNameCount = aElementNames.getLength();
	const OUString* pNames = aElementNames.getConstArray();

	if( bStorage )
	{
		for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
		{
			OUString aElementName = pNames[ i ];

			OUString aStreamName = aElementName;
			aStreamName += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );

			/*Any aElement = pLib->getByName( aElementName );*/
			if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
            {
            #if OSL_DEBUG_LEVEL > 0
                ::rtl::OStringBuffer aMessage;
                aMessage.append( "invalid library element '" );
                aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
                aMessage.append( "'." );
			    OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
            #endif
                continue;
            }
			try {
				uno::Reference< io::XStream > xElementStream = xStorage->openStreamElement(
																	aStreamName,
																	embed::ElementModes::READWRITE );
                //if ( !xElementStream.is() )
                //    throw uno::RuntimeException(); // TODO: method must either return the stream or throw an exception

				String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
				OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );

				uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
				OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
                //if ( !xProps.is() ) //TODO
                //    throw uno::RuntimeException();

                if ( xProps.is() )
                {
                    xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );

                    // #87671 Allow encryption
//REMOVE	                        aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
                    aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
                    xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );

                    Reference< XOutputStream > xOutput = xElementStream->getOutputStream();
					Reference< XNameContainer > xLib( pLib );
                    writeLibraryElement( xLib, aElementName, xOutput );
					// writeLibraryElement closes the stream
                    // xOutput->closeOutput();
                }
			}
			catch( uno::Exception& )
			{
				OSL_ENSURE( sal_False, "Problem during storing of library!\n" );
                // TODO: error handling?
			}
		}

		pLib->storeResourcesToStorage( xStorage );
	}
	else
	{
		// Export?
		bool bExport = aTargetURL.getLength();
		try
		{
			Reference< XSimpleFileAccess > xSFI = mxSFI;
			if( xToUseSFI.is() )
				xSFI = xToUseSFI;

            OUString aLibDirPath;
			if( bExport )
			{
				INetURLObject aInetObj( aTargetURL );
				aInetObj.insertName( aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );

				if( !xSFI->isFolder( aLibDirPath ) )
					xSFI->createFolder( aLibDirPath );

				pLib->storeResourcesToURL( aLibDirPath, xHandler );
			}
			else
			{
	            aLibDirPath = createAppLibraryFolder( pLib, aName );
				pLib->storeResources();
			}

			for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
			{
				OUString aElementName = pNames[ i ];

				INetURLObject aElementInetObj( aLibDirPath );
				aElementInetObj.insertName( aElementName, sal_False,
					INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				aElementInetObj.setExtension( maLibElementFileExtension );
				String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );

				/*Any aElement = pLib->getByName( aElementName );*/
				if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
                {
                #if OSL_DEBUG_LEVEL > 0
                    ::rtl::OStringBuffer aMessage;
                    aMessage.append( "invalid library element '" );
                    aMessage.append( ::rtl::OUStringToOString( aElementName, osl_getThreadTextEncoding() ) );
                    aMessage.append( "'." );
			        OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
                #endif
                    continue;
                }

				// TODO: Check modified
	            try
	            {
				    if( xSFI->exists( aElementPath ) )
					    xSFI->kill( aElementPath );
					Reference< XOutputStream > xOutput = xSFI->openFileWrite( aElementPath );
					Reference< XNameContainer > xLib( pLib );
				    writeLibraryElement( xLib, aElementName, xOutput );
				    xOutput->closeOutput();
                }
        		catch( Exception& )
                {
					if( bExport )
						throw;

		            SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aElementPath );
                    sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
            	    ErrorHandler::HandleError( nErrorCode );
                }
			}
		}
		catch( Exception& )
		{
			if( bExport )
				throw;
		}
	}
}

void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
	const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage )
{
	OUString aDummyLocation;
	Reference< XSimpleFileAccess > xDummySFA;
	implStoreLibraryIndexFile( pLib, rLib, xStorage, aDummyLocation, xDummySFA );
}

// New variant for library export
void SfxLibraryContainer::implStoreLibraryIndexFile( SfxLibrary* pLib,
	const ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage,
	const ::rtl::OUString& aTargetURL, Reference< XSimpleFileAccess > xToUseSFI )
{
	// Create sax writer
	Reference< XExtendedDocumentHandler > xHandler(
		mxMSF->createInstance(
			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
	if( !xHandler.is() )
	{
		OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
		return;
	}

	sal_Bool bLink = pLib->mbLink;
	sal_Bool bStorage = xStorage.is() && !bLink;

	// Write info file
	uno::Reference< io::XOutputStream > xOut;
	uno::Reference< io::XStream > xInfoStream;
	if( bStorage )
	{
		OUString aStreamName( maInfoFileName );
		aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );

		try {
			xInfoStream = xStorage->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
            OSL_ENSURE( xInfoStream.is(), "No stream!\n" );
			uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
            //if ( !xProps.is() )
            //    throw uno::RuntimeException(); // TODO

            if ( xProps.is() )
            {
                String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
                OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
                xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );

                // #87671 Allow encryption
//REMOVE	                aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Encrypted") );
                aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
                xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );

                xOut = xInfoStream->getOutputStream();
            }
		}
		catch( uno::Exception& )
		{
			OSL_ENSURE( sal_False, "Problem during storing of library index file!\n" );
            // TODO: error handling?
		}
	}
	else
	{
		// Export?
		bool bExport = aTargetURL.getLength();
		Reference< XSimpleFileAccess > xSFI = mxSFI;
		if( xToUseSFI.is() )
			xSFI = xToUseSFI;

        OUString aLibInfoPath;
		if( bExport )
		{
			INetURLObject aInetObj( aTargetURL );
			aInetObj.insertName( rLib.aName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
			OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
			if( !xSFI->isFolder( aLibDirPath ) )
				xSFI->createFolder( aLibDirPath );

			aInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
			aInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlb") ) );
			aLibInfoPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
		}
		else
		{
			createAppLibraryFolder( pLib, rLib.aName );
			aLibInfoPath = pLib->maLibInfoFileURL;
		}

		try
		{
		    if( xSFI->exists( aLibInfoPath ) )
			    xSFI->kill( aLibInfoPath );
		    xOut = xSFI->openFileWrite( aLibInfoPath );
        }
        catch( Exception& )
        {
			if( bExport )
				throw;

			SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
            sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
            ErrorHandler::HandleError( nErrorCode );
        }
	}
	if( !xOut.is() )
	{
		OSL_ENSURE( 0, "### couln't open output stream\n" );
		return;
	}

	Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
	xSource->setOutputStream( xOut );

    xmlscript::exportLibrary( xHandler, rLib );
}


sal_Bool SfxLibraryContainer::implLoadLibraryIndexFile(  SfxLibrary* pLib,
    ::xmlscript::LibDescriptor& rLib, const uno::Reference< embed::XStorage >& xStorage, const OUString& aIndexFileName )
{
	Reference< XParser > xParser( mxMSF->createInstance(
		OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Parser") ) ), UNO_QUERY );
	if( !xParser.is() )
	{
		OSL_ENSURE( 0, "### couln't create sax parser component\n" );
		return sal_False;
	}

	sal_Bool bLink = sal_False;
	sal_Bool bStorage = sal_False;
    if( pLib )
    {
	    bLink = pLib->mbLink;
	    bStorage = xStorage.is() && !bLink;
    }

	// Read info file
	uno::Reference< io::XInputStream > xInput;
    String aLibInfoPath;
	if( bStorage )
	{
		aLibInfoPath = maInfoFileName;
		aLibInfoPath += String( RTL_CONSTASCII_USTRINGPARAM("-lb.xml") );

		try {
			uno::Reference< io::XStream > xInfoStream =
						xStorage->openStreamElement( aLibInfoPath, embed::ElementModes::READ );
			xInput = xInfoStream->getInputStream();
		}
		catch( uno::Exception& )
		{}
	}
	else
	{
		// Create Input stream
        //String aLibInfoPath; // attention: THIS PROBLEM MUST BE REVIEWED BY SCRIPTING OWNER!!!

        if( pLib )
        {
            createAppLibraryFolder( pLib, rLib.aName );
            aLibInfoPath = pLib->maLibInfoFileURL;
        }
        else
            aLibInfoPath = aIndexFileName;

		try
		{
			xInput = mxSFI->openFileRead( aLibInfoPath );
		}
		catch( Exception& )
		{
            xInput.clear();
			if( !GbMigrationSuppressErrors )
			{
				SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
				sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
				ErrorHandler::HandleError( nErrorCode );
			}
		}
	}
	if( !xInput.is() )
	{
		// OSL_ENSURE( 0, "### couln't open input stream\n" );
		return sal_False;
	}

	InputSource source;
	source.aInputStream = xInput;
	source.sSystemId 	= aLibInfoPath;

	// start parsing
	try {
		xParser->setDocumentHandler( ::xmlscript::importLibrary( rLib ) );
		xParser->parseStream( source );
	}
	catch( Exception& )
	{
		// throw WrappedTargetException( OUString::createFromAscii( "parsing error!\n" ),
		//								Reference< XInterface >(),
		//								makeAny( e ) );
		OSL_ENSURE( 0, "Parsing error\n" );
		SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC, aLibInfoPath );
        sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
        ErrorHandler::HandleError( nErrorCode );
		return sal_False;
	}

    if( !pLib )
    {
		Reference< XNameContainer > xLib = createLibrary( rLib.aName );
		pLib = static_cast< SfxLibrary* >( xLib.get() );
		pLib->mbLoaded = sal_False;
        rLib.aStorageURL = aIndexFileName;
        checkStorageURL( rLib.aStorageURL, pLib->maLibInfoFileURL, pLib->maStorageURL,
            pLib->maUnexpandedStorageURL );

        implImportLibDescriptor( pLib, rLib );
    }

    return sal_True;
}

void SfxLibraryContainer::implImportLibDescriptor
    ( SfxLibrary* pLib, ::xmlscript::LibDescriptor& rLib )
{
    if( !pLib->mbInitialised )
    {
	    sal_Int32 nElementCount = rLib.aElementNames.getLength();
	    const OUString* pElementNames = rLib.aElementNames.getConstArray();
	    Any aDummyElement = createEmptyLibraryElement();
	    for( sal_Int32 i = 0 ; i < nElementCount ; i++ )
	    {
		    pLib->maNameContainer.insertByName( pElementNames[i], aDummyElement );
	    }
        pLib->mbPasswordProtected = rLib.bPasswordProtected;
        pLib->mbReadOnly = rLib.bReadOnly;
		pLib->mbPreload  = rLib.bPreload;
        pLib->implSetModified( sal_False );

        pLib->mbInitialised = sal_True;
    }
}


// Methods of new XLibraryStorage interface?
void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XStorage >& i_rStorage, sal_Bool bComplete )
{
	const Sequence< OUString > aNames = maNameContainer.getElementNames();
	sal_Int32 nNameCount = aNames.getLength();
    const OUString* pName = aNames.getConstArray();
	const OUString* pNamesEnd = aNames.getConstArray() + nNameCount;

	// Don't count libs from shared index file
	sal_Int32 nLibsToSave = nNameCount;
	for( ; pName != pNamesEnd; ++pName )
	{
        SfxLibrary* pImplLib = getImplLib( *pName );
		if( pImplLib->mbSharedIndexFile || pImplLib->mbExtension )
			nLibsToSave--;
	}
    if( !nLibsToSave )
        return;

	::xmlscript::LibDescriptorArray* pLibArray = new ::xmlscript::LibDescriptorArray( nLibsToSave );

	// Write to storage?
	sal_Bool bStorage = i_rStorage.is();
	uno::Reference< embed::XStorage > xSourceLibrariesStor;
	uno::Reference< embed::XStorage > xTargetLibrariesStor;
    ::rtl::OUString sTempTargetStorName;
    const bool bInplaceStorage = bStorage && ( i_rStorage == mxStorage );
	if ( bStorage )
	{
        // Don't write if only empty standard lib exists
        if ( ( nNameCount == 1 ) && ( aNames[0].equalsAscii( "Standard" ) ) )
        {
		    Any aLibAny = maNameContainer.getByName( aNames[0] );
		    Reference< XNameAccess > xNameAccess;
		    aLibAny >>= xNameAccess;
            if ( !xNameAccess->hasElements() ){
                delete pLibArray;
                return;
            }
        }

        // create the empty target storage
        try
        {
            ::rtl::OUString sTargetLibrariesStoreName;
            if ( bInplaceStorage )
            {
                // create a temporary target storage
                const ::rtl::OUStringBuffer aTempTargetNameBase = maLibrariesDir + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_temp_" ) );
                sal_Int32 index = 0;
                do
                {
                    ::rtl::OUStringBuffer aTempTargetName( aTempTargetNameBase );
                    aTempTargetName.append( index++ );

                    sTargetLibrariesStoreName = aTempTargetName.makeStringAndClear();
                    if ( !i_rStorage->hasByName( sTargetLibrariesStoreName ) )
                        break;
                }
                while ( true );
                sTempTargetStorName = sTargetLibrariesStoreName;
            }
            else
            {
                sTargetLibrariesStoreName = maLibrariesDir;
			    if ( i_rStorage->hasByName( sTargetLibrariesStoreName ) )
				    i_rStorage->removeElement( sTargetLibrariesStoreName );
            }

            xTargetLibrariesStor.set( i_rStorage->openStorageElement( sTargetLibrariesStoreName, embed::ElementModes::READWRITE ), UNO_QUERY_THROW );
	    }
	    catch( const uno::Exception& )
	    {
            DBG_UNHANDLED_EXCEPTION();
		    return;
	    }

        // open the source storage which might be used to copy yet-unmodified libraries
		try
        {
            if ( mxStorage->hasByName( maLibrariesDir ) )
                xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, bInplaceStorage ? embed::ElementModes::READWRITE : embed::ElementModes::READ );
            else if ( bInplaceStorage )
                xSourceLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READWRITE );
		}
		catch( const uno::Exception& )
		{
            DBG_UNHANDLED_EXCEPTION();
			return;
        }
	}

	int iArray = 0;
	pName = aNames.getConstArray();
	::xmlscript::LibDescriptor aLibDescriptorForExtensionLibs;
    for( ; pName != pNamesEnd; ++pName )
	{
        SfxLibrary* pImplLib = getImplLib( *pName );
		if( pImplLib->mbSharedIndexFile )
			continue;
		const bool bExtensionLib = pImplLib->mbExtension;
		::xmlscript::LibDescriptor& rLib = bExtensionLib ?
			aLibDescriptorForExtensionLibs : pLibArray->mpLibs[iArray];
		if( !bExtensionLib )
			iArray++;
		rLib.aName = *pName;

		rLib.bLink = pImplLib->mbLink;
		if( !bStorage || pImplLib->mbLink )
		{
			rLib.aStorageURL = ( pImplLib->maUnexpandedStorageURL.getLength() ) ?
				pImplLib->maUnexpandedStorageURL : pImplLib->maLibInfoFileURL;
		}
		rLib.bReadOnly = pImplLib->mbReadOnly;
		rLib.bPreload = pImplLib->mbPreload;
		rLib.bPasswordProtected = pImplLib->mbPasswordProtected;
		rLib.aElementNames = pImplLib->getElementNames();

		if( pImplLib->implIsModified() || bComplete )
		{
            // Can we simply copy the storage?
            if( !mbOldInfoFormat && !pImplLib->implIsModified() && !mbOasis2OOoFormat && xSourceLibrariesStor.is() )
            {
				try
                {
                	xSourceLibrariesStor->copyElementTo( rLib.aName, xTargetLibrariesStor, rLib.aName );
				}
                catch( const uno::Exception& )
				{
                    DBG_UNHANDLED_EXCEPTION();
                    // TODO: error handling?
				}
            }
            else
            {
				uno::Reference< embed::XStorage > xLibraryStor;
				if( bStorage )
				{
					try
                    {
						xLibraryStor = xTargetLibrariesStor->openStorageElement(
																		rLib.aName,
																		embed::ElementModes::READWRITE );
					}
					catch( uno::Exception& )
					{
                    #if OSL_DEBUG_LEVEL > 0
                        Any aError( ::cppu::getCaughtException() );
                        ::rtl::OStringBuffer aMessage;
                        aMessage.append( "couln't create sub storage for library '" );
                        aMessage.append( ::rtl::OUStringToOString( rLib.aName, osl_getThreadTextEncoding() ) );
                        aMessage.append( "'.\n\nException:" );
                        aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
					    OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
                    #endif
						return;
					}
				}

				// Maybe lib is not loaded?!
				if( bComplete )
					loadLibrary( rLib.aName );

    			if( pImplLib->mbPasswordProtected )
				    implStorePasswordLibrary( pImplLib, rLib.aName, xLibraryStor, uno::Reference< task::XInteractionHandler >() );
                    // TODO: Check return value
                else
				    implStoreLibrary( pImplLib, rLib.aName, xLibraryStor );

                implStoreLibraryIndexFile( pImplLib, rLib, xLibraryStor );
				if( bStorage )
				{
					try
                    {
						uno::Reference< embed::XTransactedObject > xTransact( xLibraryStor, uno::UNO_QUERY_THROW );
						xTransact->commit();
					}
					catch( uno::Exception& )
					{
                        DBG_UNHANDLED_EXCEPTION();
                        // TODO: error handling
					}
				}
            }

			maModifiable.setModified( sal_True );
			pImplLib->implSetModified( sal_False );
		}

        // For container info ReadOnly refers to mbReadOnlyLink
		rLib.bReadOnly = pImplLib->mbReadOnlyLink;
	}

    // if we did an in-place save into a storage (i.e. a save into the storage we were already based on),
    // then we need to clean up the temporary storage we used for this
    if ( bInplaceStorage && !sTempTargetStorName.isEmpty() )
    {
        OSL_ENSURE( xSourceLibrariesStor.is(), "SfxLibrariesContainer::storeLibraries_impl: unexpected: we should have a source storage here!" );
        try
        {
            // for this, we first remove everything from the source storage, then copy the complete content
            // from the temporary target storage. From then on, what used to be the "source storage" becomes
            // the "targt storage" for all subsequent operations.

            // (We cannot simply remove the storage, denoted by maLibrariesDir, from i_rStorage - there might be
            // open references to it.)

            if ( xSourceLibrariesStor.is() )
            {
                // remove
                const Sequence< ::rtl::OUString > aRemoveNames( xSourceLibrariesStor->getElementNames() );
                for (   const ::rtl::OUString* pRemoveName = aRemoveNames.getConstArray();
                        pRemoveName != aRemoveNames.getConstArray() + aRemoveNames.getLength();
                            ++pRemoveName
                    )
                {
                    xSourceLibrariesStor->removeElement( *pRemoveName );
                }

                // copy
                const Sequence< ::rtl::OUString > aCopyNames( xTargetLibrariesStor->getElementNames() );
                for (   const ::rtl::OUString* pCopyName = aCopyNames.getConstArray();
                        pCopyName != aCopyNames.getConstArray() + aCopyNames.getLength();
                        ++pCopyName
                    )
                {
                	xTargetLibrariesStor->copyElementTo( *pCopyName, xSourceLibrariesStor, *pCopyName );
                }
            }

            // close and remove temp target
            xTargetLibrariesStor->dispose();
            i_rStorage->removeElement( sTempTargetStorName );
            xTargetLibrariesStor.clear();
            sTempTargetStorName = ::rtl::OUString();

            // adjust target
            xTargetLibrariesStor = xSourceLibrariesStor;
            xSourceLibrariesStor.clear();
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

	if( !mbOldInfoFormat && !maModifiable.isModified() )
		return;
	maModifiable.setModified( sal_False );
    mbOldInfoFormat = sal_False;

	// Write library container info
	// Create sax writer
	Reference< XExtendedDocumentHandler > xHandler(
		mxMSF->createInstance(
			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer") ) ), UNO_QUERY );
	if( !xHandler.is() )
	{
		OSL_ENSURE( 0, "### couln't create sax-writer component\n" );
		return;
	}

	// Write info file
	uno::Reference< io::XOutputStream > xOut;
	uno::Reference< io::XStream > xInfoStream;
	if( bStorage )
	{
		OUString aStreamName( maInfoFileName );
		aStreamName += String( RTL_CONSTASCII_USTRINGPARAM("-lc.xml") );

		try {
			xInfoStream = xTargetLibrariesStor->openStreamElement( aStreamName, embed::ElementModes::READWRITE );
			uno::Reference< beans::XPropertySet > xProps( xInfoStream, uno::UNO_QUERY );
			OSL_ENSURE ( xProps.is(), "The stream must implement XPropertySet!\n" );
			if ( !xProps.is() )
				throw uno::RuntimeException();

			String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
			OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
			xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );

            // #87671 Allow encryption
			aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("UseCommonStoragePasswordEncryption") );
			xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );

			xOut = xInfoStream->getOutputStream();
		}
		catch( uno::Exception& )
		{
			sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
			ErrorHandler::HandleError( nErrorCode );
		}
	}
	else
	{
		// Create Output stream
		INetURLObject aLibInfoInetObj( String(maLibraryPath).GetToken(1) );
		aLibInfoInetObj.insertName( maInfoFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
		aLibInfoInetObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM("xlc") ) );
		String aLibInfoPath( aLibInfoInetObj.GetMainURL( INetURLObject::NO_DECODE ) );

		try
		{
		    if( mxSFI->exists( aLibInfoPath ) )
			    mxSFI->kill( aLibInfoPath );
		    xOut = mxSFI->openFileWrite( aLibInfoPath );
        }
        catch( Exception& )
        {
            xOut.clear();
			SfxErrorContext aEc( ERRCTX_SFX_SAVEDOC, aLibInfoPath );
            sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
            ErrorHandler::HandleError( nErrorCode );
        }

	}
	if( !xOut.is() )
	{
		OSL_ENSURE( 0, "### couln't open output stream\n" );
		return;
	}

	Reference< XActiveDataSource > xSource( xHandler, UNO_QUERY );
	xSource->setOutputStream( xOut );

    try
	{
		xmlscript::exportLibraryContainer( xHandler, pLibArray );
		if ( bStorage )
		{
            uno::Reference< embed::XTransactedObject > xTransact( xTargetLibrariesStor, uno::UNO_QUERY );
            OSL_ENSURE( xTransact.is(), "The storage must implement XTransactedObject!\n" );
            if ( !xTransact.is() )
                throw uno::RuntimeException();

            xTransact->commit();
        }
    }
    catch( uno::Exception& )
    {
		OSL_ENSURE( sal_False, "Problem during storing of libraries!\n" );
        sal_uIntPtr nErrorCode = ERRCODE_IO_GENERAL;
        ErrorHandler::HandleError( nErrorCode );
    }

	delete pLibArray;
}


// Methods XElementAccess
Type SAL_CALL SfxLibraryContainer::getElementType()
	throw(RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	return maNameContainer.getElementType();
}

sal_Bool SfxLibraryContainer::hasElements()
	throw(RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	sal_Bool bRet = maNameContainer.hasElements();
	return bRet;
}

// Methods XNameAccess
Any SfxLibraryContainer::getByName( const OUString& aName )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	Any aRetAny = maNameContainer.getByName( aName ) ;
	return aRetAny;
}

Sequence< OUString > SfxLibraryContainer::getElementNames()
	throw(RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	return maNameContainer.getElementNames();
}

sal_Bool SfxLibraryContainer::hasByName( const OUString& aName )
	throw(RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	return maNameContainer.hasByName( aName ) ;
}

// Methods XLibraryContainer
Reference< XNameContainer > SAL_CALL SfxLibraryContainer::createLibrary( const OUString& Name )
		throw(IllegalArgumentException, ElementExistException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	SfxLibrary* pNewLib = implCreateLibrary( Name );
    pNewLib->maLibElementFileExtension = maLibElementFileExtension;

	createVariableURL( pNewLib->maUnexpandedStorageURL, Name, maInfoFileName, true );

	Reference< XNameAccess > xNameAccess = static_cast< XNameAccess* >( pNewLib );
	Any aElement;
	aElement <<= xNameAccess;
	maNameContainer.insertByName( Name, aElement );
	maModifiable.setModified( sal_True );
    Reference< XNameContainer > xRet( xNameAccess, UNO_QUERY );
	return xRet;
}

Reference< XNameAccess > SAL_CALL SfxLibraryContainer::createLibraryLink
	( const OUString& Name, const OUString& StorageURL, sal_Bool ReadOnly )
		throw(IllegalArgumentException, ElementExistException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    // TODO: Check other reasons to force ReadOnly status
	//if( !ReadOnly )
	//{
	//}

    OUString aLibInfoFileURL;
    OUString aLibDirURL;
    OUString aUnexpandedStorageURL;
    checkStorageURL( StorageURL, aLibInfoFileURL, aLibDirURL, aUnexpandedStorageURL );


	SfxLibrary* pNewLib = implCreateLibraryLink( Name, aLibInfoFileURL, aLibDirURL, ReadOnly );
    pNewLib->maLibElementFileExtension = maLibElementFileExtension;
    pNewLib->maUnexpandedStorageURL = aUnexpandedStorageURL;
    pNewLib->maOrignialStorageURL = StorageURL;

    OUString aInitFileName;
	uno::Reference< embed::XStorage > xDummyStor;
    ::xmlscript::LibDescriptor aLibDesc;
    /*sal_Bool bReadIndexFile = */implLoadLibraryIndexFile( pNewLib, aLibDesc, xDummyStor, aInitFileName );
    implImportLibDescriptor( pNewLib, aLibDesc );

	Reference< XNameAccess > xRet = static_cast< XNameAccess* >( pNewLib );
	Any aElement;
	aElement <<= xRet;
	maNameContainer.insertByName( Name, aElement );
	maModifiable.setModified( sal_True );

	OUString aUserSearchStr   = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE" );
	OUString aSharedSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE" );
	OUString aBundledSearchStr = OUString::createFromAscii( "vnd.sun.star.expand:$BUNDLED_EXTENSIONS" );
	if( StorageURL.indexOf( aUserSearchStr ) != -1 )
	{
	    pNewLib->mbExtension = sal_True;
	}
	else if( StorageURL.indexOf( aSharedSearchStr ) != -1 || StorageURL.indexOf( aBundledSearchStr ) != -1 )
	{
	    pNewLib->mbExtension = sal_True;
	    pNewLib->mbReadOnly = sal_True;
	}

	return xRet;
}

void SAL_CALL SfxLibraryContainer::removeLibrary( const OUString& Name )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    // Get and hold library before removing
	Any aLibAny = maNameContainer.getByName( Name ) ;
	Reference< XNameAccess > xNameAccess;
	aLibAny >>= xNameAccess;
	SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
	if( pImplLib->mbReadOnly && !pImplLib->mbLink )
		throw IllegalArgumentException();

    // Remove from container
	maNameContainer.removeByName( Name );
	maModifiable.setModified( sal_True );

    // Delete library files, but not for linked libraries
    if( !pImplLib->mbLink )
    {
	    if( mxStorage.is() )
            return;
	    if( xNameAccess->hasElements() )
	    {
		    Sequence< OUString > aNames = pImplLib->getElementNames();
		    sal_Int32 nNameCount = aNames.getLength();
		    const OUString* pNames = aNames.getConstArray();
		    for( sal_Int32 i = 0 ; i < nNameCount ; ++i, ++pNames )
		    {
                pImplLib->removeElementWithoutChecks( *pNames, SfxLibrary::LibraryContainerAccess() );
		    }
	    }

        // Delete index file
        createAppLibraryFolder( pImplLib, Name );
        String aLibInfoPath = pImplLib->maLibInfoFileURL;
		try
		{
		    if( mxSFI->exists( aLibInfoPath ) )
			    mxSFI->kill( aLibInfoPath );
        }
        catch( Exception& ) {}

        // Delete folder if empty
	    INetURLObject aInetObj( String(maLibraryPath).GetToken(1) );
	    aInetObj.insertName( Name, sal_True, INetURLObject::LAST_SEGMENT,
		    sal_True, INetURLObject::ENCODE_ALL );
	    OUString aLibDirPath = aInetObj.GetMainURL( INetURLObject::NO_DECODE );

	    try
	    {
	        if( mxSFI->isFolder( aLibDirPath ) )
	        {
                Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
    		    sal_Int32 nCount = aContentSeq.getLength();
	            if( !nCount )
		            mxSFI->kill( aLibDirPath );
	        }
        }
        catch( Exception& )
        {
        }
    }
}

sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLoaded( const OUString& Name )
	throw(NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );
	sal_Bool bRet = pImplLib->mbLoaded;
	return bRet;
}


void SAL_CALL SfxLibraryContainer::loadLibrary( const OUString& Name )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	Any aLibAny = maNameContainer.getByName( Name ) ;
	Reference< XNameAccess > xNameAccess;
	aLibAny >>= xNameAccess;
	SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );

    sal_Bool bLoaded = pImplLib->mbLoaded;
	pImplLib->mbLoaded = sal_True;
	if( !bLoaded && xNameAccess->hasElements() )
	{
        if( pImplLib->mbPasswordProtected )
        {
            implLoadPasswordLibrary( pImplLib, Name );
            return;
        }

		sal_Bool bLink = pImplLib->mbLink;
		sal_Bool bStorage = mxStorage.is() && !bLink;

		uno::Reference< embed::XStorage > xLibrariesStor;
		uno::Reference< embed::XStorage > xLibraryStor;
		if( bStorage )
		{
			try {
				xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
				OSL_ENSURE( xLibrariesStor.is(), "The method must either throw exception or return a storage!\n" );
				if ( !xLibrariesStor.is() )
					throw uno::RuntimeException();

				xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
				OSL_ENSURE( xLibraryStor.is(), "The method must either throw exception or return a storage!\n" );
				if ( !xLibrariesStor.is() )
					throw uno::RuntimeException();
			}
			catch( uno::Exception& )
			{
            #if OSL_DEBUG_LEVEL > 0
                Any aError( ::cppu::getCaughtException() );
                ::rtl::OStringBuffer aMessage;
                aMessage.append( "couln't open sub storage for library '" );
                aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
                aMessage.append( "'.\n\nException:" );
                aMessage.append( ::rtl::OUStringToOString( ::comphelper::anyToString( aError ), osl_getThreadTextEncoding() ) );
			    OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
            #endif
				return;
			}
		}

		Sequence< OUString > aNames = pImplLib->getElementNames();
		sal_Int32 nNameCount = aNames.getLength();
		const OUString* pNames = aNames.getConstArray();
		for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
		{
			OUString aElementName = pNames[ i ];

			OUString aFile;
			uno::Reference< io::XInputStream > xInStream;

			if( bStorage )
			{
				uno::Reference< io::XStream > xElementStream;

				aFile = aElementName;
				aFile += String( RTL_CONSTASCII_USTRINGPARAM(".xml") );

				try {
					xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
				} catch( uno::Exception& )
				{}

				if( !xElementStream.is() )
				{
					// Check for EA2 document version with wrong extensions
					aFile = aElementName;
					aFile += String( RTL_CONSTASCII_USTRINGPARAM(".") );
					aFile += maLibElementFileExtension;
					try {
						xElementStream = xLibraryStor->openStreamElement( aFile, embed::ElementModes::READ );
					} catch( uno::Exception& )
					{}
				}

				if ( xElementStream.is() )
					xInStream = xElementStream->getInputStream();

				if ( !xInStream.is() )
				{
                #if OSL_DEBUG_LEVEL > 0
                    ::rtl::OStringBuffer aMessage;
                    aMessage.append( "couln't open library element stream - attempted to open library '" );
                    aMessage.append( ::rtl::OUStringToOString( Name, osl_getThreadTextEncoding() ) );
                    aMessage.append( "'." );
					OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() );
                #endif
					return;
				}
			}
			else
			{
		        String aLibDirPath = pImplLib->maStorageURL;
				INetURLObject aElementInetObj( aLibDirPath );
				aElementInetObj.insertName( aElementName, sal_False,
					INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				aElementInetObj.setExtension( maLibElementFileExtension );
				aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );
			}

			Reference< XNameContainer > xLib( pImplLib );
			Any aAny = importLibraryElement( xLib, aElementName, 
					   						 aFile, xInStream );
			if( pImplLib->hasByName( aElementName ) )
            {
                if( aAny.hasValue() )
				    pImplLib->maNameContainer.replaceByName( aElementName, aAny );
            }
			else
            {
				pImplLib->maNameContainer.insertByName( aElementName, aAny );
            }
		}

        pImplLib->implSetModified( sal_False );
	}
}

// Methods XLibraryContainer2
sal_Bool SAL_CALL SfxLibraryContainer::isLibraryLink( const OUString& Name )
    throw (NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );
	sal_Bool bRet = pImplLib->mbLink;
	return bRet;
}

OUString SAL_CALL SfxLibraryContainer::getLibraryLinkURL( const OUString& Name )
    throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );
	sal_Bool bLink = pImplLib->mbLink;
	if( !bLink )
		throw IllegalArgumentException();
    OUString aRetStr = pImplLib->maLibInfoFileURL;
    return aRetStr;
}

sal_Bool SAL_CALL SfxLibraryContainer::isLibraryReadOnly( const OUString& Name )
    throw (NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );
	sal_Bool bRet = pImplLib->mbReadOnly || (pImplLib->mbLink && pImplLib->mbReadOnlyLink);
	return bRet;
}

void SAL_CALL SfxLibraryContainer::setLibraryReadOnly( const OUString& Name, sal_Bool bReadOnly )
    throw (NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );
    if( pImplLib->mbLink )
    {
        if( pImplLib->mbReadOnlyLink != bReadOnly )
        {
            pImplLib->mbReadOnlyLink = bReadOnly;
            pImplLib->implSetModified( sal_True );
            maModifiable.setModified( sal_True );
        }
    }
    else
    {
        if( pImplLib->mbReadOnly != bReadOnly )
        {
	        pImplLib->mbReadOnly = bReadOnly;
            pImplLib->implSetModified( sal_True );
        }
    }
}

void SAL_CALL SfxLibraryContainer::renameLibrary( const OUString& Name, const OUString& NewName )
    throw (NoSuchElementException, ElementExistException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	if( maNameContainer.hasByName( NewName ) )
		throw ElementExistException();

    // Get and hold library before removing
	Any aLibAny = maNameContainer.getByName( Name ) ;

	// #i24094 Maybe lib is not loaded!
	Reference< XNameAccess > xNameAccess;
	aLibAny >>= xNameAccess;
	SfxLibrary* pImplLib = static_cast< SfxLibrary* >( xNameAccess.get() );
	if( pImplLib->mbPasswordProtected && !pImplLib->mbPasswordVerified )
		return;		// Lib with unverified password cannot be renamed
	loadLibrary( Name );

    // Remove from container
	maNameContainer.removeByName( Name );
	maModifiable.setModified( sal_True );

    // Rename library folder, but not for linked libraries
    bool bMovedSuccessful = true;

    // Rename files
    sal_Bool bStorage = mxStorage.is();
    if( !bStorage && !pImplLib->mbLink )
    {
        bMovedSuccessful = false;

	    OUString aLibDirPath = pImplLib->maStorageURL;

	    INetURLObject aDestInetObj( String(maLibraryPath).GetToken(1) );
	    aDestInetObj.insertName( NewName, sal_True, INetURLObject::LAST_SEGMENT,
		    sal_True, INetURLObject::ENCODE_ALL );
	    OUString aDestDirPath = aDestInetObj.GetMainURL( INetURLObject::NO_DECODE );

        // Store new URL
        OUString aLibInfoFileURL = pImplLib->maLibInfoFileURL;
        checkStorageURL( aDestDirPath, pImplLib->maLibInfoFileURL, pImplLib->maStorageURL,
            pImplLib->maUnexpandedStorageURL );

	    try
	    {
	        if( mxSFI->isFolder( aLibDirPath ) )
	        {
			    if( !mxSFI->isFolder( aDestDirPath ) )
				    mxSFI->createFolder( aDestDirPath );

                // Move index file
		        try
		        {
					if( mxSFI->exists( pImplLib->maLibInfoFileURL ) )
						mxSFI->kill( pImplLib->maLibInfoFileURL );
            	    mxSFI->move( aLibInfoFileURL, pImplLib->maLibInfoFileURL );
                }
            	catch( Exception& )
                {
                }

			    Sequence< OUString > aElementNames = xNameAccess->getElementNames();
			    sal_Int32 nNameCount = aElementNames.getLength();
			    const OUString* pNames = aElementNames.getConstArray();
			    for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
			    {
				    OUString aElementName = pNames[ i ];

				    INetURLObject aElementInetObj( aLibDirPath );
				    aElementInetObj.insertName( aElementName, sal_False,
					    INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				    aElementInetObj.setExtension( maLibElementFileExtension );
				    String aElementPath( aElementInetObj.GetMainURL( INetURLObject::NO_DECODE ) );

				    INetURLObject aElementDestInetObj( aDestDirPath );
				    aElementDestInetObj.insertName( aElementName, sal_False,
					    INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
				    aElementDestInetObj.setExtension( maLibElementFileExtension );
				    String aDestElementPath( aElementDestInetObj.GetMainURL( INetURLObject::NO_DECODE ) );

		            try
		            {
					    if( mxSFI->exists( aDestElementPath ) )
						    mxSFI->kill( aDestElementPath );
            	        mxSFI->move( aElementPath, aDestElementPath );
                    }
            		catch( Exception& )
                    {
                    }
			    }
				pImplLib->storeResourcesAsURL( aDestDirPath, NewName );

                // Delete folder if empty
                Sequence< OUString > aContentSeq = mxSFI->getFolderContents( aLibDirPath, true );
    		    sal_Int32 nCount = aContentSeq.getLength();
	            if( !nCount )
                {
       	            mxSFI->kill( aLibDirPath );
                }

                bMovedSuccessful = true;
				pImplLib->implSetModified( sal_True );
	        }
        }
        catch( Exception& )
        {
            // Restore old library
        	maNameContainer.insertByName( Name, aLibAny ) ;
        }
    }

    if( bStorage && !pImplLib->mbLink )
		pImplLib->implSetModified( sal_True );

    if( bMovedSuccessful )
       	maNameContainer.insertByName( NewName, aLibAny ) ;

}


// Methods XInitialization
void SAL_CALL SfxLibraryContainer::initialize( const Sequence< Any >& _rArguments )
    throw (Exception, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	sal_Int32 nArgCount = _rArguments.getLength();
    if ( nArgCount == 1 )
    {
        OUString sInitialDocumentURL;
        Reference< XStorageBasedDocument > xDocument;
        if ( _rArguments[0] >>= sInitialDocumentURL )
        {
            initializeFromDocumentURL( sInitialDocumentURL );
            return;
        }

        if ( _rArguments[0] >>= xDocument )
        {
            initializeFromDocument( xDocument );
            return;
        }
    }

    throw IllegalArgumentException();
}

void SAL_CALL SfxLibraryContainer::initializeFromDocumentURL( const ::rtl::OUString& _rInitialDocumentURL )
{
    init( _rInitialDocumentURL, NULL );
}

void SAL_CALL SfxLibraryContainer::initializeFromDocument( const Reference< XStorageBasedDocument >& _rxDocument )
{
    // check whether this is a valid OfficeDocument, and obtain the document's root storage
    Reference< XStorage > xDocStorage;
    try
    {
        Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY_THROW );
        if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.OfficeDocument" ) ) ) )
            xDocStorage.set( _rxDocument->getDocumentStorage(), UNO_QUERY_THROW );

        Reference< XModel > xDocument( _rxDocument, UNO_QUERY_THROW );
        Reference< XComponent > xDocComponent( _rxDocument, UNO_QUERY_THROW );

        mxOwnerDocument = xDocument;
        startComponentListening( xDocComponent );
    }
    catch( const Exception& ) { }

    if ( !xDocStorage.is() )
        throw IllegalArgumentException();

    init( OUString(), xDocStorage );
}

// OEventListenerAdapter
void SfxLibraryContainer::_disposing( const EventObject& _rSource )
{
#if OSL_DEBUG_LEVEL > 0
    Reference< XModel > xDocument( mxOwnerDocument.get(), UNO_QUERY );
    OSL_ENSURE( ( xDocument == _rSource.Source ) && xDocument.is(), "SfxLibraryContainer::_disposing: where does this come from?" );
#else
    (void)_rSource;
#endif
    dispose();
}

// OComponentHelper
void SAL_CALL SfxLibraryContainer::disposing()
{
    Reference< XModel > xModel = mxOwnerDocument;
    EventObject aEvent( xModel.get() );
    maVBAScriptListeners.disposing( aEvent );
    stopAllComponentListening();
    mxOwnerDocument = WeakReference< XModel >();
}

// Methods XLibraryContainerPassword
sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordProtected( const OUString& )
    throw (NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    return sal_False;
}

sal_Bool SAL_CALL SfxLibraryContainer::isLibraryPasswordVerified( const OUString& )
    throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	throw IllegalArgumentException();
}

sal_Bool SAL_CALL SfxLibraryContainer::verifyLibraryPassword
    ( const OUString&, const OUString& )
        throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	throw IllegalArgumentException();
}

void SAL_CALL SfxLibraryContainer::changeLibraryPassword(
    const OUString&, const OUString&, const OUString& )
        throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	throw IllegalArgumentException();
}

// Methods XContainer
void SAL_CALL SfxLibraryContainer::addContainerListener( const Reference< XContainerListener >& xListener )
	throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
	maNameContainer.addContainerListener( xListener );
}

void SAL_CALL SfxLibraryContainer::removeContainerListener( const Reference< XContainerListener >& xListener )
	throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
	maNameContainer.removeContainerListener( xListener );
}

// Methods XLibraryContainerExport
void SAL_CALL SfxLibraryContainer::exportLibrary( const OUString& Name, const OUString& URL,
	const Reference< XInteractionHandler >& Handler )
		throw ( uno::Exception, NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );

	Reference< XSimpleFileAccess > xToUseSFI;
	if( Handler.is() )
	{
		xToUseSFI = Reference< XSimpleFileAccess >( mxMSF->createInstance
			( OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), UNO_QUERY );
		if( xToUseSFI.is() )
			xToUseSFI->setInteractionHandler( Handler );
	}

	// Maybe lib is not loaded?!
	loadLibrary( Name );

	uno::Reference< ::com::sun::star::embed::XStorage > xDummyStor;
    if( pImplLib->mbPasswordProtected )
		implStorePasswordLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );
    else
		implStoreLibrary( pImplLib, Name, xDummyStor, URL, xToUseSFI, Handler );

	::xmlscript::LibDescriptor aLibDesc;
	aLibDesc.aName = Name;
	aLibDesc.bLink = false;				// Link status gets lost?
	aLibDesc.bReadOnly = pImplLib->mbReadOnly;
	aLibDesc.bPreload = false;			// Preload status gets lost?
	aLibDesc.bPasswordProtected = pImplLib->mbPasswordProtected;
	aLibDesc.aElementNames = pImplLib->getElementNames();

	implStoreLibraryIndexFile( pImplLib, aLibDesc, xDummyStor, URL, xToUseSFI );
}

OUString SfxLibraryContainer::expand_url( const OUString& url )
	throw(::com::sun::star::uno::RuntimeException)
{
    if (0 == url.compareToAscii( RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ))
    {
        if( !mxMacroExpander.is() )
        {
            Reference< XPropertySet > xProps( mxMSF, UNO_QUERY );
            OSL_ASSERT( xProps.is() );
            if( xProps.is() )
            {
                Reference< XComponentContext > xContext;
                xProps->getPropertyValue(
                    OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
                OSL_ASSERT( xContext.is() );
                if( xContext.is() )
                {
                    Reference< util::XMacroExpander > xExpander;
                    xContext->getValueByName(
                        OUSTR("/singletons/com.sun.star.util.theMacroExpander") ) >>= xExpander;
                    if(! xExpander.is())
                    {
						throw uno::DeploymentException(
                            OUSTR("no macro expander singleton available!"), Reference< XInterface >() );
                    }
                    MutexGuard guard( Mutex::getGlobalMutex() );
                    if( !mxMacroExpander.is() )
                    {
                        mxMacroExpander = xExpander;
                    }
                }
            }
        }

        if( !mxMacroExpander.is() )
            return url;

        // cut protocol
        OUString macro( url.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
        // decode uric class chars
        macro = Uri::decode( macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
        // expand macro string
        OUString ret( mxMacroExpander->expandMacros( macro ) );
        return ret;
    }
	else if( mxStringSubstitution.is() )
	{
		OUString ret( mxStringSubstitution->substituteVariables( url, false ) );
        return ret;
	}
    else
    {
        return url;
    }
}

//XLibraryContainer3
OUString SAL_CALL SfxLibraryContainer::getOriginalLibraryLinkURL( const OUString& Name )
    throw (IllegalArgumentException, NoSuchElementException, RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    SfxLibrary* pImplLib = getImplLib( Name );
	sal_Bool bLink = pImplLib->mbLink;
	if( !bLink )
		throw IllegalArgumentException();
    OUString aRetStr = pImplLib->maOrignialStorageURL;
    return aRetStr;
}
    

// XVBACompatibility
::sal_Bool SAL_CALL SfxLibraryContainer::getVBACompatibilityMode() throw (RuntimeException)
{
	return mbVBACompat;
}

void SAL_CALL SfxLibraryContainer::setVBACompatibilityMode( ::sal_Bool _vbacompatmodeon ) throw (RuntimeException)
{
    /*  The member variable mbVBACompat must be set first, the following call
        to getBasicManager() may call getVBACompatibilityMode() which returns
        this value. */
    mbVBACompat = _vbacompatmodeon;
	if( BasicManager* pBasMgr = getBasicManager() )
	{
		// get the standard library
        String aLibName = pBasMgr->GetName();
        if ( aLibName.Len() == 0 )
            aLibName = String( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );

		if( StarBASIC* pBasic = pBasMgr->GetLib( aLibName ) )
			pBasic->SetVBAEnabled( _vbacompatmodeon );

        /*  If in VBA compatibility mode, force creation of the VBA Globals
            object. Each application will create an instance of its own
            implementation and store it in its Basic manager. Implementations
            will do all necessary additional initialization, such as
            registering the global "This***Doc" UNO constant, starting the
            document events processor etc.
         */
        if( mbVBACompat ) try
        {
            Reference< XModel > xModel( mxOwnerDocument );   // weak-ref -> ref
            Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
            xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
        }
        catch( Exception& )
        {
        }
	}
}

sal_Int32 SAL_CALL SfxLibraryContainer::getRunningVBAScripts() throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    return mnRunningVBAScripts;
}

void SAL_CALL SfxLibraryContainer::addVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
{
    maVBAScriptListeners.addTypedListener( rxListener );
}

void SAL_CALL SfxLibraryContainer::removeVBAScriptListener( const Reference< vba::XVBAScriptListener >& rxListener ) throw (RuntimeException)
{
    maVBAScriptListeners.removeTypedListener( rxListener );
}

void SAL_CALL SfxLibraryContainer::broadcastVBAScriptEvent( sal_Int32 nIdentifier, const ::rtl::OUString& rModuleName ) throw (RuntimeException)
{
    // own lock for accessing the number of running scripts
    enterMethod();
    switch( nIdentifier )
    {
        case vba::VBAScriptEventId::SCRIPT_STARTED:
            ++mnRunningVBAScripts;
        break;
        case vba::VBAScriptEventId::SCRIPT_STOPPED:
            --mnRunningVBAScripts;
        break;
    }
    leaveMethod();

    Reference< XModel > xModel = mxOwnerDocument;  // weak-ref -> ref
    Reference< XInterface > xSender( xModel, UNO_QUERY_THROW );
    vba::VBAScriptEvent aEvent( xSender, nIdentifier, rModuleName );
    maVBAScriptListeners.notify( aEvent );
}

// Methods XServiceInfo
::sal_Bool SAL_CALL SfxLibraryContainer::supportsService( const ::rtl::OUString& _rServiceName )
    throw (RuntimeException)
{
    LibraryContainerMethodGuard aGuard( *this );
    Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
    const OUString* pSupportedServices = aSupportedServices.getConstArray();
    for ( sal_Int32 i=0; i<aSupportedServices.getLength(); ++i, ++pSupportedServices )
        if ( *pSupportedServices == _rServiceName )
            return sal_True;
    return sal_False;
}

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

// Implementation class SfxLibrary

// Ctor
SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
    const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI )
		: OComponentHelper( m_aMutex )
		, mxMSF( xMSF )
		, mxSFI( xSFI )
        , mrModifiable( _rModifiable )
		, maNameContainer( aType )
		, mbLoaded( sal_True )
		, mbIsModified( sal_True )
		, mbInitialised( sal_False )
		, mbLink( sal_False )
		, mbReadOnly( sal_False )
		, mbReadOnlyLink( sal_False )
		, mbPreload( sal_False )
		, mbPasswordProtected( sal_False )
		, mbPasswordVerified( sal_False )
		, mbDoc50Password( sal_False )
		, mbSharedIndexFile( sal_False )
		, mbExtension( sal_False )
{
}

SfxLibrary::SfxLibrary( ModifiableHelper& _rModifiable, const Type& aType,
    const Reference< XMultiServiceFactory >& xMSF, const Reference< XSimpleFileAccess >& xSFI,
	const OUString& aLibInfoFileURL, const OUString& aStorageURL, sal_Bool ReadOnly )
		: OComponentHelper( m_aMutex )
		, mxMSF( xMSF )
		, mxSFI( xSFI )
        , mrModifiable( _rModifiable )
		, maNameContainer( aType )
		, mbLoaded( sal_False )
		, mbIsModified( sal_True )
		, mbInitialised( sal_False )
		, maLibInfoFileURL( aLibInfoFileURL )
		, maStorageURL( aStorageURL )
		, mbLink( sal_True )
		, mbReadOnly( sal_False )
		, mbReadOnlyLink( ReadOnly )
		, mbPreload( sal_False )
		, mbPasswordProtected( sal_False )
		, mbPasswordVerified( sal_False )
		, mbDoc50Password( sal_False )
		, mbSharedIndexFile( sal_False )
		, mbExtension( sal_False )
{
}

void SfxLibrary::implSetModified( sal_Bool _bIsModified )
{
    if ( mbIsModified == _bIsModified )
        return;
    mbIsModified = _bIsModified;
    if ( mbIsModified )
        mrModifiable.setModified( sal_True );
}

// Methods XInterface
Any SAL_CALL SfxLibrary::queryInterface( const Type& rType )
	throw( RuntimeException )
{
	Any aRet;

    /*
	if( mbReadOnly )
	{
		aRet = Any( ::cppu::queryInterface( rType,
			static_cast< XContainer * >( this ),
			static_cast< XNameAccess * >( this ) ) );
	}
	else
	{
    */
		aRet = Any( ::cppu::queryInterface( rType,
			static_cast< XContainer * >( this ),
			static_cast< XNameContainer * >( this ),
			static_cast< XNameAccess * >( this ),
			static_cast< XElementAccess * >( this ),
			static_cast< XChangesNotifier * >( this ) ) );
	//}
	if( !aRet.hasValue() )
		aRet = OComponentHelper::queryInterface( rType );
	return aRet;
}

// Methods XElementAccess
Type SfxLibrary::getElementType()
	throw(RuntimeException)
{
	return maNameContainer.getElementType();
}

sal_Bool SfxLibrary::hasElements()
	throw(RuntimeException)
{
	sal_Bool bRet = maNameContainer.hasElements();
	return bRet;
}

// Methods XNameAccess
Any SfxLibrary::getByName( const OUString& aName )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
    impl_checkLoaded();

	Any aRetAny = maNameContainer.getByName( aName ) ;
	return aRetAny;
}

Sequence< OUString > SfxLibrary::getElementNames()
	throw(RuntimeException)
{
	return maNameContainer.getElementNames();
}

sal_Bool SfxLibrary::hasByName( const OUString& aName )
	throw(RuntimeException)
{
	sal_Bool bRet = maNameContainer.hasByName( aName );
	return bRet;
}

void SfxLibrary::impl_checkReadOnly()
{
	if( mbReadOnly || (mbLink && mbReadOnlyLink) )
        throw IllegalArgumentException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Library is readonly." ) ),
            // TODO: resource
            *this, 0
        );
}

void SfxLibrary::impl_checkLoaded()
{
    if ( !mbLoaded )
        throw WrappedTargetException(
            ::rtl::OUString(),
            *this,
            makeAny( LibraryNotLoadedException(
                ::rtl::OUString(),
                *this
            ) )
        );
}

// Methods XNameReplace
void SfxLibrary::replaceByName( const OUString& aName, const Any& aElement )
	throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
{
    impl_checkReadOnly();
    impl_checkLoaded();

    OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::replaceByName: replacing element is invalid!" );

	maNameContainer.replaceByName( aName, aElement );
	implSetModified( sal_True );
}


// Methods XNameContainer
void SfxLibrary::insertByName( const OUString& aName, const Any& aElement )
	throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
{
    impl_checkReadOnly();
    impl_checkLoaded();

    OSL_ENSURE( isLibraryElementValid( aElement ), "SfxLibrary::insertByName: to-be-inserted element is invalid!" );

	maNameContainer.insertByName( aName, aElement );
	implSetModified( sal_True );
}

void SfxLibrary::impl_removeWithoutChecks( const ::rtl::OUString& _rElementName )
{
	maNameContainer.removeByName( _rElementName );
	implSetModified( sal_True );

    // Remove element file
	if( !maStorageURL.isEmpty() )
	{
		INetURLObject aElementInetObj( maStorageURL );
		aElementInetObj.insertName( _rElementName, sal_False,
			INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
		aElementInetObj.setExtension( maLibElementFileExtension );
		OUString aFile = aElementInetObj.GetMainURL( INetURLObject::NO_DECODE );

		try
		{
	        if( mxSFI->exists( aFile ) )
		        mxSFI->kill( aFile );
        }
        catch( Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
	}
}

void SfxLibrary::removeByName( const OUString& Name )
	throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
    impl_checkReadOnly();
    impl_checkLoaded();
    impl_removeWithoutChecks( Name );
}

// XTypeProvider
Sequence< Type > SfxLibrary::getTypes()
	throw( RuntimeException )
{
	static OTypeCollection * s_pTypes_NameContainer = 0;
	{
		if( !s_pTypes_NameContainer )
		{
			MutexGuard aGuard( Mutex::getGlobalMutex() );
			if( !s_pTypes_NameContainer )
			{
				static OTypeCollection s_aTypes_NameContainer(
					::getCppuType( (const Reference< XNameContainer > *)0 ),
					::getCppuType( (const Reference< XContainer > *)0 ),
					::getCppuType( (const Reference< XChangesNotifier > *)0 ),
					OComponentHelper::getTypes() );
				s_pTypes_NameContainer = &s_aTypes_NameContainer;
			}
		}
		return s_pTypes_NameContainer->getTypes();
	}
}


Sequence< sal_Int8 > SfxLibrary::getImplementationId()
	throw( RuntimeException )
{
	static OImplementationId * s_pId_NameContainer = 0;
	{
		if( !s_pId_NameContainer )
		{
			MutexGuard aGuard( Mutex::getGlobalMutex() );
			if( !s_pId_NameContainer )
			{
				static OImplementationId s_aId_NameContainer;
				s_pId_NameContainer = &s_aId_NameContainer;
			}
		}
		return s_pId_NameContainer->getImplementationId();
	}
}

// Methods XContainer
void SAL_CALL SfxLibrary::addContainerListener( const Reference< XContainerListener >& xListener )
	throw (RuntimeException)
{
	maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
	maNameContainer.addContainerListener( xListener );
}

void SAL_CALL SfxLibrary::removeContainerListener( const Reference< XContainerListener >& xListener )
	throw (RuntimeException)
{
	maNameContainer.removeContainerListener( xListener );
}

// Methods XChangesNotifier
void SAL_CALL SfxLibrary::addChangesListener( const Reference< XChangesListener >& xListener )
    throw (RuntimeException)
{
	maNameContainer.setEventSource( static_cast< XInterface* >( (OWeakObject*)this ) );
	maNameContainer.addChangesListener( xListener );
}

void SAL_CALL SfxLibrary::removeChangesListener( const Reference< XChangesListener >& xListener )
    throw (RuntimeException)
{
	maNameContainer.removeChangesListener( xListener );
}

//============================================================================
// Implementation class ScriptExtensionIterator

static rtl::OUString aBasicLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.basic-library" ) );
static rtl::OUString aDialogLibMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.dialog-library" ) );

ScriptExtensionIterator::ScriptExtensionIterator( void )
	: m_eState( USER_EXTENSIONS )
	, m_bUserPackagesLoaded( false )
	, m_bSharedPackagesLoaded( false )
    , m_bBundledPackagesLoaded( false )
	, m_iUserPackage( 0 )
	, m_iSharedPackage( 0 )
   	, m_iBundledPackage( 0 )
	, m_pScriptSubPackageIterator( NULL )
{
	Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
	Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
	OSL_ASSERT( xProps.is() );
	if (xProps.is())
	{
		xProps->getPropertyValue(
			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext;
		OSL_ASSERT( m_xContext.is() );
	}
	if( !m_xContext.is() )
	{
		throw RuntimeException(
			::rtl::OUString::createFromAscii( "ScriptExtensionIterator::init(), no XComponentContext" ),
			Reference< XInterface >() );
	}
}

rtl::OUString ScriptExtensionIterator::nextBasicOrDialogLibrary( bool& rbPureDialogLib )
{
	rtl::OUString aRetLib;

	while( aRetLib.isEmpty() && m_eState != END_REACHED )
	{
		switch( m_eState )
		{
			case USER_EXTENSIONS:
			{
				Reference< deployment::XPackage > xScriptPackage =
					implGetNextUserScriptPackage( rbPureDialogLib );
				if( !xScriptPackage.is() )
					break;

				aRetLib = xScriptPackage->getURL();
				break;
			}

			case SHARED_EXTENSIONS:
			{
				Reference< deployment::XPackage > xScriptPackage =
					implGetNextSharedScriptPackage( rbPureDialogLib );
				if( !xScriptPackage.is() )
					break;

				aRetLib = xScriptPackage->getURL();
				break;
			}
			case BUNDLED_EXTENSIONS:
			{
				Reference< deployment::XPackage > xScriptPackage = 
					implGetNextBundledScriptPackage( rbPureDialogLib );
				if( !xScriptPackage.is() )
					break;

				aRetLib = xScriptPackage->getURL();
				break;
			}
            case END_REACHED:
				VOS_ENSURE( false, "ScriptExtensionIterator::nextBasicOrDialogLibrary(): Invalid case END_REACHED" );
				break;
		}
	}

	return aRetLib;
}

ScriptSubPackageIterator::ScriptSubPackageIterator( Reference< deployment::XPackage > xMainPackage )
	: m_xMainPackage( xMainPackage )
	, m_bIsValid( false )
	, m_bIsBundle( false )
	, m_nSubPkgCount( 0 )
	, m_iNextSubPkg( 0 )
{
	Reference< deployment::XPackage > xScriptPackage;
	if( !m_xMainPackage.is() )
		return;

	// Check if parent package is registered
    beans::Optional< beans::Ambiguous<sal_Bool> > option( m_xMainPackage->isRegistered
		( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
	bool bRegistered = false;
    if( option.IsPresent )
    {
        beans::Ambiguous<sal_Bool> const & reg = option.Value;
        if( !reg.IsAmbiguous && reg.Value )
			bRegistered = true;
    }
	if( bRegistered )
	{
		m_bIsValid = true;
		if( m_xMainPackage->isBundle() )
		{
			m_bIsBundle = true;
			m_aSubPkgSeq = m_xMainPackage->getBundle
				( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
			m_nSubPkgCount = m_aSubPkgSeq.getLength();
		}
	}
}

Reference< deployment::XPackage > ScriptSubPackageIterator::getNextScriptSubPackage
	( bool& rbPureDialogLib )
{
	rbPureDialogLib = false;

	Reference< deployment::XPackage > xScriptPackage;
	if( !m_bIsValid )
		return xScriptPackage;

	if( m_bIsBundle )
	{
		const Reference< deployment::XPackage >* pSeq = m_aSubPkgSeq.getConstArray();
		sal_Int32 iPkg;
		for( iPkg = m_iNextSubPkg ; iPkg < m_nSubPkgCount ; ++iPkg )
		{
			const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
			xScriptPackage = implDetectScriptPackage( xSubPkg, rbPureDialogLib );
			if( xScriptPackage.is() )
				break;
		}
		m_iNextSubPkg = iPkg + 1;
	}
	else
	{
		xScriptPackage = implDetectScriptPackage( m_xMainPackage, rbPureDialogLib );
		m_bIsValid = false;		// No more script packages
	}

	return xScriptPackage;
}

Reference< deployment::XPackage > ScriptSubPackageIterator::implDetectScriptPackage
	( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
{
	Reference< deployment::XPackage > xScriptPackage;

	if( xPackage.is() )
	{
		const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
		rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
		if( aMediaType.equals( aBasicLibMediaType ) )
		{
			xScriptPackage = xPackage;
		}
		else if( aMediaType.equals( aDialogLibMediaType ) )
		{
			rbPureDialogLib = true;
			xScriptPackage = xPackage;
		}
	}

	return xScriptPackage;
}

Reference< deployment::XPackage > ScriptExtensionIterator::implGetScriptPackageFromPackage
	( const Reference< deployment::XPackage > xPackage, bool& rbPureDialogLib )
{
	rbPureDialogLib = false;

	Reference< deployment::XPackage > xScriptPackage;
	if( !xPackage.is() )
		return xScriptPackage;

	// Check if parent package is registered
    beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered
		( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) );
	bool bRegistered = false;
    if( option.IsPresent )
    {
        beans::Ambiguous<sal_Bool> const & reg = option.Value;
        if( !reg.IsAmbiguous && reg.Value )
			bRegistered = true;
    }
	if( bRegistered )
	{
		if( xPackage->isBundle() )
		{
			Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle
				( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() );
			sal_Int32 nPkgCount = aPkgSeq.getLength();
			const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray();
			for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg )
			{
				const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ];
				const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType();
				rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
				if( aMediaType.equals( aBasicLibMediaType ) )
				{
					xScriptPackage = xSubPkg;
					break;
				}
				else if( aMediaType.equals( aDialogLibMediaType ) )
				{
					rbPureDialogLib = true;
					xScriptPackage = xSubPkg;
					break;
				}
			}
		}
		else
		{
			const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType();
			rtl::OUString aMediaType = xPackageTypeInfo->getMediaType();
			if( aMediaType.equals( aBasicLibMediaType ) )
			{
				xScriptPackage = xPackage;
			}
			else if( aMediaType.equals( aDialogLibMediaType ) )
			{
				rbPureDialogLib = true;
				xScriptPackage = xPackage;
			}
		}
	}

	return xScriptPackage;
}

Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextUserScriptPackage
	( bool& rbPureDialogLib )
{
	Reference< deployment::XPackage > xScriptPackage;

	if( !m_bUserPackagesLoaded )
	{
		try
		{
			Reference< XExtensionManager > xManager =
				ExtensionManager::get( m_xContext );
			m_aUserPackagesSeq = xManager->getDeployedExtensions
				(rtl::OUString::createFromAscii("user"),
                 Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
		}
		catch( com::sun::star::uno::DeploymentException& )
		{
			// Special Office installations may not contain deployment code
			m_eState = END_REACHED;
			return xScriptPackage;
		}

		m_bUserPackagesLoaded = true;
	}

	if( m_iUserPackage == m_aUserPackagesSeq.getLength() )
	{
		m_eState = SHARED_EXTENSIONS;		// Later: SHARED_MODULE
	}
	else
	{
		if( m_pScriptSubPackageIterator == NULL )
		{
			const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray();
			Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage ];
			VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextUserScriptPackage(): Invalid package" );
			m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
		}

		if( m_pScriptSubPackageIterator != NULL )
		{
			xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
			if( !xScriptPackage.is() )
			{
				delete m_pScriptSubPackageIterator;
				m_pScriptSubPackageIterator = NULL;
				m_iUserPackage++;
			}
		}
	}

	return xScriptPackage;
}

Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextSharedScriptPackage
	( bool& rbPureDialogLib )
{
	Reference< deployment::XPackage > xScriptPackage;

	if( !m_bSharedPackagesLoaded )
	{
		try
		{
			Reference< XExtensionManager > xSharedManager =
				ExtensionManager::get( m_xContext ); 
			m_aSharedPackagesSeq = xSharedManager->getDeployedExtensions
				(rtl::OUString::createFromAscii("shared"),
                 Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
		}
		catch( com::sun::star::uno::DeploymentException& )
		{
			// Special Office installations may not contain deployment code
			return xScriptPackage;
		}

		m_bSharedPackagesLoaded = true;
	}

	if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() )
	{
		m_eState = BUNDLED_EXTENSIONS;
	}
	else
	{
		if( m_pScriptSubPackageIterator == NULL )
		{
			const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray();
			Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage ];
			VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextSharedScriptPackage(): Invalid package" );
			m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
		}

		if( m_pScriptSubPackageIterator != NULL )
		{
			xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
			if( !xScriptPackage.is() )
			{
				delete m_pScriptSubPackageIterator;
				m_pScriptSubPackageIterator = NULL;
				m_iSharedPackage++;
			}
		}
	}

	return xScriptPackage;
}

Reference< deployment::XPackage > ScriptExtensionIterator::implGetNextBundledScriptPackage
	( bool& rbPureDialogLib )
{
	Reference< deployment::XPackage > xScriptPackage;

	if( !m_bBundledPackagesLoaded )
	{
		try
		{
			Reference< XExtensionManager > xManager =
				ExtensionManager::get( m_xContext ); 
			m_aBundledPackagesSeq = xManager->getDeployedExtensions
				(rtl::OUString::createFromAscii("bundled"),
                 Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() );
		}
		catch( com::sun::star::uno::DeploymentException& )
		{
			// Special Office installations may not contain deployment code
			return xScriptPackage;
		}

		m_bBundledPackagesLoaded = true;
	}

	if( m_iBundledPackage == m_aBundledPackagesSeq.getLength() )
	{
		m_eState = END_REACHED;
	}
	else
	{
		if( m_pScriptSubPackageIterator == NULL )
		{
			const Reference< deployment::XPackage >* pBundledPackages = m_aBundledPackagesSeq.getConstArray();
			Reference< deployment::XPackage > xPackage = pBundledPackages[ m_iBundledPackage ];
			VOS_ENSURE( xPackage.is(), "ScriptExtensionIterator::implGetNextBundledScriptPackage(): Invalid package" );
			m_pScriptSubPackageIterator = new ScriptSubPackageIterator( xPackage );
		}

		if( m_pScriptSubPackageIterator != NULL )
		{
			xScriptPackage = m_pScriptSubPackageIterator->getNextScriptSubPackage( rbPureDialogLib );
			if( !xScriptPackage.is() )
			{
				delete m_pScriptSubPackageIterator;
				m_pScriptSubPackageIterator = NULL;
				m_iBundledPackage++;
			}
		}
	}

	return xScriptPackage;
}

}   // namespace basic
