/**************************************************************
 *
 * 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_comphelper.hxx"
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/document/XLinkAuthorizer.hpp>
#include <com/sun/star/embed/XEmbedObjectCreator.hpp>
#include <com/sun/star/embed/XLinkCreator.hpp>
#include <com/sun/star/embed/XEmbedPersist.hpp>
#include <com/sun/star/embed/XLinkageSupport.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/embed/XOptimizedStorage.hpp>
#include <com/sun/star/embed/EntryInitModes.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/embed/Aspects.hpp>
#include <com/sun/star/embed/EmbedMisc.hpp>

#include <comphelper/seqstream.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/embeddedobjectcontainer.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/weakref.hxx>
#include <hash_map>
#include <algorithm>

#include <rtl/logfile.hxx>

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

namespace comphelper
{

struct hashObjectName_Impl
{
	size_t operator()(const ::rtl::OUString Str) const
	{
		return (size_t)Str.hashCode();
	}
};

struct eqObjectName_Impl
{
	sal_Bool operator()(const ::rtl::OUString Str1, const ::rtl::OUString Str2) const
	{
		return ( Str1 == Str2 );
	}
};

typedef std::hash_map
<
	::rtl::OUString,
	::com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >,
	hashObjectName_Impl,
	eqObjectName_Impl
>
EmbeddedObjectContainerNameMap;

struct EmbedImpl
{
	// TODO/LATER: remove objects from temp. Container storage when object is disposed
	EmbeddedObjectContainerNameMap maObjectContainer;
	uno::Reference < embed::XStorage > mxStorage;
	EmbeddedObjectContainer* mpTempObjectContainer;
	uno::Reference < embed::XStorage > mxImageStorage;
	uno::WeakReference < uno::XInterface > m_xModel;
	//EmbeddedObjectContainerNameMap maTempObjectContainer;
	//uno::Reference < embed::XStorage > mxTempStorage;

	/// bitfield
	bool mbOwnsStorage : 1;
	bool mbUserAllowsLinkUpdate : 1;

	const uno::Reference < embed::XStorage >& GetReplacements();
};

const uno::Reference < embed::XStorage >& EmbedImpl::GetReplacements()
{
	if ( !mxImageStorage.is() )
	{
		try
		{
			mxImageStorage = mxStorage->openStorageElement(
				::rtl::OUString::createFromAscii( "ObjectReplacements" ), embed::ElementModes::READWRITE );
		}
		catch ( uno::Exception& )
		{
			mxImageStorage = mxStorage->openStorageElement(
				::rtl::OUString::createFromAscii( "ObjectReplacements" ), embed::ElementModes::READ );
		}
	}

	if ( !mxImageStorage.is() )
		throw io::IOException();

	return mxImageStorage;
}

EmbeddedObjectContainer::EmbeddedObjectContainer()
{
	pImpl = new EmbedImpl;
	pImpl->mxStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
	pImpl->mbOwnsStorage = true;
	pImpl->mbUserAllowsLinkUpdate = true;
	pImpl->mpTempObjectContainer = 0;
}

EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor )
{
	pImpl = new EmbedImpl;
	pImpl->mxStorage = rStor;
	pImpl->mbOwnsStorage = false;
	pImpl->mbUserAllowsLinkUpdate = true;
	pImpl->mpTempObjectContainer = 0;
}

EmbeddedObjectContainer::EmbeddedObjectContainer( const uno::Reference < embed::XStorage >& rStor, const uno::Reference < uno::XInterface >& xModel )
{
	pImpl = new EmbedImpl;
	pImpl->mxStorage = rStor;
	pImpl->mbOwnsStorage = false;
	pImpl->mbUserAllowsLinkUpdate = true;
	pImpl->mpTempObjectContainer = 0;
	pImpl->m_xModel = xModel;
}

void EmbeddedObjectContainer::SwitchPersistence( const uno::Reference < embed::XStorage >& rStor )
{
	ReleaseImageSubStorage();

	if ( pImpl->mbOwnsStorage )
		pImpl->mxStorage->dispose();

	pImpl->mxStorage = rStor;
	pImpl->mbOwnsStorage = false;
}

sal_Bool EmbeddedObjectContainer::CommitImageSubStorage()
{
	if ( pImpl->mxImageStorage.is() )
	{
		try
		{
			sal_Bool bReadOnlyMode = sal_True;
			uno::Reference < beans::XPropertySet > xSet(pImpl->mxImageStorage,uno::UNO_QUERY);
			if ( xSet.is() )
			{
				// get the open mode from the parent storage
				sal_Int32 nMode = 0;
				uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("OpenMode") );
				if ( aAny >>= nMode )
					bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
			} // if ( xSet.is() )
			if ( !bReadOnlyMode )
			{
				uno::Reference< embed::XTransactedObject > xTransact( pImpl->mxImageStorage, uno::UNO_QUERY_THROW );
				xTransact->commit();
			}
		}
		catch( uno::Exception& )
		{
			return sal_False;
		}
	}

	return sal_True;
}

void EmbeddedObjectContainer::ReleaseImageSubStorage()
{
	CommitImageSubStorage();

	if ( pImpl->mxImageStorage.is() )
	{
		try
		{
			pImpl->mxImageStorage->dispose();
			pImpl->mxImageStorage = uno::Reference< embed::XStorage >();
		}
		catch( uno::Exception& )
		{
			OSL_ASSERT( "Problems releasing image substorage!\n" );
		}
	}
}

EmbeddedObjectContainer::~EmbeddedObjectContainer()
{
	ReleaseImageSubStorage();

	if ( pImpl->mbOwnsStorage )
		pImpl->mxStorage->dispose();

	delete pImpl->mpTempObjectContainer;
	delete pImpl;
}

void EmbeddedObjectContainer::CloseEmbeddedObjects()
{
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	while ( aIt != pImpl->maObjectContainer.end() )
	{
		uno::Reference < util::XCloseable > xClose( (*aIt).second, uno::UNO_QUERY );
		if ( xClose.is() )
		{
			try
			{
				xClose->close( sal_True );
			}
			catch ( uno::Exception& )
			{
			}
		}

		aIt++;
	}
}

::rtl::OUString EmbeddedObjectContainer::CreateUniqueObjectName()
{
	::rtl::OUString aPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") );
	::rtl::OUString aStr;
	sal_Int32 i=1;
	do
	{
		aStr = aPersistName;
		aStr += ::rtl::OUString::valueOf( i++ );
	}
	while( HasEmbeddedObject( aStr ) );
	// TODO/LATER: should we consider deleted objects?

	return aStr;
}

uno::Sequence < ::rtl::OUString > EmbeddedObjectContainer::GetObjectNames()
{
	uno::Sequence < ::rtl::OUString > aSeq( pImpl->maObjectContainer.size() );
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	sal_Int32 nIdx=0;
	while ( aIt != pImpl->maObjectContainer.end() )
		aSeq[nIdx++] = (*aIt++).first;
	return aSeq;
}

sal_Bool EmbeddedObjectContainer::HasEmbeddedObjects()
{
	return pImpl->maObjectContainer.size() != 0;
}

sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const ::rtl::OUString& rName )
{
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
	if ( aIt == pImpl->maObjectContainer.end() )
	{
		uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
		return xAccess->hasByName(rName);
	}
	else
		return sal_True;
}

sal_Bool EmbeddedObjectContainer::HasEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj )
{
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	while ( aIt != pImpl->maObjectContainer.end() )
	{
		if ( (*aIt).second == xObj )
			return sal_True;
		else
			aIt++;
	}

	return sal_False;
}

sal_Bool EmbeddedObjectContainer::HasInstantiatedEmbeddedObject( const ::rtl::OUString& rName )
{
	// allows to detect whether the object was already instantiated
	// currently the filter instantiate it on loading, so this method allows
	// to avoid objects pointing to the same persistence
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
	return ( aIt != pImpl->maObjectContainer.end() );
}

::rtl::OUString EmbeddedObjectContainer::GetEmbeddedObjectName( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj )
{
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	while ( aIt != pImpl->maObjectContainer.end() )
	{
		if ( (*aIt).second == xObj )
			return (*aIt).first;
		else
			aIt++;
	}

	OSL_ENSURE( 0, "Unknown object!" );
	return ::rtl::OUString();
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::GetEmbeddedObject( const ::rtl::OUString& rName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetEmbeddedObject" );

	OSL_ENSURE( !rName.isEmpty(), "Empty object name!");

	uno::Reference < embed::XEmbeddedObject > xObj;
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );

#if OSL_DEBUG_LEVEL > 1
	uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
	uno::Sequence< ::rtl::OUString> aSeq = xAccess->getElementNames();
	const ::rtl::OUString* pIter = aSeq.getConstArray();
	const ::rtl::OUString* pEnd  = pIter + aSeq.getLength();
	for(;pIter != pEnd;++pIter)
	{
		(void)*pIter;
	}
	OSL_ENSURE( aIt != pImpl->maObjectContainer.end() || xAccess->hasByName(rName), "Could not return object!" );
#endif

	// check if object was already created
	if ( aIt != pImpl->maObjectContainer.end() )
		xObj = (*aIt).second;
	else
		xObj = Get_Impl( rName, uno::Reference < embed::XEmbeddedObject >() );

	return xObj;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::Get_Impl( const ::rtl::OUString& rName, const uno::Reference < embed::XEmbeddedObject >& xCopy )
{
	uno::Reference < embed::XEmbeddedObject > xObj;
	try
	{
		// create the object from the storage
		uno::Reference < beans::XPropertySet > xSet( pImpl->mxStorage, uno::UNO_QUERY );
		sal_Bool bReadOnlyMode = sal_True;
		if ( xSet.is() )
		{
			// get the open mode from the parent storage
			sal_Int32 nMode = 0;
			uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("OpenMode") );
			if ( aAny >>= nMode )
				bReadOnlyMode = !(nMode & embed::ElementModes::WRITE );
		}

		// object was not added until now - should happen only by calling this method from "inside"
		//TODO/LATER: it would be good to detect an error when an object should be created already, but isn't (not an "inside" call)
		uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );
		uno::Sequence< beans::PropertyValue > aObjDescr( xCopy.is() ? 2 : 1 );
		aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
		aObjDescr[0].Value <<= pImpl->m_xModel.get();
		if ( xCopy.is() )
		{
			aObjDescr[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CloneFrom" ) );
			aObjDescr[1].Value <<= xCopy;
		}

		uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
		aMediaDescr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
		aMediaDescr[0].Value <<= bReadOnlyMode;
		xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromEntry(
				pImpl->mxStorage, rName,
				aMediaDescr, aObjDescr ), uno::UNO_QUERY );

		// insert object into my list
		AddEmbeddedObject( xObj, rName );
	}
	catch ( uno::Exception& )
	{
	}

	return xObj;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId,
			const uno::Sequence < beans::PropertyValue >& rArgs, ::rtl::OUString& rNewName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CreateEmbeddedObject" );

	if ( rNewName.isEmpty() )
		rNewName = CreateUniqueObjectName();

	OSL_ENSURE( !HasEmbeddedObject(rNewName), "Object to create already exists!");

	// create object from classid by inserting it into storage
	uno::Reference < embed::XEmbeddedObject > xObj;
	try
	{
		uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );

		uno::Sequence< beans::PropertyValue > aObjDescr( rArgs.getLength() + 1 );
		aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
		aObjDescr[0].Value <<= pImpl->m_xModel.get();
		::std::copy( rArgs.getConstArray(), rArgs.getConstArray() + rArgs.getLength(), aObjDescr.getArray() + 1 );
		xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew(
					rClassId, ::rtl::OUString(), pImpl->mxStorage, rNewName,
					aObjDescr ), uno::UNO_QUERY );

		AddEmbeddedObject( xObj, rNewName );

		OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
					"A freshly create object should be running always!\n" );
	}
	catch ( uno::Exception& )
	{
	}

	return xObj;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CreateEmbeddedObject( const uno::Sequence < sal_Int8 >& rClassId, ::rtl::OUString& rNewName )
{
	return CreateEmbeddedObject( rClassId, uno::Sequence < beans::PropertyValue >(), rNewName );
}

void EmbeddedObjectContainer::AddEmbeddedObject( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, const ::rtl::OUString& rName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::AddEmbeddedObject" );

#if OSL_DEBUG_LEVEL > 1
	OSL_ENSURE( !rName.isEmpty(), "Added object doesn't have a name!");
	uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
	uno::Reference < embed::XEmbedPersist > xEmb( xObj, uno::UNO_QUERY );
	uno::Reference < embed::XLinkageSupport > xLink( xEmb, uno::UNO_QUERY );
	// if the object has a persistence and the object is not a link than it must have persistence entry in the storage
	OSL_ENSURE( !( xEmb.is() && ( !xLink.is() || !xLink->isLink() ) ) || xAccess->hasByName(rName),
					"Added element not in storage!" );
#endif

	// remember object - it needs to be in storage already
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
	OSL_ENSURE( aIt == pImpl->maObjectContainer.end(), "Element already inserted!" );
	pImpl->maObjectContainer[ rName ] = xObj;
	uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
	if ( xChild.is() && xChild->getParent() != pImpl->m_xModel.get() )
		xChild->setParent( pImpl->m_xModel.get() );

	// look for object in temorary container
	if ( pImpl->mpTempObjectContainer )
	{
		aIt = pImpl->mpTempObjectContainer->pImpl->maObjectContainer.begin();
		while ( aIt != pImpl->mpTempObjectContainer->pImpl->maObjectContainer.end() )
		{
			if ( (*aIt).second == xObj )
			{
				// copy replacement image from temporary container (if there is any)
				::rtl::OUString aTempName = (*aIt).first;
				::rtl::OUString aMediaType;
				uno::Reference < io::XInputStream > xStream = pImpl->mpTempObjectContainer->GetGraphicStream( xObj, &aMediaType );
				if ( xStream.is() )
				{
					InsertGraphicStream( xStream, rName, aMediaType );
					xStream = 0;
					pImpl->mpTempObjectContainer->RemoveGraphicStream( aTempName );
				}

				// remove object from storage of temporary container
				uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
				if ( xPersist.is() )
				{
					try
					{
						pImpl->mpTempObjectContainer->pImpl->mxStorage->removeElement( aTempName );
					}
					catch ( uno::Exception& )
					{
					}
				}

				// temp. container needs to forget the object
				pImpl->mpTempObjectContainer->pImpl->maObjectContainer.erase( aIt );
				break;
			}
			else
				aIt++;
		}
	}
}

sal_Bool EmbeddedObjectContainer::StoreEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName, sal_Bool bCopy )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::StoreEmbeddedObject" );

	uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
	if ( rName.isEmpty() )
		rName = CreateUniqueObjectName();

#if OSL_DEBUG_LEVEL > 1
	uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
	OSL_ENSURE( !xPersist.is() || !xAccess->hasByName(rName), "Inserting element already present in storage!" );
	OSL_ENSURE( xPersist.is() || xObj->getCurrentState() == embed::EmbedStates::RUNNING, "Non persistent object inserted!");
#endif

	// insert objects' storage into the container storage (if object has one)
	try
	{
		if ( xPersist.is() )
		{
			uno::Sequence < beans::PropertyValue > aSeq;
			if ( bCopy )
				xPersist->storeToEntry( pImpl->mxStorage, rName, aSeq, aSeq );
			else
			{
				// TODO/LATER: possible optimization, don't store immediately
				//xPersist->setPersistentEntry( pImpl->mxStorage, rName, embed::EntryInitModes::ENTRY_NO_INIT, aSeq, aSeq );
				xPersist->storeAsEntry( pImpl->mxStorage, rName, aSeq, aSeq );
				xPersist->saveCompleted( sal_True );
			}
		}
	}
	catch ( uno::Exception& )
	{
		// TODO/LATER: better error recovery should keep storage intact
		return sal_False;
	}

	return sal_True;
}

sal_Bool EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( Object )" );
	// store it into the container storage
	if ( StoreEmbeddedObject( xObj, rName, sal_False ) )
	{
		// remember object
		AddEmbeddedObject( xObj, rName );
		return sal_True;
	}
	else
		return sal_False;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const uno::Reference < io::XInputStream >& xStm, ::rtl::OUString& rNewName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( InputStream )" );

	if ( rNewName.isEmpty() )
		rNewName = CreateUniqueObjectName();

	// store it into the container storage
	sal_Bool bIsStorage = sal_False;
	try
	{
		// first try storage persistence
		uno::Reference < embed::XStorage > xStore = ::comphelper::OStorageHelper::GetStorageFromInputStream( xStm );

		// storage was created from stream successfully
		bIsStorage = sal_True;

		uno::Reference < embed::XStorage > xNewStore = pImpl->mxStorage->openStorageElement( rNewName, embed::ElementModes::READWRITE );
		xStore->copyToStorage( xNewStore );
	}
	catch ( uno::Exception& )
	{
		if ( bIsStorage )
			// it is storage persistence, but opening of new substorage or copying to it failed
			return uno::Reference < embed::XEmbeddedObject >();

		// stream didn't contain a storage, now try stream persistence
		try
		{
			uno::Reference < io::XStream > xNewStream = pImpl->mxStorage->openStreamElement( rNewName, embed::ElementModes::READWRITE );
			::comphelper::OStorageHelper::CopyInputToOutput( xStm, xNewStream->getOutputStream() );

			// No mediatype is provided so the default for OLE objects value is used
			// it is correct so for now, but what if somebody introduces a new stream based embedded object?
			// Probably introducing of such an object must be restricted ( a storage must be used! ).
			uno::Reference< beans::XPropertySet > xProps( xNewStream, uno::UNO_QUERY_THROW );
			xProps->setPropertyValue(
					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
					uno::makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) );
		}
		catch ( uno::Exception& )
		{
			// complete disaster!
			return uno::Reference < embed::XEmbeddedObject >();
		}
	}

	// stream was copied into the container storage in either way, now try to open something form it
	uno::Reference < embed::XEmbeddedObject > xRet = GetEmbeddedObject( rNewName );
	try
	{
		if ( !xRet.is() )
			// no object could be created, so withdraw insertion
			pImpl->mxStorage->removeElement( rNewName );
	}
	catch ( uno::Exception& )
	{
	}

	return xRet;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedObject( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedObject( MediaDescriptor )" );

	if ( rNewName.isEmpty() )
		rNewName = CreateUniqueObjectName();

	uno::Reference < embed::XEmbeddedObject > xObj;
	try
	{
		uno::Reference < embed::XEmbedObjectCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );
		uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
		aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
		aObjDescr[0].Value <<= pImpl->m_xModel.get();
		xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitFromMediaDescriptor(
				pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );
		uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );

		OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
					"A freshly create object should be running always!\n" );

		// possible optimization: store later!
		if ( xPersist.is())
			xPersist->storeOwn();

		AddEmbeddedObject( xObj, rNewName );
	}
	catch ( uno::Exception& )
	{
	}

	return xObj;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::InsertEmbeddedLink( const ::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue >& aMedium, ::rtl::OUString& rNewName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertEmbeddedLink" );

	if ( rNewName.isEmpty() )
		rNewName = CreateUniqueObjectName();

	uno::Reference < embed::XEmbeddedObject > xObj;
	try
	{
		uno::Reference < embed::XLinkCreator > xFactory( ::comphelper::getProcessServiceFactory()->createInstance(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator")) ), uno::UNO_QUERY );
		uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
		aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
		uno::Any model( pImpl->m_xModel.get() );
		aObjDescr[0].Value <<= model;
		// The call to XLinkCreator::createInstanceLink() will open the link.
		// We must request for authorization now. And we need the URL for that.
		::rtl::OUString aURL;
		for ( sal_Int32 i = 0; i < aMedium.getLength(); i++ )
			if ( aMedium[i].Name.equalsAscii( "URL" ) )
				aMedium[i].Value >>= aURL;
		uno::Reference< com::sun::star::document::XLinkAuthorizer > xLinkAuthorizer( model, uno::UNO_QUERY );
		if ( xLinkAuthorizer.is() ) {
			if ( !xLinkAuthorizer->authorizeLinks( aURL ) )
				throw uno::RuntimeException();
		}
		xObj = uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceLink(
				pImpl->mxStorage, rNewName, aMedium, aObjDescr ), uno::UNO_QUERY );

		uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );

		OSL_ENSURE( !xObj.is() || xObj->getCurrentState() != embed::EmbedStates::LOADED,
					"A freshly create object should be running always!\n" );

		// possible optimization: store later!
		if ( xPersist.is())
			xPersist->storeOwn();

		AddEmbeddedObject( xObj, rNewName );
	}
	catch ( uno::Exception& )
	{
	}

	return xObj;
}

sal_Bool EmbeddedObjectContainer::TryToCopyGraphReplacement( EmbeddedObjectContainer& rSrc,
															const ::rtl::OUString& aOrigName,
															const ::rtl::OUString& aTargetName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::TryToCopyGraphReplacement" );

	sal_Bool bResult = sal_False;

	if ( ( &rSrc != this || !aOrigName.equals( aTargetName ) ) && !aOrigName.isEmpty() && !aTargetName.isEmpty() )
	{
		::rtl::OUString aMediaType;
		uno::Reference < io::XInputStream > xGrStream = rSrc.GetGraphicStream( aOrigName, &aMediaType );
		if ( xGrStream.is() )
			bResult = InsertGraphicStream( xGrStream, aTargetName, aMediaType );
	}

	return bResult;
}

sal_Bool EmbeddedObjectContainer::CopyEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyEmbeddedObject" );

	OSL_ENSURE( sal_False,
				"This method is deprecated! Use EmbeddedObjectContainer::CopyAndGetEmbeddedObject() to copy object!\n" );

	// get the object name before(!) it is assigned to a new storage
	::rtl::OUString aOrigName;
	uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
	if ( xPersist.is() )
		aOrigName = xPersist->getEntryName();

	if ( rName.isEmpty() )
		rName = CreateUniqueObjectName();

	if ( StoreEmbeddedObject( xObj, rName, sal_True ) )
	{
		TryToCopyGraphReplacement( rSrc, aOrigName, rName );
		return sal_True;
	}

	return sal_False;
}

uno::Reference < embed::XEmbeddedObject > EmbeddedObjectContainer::CopyAndGetEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CopyAndGetEmbeddedObject" );

	uno::Reference< embed::XEmbeddedObject > xResult;

	// TODO/LATER: For now only objects that implement XEmbedPersist have a replacement image, it might change in future
	// do an incompatible change so that object name is provided in all the move and copy methods
	::rtl::OUString aOrigName;
	try
	{
		uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY_THROW );
		aOrigName = xPersist->getEntryName();
	}
	catch( uno::Exception& )
	{}

	if ( rName.isEmpty() )
		rName = CreateUniqueObjectName();

	// objects without persistence are not really stored by the method
	if ( xObj.is() && StoreEmbeddedObject( xObj, rName, sal_True ) )
	{
		xResult = Get_Impl( rName, xObj);
		if ( !xResult.is() )
		{
			// this is a case when object has no real persistence
			// in such cases a new object should be explicitly created and initialized with the data of the old one
			try
			{
				uno::Reference< embed::XLinkageSupport > xOrigLinkage( xObj, uno::UNO_QUERY );
				if ( xOrigLinkage.is() && xOrigLinkage->isLink() )
				{
					// this is a OOo link, it has no persistence
					::rtl::OUString aURL = xOrigLinkage->getLinkURL();
					if ( aURL.isEmpty() )
						throw uno::RuntimeException();

					// create new linked object from the URL the link is based on
					uno::Reference < embed::XLinkCreator > xCreator(
						::comphelper::getProcessServiceFactory()->createInstance(
							::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ),
						uno::UNO_QUERY_THROW );

					uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
					aMediaDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
					aMediaDescr[0].Value <<= aURL;
					uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
					aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
					aObjDescr[0].Value <<= pImpl->m_xModel.get();
					xResult = uno::Reference < embed::XEmbeddedObject >(
								xCreator->createInstanceLink(
									pImpl->mxStorage,
									rName,
									aMediaDescr,
									aObjDescr ),
								uno::UNO_QUERY_THROW );
				}
				else
				{
					// the component is required for copying of this object
					if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
						xObj->changeState( embed::EmbedStates::RUNNING );

					// this must be an object based on properties, otherwise we can not copy it currently
					uno::Reference< beans::XPropertySet > xOrigProps( xObj->getComponent(), uno::UNO_QUERY_THROW );

					// use object class ID to create a new one and transfer all the properties
					uno::Reference < embed::XEmbedObjectCreator > xCreator(
						::comphelper::getProcessServiceFactory()->createInstance(
							::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.EmbeddedObjectCreator") ) ),
						uno::UNO_QUERY_THROW );

					uno::Sequence< beans::PropertyValue > aObjDescr( 1 );
					aObjDescr[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Parent" ) );
					aObjDescr[0].Value <<= pImpl->m_xModel.get();
					xResult = uno::Reference < embed::XEmbeddedObject >(
								xCreator->createInstanceInitNew(
									xObj->getClassID(),
									xObj->getClassName(),
									pImpl->mxStorage,
									rName,
									aObjDescr ),
								uno::UNO_QUERY_THROW );

					if ( xResult->getCurrentState() == embed::EmbedStates::LOADED )
						xResult->changeState( embed::EmbedStates::RUNNING );

					uno::Reference< beans::XPropertySet > xTargetProps( xResult->getComponent(), uno::UNO_QUERY_THROW );

					// copy all the properties from xOrigProps to xTargetProps
					uno::Reference< beans::XPropertySetInfo > xOrigInfo = xOrigProps->getPropertySetInfo();
					if ( !xOrigInfo.is() )
						throw uno::RuntimeException();

					uno::Sequence< beans::Property > aPropertiesList = xOrigInfo->getProperties();
					for ( sal_Int32 nInd = 0; nInd < aPropertiesList.getLength(); nInd++ )
					{
						try
						{
							xTargetProps->setPropertyValue(
								aPropertiesList[nInd].Name,
								xOrigProps->getPropertyValue( aPropertiesList[nInd].Name ) );
						}
						catch( beans::PropertyVetoException& )
						{
							// impossibility to copy readonly property is not treated as an error for now
							// but the assertion is helpful to detect such scenarios and review them
							OSL_ENSURE( sal_False, "Could not copy readonly property!\n" );
						}
					}
				}

				if ( xResult.is() )
					AddEmbeddedObject( xResult, rName );
			}
			catch( uno::Exception& )
			{
				if ( xResult.is() )
				{
					try
					{
						xResult->close( sal_True );
					}
					catch( uno::Exception& )
					{}
					xResult = uno::Reference< embed::XEmbeddedObject >();
				}
			}
		}
	}

	OSL_ENSURE( xResult.is(), "Can not copy embedded object that has no persistence!\n" );

	if ( xResult.is() )
	{
		// the object is successfully copied, try to copy graphical replacement
		if ( !aOrigName.isEmpty() )
			TryToCopyGraphReplacement( rSrc, aOrigName, rName );

		// the object might need the size to be set
		try
		{
			if ( xResult->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::EMBED_NEEDSSIZEONLOAD )
				xResult->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT,
											xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
		}
		catch( uno::Exception& )
		{}
	}

	return xResult;
}

sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( EmbeddedObjectContainer& rSrc, const uno::Reference < embed::XEmbeddedObject >& xObj, ::rtl::OUString& rName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Object )" );

	// get the object name before(!) it is assigned to a new storage
	uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
	::rtl::OUString aName;
	if ( xPersist.is() )
		aName = xPersist->getEntryName();

	// now move the object to the new container; the returned name is the new persist name in this container
	sal_Bool bRet;

	try
	{
		bRet = InsertEmbeddedObject( xObj, rName );
		if ( bRet )
			TryToCopyGraphReplacement( rSrc, aName, rName );
	}
	catch ( uno::Exception& e )
	{
		(void)e;
		OSL_ENSURE( sal_False, "Failed to insert embedded object into storage!" );
		bRet = sal_False;
	}

	if ( bRet )
	{
		// now remove the object from the former container
		bRet = sal_False;
		EmbeddedObjectContainerNameMap::iterator aIt = rSrc.pImpl->maObjectContainer.begin();
		while ( aIt != rSrc.pImpl->maObjectContainer.end() )
		{
			if ( (*aIt).second == xObj )
			{
				rSrc.pImpl->maObjectContainer.erase( aIt );
				bRet = sal_True;
				break;
			}

			aIt++;
		}

		OSL_ENSURE( bRet, "Object not found for removal!" );
		if ( xPersist.is() )
		{
			// now it's time to remove the storage from the container storage
			try
			{
				if ( xPersist.is() )
					rSrc.pImpl->mxStorage->removeElement( aName );
			}
			catch ( uno::Exception& )
			{
				OSL_ENSURE( sal_False, "Failed to remove object from storage!" );
				bRet = sal_False;
			}
		}

		// rSrc.RemoveGraphicStream( aName );
	}

	return bRet;
}

//sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose )
// #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+
sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const ::rtl::OUString& rName, sal_Bool bClose, sal_Bool bKeepToTempStorage )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Name )" );

	uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( rName );
	if ( xObj.is() )
		//return RemoveEmbeddedObject( xObj, bClose );
		return RemoveEmbeddedObject( xObj, bClose, bKeepToTempStorage );
	else
		return sal_False;
}

sal_Bool EmbeddedObjectContainer::MoveEmbeddedObject( const ::rtl::OUString& rName, EmbeddedObjectContainer& rCnt )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::MoveEmbeddedObject( Name )" );

	// find object entry
	EmbeddedObjectContainerNameMap::iterator aIt2 = rCnt.pImpl->maObjectContainer.find( rName );
	OSL_ENSURE( aIt2 == rCnt.pImpl->maObjectContainer.end(), "Object does already exist in target container!" );

	if ( aIt2 != rCnt.pImpl->maObjectContainer.end() )
		return sal_False;

	uno::Reference < embed::XEmbeddedObject > xObj;
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.find( rName );
	if ( aIt != pImpl->maObjectContainer.end() )
	{
		xObj = (*aIt).second;
		try
		{
			if ( xObj.is() )
			{
				// move object
				::rtl::OUString aName( rName );
				rCnt.InsertEmbeddedObject( xObj, aName );
				pImpl->maObjectContainer.erase( aIt );
				uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
				if ( xPersist.is() )
					pImpl->mxStorage->removeElement( rName );
			}
			else
			{
				// copy storages; object *must* have persistence!
				uno::Reference < embed::XStorage > xOld = pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READ );
				uno::Reference < embed::XStorage > xNew = rCnt.pImpl->mxStorage->openStorageElement( rName, embed::ElementModes::READWRITE );
				xOld->copyToStorage( xNew );
			}

			rCnt.TryToCopyGraphReplacement( *this, rName, rName );
			// RemoveGraphicStream( rName );

			return sal_True;
		}
		catch ( uno::Exception& )
		{
			OSL_ENSURE(0,"Could not move object!");
			return sal_False;
		}

	}
	else
		OSL_ENSURE(0,"Unknown object!");
	return sal_False;
}

//sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose )
// #i119941, bKeepToTempStorage: use to specify whether store the removed object to temporary storage+
sal_Bool EmbeddedObjectContainer::RemoveEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Bool bClose, sal_Bool bKeepToTempStorage )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveEmbeddedObject( Object )" );

	uno::Reference < embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
	::rtl::OUString aName;
	if ( xPersist.is() )
		aName = xPersist->getEntryName();

#if OSL_DEBUG_LEVEL > 1
	uno::Reference < container::XNameAccess > xAccess( pImpl->mxStorage, uno::UNO_QUERY );
	uno::Reference < embed::XLinkageSupport > xLink( xPersist, uno::UNO_QUERY );
	sal_Bool bIsNotEmbedded = !xPersist.is() || xLink.is() && xLink->isLink();

	// if the object has a persistence and the object is not a link than it must have persistence entry in the storage
	OSL_ENSURE( bIsNotEmbedded || xAccess->hasByName(aName), "Removing element not present in storage!" );
#endif

	// try to close it if permitted
	if ( bClose )
	{
		uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY );
		try
		{
			xClose->close( sal_True );
		}
		catch ( util::CloseVetoException& )
		{
			bClose = sal_False;
		}
	}

	if ( !bClose )
	{
		// somebody still needs the object, so we must assign a temporary persistence
		try
		{
		//	if ( xPersist.is() )
			if ( xPersist.is() && bKeepToTempStorage )	// #i119941
			{
				/*
				// TODO/LATER: needs storage handling! Why not letting the object do it?!
				if ( !pImpl->mxTempStorage.is() )
					pImpl->mxTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
				uno::Sequence < beans::PropertyValue > aSeq;

				::rtl::OUString aTmpPersistName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Object ") );
				aTmpPersistName += ::rtl::OUString::valueOf( (sal_Int32) pImpl->maTempObjectContainer.size() );

				xPersist->storeAsEntry( pImpl->mxTempStorage, aTmpPersistName, aSeq, aSeq );
				xPersist->saveCompleted( sal_True );

				pImpl->maTempObjectContainer[ aTmpPersistName ] = uno::Reference < embed::XEmbeddedObject >();
				*/

				if ( !pImpl->mpTempObjectContainer )
				{
					pImpl->mpTempObjectContainer = new EmbeddedObjectContainer();
					try
					{
						// TODO/LATER: in future probably the temporary container will have two storages ( of two formats )
						//             the media type will be provided with object insertion
						::rtl::OUString aOrigStorMediaType;
						uno::Reference< beans::XPropertySet > xStorProps( pImpl->mxStorage, uno::UNO_QUERY_THROW );
						static const ::rtl::OUString s_sMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
						xStorProps->getPropertyValue( s_sMediaType ) >>= aOrigStorMediaType;

						OSL_ENSURE( !aOrigStorMediaType.isEmpty(), "No valuable media type in the storage!\n" );

						uno::Reference< beans::XPropertySet > xTargetStorProps(
																	pImpl->mpTempObjectContainer->pImpl->mxStorage,
																	uno::UNO_QUERY_THROW );
						xTargetStorProps->setPropertyValue( s_sMediaType,uno::makeAny( aOrigStorMediaType ) );
					}
					catch( uno::Exception& )
					{
						OSL_ENSURE( sal_False, "Can not set the new media type to a storage!\n" );
					}
				}

				::rtl::OUString aTempName, aMediaType;
				pImpl->mpTempObjectContainer->InsertEmbeddedObject( xObj, aTempName );

				uno::Reference < io::XInputStream > xStream = GetGraphicStream( xObj, &aMediaType );
				if ( xStream.is() )
					pImpl->mpTempObjectContainer->InsertGraphicStream( xStream, aTempName, aMediaType );

				// object is stored, so at least it can be set to loaded state
				xObj->changeState( embed::EmbedStates::LOADED );
			}
			else
				// objects without persistence need to stay in running state if they shall not be closed
				xObj->changeState( embed::EmbedStates::RUNNING );
		}
		catch ( uno::Exception& )
		{
			return sal_False;
		}
	}

	sal_Bool bFound = sal_False;
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	while ( aIt != pImpl->maObjectContainer.end() )
	{
		if ( (*aIt).second == xObj )
		{
			pImpl->maObjectContainer.erase( aIt );
			bFound = sal_True;
			uno::Reference < container::XChild > xChild( xObj, uno::UNO_QUERY );
			if ( xChild.is() )
				xChild->setParent( uno::Reference < uno::XInterface >() );
			break;
		}

		aIt++;
	}

	OSL_ENSURE( bFound, "Object not found for removal!" );
	// if ( xPersist.is() )
	if ( xPersist.is() && bKeepToTempStorage )	// #i119941
	{
		// remove replacement image (if there is one)
		RemoveGraphicStream( aName );

		// now it's time to remove the storage from the container storage
		try
		{
#if OSL_DEBUG_LEVEL > 1
			// if the object has a persistence and the object is not a link than it must have persistence entry in storage
			OSL_ENSURE( bIsNotEmbedded || pImpl->mxStorage->hasByName( aName ), "The object has no persistence entry in the storage!" );
#endif
			if ( xPersist.is() && pImpl->mxStorage->hasByName( aName ) )
				pImpl->mxStorage->removeElement( aName );
		}
		catch ( uno::Exception& )
		{
			OSL_ENSURE( sal_False, "Failed to remove object from storage!" );
			return sal_False;
		}
	}

	return sal_True;
}

sal_Bool EmbeddedObjectContainer::CloseEmbeddedObject( const uno::Reference < embed::XEmbeddedObject >& xObj )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::CloseEmbeddedObject" );

	// disconnect the object from the container and close it if possible

	sal_Bool bFound = sal_False;
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	while ( aIt != pImpl->maObjectContainer.end() )
	{
		if ( (*aIt).second == xObj )
		{
			pImpl->maObjectContainer.erase( aIt );
			bFound = sal_True;
			break;
		}

		aIt++;
	}

	if ( bFound )
	{
		uno::Reference < ::util::XCloseable > xClose( xObj, uno::UNO_QUERY );
		try
		{
			xClose->close( sal_True );
		}
		catch ( uno::Exception& )
		{
			// it is no problem if the object is already closed
			// TODO/LATER: what if the object can not be closed?
		}
	}

	return bFound;
}

uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::rtl::OUString& aName, rtl::OUString* pMediaType )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Name )" );

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

	OSL_ENSURE( !aName.isEmpty(), "Retrieving graphic for unknown object!" );
	if ( !aName.isEmpty() )
	{
		try
		{
			uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements();
			uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( aName, embed::ElementModes::READ );
			xStream = xGraphicStream->getInputStream();
			if ( pMediaType )
			{
				uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
				if ( xSet.is() )
				{
					uno::Any aAny = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("MediaType") );
					aAny >>= *pMediaType;
				}
			}
		}
		catch ( uno::Exception& )
		{
		}
	}

	return xStream;
}

uno::Reference < io::XInputStream > EmbeddedObjectContainer::GetGraphicStream( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& xObj, rtl::OUString* pMediaType )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::GetGraphicStream( Object )" );

	// get the object name
	::rtl::OUString aName;
	EmbeddedObjectContainerNameMap::iterator aIt = pImpl->maObjectContainer.begin();
	while ( aIt != pImpl->maObjectContainer.end() )
	{
		if ( (*aIt).second == xObj )
		{
			aName = (*aIt).first;
			break;
		}

		aIt++;
	}

	// try to load it from the container storage
	return GetGraphicStream( aName, pMediaType );
}

sal_Bool EmbeddedObjectContainer::InsertGraphicStream( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStream" );

	try
	{
		uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements();

		// store it into the subfolder
		uno::Reference < io::XOutputStream > xOutStream;
		uno::Reference < io::XStream > xGraphicStream = xReplacements->openStreamElement( rObjectName,
				embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
		xOutStream = xGraphicStream->getOutputStream();
		::comphelper::OStorageHelper::CopyInputToOutput( rStream, xOutStream );
		xOutStream->flush();

		uno::Reference< beans::XPropertySet > xPropSet( xGraphicStream, uno::UNO_QUERY );
		if ( !xPropSet.is() )
			throw uno::RuntimeException();

		xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" ),
									uno::makeAny( (sal_Bool)sal_True ) );
		uno::Any aAny;
		aAny <<= rMediaType;
		xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii("MediaType"), aAny );

		xPropSet->setPropertyValue( ::rtl::OUString::createFromAscii( "Compressed" ),
									uno::makeAny( (sal_Bool)sal_True ) );
	}
	catch( uno::Exception& )
	{
		return sal_False;
	}

	return sal_True;
}

sal_Bool EmbeddedObjectContainer::InsertGraphicStreamDirectly( const com::sun::star::uno::Reference < com::sun::star::io::XInputStream >& rStream, const ::rtl::OUString& rObjectName, const rtl::OUString& rMediaType )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::InsertGraphicStreamDirectly" );

	try
	{
		uno::Reference < embed::XStorage > xReplacement = pImpl->GetReplacements();
		uno::Reference < embed::XOptimizedStorage > xOptRepl( xReplacement, uno::UNO_QUERY_THROW );

		// store it into the subfolder
		uno::Sequence< beans::PropertyValue > aProps( 3 );
		aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) );
		aProps[0].Value <<= rMediaType;
		aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCommonStoragePasswordEncryption" ) );
		aProps[1].Value <<= (sal_Bool)sal_True;
		aProps[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Compressed" ) );
		aProps[2].Value <<= (sal_Bool)sal_True;

		if ( xReplacement->hasByName( rObjectName ) )
			xReplacement->removeElement( rObjectName );

		xOptRepl->insertStreamElementDirect( rObjectName, rStream, aProps );
	}
	catch( uno::Exception& )
	{
		return sal_False;
	}

	return sal_True;
}


sal_Bool EmbeddedObjectContainer::RemoveGraphicStream( const ::rtl::OUString& rObjectName )
{
	RTL_LOGFILE_CONTEXT( aLog, "comphelper (mv76033) comphelper::EmbeddedObjectContainer::RemoveGraphicStream" );

	try
	{
		uno::Reference < embed::XStorage > xReplacements = pImpl->GetReplacements();
		xReplacements->removeElement( rObjectName );
	}
	catch( uno::Exception& )
	{
		return sal_False;
	}

	return sal_True;
}
namespace {
	void InsertStreamIntoPicturesStorage_Impl( const uno::Reference< embed::XStorage >& xDocStor,
											const uno::Reference< io::XInputStream >& xInStream,
											const ::rtl::OUString& aStreamName )
	{
		OSL_ENSURE( !aStreamName.isEmpty() && xInStream.is() && xDocStor.is(), "Misuse of the method!\n" );

		try
		{
			uno::Reference< embed::XStorage > xPictures = xDocStor->openStorageElement(
										::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Pictures" ) ),
										embed::ElementModes::READWRITE );
			uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement(
										aStreamName,
										embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
			uno::Reference< io::XOutputStream > xOutStream(
										xObjReplStr->getInputStream(), uno::UNO_QUERY_THROW );

			::comphelper::OStorageHelper::CopyInputToOutput( xInStream, xOutStream );
			xOutStream->closeOutput();

			uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY );
			if ( xTransact.is() )
				xTransact->commit();
		}
		catch( uno::Exception& )
		{
			OSL_ENSURE( sal_False, "The pictures storage is not available!\n" );
		}
	}

}
// -----------------------------------------------------------------------------
sal_Bool EmbeddedObjectContainer::StoreAsChildren(sal_Bool _bOasisFormat,sal_Bool _bCreateEmbedded,const uno::Reference < embed::XStorage >& _xStorage)
{
	sal_Bool bResult = sal_False;
	try
	{
		comphelper::EmbeddedObjectContainer aCnt( _xStorage );
		const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames();
		const ::rtl::OUString* pIter = aNames.getConstArray();
		const ::rtl::OUString* pEnd  = pIter + aNames.getLength();
		for(;pIter != pEnd;++pIter)
		{
			uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter );
			OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
			if ( xObj.is() )
			{
				sal_Bool bSwitchBackToLoaded = sal_False;
				uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );

				uno::Reference < io::XInputStream > xStream;
				::rtl::OUString aMediaType;

				sal_Int32 nCurState = xObj->getCurrentState();
				if ( nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING )
				{
					// means that the object is not active
					// copy replacement image from old to new container
					xStream = GetGraphicStream( xObj, &aMediaType );
				}

				if ( !xStream.is() && getUserAllowsLinkUpdate() )
				{
					// the image must be regenerated
					// TODO/LATER: another aspect could be used
					if ( xObj->getCurrentState() == embed::EmbedStates::LOADED )
							bSwitchBackToLoaded = sal_True;

					xStream = GetGraphicReplacementStream(
															embed::Aspects::MSOLE_CONTENT,
															xObj,
															&aMediaType );
				}

				if ( _bOasisFormat || (xLink.is() && xLink->isLink()) )
				{
					if ( xStream.is() )
					{
						if ( _bOasisFormat )
						{
							// if it is an embedded object or the optimized inserting fails the normal inserting should be done
							if ( _bCreateEmbedded
								 || !aCnt.InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) )
								 aCnt.InsertGraphicStream( xStream, *pIter, aMediaType );
						}
						else
						{
							// it is a linked object exported into SO7 format
							InsertStreamIntoPicturesStorage_Impl( _xStorage, xStream, *pIter );
						}
					}
				}

				uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
				if ( xPersist.is() )
				{
					uno::Sequence< beans::PropertyValue > aArgs( _bOasisFormat ? 2 : 3 );
					aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StoreVisualReplacement" ) );
					aArgs[0].Value <<= (sal_Bool)( !_bOasisFormat );

					// if it is an embedded object or the optimized inserting fails the normal inserting should be done
					aArgs[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanTryOptimization" ) );
					aArgs[1].Value <<= !_bCreateEmbedded;
					if ( !_bOasisFormat )
					{
						// if object has no cached replacement it will use this one
						aArgs[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualReplacement" ) );
						aArgs[2].Value <<= xStream;
					}

					xPersist->storeAsEntry( _xStorage,
											xPersist->getEntryName(),
											uno::Sequence< beans::PropertyValue >(),
											aArgs );
				}

				if ( bSwitchBackToLoaded )
					// switch back to loaded state; that way we have a minimum cache confusion
					xObj->changeState( embed::EmbedStates::LOADED );
			}
		}

		bResult = aCnt.CommitImageSubStorage();

	}
	catch ( uno::Exception& )
	{
		// TODO/LATER: error handling
		bResult = sal_False;
	}

	// the old SO6 format does not store graphical replacements
	if ( !_bOasisFormat && bResult )
	{
		try
		{
			// the substorage still can not be locked by the embedded object container
			::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) );
			if ( _xStorage->hasByName( aObjReplElement ) && _xStorage->isStorageElement( aObjReplElement ) )
				_xStorage->removeElement( aObjReplElement );
		}
		catch ( uno::Exception& )
		{
			// TODO/LATER: error handling;
			bResult = sal_False;
		}
	}
	return bResult;
}
// -----------------------------------------------------------------------------
sal_Bool EmbeddedObjectContainer::StoreChildren(sal_Bool _bOasisFormat,sal_Bool _bObjectsOnly)
{
	sal_Bool bResult = sal_True;
	const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames();
	const ::rtl::OUString* pIter = aNames.getConstArray();
	const ::rtl::OUString* pEnd  = pIter + aNames.getLength();
	for(;pIter != pEnd;++pIter)
	{
		uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter );
		OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
		if ( xObj.is() )
		{
			sal_Int32 nCurState = xObj->getCurrentState();
			if ( _bOasisFormat && nCurState != embed::EmbedStates::LOADED && nCurState != embed::EmbedStates::RUNNING )
			{
				// means that the object is active
				// the image must be regenerated
				::rtl::OUString aMediaType;

				// TODO/LATER: another aspect could be used
				uno::Reference < io::XInputStream > xStream =
							GetGraphicReplacementStream(
														embed::Aspects::MSOLE_CONTENT,
														xObj,
														&aMediaType );
				if ( xStream.is() )
				{
					if ( !InsertGraphicStreamDirectly( xStream, *pIter, aMediaType ) )
						InsertGraphicStream( xStream, *pIter, aMediaType );
				}
			}

			// TODO/LATER: currently the object by default does not cache replacement image
			// that means that if somebody loads SO7 document and store its objects using
			// this method the images might be lost.
			// Currently this method is only used on storing to alien formats, that means
			// that SO7 documents storing does not use it, and all other filters are
			// based on OASIS format. But if it changes the method must be fixed. The fix
			// must be done only on demand since it can affect performance.

			uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
			if ( xPersist.is() )
			{
				try
				{
					// TODO/LATER: only storing if changed!
					//xPersist->storeOwn();	//commented, i120168

					// begin:all charts will be persisted as xml format on disk when saving, which is time consuming.
					// '_bObjectsOnly' mean we are storing to alien formats.
					//  'isStorageElement' mean current object is NOT an MS OLE format. (may also include in future), i120168
					if (_bObjectsOnly && (nCurState == embed::EmbedStates::LOADED || nCurState == embed::EmbedStates::RUNNING)
						&& (pImpl->mxStorage->isStorageElement( *pIter ) ))
					{
						uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
						if ( xModifiable.is() && xModifiable->isModified())
						{
							xPersist->storeOwn();
						}
						else
						{
							// do nothing. Embedded model is not modified, no need to persist.
						}
					}
					else // the embedded object is in active status, always store back it.
					{
						xPersist->storeOwn();
					}
					// end i120168
				}
				catch( uno::Exception& )
				{
					// TODO/LATER: error handling
					bResult = sal_False;
					break;
				}
			}

			if ( !_bOasisFormat && !_bObjectsOnly )
			{
				// copy replacement images for linked objects
				try
				{
					uno::Reference< embed::XLinkageSupport > xLink( xObj, uno::UNO_QUERY );
					if ( xLink.is() && xLink->isLink() )
					{
						::rtl::OUString aMediaType;
						uno::Reference < io::XInputStream > xInStream = GetGraphicStream( xObj, &aMediaType );
						if ( xInStream.is() )
							InsertStreamIntoPicturesStorage_Impl( pImpl->mxStorage, xInStream, *pIter );
					}
				}
				catch( uno::Exception& )
				{
				}
			}
		}
	}

	if ( bResult && _bOasisFormat )
		bResult = CommitImageSubStorage();

	if ( bResult && !_bObjectsOnly )
	{
		try
		{
			ReleaseImageSubStorage();
			::rtl::OUString aObjReplElement( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) );
			if ( !_bOasisFormat && pImpl->mxStorage->hasByName( aObjReplElement ) && pImpl->mxStorage->isStorageElement( aObjReplElement ) )
				pImpl->mxStorage->removeElement( aObjReplElement );
		}
		catch( uno::Exception& )
		{
			// TODO/LATER: error handling
			bResult = sal_False;
		}
	}
	return bResult;
}
// -----------------------------------------------------------------------------
uno::Reference< io::XInputStream > EmbeddedObjectContainer::GetGraphicReplacementStream(
																sal_Int64 nViewAspect,
																const uno::Reference< embed::XEmbeddedObject >& xObj,
																::rtl::OUString* pMediaType )
{
	uno::Reference< io::XInputStream > xInStream;
	if ( xObj.is() )
	{
		try
		{
			// retrieving of the visual representation can switch object to running state
			embed::VisualRepresentation aRep = xObj->getPreferredVisualRepresentation( nViewAspect );
			if ( pMediaType )
				*pMediaType = aRep.Flavor.MimeType;

			uno::Sequence < sal_Int8 > aSeq;
			aRep.Data >>= aSeq;
			xInStream = new ::comphelper::SequenceInputStream( aSeq );
		}
		catch ( uno::Exception& )
		{
		}
	}

	return xInStream;
}
// -----------------------------------------------------------------------------
sal_Bool EmbeddedObjectContainer::SetPersistentEntries(const uno::Reference< embed::XStorage >& _xStorage,bool _bClearModifedFlag)
{
	sal_Bool bError = sal_False;
	const uno::Sequence < ::rtl::OUString > aNames = GetObjectNames();
	const ::rtl::OUString* pIter = aNames.getConstArray();
	const ::rtl::OUString* pEnd  = pIter + aNames.getLength();
	for(;pIter != pEnd;++pIter)
	{
		uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObject( *pIter );
		OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
		if ( xObj.is() )
		{
			uno::Reference< embed::XEmbedPersist > xPersist( xObj, uno::UNO_QUERY );
			if ( xPersist.is() )
			{
				try
				{
					xPersist->setPersistentEntry( _xStorage,
												*pIter,
												embed::EntryInitModes::NO_INIT,
												uno::Sequence< beans::PropertyValue >(),
												uno::Sequence< beans::PropertyValue >() );

				}
				catch( uno::Exception& )
				{
					// TODO/LATER: error handling
					bError = sal_True;
					break;
				}
			}
			if ( _bClearModifedFlag )
			{
				// if this method is used as part of SaveCompleted the object must stay unmodified after execution
				try
				{
					uno::Reference< util::XModifiable > xModif( xObj->getComponent(), uno::UNO_QUERY_THROW );
					if ( xModif->isModified() )
						xModif->setModified( sal_False );
				}
				catch( uno::Exception& )
				{
				}
			}
		}
	}
	return bError;
}

bool EmbeddedObjectContainer::getUserAllowsLinkUpdate() const
{
	return pImpl->mbUserAllowsLinkUpdate;
}

void EmbeddedObjectContainer::setUserAllowsLinkUpdate(bool bNew)
{
	if(pImpl->mbUserAllowsLinkUpdate != bNew)
	{
		pImpl->mbUserAllowsLinkUpdate = bNew;
	}
}

}

/* vim: set noet sw=4 ts=4: */
