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

#include "cppu/EnvDcp.hxx"

#include "sal/alloca.h"
#include "osl/diagnose.h"
#include "osl/interlck.h"
#include "osl/mutex.hxx"
#include "osl/module.h"
#include "osl/process.h"
#include "rtl/process.h"
#include "rtl/unload.h"
#include "rtl/string.hxx"
#include "rtl/ustring.hxx"
#include "rtl/ustrbuf.hxx"
#include "rtl/instance.hxx"
#include "typelib/typedescription.h"
#include "uno/dispatcher.h"
#include "uno/environment.h"
#include "uno/lbnames.h"
#include "prim.hxx"
#include "destr.hxx"
#include "loadmodule.hxx"

#include <hash_map>
#include <vector>
#include <stdio.h>


using ::rtl::OUString;

namespace
{

//------------------------------------------------------------------------------
inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
                              typelib_InterfaceTypeDescription * pTD2 )
{
    return (pTD1 == pTD2 ||
            (((typelib_TypeDescription *)pTD1)->pTypeName->length ==
             ((typelib_TypeDescription *)pTD2)->pTypeName->length &&
             ::rtl_ustr_compare(
                 ((typelib_TypeDescription *) pTD1)->pTypeName->buffer,
                 ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0));
}

struct ObjectEntry;
struct uno_DefaultEnvironment;

//------------------------------------------------------------------------------
struct InterfaceEntry
{
    sal_Int32 refCount;
    void * pInterface;
    uno_freeProxyFunc fpFreeProxy;
    typelib_InterfaceTypeDescription * pTypeDescr;
};

struct ObjectEntry
{
    OUString oid;
    sal_Int32 nRef;
    ::std::vector< InterfaceEntry > aInterfaces;
    bool mixedObject;
    
    inline ObjectEntry( const OUString & rOId_ );

    inline void append(
        uno_DefaultEnvironment * pEnv,
        void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
        uno_freeProxyFunc fpFreeProxy );
    inline InterfaceEntry * find(
        typelib_InterfaceTypeDescription * pTypeDescr );
    inline sal_Int32 find( void * iface_ptr, ::std::size_t pos );
};

//------------------------------------------------------------------------------
struct FctPtrHash :
    public ::std::unary_function< const void *, ::std::size_t >
{
    ::std::size_t operator () ( const void * pKey ) const
        { return (::std::size_t) pKey; }
};

//------------------------------------------------------------------------------
struct FctOUStringHash :
    public ::std::unary_function< const OUString &, ::std::size_t >
{
    ::std::size_t operator () ( const OUString & rKey ) const
        { return rKey.hashCode(); }
};

// mapping from environment name to environment
typedef ::std::hash_map<
    OUString, uno_Environment *, FctOUStringHash,
    ::std::equal_to< OUString > > OUString2EnvironmentMap;

// mapping from ptr to object entry
typedef ::std::hash_map<
    void *, ObjectEntry *, FctPtrHash,
    ::std::equal_to< void * > > Ptr2ObjectMap;
// mapping from oid to object entry
typedef ::std::hash_map<
    OUString, ObjectEntry *, FctOUStringHash,
    ::std::equal_to< OUString > > OId2ObjectMap;


//==============================================================================
struct EnvironmentsData
{
    ::osl::Mutex mutex;
    OUString2EnvironmentMap aName2EnvMap;

    EnvironmentsData() : isDisposing(false) {}
    ~EnvironmentsData();

    inline void getEnvironment(
        uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext );
    inline void registerEnvironment( uno_Environment ** ppEnv );
    inline void getRegisteredEnvironments(
        uno_Environment *** pppEnvs, sal_Int32 * pnLen,
        uno_memAlloc memAlloc, const OUString & rEnvDcp );

    bool isDisposing;
};

namespace
{
    struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {};
}

//==============================================================================
struct uno_DefaultEnvironment : public uno_ExtEnvironment
{
    sal_Int32 nRef;
    sal_Int32 nWeakRef;
    
    ::osl::Mutex mutex;
    Ptr2ObjectMap aPtr2ObjectMap;
    OId2ObjectMap aOId2ObjectMap;
    
    uno_DefaultEnvironment(
        const OUString & rEnvDcp_, void * pContext_ );
    ~uno_DefaultEnvironment();
};

//______________________________________________________________________________
inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
    : oid( rOId_ ),
      nRef( 0 ),
      mixedObject( false )
{
    aInterfaces.reserve( 2 );
}

//______________________________________________________________________________
inline void ObjectEntry::append(
    uno_DefaultEnvironment * pEnv,
    void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
    uno_freeProxyFunc fpFreeProxy )
{
    InterfaceEntry aNewEntry;
    if (! fpFreeProxy)
        (*pEnv->acquireInterface)( pEnv, pInterface );
    aNewEntry.refCount = 1;
    aNewEntry.pInterface = pInterface;
    aNewEntry.fpFreeProxy = fpFreeProxy;
    typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr );
    aNewEntry.pTypeDescr = pTypeDescr;
    
    ::std::pair< Ptr2ObjectMap::iterator, bool > insertion(
        pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type(
                                         pInterface, this ) ) );
    OSL_ASSERT( insertion.second ||
                (find( pInterface, 0 ) >= 0 &&
                 // points to the same object entry:
                 insertion.first->second == this) );
    aInterfaces.push_back( aNewEntry );
}

//______________________________________________________________________________
inline InterfaceEntry * ObjectEntry::find(
    typelib_InterfaceTypeDescription * pTypeDescr_ )
{
    OSL_ASSERT( ! aInterfaces.empty() );
    if (aInterfaces.empty())
        return 0;
    
    // shortcut common case:
    OUString const & type_name =
        OUString::unacquired(
            &((typelib_TypeDescription *) pTypeDescr_)->pTypeName );
    if (type_name.equalsAsciiL(
            RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
    {
        return &aInterfaces[ 0 ];
    }
    
    ::std::size_t nSize = aInterfaces.size();
    for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
    {
        typelib_InterfaceTypeDescription * pITD =
            aInterfaces[ nPos ].pTypeDescr;
        while (pITD)
        {
            if (td_equals( pITD, pTypeDescr_ ))
                return &aInterfaces[ nPos ];
            pITD = pITD->pBaseTypeDescription;
        }
    }
    return 0;
}

//______________________________________________________________________________
inline sal_Int32 ObjectEntry::find(
    void * iface_ptr, ::std::size_t pos )
{
    ::std::size_t size = aInterfaces.size();
    for ( ; pos < size; ++pos )
    {
        if (aInterfaces[ pos ].pInterface == iface_ptr)
            return pos;
    }
    return -1;
}

extern "C"
{

//------------------------------------------------------------------------------
static void SAL_CALL defenv_registerInterface(
    uno_ExtEnvironment * pEnv, void ** ppInterface,
    rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
{
    OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
    OUString const & rOId = OUString::unacquired( &pOId );
    
    uno_DefaultEnvironment * that =
        static_cast< uno_DefaultEnvironment * >( pEnv );
    ::osl::ClearableMutexGuard guard( that->mutex );
    
    // try to insert dummy 0:
    std::pair<OId2ObjectMap::iterator, bool> const insertion(
        that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) );
    if (insertion.second)
    {
        ObjectEntry * pOEntry = new ObjectEntry( rOId );
        insertion.first->second = pOEntry;
        ++pOEntry->nRef; // another register call on object
        pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
    }
    else // object entry exists
    {
        ObjectEntry * pOEntry = insertion.first->second;
        ++pOEntry->nRef; // another register call on object
        InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );

        if (pIEntry) // type entry exists
        {
            ++pIEntry->refCount;
            if (pIEntry->pInterface != *ppInterface)
            {
                void * pInterface = pIEntry->pInterface;
                (*pEnv->acquireInterface)( pEnv, pInterface );
                guard.clear();
                (*pEnv->releaseInterface)( pEnv, *ppInterface );
                *ppInterface = pInterface;
            }
        }
        else
        {
            pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
        }
    }
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_registerProxyInterface(
    uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy,
    rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
{
    OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy,
                "### null ptr!" );
    OUString const & rOId = OUString::unacquired( &pOId );
    
    uno_DefaultEnvironment * that =
        static_cast< uno_DefaultEnvironment * >( pEnv );
    ::osl::ClearableMutexGuard guard( that->mutex );
    
    // try to insert dummy 0:
    std::pair<OId2ObjectMap::iterator, bool> const insertion(
        that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, 0 ) ) );
    if (insertion.second)
    {
        ObjectEntry * pOEntry = new ObjectEntry( rOId );
        insertion.first->second = pOEntry;
        ++pOEntry->nRef; // another register call on object
        pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
    }
    else // object entry exists
    {
        ObjectEntry * pOEntry = insertion.first->second;
        
        // first registration was an original, then registerProxyInterface():
        pOEntry->mixedObject |=
            (!pOEntry->aInterfaces.empty() &&
             pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
        
        ++pOEntry->nRef; // another register call on object
        InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );

        if (pIEntry) // type entry exists
        {
            if (pIEntry->pInterface == *ppInterface)
            {
                ++pIEntry->refCount;
            }
            else
            {
                void * pInterface = pIEntry->pInterface;
                (*pEnv->acquireInterface)( pEnv, pInterface );
                --pOEntry->nRef; // manual revoke of proxy to be freed
                guard.clear();
                (*freeProxy)( pEnv, *ppInterface );
                *ppInterface = pInterface;
            }
        }
        else
        {
            pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
        }
    }
}

//------------------------------------------------------------------------------
static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam)
{
	uno_ExtEnvironment * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
	void               * pInterface = va_arg(*pParam, void *);

    OSL_ENSURE( pEnv && pInterface, "### null ptr!" );
    uno_DefaultEnvironment * that =
        static_cast< uno_DefaultEnvironment * >( pEnv );
    ::osl::ClearableMutexGuard guard( that->mutex );

    Ptr2ObjectMap::const_iterator const iFind(
        that->aPtr2ObjectMap.find( pInterface ) );
    OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() );
    ObjectEntry * pOEntry = iFind->second;
    if (! --pOEntry->nRef)
    {
        // cleanup maps
        that->aOId2ObjectMap.erase( pOEntry->oid );
        sal_Int32 nPos;
        for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
        {
            that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface );
        }

        // the last proxy interface of the environment might kill this
        // environment, because of releasing its language binding!!!
        guard.clear();

        // release interfaces
        for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
        {
            InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
            typelib_typedescription_release(
                (typelib_TypeDescription *) rEntry.pTypeDescr );
            if (rEntry.fpFreeProxy) // is proxy or used interface?
            {
                (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
            }
            else
            {
                (*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
            }
        }

        delete pOEntry;
    }
    else if (pOEntry->mixedObject)
    {
        OSL_ASSERT( !pOEntry->aInterfaces.empty() &&
                    pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 );

        sal_Int32 index = pOEntry->find( pInterface, 1 );
        OSL_ASSERT( index > 0 );
        if (index > 0)
        {
            InterfaceEntry & entry = pOEntry->aInterfaces[ index ];
            OSL_ASSERT( entry.pInterface == pInterface );
            if (entry.fpFreeProxy != 0)
            {
                --entry.refCount;
                if (entry.refCount == 0)
                {
                    uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy;
                    typelib_TypeDescription * pTypeDescr =
                        reinterpret_cast< typelib_TypeDescription * >(
                            entry.pTypeDescr );
                    
                    pOEntry->aInterfaces.erase(
                        pOEntry->aInterfaces.begin() + index );
                    if (pOEntry->find( pInterface, index ) < 0)
                    {
                        // proxy ptr not registered for another interface:
                        // remove from ptr map
#if OSL_DEBUG_LEVEL > 0
                        ::std::size_t erased =
#endif
                              that->aPtr2ObjectMap.erase( pInterface );
                        OSL_ASSERT( erased == 1 );
                    }
                    
                    guard.clear();
                    
                    typelib_typedescription_release( pTypeDescr );
                    (*fpFreeProxy)( pEnv, pInterface );
                }
            }
        }
    }
}

static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface)
{
	uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface);
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_getObjectIdentifier(
    uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
{
    OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
    if (*ppOId)
    {
        ::rtl_uString_release( *ppOId );
        *ppOId = 0;
    }

    uno_DefaultEnvironment * that =
        static_cast< uno_DefaultEnvironment * >( pEnv );
    ::osl::ClearableMutexGuard guard( that->mutex );

    Ptr2ObjectMap::const_iterator const iFind(
        that->aPtr2ObjectMap.find( pInterface ) );
    if (iFind == that->aPtr2ObjectMap.end())
    {
        guard.clear();
        (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
    }
    else
    {
        rtl_uString * hstr = iFind->second->oid.pData;
        rtl_uString_acquire( hstr );
        *ppOId = hstr;
    }
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_getRegisteredInterface(
    uno_ExtEnvironment * pEnv, void ** ppInterface,
    rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
{
    OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
    if (*ppInterface)
    {
        (*pEnv->releaseInterface)( pEnv, *ppInterface );
        *ppInterface = 0;
    }

    OUString const & rOId = OUString::unacquired( &pOId );
    uno_DefaultEnvironment * that =
        static_cast< uno_DefaultEnvironment * >( pEnv );
    ::osl::MutexGuard guard( that->mutex );

    OId2ObjectMap::const_iterator const iFind
        ( that->aOId2ObjectMap.find( rOId ) );
    if (iFind != that->aOId2ObjectMap.end())
    {
        InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
        if (pIEntry)
        {
            (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
            *ppInterface = pIEntry->pInterface;
        }
    }
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_getRegisteredInterfaces(
    uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen,
    uno_memAlloc memAlloc )
{
    OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" );
    uno_DefaultEnvironment * that =
        static_cast< uno_DefaultEnvironment * >( pEnv );
    ::osl::MutexGuard guard( that->mutex );

    sal_Int32 nLen = that->aPtr2ObjectMap.size();
    sal_Int32 nPos = 0;
    void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) );

    Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() );
    Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() );
    while (iPos != iEnd)
    {
        (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first );
        ++iPos;
    }

    *pppInterfaces = ppInterfaces;
    *pnLen = nLen;
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
{
    uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    ::osl_incrementInterlockedCount( &that->nWeakRef );
    ::osl_incrementInterlockedCount( &that->nRef );
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_release( uno_Environment * pEnv )
{
    uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    if (! ::osl_decrementInterlockedCount( &that->nRef ))
    {
        // invoke dispose callback
        if (pEnv->environmentDisposing)
        {
            (*pEnv->environmentDisposing)( pEnv );
        }

        OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" );
    }
    // free memory if no weak refs left
    if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
    {
        delete that;
    }
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
{
    uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    ::osl_incrementInterlockedCount( &that->nWeakRef );
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv )
{
    uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    if (! ::osl_decrementInterlockedCount( &that->nWeakRef ))
    {
        delete that;
    }
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_harden(
    uno_Environment ** ppHardEnv, uno_Environment * pEnv )
{
    if (*ppHardEnv)
    {
        (*(*ppHardEnv)->release)( *ppHardEnv );
        *ppHardEnv = 0;
    }

    EnvironmentsData & rData = theEnvironmentsData::get();

    if (rData.isDisposing)
        return;

    uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    {
    ::osl::MutexGuard guard( rData.mutex );
    if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead
    {
        that->nRef = 0;
        return;
    }
    }
    ::osl_incrementInterlockedCount( &that->nWeakRef );
    *ppHardEnv = pEnv;
}

//------------------------------------------------------------------------------
static void SAL_CALL defenv_dispose( uno_Environment * )
{
}
}

//______________________________________________________________________________
uno_DefaultEnvironment::uno_DefaultEnvironment(
    const OUString & rEnvDcp_, void * pContext_ )
    : nRef( 0 ),
      nWeakRef( 0 )
{
    uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
    that->pReserved = 0;
    // functions
    that->acquire = defenv_acquire;
    that->release = defenv_release;
    that->acquireWeak = defenv_acquireWeak;
    that->releaseWeak = defenv_releaseWeak;
    that->harden = defenv_harden;
    that->dispose = defenv_dispose;
    that->pExtEnv = this;
    // identifier
    ::rtl_uString_acquire( rEnvDcp_.pData );
    that->pTypeName = rEnvDcp_.pData;
    that->pContext = pContext_;

    // will be late initialized
    that->environmentDisposing = 0;

    uno_ExtEnvironment::registerInterface = defenv_registerInterface;
    uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface;
    uno_ExtEnvironment::revokeInterface = defenv_revokeInterface;
    uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier;
    uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface;
    uno_ExtEnvironment::getRegisteredInterfaces =
        defenv_getRegisteredInterfaces;

}

//______________________________________________________________________________
uno_DefaultEnvironment::~uno_DefaultEnvironment()
{
    ::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
}

//==============================================================================
static void writeLine(
    void * stream, const sal_Char * pLine, const sal_Char * pFilter )
{
    if (pFilter && *pFilter)
    {
        // lookup pFilter in pLine
        while (*pLine)
        {
            if (*pLine == *pFilter)
            {
                sal_Int32 nPos = 1;
                while (pLine[nPos] && pFilter[nPos] == pLine[nPos])
                {
                    ++nPos;
                }
                if (! pFilter[nPos])
                {
                    if (stream)
                    {
                        fprintf( (FILE *) stream, "%s\n", pLine );
                    }
                    else
                    {
                        OSL_TRACE( pLine );
                        OSL_TRACE( "\n" );
                    }
                }
            }
            ++pLine;
        }
    }
    else
    {
        if (stream)
        {
            fprintf( (FILE *) stream, "%s\n", pLine );
        }
        else
        {
            fprintf( stderr, "%s\n", pLine );
        }
    }
}

//==============================================================================
static void writeLine(
    void * stream, const OUString & rLine, const sal_Char * pFilter )
{
    ::rtl::OString aLine( ::rtl::OUStringToOString(
                              rLine, RTL_TEXTENCODING_ASCII_US ) );
    writeLine( stream, aLine.getStr(), pFilter );
}

//##############################################################################
extern "C" void SAL_CALL uno_dumpEnvironment(
    void * stream, uno_Environment * pEnv, const sal_Char * pFilter )
    SAL_THROW_EXTERN_C()
{
    OSL_ENSURE( pEnv, "### null ptr!" );
    ::rtl::OUStringBuffer buf;

    if (! pEnv->pExtEnv)
    {
        writeLine( stream, "###################################"
                   "###########################################", pFilter );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment: ") );
        buf.append( pEnv->pTypeName );
        writeLine( stream, buf.makeStringAndClear(), pFilter );
        writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter );
        return;
    }

    writeLine( stream, "########################################"
               "######################################", pFilter );
    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment dump: ") );
    buf.append( pEnv->pTypeName );
    writeLine( stream, buf.makeStringAndClear(), pFilter );

    uno_DefaultEnvironment * that =
        reinterpret_cast< uno_DefaultEnvironment * >(pEnv);
    ::osl::MutexGuard guard( that->mutex );

    Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap );
    OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() );
    while (iPos != that->aOId2ObjectMap.end())
    {
        ObjectEntry * pOEntry = iPos->second;
        
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") );
        if (pOEntry->mixedObject)
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") );
        buf.append( pOEntry->nRef, 10 );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") );
        buf.append( pOEntry->oid );
        buf.append( (sal_Unicode) '\"' );
        writeLine( stream, buf.makeStringAndClear(), pFilter );

        for ( ::std::size_t nPos = 0;
              nPos < pOEntry->aInterfaces.size(); ++nPos )
        {
            const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos];
            
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("  - ") );
            buf.append(
                ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
            if (rIEntry.fpFreeProxy)
            {
                buf.appendAscii(
                    RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") );
                buf.append(
                    reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 );
            }
            else
            {
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") );
            }
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") );
            buf.append(
                reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 );
            
            if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0)
            {
                ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface );
                if (erased != 1)
                {
                    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
                                         " (ptr not found in map!)") );
                }
            }
            writeLine( stream, buf.makeStringAndClear(), pFilter );
        }
        ++iPos;
    }
    if (! ptr2obj.empty())
        writeLine( stream, "ptr map inconsistency!!!", pFilter );
    writeLine( stream, "#####################################"
               "#########################################", pFilter );
}

//##############################################################################
extern "C" void SAL_CALL uno_dumpEnvironmentByName(
    void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter )
    SAL_THROW_EXTERN_C()
{
    uno_Environment * pEnv = 0;
    uno_getEnvironment( &pEnv, pEnvDcp, 0 );
    if (pEnv)
    {
        ::uno_dumpEnvironment( stream, pEnv, pFilter );
        (*pEnv->release)( pEnv );
    }
    else
    {
        ::rtl::OUStringBuffer buf( 32 );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") );
        buf.append( pEnvDcp );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") );
        writeLine( stream, buf.makeStringAndClear(), pFilter );
    }
}

//------------------------------------------------------------------------------
inline static const OUString & unoenv_getStaticOIdPart()
{
    static OUString * s_pStaticOidPart = 0;
    if (! s_pStaticOidPart)
    {
        ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
        if (! s_pStaticOidPart)
        {
            ::rtl::OUStringBuffer aRet( 64 );
            aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
            // pid
            oslProcessInfo info;
            info.Size = sizeof(oslProcessInfo);
            if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) ==
                osl_Process_E_None)
            {
                aRet.append( (sal_Int64)info.Ident, 16 );
            }
            else
            {
                aRet.appendAscii(
                    RTL_CONSTASCII_STRINGPARAM("unknown process id") );
            }
            // good guid
            sal_uInt8 ar[16];
            ::rtl_getGlobalProcessId( ar );
            aRet.append( (sal_Unicode)';' );
            for ( sal_Int32 i = 0; i < 16; ++i )
                aRet.append( (sal_Int32)ar[i], 16 );

            static OUString s_aStaticOidPart( aRet.makeStringAndClear() );
            s_pStaticOidPart = &s_aStaticOidPart;
        }
    }
    return *s_pStaticOidPart;
}

extern "C"
{

//------------------------------------------------------------------------------
static void SAL_CALL unoenv_computeObjectIdentifier(
    uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
{
    OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
    if (*ppOId)
    {
        ::rtl_uString_release( *ppOId );
        *ppOId = 0;
    }

    uno_Interface * pUnoI = (uno_Interface *)
        ::cppu::binuno_queryInterface(
            pInterface, *typelib_static_type_getByTypeClass(
                typelib_TypeClass_INTERFACE ) );
    if (0 != pUnoI)
    {
        (*pUnoI->release)( pUnoI );
        // interface
        ::rtl::OUStringBuffer oid( 64 );
        oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 );
        oid.append( static_cast< sal_Unicode >(';') );
        // environment[context]
        oid.append( ((uno_Environment *) pEnv)->pTypeName );
        oid.append( static_cast< sal_Unicode >('[') );
        oid.append( reinterpret_cast< sal_Int64 >(
                        reinterpret_cast<
                        uno_Environment * >(pEnv)->pContext ), 16 );
        // process;good guid
        oid.append( unoenv_getStaticOIdPart() );
        OUString aStr( oid.makeStringAndClear() );
        ::rtl_uString_acquire( *ppOId = aStr.pData );
    }
}

//==============================================================================
static void SAL_CALL unoenv_acquireInterface(
    uno_ExtEnvironment *, void * pUnoI_ )
{
    uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
    (*pUnoI->acquire)( pUnoI );
}

//==============================================================================
static void SAL_CALL unoenv_releaseInterface(
    uno_ExtEnvironment *, void * pUnoI_ )
{
    uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
    (*pUnoI->release)( pUnoI );
}
}

//______________________________________________________________________________
EnvironmentsData::~EnvironmentsData()
{
    ::osl::MutexGuard guard( mutex );
    isDisposing = true;

    for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
          iPos != aName2EnvMap.end(); ++iPos )
    {
        uno_Environment * pWeak = iPos->second;
        uno_Environment * pHard = 0;
        (*pWeak->harden)( &pHard, pWeak );
        (*pWeak->releaseWeak)( pWeak );

        if (pHard)
        {
#if OSL_DEBUG_LEVEL > 1
            ::uno_dumpEnvironment( 0, pHard, 0 );
#endif
            (*pHard->dispose)( pHard ); // send explicit dispose
            (*pHard->release)( pHard );
        }
    }
}

//______________________________________________________________________________
inline void EnvironmentsData::getEnvironment(
    uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext )
{
    if (*ppEnv)
    {
        (*(*ppEnv)->release)( *ppEnv );
        *ppEnv = 0;
    }

    OUString aKey(
        OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) );
    aKey += rEnvDcp;

    // try to find registered mapping
    OUString2EnvironmentMap::const_iterator const iFind(
        aName2EnvMap.find( aKey ) );
    if (iFind != aName2EnvMap.end())
    {
        uno_Environment * pWeak = iFind->second;
        (*pWeak->harden)( ppEnv, pWeak );
    }
}

//______________________________________________________________________________
inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
{
    OSL_ENSURE( ppEnv, "### null ptr!" );
    uno_Environment * pEnv =  *ppEnv;

    OUString aKey(
        OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) );
    aKey += pEnv->pTypeName;

    // try to find registered environment
    OUString2EnvironmentMap::const_iterator const iFind(
        aName2EnvMap.find( aKey ) );
    if (iFind == aName2EnvMap.end())
    {
        (*pEnv->acquireWeak)( pEnv );
        ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion(
            aName2EnvMap.insert(
                OUString2EnvironmentMap::value_type( aKey, pEnv ) ) );
        OSL_ENSURE(
            insertion.second, "### insertion of env into map failed?!" );
    }
    else
    {
        uno_Environment * pHard = 0;
        uno_Environment * pWeak = iFind->second;
        (*pWeak->harden)( &pHard, pWeak );
        if (pHard)
        {
            if (pEnv)
                (*pEnv->release)( pEnv );
            *ppEnv = pHard;
        }
        else // registered one is dead
        {
            (*pWeak->releaseWeak)( pWeak );
            (*pEnv->acquireWeak)( pEnv );
            aName2EnvMap[ aKey ] = pEnv;
        }
    }
}

//______________________________________________________________________________
inline void EnvironmentsData::getRegisteredEnvironments(
    uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
    const OUString & rEnvDcp )
{
    OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" );

    // max size
    uno_Environment ** ppFound = (uno_Environment **)alloca(
        sizeof(uno_Environment *) * aName2EnvMap.size() );
    sal_Int32 nSize = 0;

    // find matching environment
    for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
          iPos != aName2EnvMap.end(); ++iPos )
    {
        uno_Environment * pWeak = iPos->second;
        if (!rEnvDcp.getLength() ||
            rEnvDcp.equals( pWeak->pTypeName ))
        {
            ppFound[nSize] = 0;
            (*pWeak->harden)( &ppFound[nSize], pWeak );
            if (ppFound[nSize])
                ++nSize;
        }
    }

    *pnLen = nSize;
    if (nSize)
    {
        *pppEnvs = (uno_Environment **) (*memAlloc)(
            sizeof (uno_Environment *) * nSize );
        OSL_ASSERT( *pppEnvs );
        while (nSize--)
        {
            (*pppEnvs)[nSize] = ppFound[nSize];
        }
    }
    else
    {
        *pppEnvs = 0;
    }
}

static bool loadEnv(OUString const  & cLibStem, 
					uno_Environment * pEnv,
					void            * /*pContext*/)
{
	// late init with some code from matching uno language binding
	// will be unloaded by environment
	oslModule hMod = cppu::detail::loadModule( cLibStem );
	
	if (!hMod)
		return false;

	OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT));
	uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
		::osl_getFunctionSymbol( hMod, aSymbolName.pData );
	if (!fpInit)
	{
		::osl_unloadModule( hMod );
		return false;
	}

	(*fpInit)( pEnv ); // init of environment
	::rtl_registerModuleForUnloading( hMod );

	return true;
}


extern "C"
{

//------------------------------------------------------------------------------
static uno_Environment * initDefaultEnvironment(
    const OUString & rEnvDcp, void * pContext )
{
    uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase;
	(*pEnv->acquire)( pEnv );

	OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp);

    // create default environment
    if (envTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
    {
        uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
		that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
		that->acquireInterface = unoenv_acquireInterface;
		that->releaseInterface = unoenv_releaseInterface;

		OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp);
		if (envPurpose.getLength()) 
		{
			rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1);
			libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno") );
			
			if(!loadEnv(libStem, pEnv, pContext))
			{
				pEnv->release(pEnv);
				return NULL;
			}
		}
    }
    else
    {
        // late init with some code from matching uno language binding
        ::rtl::OUStringBuffer aLibName( 16 );
        aLibName.append( envTypeName );
        aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" ) );
        OUString aStr( aLibName.makeStringAndClear() );

		if (!loadEnv(aStr, pEnv, pContext))
		{
			pEnv->release(pEnv);
			return NULL;
		}
    }

    return pEnv;
}

//##############################################################################
void SAL_CALL uno_createEnvironment(
    uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
    SAL_THROW_EXTERN_C()
{
    OSL_ENSURE( ppEnv, "### null ptr!" );
    if (*ppEnv)
        (*(*ppEnv)->release)( *ppEnv );
    
    OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
    *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
}

//##############################################################################
void SAL_CALL uno_direct_getEnvironment(
    uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
    SAL_THROW_EXTERN_C()
{
    OSL_ENSURE( ppEnv, "### null ptr!" );
    OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );

    EnvironmentsData & rData = theEnvironmentsData::get();

    ::osl::MutexGuard guard( rData.mutex );
    rData.getEnvironment( ppEnv, rEnvDcp, pContext );
    if (! *ppEnv)
    {
        *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
        if (*ppEnv)
        {
            // register new environment:
            rData.registerEnvironment( ppEnv );
        }
    }
}

//##############################################################################
void SAL_CALL uno_getRegisteredEnvironments(
    uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
    rtl_uString * pEnvDcp )
    SAL_THROW_EXTERN_C()
{
    EnvironmentsData & rData = theEnvironmentsData::get();

    ::osl::MutexGuard guard( rData.mutex );
    rData.getRegisteredEnvironments(
        pppEnvs, pnLen, memAlloc,
        (pEnvDcp ? OUString(pEnvDcp) : OUString()) );
}

} // extern "C"

}

