/**************************************************************
 *
 * 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_cppuhelper.hxx"

#ifdef DIAG
#define CONTEXT_DIAG
#endif

#if OSL_DEBUG_LEVEL > 0
#include <stdio.h>
#endif

#include <vector>
#include <hash_map>
#ifdef CONTEXT_DIAG
#include <map>
#endif

#include <osl/diagnose.h>
#include <osl/mutex.hxx>

#include <rtl/ustrbuf.hxx>

#include <uno/mapping.hxx>

#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/compbase2.hxx>
#include <cppuhelper/component_context.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include "com/sun/star/uno/RuntimeException.hpp"

#include <hash_map>
#include <memory>

#define SMGR_SINGLETON "/singletons/com.sun.star.lang.theServiceManager"
#define TDMGR_SINGLETON "/singletons/com.sun.star.reflection.theTypeDescriptionManager"
#define AC_SINGLETON "/singletons/com.sun.star.security.theAccessController"
#define AC_POLICY "/singletons/com.sun.star.security.thePolicy"
#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )


using namespace ::osl;
using namespace ::rtl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;

namespace cppu
{

#ifdef CONTEXT_DIAG
//--------------------------------------------------------------------------------------------------
static OUString val2str( void const * pVal, typelib_TypeDescriptionReference * pTypeRef )
{
	OSL_ASSERT( pVal );
	if (pTypeRef->eTypeClass == typelib_TypeClass_VOID)
		return OUSTR("void");

	OUStringBuffer buf( 64 );
	buf.append( (sal_Unicode)'(' );
	buf.append( pTypeRef->pTypeName );
	buf.append( (sal_Unicode)')' );

	switch (pTypeRef->eTypeClass)
	{
	case typelib_TypeClass_INTERFACE:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
		buf.append( (sal_Int64)*(void **)pVal, 16 );
		break;
	case typelib_TypeClass_STRUCT:
	case typelib_TypeClass_EXCEPTION:
	{
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
		typelib_TypeDescription * pTypeDescr = 0;
		::typelib_typedescriptionreference_getDescription( &pTypeDescr, pTypeRef );
		OSL_ASSERT( pTypeDescr );
		if (! pTypeDescr->bComplete)
			::typelib_typedescription_complete( &pTypeDescr );

		typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr;
		sal_Int32 nDescr = pCompType->nMembers;

		if (pCompType->pBaseTypeDescription)
		{
			buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->pWeakRef ) );
			if (nDescr)
				buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
		}

		typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
		sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
		rtl_uString ** ppMemberNames = pCompType->ppMemberNames;

		for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
		{
			buf.append( ppMemberNames[ nPos ] );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
			typelib_TypeDescription * pMemberType = 0;
			TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[ nPos ] );
			buf.append( val2str( (char *)pVal + pMemberOffsets[ nPos ], pMemberType->pWeakRef ) );
			TYPELIB_DANGER_RELEASE( pMemberType );
			if (nPos < (nDescr -1))
				buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
		}

		::typelib_typedescription_release( pTypeDescr );

		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
		break;
	}
	case typelib_TypeClass_SEQUENCE:
	{
		typelib_TypeDescription * pTypeDescr = 0;
		TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );

		uno_Sequence * pSequence = *(uno_Sequence **)pVal;
		typelib_TypeDescription * pElementTypeDescr = 0;
		TYPELIB_DANGER_GET( &pElementTypeDescr, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );

		sal_Int32 nElementSize = pElementTypeDescr->nSize;
		sal_Int32 nElements	   = pSequence->nElements;

		if (nElements)
		{
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
			char * pElements = pSequence->elements;
			for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
			{
				buf.append( val2str( pElements + (nElementSize * nPos), pElementTypeDescr->pWeakRef ) );
				if (nPos < (nElements -1))
					buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
			}
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
		}
		else
		{
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
		}
		TYPELIB_DANGER_RELEASE( pElementTypeDescr );
		TYPELIB_DANGER_RELEASE( pTypeDescr );
		break;
	}
	case typelib_TypeClass_ANY:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
		buf.append( val2str( ((uno_Any *)pVal)->pData,
							 ((uno_Any *)pVal)->pType ) );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
		break;
	case typelib_TypeClass_TYPE:
		buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName );
		break;
	case typelib_TypeClass_STRING:
		buf.append( (sal_Unicode)'\"' );
		buf.append( *(rtl_uString **)pVal );
		buf.append( (sal_Unicode)'\"' );
		break;
	case typelib_TypeClass_ENUM:
	{
		typelib_TypeDescription * pTypeDescr = 0;
		::typelib_typedescriptionreference_getDescription( &pTypeDescr, pTypeRef );
		OSL_ASSERT( pTypeDescr );
		if (! pTypeDescr->bComplete)
			::typelib_typedescription_complete( &pTypeDescr );

		sal_Int32 * pValues = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues;
		sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues;
		while (nPos--)
		{
			if (pValues[ nPos ] == *(sal_Int32 *)pVal)
				break;
		}
		if (nPos >= 0)
			buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[ nPos ] );
		else
			buf.append( (sal_Unicode)'?' );

		::typelib_typedescription_release( pTypeDescr );
		break;
	}
	case typelib_TypeClass_BOOLEAN:
		if (*(sal_Bool *)pVal)
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
		else
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
		break;
	case typelib_TypeClass_CHAR:
		buf.append( (sal_Unicode)'\'' );
		buf.append( *(sal_Unicode *)pVal );
		buf.append( (sal_Unicode)'\'' );
		break;
	case typelib_TypeClass_FLOAT:
		buf.append( *(float *)pVal );
		break;
	case typelib_TypeClass_DOUBLE:
		buf.append( *(double *)pVal );
		break;
	case typelib_TypeClass_BYTE:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
		buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 );
		break;
	case typelib_TypeClass_SHORT:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
		buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 );
		break;
	case typelib_TypeClass_UNSIGNED_SHORT:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
		buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 );
		break;
	case typelib_TypeClass_LONG:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
		buf.append( *(sal_Int32 *)pVal, 16 );
		break;
	case typelib_TypeClass_UNSIGNED_LONG:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
		buf.append( (sal_Int64)*(sal_uInt32 *)pVal, 16 );
		break;
	case typelib_TypeClass_HYPER:
	case typelib_TypeClass_UNSIGNED_HYPER:
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
#if defined(GCC) && defined(SPARC)
		{
			sal_Int64 aVal;
			*(sal_Int32 *)&aVal = *(sal_Int32 *)pVal;
			*((sal_Int32 *)&aVal +1)= *((sal_Int32 *)pVal +1);
			buf.append( aVal, 16 );
		}
#else
		buf.append( *(sal_Int64 *)pVal, 16 );
#endif
		break;
	default:
		buf.append( (sal_Unicode)'?' );
	}

	return buf.makeStringAndClear();
}
//--------------------------------------------------------------------------------------------------
static void dumpEntry( OUString const & key, Any const & value )
{
    OUString val( val2str( value.getValue(), value.getValueTypeRef() ) );
    OString key_str( OUStringToOString( key, RTL_TEXTENCODING_ASCII_US ) );
    OString val_str( OUStringToOString( val, RTL_TEXTENCODING_ASCII_US ) );
    ::fprintf( stderr, "| %s = %s\n", key_str.getStr(), val_str.getStr() );
}
#endif
//--------------------------------------------------------------------------------------------------
static inline void try_dispose( Reference< XInterface > const & xInstance )
    SAL_THROW( (RuntimeException) )
{
    Reference< lang::XComponent > xComp( xInstance, UNO_QUERY );
    if (xComp.is())
    {
        xComp->dispose();
    }
}
//--------------------------------------------------------------------------------------------------
static inline void try_dispose( Reference< lang::XComponent > const & xComp )
    SAL_THROW( (RuntimeException) )
{
    if (xComp.is())
    {
        xComp->dispose();
    }
}

//==================================================================================================

class DisposingForwarder
    : public WeakImplHelper1< lang::XEventListener >
{
    Reference< lang::XComponent > m_xTarget;

    inline DisposingForwarder( Reference< lang::XComponent > const & xTarget )
        SAL_THROW( () )
        : m_xTarget( xTarget )
        { OSL_ASSERT( m_xTarget.is() ); }
public:
    // listens at source for disposing, then disposes target
    static inline void listen(
        Reference< lang::XComponent > const & xSource,
        Reference< lang::XComponent > const & xTarget )
        SAL_THROW( (RuntimeException) );

    virtual void SAL_CALL disposing( lang::EventObject const & rSource )
        throw (RuntimeException);
};
//__________________________________________________________________________________________________
inline void DisposingForwarder::listen(
    Reference< lang::XComponent > const & xSource,
    Reference< lang::XComponent > const & xTarget )
    SAL_THROW( (RuntimeException) )
{
    if (xSource.is())
    {
        xSource->addEventListener( new DisposingForwarder( xTarget ) );
    }
}
//__________________________________________________________________________________________________
void DisposingForwarder::disposing( lang::EventObject const & )
    throw (RuntimeException)
{
    m_xTarget->dispose();
    m_xTarget.clear();
}

//==================================================================================================
struct MutexHolder
{
protected:
    Mutex m_mutex;
};
//==================================================================================================

class ComponentContext
    : private MutexHolder
    , public WeakComponentImplHelper2< XComponentContext,
                                       container::XNameContainer >
{
protected:
    Reference< XComponentContext > m_xDelegate;

    struct ContextEntry
    {
        Any value;
        bool lateInit;

        inline ContextEntry( Any const & value_, bool lateInit_ )
            : value( value_ )
            , lateInit( lateInit_ )
            {}
    };
    typedef ::std::hash_map< OUString, ContextEntry * , OUStringHash > t_map;
    t_map m_map;

    Reference< lang::XMultiComponentFactory > m_xSMgr;

protected:
    Any lookupMap( OUString const & rName )
        SAL_THROW( (RuntimeException) );

	virtual void SAL_CALL disposing();
public:
    ComponentContext(
        ContextEntry_Init const * pEntries, sal_Int32 nEntries,
        Reference< XComponentContext > const & xDelegate );
    virtual ~ComponentContext()
        SAL_THROW( () );

    // XComponentContext
    virtual Any SAL_CALL getValueByName( OUString const & rName )
        throw (RuntimeException);
    virtual Reference<lang::XMultiComponentFactory> SAL_CALL getServiceManager()
        throw (RuntimeException);

    // XNameContainer
    virtual void SAL_CALL insertByName(
        OUString const & name, Any const & element )
        throw (lang::IllegalArgumentException, container::ElementExistException,
               lang::WrappedTargetException, RuntimeException);
    virtual void SAL_CALL removeByName( OUString const & name )
        throw (container::NoSuchElementException,
               lang::WrappedTargetException, RuntimeException);
    // XNameReplace
    virtual void SAL_CALL replaceByName(
        OUString const & name, Any const & element )
        throw (lang::IllegalArgumentException,container::NoSuchElementException,
               lang::WrappedTargetException, RuntimeException);
    // XNameAccess
    virtual Any SAL_CALL getByName( OUString const & name )
        throw (container::NoSuchElementException,
               lang::WrappedTargetException, RuntimeException);
    virtual Sequence<OUString> SAL_CALL getElementNames()
        throw (RuntimeException);
    virtual sal_Bool SAL_CALL hasByName( OUString const & name )
        throw (RuntimeException);
    // XElementAccess
    virtual Type SAL_CALL getElementType() throw (RuntimeException);
    virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException);
};

// XNameContainer
//______________________________________________________________________________
void ComponentContext::insertByName(
    OUString const & name, Any const & element )
    throw (lang::IllegalArgumentException, container::ElementExistException,
           lang::WrappedTargetException, RuntimeException)
{
    t_map::mapped_type entry(
        new ContextEntry(
            element,
            /* lateInit_: */
            name.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
            !element.hasValue() ) );
    MutexGuard guard( m_mutex );
    ::std::pair<t_map::iterator, bool> insertion( m_map.insert(
        t_map::value_type( name, entry ) ) );
    if (! insertion.second)
        throw container::ElementExistException(
            OUSTR("element already exists: ") + name,
            static_cast<OWeakObject *>(this) );
}

//______________________________________________________________________________
void ComponentContext::removeByName( OUString const & name )
        throw (container::NoSuchElementException,
               lang::WrappedTargetException, RuntimeException)
{
    MutexGuard guard( m_mutex );
    t_map::iterator iFind( m_map.find( name ) );
    if (iFind == m_map.end())
        throw container::NoSuchElementException(
            OUSTR("no such element: ") + name,
            static_cast<OWeakObject *>(this) );

    delete iFind->second;
    m_map.erase(iFind);
}

// XNameReplace
//______________________________________________________________________________
void ComponentContext::replaceByName(
    OUString const & name, Any const & element )
    throw (lang::IllegalArgumentException,container::NoSuchElementException,
           lang::WrappedTargetException, RuntimeException)
{
    MutexGuard guard( m_mutex );
    t_map::const_iterator const iFind( m_map.find( name ) );
    if (iFind == m_map.end())
        throw container::NoSuchElementException(
            OUSTR("no such element: ") + name,
            static_cast<OWeakObject *>(this) );
    if (name.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("/singletons/") ) &&
        !element.hasValue())
    {
        iFind->second->value.clear();
        iFind->second->lateInit = true;
    }
    else
    {
        iFind->second->value = element;
        iFind->second->lateInit = false;
    }
}

// XNameAccess
//______________________________________________________________________________
Any ComponentContext::getByName( OUString const & name )
    throw (container::NoSuchElementException,
           lang::WrappedTargetException, RuntimeException)
{
    return getValueByName( name );
}

//______________________________________________________________________________
Sequence<OUString> ComponentContext::getElementNames()
    throw (RuntimeException)
{
    MutexGuard guard( m_mutex );
    Sequence<OUString> ret( m_map.size() );
    OUString * pret = ret.getArray();
    sal_Int32 pos = 0;
    t_map::const_iterator iPos( m_map.begin() );
    t_map::const_iterator const iEnd( m_map.end() );
    for ( ; iPos != iEnd; ++iPos )
        pret[pos++] = iPos->first;
    return ret;
}

//______________________________________________________________________________
sal_Bool ComponentContext::hasByName( OUString const & name )
    throw (RuntimeException)
{
    MutexGuard guard( m_mutex );
    return m_map.find( name ) != m_map.end();
}

// XElementAccess
//______________________________________________________________________________
Type ComponentContext::getElementType() throw (RuntimeException)
{
    return ::getVoidCppuType();
}

//______________________________________________________________________________
sal_Bool ComponentContext::hasElements() throw (RuntimeException)
{
    MutexGuard guard( m_mutex );
    return ! m_map.empty();
}

//__________________________________________________________________________________________________
Any ComponentContext::lookupMap( OUString const & rName )
    SAL_THROW( (RuntimeException) )
{
#ifdef CONTEXT_DIAG
    if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("dump_maps") ))
    {
        ::fprintf( stderr, ">>> dumping out ComponentContext %p m_map:\n", this );
        typedef ::std::map< OUString, ContextEntry * > t_sorted; // sorted map
        t_sorted sorted;
        for ( t_map::const_iterator iPos( m_map.begin() ); iPos != m_map.end(); ++iPos )
        {
            sorted[ iPos->first ] = iPos->second;
        }
        {
        for ( t_sorted::const_iterator iPos( sorted.begin() ); iPos != sorted.end(); ++iPos )
        {
            dumpEntry( iPos->first, iPos->second->value );
        }
        }
        return Any();
    }
#endif

    ResettableMutexGuard guard( m_mutex );
    t_map::const_iterator iFind( m_map.find( rName ) );
    if (iFind == m_map.end())
        return Any();

    t_map::mapped_type pEntry = iFind->second;
    if (! pEntry->lateInit)
        return pEntry->value;

    // late init singleton entry
    Reference< XInterface > xInstance;
    guard.clear();

    try
    {
        Any usesService( getValueByName( rName + OUSTR("/service") ) );
        Any args_( getValueByName( rName + OUSTR("/arguments") ) );
        Sequence<Any> args;
        if (args_.hasValue() && !(args_ >>= args))
        {
            args.realloc( 1 );
            args[ 0 ] = args_;
        }

        Reference< lang::XSingleComponentFactory > xFac;
        if (usesService >>= xFac) // try via factory
        {
            xInstance = args.getLength()
                ? xFac->createInstanceWithArgumentsAndContext( args, this )
                : xFac->createInstanceWithContext( this );
        }
        else
        {
            Reference< lang::XSingleServiceFactory > xFac2;
            if (usesService >>= xFac2)
            {
                // try via old XSingleServiceFactory
#if OSL_DEBUG_LEVEL > 0
                ::fprintf(
                    stderr,
                    "### omitting context for service instantiation!\n" );
#endif
                xInstance = args.getLength()
                    ? xFac2->createInstanceWithArguments( args )
                    : xFac2->createInstance();
            }
            else if (m_xSMgr.is()) // optionally service name
            {
                OUString serviceName;
                if ((usesService >>= serviceName) &&
                    serviceName.getLength())
                {
                    xInstance = args.getLength()
                        ? m_xSMgr->createInstanceWithArgumentsAndContext(
                            serviceName, args, this )
                        : m_xSMgr->createInstanceWithContext(
                            serviceName, this );
                }
            }
        }
    }
    catch (RuntimeException &)
    {
        throw;
    }
    catch (Exception & exc) // rethrow as WrappedTargetRuntimeException
    {
        Any caught( getCaughtException() );
        OUStringBuffer buf;
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
                             "exception occurred raising singleton \"") );
        buf.append( rName );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\": ") );
        buf.append( exc.Message );
        throw lang::WrappedTargetRuntimeException(
            buf.makeStringAndClear(), static_cast<OWeakObject *>(this),caught );
    }

    if (! xInstance.is())
    {
        throw RuntimeException(
            OUSTR("no service object raising singleton ") + rName,
            static_cast<OWeakObject *>(this) );
    }

    Any ret;
    guard.reset();
    iFind = m_map.find( rName );
    if (iFind != m_map.end())
    {
        pEntry = iFind->second;
        if (pEntry->lateInit)
        {
            pEntry->value <<= xInstance;
            pEntry->lateInit = false;
            return pEntry->value;
        }
        else
            ret = pEntry->value;
    }
    guard.clear();
    try_dispose( xInstance );
    return ret;
}

//__________________________________________________________________________________________________
Any ComponentContext::getValueByName( OUString const & rName )
    throw (RuntimeException)
{
    // to determine the root context:
    if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_root") ))
    {
        if (m_xDelegate.is())
            return m_xDelegate->getValueByName( rName );
        else
            return makeAny( Reference<XComponentContext>(this) );
    }

    Any ret( lookupMap( rName ) );
    if (!ret.hasValue() && m_xDelegate.is())
    {
        return m_xDelegate->getValueByName( rName );
    }
    return ret;
}
//__________________________________________________________________________________________________
Reference< lang::XMultiComponentFactory > ComponentContext::getServiceManager()
    throw (RuntimeException)
{
    return m_xSMgr;
}
//__________________________________________________________________________________________________
ComponentContext::~ComponentContext()
    SAL_THROW( () )
{
#ifdef CONTEXT_DIAG
    ::fprintf( stderr, "> destructed context %p\n", this );
#endif
    t_map::const_iterator iPos( m_map.begin() );
    t_map::const_iterator const iEnd( m_map.end() );
    for ( ; iPos != iEnd; ++iPos )
        delete iPos->second;
    m_map.clear();
}
//__________________________________________________________________________________________________
void ComponentContext::disposing()
{
#ifdef CONTEXT_DIAG
    ::fprintf( stderr, "> disposing context %p\n", this );
#endif

    Reference< lang::XComponent > xTDMgr, xAC, xPolicy; // to be disposed separately

    // dispose all context objects
    t_map::const_iterator iPos( m_map.begin() );
    t_map::const_iterator const iEnd( m_map.end() );
    for ( ; iPos != iEnd; ++iPos )
    {
        t_map::mapped_type pEntry = iPos->second;

        // service manager disposed separately
        if (!m_xSMgr.is() ||
            !iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON) ))
        {
            if (pEntry->lateInit)
            {
                // late init
                MutexGuard guard( m_mutex );
                if (pEntry->lateInit)
                {
                    pEntry->value.clear(); // release factory
                    pEntry->lateInit = false;
                    continue;
                }
            }

            Reference< lang::XComponent > xComp;
            pEntry->value >>= xComp;
            if (xComp.is())
            {
                if (iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(TDMGR_SINGLETON) ))
                {
                    xTDMgr = xComp;
                }
                else if (iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(AC_SINGLETON) ))
                {
                    xAC = xComp;
                }
                else if (iPos->first.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(AC_POLICY) ))
                {
                    xPolicy = xComp;
                }
                else // dispose immediately
                {
                    xComp->dispose();
                }
            }
        }
    }

    // dispose service manager
    try_dispose( m_xSMgr );
    m_xSMgr.clear();
    // dispose ac
    try_dispose( xAC );
    // dispose policy
    try_dispose( xPolicy );
    // dispose tdmgr; revokes callback from cppu runtime
    try_dispose( xTDMgr );

    iPos = m_map.begin();
    for ( ; iPos != iEnd; ++iPos )
        delete iPos->second;
    m_map.clear();
}
//__________________________________________________________________________________________________
ComponentContext::ComponentContext(
    ContextEntry_Init const * pEntries, sal_Int32 nEntries,
    Reference< XComponentContext > const & xDelegate )
    : WeakComponentImplHelper2< XComponentContext, container::XNameContainer >(
        m_mutex ),
      m_xDelegate( xDelegate )
{
    for ( sal_Int32 nPos = 0; nPos < nEntries; ++nPos )
    {
        ContextEntry_Init const & rEntry = pEntries[ nPos ];

        if (rEntry.name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(SMGR_SINGLETON) ))
        {
            rEntry.value >>= m_xSMgr;
        }

        if (rEntry.bLateInitService)
        {
            // singleton entry
            m_map[ rEntry.name ] = new ContextEntry( Any(), true );
            // /service
            m_map[ rEntry.name + OUSTR("/service") ] = new ContextEntry( rEntry.value, false );
            // /initial-arguments are provided as optional context entry
        }
        else
        {
            // only value, no late init factory nor string
            m_map[ rEntry.name ] = new ContextEntry( rEntry.value, false );
        }
    }

    if (!m_xSMgr.is() && m_xDelegate.is())
    {
        // wrap delegate's smgr XPropertySet into new smgr
        Reference< lang::XMultiComponentFactory > xMgr( m_xDelegate->getServiceManager() );
        if (xMgr.is())
        {
            osl_incrementInterlockedCount( &m_refCount );
            try
            {
                // create new smgr based on delegate's one
                m_xSMgr.set(
                    xMgr->createInstanceWithContext(
                        OUSTR("com.sun.star.comp.stoc.OServiceManagerWrapper"), xDelegate ),
                    UNO_QUERY );
                // patch DefaultContext property of new one
                Reference< beans::XPropertySet > xProps( m_xSMgr, UNO_QUERY );
                OSL_ASSERT( xProps.is() );
                if (xProps.is())
                {
                    Reference< XComponentContext > xThis( this );
                    xProps->setPropertyValue( OUSTR("DefaultContext"), makeAny( xThis ) );
                }
            }
            catch (...)
            {
                osl_decrementInterlockedCount( &m_refCount );
                throw;
            }
            osl_decrementInterlockedCount( &m_refCount );
            OSL_ASSERT( m_xSMgr.is() );
        }
    }
}


//##################################################################################################
extern "C" { static void s_createComponentContext_v(va_list * pParam)
{
    ContextEntry_Init const  * pEntries     = va_arg(*pParam, ContextEntry_Init const *);
	sal_Int32                  nEntries     = va_arg(*pParam, sal_Int32);
	XComponentContext        * pDelegatee   = va_arg(*pParam, XComponentContext *);
	void                    ** ppContext    = va_arg(*pParam, void **);
	uno::Mapping             * pTarget2curr = va_arg(*pParam, uno::Mapping *);

	Reference<XComponentContext> xDelegate(pDelegatee, SAL_NO_ACQUIRE);
	Reference<XComponentContext> xContext;

    if (nEntries > 0)
    {
        try
        {
			ComponentContext * p = new ComponentContext( pEntries, nEntries, xDelegate );
            xContext.set(p);
            // listen delegate for disposing, to dispose this (wrapping) context first.
            DisposingForwarder::listen( Reference< lang::XComponent >::query( xDelegate ), p );
        }
        catch (Exception & exc)
        {
            (void) exc; // avoid warning about unused variable
            OSL_ENSURE( 0, OUStringToOString(
                            exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
			xContext.clear();
        }
    }
    else
    {
        xContext = xDelegate;
    }

	delete[] pEntries;

	*ppContext = pTarget2curr->mapInterface(xContext.get(), ::getCppuType(&xContext));
}}

Reference< XComponentContext > SAL_CALL createComponentContext(
    ContextEntry_Init const * pEntries, sal_Int32 nEntries,
    Reference< XComponentContext > const & xDelegate )
    SAL_THROW( () )
{
	uno::Environment curr_env(Environment::getCurrent());
	uno::Environment source_env(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CPPU_STRINGIFY(CPPU_ENV))));

	uno::Mapping curr2source(curr_env, source_env);
	uno::Mapping source2curr(source_env, curr_env);

	ContextEntry_Init * mapped_entries = new ContextEntry_Init[nEntries];
	for (sal_Int32 nPos = 0; nPos < nEntries; ++ nPos)
	{
		mapped_entries[nPos].bLateInitService = pEntries[nPos].bLateInitService;
		mapped_entries[nPos].name             = pEntries[nPos].name;

		uno_type_any_constructAndConvert(&mapped_entries[nPos].value,
										 const_cast<void *>(pEntries[nPos].value.getValue()),
										 pEntries[nPos].value.getValueTypeRef(),
										 curr2source.get());
	}

	void * mapped_delegate = curr2source.mapInterface(xDelegate.get(), ::getCppuType(&xDelegate));
	XComponentContext * pXComponentContext = NULL;
	source_env.invoke(s_createComponentContext_v, mapped_entries, nEntries, mapped_delegate, &pXComponentContext, &source2curr);

	return Reference<XComponentContext>(pXComponentContext, SAL_NO_ACQUIRE);
}

}
