/**************************************************************
 * 
 * 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/Aspects.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/embed/EmbedVerbs.hpp>
#include <com/sun/star/embed/EntryInitModes.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/XOptimizedStorage.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/EmbedUpdateModes.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/frame/XLoadable.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XModule.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/util/XModifiable.hpp>

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCEESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/IllegalTypeException.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>

#include <comphelper/fileformat.h>
#include <comphelper/storagehelper.hxx>
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/namedvaluecollection.hxx>

#include <rtl/logfile.hxx>

#include <tools/diagnose_ex.h>

#define USE_STORAGEBASED_DOCUMENT

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


//------------------------------------------------------
uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr,
															sal_Bool bCanUseDocumentBaseURL )
{
	uno::Sequence< beans::PropertyValue > aResult;
	sal_Int32 nResLen = 0;

	for ( sal_Int32 nInd = 0; nInd < aMedDescr.getLength(); nInd++ )
	{
		if ( aMedDescr[nInd].Name.equalsAscii( "ComponentData" )
		  || aMedDescr[nInd].Name.equalsAscii( "DocumentTitle" )
		  || aMedDescr[nInd].Name.equalsAscii( "InteractionHandler" )
		  || aMedDescr[nInd].Name.equalsAscii( "JumpMark" )
		  // || aMedDescr[nInd].Name.equalsAscii( "Password" ) makes no sence for embedded objects
		  || aMedDescr[nInd].Name.equalsAscii( "Preview" )
		  || aMedDescr[nInd].Name.equalsAscii( "ReadOnly" )
		  || aMedDescr[nInd].Name.equalsAscii( "StartPresentation" )
		  || aMedDescr[nInd].Name.equalsAscii( "RepairPackage" )
		  || aMedDescr[nInd].Name.equalsAscii( "StatusIndicator" )
		  || aMedDescr[nInd].Name.equalsAscii( "ViewData" )
		  || aMedDescr[nInd].Name.equalsAscii( "ViewId" )
		  || aMedDescr[nInd].Name.equalsAscii( "MacroExecutionMode" )
		  || aMedDescr[nInd].Name.equalsAscii( "UpdateDocMode" )
		  || (aMedDescr[nInd].Name.equalsAscii( "DocumentBaseURL" ) && bCanUseDocumentBaseURL) )
		{
			aResult.realloc( ++nResLen );
			aResult[nResLen-1] = aMedDescr[nInd];
		}
	}

	return aResult;
}

//------------------------------------------------------
uno::Sequence< beans::PropertyValue > addAsTemplate( const uno::Sequence< beans::PropertyValue >& aOrig )
{
	sal_Bool bAsTemplateSet = sal_False;
	sal_Int32 nLength = aOrig.getLength();
	uno::Sequence< beans::PropertyValue > aResult( nLength );

	for ( sal_Int32 nInd = 0; nInd < nLength; nInd++ )
	{
		aResult[nInd].Name = aOrig[nInd].Name;
		if ( aResult[nInd].Name.equalsAscii( "AsTemplate" ) )
		{
			aResult[nInd].Value <<= sal_True;
			bAsTemplateSet = sal_True;
		}
		else
			aResult[nInd].Value = aOrig[nInd].Value;
	}

	if ( !bAsTemplateSet )
	{
		aResult.realloc( nLength + 1 );
		aResult[nLength].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
		aResult[nLength].Value <<= sal_True;
	}

	return aResult;
}

//------------------------------------------------------
uno::Reference< io::XInputStream > createTempInpStreamFromStor(
															const uno::Reference< embed::XStorage >& xStorage,
															const uno::Reference< lang::XMultiServiceFactory >& xFactory )
{
	OSL_ENSURE( xStorage.is(), "The storage can not be empty!" );

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

	const ::rtl::OUString aServiceName ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.io.TempFile" ) );
	uno::Reference < io::XStream > xTempStream = uno::Reference < io::XStream > (
															xFactory->createInstance ( aServiceName ),
															uno::UNO_QUERY );
	if ( xTempStream.is() )
	{
		uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
					xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
					uno::UNO_QUERY );

		uno::Sequence< uno::Any > aArgs( 2 );
		aArgs[0] <<= xTempStream;
		aArgs[1] <<= embed::ElementModes::READWRITE;
		uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
														uno::UNO_QUERY );
		if ( !xTempStorage.is() )
			throw uno::RuntimeException(); // TODO:

		try
		{
			xStorage->copyToStorage( xTempStorage );
		} catch( uno::Exception& e )
		{
			throw embed::StorageWrappedTargetException(
						::rtl::OUString::createFromAscii( "Can't copy storage!" ),
						uno::Reference< uno::XInterface >(),
						uno::makeAny( e ) );
		}

		try {
			uno::Reference< lang::XComponent > xComponent( xTempStorage, uno::UNO_QUERY );
			OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
			if ( xComponent.is() )
				xComponent->dispose();
		}
		catch ( uno::Exception& )
		{
		}

		try {
			uno::Reference< io::XOutputStream > xTempOut = xTempStream->getOutputStream();
			if ( xTempOut.is() )
				xTempOut->closeOutput();
		}
		catch ( uno::Exception& )
		{
		}

		xResult = xTempStream->getInputStream();
	}

	return xResult;

}

//------------------------------------------------------
static void TransferMediaType( const uno::Reference< embed::XStorage >& i_rSource, const uno::Reference< embed::XStorage >& i_rTarget )
{
    try
    {
        const uno::Reference< beans::XPropertySet > xSourceProps( i_rSource, uno::UNO_QUERY_THROW );
        const uno::Reference< beans::XPropertySet > xTargetProps( i_rTarget, uno::UNO_QUERY_THROW );
        const ::rtl::OUString sMediaTypePropName( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
        xTargetProps->setPropertyValue( sMediaTypePropName, xSourceProps->getPropertyValue( sMediaTypePropName ) );
    }
    catch( const uno::Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

//------------------------------------------------------
static uno::Reference< util::XCloseable > CreateDocument( const uno::Reference< lang::XMultiServiceFactory >& _rxFactory,
    const ::rtl::OUString& _rDocumentServiceName, bool _bEmbeddedScriptSupport, const bool i_bDocumentRecoverySupport )
{
    ::comphelper::NamedValueCollection aArguments;
    aArguments.put( "EmbeddedObject", (sal_Bool)sal_True );
    aArguments.put( "EmbeddedScriptSupport", (sal_Bool)_bEmbeddedScriptSupport );
    aArguments.put( "DocumentRecoverySupport", (sal_Bool)i_bDocumentRecoverySupport );

    uno::Reference< uno::XInterface > xDocument;
    try
    {
        xDocument = _rxFactory->createInstanceWithArguments( _rDocumentServiceName, aArguments.getWrappedPropertyValues() );
    }
    catch( const uno::Exception& )
    {
        // if an embedded object implementation does not support XInitialization,
        // the default factory from cppuhelper will throw an
        // IllegalArgumentException when we try to create the instance with arguments.
        // Okay, so we fall back to creating the instance without any arguments.
        OSL_ASSERT("Consider implementing interface XInitialization to avoid duplicate construction");
        xDocument = _rxFactory->createInstance( _rDocumentServiceName );
    }

    return uno::Reference< util::XCloseable >( xDocument, uno::UNO_QUERY );
}

//------------------------------------------------------
static void SetDocToEmbedded( const uno::Reference< frame::XModel > xDocument, const ::rtl::OUString& aModuleName )
{
	if ( xDocument.is() )
	{
		uno::Sequence< beans::PropertyValue > aSeq( 1 );
		aSeq[0].Name = ::rtl::OUString::createFromAscii( "SetEmbedded" );
		aSeq[0].Value <<= sal_True;
		xDocument->attachResource( ::rtl::OUString(), aSeq );

		if ( aModuleName.getLength() )
		{
			try
			{
				uno::Reference< frame::XModule > xModule( xDocument, uno::UNO_QUERY_THROW );
				xModule->setIdentifier( aModuleName );
			}
			catch( uno::Exception& )
			{}
		}
	}
}

//------------------------------------------------------
void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
												  const uno::Reference< embed::XStorage >& xNewObjectStorage,
												  const ::rtl::OUString& aNewName )
{
	if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
	{
		OSL_ENSURE( xNewObjectStorage == m_xObjectStorage, "The storage must be the same!\n" );
		return;
	}

    uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
    OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );

    m_xObjectStorage = xNewObjectStorage;
    m_xParentStorage = xNewParentStorage;
    m_aEntryName = aNewName;

#ifdef USE_STORAGEBASED_DOCUMENT
	// the linked document should not be switched
	if ( !m_bIsLink )
	{
		uno::Reference< document::XStorageBasedDocument > xDoc( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
		if ( xDoc.is() )
            SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
	}
#endif

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

//------------------------------------------------------
void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStorage >& xNewParentStorage,
												  const ::rtl::OUString& aNewName )
{
	if ( xNewParentStorage == m_xParentStorage && aNewName.equals( m_aEntryName ) )
		return;

	sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;

	uno::Reference< embed::XStorage > xNewOwnStorage = xNewParentStorage->openStorageElement( aNewName, nStorageMode );
	OSL_ENSURE( xNewOwnStorage.is(), "The method can not return empty reference!" );

	SwitchOwnPersistence( xNewParentStorage, xNewOwnStorage, aNewName );
}

//------------------------------------------------------
void OCommonEmbeddedObject::EmbedAndReparentDoc_Impl( const uno::Reference< util::XCloseable >& i_rxDocument ) const
{
    SetDocToEmbedded( uno::Reference< frame::XModel >( i_rxDocument, uno::UNO_QUERY ), m_aModuleName );

    try
    {
        uno::Reference < container::XChild > xChild( i_rxDocument, uno::UNO_QUERY );
        if ( xChild.is() )
            xChild->setParent( m_xParent );
    }
    catch( const lang::NoSupportException & )
    {
        OSL_ENSURE( false, "OCommonEmbeddedObject::EmbedAndReparentDoc: cannot set parent at document!" );
    }
}

//------------------------------------------------------
uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
{
    uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
                                                m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );

	uno::Reference< frame::XModel > xModel( xDocument, uno::UNO_QUERY );
	uno::Reference< frame::XLoadable > xLoadable( xModel, uno::UNO_QUERY );
	if ( !xLoadable.is() )
		throw uno::RuntimeException();

	try
	{
		// set the document mode to embedded as the first action on document!!!
        EmbedAndReparentDoc_Impl( xDocument );

        // if we have a storage to recover the document from, do not use initNew, but instead load from that storage
        bool bInitNew = true;
        if ( m_xRecoveryStorage.is() )
        {
            uno::Reference< document::XStorageBasedDocument > xDoc( xLoadable, uno::UNO_QUERY );
            OSL_ENSURE( xDoc.is(), "OCommonEmbeddedObject::InitNewDocument_Impl: cannot recover from a storage when the document is not storage based!" );
            if ( xDoc.is() )
            {
                ::comphelper::NamedValueCollection aLoadArgs;
                FillDefaultLoadArgs_Impl( m_xRecoveryStorage, aLoadArgs );

                xDoc->loadFromStorage( m_xRecoveryStorage, aLoadArgs.getPropertyValues() );
                SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
                bInitNew = false;
            }
        }

        if ( bInitNew )
        {
		    // init document as a new
		    xLoadable->initNew();
        }
	    xModel->attachResource( xModel->getURL(), m_aDocMediaDescriptor );
	}
	catch( uno::Exception& )
	{
		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
		if ( xCloseable.is() )
		{
			try
			{
				xCloseable->close( sal_True );
			}
			catch( uno::Exception& )
			{
			}
		}

		throw; // TODO
	}

	return xDocument;
}

//------------------------------------------------------
uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
{
    uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
                                                m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );

	uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
	if ( !xLoadable.is() )
		throw uno::RuntimeException();

	sal_Int32 nLen = 2;
	uno::Sequence< beans::PropertyValue > aArgs( nLen );
	aArgs[0].Name = ::rtl::OUString::createFromAscii( "URL" );
	aArgs[0].Value <<= m_aLinkURL;
	aArgs[1].Name = ::rtl::OUString::createFromAscii( "FilterName" );
	aArgs[1].Value <<= m_aLinkFilterName;
	if ( m_bLinkHasPassword )
	{
		aArgs.realloc( ++nLen );
		aArgs[nLen-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) );
		aArgs[nLen-1].Value <<= m_aLinkPassword;
	}

	aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
	for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
	{
		aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
		aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
	}

	try
	{
		// the document is not really an embedded one, it is a link
        EmbedAndReparentDoc_Impl( xDocument );

		// load the document
		xLoadable->load( aArgs );

		if ( !m_bLinkHasPassword )
		{
			// check if there is a password to cache
			uno::Reference< frame::XModel > xModel( xLoadable, uno::UNO_QUERY_THROW );
			uno::Sequence< beans::PropertyValue > aProps = xModel->getArgs();
			for ( sal_Int32 nInd = 0; nInd < aProps.getLength(); nInd++ )
				if ( aProps[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) ) )
				  && ( aProps[nInd].Value >>= m_aLinkPassword ) )
				{
					m_bLinkHasPassword = sal_True;
					break;
				}
		}
	}
	catch( uno::Exception& )
	{
		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
		if ( xCloseable.is() )
		{
			try
			{
				xCloseable->close( sal_True );
			}
			catch( uno::Exception& )
			{
			}
		}

		throw; // TODO
	}

	return xDocument;

}

//------------------------------------------------------
::rtl::OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const
{
    ::rtl::OUString aFilterName = GetPresetFilterName();
    if ( !aFilterName.getLength() )
    {
        try {
	        ::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
            aFilterName = aHelper.GetDefaultFilterFromServiceName( GetDocumentServiceName(), nVersion );
        } catch( uno::Exception& )
        {}
    }

    return aFilterName;
}

//------------------------------------------------------
void OCommonEmbeddedObject::FillDefaultLoadArgs_Impl( const uno::Reference< embed::XStorage >& i_rxStorage,
        ::comphelper::NamedValueCollection& o_rLoadArgs ) const
{
    o_rLoadArgs.put( "DocumentBaseURL", GetBaseURL_Impl() );
    o_rLoadArgs.put( "HierarchicalDocumentName", m_aEntryName );
    o_rLoadArgs.put( "ReadOnly", m_bReadOnly );

    ::rtl::OUString aFilterName = GetFilterName( ::comphelper::OStorageHelper::GetXStorageFormat( i_rxStorage ) );
    OSL_ENSURE( aFilterName.getLength(), "OCommonEmbeddedObject::FillDefaultLoadArgs_Impl: Wrong document service name!" );
	if ( !aFilterName.getLength() )
		throw io::IOException();    // TODO: error message/code

    o_rLoadArgs.put( "FilterName", aFilterName );
}

//------------------------------------------------------
uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadDocumentFromStorage_Impl()
{
    ENSURE_OR_THROW( m_xObjectStorage.is(), "no object storage" );

    const uno::Reference< embed::XStorage > xSourceStorage( m_xRecoveryStorage.is() ? m_xRecoveryStorage : m_xObjectStorage );

    uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
                                                m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );

    //#i103460# ODF: take the size given from the parent frame as default
    uno::Reference< chart2::XChartDocument > xChart( xDocument, uno::UNO_QUERY );
    if( xChart.is() )
    {
        uno::Reference< embed::XVisualObject > xChartVisualObject( xChart, uno::UNO_QUERY );
        if( xChartVisualObject.is() )
            xChartVisualObject->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, m_aDefaultSizeForChart_In_100TH_MM );
    }

    uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
    uno::Reference< document::XStorageBasedDocument > xDoc
#ifdef USE_STORAGEBASED_DOCUMENT
            ( xDocument, uno::UNO_QUERY )
#endif
            ;
    if ( !xDoc.is() && !xLoadable.is() ) ///BUG: This should be || instead of && ?
		throw uno::RuntimeException();

    ::comphelper::NamedValueCollection aLoadArgs;
    FillDefaultLoadArgs_Impl( xSourceStorage, aLoadArgs );

	uno::Reference< io::XInputStream > xTempInpStream;
    if ( !xDoc.is() )
    {
        xTempInpStream = createTempInpStreamFromStor( xSourceStorage, m_xFactory );
        if ( !xTempInpStream.is() )
            throw uno::RuntimeException();

		::rtl::OUString aTempFileURL;
		try
		{
			// no need to let the file stay after the stream is removed since the embedded document
			// can not be stored directly
			uno::Reference< beans::XPropertySet > xTempStreamProps( xTempInpStream, uno::UNO_QUERY_THROW );
			xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL;
		}
		catch( uno::Exception& )
		{
		}

		OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" );

        aLoadArgs.put( "URL", aTempFileURL );
        aLoadArgs.put( "InputStream", xTempInpStream );
    }

	// aLoadArgs.put( "AsTemplate", sal_True );

    aLoadArgs.merge( m_aDocMediaDescriptor, true );

	try
	{
		// set the document mode to embedded as the first step!!!
        EmbedAndReparentDoc_Impl( xDocument );

        if ( xDoc.is() )
        {
            xDoc->loadFromStorage( xSourceStorage, aLoadArgs.getPropertyValues() );
            if ( xSourceStorage != m_xObjectStorage )
                SwitchDocToStorage_Impl( xDoc, m_xObjectStorage );
        }
        else
            xLoadable->load( aLoadArgs.getPropertyValues() );
	}
	catch( uno::Exception& )
	{
		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
		if ( xCloseable.is() )
		{
			try
			{
				xCloseable->close( sal_True );
			}
			catch( uno::Exception& )
			{
                DBG_UNHANDLED_EXCEPTION();
			}
		}

		throw; // TODO
	}

	return xDocument;
}

//------------------------------------------------------
uno::Reference< io::XInputStream > OCommonEmbeddedObject::StoreDocumentToTempStream_Impl(
																			sal_Int32 nStorageFormat,
																			const ::rtl::OUString& aBaseURL,
																			const ::rtl::OUString& aHierarchName )
{
	uno::Reference < io::XOutputStream > xTempOut(
				m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
				uno::UNO_QUERY );
	uno::Reference< io::XInputStream > aResult( xTempOut, uno::UNO_QUERY );

	if ( !xTempOut.is() || !aResult.is() )
		throw uno::RuntimeException(); // TODO:

    uno::Reference< frame::XStorable > xStorable;
	{
		osl::MutexGuard aGuard( m_aMutex );
		if ( m_pDocHolder )
			xStorable = uno::Reference< frame::XStorable > ( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
	}

	if( !xStorable.is() )
		throw uno::RuntimeException(); // TODO:

	::rtl::OUString aFilterName = GetFilterName( nStorageFormat );

	OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
	if ( !aFilterName.getLength() )
		throw io::IOException(); // TODO:

	uno::Sequence< beans::PropertyValue > aArgs( 4 );
	aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
	aArgs[0].Value <<= aFilterName;
	aArgs[1].Name = ::rtl::OUString::createFromAscii( "OutputStream" );
	aArgs[1].Value <<= xTempOut;
	aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
	aArgs[2].Value <<= aBaseURL;
	aArgs[3].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
	aArgs[3].Value <<= aHierarchName;

	xStorable->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aArgs );
	try
	{
		xTempOut->closeOutput();
	}
	catch( uno::Exception& )
	{
		OSL_ENSURE( sal_False, "Looks like stream was closed already" );
	}

	return aResult;
}

//------------------------------------------------------
void OCommonEmbeddedObject::SaveObject_Impl()
{
	if ( m_xClientSite.is() )
	{
		try
		{
			// check whether the component is modified,
			// if not there is no need for storing
    		uno::Reference< util::XModifiable > xModifiable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
			if ( xModifiable.is() && !xModifiable->isModified() )
				return;
		}
		catch( uno::Exception& )
		{}

		try {
			m_xClientSite->saveObject();
		}
		catch( uno::Exception& )
		{
			OSL_ENSURE( sal_False, "The object was not stored!\n" );
		}
	}
}

//------------------------------------------------------
::rtl::OUString OCommonEmbeddedObject::GetBaseURL_Impl() const
{
	::rtl::OUString aBaseURL;
	sal_Int32 nInd = 0;

	if ( m_xClientSite.is() )
	{
		try
		{
			uno::Reference< frame::XModel > xParentModel( m_xClientSite->getComponent(), uno::UNO_QUERY_THROW );
			uno::Sequence< beans::PropertyValue > aModelProps = xParentModel->getArgs();
			for ( nInd = 0; nInd < aModelProps.getLength(); nInd++ )
				if ( aModelProps[nInd].Name.equals(
												::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
				{
					aModelProps[nInd].Value >>= aBaseURL;
					break;
				}


		}
		catch( uno::Exception& )
		{}
	}

	if ( !aBaseURL.getLength() )
	{
		for ( nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
			if ( m_aDocMediaDescriptor[nInd].Name.equals(
												::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
			{
				m_aDocMediaDescriptor[nInd].Value >>= aBaseURL;
				break;
			}
	}

	if ( !aBaseURL.getLength() )
		aBaseURL = m_aDefaultParentBaseURL;

	return aBaseURL;
}

//------------------------------------------------------
::rtl::OUString OCommonEmbeddedObject::GetBaseURLFrom_Impl(
					const uno::Sequence< beans::PropertyValue >& lArguments,
					const uno::Sequence< beans::PropertyValue >& lObjArgs )
{
	::rtl::OUString aBaseURL;
	sal_Int32 nInd = 0;

	for ( nInd = 0; nInd < lArguments.getLength(); nInd++ )
		if ( lArguments[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentBaseURL" ) ) ) )
		{
			lArguments[nInd].Value >>= aBaseURL;
			break;
		}

	if ( !aBaseURL.getLength() )
	{
		for ( nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
			if ( lObjArgs[nInd].Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultParentBaseURL" ) ) ) )
			{
				lObjArgs[nInd].Value >>= aBaseURL;
				break;
			}
	}

	return aBaseURL;
}


//------------------------------------------------------
void OCommonEmbeddedObject::SwitchDocToStorage_Impl( const uno::Reference< document::XStorageBasedDocument >& xDoc, const uno::Reference< embed::XStorage >& xStorage )
{
	xDoc->switchToStorage( xStorage );

    uno::Reference< util::XModifiable > xModif( xDoc, uno::UNO_QUERY );
	if ( xModif.is() )
		xModif->setModified( sal_False );

    if ( m_xRecoveryStorage.is() )
        m_xRecoveryStorage.clear();
}

//------------------------------------------------------
void OCommonEmbeddedObject::StoreDocToStorage_Impl( const uno::Reference< embed::XStorage >& xStorage,
													sal_Int32 nStorageFormat,
													const ::rtl::OUString& aBaseURL,
													const ::rtl::OUString& aHierarchName,
													sal_Bool bAttachToTheStorage )
{
	OSL_ENSURE( xStorage.is(), "No storage is provided for storing!" );

	if ( !xStorage.is() )
		throw uno::RuntimeException(); // TODO:

#ifdef USE_STORAGEBASED_DOCUMENT
    uno::Reference< document::XStorageBasedDocument > xDoc;
	{
		osl::MutexGuard aGuard( m_aMutex );
		if ( m_pDocHolder )
			xDoc = uno::Reference< document::XStorageBasedDocument >( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
	}

    if ( xDoc.is() )
    {
	    ::rtl::OUString aFilterName = GetFilterName( nStorageFormat );

        OSL_ENSURE( aFilterName.getLength(), "Wrong document service name!" );
        if ( !aFilterName.getLength() )
            throw io::IOException(); // TODO:

        uno::Sequence< beans::PropertyValue > aArgs( 3 );
        aArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
        aArgs[0].Value <<= aFilterName;
        aArgs[2].Name = ::rtl::OUString::createFromAscii( "DocumentBaseURL" );
        aArgs[2].Value <<= aBaseURL;
        aArgs[1].Name = ::rtl::OUString::createFromAscii( "HierarchicalDocumentName" );
        aArgs[1].Value <<= aHierarchName;

        xDoc->storeToStorage( xStorage, aArgs );
		if ( bAttachToTheStorage )
            SwitchDocToStorage_Impl( xDoc, xStorage );
    }
    else
#endif
    {
        // store document to temporary stream based on temporary file
        uno::Reference < io::XInputStream > xTempIn = StoreDocumentToTempStream_Impl( nStorageFormat, aBaseURL, aHierarchName );

        OSL_ENSURE( xTempIn.is(), "The stream reference can not be empty!\n" );

        // open storage based on document temporary file for reading
        uno::Reference < lang::XSingleServiceFactory > xStorageFactory(
                    m_xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ),
                    uno::UNO_QUERY );

        uno::Sequence< uno::Any > aArgs(1);
        aArgs[0] <<= xTempIn;
        uno::Reference< embed::XStorage > xTempStorage( xStorageFactory->createInstanceWithArguments( aArgs ),
                                                            uno::UNO_QUERY );
        if ( !xTempStorage.is() )
            throw uno::RuntimeException(); // TODO:

        // object storage must be commited automatically
        xTempStorage->copyToStorage( xStorage );
    }
}

//------------------------------------------------------
uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateDocFromMediaDescr_Impl(
										const uno::Sequence< beans::PropertyValue >& aMedDescr )
{
    uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xFactory, GetDocumentServiceName(),
                                                m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );

	uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY );
	if ( !xLoadable.is() )
		throw uno::RuntimeException();

	try
	{
		// set the document mode to embedded as the first action on the document!!!
        EmbedAndReparentDoc_Impl( xDocument );

		xLoadable->load( addAsTemplate( aMedDescr ) );
	}
	catch( uno::Exception& )
	{
		uno::Reference< util::XCloseable > xCloseable( xDocument, uno::UNO_QUERY );
		if ( xCloseable.is() )
		{
			try
			{
				xCloseable->close( sal_True );
			}
			catch( uno::Exception& )
			{
			}
		}

		throw; // TODO
	}

	return xDocument;
}

//------------------------------------------------------
uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_Impl()
{
    uno::Reference< util::XCloseable > xResult;

	OSL_ENSURE( m_bIsLink, "The object is not a linked one!\n" );

	uno::Sequence< beans::PropertyValue > aTempMediaDescr;

	sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
	try {
		nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
	}
	catch ( beans::IllegalTypeException& )
	{
		// the container just has an unknown type, use current file format
	}
	catch ( uno::Exception& )
	{
		OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" );
	}

    if ( m_pDocHolder->GetComponent().is() )
	{
		aTempMediaDescr.realloc( 4 );

		// TODO/LATER: may be private:stream should be used as target URL
		::rtl::OUString aTempFileURL;
		uno::Reference< io::XInputStream > xTempStream = StoreDocumentToTempStream_Impl( SOFFICE_FILEFORMAT_CURRENT,
																						 ::rtl::OUString(),
																						 ::rtl::OUString() );
		try
		{
			// no need to let the file stay after the stream is removed since the embedded document
			// can not be stored directly
			uno::Reference< beans::XPropertySet > xTempStreamProps( xTempStream, uno::UNO_QUERY_THROW );
			xTempStreamProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) ) >>= aTempFileURL;
		}
		catch( uno::Exception& )
		{
		}

		OSL_ENSURE( aTempFileURL.getLength(), "Coudn't retrieve temporary file URL!\n" );

		aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
		aTempMediaDescr[0].Value <<= aTempFileURL;
		aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "InputStream" );
		aTempMediaDescr[1].Value <<= xTempStream;
		aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "FilterName" );
		aTempMediaDescr[2].Value <<= GetFilterName( nStorageFormat );
		aTempMediaDescr[3].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
		aTempMediaDescr[3].Value <<= sal_True;
	}
	else
	{
		aTempMediaDescr.realloc( 2 );
		aTempMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
		aTempMediaDescr[0].Value <<= m_aLinkURL;
		aTempMediaDescr[1].Name = ::rtl::OUString::createFromAscii( "FilterName" );
		aTempMediaDescr[1].Value <<= m_aLinkFilterName;
		// aTempMediaDescr[2].Name = ::rtl::OUString::createFromAscii( "AsTemplate" );
		// aTempMediaDescr[2].Value <<= sal_True;
	}

	xResult = CreateDocFromMediaDescr_Impl( aTempMediaDescr );

	return xResult;
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::setPersistentEntry(
					const uno::Reference< embed::XStorage >& xStorage,
					const ::rtl::OUString& sEntName,
					sal_Int32 nEntryConnectionMode,
					const uno::Sequence< beans::PropertyValue >& lArguments,
					const uno::Sequence< beans::PropertyValue >& lObjArgs )
		throw ( lang::IllegalArgumentException,
				embed::WrongStateException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::setPersistentEntry" );

	// the type of the object must be already set
	// a kind of typedetection should be done in the factory

	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											1 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											2 );

	// May be LOADED should be forbidden here ???
	if ( ( m_nObjectState != -1 || nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
	  && ( m_nObjectState == -1 || nEntryConnectionMode != embed::EntryInitModes::NO_INIT ) )
	{
		// if the object is not loaded
		// it can not get persistant representation without initialization

		// if the object is loaded
		// it can switch persistant representation only without initialization

		throw embed::WrongStateException(
					::rtl::OUString::createFromAscii( "Can't change persistant representation of activated object!\n" ),
					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
	}

    if ( m_bWaitSaveCompleted )
	{
		if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
        {
            // saveCompleted is expected, handle it accordingly
            if ( m_xNewParentStorage == xStorage && m_aNewEntryName.equals( sEntName ) )
            {
                saveCompleted( sal_True );
                return;
            }

            // if a completely different entry is provided, switch first back to the old persistence in saveCompleted
            // and then switch to the target persistence
            sal_Bool bSwitchFurther = ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) );
			saveCompleted( sal_False );
            if ( !bSwitchFurther )
                return;
        }
		else
			throw embed::WrongStateException(
						::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ),
						uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
	}

	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
	if ( m_bIsLink )
	{
		m_aEntryName = sEntName;
		return;
	}

	uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
	if ( !xNameAccess.is() )
		throw uno::RuntimeException(); //TODO

	// detect entry existence
	sal_Bool bElExists = xNameAccess->hasByName( sEntName );

	m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments,
												  nEntryConnectionMode != embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT );

	m_bReadOnly = sal_False;
	for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
		if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
			lArguments[nInd].Value >>= m_bReadOnly;

	// TODO: use lObjArgs for StoreVisualReplacement
	for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
		if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
		{
			uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
			if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
				m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );
		}
		else if ( lObjArgs[nObjInd].Name.equalsAscii( "DefaultParentBaseURL" ) )
		{
			lObjArgs[nObjInd].Value >>= m_aDefaultParentBaseURL;
		}
        else if ( lObjArgs[nObjInd].Name.equalsAscii( "Parent" ) )
		{
            lObjArgs[nObjInd].Value >>= m_xParent;
		}
        else if ( lObjArgs[nObjInd].Name.equalsAscii( "IndividualMiscStatus" ) )
		{
            sal_Int64 nMiscStatus=0;
            lObjArgs[nObjInd].Value >>= nMiscStatus;
            m_nMiscStatus |= nMiscStatus;
		}
        else if ( lObjArgs[nObjInd].Name.equalsAscii( "CloneFrom" ) )
        {
            uno::Reference < embed::XEmbeddedObject > xObj;
            lObjArgs[nObjInd].Value >>= xObj;
            if ( xObj.is() )
            {
                m_bHasClonedSize = sal_True;
                m_aClonedSize = xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT );
                m_nClonedMapUnit = xObj->getMapUnit( embed::Aspects::MSOLE_CONTENT );
            }
        }
        else if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceFrameProperties" ) )
		{
			uno::Sequence< uno::Any > aOutFrameProps;
            uno::Sequence< beans::NamedValue > aOutFramePropsTyped;
			if ( lObjArgs[nObjInd].Value >>= aOutFrameProps )
            {
				m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
            }
            else if ( lObjArgs[nObjInd].Value >>= aOutFramePropsTyped )
            {
                aOutFrameProps.realloc( aOutFramePropsTyped.getLength() );
                uno::Any* pProp = aOutFrameProps.getArray();
                for (   const beans::NamedValue* pTypedProp = aOutFramePropsTyped.getConstArray();
                        pTypedProp != aOutFramePropsTyped.getConstArray() + aOutFramePropsTyped.getLength();
                        ++pTypedProp, ++pProp
                    )
                {
                    *pProp <<= *pTypedProp;
                }
				m_pDocHolder->SetOutplaceFrameProperties( aOutFrameProps );
            }
            else
                OSL_ENSURE( false, "OCommonEmbeddedObject::setPersistentEntry: illegal type for argument 'OutplaceFrameProperties'!" );
		}
		else if ( lObjArgs[nObjInd].Name.equalsAscii( "ModuleName" ) )
		{
			lObjArgs[nObjInd].Value >>= m_aModuleName;
		}
		else if ( lObjArgs[nObjInd].Name.equalsAscii( "EmbeddedScriptSupport" ) )
        {
			OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bEmbeddedScriptSupport );
        }
		else if ( lObjArgs[nObjInd].Name.equalsAscii( "DocumentRecoverySupport" ) )
        {
			OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_bDocumentRecoverySupport );
        }
        else if ( lObjArgs[nObjInd].Name.equalsAscii( "RecoveryStorage" ) )
        {
			OSL_VERIFY( lObjArgs[nObjInd].Value >>= m_xRecoveryStorage );
        }


	sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;

	SwitchOwnPersistence( xStorage, sEntName );

	if ( nEntryConnectionMode == embed::EntryInitModes::DEFAULT_INIT )
	{
		if ( bElExists )
		{
			// the initialization from existing storage allows to leave object in loaded state
			m_nObjectState = embed::EmbedStates::LOADED;
		}
		else
		{
            m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );
            if ( !m_pDocHolder->GetComponent().is() )
				throw io::IOException(); // TODO: can not create document

			m_nObjectState = embed::EmbedStates::RUNNING;
		}
	}
	else
	{
		if ( ( nStorageMode & embed::ElementModes::READWRITE ) != embed::ElementModes::READWRITE )
			throw io::IOException();

		if ( nEntryConnectionMode == embed::EntryInitModes::NO_INIT )
		{
			// the document just already changed its storage to store to
			// the links to OOo documents for now ignore this call
			// TODO: OOo links will have persistence so it will be switched here
		}
		else if ( nEntryConnectionMode == embed::EntryInitModes::TRUNCATE_INIT )
		{
            if ( m_xRecoveryStorage.is() )
                TransferMediaType( m_xRecoveryStorage, m_xObjectStorage );

			// TODO:
            m_pDocHolder->SetComponent( InitNewDocument_Impl(), m_bReadOnly );

            if ( !m_pDocHolder->GetComponent().is() )
				throw io::IOException(); // TODO: can not create document

			m_nObjectState = embed::EmbedStates::RUNNING;
		}
		else if ( nEntryConnectionMode == embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT )
		{
            m_pDocHolder->SetComponent( CreateDocFromMediaDescr_Impl( lArguments ), m_bReadOnly );
			m_nObjectState = embed::EmbedStates::RUNNING;
		}
		//else if ( nEntryConnectionMode == embed::EntryInitModes::TRANSFERABLE_INIT )
		//{
			//TODO:
		//}
		else
			throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Wrong connection mode is provided!\n" ),
										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
										3 );
	}
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::XStorage >& xStorage,
							const ::rtl::OUString& sEntName,
							const uno::Sequence< beans::PropertyValue >& lArguments,
							const uno::Sequence< beans::PropertyValue >& lObjArgs )
		throw ( lang::IllegalArgumentException,
				embed::WrongStateException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeToEntry" );

	::osl::ResettableMutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( m_nObjectState == -1 )
	{
		// the object is still not loaded
		throw embed::WrongStateException( ::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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
	if ( m_bIsLink )
		return;

	OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );

	sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
	sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
	try {
		nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
	}
	catch ( beans::IllegalTypeException& )
	{
		// the container just has an unknown type, use current file format
	}
	catch ( uno::Exception& )
	{
		OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" );
	}

	try
	{
		nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
	}
	catch ( beans::IllegalTypeException& )
	{
		// the container just has an unknown type, use current file format
	}
	catch ( uno::Exception& )
	{
		OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" );
	}

	sal_Bool bTryOptimization = sal_False;
	for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
	{
		// StoreVisualReplacement and VisualReplacement args have no sence here
		if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
			lObjArgs[nInd].Value >>= bTryOptimization;
	}

	sal_Bool bSwitchBackToLoaded = sal_False;

	// Storing to different format can be done only in running state.
	if ( m_nObjectState == embed::EmbedStates::LOADED )
	{
		// TODO/LATER: copying is not legal for documents with relative links.
		if ( nTargetStorageFormat == nOriginalStorageFormat )
		{
			sal_Bool bOptimizationWorks = sal_False;
			if ( bTryOptimization )
			{
				try
				{
					// try to use optimized copying
					uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
					uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
					xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
					bOptimizationWorks = sal_True;
				}
				catch( uno::Exception& )
				{
				}
			}

			if ( !bOptimizationWorks )
				m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
		}
		else
		{
			changeState( embed::EmbedStates::RUNNING );
			bSwitchBackToLoaded = sal_True;
		}
	}

	if ( m_nObjectState != embed::EmbedStates::LOADED )
	{
		uno::Reference< embed::XStorage > xSubStorage =
					xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );

		if ( !xSubStorage.is() )
			throw uno::RuntimeException(); //TODO

		aGuard.clear();
		// TODO/LATER: support hierarchical name for embedded objects in embedded objects
		StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
		aGuard.reset();

		if ( bSwitchBackToLoaded )
			changeState( embed::EmbedStates::LOADED );
	}

	// TODO: should the listener notification be done?
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::XStorage >& xStorage,
							const ::rtl::OUString& sEntName,
							const uno::Sequence< beans::PropertyValue >& lArguments,
							const uno::Sequence< beans::PropertyValue >& lObjArgs )
		throw ( lang::IllegalArgumentException,
				embed::WrongStateException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeAsEntry" );

	// TODO: use lObjArgs

	::osl::ResettableMutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( m_nObjectState == -1 )
	{
		// the object is still not loaded
		throw embed::WrongStateException( ::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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
	if ( m_bIsLink )
	{
    	m_aNewEntryName = sEntName;
		return;
	}

	OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );

	sal_Int32 nTargetStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
	sal_Int32 nOriginalStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
	try {
		nTargetStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( xStorage );
	}
	catch ( beans::IllegalTypeException& )
	{
		// the container just has an unknown type, use current file format
	}
	catch ( uno::Exception& )
	{
		OSL_ENSURE( sal_False, "Can not retrieve target storage media type!\n" );
	}

	try
	{
		nOriginalStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
	}
	catch ( beans::IllegalTypeException& )
	{
		// the container just has an unknown type, use current file format
	}
	catch ( uno::Exception& )
	{
		OSL_ENSURE( sal_False, "Can not retrieve own storage media type!\n" );
	}

	PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAs" ) );

	sal_Bool bTryOptimization = sal_False;
	for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
	{
		// StoreVisualReplacement and VisualReplacement args have no sence here
		if ( lObjArgs[nInd].Name.equalsAscii( "CanTryOptimization" ) )
			lObjArgs[nInd].Value >>= bTryOptimization;
	}

	sal_Bool bSwitchBackToLoaded = sal_False;

	// Storing to different format can be done only in running state.
	if ( m_nObjectState == embed::EmbedStates::LOADED )
	{
		// TODO/LATER: copying is not legal for documents with relative links.
		if ( nTargetStorageFormat == nOriginalStorageFormat )
		{
			sal_Bool bOptimizationWorks = sal_False;
			if ( bTryOptimization )
			{
				try
				{
					// try to use optimized copying
					uno::Reference< embed::XOptimizedStorage > xSource( m_xParentStorage, uno::UNO_QUERY_THROW );
					uno::Reference< embed::XOptimizedStorage > xTarget( xStorage, uno::UNO_QUERY_THROW );
					xSource->copyElementDirectlyTo( m_aEntryName, xTarget, sEntName );
					bOptimizationWorks = sal_True;
				}
				catch( uno::Exception& )
				{
				}
			}

			if ( !bOptimizationWorks )
				m_xParentStorage->copyElementTo( m_aEntryName, xStorage, sEntName );
		}
		else
		{
			changeState( embed::EmbedStates::RUNNING );
			bSwitchBackToLoaded = sal_True;
		}
	}

	uno::Reference< embed::XStorage > xSubStorage =
				xStorage->openStorageElement( sEntName, embed::ElementModes::READWRITE );

	if ( !xSubStorage.is() )
		throw uno::RuntimeException(); //TODO

	if ( m_nObjectState != embed::EmbedStates::LOADED )
	{
		aGuard.clear();
		// TODO/LATER: support hierarchical name for embedded objects in embedded objects
		StoreDocToStorage_Impl( xSubStorage, nTargetStorageFormat, GetBaseURLFrom_Impl( lArguments, lObjArgs ), sEntName, sal_False );
		aGuard.reset();

		if ( bSwitchBackToLoaded )
			changeState( embed::EmbedStates::LOADED );
	}

	m_bWaitSaveCompleted = sal_True;
	m_xNewObjectStorage = xSubStorage;
	m_xNewParentStorage = xStorage;
    m_aNewEntryName = sEntName;
	m_aNewDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );

	// TODO: register listeners for storages above, in case thay are disposed
	// 		 an exception will be thrown on saveCompleted( true )

	// TODO: should the listener notification be done here or in saveCompleted?
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew )
		throw ( embed::WrongStateException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::saveCompleted" );

	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

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

	// for now support of this interface is required to allow breaking of links and converting them to normal embedded
	// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
	// OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!\n" );
	if ( m_bIsLink )
	{
		if ( bUseNew )
			m_aEntryName = m_aNewEntryName;
		m_aNewEntryName = ::rtl::OUString();
		return;
	}

	// it is allowed to call saveCompleted( false ) for nonstored objects
	if ( !m_bWaitSaveCompleted && !bUseNew )
		return;

	OSL_ENSURE( m_bWaitSaveCompleted, "Unexpected saveCompleted() call!\n" );
	if ( !m_bWaitSaveCompleted )
		throw io::IOException(); // TODO: illegal call

	OSL_ENSURE( m_xNewObjectStorage.is() && m_xNewParentStorage.is() , "Internal object information is broken!\n" );
	if ( !m_xNewObjectStorage.is() || !m_xNewParentStorage.is() )
		throw uno::RuntimeException(); // TODO: broken internal information

	if ( bUseNew )
	{
		SwitchOwnPersistence( m_xNewParentStorage, m_xNewObjectStorage, m_aNewEntryName );
		m_aDocMediaDescriptor = m_aNewDocMediaDescriptor;

		uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
		if ( xModif.is() )
			xModif->setModified( sal_False );

		PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveAsDone" ) );
	}
	else
	{
		try {
			uno::Reference< lang::XComponent > xComponent( m_xNewObjectStorage, uno::UNO_QUERY );
			OSL_ENSURE( xComponent.is(), "Wrong storage implementation!" );
			if ( xComponent.is() )
				xComponent->dispose();
		}
		catch ( uno::Exception& )
		{
		}
	}

	m_xNewObjectStorage = uno::Reference< embed::XStorage >();
	m_xNewParentStorage = uno::Reference< embed::XStorage >();
	m_aNewEntryName = ::rtl::OUString();
	m_aNewDocMediaDescriptor.realloc( 0 );
	m_bWaitSaveCompleted = sal_False;

	if ( bUseNew )
	{
		// TODO: notify listeners

		if ( m_nUpdateMode == embed::EmbedUpdateModes::ALWAYS_UPDATE )
		{
			// TODO: update visual representation
		}
	}
}

//------------------------------------------------------
sal_Bool SAL_CALL OCommonEmbeddedObject::hasEntry()
		throw ( embed::WrongStateException,
				uno::RuntimeException )
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

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

	if ( m_xObjectStorage.is() )
		return sal_True;

	return sal_False;
}

//------------------------------------------------------
::rtl::OUString SAL_CALL OCommonEmbeddedObject::getEntryName()
		throw ( embed::WrongStateException,
				uno::RuntimeException )
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( m_nObjectState == -1 )
	{
		// the object is still not loaded
		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	return m_aEntryName;
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::storeOwn()
		throw ( embed::WrongStateException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OCommonEmbeddedObject::storeOwn" );

	// during switching from Activated to Running and from Running to Loaded states the object will
	// ask container to store the object, the container has to make decision
	// to do so or not

	::osl::ResettableMutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( m_nObjectState == -1 )
	{
		// the object is still not loaded
		throw embed::WrongStateException( ::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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	if ( m_bReadOnly )
		throw io::IOException(); // TODO: access denied

	// nothing to do, if the object is in loaded state
	if ( m_nObjectState == embed::EmbedStates::LOADED )
		return;

	PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSave" ) );

    OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If an object is activated or in running state it must have a document!\n" );
    if ( !m_pDocHolder->GetComponent().is() )
		throw uno::RuntimeException();

	if ( m_bIsLink )
	{
		// TODO: just store the document to it's location
		uno::Reference< frame::XStorable > xStorable( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
		if ( !xStorable.is() )
			throw uno::RuntimeException(); // TODO

        // free the main mutex for the storing time
        aGuard.clear();

        xStorable->store();

        aGuard.reset();
	}
	else
	{
		OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!\n" );

		if ( !m_xObjectStorage.is() )
			throw io::IOException(); //TODO: access denied

		sal_Int32 nStorageFormat = SOFFICE_FILEFORMAT_CURRENT;
		try {
			nStorageFormat = ::comphelper::OStorageHelper::GetXStorageFormat( m_xParentStorage );
		}
		catch ( beans::IllegalTypeException& )
		{
			// the container just has an unknown type, use current file format
		}
		catch ( uno::Exception& )
		{
			OSL_ENSURE( sal_False, "Can not retrieve storage media type!\n" );
		}

		aGuard.clear();
		StoreDocToStorage_Impl( m_xObjectStorage, nStorageFormat, GetBaseURL_Impl(), m_aEntryName, sal_True );
		aGuard.reset();
	}

	uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
	if ( xModif.is() )
		xModif->setModified( sal_False );

	PostEvent_Impl( ::rtl::OUString::createFromAscii( "OnSaveDone" ) );
}

//------------------------------------------------------
sal_Bool SAL_CALL OCommonEmbeddedObject::isReadonly()
		throw ( embed::WrongStateException,
				uno::RuntimeException )
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( m_nObjectState == -1 )
	{
		// the object is still not loaded
		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	return m_bReadOnly;
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::reload(
				const uno::Sequence< beans::PropertyValue >& lArguments,
				const uno::Sequence< beans::PropertyValue >& lObjArgs )
		throw ( lang::IllegalArgumentException,
				embed::WrongStateException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	// TODO: use lObjArgs
	// for now this method is used only to switch readonly state

	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( m_nObjectState == -1 )
	{
		// the object is still not loaded
		throw embed::WrongStateException( ::rtl::OUString::createFromAscii( "The object persistence is not initialized!\n" ),
										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
	}

	if ( m_nObjectState != embed::EmbedStates::LOADED )
	{
		// the object is still not loaded
		throw embed::WrongStateException(
								::rtl::OUString::createFromAscii( "The object must be in loaded state to be reloaded!\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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	if ( m_bIsLink )
	{
		// reload of the link
		::rtl::OUString aOldLinkFilter = m_aLinkFilterName;

		::rtl::OUString aNewLinkFilter;
		for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
		{
			if ( lArguments[nInd].Name.equalsAscii( "URL" ) )
			{
				// the new URL
				lArguments[nInd].Value >>= m_aLinkURL;
				m_aLinkFilterName = ::rtl::OUString();
			}
			else if ( lArguments[nInd].Name.equalsAscii( "FilterName" ) )
			{
				lArguments[nInd].Value >>= aNewLinkFilter;
				m_aLinkFilterName = ::rtl::OUString();
			}
		}

		::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
		if ( !m_aLinkFilterName.getLength() )
		{
			if ( aNewLinkFilter.getLength() )
				m_aLinkFilterName = aNewLinkFilter;
			else
			{
				uno::Sequence< beans::PropertyValue > aArgs( 1 );
				aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
				aArgs[0].Value <<= m_aLinkURL;
				m_aLinkFilterName = aHelper.UpdateMediaDescriptorWithFilterName( aArgs, sal_False );
			}
		}

		if ( !aOldLinkFilter.equals( m_aLinkFilterName ) )
		{
			uno::Sequence< beans::NamedValue > aObject = aHelper.GetObjectPropsByFilter( m_aLinkFilterName );

			// TODO/LATER: probably the document holder could be cleaned explicitly as in the destructor
			m_pDocHolder->release();
			m_pDocHolder = NULL;

			LinkInit_Impl( aObject, lArguments, lObjArgs );
		}
	}
	
	m_aDocMediaDescriptor = GetValuableArgs_Impl( lArguments, sal_True );

	// TODO: use lObjArgs for StoreVisualReplacement
	for ( sal_Int32 nObjInd = 0; nObjInd < lObjArgs.getLength(); nObjInd++ )
		if ( lObjArgs[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) )
		{
			uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor;
			if ( lObjArgs[nObjInd].Value >>= xDispatchInterceptor )
				m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor );

			break;
		}

	// TODO:
	// when document allows reloading through API the object can be reloaded not only in loaded state

	sal_Bool bOldReadOnlyValue = m_bReadOnly;

	m_bReadOnly = sal_False;
	for ( sal_Int32 nInd = 0; nInd < lArguments.getLength(); nInd++ )
		if ( lArguments[nInd].Name.equalsAscii( "ReadOnly" ) )
			lArguments[nInd].Value >>= m_bReadOnly;

	if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLink )
	{
		// close own storage
		try {
			uno::Reference< lang::XComponent > xComponent( m_xObjectStorage, uno::UNO_QUERY );
			OSL_ENSURE( !m_xObjectStorage.is() || xComponent.is(), "Wrong storage implementation!" );
			if ( xComponent.is() )
				xComponent->dispose();
		}
		catch ( uno::Exception& )
		{
		}

		sal_Int32 nStorageMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
		m_xObjectStorage = m_xParentStorage->openStorageElement( m_aEntryName, nStorageMode );
	}
}

//------------------------------------------------------
void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XStorage >& xStorage,
												const ::rtl::OUString& sEntName )
		throw ( lang::IllegalArgumentException,
				embed::WrongStateException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( !m_bIsLink )
	{
		// it must be a linked initialized object
		throw embed::WrongStateException(
					::rtl::OUString::createFromAscii( "The object is not a valid linked object!\n" ),
					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );
	}
#if 0
	else
	{
		// the current implementation of OOo links does not implement this method since it does not implement
		// all the set of interfaces required for OOo embedded object ( XEmbedPersist is not supported ).
		throw io::IOException(); // TODO:
	}
#endif

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											1 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											2 );

	if ( !m_bIsLink || m_nObjectState == -1 )
	{
		// it must be a linked initialized object
		throw embed::WrongStateException(
					::rtl::OUString::createFromAscii( "The object is not a valid linked object!\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 >( static_cast< ::cppu::OWeakObject* >(this) ) );

	uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
	if ( !xNameAccess.is() )
		throw uno::RuntimeException(); //TODO

	// detect entry existence
	/*sal_Bool bElExists =*/ xNameAccess->hasByName( sEntName );

	m_bReadOnly = sal_False;
//	sal_Int32 nStorageMode = embed::ElementModes::READWRITE;

	if ( m_xParentStorage != xStorage || !m_aEntryName.equals( sEntName ) )
		SwitchOwnPersistence( xStorage, sEntName );

	// for linked object it means that it becomes embedded object
	// the document must switch it's persistence also

	// TODO/LATER: handle the case when temp doc can not be created
	// the document is a new embedded object so it must be marked as modified
    uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
    uno::Reference< util::XModifiable > xModif( m_pDocHolder->GetComponent(), uno::UNO_QUERY );
	if ( !xModif.is() )
		throw uno::RuntimeException();
	try
	{
		xModif->setModified( sal_True );
	}
	catch( uno::Exception& )
	{}

    m_pDocHolder->SetComponent( xDocument, m_bReadOnly );
    OSL_ENSURE( m_pDocHolder->GetComponent().is(), "If document cant be created, an exception must be thrown!\n" );

	if ( m_nObjectState == embed::EmbedStates::LOADED )
	{
		// the state is changed and can not be switched to loaded state back without saving
		m_nObjectState = embed::EmbedStates::RUNNING;
		StateChangeNotification_Impl( sal_False, embed::EmbedStates::LOADED, m_nObjectState, aGuard );
	}
	else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
		m_pDocHolder->Show();

	m_bIsLink = sal_False;
	m_aLinkFilterName = ::rtl::OUString();
	m_aLinkURL = ::rtl::OUString();
}

//------------------------------------------------------
sal_Bool SAL_CALL  OCommonEmbeddedObject::isLink()
		throw ( embed::WrongStateException,
				uno::RuntimeException )
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	// Actually this information is clear even in case object is wayting for saveCompleted
	// 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 m_bIsLink;
}

//------------------------------------------------------
::rtl::OUString SAL_CALL OCommonEmbeddedObject::getLinkURL()
		throw ( embed::WrongStateException,
				uno::Exception,
				uno::RuntimeException )
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	// Actually this information is clear even in case object is wayting for saveCompleted
	// 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) ) );

	if ( !m_bIsLink )
		throw embed::WrongStateException(
					::rtl::OUString::createFromAscii( "The object is not a link object!\n" ),
					uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) );

	return m_aLinkURL;
}

