/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "pyuno_impl.hxx"

#include <osl/thread.h>
#include <osl/module.h>
#include <osl/process.h>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/bootstrap.hxx>
#include <locale.h>

#include <typelib/typedescription.hxx>

#include <com/sun/star/beans/XMaterialHolder.hpp>

#include <vector>

using rtl::OUString;
using rtl::OUStringToOString;
using rtl::OUStringBuffer;
using rtl::OStringBuffer;
using rtl::OString;

using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Any;
using com::sun::star::uno::TypeDescription;
using com::sun::star::uno::Sequence;
using com::sun::star::uno::Type;
using com::sun::star::uno::UNO_QUERY;
using com::sun::star::uno::RuntimeException;
using com::sun::star::uno::XComponentContext;
using com::sun::star::lang::XSingleServiceFactory;
using com::sun::star::lang::XUnoTunnel;
using com::sun::star::reflection::XIdlReflection;
using com::sun::star::script::XTypeConverter;
using com::sun::star::script::XInvocationAdapterFactory2;
using com::sun::star::script::XInvocation;
using com::sun::star::beans::XMaterialHolder;
using com::sun::star::beans::XIntrospection;

namespace pyuno
{
#define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )

static PyTypeObject RuntimeImpl_Type =
{
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    const_cast< char * >("pyuno_runtime"),
    sizeof (RuntimeImpl),
    0,
    (destructor) RuntimeImpl::del,
    (printfunc) 0,
    (getattrfunc) 0,
    (setattrfunc) 0,
#if PY_MAJOR_VERSION >= 3
    0, 
#else
    (cmpfunc) 0,
#endif
    (reprfunc) 0,
    0,
    0,
    0,
    (hashfunc) 0,
    (ternaryfunc) 0,
    (reprfunc) 0,
    (getattrofunc)0,
    (setattrofunc)0,
    NULL,
    0,
    NULL,
    (traverseproc)0,
    (inquiry)0,
    (richcmpfunc)0,
    0,
    (getiterfunc)0,
    (iternextfunc)0,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    (descrgetfunc)0,
    (descrsetfunc)0,
    0,
    (initproc)0,
    (allocfunc)0,
    (newfunc)0,
    (freefunc)0,
    (inquiry)0,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    (destructor)0
#if PY_VERSION_HEX >= 0x02060000
    , 0
#endif
};

/*----------------------------------------------------------------------
  Runtime implementation
 -----------------------------------------------------------------------*/
static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl )
    throw ( com::sun::star::uno::RuntimeException )
{
    PyThreadState * state = PyThreadState_Get();
    if( ! state )
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
            "python global interpreter must be held (thread must be attached)" )),
                                Reference< XInterface > () );
    }

    globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));

    if( ! globalDict.is() ) // FATAL !
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
            "can't find __main__ module" )), Reference< XInterface > ());
    }
    runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" );
}

static PyRef importUnoModule( ) throw ( RuntimeException )
{
    PyRef globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
    // import the uno module
    PyRef module( PyImport_ImportModule( const_cast< char * >("uno") ), SAL_NO_ACQUIRE );
    if( PyErr_Occurred() )
    {
        PyRef excType, excValue, excTraceback;
        PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
        PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE );

        OUStringBuffer buf;
        buf.appendAscii( "python object raised an unknown exception (" );
        PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE );
        
        buf.append( pyString2ustring( valueRep.get() ) ).appendAscii( ", traceback follows\n" );
        buf.append( pyString2ustring( str.get() ) );
        throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
    }
    PyRef dict( PyModule_GetDict( module.get() ) );
    return dict;
}

static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
{
    *pLevel = LogLevel::NONE;
    *ppFile = 0;
    OUString fileName;
    osl_getModuleURLFromFunctionAddress(
        reinterpret_cast< oslGenericFunction >(readLoggingConfig),
        (rtl_uString **) &fileName );
    fileName = OUString( fileName.getStr(), fileName.lastIndexOf( '/' )+1 );
    fileName += OUString::createFromAscii(  SAL_CONFIGFILE("pyuno") );
    rtl::Bootstrap bootstrapHandle( fileName );

    OUString str;
    if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGLEVEL" ), str ) )
    {
        if( str.equalsAscii( "NONE" ) )
            *pLevel = LogLevel::NONE;
        else if( str.equalsAscii( "CALL" ) )
            *pLevel = LogLevel::CALL;
        else if( str.equalsAscii( "ARGS" ) )
            *pLevel = LogLevel::ARGS;
        else
        {
            fprintf( stderr, "unknown loglevel %s\n",
                     OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
        }
    }
    if( *pLevel > LogLevel::NONE )
    {
        *ppFile = stdout;
        if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGTARGET" ), str ) )
        {
            if( str.equalsAscii( "stdout" ) )
                *ppFile = stdout; 
            else if( str.equalsAscii( "stderr" ) )
                *ppFile = stderr; 
            else
            {
                oslProcessInfo data;
                data.Size = sizeof( data );
                osl_getProcessInfo(
                    0 , osl_Process_IDENTIFIER , &data );
                osl_getSystemPathFromFileURL( str.pData, &str.pData);
                OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
                o += ".";
                o += OString::valueOf( (sal_Int32)data.Ident );
                
                *ppFile = fopen( o.getStr() , "w" );
                if ( *ppFile )
                {
                    // do not buffer (useful if e.g. analyzing a crash)
                    setvbuf( *ppFile, 0, _IONBF, 0 ); 
                }
                else
                {
                    fprintf( stderr, "couldn't create file %s\n",
                             OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
                    
                }
            }
        }
    }
}

/*-------------------------------------------------------------------
 RuntimeImpl implementations
 *-------------------------------------------------------------------*/
PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx )
    throw( com::sun::star::uno::RuntimeException )
{
    RuntimeImpl *me = PyObject_New (RuntimeImpl, &RuntimeImpl_Type);
    if( ! me )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ),
            Reference< XInterface > () );
    me->cargo = 0;
    // must use a different struct here, as the PyObject_New
    // makes C++ unusable
    RuntimeCargo *c = new RuntimeCargo();
    readLoggingConfig( &(c->logLevel) , &(c->logFile) );
    log( c, LogLevel::CALL, "Instantiating pyuno bridge" );
    
    c->valid = 1;
    c->xContext = ctx;
    c->xInvocation = Reference< XSingleServiceFactory > (
        ctx->getServiceManager()->createInstanceWithContext(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ),
            ctx ),
        UNO_QUERY );
    if( ! c->xInvocation.is() )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation service" ) ),
            Reference< XInterface > () );

    c->xTypeConverter = Reference< XTypeConverter > (
        ctx->getServiceManager()->createInstanceWithContext(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ),
            ctx ),
        UNO_QUERY );
    if( ! c->xTypeConverter.is() )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate typeconverter service" )),
            Reference< XInterface > () );

    c->xCoreReflection = Reference< XIdlReflection > (
        ctx->getServiceManager()->createInstanceWithContext(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" ) ),
            ctx ),
        UNO_QUERY );
    if( ! c->xCoreReflection.is() )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate corereflection service" )),
            Reference< XInterface > () );

    c->xAdapterFactory = Reference< XInvocationAdapterFactory2 > (
        ctx->getServiceManager()->createInstanceWithContext(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.InvocationAdapterFactory" ) ),
            ctx ),
        UNO_QUERY );
    if( ! c->xAdapterFactory.is() )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation adapter factory service" )),
            Reference< XInterface > () );

    c->xIntrospection = Reference< XIntrospection > (
        ctx->getServiceManager()->createInstanceWithContext(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ),
            ctx ),
        UNO_QUERY );
    if( ! c->xIntrospection.is() )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate introspection service" )),
            Reference< XInterface > () );
    
    Any a = ctx->getValueByName(OUString(
        RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager" )) );
    a >>= c->xTdMgr;
    if( ! c->xTdMgr.is() )
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )),
            Reference< XInterface > () );
            
    me->cargo =c;
    return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE );
}

void  stRuntimeImpl::del(PyObject* self)
{
    RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self );
    if( me->cargo->logFile )
        fclose( me->cargo->logFile );
    delete me->cargo;
    PyObject_Del (self);
}


void Runtime::initialize( const Reference< XComponentContext > & ctx )
    throw ( RuntimeException )
{
    PyRef globalDict, runtime;
    getRuntimeImpl( globalDict , runtime );
    RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
    
    if( runtime.is() && impl->cargo->valid )
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
            "pyuno runtime has already been initialized before" ) ),
                                Reference< XInterface > () );
    }
    PyRef keep( RuntimeImpl::create( ctx ) );
    PyDict_SetItemString( globalDict.get(), "pyuno_runtime" , keep.get() );
    Py_XINCREF( keep.get() );
}


bool Runtime::isInitialized() throw ( RuntimeException )
{
    PyRef globalDict, runtime;
    getRuntimeImpl( globalDict , runtime );
    RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
    return runtime.is() && impl->cargo->valid;
}

void Runtime::finalize() throw (RuntimeException)
{
    PyRef globalDict, runtime;
    getRuntimeImpl( globalDict , runtime );
    RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
    if( !runtime.is() || ! impl->cargo->valid )
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
            "pyuno bridge must have been initialized before finalizing" )),
                                Reference< XInterface > () );
    }
    impl->cargo->valid = false;
    impl->cargo->xInvocation.clear();
    impl->cargo->xContext.clear();
    impl->cargo->xTypeConverter.clear();
}

Runtime::Runtime() throw(  RuntimeException )
    : impl( 0 )
{
    PyRef globalDict, runtime;
    getRuntimeImpl( globalDict , runtime );
    if( ! runtime.is() )
    {
        throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("pyuno runtime is not initialized, "
                                                  "(the pyuno.bootstrap needs to be called before using any uno classes)")),
            Reference< XInterface > () );
    }
    impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
    Py_XINCREF( runtime.get() );
}

Runtime::Runtime( const Runtime & r )
{
    impl = r.impl;
    Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
}

Runtime::~Runtime()
{
    Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
}

Runtime & Runtime::operator = ( const Runtime & r )
{
    PyRef temp( reinterpret_cast< PyObject * >(r.impl) );
    Py_XINCREF( temp.get() );
    Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
    impl = r.impl;
    return *this;
}

PyRef Runtime::any2PyObject (const Any &a ) const
    throw ( com::sun::star::script::CannotConvertException,
            com::sun::star::lang::IllegalArgumentException,
            RuntimeException)
{
    if( ! impl->cargo->valid )
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
            "pyuno runtime must be initialized before calling any2PyObject" )),
                                Reference< XInterface > () );
    }
    
    switch (a.getValueTypeClass ())
    {
    case typelib_TypeClass_VOID:
	{
        Py_INCREF (Py_None);
        return PyRef(Py_None);
	}
    case typelib_TypeClass_CHAR:
	{
        sal_Unicode c = *(sal_Unicode*)a.getValue();
        return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE );
	}
    case typelib_TypeClass_BOOLEAN:
	{
        sal_Bool b = sal_Bool();
        if ((a >>= b) && b)
            return Py_True; 
        else
            return Py_False;
	}
    case typelib_TypeClass_BYTE:
    case typelib_TypeClass_SHORT:
    case typelib_TypeClass_UNSIGNED_SHORT:
    case typelib_TypeClass_LONG:
	{
        sal_Int32 l = 0;
        a >>= l;
#if PY_MAJOR_VERSION >= 3
        return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE );
#else
        return PyRef( PyInt_FromLong (l), SAL_NO_ACQUIRE );
#endif
	}
    case typelib_TypeClass_UNSIGNED_LONG:
	{
        sal_uInt32 l = 0;
        a >>= l;
        return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
	}
    case typelib_TypeClass_HYPER:
	{
        sal_Int64 l = 0;
        a >>= l;
        return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
	}
    case typelib_TypeClass_UNSIGNED_HYPER:
	{
        sal_uInt64 l = 0;
        a >>= l;
        return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
	}
    case typelib_TypeClass_FLOAT:
	{
        float f = 0.0;
        a >>= f;
        return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
	}
    case typelib_TypeClass_DOUBLE:
	{
        double d = 0.0;
        a >>= d;
        return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
	}
    case typelib_TypeClass_STRING:
	{
        OUString tmp_ostr;
        a >>= tmp_ostr;
        return ustring2PyUnicode( tmp_ostr );
	}
    case typelib_TypeClass_TYPE:
	{
        Type t;
        a >>= t;
        OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
        return PyRef(
            PyUNO_Type_new (
                o.getStr(),  (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
            SAL_NO_ACQUIRE);
	}
    case typelib_TypeClass_ANY:
	{
        //I don't think this can happen.
        Py_INCREF (Py_None);
        return Py_None;
	}
    case typelib_TypeClass_ENUM:
	{
        sal_Int32 l = *(sal_Int32 *) a.getValue();
        TypeDescription desc( a.getValueType() );
        if( desc.is() )
        {
            desc.makeComplete();
            typelib_EnumTypeDescription *pEnumDesc =
                (typelib_EnumTypeDescription *) desc.get();
            for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ )
            {
                if( pEnumDesc->pEnumValues[i] == l )
                {
                    OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US);
                    OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US);
                    return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE );
                }
            }
        }
        OUStringBuffer buf;
        buf.appendAscii( "Any carries enum " );
        buf.append( a.getValueType().getTypeName());
        buf.appendAscii( " with invalid value " ).append( l );
        throw RuntimeException( buf.makeStringAndClear() , Reference< XInterface > ()  );
	}
    case typelib_TypeClass_EXCEPTION:
    case typelib_TypeClass_STRUCT:
    {
        PyRef excClass = getClass( a.getValueType().getTypeName(), *this );
        PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE);
        PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE );
        PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() );
        PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE );
        if( ! ret.is() )
        {
            OUStringBuffer buf;
            buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
            buf.append( a.getValueType().getTypeName() );
            throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
        }

        if( com::sun::star::uno::TypeClass_EXCEPTION == a.getValueTypeClass() )
        {
            // add the message in a standard python way !
            PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
            
            // assuming that the Message is always the first member, wuuuu
            void *pData = (void*)a.getValue();
            OUString message = *(OUString * )pData;
            PyRef pymsg = USTR_TO_PYSTR( message );
            PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() );
            // the exception base functions want to have an "args" tuple,
            // which contains the message
            PyObject_SetAttrString( ret.get(), const_cast< char * >("args"), args.get() );
        }
        return ret;
    }
    case typelib_TypeClass_SEQUENCE:
	{
        Sequence<Any> s;

        Sequence< sal_Int8 > byteSequence;
        if( a >>= byteSequence )
        {
            // byte sequence is treated in a special way because of peformance reasons
            // @since 0.9.2
            return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
        }
        else
        {
            Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter;
            Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation;
            tc->convertTo (a, ::getCppuType (&s)) >>= s;
            PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE);
            int i=0;
            OUString errMsg;
            try
            {
                for ( i = 0; i < s.getLength (); i++)
                {
                    PyRef element;
                    element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() ));
                    OSL_ASSERT( element.is() );
                    PyTuple_SetItem( tuple.get(), i, element.getAcquired() );
                }
            }
            catch( com::sun::star::uno::Exception & )
            {
                for( ; i < s.getLength() ; i ++ )
                {
                    Py_INCREF( Py_None );
                    PyTuple_SetItem( tuple.get(), i,  Py_None );
                }
                throw;
            }
            return tuple;
	    }
	}
    case typelib_TypeClass_INTERFACE:
	{
        Reference< XUnoTunnel > tunnel;
        a >>= tunnel;
        if( tunnel.is() )
        {
            sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
            if( that )
                return ((Adapter*)sal::static_int_cast< sal_IntPtr >(that))->getWrappedObject();
        }
        //This is just like the struct case:
        return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE );
	}
    default:
	{
        OUStringBuffer buf;
        buf.appendAscii( "Unknonwn UNO type class " );
        buf.append( (sal_Int32 ) a.getValueTypeClass() );
        throw RuntimeException(buf.makeStringAndClear( ), Reference< XInterface > () );
	}
    }
    //We shouldn't be here...
    Py_INCREF( Py_None );
    return Py_None;
}

static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o )
{
    Sequence< Type > ret;

    PyRef method( PyObject_GetAttrString( o , const_cast< char * >("getTypes") ), SAL_NO_ACQUIRE );
    raiseInvocationTargetExceptionWhenNeeded( r );
    if( method.is() && PyCallable_Check( method.get() ) )
    {
        PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE );
        raiseInvocationTargetExceptionWhenNeeded( r );
        if( types.is() && PyTuple_Check( types.get() ) )
        {
            int size = PyTuple_Size( types.get() );

            // add the XUnoTunnel interface  for uno object identity concept (hack)
            ret.realloc( size + 1 );
            for( int i = 0 ; i < size ; i ++ )
            {
                Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i));
                a >>= ret[i];
            }
            ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 );
        }
    }
    return ret;
}

Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) const
    throw ( com::sun::star::uno::RuntimeException )
{
    if( ! impl->cargo->valid )
    {
        throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
            "pyuno runtime must be initialized before calling any2PyObject" )),
                                Reference< XInterface > () );
    }

    Any a;
    PyObject *o = source.get();
    if( Py_None == o )
    {

    }
#if PY_MAJOR_VERSION >= 3	// Python 3 has no PyInt
    else if (PyBool_Check(o))
    {
        if( o == Py_True )
        {
            sal_Bool b = sal_True;
            a = Any( &b, getBooleanCppuType() );
        }
        else
        {
            sal_Bool b = sal_False;
            a = Any( &b, getBooleanCppuType() );
        }
    }
#else
    else if (PyInt_Check (o))
    {
        if( o == Py_True )
        {
            sal_Bool b = sal_True;
            a = Any( &b, getBooleanCppuType() );
        }
        else if ( o == Py_False )
        {
            sal_Bool b = sal_False;
            a = Any( &b, getBooleanCppuType() );
        }
        else
        {
            sal_Int32 l = (sal_Int32) PyInt_AsLong( o );
            if( l < 128 && l >= -128 )
            {
                sal_Int8 b = (sal_Int8 ) l;
                a <<= b;
            }
            else if( l <= 0x7fff && l >= -0x8000 )
            {
                sal_Int16 s = (sal_Int16) l;
                a <<= s;
            }
            else
            {
                a <<= l;
            }
        }
    }
#endif				// Python 3 has no PyInt
    else if (PyLong_Check (o))
    {
        sal_Int64 l = (sal_Int64)PyLong_AsLong (o);
        if( l < 128 && l >= -128 )
        {
            sal_Int8 b = (sal_Int8 ) l;
            a <<= b;
        }
        else if( l <= 0x7fff && l >= -0x8000 )
        {
            sal_Int16 s = (sal_Int16) l;
            a <<= s;
        }
        else if( l <= SAL_CONST_INT64(0x7fffffff) &&
                 l >= -SAL_CONST_INT64(0x80000000) )
        {
            sal_Int32 l32 = (sal_Int32) l;
            a <<= l32;
        }
        else
        {
            a <<= l;
        }
    }
    else if (PyFloat_Check (o))
    {
        double d = PyFloat_AsDouble (o);
        a <<= d;
    }
#if PY_MAJOR_VERSION < 3
    else if (PyBytes_Check (o))
	a <<= pyString2ustring(o);
#endif
    else if( PyUnicode_Check( o ) )
	a <<= pyString2ustring(o);
    else if (PyTuple_Check (o))
    {
        Sequence<Any> s (PyTuple_Size (o));
        for (int i = 0; i < PyTuple_Size (o); i++)
        {
            s[i] = pyObject2Any (PyTuple_GetItem (o, i), mode );
        }
        a <<= s;
    }
    else
    {
        Runtime runtime;
        // should be removed, in case ByteSequence gets derived from String 
        if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) )
        {
            PyRef str(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE);
            Sequence< sal_Int8 > seq;
            if( PyBytes_Check( str.get() ) )
            {
                seq = Sequence<sal_Int8 > (
                    (sal_Int8*) PyBytes_AsString(str.get()), PyBytes_Size(str.get()));
            }
#if PY_MAJOR_VERSION >= 3
            else if ( PyByteArray_Check( str.get() ) )
            {
                seq = Sequence< sal_Int8 >(
                    (sal_Int8 *) PyByteArray_AS_STRING(str.get()), PyByteArray_GET_SIZE(str.get()));
            }
#endif
            a <<= seq;                                                          
        }
        else
        if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
        {
            Type t = PyType2Type( o );
            a <<= t;
        }
        else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) )
        {
            a = PyEnum2Enum( o );
        }
        else if( isInstanceOfStructOrException( o ) )
        {
            PyRef struc(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE);
            PyUNO * obj = (PyUNO*)struc.get();
            Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY );
            if( holder.is( ) )
                a = holder->getMaterial();
            else
            {
                throw RuntimeException(
                    USTR_ASCII( "struct or exception wrapper does not support XMaterialHolder" ),
                    Reference< XInterface > () );
            }
        }
        else if( PyObject_IsInstance( o, getPyUnoClass().get() ) )
        {
            PyUNO* o_pi;
            o_pi = (PyUNO*) o;
            if (o_pi->members->wrappedObject.getValueTypeClass () ==
                com::sun::star::uno::TypeClass_STRUCT ||
                o_pi->members->wrappedObject.getValueTypeClass () ==
                com::sun::star::uno::TypeClass_EXCEPTION)
            {
                Reference<XMaterialHolder> my_mh (o_pi->members->xInvocation, UNO_QUERY);

                if (!my_mh.is ())
                {
                    throw RuntimeException(
                        USTR_ASCII( "struct wrapper does not support XMaterialHolder" ),
                        Reference< XInterface > () );
                }
                else
                    a = my_mh->getMaterial ();
            }
            else
            {
                a = o_pi->members->wrappedObject;
            }
        }
        else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) )
        {
            sal_Unicode c = PyChar2Unicode( o );
            a.setValue( &c, getCharCppuType( ));
        }
        else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) )
        {
            if( ACCEPT_UNO_ANY == mode )
            {
                a = pyObject2Any( PyRef( PyObject_GetAttrString( o , const_cast< char * >("value") ), SAL_NO_ACQUIRE) );
                Type t;
                pyObject2Any( PyRef( PyObject_GetAttrString( o, const_cast< char * >("type") ), SAL_NO_ACQUIRE ) ) >>= t;

                try
                {
                    a = getImpl()->cargo->xTypeConverter->convertTo( a, t );
                }
                catch( com::sun::star::uno::Exception & e )
                {
                    throw RuntimeException( e.Message, e.Context );
                }
            }
            else
            {
                throw RuntimeException(
                    OUString( RTL_CONSTASCII_USTRINGPARAM(
                                  "uno.Any instance not accepted during method call, "
                                  "use uno.invoke instead" ) ),
                    Reference< XInterface > () );
            }
        }
        else
        {
            Reference< XInterface > mappedObject;
            Reference< XInvocation > adapterObject;
            
            // instance already mapped out to the world ?
            PyRef2Adapter::iterator ii = impl->cargo->mappedObjects.find( PyRef( o ) );
            if( ii != impl->cargo->mappedObjects.end() )
            {
                adapterObject = ii->second;
            }

            if( adapterObject.is() )
            {
                // object got already bridged !
                Reference< com::sun::star::lang::XUnoTunnel > tunnel( adapterObject, UNO_QUERY );
                
                Adapter *pAdapter = ( Adapter * )
                    sal::static_int_cast< sal_IntPtr >(
                        tunnel->getSomething(
                            ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
                
                mappedObject = impl->cargo->xAdapterFactory->createAdapter(
                    adapterObject, pAdapter->getWrappedTypes() );
            }
            else 
            {
                Sequence< Type > interfaces = invokeGetTypes( *this, o );
                if( interfaces.getLength() )
                {
                    Adapter *pAdapter = new Adapter( o, interfaces );
                    mappedObject = 
                        getImpl()->cargo->xAdapterFactory->createAdapter(
                            pAdapter, interfaces );
                    
                    // keep a list of exported objects to ensure object identity !
                    impl->cargo->mappedObjects[ PyRef(o) ] =
                        com::sun::star::uno::WeakReference< XInvocation > ( pAdapter );
                }
            }
            if( mappedObject.is() )
            {
                a = com::sun::star::uno::makeAny( mappedObject );
            }
            else
            {
                OUStringBuffer buf;
                buf.appendAscii( "Couldn't convert " );
                PyRef reprString( PyObject_Str( o ) , SAL_NO_ACQUIRE );
                buf.append( pyString2ustring( reprString.get() ) );
                buf.appendAscii( " to a UNO type" );
                throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
            }
        }
    }
    return a;
}

Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
{
    PyRef str;
    Any ret;
    if( excTraceback.is() )
    {
        PyRef unoModule( impl ? impl->cargo->getUnoModule() : 0 );
        if( unoModule.is() )
        {
            PyRef extractTraceback(
                PyDict_GetItemString(unoModule.get(),"_uno_extract_printable_stacktrace" ) );
            
            if( extractTraceback.is() )
            {
                PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE );
                PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() );
                str = PyRef( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE);
            }
            else
            {
                str = PyRef(
                    PyBytes_FromString( "Couldn't find uno._uno_extract_printable_stacktrace" ),
                    SAL_NO_ACQUIRE );
            }
        }
        else
        {
            str = PyRef(
                PyBytes_FromString( "Couldn't find uno.py, no stacktrace available" ),
                SAL_NO_ACQUIRE );
        }

    }
    else
    {
        // it may occur, that no traceback is given (e.g. only native code below)
        str = PyRef( PyBytes_FromString( "no traceback available" ), SAL_NO_ACQUIRE);
    }
    
    if( isInstanceOfStructOrException( excValue.get() ) )
    {
        ret = pyObject2Any( excValue );
    }
    else
    {
        OUStringBuffer buf;
        PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
        if( typeName.is() )
        {
            buf.append( pyString2ustring( typeName.get() ) );
        }
        else
        {
            buf.appendAscii( "no typename available" );
        }
        buf.appendAscii( ": " );
        PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
        if( valueRep.is() )
        {
            buf.append( pyString2ustring( valueRep.get()));
        }
        else
        {
            buf.appendAscii( "Couldn't convert exception value to a string" );
        }
        buf.appendAscii( ", traceback follows\n" );
        if( str.is() )
        {
            buf.append( pyString2ustring( str.get() ) );
        }
        else
        {
            buf.appendAscii( ", no traceback available\n" );
        }
        RuntimeException e;
        e.Message = buf.makeStringAndClear();
        ret = com::sun::star::uno::makeAny( e );
    }
    return ret;
}


static const char * g_NUMERICID = "pyuno.lcNumeric";
static ::std::vector< rtl::OString > g_localeList;

static const char *ensureUnlimitedLifetime( const char *str )
{
    int size = g_localeList.size();
    int i;
    for( i = 0 ; i < size ; i ++ )
    {
        if( 0 == strcmp( g_localeList[i].getStr(), str ) )
            break;
    }
    if( i == size )
    {
        g_localeList.push_back( str );
    }
    return g_localeList[i].getStr();
}


PyThreadAttach::PyThreadAttach( PyInterpreterState *interp)
    throw ( com::sun::star::uno::RuntimeException )
{
    tstate = PyThreadState_New( interp );
    if( !tstate  )
        throw RuntimeException(
            OUString(RTL_CONSTASCII_USTRINGPARAM( "Couldn't create a pythreadstate" ) ),
            Reference< XInterface > () );
    PyEval_AcquireThread( tstate);
    // set LC_NUMERIC to "C"
    const char * oldLocale =
        ensureUnlimitedLifetime( setlocale( LC_NUMERIC, 0 )  );
    setlocale( LC_NUMERIC, "C" );
    PyRef locale( // python requires C locale
        PyLong_FromVoidPtr( (void*)oldLocale ), SAL_NO_ACQUIRE);
    PyDict_SetItemString(
        PyThreadState_GetDict(), g_NUMERICID, locale.get() );
}

PyThreadAttach::~PyThreadAttach()
{
    PyObject *value =
        PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
    if( value )
        setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
    PyThreadState_Clear( tstate );
    PyEval_ReleaseThread( tstate );
    PyThreadState_Delete( tstate );
    
}

PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException )
{
    tstate = PyThreadState_Get();
    PyObject *value =
        PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
    if( value )
        setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
    PyEval_ReleaseThread( tstate );
}

    /** Acquires the global interpreter lock again

    */
PyThreadDetach::~PyThreadDetach()
{
    PyEval_AcquireThread( tstate );
//     PyObject *value =
//         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );

    // python requires C LC_NUMERIC locale,
    // always set even when it is already "C"
    setlocale( LC_NUMERIC, "C" );    
}


PyRef RuntimeCargo::getUnoModule()
{
    if( ! dictUnoModule.is() )
    {
        dictUnoModule = importUnoModule();
    }
    return dictUnoModule;
}
}
