/**************************************************************
 *
 * 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 sense 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(), "Couldn'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 committed 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(), "Couldn'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 persistent representation without initialization

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

		throw embed::WrongStateException(
					::rtl::OUString::createFromAscii( "Can't change persistent 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 sense 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 sense 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 can't 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;
}
