/**************************************************************
 * 
 * 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/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;
    sal_Bool bOwnsStorage;

    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->bOwnsStorage = sal_True;
    pImpl->mpTempObjectContainer = 0;
}

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

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

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

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

    pImpl->mxStorage = rStor;
    pImpl->bOwnsStorage = sal_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->bOwnsStorage )
        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 optimisation, 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" ) );
        aObjDescr[0].Value <<= pImpl->m_xModel.get();
        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 depricated! 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() )
                {
                    // 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 conteiner
            ::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 persited 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;
}
}
