/**************************************************************
 * 
 * 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.getLength(), "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.getLength() )
        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.getLength(), "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 persistance 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.getLength() )
        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.getLength() )
        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.getLength() )
        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.getLength() )
        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.getLength() && aTargetName.getLength() )
	{
		::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.getLength() )
        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.getLength() )
        rName = CreateUniqueObjectName();

	// objects without persistance 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.getLength() )
						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 tranfer 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 persistance!\n" );

	if ( xResult.is() )
	{
		// the object is successfully copied, try to copy graphical replacement
		if ( aOrigName.getLength() )
			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 persistance 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.getLength(), "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 persistance 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.getLength(), "Retrieving graphic for unknown object!" );
	if ( aName.getLength() )
	{
    	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.getLength() && 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.embeded model is not modified, no need to persist.
                        }
                    }
                    else //the embeded 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;
}
}
