/**************************************************************
 * 
 * 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_embeddedobj.hxx"

#include <commonembobj.hxx>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/embed/EmbedVerbs.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/EmbedUpdateModes.hpp>
#include <com/sun/star/embed/XInplaceClient.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/beans/NamedValue.hpp>

#include <cppuhelper/typeprovider.hxx>
#include <cppuhelper/interfacecontainer.h>
#include <comphelper/mimeconfighelper.hxx>

#include "closepreventer.hxx"
#include "intercept.hxx"

using namespace ::com::sun::star;


uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
                                                            sal_Bool bCanUseDocumentBaseURL );

//------------------------------------------------------
OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< lang::XMultiServiceFactory >& xFactory,
                                                const uno::Sequence< beans::NamedValue >& aObjProps )
: m_pDocHolder( NULL )
, m_pInterfaceContainer( NULL )
, m_bReadOnly( sal_False )
, m_bDisposed( sal_False )
, m_bClosed( sal_False )
, m_nObjectState( -1 )
, m_nTargetState( -1 )
, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
, m_xFactory( xFactory )
, m_nMiscStatus( 0 )
, m_bEmbeddedScriptSupport( sal_True )
, m_bDocumentRecoverySupport( sal_True )
, m_bWaitSaveCompleted( sal_False )
, m_bIsLink( sal_False )
, m_bLinkHasPassword( sal_False )
, m_bHasClonedSize( sal_False )
, m_nClonedMapUnit( 0 )
{
    CommonInit_Impl( aObjProps );
}

//------------------------------------------------------
OCommonEmbeddedObject::OCommonEmbeddedObject(
        const uno::Reference< lang::XMultiServiceFactory >& xFactory,
        const uno::Sequence< beans::NamedValue >& aObjProps,
        const uno::Sequence< beans::PropertyValue >& aMediaDescr,
        const uno::Sequence< beans::PropertyValue >& aObjectDescr )
: m_pDocHolder( NULL )
, m_pInterfaceContainer( NULL )
, m_bReadOnly( sal_False )
, m_bDisposed( sal_False )
, m_bClosed( sal_False )
, m_nObjectState( embed::EmbedStates::LOADED )
, m_nTargetState( -1 )
, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE )
, m_xFactory( xFactory )
, m_nMiscStatus( 0 )
, m_bEmbeddedScriptSupport( sal_True )
, m_bDocumentRecoverySupport( sal_True )
, m_bWaitSaveCompleted( sal_False )
, m_bIsLink( sal_True )
, m_bLinkHasPassword( sal_False )
, m_bHasClonedSize( sal_False )
, m_nClonedMapUnit( 0 )
{
    // linked object has no own persistence so it is in loaded state starting from creation
    LinkInit_Impl( aObjProps, aMediaDescr, aObjectDescr );
}

//------------------------------------------------------
void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedValue >& aObjectProps )
{
    OSL_ENSURE( m_xFactory.is(), "No ServiceFactory is provided!\n" );
    if ( !m_xFactory.is() )
        throw uno::RuntimeException();

    m_pDocHolder = new DocumentHolder( m_xFactory, this );
    m_pDocHolder->acquire();

    // parse configuration entries
    // TODO/LATER: in future UI names can be also provided here
    for ( sal_Int32 nInd = 0; nInd < aObjectProps.getLength(); nInd++ )
    {
        if ( aObjectProps[nInd].Name.equalsAscii( "ClassID" ) )
            aObjectProps[nInd].Value >>= m_aClassID;
        else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentServiceName" ) )
            aObjectProps[nInd].Value >>= m_aDocServiceName;
        else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentFilterName" ) )
            aObjectProps[nInd].Value >>= m_aPresetFilterName;
        else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectMiscStatus" ) )
            aObjectProps[nInd].Value >>= m_nMiscStatus;
        else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectVerbs" ) )
            aObjectProps[nInd].Value >>= m_aObjectVerbs;
    }

    if ( m_aClassID.getLength() != 16 /*|| !m_aDocServiceName.getLength()*/ )
        throw uno::RuntimeException(); // something goes really wrong

    // accepted states
    m_aAcceptedStates.realloc( NUM_SUPPORTED_STATES );

    m_aAcceptedStates[0] = embed::EmbedStates::LOADED;
    m_aAcceptedStates[1] = embed::EmbedStates::RUNNING;
    m_aAcceptedStates[2] = embed::EmbedStates::INPLACE_ACTIVE;
    m_aAcceptedStates[3] = embed::EmbedStates::UI_ACTIVE;
    m_aAcceptedStates[4] = embed::EmbedStates::ACTIVE;


    // intermediate states
    // In the following table the first index points to starting state,
    // the second one to the target state, and the sequence referenced by
    // first two indexes contains intermediate states, that should be
    // passed by object to reach the target state.
    // If the sequence is empty that means that indirect switch from start
    // state to the target state is forbidden, only if direct switch is possible
    // the state can be reached.

    m_pIntermediateStatesSeqs[0][2].realloc( 1 );
    m_pIntermediateStatesSeqs[0][2][0] = embed::EmbedStates::RUNNING;

    m_pIntermediateStatesSeqs[0][3].realloc( 2 );
    m_pIntermediateStatesSeqs[0][3][0] = embed::EmbedStates::RUNNING;
    m_pIntermediateStatesSeqs[0][3][1] = embed::EmbedStates::INPLACE_ACTIVE;

    m_pIntermediateStatesSeqs[0][4].realloc( 1 );
    m_pIntermediateStatesSeqs[0][4][0] = embed::EmbedStates::RUNNING;

    m_pIntermediateStatesSeqs[1][3].realloc( 1 );
    m_pIntermediateStatesSeqs[1][3][0] = embed::EmbedStates::INPLACE_ACTIVE;

    m_pIntermediateStatesSeqs[2][0].realloc( 1 );
    m_pIntermediateStatesSeqs[2][0][0] = embed::EmbedStates::RUNNING;

    m_pIntermediateStatesSeqs[3][0].realloc( 2 );
    m_pIntermediateStatesSeqs[3][0][0] = embed::EmbedStates::INPLACE_ACTIVE;
    m_pIntermediateStatesSeqs[3][0][1] = embed::EmbedStates::RUNNING;

    m_pIntermediateStatesSeqs[3][1].realloc( 1 );
    m_pIntermediateStatesSeqs[3][1][0] = embed::EmbedStates::INPLACE_ACTIVE;

    m_pIntermediateStatesSeqs[4][0].realloc( 1 );
    m_pIntermediateStatesSeqs[4][0][0] = embed::EmbedStates::RUNNING;

    // verbs table
    sal_Int32 nVerbTableSize = 0;
    for ( sal_Int32 nVerbInd = 0; nVerbInd < m_aObjectVerbs.getLength(); nVerbInd++ )
    {
        if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_PRIMARY )
        {
            m_aVerbTable.realloc( ++nVerbTableSize );
            m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
            m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
            m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
        }
        else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_SHOW )
        {
            m_aVerbTable.realloc( ++nVerbTableSize );
            m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
            m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
            m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
        }
        else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN )
        {
            m_aVerbTable.realloc( ++nVerbTableSize );
            m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
            m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
            m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::ACTIVE;
        }
        else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_IPACTIVATE )
        {
            m_aVerbTable.realloc( ++nVerbTableSize );
            m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
            m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
            m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::INPLACE_ACTIVE;
        }
        else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_UIACTIVATE )
        {
            m_aVerbTable.realloc( ++nVerbTableSize );
            m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
            m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
            m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE;
        }
        else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_HIDE )
        {
            m_aVerbTable.realloc( ++nVerbTableSize );
            m_aVerbTable[nVerbTableSize - 1].realloc( 2 );
            m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID;
            m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::RUNNING;
        }
    }
}

//------------------------------------------------------
void OCommonEmbeddedObject::LinkInit_Impl(
                                const uno::Sequence< beans::NamedValue >& aObjectProps,
                                const uno::Sequence< beans::PropertyValue >& aMediaDescr,
                                const uno::Sequence< beans::PropertyValue >& aObjectDescr )
{
    // setPersistance has no effect on own links, so the complete initialization must be done here

    for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ )
        if ( aMediaDescr[nInd].Name.equalsAscii( "URL" ) )
            aMediaDescr[nInd].Value >>= m_aLinkURL;
        else if ( aMediaDescr[nInd].Name.equalsAscii( "FilterName" ) )
            aMediaDescr[nInd].Value >>= m_aLinkFilterName;

    OSL_ENSURE( m_aLinkURL.getLength() && m_aLinkFilterName.getLength(), "Filter and URL must be provided!\n" );

    m_bReadOnly = sal_True;
    if ( m_aLinkFilterName.getLength() )
    {
        ::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
        ::rtl::OUString aExportFilterName = aHelper.GetExportFilterFromImportFilter( m_aLinkFilterName );
        m_bReadOnly = !( aExportFilterName.equals( m_aLinkFilterName ) );
    }

    m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, sal_False );

    uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
    for ( sal_Int32 nObjInd = 0; nObjInd < aObjectDescr.getLength(); nObjInd++ )
        if ( aObjectDescr[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
        {
            aObjectDescr[nObjInd].Value >>= xDispatchInterceptor;
            break;
        }
        else if ( aObjectDescr[nObjInd].Name.equalsAscii( "Parent" ) )
        {
            aObjectDescr[nObjInd].Value >>= m_xParent;
        }

    CommonInit_Impl( aObjectProps );

    if ( xDispatchInterceptor.is() )
        m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
}

//------------------------------------------------------
OCommonEmbeddedObject::~OCommonEmbeddedObject()
{
    if ( m_pInterfaceContainer || m_pDocHolder )
    {
        m_refCount++;
        try {
            lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );

            if ( m_pInterfaceContainer )
            {
                m_pInterfaceContainer->disposeAndClear( aSource );

                delete m_pInterfaceContainer;
                m_pInterfaceContainer = NULL;
            }
        } catch( uno::Exception& ) {}

        try {
            if ( m_pDocHolder )
            {
                m_pDocHolder->CloseFrame();
                try {
                    m_pDocHolder->CloseDocument( sal_True, sal_True );
                } catch ( uno::Exception& ) {}
                m_pDocHolder->FreeOffice();

                m_pDocHolder->release();
                m_pDocHolder = NULL;
            }
        } catch( uno::Exception& ) {}
    }
}

//------------------------------------------------------
void OCommonEmbeddedObject::requestPositioning( const awt::Rectangle& aRect )
{
    // the method is called in case object is inplace active and the object window was resized

    OSL_ENSURE( m_xClientSite.is(), "The client site must be set for inplace active object!\n" );
    if ( m_xClientSite.is() )
    {
        uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY );

        OSL_ENSURE( xInplaceClient.is(), "The client site must support XInplaceClient to allow inplace activation!\n" );
        if ( xInplaceClient.is() )
        {
            try {
                xInplaceClient->changedPlacement( aRect );
            }
            catch( uno::Exception& )
            {
                OSL_ENSURE( sal_False, "Exception on request to resize!\n" );
            }
        }
    }
}

//------------------------------------------------------
void OCommonEmbeddedObject::PostEvent_Impl( const ::rtl::OUString& aEventName,
                                            const uno::Reference< uno::XInterface >& /*xSource*/ )
{
    if ( m_pInterfaceContainer )
    {
        ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer(
                                            ::getCppuType((const uno::Reference< document::XEventListener >*)0) );
        if( pIC )
        {
            document::EventObject aEvent;
            aEvent.EventName = aEventName;
            aEvent.Source = uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) );
            // For now all the events are sent as object events
            // aEvent.Source = ( xSource.is() ? xSource
            //                       : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) );
            ::cppu::OInterfaceIteratorHelper aIt( *pIC );
            while( aIt.hasMoreElements() )
            {
                try
                {
                    ((document::XEventListener *)aIt.next())->notifyEvent( aEvent );
                }
                catch( uno::RuntimeException& )
                {
                    aIt.remove();
                }

                // the listener could dispose the object.
                if ( m_bDisposed )
                    return;
            }
        }
    }
}

//------------------------------------------------------
uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType )
        throw( uno::RuntimeException )
{
    uno::Any aReturn;

    if ( rType == ::getCppuType( (uno::Reference< embed::XEmbeddedObject > const *)0 ))
    {
        void * p = static_cast< embed::XEmbeddedObject * >( this );
        return uno::Any( &p, rType );
    }
    else
        aReturn <<= ::cppu::queryInterface(
                    rType,
                    static_cast< embed::XInplaceObject* >( this ),
                    static_cast< embed::XVisualObject* >( this ),
                    static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ),
                    static_cast< embed::XEmbedPersist* >( this ),
                    static_cast< embed::XLinkageSupport* >( this ),
                    static_cast< embed::XStateChangeBroadcaster* >( this ),
                    static_cast< embed::XClassifiedObject* >( this ),
                    static_cast< embed::XComponentSupplier* >( this ),
                    static_cast< util::XCloseable* >( this ),
                    static_cast< container::XChild* >( this ),
                    static_cast< chart2::XDefaultSizeTransmitter* >( this ),
                    static_cast< document::XEventBroadcaster* >( this ) );

    if ( aReturn.hasValue() )
        return aReturn;
    else
        return ::cppu::OWeakObject::queryInterface( rType ) ;

}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::acquire()
        throw()
{
    ::cppu::OWeakObject::acquire() ;
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::release()
        throw()
{
    ::cppu::OWeakObject::release() ;
}

//------------------------------------------------------
uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes()
        throw( uno::RuntimeException )
{
    static ::cppu::OTypeCollection* pTypeCollection = NULL;

    if ( !pTypeCollection )
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if ( !pTypeCollection )
        {
            if ( m_bIsLink )
            {
                static ::cppu::OTypeCollection aTypeCollection(
                                            ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ),
                                            ::getCppuType( (const uno::Reference< container::XChild >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XLinkageSupport >*)NULL ) );

                pTypeCollection = &aTypeCollection ;
            }
            else
            {
                   static ::cppu::OTypeCollection aTypeCollection(
                                            ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ),
                                            ::getCppuType( (const uno::Reference< container::XChild >*)NULL ),
                                            ::getCppuType( (const uno::Reference< embed::XEmbedPersist >*)NULL ) );

                pTypeCollection = &aTypeCollection ;
            }
        }
    }

    return pTypeCollection->getTypes() ;

}

//------------------------------------------------------
uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getImplementationId()
        throw( uno::RuntimeException )
{
    static ::cppu::OImplementationId* pID = NULL ;

    if ( !pID )
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ;
        if ( !pID )
        {
            static ::cppu::OImplementationId aID( sal_False ) ;
            pID = &aID ;
        }
    }

    return pID->getImplementationId() ;
}

//------------------------------------------------------
uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID()
        throw ( uno::RuntimeException )
{
    if ( m_bDisposed )
        throw lang::DisposedException();

    return m_aClassID;
}

//------------------------------------------------------
::rtl::OUString SAL_CALL OCommonEmbeddedObject::getClassName()
        throw ( uno::RuntimeException )
{
    if ( m_bDisposed )
        throw lang::DisposedException();

    return m_aClassName;
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::setClassInfo(
                const uno::Sequence< sal_Int8 >& /*aClassID*/, const ::rtl::OUString& /*aClassName*/ )
        throw ( lang::NoSupportException,
                uno::RuntimeException )
{
    // the object class info can not be changed explicitly
    throw lang::NoSupportException(); //TODO:
}

//------------------------------------------------------
uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent()
        throw ( uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    // add an exception
    if ( m_nObjectState == -1 )
    {
        // the object is still not loaded
        throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ),
                                        uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
    }

    // if ( m_bWaitSaveCompleted )
    //     throw embed::WrongStateException(
    //                 ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
    //                 uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) );

    return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
}

//----------------------------------------------
void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener )
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_pInterfaceContainer )
        m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );

    m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ),
                                                        xListener );
}

//----------------------------------------------
void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener(
                    const uno::Reference< embed::XStateChangeListener >& xListener )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_pInterfaceContainer )
        m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ),
                                                xListener );
}

//----------------------------------------------
void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership )
    throw ( util::CloseVetoException,
            uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bClosed )
        throw lang::DisposedException(); // TODO

    uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) );
    lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) );

    if ( m_pInterfaceContainer )
    {
        ::cppu::OInterfaceContainerHelper* pContainer =
            m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
        if ( pContainer != NULL )
        {
            ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
            while (pIterator.hasMoreElements())
            {
                try
                {
                    ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership );
                }
                catch( uno::RuntimeException& )
                {
                    pIterator.remove();
                }
            }
        }

        pContainer = m_pInterfaceContainer->getContainer(
                                    ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) );
        if ( pContainer != NULL )
        {
            ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer);
            while (pCloseIterator.hasMoreElements())
            {
                try
                {
                    ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource );
                }
                catch( uno::RuntimeException& )
                {
                    pCloseIterator.remove();
                }
            }
        }

        m_pInterfaceContainer->disposeAndClear( aSource );
    }

    m_bDisposed = sal_True; // the object is disposed now for outside

    // it is possible that the document can not be closed, in this case if the argument is false
    // the exception will be thrown otherwise in addition to exception the object must register itself
    // as termination listener and listen for document events

    if ( m_pDocHolder )
    {
        m_pDocHolder->CloseFrame();

        try {
            m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership );
        }
        catch( uno::Exception& )
        {
            if ( bDeliverOwnership )
            {
                m_pDocHolder->release();
                m_pDocHolder = NULL;
                m_bClosed = sal_True;
            }

            throw;
        }

        m_pDocHolder->FreeOffice();

        m_pDocHolder->release();
        m_pDocHolder = NULL;
    }

    // TODO: for now the storage will be disposed by the object, but after the document
    // will use the storage, the storage will be disposed by the document and recreated by the object
    if ( m_xObjectStorage.is() )
    {
        uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY );
        OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" );

        if ( xComp.is() )
        {
            try {
                xComp->dispose();
            } catch ( uno::Exception& ) {}
        }

        m_xObjectStorage.clear();
        m_xRecoveryStorage.clear();
    }

    m_bClosed = sal_True; // the closing succeeded
}

//----------------------------------------------
void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener )
    throw ( uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_pInterfaceContainer )
        m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );

    m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), xListener );
}

//----------------------------------------------
void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener )
    throw (uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_pInterfaceContainer )
        m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ),
                                                xListener );
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener )
        throw ( uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_bDisposed )
        throw lang::DisposedException(); // TODO

    if ( !m_pInterfaceContainer )
        m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex );

    m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), xListener );
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
        throw ( uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( m_aMutex );
    if ( m_pInterfaceContainer )
        m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ),
                                                xListener );
}

