diff -ruNp cli_ure-orig/prj/build.lst cli_ure/prj/build.lst
--- cli_ure-orig/prj/build.lst	2007-07-20 12:36:10.000000000 +0200
+++ cli_ure/prj/build.lst	2007-07-20 12:41:11.000000000 +0200
@@ -8,5 +8,6 @@
 ure	cli_ure\unotypes			nmake	-	w,vc7	ure_unotypes ure_source_version ure_source_source.w ure_source_climaker.w ure_inc NULL
 ure	cli_ure\source\ure			nmake	-	w,vc7	ure_source_ure ure_source_version ure_source_source.w ure_unotypes.w ure_inc NULL
 ure	cli_ure\source\uno_bridge	nmake	-	w,vc7	ure_source_uno_bridge ure_unotypes.w ure_source_ure.w ure_inc NULL
+ure	cli_ure\source\mono_bridge      nmake   -       u       ure_source_mono_bridge ure_unotypes ure_source_ure ure_inc NULL
 ure	cli_ure\source\native		nmake	-	w,vc7	ure_source_native ure_source_version ure_source_source.w ure_source_ure.w ure_unotypes.w ure_source_uno_bridge.w ure_inc NULL
 #ure	cli_ure\util			nmake	-	w,vc7	ure_util ure_source_ure.w ure_source_native.w NULL
diff -ruNp cli_ure-orig/source/mono_bridge/binaryuno.cs cli_ure/source/mono_bridge/binaryuno.cs
--- cli_ure-orig/source/mono_bridge/binaryuno.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/binaryuno.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,192 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace uno.Binary {
+
+using System;
+using System.Runtime.InteropServices;
+using uno.Typelib;
+using uno.rtl;
+
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct Any
+{
+    /** type of value
+     */
+    public uno.Typelib.TypeDescriptionReference *pType;
+
+    /** pointer to value; this may point to pReserved and thus the uno_Any is not anytime
+        mem-copyable! You may have to correct the pData pointer to pReserved. Otherwise you need
+        not, because the data is stored in heap space.
+    */
+    public void *pData;
+    /** reserved space for storing value
+    */
+    public void *pReserved;
+
+    [ DllImport("uno_cppu", EntryPoint="uno_any_construct") ]
+    public static unsafe extern void Construct(/* Any */ void *dest,
+					       void *source,
+					       /* uno.Typelib.TypeDescriptionReference */ void *type,
+					       void *acquireFunction);
+
+    [ DllImport("uno_cppu", EntryPoint="uno_any_destruct") ]
+    public static unsafe extern void Destroy(/* Any */ void *value, void *releaseFunction);
+}
+
+// FIXME wrap this nicely
+public struct Interface 
+{
+    [ DllImport("cli_uno", EntryPoint="cli_uno_interface_acquire") ]
+    public static extern void Acquire(IntPtr unoInterface);
+
+    [ DllImport("cli_uno", EntryPoint="cli_uno_interface_release") ]
+    public static extern void Release(IntPtr unoInterface);
+
+    [ DllImport("cli_uno", EntryPoint="cli_uno_interface_dispatch") ]
+    public static unsafe extern void Dispatch(IntPtr unoInterface,
+                                              /* uno.Typelib.TypeDescription */ void *memberTD,
+                                              void *result,
+                                              void **args,
+                                              uno.Binary.Any **exception);
+}
+
+// FIXME and this
+public class Environment
+{
+    [ DllImport("cli_uno", EntryPoint="cli_uno_environment_getObjectIdentifier") ]
+    public static unsafe extern void GetObjectIdentifier(IntPtr unoEnvironment,
+							 UString** oid,
+							 IntPtr unoInterface);
+
+    [ DllImport("cli_uno", EntryPoint="cli_uno_environment_registerInterface") ]
+    public static unsafe extern void RegisterInterface(
+        IntPtr unoEnvironment,
+        ref IntPtr ppInterface,
+        /* UString */ void* oid,
+        /* InterfaceTypeDescription */ void *td);
+
+    [ DllImport("cli_uno", EntryPoint="cli_uno_environment_getRegisteredInterface") ]
+    public static unsafe extern void GetRegisteredInterface(
+        IntPtr unoEnvironment,
+        ref IntPtr ppInterface,
+        /* UString */ void* oid,
+        /* InterfaceTypeDescription */ void *td);
+}
+
+public struct Data
+{
+    [ DllImport("uno_cppu", EntryPoint="uno_type_destructData") ]
+    public static unsafe extern void Destroy(void *data,
+                                             /* uno.Typelib.TypeDescription */ void *td,
+                                             // FIXME is this okay? release is a function pointer
+                                             void *release);
+}
+
+public unsafe struct SequencePtr
+{
+    int *sal_Sequence;
+
+    // 	sal_Int32			nRefCount;
+    // 	sal_Int32			nElements;
+    // 	char				elements[1];
+
+	/** element count<br>
+	*/
+	/** elements array<br>
+	*/
+
+	/** reference count of sequence<br>
+	*/
+    private unsafe int nRefCount
+    {
+        get { return *(sal_Sequence); }
+        set { *(sal_Sequence) = value; }
+    }
+
+    public unsafe int nElements
+    {
+        get { return *(sal_Sequence + 1); }
+        set { *(sal_Sequence + 1) = value; }
+    }
+
+    public unsafe IntPtr elementsPtr
+    {
+        get { return new IntPtr((void *)(sal_Sequence + 2)); }        
+    }
+
+    private unsafe SequencePtr(void *mem)
+    {
+        sal_Sequence = (int*)mem;
+    }
+
+    private const int HEADER_SIZE = 8; // FIXME alignment
+
+    public static SequencePtr Allocate(int length, int elementSize)
+    {
+        void *rtlPtr = uno.rtl.Mem.Allocate(HEADER_SIZE + (length * elementSize));
+        SequencePtr seqPtr = new SequencePtr(rtlPtr);
+        seqPtr.nRefCount = 1;
+        seqPtr.nElements = length;
+        return seqPtr;
+    }
+}
+}
diff -ruNp cli_ure-orig/source/mono_bridge/bridge.cs cli_ure/source/mono_bridge/bridge.cs
--- cli_ure-orig/source/mono_bridge/bridge.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/bridge.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,1873 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace com.sun.star.bridges.mono_uno /* FIXME use some uno.foo namespace ? */
+{
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Remoting;
+using System.Text;
+using uno.Binary;
+using uno.rtl;
+using uno.Typelib;
+
+public unsafe class Bridge
+{
+    static IntPtr unoEnvironment;
+    static cli_uno.Cli_environment managedEnvironment;    
+
+    Bridge(IntPtr unoEnv)
+    {
+        unoEnvironment = unoEnv;
+        managedEnvironment = new cli_uno.Cli_environment();
+    }
+
+    public unsafe IntPtr MapManagedToUno(object managedData, TypeDescription *td)
+    {
+        IntPtr result = new IntPtr(null);
+
+        // get oid from managed environment
+        string oid = cli_uno.Cli_environment.getObjectIdentifier(managedData);
+
+        UString* unoOid = null;
+        UString.NewFromString(&unoOid, oid);
+        uno.Binary.Environment.GetRegisteredInterface(unoEnvironment,
+                                                      ref result,
+                                                      unoOid,
+                                                      (InterfaceTypeDescription *)td);
+        if (result == IntPtr.Zero)
+            lock (typeof(cli_uno.Cli_environment))
+            {
+                uno.Binary.Environment.GetRegisteredInterface(unoEnvironment,
+                                                              ref result,
+                                                              unoOid,
+                                                              (InterfaceTypeDescription *)td);
+                if (result == IntPtr.Zero)
+                    result = CreateManagedProxy(managedData, td, unoOid);
+            }
+            
+        UString.Release(unoOid);
+
+        return result;            
+    }
+
+    public unsafe object MapUnoToManaged(IntPtr unoInterface, InterfaceTypeDescription *iTD)
+    {
+        object result = null;
+
+        UString* oidPtr = null;
+        uno.Binary.Environment.GetObjectIdentifier(unoEnvironment, &oidPtr, unoInterface);
+
+        // See if the interface was already mapped
+        Type ifaceType = MapUnoType((TypeDescription *)iTD);
+        string oid = UString.UStringToString(oidPtr);
+        // the string is owned by unoEnvironment
+        oidPtr = null;
+
+        lock (managedEnvironment)
+        {
+            result = managedEnvironment.getRegisteredInterface(oid, ifaceType);
+            if (result != null)
+            {
+                // There is already an registered object. It can either be a proxy
+                // for the UNO object or a real cli object. In the first case we
+                // tell the proxy that it shall also represent the current UNO
+                // interface. If it already does that, then it does nothing
+                if (RemotingServices.IsTransparentProxy(result))
+                {
+                    UnoInterfaceProxy p = (UnoInterfaceProxy)RemotingServices.GetRealProxy(result);
+                    p.AddUnoInterface(unoInterface, iTD);
+                }
+            }
+            else
+            {
+                result = UnoInterfaceProxy.Create(this, unoInterface, iTD, oid);
+            }
+        }
+
+        return result;
+    }
+
+    // FIXME convert cli types to expected types, e.g a long to a short where the uno type
+    // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
+    // @param assign the uno_data has to be destructed (in/out args)
+    unsafe void MapToUno(void *unoData, object managedData,
+                         // FIXME it's a TypeDescriptionReference
+                         TypeDescription *type, bool assign)
+    {
+        // FIXME acquire the TypeDescription?
+        // FIXME assert that all the type equivalences in the comments hold
+        switch (type->eTypeClass)
+        {
+        case TypeClass.VOID:
+            break;
+        case TypeClass.CHAR:
+            *(ushort *)unoData = (char)managedData; // sal_Unicode = ushort
+            break;
+        case TypeClass.BOOLEAN:
+            *(byte *)unoData = (bool)managedData ? (byte)1 : (byte)0; // sal_Bool = byte
+            break;
+        case TypeClass.BYTE:
+            *(byte *)unoData = (byte)managedData; // sal_Int8 = byte
+            break;
+        case TypeClass.SHORT:
+            *(short *)unoData = (short)managedData; // sal_Int16 = short
+            break;
+        case TypeClass.UNSIGNED_SHORT:
+            *(ushort *)unoData = (ushort)managedData; // sal_uInt16 = ushort
+            break;
+        case TypeClass.LONG:
+            *(int *)unoData = (int)managedData; // sal_Int32 = int
+            break;
+        case TypeClass.UNSIGNED_LONG:
+            *(uint *)unoData = (uint)managedData; // sal_uInt32 = uint
+            break;
+        case TypeClass.HYPER:
+            *(long *)unoData = (long)managedData; // sal_Int64 = long
+            break;
+        case TypeClass.UNSIGNED_HYPER:
+            *(ulong *)unoData = (ulong)managedData; // sal_uInt64 = ulong
+            break;
+        case TypeClass.FLOAT:
+            *(float *)unoData = (float)managedData; // C++ float = C# float
+            break;
+        case TypeClass.DOUBLE:
+            *(double *)unoData = (double)managedData; // C++ double = C# double
+            break;
+        case TypeClass.STRING:
+        {
+            if (assign && *(UString **)unoData != null)
+                UString.Release(*(UString **)unoData);
+
+            *(UString **)unoData = null;
+            if (managedData == null)
+            {
+                UString.New((UString **)unoData);
+            }
+            else
+            {
+                string s = (string)managedData;
+                UString.NewFromString((UString **)unoData, s);
+            }
+        }
+        break;
+        case TypeClass.TYPE:
+            if (assign)
+                TypeDescriptionReference.Release(*(TypeDescriptionReference **)unoData);
+
+            *(TypeDescriptionReference **)unoData = MapManagedType((Type)managedData);
+            break;
+        case TypeClass.ANY:
+        {
+            uno.Binary.Any *binAny = (uno.Binary.Any *)unoData;
+
+            if (assign)
+                uno.Binary.Any.Destroy(binAny, null);
+
+            if (managedData == null)
+            {
+                uno.Binary.Any.Construct(binAny, null, null, null);
+                break;
+            }
+
+            uno.Any any = (uno.Any)managedData;
+            TypeDescription *valueTD = (TypeDescription *)MapManagedType(any.Type);
+
+            // if there's enough room in void *pReserved, store the value in the pointer
+            binAny->pData = &binAny->pReserved; // this triggers a bug in mcs < 1.1.4
+            switch (valueTD->eTypeClass)
+            {
+            case TypeClass.VOID:
+                break;
+            case TypeClass.CHAR:
+                *(ushort *)binAny->pData = (char)any.Value;
+                break;
+            case TypeClass.BOOLEAN:
+                *(byte *)binAny->pData = (bool)any.Value ? (byte)1 : (byte)0;
+                break;
+            case TypeClass.BYTE:
+                *(byte *)binAny->pData = (byte)any.Value;
+                break;
+            case TypeClass.SHORT:
+                *(short *)binAny->pData = (short)any.Value;
+                break;
+            case TypeClass.UNSIGNED_SHORT:
+                *(ushort *)binAny->pData = (ushort)any.Value;
+                break;
+            case TypeClass.LONG:
+                *(int *)binAny->pData = (int)any.Value;
+                break;
+            case TypeClass.UNSIGNED_LONG:
+                *(uint *)binAny->pData = (uint)any.Value;
+                break;
+            case TypeClass.HYPER:
+                if (sizeof(long) > sizeof(void *))
+                    binAny->pData = uno.rtl.Mem.Allocate(sizeof(long));
+
+                *(long *)binAny->pData = (long)any.Value;
+                break;
+            case TypeClass.UNSIGNED_HYPER:
+                if (sizeof(ulong) > sizeof(void *))
+                    binAny->pData = uno.rtl.Mem.Allocate(sizeof(ulong));
+
+                *(ulong *)binAny->pData = (ulong)any.Value;
+                break;
+            case TypeClass.FLOAT:
+                if (sizeof(float) > sizeof(void *)) // FIXME can this happen?
+                    binAny->pData = uno.rtl.Mem.Allocate(sizeof(float));
+
+                *(float *)binAny->pData = (float)any.Value;
+                break;
+            case TypeClass.DOUBLE:
+                if (sizeof(double) > sizeof(void *))
+                    binAny->pData = uno.rtl.Mem.Allocate(sizeof(double));
+
+                *(double *)binAny->pData = (double)any.Value;
+                break;
+            case TypeClass.STRING:
+                // string anies are used so often, that we handle them
+                // separately, to be a little faster than with an
+                // extra MapToUno call
+                
+                // the Any was already destroyed, can't contain a
+                // valid string that we could leak here.
+                *(UString **)binAny->pData = null;
+
+                if (managedData == null)
+                {
+                    UString.New((UString **)binAny->pData);
+                }
+                else
+                {
+                    string s = (string)any.Value;
+                    UString.NewFromString((UString **)binAny->pData, s);
+                }
+                // the string is owned by the Any
+                break;
+            case TypeClass.ENUM:
+                *(int *) binAny->pData = System.Convert.ToInt32(any.Value);
+                break;
+            case TypeClass.TYPE:
+            case TypeClass.SEQUENCE:
+            case TypeClass.INTERFACE:
+                binAny->pReserved = null;
+                MapToUno(binAny->pData, any.Value, valueTD, false /* no assign */);
+                break;
+            case TypeClass.STRUCT:
+            case TypeClass.EXCEPTION:
+                binAny->pData = uno.rtl.Mem.Allocate(valueTD->nSize);
+                MapToUno(binAny->pData, any.Value, valueTD, false /* no assign */);
+                break;
+            default:
+                // FIXME
+                throw new Exception();
+            }
+            binAny->pType = (TypeDescriptionReference *)valueTD;
+            TypeDescriptionReference.Acquire(binAny->pType);
+        }
+        break;
+        case TypeClass.ENUM:
+            *(int *)unoData = System.Convert.ToInt32(managedData);
+            break;
+        case TypeClass.STRUCT:
+        case TypeClass.EXCEPTION:
+        {
+            TypeDescription *td = null; // FIXME leak
+            TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+            CompoundTypeDescription *compTD = (CompoundTypeDescription *)td;
+            StructTypeDescription *structTD = null;
+
+            if (type->eTypeClass == TypeClass.STRUCT)
+                structTD = (StructTypeDescription *)type;
+
+            if (((TypeDescription *)compTD)->bComplete == 0)
+                TypeDescription.Complete((TypeDescription **)&compTD);
+
+            int members = compTD->nMembers;
+            Type managedType = null;
+            if (managedData != null)
+                managedType = managedData.GetType();
+
+            if (compTD->pBaseTypeDescription != null)
+                MapToUno(unoData, managedData,
+                         (TypeDescription *)((TypeDescription *)compTD->pBaseTypeDescription)->pWeakRef,
+                         assign);
+
+            TypeDescriptionReference *memberType = null;
+            for (int i = 0; i < members; ++i)
+            {
+                memberType = compTD->ppTypeRefs[i];
+
+                object val = null;
+                if (managedData != null)
+                {
+                    string fieldName = UString.UStringToString(compTD->ppMemberNames[i]);
+                    FieldInfo fieldInfo = managedType.GetField(fieldName);
+                    // special case for Exception.Message property
+                    // The com.sun.star.uno.Exception.Message field is mapped to the
+                    // System.Exception property. Type.GetField("Message") returns null
+                    if (fieldInfo == null &&
+                        UString.UStringToString(type->pTypeName) == "com.sun.star.uno.Exception")
+                    {
+                        // get ExceptionMessage property
+                        if (fieldName == "Message")
+                        {
+                            PropertyInfo propInfo = managedType.GetProperty(fieldName);
+                            val = propInfo.GetValue(managedData, null);
+                        } // FIXME  else throw exception
+                    }
+                    else if (fieldInfo != null)
+                    {
+                        val = fieldInfo.GetValue(managedData);
+                    } // FIXME else throw exception
+                }
+
+                void *p = (byte *)unoData + compTD->pMemberOffsets[i];
+                // When using polymorphic structs then the parameterized members can be null.
+                // Then we set a default value.
+                bool useDefault = ((structTD != null &&
+                                    structTD->pParameterizedTypes != null &&
+                                    structTD->pParameterizedTypes[i] == 1 &&
+                                    val == null) ||
+                                   managedData == null);
+                switch (memberType->eTypeClass)
+                {
+                case TypeClass.CHAR:
+                    if (useDefault)
+                        *(ushort *)p = 0;
+                    else
+                        *(ushort *)p = (char)val;
+                    break;
+                case TypeClass.BOOLEAN:
+                    if (useDefault)
+                        *(byte *)p = (byte)0;
+                    else
+                        *(byte *)p = (bool)val ? (byte)1 : (byte)0;
+                    break;
+                case TypeClass.BYTE:
+                    if (useDefault)
+                        *(byte *)p = (byte)0;
+                    else
+                        *(byte *)p = (byte)val;
+                    break;
+                case TypeClass.SHORT:
+                    if (useDefault)
+                        *(short *)p = (short)0;
+                    else
+                        *(short *)p = (short)val;
+                    break;
+                case TypeClass.UNSIGNED_SHORT:
+                    if (useDefault)
+                        *(ushort *)p = (ushort)0;
+                    else
+                        *(ushort *)p = (ushort)val;
+                    break;
+                case TypeClass.LONG:
+                    if (useDefault)
+                        *(int *)p = 0;
+                    else
+                        *(int *)p = (int)val;
+                    break;
+                case TypeClass.UNSIGNED_LONG:
+                    if (useDefault)
+                        *(uint *)p = (uint)0;
+                    else
+                        *(uint *)p = (uint)val;
+                    break;
+                case TypeClass.HYPER:
+                    if (useDefault)
+                        *(long *)p = (long)0;
+                    else
+                        *(long *)p = (long)val;
+                    break;
+                case TypeClass.UNSIGNED_HYPER:
+                    if (useDefault)
+                        *(ulong *)p = (ulong)0;
+                    else
+                        *(ulong *)p = (ulong)val;
+                    break;
+                case TypeClass.FLOAT:
+                    if (useDefault)
+                        *(float *)p = 0.0F;
+                    else
+                        *(float *)p = (float)val;
+                    break;
+                case TypeClass.DOUBLE:
+                    if (useDefault)
+                        *(double *)p = 0.0;
+                    else
+                        *(double *)p = (double)val;
+                    break;
+                default:
+                    // FIXME enum should be converted here
+                    MapToUno(p, val, (TypeDescription *)memberType, assign);
+                    break;
+                }       
+            }
+            // FIXME exception handling
+        }
+        break;
+        case TypeClass.SEQUENCE:
+        {
+            TypeDescription *td = null; // FIXME
+            TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+            TypeDescriptionReference *elementType =
+                ((IndirectTypeDescription *)td)->pType;
+
+            SequencePtr seq = new SequencePtr();
+
+            if (managedData != null)
+            {
+                Array array = (Array)managedData;
+                int length = array.GetLength(0);
+
+                switch (elementType->eTypeClass)
+                {
+                case TypeClass.CHAR:
+                    seq = SequencePtr.Allocate(length, sizeof(ushort));
+                    Marshal.Copy((char [])managedData, 0, seq.elementsPtr, length);
+                    break;
+/*                case TypeClass.BOOLEAN:
+                    // FIXME bool vs. byte ???
+                    seq = SequencePtr.Allocate(length, sizeof(byte));
+                    Marshal.Copy((byte [])managedData, 0, seq.elementsPtr, length);
+                    break;*/
+                case TypeClass.BYTE:
+                    seq = SequencePtr.Allocate(length, sizeof(byte));
+                    Marshal.Copy((byte [])managedData, 0, seq.elementsPtr, length);
+                    break;
+                case TypeClass.SHORT:
+                    seq = SequencePtr.Allocate(length, sizeof(short));
+                    Marshal.Copy((short [])managedData, 0, seq.elementsPtr, length);
+                    break;
+/*                case TypeClass.UNSIGNED_SHORT:
+                    seq = SequencePtr.Allocate(length, sizeof(ushort));
+                    Marshal.Copy((short [])managedData, 0, seq.elementsPtr, length);
+                    break; */
+                case TypeClass.LONG:
+                    seq = SequencePtr.Allocate(length, sizeof(int));
+                    Marshal.Copy((int [])managedData, 0, seq.elementsPtr, length);
+                    break;
+/*                case TypeClass.UNSIGNED_LONG:
+                    seq = SequencePtr.Allocate(length, sizeof(uint));
+                    Marshal.Copy((int [])managedData, 0, seq.elementsPtr, length);
+                    break; */
+                case TypeClass.HYPER:
+                    seq = SequencePtr.Allocate(length, sizeof(long));
+                    Marshal.Copy((long [])managedData, 0, seq.elementsPtr, length);
+                    break;
+/*                case TypeClass.UNSIGNED_HYPER:
+                    seq = SequencePtr.Allocate(length, sizeof(ulong));
+                    Marshal.Copy((long [])managedData, 0, seq.elementsPtr, length);
+                    break; */
+                case TypeClass.FLOAT:
+                    seq = SequencePtr.Allocate(length, sizeof(float));
+                    Marshal.Copy((float [])managedData, 0, seq.elementsPtr, length);
+                    break;
+                case TypeClass.DOUBLE:
+                    seq = SequencePtr.Allocate(length, sizeof(double));
+                    Marshal.Copy((double [])managedData, 0, seq.elementsPtr, length);
+                    break;
+                case TypeClass.STRING:
+                {
+                    seq = SequencePtr.Allocate(length, sizeof(void *));
+                    string[] stringArray = (string [])managedData;
+                    for (int i = 0; i < length; ++i)
+                    {
+                        UString** pStr = ((UString** )seq.elementsPtr) + i;
+                        *pStr = null;
+                        UString.NewFromString(pStr, stringArray[i]);
+                        // string ownership goes to callee
+                    }
+                }
+                break;
+                case TypeClass.ENUM:
+                    seq = SequencePtr.Allocate(length, sizeof(int));
+                    for (int i = 0; i < length; ++i)
+                        ((int *)seq.elementsPtr)[i] =
+                            Convert.ToInt32(array.GetValue(i));
+                    break;
+                case TypeClass.TYPE:
+                case TypeClass.ANY:
+                case TypeClass.STRUCT:
+                case TypeClass.EXCEPTION:
+                case TypeClass.SEQUENCE:
+                case TypeClass.INTERFACE:
+		// FIXME: surely we can do better for this lot [!] - sign problems ...
+                case TypeClass.BOOLEAN:
+                case TypeClass.UNSIGNED_SHORT:
+		 case TypeClass.UNSIGNED_LONG:
+                case TypeClass.UNSIGNED_HYPER:
+                {
+                    seq = SequencePtr.Allocate(
+                        length, ((TypeDescription *)elementType)->nSize);
+
+                    for (int i = 0; i < length; ++i)
+                    {
+                        void *p =
+                            (byte *)seq.elementsPtr +
+                            i * ((TypeDescription *)elementType)->nSize;
+                        object elementData = ((Array)managedData).GetValue(i);
+                        MapToUno(p, elementData,
+                                 (TypeDescription *)((TypeDescription *)elementType)->pWeakRef,
+                                 false /* no assign */);
+                    }
+                    // FIXME exception handling
+                }
+                break;
+                default:
+                    break; // FIXME throw some exception
+                }
+            }
+            else
+            {
+                seq = SequencePtr.Allocate(0, sizeof(int));
+            }
+            *(SequencePtr *)unoData = seq;
+        }
+        break;
+        case TypeClass.INTERFACE:
+        {
+            if (assign && *(void **)unoData != null)
+                uno.Binary.Interface.Release(new IntPtr(*(void **)unoData));
+
+            if (managedData == null)
+                *(void **)unoData = null;
+            else
+            {
+                TypeDescription *td = null; // FIXME leak
+                TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);         
+                *(void **)unoData = MapManagedToUno(managedData, td).ToPointer();
+            }
+            break;
+        }
+        default:
+            // FIXME throw some exception
+            break;
+        }
+    }
+
+    unsafe void MapToManaged(ref object managedData, void *unoData,
+                             TypeDescriptionReference *type, Type info, bool dontCreateObj)
+    {
+        switch (type->eTypeClass)
+        {
+        case TypeClass.CHAR:
+            managedData = (char)*(ushort *)unoData;
+            break;
+        case TypeClass.BOOLEAN:
+            managedData = (*(byte *)unoData != 0);
+            break;
+        case TypeClass.BYTE:
+            managedData = *(byte *)unoData;
+            break;
+        case TypeClass.SHORT:
+            managedData = *(short *)unoData;
+            break;
+        case TypeClass.UNSIGNED_SHORT:
+            managedData = *(ushort *)unoData;
+            break;
+        case TypeClass.LONG:
+            managedData = *(int *)unoData;
+            break;
+        case TypeClass.UNSIGNED_LONG:
+            managedData = *(uint *)unoData;
+            break;
+        case TypeClass.HYPER:
+            managedData = *(long *)unoData;
+            break;
+        case TypeClass.UNSIGNED_HYPER:
+            managedData = *(ulong *)unoData;
+            break;
+        case TypeClass.FLOAT:
+            managedData = *(float *)unoData;
+            break;
+        case TypeClass.DOUBLE:
+            managedData = *(double *)unoData;
+            break;
+        case TypeClass.STRING:
+            managedData = UString.UStringToString(*(UString **)unoData);
+            break;
+        case TypeClass.TYPE:
+            managedData = MapUnoType(*(TypeDescriptionReference **)unoData);
+            break;
+        case TypeClass.ANY:
+        {
+            uno.Binary.Any *binAny = (uno.Binary.Any *)unoData;
+            if (binAny->pType->eTypeClass != TypeClass.VOID)
+            {
+                object value = null;
+                MapToManaged(ref value, binAny->pData, binAny->pType, null, false);
+                managedData = new uno.Any(MapUnoType(binAny->pType), value);
+            }
+            else
+            {
+                managedData = uno.Any.VOID;
+            }
+            break;
+        }
+        case TypeClass.ENUM:
+            if (info != null)
+                managedData = Enum.ToObject(
+                    info.GetElementType(), *(int *)unoData);
+            else
+                managedData = Enum.ToObject(
+                    MapUnoType(type), *(int *)unoData);
+            break;
+        case TypeClass.STRUCT:
+        case TypeClass.EXCEPTION:
+        {
+            TypeDescription *td = null; // FIXME leak
+            TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+            CompoundTypeDescription *compTD = (CompoundTypeDescription *)td;
+
+            if (((TypeDescription *)compTD)->bComplete == 0)
+                TypeDescription.Complete((TypeDescription **)&compTD);
+
+            // create the type
+            Type managedType = LoadCliType(td->pTypeName);
+
+            // detect if we recursivly convert inherited
+            // structures. If this point is reached because of a
+            // recursive call during converting a struct then we must
+            // not create a new object rather we use the one in
+            // cli_data argument.
+            object managedObject;
+            if (dontCreateObj)
+                managedObject = managedData;
+            else
+            {
+                // Special handling for Exception conversion. We must
+                // call constructor System::Exception to pass the
+                // message string
+                if (typeof(unoidl.com.sun.star.uno.Exception).IsAssignableFrom(managedType))
+                {
+                    // We need to get the Message field. Therefore we
+                    // must obtain the offset from the
+                    // typedescription. The base interface of all
+                    // exceptions is com::sun::star::uno::Exception
+                    // which contains the message
+                    CompoundTypeDescription *pCTD = compTD;
+                    while (pCTD->pBaseTypeDescription != null)
+                        pCTD = pCTD->pBaseTypeDescription;
+
+                    int pos = -1;                    
+                    for (int i = 0; i < pCTD->nMembers; ++i)
+                    {
+                        if (UString.UStringToString(pCTD->ppMemberNames[i]) == "Message")
+                        {
+                            pos = i;
+                            break;
+                        }
+                    }
+
+                    int offset = pCTD->pMemberOffsets[pos];
+                    // With the offset within the exception we can get
+                    // the message string
+                    string message = UString.UStringToString(
+                        (*(UString **)((byte *)unoData + offset)));
+                    // We need to find a constructor for the exception
+                    // that takes the message string.  We assume that
+                    // the first argument is the message string
+                    ConstructorInfo[] ctorInfos = managedType.GetConstructors();
+                    ConstructorInfo ctorInfo = null;
+                    // Constructor must at least have 2 params for the base
+                    // unoidl.com.sun.star.uno.Exception (String, Object);
+                    int numArgs = -1;
+                    foreach (ConstructorInfo ci in ctorInfos)
+                    {
+                        numArgs = ci.GetParameters().Length;
+                        if (numArgs < 2)
+                            continue;
+                        ctorInfo = ci;
+                        break;                            
+                    }
+                    
+                    // Prepare parameters for constructor
+                    object[] args = new object[numArgs];
+                    // only initialize the first argument with the
+                    // message. All unoidl.<Foo Exception>s are
+                    // autogenerated, we know that this is safe.
+                    args[0] = message;
+                    managedObject = ctorInfo.Invoke(args);
+                }
+                else
+                    managedObject = Activator.CreateInstance(managedType);
+            }
+
+            TypeDescriptionReference **memberTypeRefs = compTD->ppTypeRefs;
+            int *memberOffsets = compTD->pMemberOffsets;
+
+            if (compTD->pBaseTypeDescription != null)
+            {
+                // convert inherited struct
+                // cliObj is passed inout (args in_param, out_param are true), hence the passed
+                // cliObj is used by the callee instead of a newly created struct
+                MapToManaged(ref managedObject,  unoData,
+                             ((TypeDescription *)compTD->pBaseTypeDescription)->pWeakRef,
+                             null,
+                             true);
+            }
+            for (int i = compTD->nMembers - 1; i >= 0; --i)
+            {
+                TypeDescriptionReference *memberType = memberTypeRefs[i];
+                string memberName = UString.UStringToString(compTD->ppMemberNames[i]);
+                FieldInfo fieldInfo = managedType.GetField(memberName);
+                // special case for Exception.Message. The field has already been
+                // set while constructing cli object
+                if (fieldInfo == null &&
+                    UString.UStringToString(type->pTypeName) == "com.sun.star.uno.Exception")
+                    continue;
+
+                void *p = (byte *)unoData + memberOffsets[i];
+                switch (memberType->eTypeClass)
+                {
+                case TypeClass.CHAR:
+                    fieldInfo.SetValue(managedObject, (char)*(short *)p);
+                    break;
+                case TypeClass.BOOLEAN:
+                    fieldInfo.SetValue(managedObject, (*(byte *)p) != 0);
+                    break;
+                case TypeClass.BYTE:
+                    fieldInfo.SetValue(managedObject, *(byte *)p);
+                    break;
+                case TypeClass.SHORT:
+                    fieldInfo.SetValue(managedObject, *(short *)p);
+                    break;
+                case TypeClass.UNSIGNED_SHORT:
+                    fieldInfo.SetValue(managedObject, *(ushort *)p);
+                    break;
+                case TypeClass.LONG:
+                    fieldInfo.SetValue(managedObject, *(int *)p);
+                    break;
+                case TypeClass.UNSIGNED_LONG:
+                    fieldInfo.SetValue(managedObject, *(uint *)p);
+                    break;
+                case TypeClass.HYPER:
+                    fieldInfo.SetValue(managedObject, *(long *)p);
+                    break;
+                case TypeClass.UNSIGNED_HYPER:
+                    fieldInfo.SetValue(managedObject, *(ulong *)p);
+                    break;
+                case TypeClass.FLOAT:
+                    fieldInfo.SetValue(managedObject, *(float *)p);
+                    break;
+                case TypeClass.DOUBLE:
+                    fieldInfo.SetValue(managedObject, *(double *)p);
+                    break;
+                default:
+                {
+                    object managedValue = null;
+                    MapToManaged(ref managedValue, p, memberType, null, false);
+                    fieldInfo.SetValue(managedObject, managedValue);
+                    break;
+                }
+                }
+            }
+            managedData = managedObject;
+            break;
+        }
+        case TypeClass.SEQUENCE:
+        {
+            SequencePtr seq = *(SequencePtr *)unoData;
+            int length = seq.nElements;
+
+            TypeDescription *td = null; // FIXME leak
+            TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+            TypeDescriptionReference *elementType = ((IndirectTypeDescription *)td)->pType;
+
+            switch (elementType->eTypeClass)
+            {
+            case TypeClass.CHAR:
+            {
+                char[] array = new char[length];
+                Marshal.Copy(seq.elementsPtr, array, 0, length);
+                managedData = array;
+                break;
+            }
+            case TypeClass.BOOLEAN:
+            {
+                bool[] array = new bool[length];
+                byte *source = (byte *)seq.elementsPtr;
+                if (length > 0) fixed (bool *arrayPtr = array)
+                {
+                    bool *dest = arrayPtr;
+                    for (int i = 0; i < length; ++i)
+                        *dest++ = (*source++ != 0);
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.BYTE:
+            {
+                byte[] array = new byte[length];
+                byte *source = (byte *)seq.elementsPtr;
+                if (length > 0) fixed (byte *arrayPtr = array)
+                {
+                    byte *dest = arrayPtr;
+                    for (int i = 0; i < length; ++i)
+                        *dest++ = *source++;
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.SHORT:
+            {
+                short[] array = new short[length];
+                Marshal.Copy(seq.elementsPtr, array, 0, length);
+                managedData = array;
+                break;
+            }
+            case TypeClass.UNSIGNED_SHORT:
+            {
+                ushort[] array = new ushort[length];
+                ushort *source = (ushort *)seq.elementsPtr;
+                if (length > 0) fixed (ushort *arrayPtr = array)
+                {
+                    ushort *dest = arrayPtr;
+                    for (int i = 0; i < length; ++i)
+                        *dest++ = *source++;
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.LONG:
+            {
+                int[] array = new int[length];
+                Marshal.Copy(seq.elementsPtr, array, 0, length);
+                managedData = array;
+                break;
+            }
+            case TypeClass.UNSIGNED_LONG:
+            {
+                uint[] array = new uint[length];
+                uint *source = (uint *)seq.elementsPtr;
+                if (length > 0) fixed (uint *arrayPtr = array)
+                {
+                    uint *dest = arrayPtr;
+                    for (int i = 0; i < length; ++i)
+                        *dest++ = *source++;
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.HYPER:
+            {
+                long[] array = new long[length];
+                Marshal.Copy(seq.elementsPtr, array, 0, length);
+                managedData = array;
+                break;
+            }
+            case TypeClass.UNSIGNED_HYPER:
+            {
+                ulong[] array = new ulong[length];
+                ulong *source = (ulong *)seq.elementsPtr;
+                if (length > 0) fixed (ulong *arrayPtr = array)
+                {
+                    ulong *dest = arrayPtr;
+                    for (int i = 0; i < length; ++i)
+                        *dest++ = *source++;
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.FLOAT:
+            {
+                float[] array = new float[length];
+                Marshal.Copy(seq.elementsPtr, array, 0, length);
+                managedData = array;
+                break;
+            }
+            case TypeClass.DOUBLE:
+            {
+                double[] array = new double[length];
+                Marshal.Copy(seq.elementsPtr, array, 0, length);
+                managedData = array;
+                break;
+            }
+            case TypeClass.STRING:
+            {
+                string[] array = new string[length];
+                for (int i = 0; i < length; ++i)
+                {
+                    UString *us  = ((UString **)seq.elementsPtr)[i];
+                    array[i] = UString.UStringToString(us);
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.TYPE:
+            {
+                Type[] array = new Type[length];
+                for (int i = 0; i < length; ++i)
+                    array[i] = MapUnoType(((TypeDescriptionReference **)
+                                           seq.elementsPtr)[i]);
+                managedData = array;
+                break;
+            }
+            case TypeClass.ANY:
+            {
+                uno.Any[] array = new uno.Any[length];
+                uno.Binary.Any *binAny = (uno.Binary.Any *)seq.elementsPtr;
+                for (int i = 0; i < length; ++i)
+                {
+                    object any = new uno.Any();
+                    MapToManaged(ref any, (void **)(binAny + i),
+                                 (TypeDescriptionReference *)elementType,
+                                 null, false);
+                    array[i] = (uno.Any)any;
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.ENUM:
+            {
+                Type enumType = null;
+                if (info != null)
+                {
+                    enumType = info.GetElementType();
+                    // enumType is EnumType[], get EnumType
+                    enumType = enumType.GetElementType();
+                }
+                else
+                    enumType = MapUnoType(elementType);
+
+                Array array = Array.CreateInstance(enumType, length);
+                for (int i = 0; i < length; ++i)
+                {
+                    array.SetValue(Enum.ToObject(enumType,
+                                                 ((int *)seq.elementsPtr)[i]),
+                                   i);
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.STRUCT:
+            case TypeClass.EXCEPTION:
+            {
+                Array array = Array.CreateInstance(MapUnoType(elementType), length);
+                if (length > 0)
+                {
+                    // FIXME check this
+                    byte *p = (byte *)seq.elementsPtr;
+                    int size = ((TypeDescription *)elementType)->nSize;
+                    for (int i = 0; i < length; ++i)
+                    {
+                        object val = null;
+                        MapToManaged(ref val, p + (size * i), elementType, null, false);
+                        array.SetValue(val, i);
+                    }
+                }
+                managedData = array;
+                break;
+            }
+            // FIXME verify (says cli_data.cxx)
+            case TypeClass.SEQUENCE:
+            {
+                Array array = Array.CreateInstance(
+                    MapUnoType(elementType), length);
+                if (length > 0)
+                {
+                    SequencePtr *elements = (SequencePtr *)seq.elementsPtr;
+                    for (int i = 0; i < length; ++i)
+                    {
+                        object val = null;
+                        MapToManaged(ref val, elements + i, elementType, null, false);
+                        array.SetValue(val, i);
+                    }
+                }
+                managedData = array;
+                break;
+            }
+            case TypeClass.INTERFACE:
+            {
+                Type ifaceType = MapUnoType(elementType);
+                Array array = Array.CreateInstance(ifaceType, length);
+
+                byte *p = (byte *)seq.elementsPtr;
+                int size = ((TypeDescription *)elementType)->nSize;
+                for (int i = 0; i < length; ++i)
+                {
+                    object val = null;
+                    MapToManaged(ref val, p + (size * i), elementType, null, false);
+                    array.SetValue(val, i);
+                }
+                managedData = array;
+                break;
+            }
+            default:
+            {
+                // FIXME throw some exception
+                break;
+            }
+            }
+            break;
+        }
+        case TypeClass.INTERFACE:
+        {
+            IntPtr unoI = new IntPtr(*(void **)unoData);
+            if (unoI != IntPtr.Zero)
+            {
+                TypeDescription *td = null; // FIXME leak
+                TypeDescriptionReference.GetDescription(&td, type);
+                managedData = MapUnoToManaged(unoI, (InterfaceTypeDescription *)td);
+            }
+            else
+                managedData = null;
+            break;
+        }
+        default:
+        {
+            // FIXME throw some exception
+            break;
+        }
+        }
+    }
+
+    public static Type MapUnoType(TypeDescription *TD)
+    {
+        return MapUnoType(TD->pWeakRef);
+    }
+    
+    public static Type MapUnoType(TypeDescriptionReference *TD)
+    {
+        Type result;
+
+        switch(TD->eTypeClass)
+        {
+        case TypeClass.VOID:
+            result = typeof(void);
+            break;
+        case TypeClass.CHAR:
+            result = typeof(char);
+            break;
+        case TypeClass.BOOLEAN:
+            result = typeof(bool);
+            break;
+        case TypeClass.BYTE:
+            result = typeof(byte);
+            break;
+        case TypeClass.SHORT:
+            result = typeof(short);
+            break;
+        case TypeClass.UNSIGNED_SHORT:
+            result = typeof(ushort);
+            break;
+        case TypeClass.LONG:
+            result = typeof(int);
+            break;
+        case TypeClass.UNSIGNED_LONG:
+            result = typeof(uint);
+            break;
+        case TypeClass.HYPER:
+            result = typeof(long);
+            break;
+        case TypeClass.UNSIGNED_HYPER:
+            result = typeof(ulong);
+            break;
+        case TypeClass.FLOAT:
+            result = typeof(float);
+            break;
+        case TypeClass.DOUBLE:
+            result = typeof(double);
+            break;
+        case TypeClass.STRING:
+            result = typeof(string);
+            break;
+        case TypeClass.TYPE:
+            result = typeof(Type);
+            break;
+        case TypeClass.ANY:
+            result = typeof(uno.Any);
+            break;
+        case TypeClass.ENUM:
+        case TypeClass.STRUCT:
+        case TypeClass.EXCEPTION:
+            result = LoadCliType(TD->pTypeName);
+            break;
+        case TypeClass.INTERFACE:
+            // special handling for XInterface, since it does not exist in cli.
+            if (UString.UStringToString(TD->pTypeName) == "com.sun.star.uno.XInterface")
+                result = typeof(object);
+            else
+                result = LoadCliType(TD->pTypeName);
+            break;
+        case TypeClass.SEQUENCE:
+        {
+            TypeDescription *seqType = null; // FIXME leak
+            TypeDescriptionReference.GetDescription(&seqType, TD);
+
+            // FIXME do something with TD here?
+            TypeDescriptionReference *elementTDRef =
+                ((IndirectTypeDescription *)seqType)->pType;
+
+            switch (elementTDRef->eTypeClass)
+            {
+            case TypeClass.CHAR:
+                result = Type.GetType("System.Char[]");
+                break;
+            case TypeClass.BOOLEAN:
+                result = Type.GetType("System.Boolean[]");
+                break;
+            case TypeClass.BYTE:
+                result = Type.GetType("System.Byte[]");
+                break;
+            case TypeClass.SHORT:
+                result = Type.GetType("System.Int16[]");
+                break;
+            case TypeClass.UNSIGNED_SHORT:
+                result = Type.GetType("System.UInt16[]");
+                break;
+            case TypeClass.LONG:
+                result = Type.GetType("System.Int32[]");
+                break;
+            case TypeClass.UNSIGNED_LONG:
+                result = Type.GetType("System.UInt32[]");
+                break;
+            case TypeClass.HYPER:
+                result = Type.GetType("System.Int64[]");
+                break;
+            case TypeClass.UNSIGNED_HYPER:
+                result = Type.GetType("System.UInt64[]");
+                break;
+            case TypeClass.FLOAT:
+                result = Type.GetType("System.Single[]");
+                break;
+            case TypeClass.DOUBLE:
+                result = Type.GetType("System.Double[]");
+                break;
+            case TypeClass.STRING:
+                result = Type.GetType("System.String[]");
+                break;
+            case TypeClass.TYPE:
+                result = Type.GetType("System.Type[]");
+                break;
+            case TypeClass.ANY:
+            case TypeClass.ENUM:
+            case TypeClass.EXCEPTION:
+            case TypeClass.STRUCT:
+            case TypeClass.INTERFACE:
+            case TypeClass.SEQUENCE:
+                result = LoadCliType(TD->pTypeName);
+                break;
+            default:
+                // FIXME can't happen
+                result = null;
+                break;
+            }
+            break;
+        }
+        default:
+            // FIXME can't happen
+            result = null;
+            break;
+        }
+        return result;
+    }
+
+    public static Type LoadCliType(UString* unoName)
+    {
+        return LoadCliType(MapUnoTypeName(UString.UStringToString(unoName)));
+    }
+
+    public static Type LoadCliType(string unoName)
+    {
+        Type result = null;
+        bool isPolymorphic = false;
+
+        string loadName = unoName;
+        int index = unoName.IndexOf('<');
+        if (index != -1)
+        {
+            loadName = unoName.Substring(0, index);
+            isPolymorphic = true;
+        }
+        
+        result = Type.GetType(loadName + ",cli_types");
+
+        if (result == null)
+            result = Type.GetType(loadName + ",cli_basetypes");
+
+        if (result == null)
+            result = Type.GetType(loadName, false);
+
+        if (result == null)
+        {
+            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
+            {
+                result = a.GetType(loadName, false);
+                if (result != null)
+                    break;
+            }
+        }
+
+        if (result == null)
+            // FIXME don't use generic Exception type
+            throw new Exception("A type could not be loaded: " + loadName);
+
+        if (isPolymorphic)
+            result = uno.PolymorphicType.GetType(result, unoName);
+
+        return result;            
+    }
+
+    static TypeDescriptionReference *MapManagedType(Type managedType)
+    {
+        TypeDescriptionReference *result = null;
+        if (managedType == null)
+        {
+            result = *TypeDescriptionReference.GetByTypeClass(TypeClass.VOID);
+            TypeDescriptionReference.Acquire(result);
+            return result;
+        }
+
+        // check for Enum first,
+        // because otherwise case System.TypeCode.Int32 applies
+        if (managedType.IsEnum)
+        {
+            UString* unoTypeName = MapManagedTypeName(managedType.FullName);
+            TypeDescriptionReference.New(&result, TypeClass.ENUM, unoTypeName);
+            TypeDescriptionReference.Acquire(result);
+        }
+        else
+        {
+            switch (System.Type.GetTypeCode(managedType))
+            {
+            case System.TypeCode.Boolean:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.BOOLEAN);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Char:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.CHAR);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Byte:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.BYTE);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Int16:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.SHORT);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Int32:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.LONG);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Int64:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.HYPER);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.UInt16:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.UNSIGNED_SHORT);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.UInt32:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.UNSIGNED_LONG);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.UInt64:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.UNSIGNED_HYPER);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Single:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.FLOAT);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.Double:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.DOUBLE);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            case System.TypeCode.String:
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.STRING);
+                TypeDescriptionReference.Acquire(result);
+                break;
+            }
+        }
+
+        if (result == null)
+        {
+            string managedTypeName = managedType.FullName;
+            if (managedTypeName == "System.Void")
+            {
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.VOID);
+                TypeDescriptionReference.Acquire(result);
+            }
+            else if (managedTypeName == "System.Type")
+            {
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.TYPE);
+                TypeDescriptionReference.Acquire(result);
+            }
+            else if (managedTypeName == "uno.Any")
+            {
+                result = *TypeDescriptionReference.GetByTypeClass(TypeClass.ANY);
+                TypeDescriptionReference.Acquire(result);
+            }
+            else
+            {
+                UString* unoTypeName;
+
+                uno.PolymorphicType poly = managedType as uno.PolymorphicType;
+                if (poly != null)
+                    unoTypeName = MapManagedTypeName(poly.PolymorphicName);
+                else
+                    unoTypeName = MapManagedTypeName(managedTypeName);
+
+                TypeDescription *td = null;
+                TypeDescription.GetByName(&td, unoTypeName);
+                if (td != null)
+                {
+                    result = td->pWeakRef;
+                    TypeDescriptionReference.Acquire(result);
+                    TypeDescription.Release(td);
+                }
+            }
+        }
+
+        if (result == null)
+        {
+            // FIXME - quite probably we should throw an exception here instead.
+            result = *TypeDescriptionReference.GetByTypeClass(TypeClass.VOID);
+            TypeDescriptionReference.Acquire(result);
+        }
+
+        return result;
+    }
+
+    static string MapUnoTypeName(string typeName)
+    {
+        StringBuilder buf = new StringBuilder();
+
+        // determine if the type is a sequence and its dimensions
+        int dims = 0;
+        if (typeName[0] == '[')
+        {
+            int index = 1;
+            while (true)
+            {
+                if (typeName[index++] == ']')
+                    ++dims;
+                if (typeName[index++] != '[')
+                    break;
+            }
+            typeName = typeName.Substring(index - 1);
+        }
+
+        switch (typeName)
+        {
+        case "boolean":
+            buf.Append("System.Boolean");
+            break;
+        case "char":
+            buf.Append("System.Char");
+            break;
+        case "byte":
+            buf.Append("System.Byte");
+            break;
+        case "short":
+            buf.Append("System.Int16");
+            break;
+        case "unsigned short":
+            buf.Append("System.UInt16");
+            break;
+        case "long":
+            buf.Append("System.Int32");
+            break;
+        case "unsigned long":
+            buf.Append("System.UInt32");
+            break;
+        case "hyper":
+            buf.Append("System.Int64");
+            break;
+        case "unsigned hyper":
+            buf.Append("System.UInt64");
+            break;
+        case "float":
+            buf.Append("System.Single");
+            break;
+        case "double":
+            buf.Append("System.Double");
+            break;
+        case "string":
+            buf.Append("System.String");
+            break;
+        case "void":
+            buf.Append("System.Void");
+            break;
+        case "type":
+            buf.Append("System.Type");
+            break;
+        case "com.sun.star.uno.XInterface":
+            buf.Append("System.Object");
+            break;
+        case "any":
+            buf.Append("uno.Any");
+            break;
+        default:
+            // put "unoidl." at the beginning
+            buf.Append("unoidl.");
+            // for polymorphic struct types remove the brackets, e.g. mystruct<bool> -> mystruct
+            buf.Append(MapUnoPolymorphicName(typeName));
+            break;
+        }
+
+        // append []
+        for ( ; dims > 0; --dims)
+            buf.Append("[]");
+
+        return buf.ToString();
+    }
+
+    /** For example, there is a uno type
+        com.sun.star.Foo<char, long>.
+        The values in the type list
+        are uno types and are replaced by cli types, such as System.Char,
+        System.Int32, etc.
+    */
+    static string MapUnoPolymorphicName(string unoName)
+    {
+        int startIndex = unoName.LastIndexOf('<');
+        if (startIndex == -1)
+            return unoName;
+
+        // get the type list within < and >
+        int endIndex = unoName.LastIndexOf('>');
+        string list = unoName.Substring(startIndex + 1, endIndex - startIndex - 1);
+
+        // parse the type list and replace the types with the corresponding CLI types
+        char[] delimiters = new char[] { ',' };
+        string[] unoTypes = list.Split(delimiters);
+
+        StringBuilder builder = new StringBuilder(unoName.Substring(0, startIndex + 1));
+
+        int typeCount = unoTypes.Length;
+        for (int i = 0; i < typeCount; ++i)
+            builder.Append(MapUnoTypeName(unoTypes[i]));
+
+        builder.Append('>');
+        return builder.ToString();            
+    }
+    
+    static UString* MapManagedTypeName(string typeName)
+    {
+        int dims = 0;
+        int index = 0;
+        
+        if ((index = typeName.IndexOf("[]")) > 0)
+        {
+            dims = 1;
+            
+            int curIndex = index;
+            while ((curIndex + 2) < typeName.Length &&
+                   (curIndex = typeName.IndexOf("[]", curIndex + 2)) > 0)
+                ++dims;
+
+            // get the element name by removing the brackets
+            typeName = typeName.Substring(0, index);            
+        }
+            
+        StringBuilder buf = new StringBuilder(256);
+        for (; dims > 0; --dims)
+            buf.Append("[]");
+
+        switch (typeName)
+        {
+        case "System.Boolean":
+            buf.Append("boolean");
+            break;
+        case "System.Char":
+            buf.Append("char");
+            break;
+        case "System.Byte":
+            buf.Append("byte");
+            break;
+        case "System.Int16":
+            buf.Append("short");
+            break;
+        case "System.UInt16":
+            buf.Append("unsigned short");
+            break;
+        case "System.Int32":
+            buf.Append("long");
+            break;
+        case "System.UInt32":
+            buf.Append("unsigned long");
+            break;
+        case "System.Int64":
+            buf.Append("hyper");
+            break;
+        case "System.UInt64":
+            buf.Append("unsigned hyper");
+            break;
+        case "System.Single":
+            buf.Append("float");
+            break;
+        case "System.Double":
+            buf.Append("double");
+            break;
+        case "System.String":
+            buf.Append("string");
+            break;
+        case "System.Void":
+            buf.Append("void");
+            break;
+        case "System.Type":
+            buf.Append("type");
+            break;
+        case "System.Object":
+            buf.Append("com.sun.star.uno.XInterface");
+            break;
+        case "uno.Any":
+            buf.Append("any");
+            break;
+        default:
+        {
+            string name = MapManagedPolymorphicName(typeName);
+            int i = name.IndexOf('.');
+            buf.Append(name.Substring(i + 1));
+            break;
+        }
+        }
+
+        UString *rtl_uString = null;
+        UString.NewFromStringBuilder(&rtl_uString, buf);
+        return rtl_uString;
+    }
+
+    static string MapManagedPolymorphicName(string unoName)
+    {
+        int startIndex = unoName.LastIndexOf('<');
+        if (startIndex == -1)
+            return unoName;
+
+        // get the type list withing < and >
+        int endIndex = unoName.LastIndexOf('>');
+        string list = unoName.Substring(startIndex + 1, endIndex - startIndex - 1);
+
+        // parse the type list and replace the types with the corresponding CLI types
+        char[] delimiters = new char[] { ',' };
+        string[] unoTypes = list.Split(delimiters);
+
+        StringBuilder builder = new StringBuilder(unoName.Substring(0, startIndex + 1));
+        
+        int typeCount = unoTypes.Length;
+        for (int i = 0; i < typeCount; ++i)
+            builder.Append(UString.UStringToString(MapManagedTypeName(unoTypes[i])));
+        builder.Append('>');
+        return builder.ToString();
+    }
+
+    [StructLayout(LayoutKind.Explicit)]
+    private unsafe struct largest
+    {
+        [FieldOffset(0)] long n;
+        [FieldOffset(0)] double d;
+        [FieldOffset(0)] void *p;
+        [FieldOffset(0)] uno.Binary.Any a;    
+    }
+
+    // FIXME args[i] must be of same type as return value
+    public unsafe uno.Any CallUno(IntPtr unoInterface, TypeDescription *memberTD,
+                                  TypeDescriptionReference *returnType, int nParams,
+                                  MethodParameter *parameters, object[] args,
+                                  Type[] argTypes, out uno.Any exception)
+    {
+        int returnSize = sizeof(largest);
+
+        if (returnType != null &&
+            (returnType->eTypeClass == TypeClass.STRUCT ||
+             returnType->eTypeClass == TypeClass.EXCEPTION))
+        {
+            // FIXME leak
+            TypeDescription *td = null;
+            TypeDescriptionReference.GetDescription(&td, returnType);
+            
+            if (td->nSize > returnSize)
+                returnSize = td->nSize;
+        }
+
+        // Prepare memory that contains all converted arguments and
+        // return values. The memory block contains first pointers to
+        // the arguments which are in the same block For example, 2
+        // arguments, 1 ret.
+        //
+        //      | Pointer
+        //      | Pointer
+        //      | Return value
+        //      | Arg 1
+        //      | Arg 2
+        //
+        // If an argument is larger then struct largest, such as some
+        // structures, then the pointer points to an extra block of
+        // memory. The same goes for a big return value.
+        // FIXME the last sentence is bullshit. Get it deleted from cli_uno ;)
+        byte *mem = stackalloc byte[nParams * sizeof(void *) +
+                                    returnSize +
+                                    nParams * sizeof(largest)];
+
+        // array of pointers to args
+        void **unoArgPtrs = (void **)mem;
+
+        // Return Value
+        void *unoRetPtr = null;
+        largest *unoArgs = (largest *)(unoArgPtrs + nParams);
+        if (memberTD->eTypeClass != TypeClass.INTERFACE_ATTRIBUTE || nParams != 1)
+	{
+            // If an attribute is set, then unoRet must be null, e.g. void setAttribute(int)
+	    unoRetPtr = (void *)unoArgs;
+	    unoArgs = (largest *)((byte *)unoRetPtr + returnSize);
+	}
+
+        for (int i = 0; i < nParams; ++i)
+        {
+            // FIXME it's a TypeDescriptionReference
+            TypeDescription *type = (TypeDescription *)parameters[i].pTypeRef;
+
+            unoArgPtrs[i] = unoArgs + i;
+            if ((type->eTypeClass == TypeClass.STRUCT ||
+                 type->eTypeClass == TypeClass.EXCEPTION) &&
+                (type->nSize > sizeof(largest)))
+            {
+                // stackalloc is only allowed in initializers
+                byte *bigArgPtr = stackalloc byte[type->nSize];
+
+                unoArgPtrs[i] = bigArgPtr;
+            }
+                            
+            if (parameters[i].bIn != 0)
+            {
+                // FIXME error handling
+                MapToUno(unoArgPtrs[i], args[i], type, false /* no assign */);
+            }
+        }
+
+        uno.Binary.Any unoExceptionHolder;
+        uno.Binary.Any *unoExc = &unoExceptionHolder;
+
+        // call binary uno      
+        uno.Binary.Interface.Dispatch(
+            unoInterface, memberTD, unoRetPtr, unoArgPtrs, &unoExc);
+
+        if (unoExc == null)
+        {
+            exception = uno.Any.VOID;
+
+            // convert out args, destroy uno args
+            for (int i = 0; i < nParams; ++i)
+            {
+                // FIXME it's a TypeDescriptionReference
+                TypeDescription *type = (TypeDescription *)parameters[i].pTypeRef;
+
+                if (parameters[i].bOut != 0)
+                {
+                    // FIXME error handling
+                    MapToManaged(ref args[i], unoArgPtrs[i], parameters[i].pTypeRef,
+                                 argTypes != null ? argTypes[i] : null, false);
+                }
+
+                // cleanup args
+                if (type->eTypeClass < TypeClass.DOUBLE &&
+                    type->eTypeClass != TypeClass.ENUM) // no need to destroy these
+                    uno.Binary.Data.Destroy(unoArgPtrs[i], type, null);
+            }
+
+            if (returnType != null && returnType->eTypeClass != TypeClass.VOID)
+            {
+                // convert uno return value
+                object result = null;
+                // FIXME error handling
+                MapToManaged(ref result, unoRetPtr, returnType, null, false);
+                uno.Binary.Data.Destroy(unoRetPtr, (TypeDescription *)returnType, null);
+                return new uno.Any(MapUnoType(returnType), result); // FIXME is this correct?
+            }
+
+            return uno.Any.VOID;
+        }
+        else // exception occured
+        {
+            for (int i = 0; i < nParams; ++i)
+                if (parameters[i].bIn != 0)
+                    uno.Binary.Data.Destroy(unoArgPtrs[i], (TypeDescription *)parameters[i].pTypeRef, null);
+
+            // FIXME needs uno.Any vs System.Object clarification
+            object exc = null;
+            MapToManaged(ref exc, unoExceptionHolder.pData,
+                         unoExceptionHolder.pType, null, false);
+            exception = new uno.Any(MapUnoType(unoExceptionHolder.pType), exc);
+            return uno.Any.VOID;
+        }
+
+        // FIXME error handling
+    }
+
+    // FIXME rename, to say what it does, not how it does this
+    public void RegisterWithCliEnvironment(object managedI, string oid)
+    {
+        managedEnvironment.registerInterface(managedI, oid);
+    }
+
+    public void RegisterWithCliEnvironment(object managedI, string oid, Type type)
+    {
+        managedEnvironment.registerInterface(managedI, oid, type);
+    }
+
+    public void RegisterWithUnoEnvironment(ref IntPtr unoInterface, string oid, InterfaceTypeDescription *TD)
+    {
+        UString *unoOid = null;
+        UString.NewFromString(&unoOid, oid);
+        
+        uno.Binary.Environment.RegisterInterface(unoEnvironment, ref unoInterface, unoOid, TD);
+
+        UString.Release(unoOid);
+    }
+
+    public void GetInterfaceFromUnoEnvironment(ref IntPtr unoInterface, UString* unoOid, InterfaceTypeDescription* TD)
+    {
+        uno.Binary.Environment.GetRegisteredInterface(unoEnvironment, ref unoInterface, unoOid, TD);
+    }
+
+    public void RevokeFromUnoEnvironment(IntPtr unoInterface)
+    {
+        throw new NotImplementedException();
+    }
+    
+    public unsafe IntPtr CreateManagedProxy(object managedInterface,
+                                            TypeDescription* td,
+                                            UString* oid)
+    {
+        // register original interface
+        RegisterWithCliEnvironment(managedInterface,
+                                   UString.UStringToString(oid),
+                                   Bridge.MapUnoType(td));
+
+        ManagedProxy proxy = new ManagedProxy(this, managedInterface, td, oid);
+        GCHandle gchandle = GCHandle.Alloc(proxy);
+
+        // create binary uno uno_Interface and register proxy with target environment
+        IntPtr unoI = CreateBinaryProxyAndRegister(unoEnvironment, (IntPtr)gchandle,
+                                                   oid, td);
+
+        proxy.NativeProxy = unoI;
+        return unoI;
+    }
+
+    [ DllImport("cli_uno", EntryPoint="cli_uno_environment_createMonoProxyAndRegister") ]
+    public static unsafe extern IntPtr CreateBinaryProxyAndRegister(
+        IntPtr unoEnvironment,
+        IntPtr monoProxy,
+        /* UString */ void* oid,
+        /* InterfaceTypeDescription */ void* td);
+
+    public unsafe void CallManaged(object managedI, Type ifaceType, MethodInfo method,
+                                   TypeDescriptionReference* returnType,
+                                   MethodParameter* parameters, int nParams, void* unoRet,
+                                   void** unoArgs, uno.Binary.Any** unoExc)
+    {
+        object[] args = new object[nParams];
+        for (int i = 0; i < nParams; ++i)
+            if (parameters[i].bIn != 0)
+                MapToManaged(ref args[i], unoArgs[i], parameters[i].pTypeRef, null, false);
+
+        object invocationResult = null;
+        try
+        {
+            invocationResult = method.Invoke(managedI, args);
+        }
+        catch (TargetInvocationException e)
+        {
+            Exception exc = e.InnerException;
+            TypeDescription* td = null;
+            // FIXME leak
+            TypeDescriptionReference.GetDescription(&td, MapManagedType(exc.GetType()));
+            void* memExc = uno.rtl.Mem.Allocate(td->nSize);
+            MapToUno(memExc, exc, /* FIXME !!!*/ (TypeDescription*)td->pWeakRef, false);
+            (*unoExc)->pType = td->pWeakRef;
+            (*unoExc)->pData = memExc;
+            return;
+        }
+        catch (Exception e)
+        {
+            // FIXME
+        }
+
+        // convert out, in/out params
+        for (int i = 0; i < nParams; ++i)
+        {
+            if (parameters[i].bOut != 0)
+            {
+                MapToUno(
+                    unoArgs[i], args[i], /* FIXME !!! */(TypeDescription*)parameters[i].pTypeRef,
+                    parameters[i].bIn != 0 /* assign if inout */);
+                // FIXME error handling
+            }
+        }
+
+        // return value
+        if (returnType != null)
+            MapToUno(unoRet, invocationResult, /* FIXME !!! */(TypeDescription*)returnType, false /* no assign */);
+
+        // no exception occurred
+        *unoExc = null;
+    }
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/cli_environment.cs cli_ure/source/mono_bridge/cli_environment.cs
--- cli_ure-orig/source/mono_bridge/cli_environment.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/cli_environment.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,204 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace cli_uno
+{
+
+using System;
+using System.Collections;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Proxies;
+using System.Text;
+
+using com.sun.star.bridges.mono_uno;
+
+public class Cli_environment
+{
+    static string sOidPart = ";cli[0];";
+
+    static Hashtable m_objects = Hashtable.Synchronized(new Hashtable());
+
+    static string createKey(string oid, Type t)
+    {
+        return oid + t.FullName;
+    }
+
+//     FIXME setup debugging info here
+//     public Cli_environment()
+//     {
+//     }
+
+//     FIXME assert there are no more registered objects
+//     public ~Cli_environment()
+//     {
+//     }
+
+    /**
+       Registers an UNO object as being mapped by this bridge. The resulting
+       cli object is represents all interfaces of the UNO object. Therefore the
+       object can be registered only with its OID; a type is not necessary.
+    */
+    public object registerInterface(object obj, string oid)
+    {
+        // FIXME debugging stuff
+        m_objects.Add(oid, obj); // new WeakReference(obj));
+        return obj;
+    }
+
+    /**
+       Registers a CLI object as being mapped by this bridge. The resulting
+       object represents exactly one UNO interface.
+     */
+    public object registerInterface(object obj, string oid, Type type)
+    {
+        // FIXME debugging stuff
+        string key = createKey(oid, type);
+        m_objects.Add(key, obj); // new WeakReference(obj));
+        return obj;
+    }
+
+    /**
+       By revoking an interface it is declared that the respective interface has
+       not been mapped. The proxy implementations call revoke interface in their
+       destructors.
+     */
+    public void revokeInterface(string oid)
+    {
+        revokeInterface(oid, null);
+    }
+
+    public void revokeInterface(string oid, Type type)
+    {
+        // FIXME debugging stuff
+        string key = type != null ? createKey(oid, type) : oid;
+        m_objects.Remove(key);
+    }
+
+    /**
+     * Retrieves an interface identified by its object id and type from this
+     * environment.
+     *
+     * @param oid object id of interface to be retrieved
+     * @param type the type description of the interface to be retrieved
+     * @see com.sun.star.uno.IEnvironment#getRegisteredInterface
+     */
+    public object getRegisteredInterface(string oid, Type type)
+    {
+        // try if it is a UNO interface
+        object ret = null;
+        ret = m_objects[oid];
+        if (ret == null)
+        {
+            // try if it is a proxy for a cli object
+            oid = createKey(oid, type);
+            ret = m_objects[oid];
+        }
+/*        if (ret != null)
+        {
+            WeakReference weakIface = (WeakReference)ret;
+            ret = weakIface.Target;
+        } */
+
+        if (ret == null)
+            m_objects.Remove(oid);
+
+        return ret;
+    }
+
+        /**
+         * Generates a worldwide unique object identifier (oid) for the given object. It is
+     * guaranteed, that subsequent calls to the method with the same object
+     * will give the same id.
+         * <p>
+         * @return     the generated oid.
+         * @param      object     the object for which a Oid should be generated.
+         */
+    public static string getObjectIdentifier(object obj)
+    {
+        string oid = null;
+        RealProxy realProxy = null;
+
+        if (RemotingServices.IsTransparentProxy(obj))
+            realProxy = RemotingServices.GetRealProxy(obj);
+
+        if (realProxy != null)
+        {
+            UnoInterfaceProxy proxyImpl = realProxy as UnoInterfaceProxy;
+            if (proxyImpl != null)
+                oid = proxyImpl.Oid;
+        }
+
+        if (oid == null)
+        {
+            Guid gd = typeof(Cli_environment).GUID; // FIXME apparently not a good idea with mono
+            StringBuilder buf = new StringBuilder(128);
+            buf.Append(obj.GetHashCode());
+            buf.Append(sOidPart);
+            buf.Append(gd);
+            oid = buf.ToString();
+        }
+
+        return oid;
+    }
+
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/makefile.mk cli_ure/source/mono_bridge/makefile.mk
--- cli_ure-orig/source/mono_bridge/makefile.mk	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/makefile.mk	2007-07-20 12:45:49.000000000 +0200
@@ -0,0 +1,137 @@
+#*************************************************************************
+#
+#   $RCSfile: $
+#
+#   $Revision: $
+#
+#   last change: $Author: $ $Date: $
+#
+#   The Contents of this file are made available subject to the terms of
+#   either of the following licenses
+#
+#          - GNU Lesser General Public License Version 2.1
+#          - Sun Industry Standards Source License Version 1.1
+#
+#   Sun Microsystems Inc., October, 2000
+#
+#   GNU Lesser General Public License Version 2.1
+#   =============================================
+#   Copyright 2000 by Sun Microsystems, Inc.
+#   901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License version 2.1, as published by the Free Software Foundation.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public
+#   License along with this library; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+#   MA  02111-1307  USA
+#
+#
+#   Sun Industry Standards Source License Version 1.1
+#   =================================================
+#   The contents of this file are subject to the Sun Industry Standards
+#   Source License Version 1.1 (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.openoffice.org/license.html.
+#
+#   Software provided under this License is provided on an "AS IS" basis,
+#   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+#   WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+#   See the License for the specific provisions governing your rights and
+#   obligations concerning the Software.
+#
+#   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+#   Copyright: 2000 by Sun Microsystems, Inc.
+#
+#   All Rights Reserved.
+#
+#   Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=bridges
+TARGET=cli_uno
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+.IF "$(ENABLE_MONO)" != "YES"
+dummy:
+     @echo "Mono binding disabled - skipping ..."
+.ELSE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE :  settings.mk
+CFLAGS+=$(MONO_CFLAGS)
+
+# --- Files --------------------------------------------------------
+
+ALLTAR : 				\
+	$(SHL1TARGETN)			\
+	$(BIN)$/cli_uno_bridge.dll
+
+CSFILES= 			\
+	binaryuno.cs 		\
+	bridge.cs 		\
+	cli_environment.cs 	\
+	managed_proxy.cs 	\
+	rtl_ustring.cs 		\
+	typeclass.cs		\
+	typedescription.cs	\
+	uik.cs			\
+	uno_proxy.cs
+
+ASSEMBLIES_DIR=$(SOLARVERSION)$/$(INPATH)$/bin$(EXT_UPDMINOR)
+$(BIN)$/cli_uno_bridge.dll : $(CSFILES)
+	+$(CSC) $(CSCFLAGS)					\
+		-target:library					\
+		-unsafe						\
+		-out:$@						\
+		-keyfile:$(BIN)$/cliuno.snk \
+		-reference:$(BIN)$/cli_basetypes.dll	\
+		-reference:$(BIN)$/cli_types.dll	\
+		$(CSFILES)
+
+SLOFILES=                       \
+	$(SLO)$/mono_bridge.obj	\
+	$(SLO)$/mono_proxy.obj	\
+	$(SLO)$/uno_glue.obj
+
+SHL1TARGET=$(TARGET)
+
+SHL1STDLIBS=	            \
+	$(CPPULIB)          \
+	$(SALLIB)           \
+	$(SALHELPERLIB)
+
+
+SHL1STDLIBS+=$(MONO_LIBS)
+
+# SHL1VERSIONMAP=..$/bridge_exports.map
+
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+
+
+# --- Targets ------------------------------------------------------
+
+.ENDIF
+
+.INCLUDE :  target.mk
+
diff -ruNp cli_ure-orig/source/mono_bridge/managed_proxy.cs cli_ure/source/mono_bridge/managed_proxy.cs
--- cli_ure-orig/source/mono_bridge/managed_proxy.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/managed_proxy.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,477 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace com.sun.star.bridges.mono_uno /* FIXME use some uno.foo namespace ? */
+{
+
+using System;
+using System.Reflection;
+using System.Runtime;
+
+using uno.Typelib;
+using uno.rtl;    
+
+public unsafe class ManagedProxy
+{
+    Bridge bridge;
+    object managedI;
+    TypeDescription *unoType;
+    UString* unoOid;
+    string oid;
+    Type type;
+    IntPtr nativeProxy;
+
+    enum MethodKind {METHOD = 0, SET, GET};
+
+    /** The array contains MethodInfos  of the cli object. Each one reflects an
+        implemented interface method of the interface for which this proxy was
+        created. The MethodInfos are from the object's method and not from the
+        interface type. That is, they can be used to invoke the methods. The
+        order of the MethodInfo objects corresponds to the order of the
+        interface methods (see member m_type). Position 0 contains the
+        MethodInfo of the first method of the interface which represents the
+        root of the inheritance chain. The last MethodInfo represents the last
+        method of the furthest derived interface.
+
+        The array is completely initialized in the constructor of this object.
+
+        When the uno_DispatchMethod is called for this proxy then it receives
+        a typelib_TypeDescription of the member which is either an attribute
+        (setter or getter) or method. After determining the position of the
+        method within the UNO interface one can use the position to obtain the
+        MethodInfo of the corresponding cli method. To obtain the index for the
+        m_arMethodInfos array the function position has to be decreased by 3.
+        This is becaus, the cli interface does not contain the XInterface
+        methods.
+    */
+    MethodInfo[] methodInfos;
+
+    /** This array is similar to m_arMethodInfos but it contains the MethodInfo
+        objects of the interface (not the object). When a call is made from uno
+        to cli then the uno method name is compared to the cli method name. The
+        cli method name can be obtained from the MethodInfo object in this
+        array. The name of the actual implemented method may not be the same as
+        the interface method.
+    */
+    MethodInfo[] interfaceMethodInfos;
+
+    /** Maps the position of the method in the UNO interface to the position of
+        the corresponding MethodInfo in m_arMethodInfos. The Uno position must
+        not include the XInterface methods. For example,
+        pos 0 = XInterface::queryInterface
+        pos 1 = XInterface::acquire
+        pos 2 = XInterface::release
+
+        That is the real Uno position has to be deducted by 3. Then
+        arUnoPosToCliPos[pos] contains the index for m_arMethodInfos.
+        
+     */
+    int[] unoPosToCliPos;
+
+    /** Count of inherited interfaces of the cli interface.
+     */
+    int inheritedInterfacesCount = 0;
+    /** Contains the number of methods of each interface. 
+     */
+    int[] interfaceMethodCounts;
+
+    public unsafe ManagedProxy(Bridge bridge, object managedI,
+                               TypeDescription* TD, UString* oid)
+    {
+        this.bridge = bridge;
+        this.managedI = managedI;
+        this.unoType = TD;
+        TypeDescription.Acquire(this.unoType);
+        this.unoOid = oid;
+        UString.Acquire(this.unoOid);
+        this.oid = UString.UStringToString(oid);
+
+        if (TD != null && TD->bComplete == 0)
+            TypeDescription.Complete(&TD);
+
+        this.type = Bridge.MapUnoType(this.unoType);
+        this.nativeProxy = IntPtr.Zero;
+        makeMethodInfos();
+    }
+
+    ~ManagedProxy()
+    {
+        UString.Release(this.unoOid);
+        TypeDescription.Release(this.unoType);
+    }
+
+    /** Prepares an array (m_arMethoInfos) containing MethodInfo object of the
+        interface and all inherited interfaces. At index null is the first
+        method of the base interface and at the last position is the last method
+        of the furthest derived interface.
+        If a UNO call is received then one can determine the position of the
+        method (or getter or setter for an attribute) from the passed type
+        information. The position minus 3 (there is no XInterface in the cli
+        mapping) corresponds to the index of the cli interface method in the
+        array.
+    */
+    void makeMethodInfos()
+    {
+        if (!type.IsInterface)
+            return;
+
+        MethodInfo[] thisMethods = type.GetMethods();
+        // get the inherited interfaces
+        Type[] inheritedIfaces = type.GetInterfaces();
+        inheritedInterfacesCount = inheritedIfaces.Length;
+
+        // array containing the number of methods for the interface
+        // and its inherited interfaces
+        interfaceMethodCounts = new int[inheritedInterfacesCount + 1];
+
+        // determine the number of all interface methods, including
+        // the inherited interfaces
+        int methodCount = thisMethods.Length;
+        foreach (Type iface in inheritedIfaces)
+            methodCount += iface.GetMethods().Length;
+
+        // array containing MethodInfos of the managed object
+        methodInfos = new MethodInfo[methodCount];
+
+        // array containing MethodInfos of the interface
+        interfaceMethodInfos = new MethodInfo[methodCount];
+
+        // array containing the mapping of UNO interface pos to pos in
+        // methodInfos
+        unoPosToCliPos = new int[methodCount];
+        
+        for (int i = 0; i < methodCount; ++i)
+            unoPosToCliPos[i] = -1;
+        
+        // fill methodInfos with the mappings
+        // !!! InterfaceMapping.TargetMethods should be MethodInfo*[] according
+        // to documentation
+        // but it is Type*[] instead. Bug in the framework?
+        // FIXME ^ what does mono do?
+        Type objType = managedI.GetType();
+        try
+        {
+            int index = 0;
+            // now get the methods from the inherited interface
+            // inheritedIfaces[0] is the direct base interface
+            // inheritedIfaces[n] is the furthest inherited interface
+            // Start with the base interface
+            for (int i = inheritedIfaces.Length - 1; i >= 0; --i)
+            {
+                InterfaceMapping mapInherited =
+                    objType.GetInterfaceMap(inheritedIfaces[i]);
+                
+                interfaceMethodCounts[i] = mapInherited.TargetMethods.Length;
+                for (int j = 0; j < interfaceMethodCounts[i]; ++j, ++index)
+                {
+                    methodInfos[index] = mapInherited.TargetMethods[j] as MethodInfo;
+                    interfaceMethodInfos[index] =
+                        mapInherited.InterfaceMethods[j] as MethodInfo;
+                }
+            }
+
+            // At last come the methods of the furthest derived interface
+            InterfaceMapping map = objType.GetInterfaceMap(type);
+            interfaceMethodCounts[inheritedInterfacesCount] =
+                map.TargetMethods.Length;
+            for (int j = 0;
+                 j < interfaceMethodCounts[inheritedInterfacesCount]; ++j, ++index)
+            {
+                methodInfos[index] = map.TargetMethods[j] as MethodInfo;
+                interfaceMethodInfos[index] =
+                    map.InterfaceMethods[j] as MethodInfo;
+            }
+        }
+        catch (InvalidCastException)
+        {
+            // FIXME do something (can this happen, is "as" not the
+            // proper translation for "__try_cast" ?
+        }
+    }
+
+    /**Obtains a MethodInfo which can be used to invoke the cli object.
+       Internally it maps nUnoFunctionPos to an index that is used to get the
+       corresponding MethodInfo object from m_arMethoInfos. The mapping table
+       is dynamically initialized. If the cli interface has no base interface
+       or exactly one then the mapping table is initialized in one go at the
+       first call. In all ensuing calls the MethodInfo object is immediately
+       retrieved through the mapping table.
+
+       If the interface has more then one interface in its inheritance chain,
+       that is Type.GetInterfaces return more then one Type, then the mapping
+       table is partially initiallized. On the first call the mappings for the
+       methods of the belonging interface are created.
+
+       The implementation assumes that the order of interface methods as
+       provided by InterfaceMapping.InterfaceMethods corresponds to the order
+       of methods in the interface declaration.
+      
+       @param nUnoFunctionPos
+       Position of the method in the uno interface.
+     */
+    unsafe MethodInfo getMethodInfo(int unoFunctionPos, UString* unoMethodName, MethodKind methodKind)
+    {
+        MethodInfo result = null;
+
+        // deduct 3 for XInterface methods
+        unoFunctionPos -= 3;
+        lock (unoPosToCliPos)
+        {
+            int cliPos = unoPosToCliPos[unoFunctionPos];
+            if (cliPos != -1)
+                return methodInfos[cliPos];
+
+            // create the method function name
+            string methodName = UString.UStringToString(unoMethodName);
+            switch (methodKind)
+            {
+            case MethodKind.METHOD:
+                break;
+            case MethodKind.SET:
+                methodName = "set_" + methodName;
+                break;
+            case MethodKind.GET:
+                methodName = "get_" + methodName;
+                break;
+            default:
+                // FIXME assert not reached
+                break;
+            }
+
+            // Find the cli interface method that corresponds to the Uno method
+            int indexCliMethod = -1;
+            // If the cli interfaces and their methods are in the same order
+            // as they were declared (inheritance chain and within the interface)
+            // then unoFunctionPos should lead to the correct method. However,
+            // the documentation does not say that this ordering is given.
+            if (methodName == interfaceMethodInfos[unoFunctionPos].Name)
+                indexCliMethod = unoFunctionPos;
+            else
+            {
+                int methodCount = interfaceMethodInfos.Length;
+                for (int i = 0; i < methodCount; ++i)
+                {
+                    if (interfaceMethodInfos[i].Name == methodName)
+                    {
+                        indexCliMethod = i;
+                        break;
+                    }
+                }
+            }
+            
+            if (indexCliMethod == -1 )
+            {
+                // FIXME throw some exception
+                return null;
+            }
+            unoPosToCliPos[unoFunctionPos] = indexCliMethod;
+            result = methodInfos[indexCliMethod];
+        }
+
+        return result;
+    }
+
+    void Acquire()
+    {
+        uno.Binary.Interface.Acquire(nativeProxy);
+    }
+
+    void Release()
+    {
+        uno.Binary.Interface.Release(nativeProxy);
+    }
+
+    unsafe void Dispatch(TypeDescription* memberTD, void* unoRet, void** unoArgs,
+                         uno.Binary.Any** unoExc)
+    {
+        switch (memberTD->eTypeClass)
+        {
+        case TypeClass.INTERFACE_ATTRIBUTE:
+        {
+            int memberPos = ((InterfaceMemberTypeDescription*)memberTD)->nPosition;
+            InterfaceTypeDescription* ifaceTD = (InterfaceTypeDescription*)unoType;
+            int functionPos = ifaceTD->pMapMemberIndexToFunctionIndex[memberPos];
+
+            if (unoRet != null) // is getter method
+            {
+                MethodInfo info = getMethodInfo(
+                    functionPos,
+                    ((InterfaceMemberTypeDescription*)memberTD)->pMemberName,
+                    MethodKind.GET);
+                bridge.CallManaged(
+                    managedI, type, info,
+                    ((InterfaceAttributeTypeDescription*)memberTD)->pAttributeTypeRef,
+                    null, 0, // no params
+                    unoRet, null, unoExc);
+            }
+            else // is setter method
+            {
+                MethodInfo info = getMethodInfo(
+                    // set follows get method
+                    functionPos + 1,
+                    ((InterfaceMemberTypeDescription*)memberTD)->pMemberName,
+                    MethodKind.SET);
+                MethodParameter param;
+                param.pTypeRef = ((InterfaceAttributeTypeDescription*)memberTD)->pAttributeTypeRef;
+                param.bIn = 1;
+                param.bOut = 0;
+
+                bridge.CallManaged(
+                    managedI, type, info,
+                    null /* indicated void return */, &param, 1,
+                    null, unoArgs, unoExc);                    
+            }
+            break;
+        }
+        case TypeClass.INTERFACE_METHOD:
+        {
+            int memberPos = ((InterfaceMemberTypeDescription*)memberTD)->nPosition;
+            InterfaceTypeDescription* ifaceTD = (InterfaceTypeDescription*)unoType;
+            int functionPos = ifaceTD->pMapMemberIndexToFunctionIndex[memberPos];
+
+            switch (functionPos)
+            {
+            case 0: // queryInterface()
+            {
+                TypeDescription* requestedTD = null;
+                // FIXME leak
+		 TypeDescriptionReference * argTD = *(TypeDescriptionReference **) unoArgs[0];
+		 if (argTD != null)
+	                TypeDescriptionReference.GetDescription(&requestedTD, argTD);
+                if (requestedTD == null || requestedTD->eTypeClass != TypeClass.INTERFACE)
+		 {
+                   uno.Binary.Any.Construct((uno.Binary.Any*)unoRet, null, null, null);
+		    *unoExc = null;
+		    break;
+                }
+
+                IntPtr unoInterface = IntPtr.Zero;
+
+                bridge.GetInterfaceFromUnoEnvironment(ref unoInterface, unoOid,
+                                                      (InterfaceTypeDescription*)requestedTD);
+
+                if (unoInterface == IntPtr.Zero)
+                {
+                    Type requestedType = Bridge.MapUnoType(requestedTD);
+                    if (requestedType.IsInstanceOfType(managedI))
+                    {
+                        IntPtr unoI = bridge.MapManagedToUno(managedI, requestedTD);
+                        uno.Binary.Any.Construct(
+                            (uno.Binary.Any*)unoRet, &unoI, requestedTD, null);
+                        uno.Binary.Interface.Release(unoI);
+                    }
+                    else // object does not support requested interface
+                    {
+                        uno.Binary.Any.Construct((uno.Binary.Any*)unoRet, null, null, null);
+                    }
+                    // no exception occurred
+                    *unoExc = null;
+                }
+                else
+                {
+                    uno.Binary.Any.Construct((uno.Binary.Any*)unoRet, &unoInterface,
+                                             requestedTD, null);
+                    *unoExc = null;
+                }
+                break;
+            }
+            case 1: // acquire this proxy()
+                Acquire();
+                *unoExc = null;
+                break;
+            case 2: // release this proxy()
+                Release();
+                *unoExc = null;
+                break;
+            default: // arbitrary method call
+            {
+                InterfaceMethodTypeDescription* methodTD = 
+                    (InterfaceMethodTypeDescription*)memberTD;
+                UString* methodName = ((InterfaceMemberTypeDescription*)memberTD)->pMemberName;
+
+                MethodInfo info = getMethodInfo(functionPos, methodName, MethodKind.METHOD);
+
+                bridge.CallManaged(
+                    managedI, type, info,
+                    methodTD->pReturnTypeRef, methodTD->pParams,
+                    methodTD->nParams,
+                    unoRet, unoArgs, unoExc);
+                break;
+            }
+            }
+      
+            break;
+        }
+        default: // Cannot happen
+        {
+            break;// FIXME Throw an error
+        }
+        }
+    }
+
+    public IntPtr NativeProxy
+    {
+        get { return nativeProxy; }
+        set { nativeProxy = value; }
+    }
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/mono_bridge.cxx cli_ure/source/mono_bridge/mono_bridge.cxx
--- cli_ure-orig/source/mono_bridge/mono_bridge.cxx	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/mono_bridge.cxx	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,412 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+
+#include "osl/diagnose.h"
+#include "rtl/unload.h"
+#include "rtl/ustring.hxx"
+
+#include "uno/mapping.hxx"
+
+extern "C" {
+#include "mono/metadata/appdomain.h"
+#include "mono/metadata/assembly.h"
+#include "mono/metadata/debug-helpers.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/threads.h"
+}
+
+#include "mono_bridge.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::rtl;
+using namespace ::mono_uno;
+
+extern "C" {
+
+void SAL_CALL Mapping_acquire( uno_Mapping * mapping )
+    SAL_THROW_EXTERN_C()
+{
+    static_cast< Mapping const * >( mapping )->m_bridge->acquire();
+}
+
+void SAL_CALL Mapping_release( uno_Mapping * mapping )
+    SAL_THROW_EXTERN_C()
+{
+    static_cast< Mapping const * >( mapping )->m_bridge->release();
+}
+
+void SAL_CALL Mapping_map_to_uno(
+    uno_Mapping * mapping, void ** ppOut,
+    void * pIn, typelib_InterfaceTypeDescription * td )
+    SAL_THROW_EXTERN_C()
+{
+    uno_Interface ** ppUnoI = (uno_Interface **)ppOut;
+    void * monoI = pIn;
+
+// FIXME do this here? OSL_ASSERT( sizeof (void *) >= sizeof (guint32))
+    OSL_ENSURE( ppUnoI && td, "### null ptr!" );
+
+    if (0 != *ppUnoI)
+    {
+        uno_Interface * pUnoI = *ppUnoI;
+        (*pUnoI->release)( pUnoI );
+        *ppUnoI = 0;
+    }
+
+    try
+    {
+        Bridge const *bridge =
+            static_cast< Mapping const * >( mapping )->m_bridge;
+        // FIXME any wrapper necessary around mono calls? cf. JNI_guarded_context
+        uno_Interface * pUnoI = bridge->map_to_uno(
+            monoI, (typelib_TypeDescription *)td );
+        *ppUnoI = pUnoI;
+    }
+    catch (BridgeRuntimeError & err)
+    {
+#if OSL_DEBUG_LEVEL > 0
+        OString cstr_msg(
+            OUStringToOString(
+                OUSTR("[mono_uno bridge error] ") + err.m_message,
+                RTL_TEXTENCODING_ASCII_US ) );
+        OSL_ENSURE( 0, cstr_msg.getStr() );
+#endif    
+    }
+}
+
+void SAL_CALL Mapping_map_to_mono(
+    uno_Mapping * mapping, void ** ppOut,
+    void * pIn, typelib_InterfaceTypeDescription * td )
+    SAL_THROW_EXTERN_C()
+{
+    void ** pMonoI = ppOut;
+    uno_Interface * pUnoI = (uno_Interface *)pIn;
+
+    OSL_ENSURE( ppOut && td, "### null ptr!" );
+
+    if (0 != *pMonoI)
+    {
+        // FIXME JNI bridge has guarded_context here
+        // FIXME: do the right thing in the managed bridge
+        // mono_gchandle_free( *pMonoI );
+    }
+
+    try
+    {
+        if (0 != pUnoI)
+        {
+            Bridge const * bridge =
+                static_cast< Mapping const *>( mapping )->m_bridge;
+            // FIXME guarded context
+             *ppOut = (void *)bridge->map_to_mono(
+                 pUnoI, (typelib_TypeDescription *)td );
+             OSL_ASSERT( ppOut && *ppOut );
+        }
+    }
+    catch (BridgeRuntimeError & err)
+    {
+#if OSL_DEBUG_LEVEL >= 1
+        rtl::OString cstr_msg(
+            rtl::OUStringToOString(
+                OUSTR("[mono_uno bridge error] ") + err.m_message,
+                RTL_TEXTENCODING_ASCII_US ) );
+        OSL_ENSURE( 0, cstr_msg.getStr() );
+#endif
+    }
+}
+
+void SAL_CALL Bridge_free( uno_Mapping * mapping )
+    SAL_THROW_EXTERN_C()
+{
+    Mapping * that = static_cast< Mapping * >( mapping );
+    delete that->m_bridge;
+}
+
+} // extern "C"
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+namespace mono_uno
+{
+
+void Bridge::acquire() const SAL_THROW( () )
+{
+    if (1 == osl_incrementInterlockedCount( &m_ref ))
+    {
+        if (m_registered_mono2uno)
+        {
+            uno_Mapping * mapping = const_cast< Mapping * >( &m_mono2uno );
+            uno_registerMapping(
+                &mapping, Bridge_free,
+                m_mono_env, (uno_Environment *)m_uno_env, 0 );
+        }
+        else
+        {
+            uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2mono );
+            uno_registerMapping(
+                &mapping, Bridge_free,
+                (uno_Environment *)m_uno_env, m_mono_env, 0 );
+        }
+    }
+}
+
+void Bridge::release() const SAL_THROW( () )
+{
+    if (! osl_decrementInterlockedCount( &m_ref ))
+    {
+        uno_revokeMapping(
+            m_registered_mono2uno
+            ? const_cast< Mapping * >( &m_mono2uno )
+            : const_cast< Mapping * >( &m_uno2mono ) );
+    }
+}
+
+Bridge::Bridge(
+    uno_Environment * mono_env, uno_ExtEnvironment * uno_env,
+    bool registered_mono2uno )
+    : m_ref( 1 ),
+      m_uno_env( uno_env ),
+      m_mono_env( mono_env ),
+      m_registered_mono2uno( registered_mono2uno )
+{
+    MonoDomain * pDomain = mono_get_root_domain();
+    // FIXME where is this freed?
+    MonoAssembly * pAssembly = mono_domain_assembly_open( pDomain, "cli_uno_bridge.dll" );
+    // FIXME and this, is this needed later?
+    MonoClass * pClass = mono_class_from_name (
+        (MonoImage *)mono_assembly_get_image( pAssembly ), "com.sun.star.bridges.mono_uno", "Bridge" );
+    OSL_ASSERT( 0 != pClass );
+    /* FIXME add args to method description string */
+    MonoMethodDesc * pMethodDesc = mono_method_desc_new( ":.ctor", FALSE );
+    MonoMethod * pCtor = mono_method_desc_search_in_class( pMethodDesc, pClass );
+    mono_method_desc_free( pMethodDesc );
+    OSL_ASSERT( 0 != pCtor );
+
+    pMethodDesc = mono_method_desc_new( "Bridge:MapManagedToUno", FALSE );
+    m_mapManagedToUnoMethod = mono_method_desc_search_in_class( pMethodDesc, pClass );
+    mono_method_desc_free( pMethodDesc );
+    OSL_ASSERT( 0 != m_mapManagedToUnoMethod );
+
+    pMethodDesc = mono_method_desc_new( "Bridge:MapUnoToManaged", FALSE );
+    m_mapUnoToManagedMethod = mono_method_desc_search_in_class( pMethodDesc, pClass );
+    mono_method_desc_free( pMethodDesc );
+    OSL_ASSERT( 0 != m_mapUnoToManagedMethod );
+
+    gpointer pParams[1];
+    pParams[0] = &uno_env;
+    m_managedBridge = mono_object_new( pDomain, pClass );
+    mono_uno::runtime_invoke( pCtor, m_managedBridge, pParams, NULL,
+							  mono_object_get_domain( m_managedBridge ) );
+
+    OSL_ASSERT( 0 != m_mono_env && 0 != m_uno_env );
+    (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
+    (*m_mono_env->acquire)( m_mono_env );
+
+    // mono2uno mapping
+    m_mono2uno.acquire = Mapping_acquire;
+    m_mono2uno.release = Mapping_release;
+    m_mono2uno.mapInterface = Mapping_map_to_uno;
+    m_mono2uno.m_bridge = this;
+    // uno2mono mapping
+    m_uno2mono.acquire = Mapping_acquire;
+    m_uno2mono.release = Mapping_release;
+    m_uno2mono.mapInterface = Mapping_map_to_mono;
+    m_uno2mono.m_bridge = this;
+
+    (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt );
+}
+
+Bridge::~Bridge() SAL_THROW( () )
+{
+    (*m_mono_env->release)( m_mono_env );
+    (*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
+    // FIXME release managed bridge
+
+    (*g_moduleCount.modCnt.release)( &g_moduleCount.modCnt );
+}
+
+void * Bridge::map_to_mono(
+    uno_Interface *pUnoI, typelib_TypeDescription * pTD ) const
+{
+    gpointer pMonoParams[2];
+
+    pMonoParams[0] = &pUnoI;
+    pMonoParams[1] = pTD;
+    
+    return
+        mono_uno::runtime_invoke( m_mapUnoToManagedMethod,
+								  m_managedBridge, pMonoParams, NULL,
+								  mono_object_get_domain( m_managedBridge ) );
+}
+
+uno_Interface * Bridge::map_to_uno(
+    void * pMonoI, typelib_TypeDescription * pTD ) const
+{
+    gpointer pMonoParams[2];
+    uno_Interface ** ppResult;
+
+    pMonoParams[0] = pMonoI;
+    pMonoParams[1] = pTD;
+
+    ppResult = (uno_Interface **)mono_object_unbox(
+        mono_uno::runtime_invoke( m_mapManagedToUnoMethod,
+								  m_managedBridge, pMonoParams, NULL,
+								  mono_object_get_domain( m_managedBridge ) ) );
+
+    return *ppResult;
+}
+
+} // namespace mono_uno
+
+extern "C" {
+
+// void SAL_CALL mono_environmentDisposing( uno_Environment * mono_env )
+// 	SAL_THROW_EXTERN_C()
+// {
+// }
+
+void SAL_CALL uno_initEnvironment( uno_Environment * mono_env )
+	SAL_THROW_EXTERN_C()
+{
+	// mono_env->environmentDisposing = mono_environmentDisposing;
+	mono_env->pExtEnv = 0; /* no extended support */
+}
+
+void SAL_CALL uno_ext_getMapping(
+	uno_Mapping ** ppMapping, uno_Environment *pFrom, uno_Environment *pTo )
+	SAL_THROW_EXTERN_C()
+{
+	OSL_ASSERT( 0 != ppMapping && 0 != pFrom && 0 != pTo );
+    if (0 != *ppMapping)
+    {
+        (*(*ppMapping)->release)( *ppMapping );
+        *ppMapping = 0;
+    }
+
+    /* FIXME check that mono's and sal's types have matching sizes
+     * like jni_bridge does? */
+
+    OUString const & from_env_typename = OUString::unacquired( &pFrom->pTypeName );
+    OUString const & to_env_typename = OUString::unacquired( &pTo->pTypeName );
+
+    uno_Mapping * mapping = 0;
+
+    try
+    {
+        if (from_env_typename.equalsAsciiL(
+                RTL_CONSTASCII_STRINGPARAM( UNO_LB_CLI )) &&
+            to_env_typename.equalsAsciiL(
+                RTL_CONSTASCII_STRINGPARAM( UNO_LB_UNO)))
+        {
+            Bridge * bridge =
+                new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
+            mapping = &bridge->m_mono2uno;
+            uno_registerMapping(
+                &mapping, Bridge_free, pFrom,
+                (uno_Environment *)pTo->pExtEnv, 0);
+        }
+        else if (from_env_typename.equalsAsciiL(
+                     RTL_CONSTASCII_STRINGPARAM( UNO_LB_UNO)) &&
+                 to_env_typename.equalsAsciiL(
+                     RTL_CONSTASCII_STRINGPARAM( UNO_LB_CLI)))
+        {
+            Bridge * bridge =
+                new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
+            mapping = &bridge->m_uno2mono;
+            uno_registerMapping(
+                &mapping, Bridge_free,
+                (uno_Environment *)pFrom->pExtEnv, pTo, 0);
+        }
+    }
+    catch (BridgeRuntimeError & err)
+    {
+#if OSL_DEBUG_LEVEL >= 1
+        OString cstr_msg(
+                OUStringToOString(
+                    OUSTR("[mono_uno bridge error] ") + err.m_message,
+                    RTL_TEXTENCODING_ASCII_US ) );
+            OSL_ENSURE( 0, cstr_msg.getStr() );
+#endif
+    }
+
+    *ppMapping = mapping;
+}
+
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+    SAL_THROW_EXTERN_C()
+{
+    return (*g_moduleCount.canUnload)( &g_moduleCount, pTime );
+}
+
+} // extern "C"
+
+MonoObject*
+mono_uno::runtime_invoke (MonoMethod *method, void *obj, void **params,
+						  MonoObject **exc, MonoDomain *domain)
+{
+	mono_thread_attach( domain );
+	return mono_runtime_invoke( method, obj, params, exc );
+}
diff -ruNp cli_ure-orig/source/mono_bridge/mono_bridge.h cli_ure/source/mono_bridge/mono_bridge.h
--- cli_ure-orig/source/mono_bridge/mono_bridge.h	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/mono_bridge.h	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_MONO_BRIDGE_H
+#define INCLUDED_MONO_BRIDGE_H
+
+#include "glib/gtypes.h"
+#include "osl/interlck.h"
+#include "rtl/ustring.hxx"
+#include "typelib/typedescription.hxx"
+#include "uno/dispatcher.h"
+#include "uno/mapping.h"
+
+extern "C" {
+#include "mono/metadata/appdomain.h"
+#include "mono/metadata/debug-helpers.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/threads.h"
+}
+
+namespace cssu = com::sun::star::uno;
+
+typedef struct _uno_ExtEnvironment uno_ExtEnvironment;
+typedef struct _uno_Environment uno_Environment;
+typedef struct _typelib_TypeDescription typelib_TypeDescription;
+
+namespace mono_uno
+{
+
+MonoObject* runtime_invoke (MonoMethod *method, void *obj, void **params,
+							MonoObject **exc, MonoDomain *domain);
+
+//==== holds environments and mappings =========================================
+struct Bridge;
+struct Mapping : public uno_Mapping
+{
+    Bridge * m_bridge;
+};
+
+//==============================================================================
+struct Bridge
+{
+    mutable oslInterlockedCount m_ref;
+    MonoObject *                m_managedBridge;
+    
+    uno_ExtEnvironment *        m_uno_env;
+    uno_Environment *           m_mono_env;
+    
+    Mapping                     m_mono2uno;
+    Mapping                     m_uno2mono;
+    bool                        m_registered_mono2uno;
+    
+    MonoMethod *                m_mapUnoToManagedMethod;
+    MonoMethod *                m_mapManagedToUnoMethod;
+
+    ~Bridge() SAL_THROW( () );
+    explicit Bridge(
+        uno_Environment * mono_env, uno_ExtEnvironment * uno_env,
+        bool registered_mono2uno );
+    
+    void acquire() const;
+    void release() const;
+
+    void * map_to_mono(
+        uno_Interface * pUnoI, typelib_TypeDescription * pTD ) const;
+
+    uno_Interface * map_to_uno(
+        void * pMonoI, typelib_TypeDescription * pTD ) const;
+};
+
+struct MonoProxy : public uno_Interface
+{
+    mutable oslInterlockedCount m_ref;
+    guint32                     m_managedProxy;
+    uno_ExtEnvironment *        m_unoEnv;
+    const cssu::TypeDescription m_unoType;
+    const rtl::OUString         m_Oid;
+    MonoMethod *                m_managedDispatch;
+
+    void acquire() const;
+    void release() const;
+    void dispatch(typelib_TypeDescription const * member_td, void * uno_ret,
+                  void * uno_args [], uno_Any ** uno_exc);
+
+    MonoProxy(uno_ExtEnvironment * pUnoEnv, guint32 managedProxy,
+              rtl_uString * pOid, typelib_TypeDescription * pTD);
+};
+
+struct BridgeRuntimeError
+{
+    ::rtl::OUString m_message;
+    
+    inline BridgeRuntimeError( ::rtl::OUString const & message )
+        : m_message( message )
+        {}
+};
+
+}
+
+#endif
diff -ruNp cli_ure-orig/source/mono_bridge/mono_proxy.cxx cli_ure/source/mono_bridge/mono_proxy.cxx
--- cli_ure-orig/source/mono_bridge/mono_proxy.cxx	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/mono_proxy.cxx	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,201 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "mono_bridge.h"
+
+#include "rtl/ustring.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "typelib/typedescription.h"
+
+extern "C" {
+#include "mono/metadata/threads.h"
+}
+
+using namespace mono_uno;
+
+extern "C" {
+
+static void SAL_CALL mono_proxy_free( uno_ExtEnvironment * env, void * proxy)
+{
+    MonoProxy * monoProxy = reinterpret_cast< MonoProxy * >( proxy );
+
+    delete monoProxy;
+}
+
+uno_Interface * SAL_CALL cli_uno_environment_createMonoProxyAndRegister(
+    uno_ExtEnvironment *pUnoEnv, void *pMonoProxy, rtl_uString *pOid,
+    typelib_TypeDescription *pTD )
+    SAL_THROW_EXTERN_C()
+{
+    uno_Interface * proxy = static_cast< uno_Interface * >(
+        new MonoProxy( pUnoEnv,
+                       static_cast< guint32 >( reinterpret_cast< sal_IntPtr >( pMonoProxy ) ),
+                       pOid, pTD ) );
+
+    pUnoEnv->registerProxyInterface(
+        pUnoEnv,
+        reinterpret_cast< void ** >( &proxy ),
+        mono_proxy_free,
+        pOid,
+        (typelib_InterfaceTypeDescription*) pTD );
+
+    return proxy;
+}
+
+static void SAL_CALL mono_proxy_acquire( uno_Interface * pUnoI )
+{
+    MonoProxy const * that = static_cast< MonoProxy const * >( pUnoI );
+    that->acquire();
+}
+
+static void SAL_CALL mono_proxy_release( uno_Interface * pUnoI )
+{
+    MonoProxy const * that = static_cast< MonoProxy const * >( pUnoI );
+    that->release();
+}
+
+static void SAL_CALL mono_proxy_dispatch(
+    uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+    void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+    SAL_THROW_EXTERN_C()
+{
+    MonoProxy * that = static_cast< MonoProxy * >( pUnoI );
+    that->dispatch( member_td, uno_ret, uno_args, uno_exc );
+}
+
+} // extern "C"
+
+namespace mono_uno
+{
+
+MonoProxy::MonoProxy(uno_ExtEnvironment * pUnoEnv, guint32 managedProxy,
+                     rtl_uString *pOid, typelib_TypeDescription * pTD):
+    m_ref(1),
+    m_unoEnv(pUnoEnv),
+    m_managedProxy(managedProxy), // FIXME free this in the destructor?
+    m_Oid(pOid),
+    m_unoType(pTD)
+{
+    uno_Interface::acquire = mono_proxy_acquire;
+    uno_Interface::release = mono_proxy_release;
+    uno_Interface::pDispatcher = mono_proxy_dispatch;
+
+    MonoObject * pObj = mono_gchandle_get_target( m_managedProxy );
+    MonoClass * pClass = mono_object_get_class( pObj );
+    MonoMethodDesc * pMethodDesc = mono_method_desc_new( "ManagedProxy:Dispatch", FALSE );
+    m_managedDispatch = mono_method_desc_search_in_class( pMethodDesc, pClass );
+    mono_method_desc_free( pMethodDesc );
+    OSL_ASSERT( 0 != m_managedDispatch );
+}
+
+inline void MonoProxy::acquire() const
+{
+    if (1 == osl_incrementInterlockedCount( &m_ref ))
+    {
+        // rebirth of proxy zombie
+        void * that = const_cast< MonoProxy * >( this );
+        // register at uno env
+        (*m_unoEnv->registerProxyInterface)(
+            m_unoEnv, &that,
+            mono_proxy_free, m_Oid.pData,
+            (typelib_InterfaceTypeDescription *)m_unoType.get() );
+#if OSL_DEBUG_LEVEL >= 2
+        OSL_ASSERT( this == (void const * const)that );
+#endif
+    }
+}
+
+inline void MonoProxy::release() const
+{
+    if (0 == osl_decrementInterlockedCount( &m_ref ))
+    {
+        // revoke from uno env on last release,
+        // The proxy can be resurrected if acquire is called before the uno
+        // environment calls mono_proxy_free. mono_proxy_free will
+        //delete the proxy. The environment does not acquire a registered
+        //proxy.
+        (*m_unoEnv->revokeInterface)(
+            m_unoEnv, const_cast< MonoProxy * >( this ) );
+    }
+}
+
+inline void MonoProxy::dispatch( typelib_TypeDescription const * member_td,
+                                 void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+{
+    OSL_ASSERT( m_managedDispatch != 0 );
+    
+    gpointer pMonoParams[4];
+
+    pMonoParams[0] = const_cast< typelib_TypeDescription * >(member_td);
+    pMonoParams[1] = uno_ret;
+    pMonoParams[2] = uno_args;
+    pMonoParams[3] = uno_exc;
+
+	MonoObject *obj = mono_gchandle_get_target( m_managedProxy );
+
+    mono_uno::runtime_invoke( m_managedDispatch,
+							  obj, pMonoParams, NULL,
+							  mono_object_get_domain( obj ) );
+}
+
+}
+
diff -ruNp cli_ure-orig/source/mono_bridge/rtl_ustring.cs cli_ure/source/mono_bridge/rtl_ustring.cs
--- cli_ure-orig/source/mono_bridge/rtl_ustring.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/rtl_ustring.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace uno.rtl {
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+public unsafe struct UString
+{
+    public int RefCount;
+    public int Length;
+    public char FirstChar;
+
+    [DllImport("sal")]
+    private static extern void rtl_uString_acquire(void* data);
+
+    [DllImport("sal")]
+    private static unsafe extern void rtl_uString_release(void* data);
+
+    [DllImport("sal")]
+    private static unsafe extern void rtl_uString_new(void* data);
+
+    [DllImport("sal")]
+    private static unsafe extern void rtl_uString_newFromStr_WithLength(
+        void* data,
+        // this should pass a pointer to the original string's char[]
+        [MarshalAs(UnmanagedType.LPWStr)] string value,
+        int len);
+
+    [DllImport("sal")]
+    private static unsafe extern void rtl_uString_newFromStr_WithLength(
+        void* data,
+        // this should pass a pointer to the stringbuilder's internal char[]
+        [MarshalAs(UnmanagedType.LPWStr)] StringBuilder buffer,
+        int len);
+
+    public static unsafe void Acquire(UString* us)
+    {
+        rtl_uString_acquire(us);
+    }
+
+    public static unsafe void Release(UString* us)
+    {
+        rtl_uString_release(us);
+    }
+
+    public static unsafe void New(UString** p)
+    {
+        rtl_uString_new(p);
+    }
+
+    public static unsafe void NewFromString(UString **p, string s)
+    {
+        rtl_uString_newFromStr_WithLength(p, s, s.Length);
+    }
+
+    public static unsafe void NewFromStringBuilder(UString **p, StringBuilder sb)
+    {
+        rtl_uString_newFromStr_WithLength(p, sb, sb.Length);
+    }
+
+    public static unsafe string UStringToString(UString *p)
+    {
+        return new String(&(p->FirstChar), 0, p->Length);
+    }
+}
+
+// FIXME move this to its own file or rename this file to e.g. sal
+public unsafe struct Mem
+{
+    // FIXME parameter is a sal_Size which is unsigned and has the
+    // size of a native long.  Thus this is not 64bit safe.  Might have
+    // to write a glue function that always takes 32bit.
+    [DllImport("sal", EntryPoint="rtl_allocateMemory")]    
+	public static unsafe extern void *Allocate(int bytes);
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/typeclass.cs cli_ure/source/mono_bridge/typeclass.cs
--- cli_ure-orig/source/mono_bridge/typeclass.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/typeclass.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace uno.Typelib {
+
+public class TypeClass
+{
+	/** type class of void */
+	public const int VOID = 0;
+	/** type class of char */
+	public const int CHAR = 1;
+	/** type class of boolean */
+	public const int BOOLEAN = 2;
+	/** type class of byte */
+	public const int BYTE = 3;
+	/** type class of short */
+	public const int SHORT = 4;
+	/** type class of unsigned short */
+	public const int UNSIGNED_SHORT = 5;
+	/** type class of long */
+	public const int LONG = 6;
+	/** type class of unsigned long */
+	public const int UNSIGNED_LONG = 7;
+	/** type class of hyper */
+	public const int HYPER = 8;
+	/** type class of unsigned hyper */
+	public const int UNSIGNED_HYPER = 9;
+	/** type class of float */
+	public const int FLOAT = 10;
+	/** type class of double */
+	public const int DOUBLE = 11;
+	/** type class of string */
+	public const int STRING = 12;
+	/** type class of type */
+	public const int TYPE = 13;
+	/** type class of any */
+	public const int ANY = 14;
+	/** type class of enum */
+	public const int ENUM = 15;
+	/** type class of typedef */
+	public const int TYPEDEF = 16;
+	/** type class of struct */
+	public const int STRUCT = 17;
+	/** type class of union (not implemented) */
+	public const int UNION = 18;
+	/** type class of exception */
+	public const int EXCEPTION = 19;
+	/** type class of sequence */
+	public const int SEQUENCE = 20;
+	/** type class of array (not implemented) */
+	public const int ARRAY = 21;
+	/** type class of interface */
+	public const int INTERFACE = 22;
+	/** type class of service (not implemented) */
+	public const int SERVICE = 23;
+	/** type class of module (not implemented) */
+	public const int MODULE = 24;
+	/** type class of interface method */
+	public const int INTERFACE_METHOD = 25;
+	/** type class of interface attribute */
+	public const int INTERFACE_ATTRIBUTE = 26;
+	/** type class of unknown type */
+	public const int UNKNOWN = 27;
+    /** type class of properties */
+    public const int PROPERTY = 28;
+    /** type class of constants */
+    public const int CONSTANT = 29;
+    /** type class of constants groups */
+    public const int CONSTANTS = 30;
+    /** type class of singletons */
+    public const int SINGLETON = 31;
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/typedescription.cs cli_ure/source/mono_bridge/typedescription.cs
--- cli_ure-orig/source/mono_bridge/typedescription.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/typedescription.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,645 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace uno.Typelib {
+
+using System;
+using System.Runtime.InteropServices;
+
+/** Holds a weak reference to a type description.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct TypeDescriptionReference
+{
+    /** reference count of type; don't ever modify this by yourself, use
+        typedescriptionreference_acquire() and typedescriptionreference_release()
+    */
+    public int                             nRefCount;
+    /** number of static references of type, because of the fact that some types are needed
+        until program termination and are commonly held static.
+    */
+    public int                             nStaticRefCount;
+    /** type class of type
+    */
+    public int                             eTypeClass;
+    /** fully qualified name of type.
+    */ 
+    public uno.rtl.UString *               pTypeName;
+    /** pointer to full typedescription; this value is only valid if the type is never swapped out
+    */
+    public TypeDescription *               pType;
+    /** pointer to optimize the runtime; not for public use
+    */
+    public void *                          pUniqueIdentifier;
+    /** reserved for future use; 0 if not used
+    */
+    public void *                          pReserved;
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_acquire") ]
+	public static extern void Acquire(/* TypeDescriptionReference */ void *td);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_release") ]
+    public static extern void Release(/* TypeDescriptionReference */ void *td);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_new") ]
+    public static extern void New(TypeDescriptionReference **ppTDR,
+                                  int /* enum typelib_TypeClass */ eTypeClass,
+                                  /* uno.rtl.UString */ void *pTypeName);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_static_type_getByTypeClass") ]
+    public static extern TypeDescriptionReference **GetByTypeClass(
+        int /* enum typelib_TypeClass */ eTypeClass);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_getDescription") ]
+    public static extern void GetDescription(
+        TypeDescription ** ppRet, /* TypeDescriptionReference */ void * pRef);
+}
+
+/** Full type description of a type. Memory layout of this struct is identical to the
+    TypeDescriptionReference for the first six members.
+    So a typedescription can be used as type reference. 
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct TypeDescription
+{
+    /** reference count; don't ever modify this by yourself, use
+        typedescription_acquire() and typedescription_release()
+    */
+    public int                             nRefCount;
+    /** number of static references of type, because of the fact that some types are needed
+        until program termination and are commonly held static.
+    */
+    public int                             nStaticRefCount;
+    /** type class of type
+    */
+    public int                             eTypeClass; 
+    /** fully qualified name of type.
+    */ 
+    public uno.rtl.UString *               pTypeName;
+    /** pointer to self to distinguish reference from description; for internal use only
+    */
+    public TypeDescription *               pSelf;
+    /** pointer to optimize the runtime; not for public use
+    */
+    public void *                          pUniqueIdentifier;
+    /** reserved for future use; 0 if not used
+    */
+    public void *                          pReserved;
+    
+    /** flag to determine whether the description is complete:
+        compound and union types lack of member names, enums lack of member types and names,
+        interfaces lack of members and table init.
+        Call typedescription_complete() if false.
+    */
+    public byte                            bComplete;
+    /** size of type
+    */
+    public int                             nSize;
+    /** alignment of type
+    */
+    public int                             nAlignment;
+    /** pointer to weak reference
+    */
+    public TypeDescriptionReference *      pWeakRef;
+    /** determines, if type can be unloaded (and it is possible to reloaded it)
+    */
+    public byte                            bOnDemand;
+
+    /* FIXME move to TypeDescriptionReference */
+    public static TypeDescriptionReference *VoidType
+    {
+        get { return null; /* FIXME, use typelib_static_type_getByTypeClass(VOID) */ }
+    }
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_getByName") ]
+    public static extern void GetByName(TypeDescription **pTD,
+                                        /* uno.rtl.UString */ void *name);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_acquire") ]
+    public static extern void Acquire(/* TypeDescription */ void *td);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_release") ]
+    public static extern void Release(/* TypeDescription */ void *td);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_complete") ]
+    public static extern bool Complete(TypeDescription **pTD);
+}
+
+/** Type description for exception types.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct CompoundTypeDescription
+{
+    /** inherits all members of TypeDescription
+    */
+    public TypeDescription                 aBase;
+    
+    /** pointer to base type description, else 0
+    */
+    public CompoundTypeDescription *       pBaseTypeDescription;
+    
+    /** number of members
+    */
+    public int                             nMembers;
+    /** byte offsets of each member including the size the base type
+    */
+    public int *                           pMemberOffsets;
+    /** members of the struct or exception
+    */
+    public TypeDescriptionReference **     ppTypeRefs;
+    /** member names of the struct or exception.
+    */
+    public uno.rtl.UString **              ppMemberNames;
+}
+
+/**
+   Type description for struct types.
+
+   This is only used to represent plain struct types and instantiated
+   polymorphic struct types; there is no representation of polymorphic struct
+   type templates at this level.
+
+   @since UDK 3.2.0
+ */
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct StructTypeDescription
+{
+    /**
+       Derived from CompoundTypeDescription.
+     */
+    public CompoundTypeDescription         aBase;
+
+    /**
+       Flags for direct members, specifying whether they are of parameterized
+       type (true) or explict type (false).
+
+       For a plain struct type, this is a null pointer.
+     */
+    public byte *                          pParameterizedTypes;
+}
+
+/** Type description of a union. The type class of this description is TypeClass_UNION.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct UnionTypeDescription
+{
+    /** inherits all members of TypeDescription
+    */
+    public TypeDescription                 aBase;
+    
+    /** type of the discriminant
+    */
+    public TypeDescriptionReference *      pDiscriminantTypeRef;
+    
+    /** union default descriminant
+    */
+    public long                            nDefaultDiscriminant;
+    /** union default member type (may be 0)
+     */
+    public TypeDescriptionReference *      pDefaultTypeRef;
+    /** number of union member types
+    */
+    public int                             nMembers;
+    /** union member discriminant values (same order as idl declaration)
+    */
+    public long *                          pDiscriminants;
+    /** union member value types (same order as idl declaration)
+    */
+    public TypeDescriptionReference **     ppTypeRefs;
+    /** union member value names (same order as idl declaration)
+    */
+    public uno.rtl.UString **              ppMemberNames;
+    /** union value offset for data access
+    */
+    public int                             nValueOffset;
+}
+
+/** Type description of an array or sequence.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct IndirectTypeDescription
+{
+    /** inherits all members of TypeDescription
+    */
+    public TypeDescription                 aBase;
+    
+    /** array, sequence: pointer to element type
+    */
+    public TypeDescriptionReference *      pType;
+}
+
+/** Type description of an array.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct ArrayTypeDescription
+{
+    /** inherits all members of IndirectTypeDescription
+    */
+    public IndirectTypeDescription         aBase;
+    
+    /** number of dimensions
+    */
+    public int                             nDimensions;
+    /** number of total array elements
+    */
+    public int                             nTotalElements;
+    /** array of dimensions
+    */
+    public int *                           pDimensions;
+}
+
+/** Type description of an enum. The type class of this description is TypeClass_ENUM.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct EnumTypeDescription
+{
+    /** inherits all members of TypeDescription
+    */
+    public TypeDescription                 aBase;
+    
+    /** first value of the enum
+    */
+    public int                             nDefaultEnumValue;
+    /** number of enum values
+    */
+    public int                             nEnumValues;
+    /** names of enum values
+    */
+    public uno.rtl.UString **              ppEnumNames;
+    /** values of enum (corresponding to names in similar order)
+    */
+    public int *                           pEnumValues;
+}
+
+/** Description of an interface method parameter.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct MethodParameter
+{
+    /** name of parameter
+    */
+    public uno.rtl.UString *               pName;
+    /** type of parameter
+    */
+    public TypeDescriptionReference *      pTypeRef;
+    /** true: the call type of this parameter is [in] or [inout]
+        false: the call type of this parameter is [out]
+    */
+    public byte                            bIn;
+    /** true: the call type of this parameter is [out] or [inout]
+        false: the call type of this parameter is [in]
+    */
+    public byte                            bOut;
+}
+
+/** Common base type description of InterfaceMethodTypeDescription and
+    InterfaceAttributeTypeDescription.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceMemberTypeDescription
+{
+    /** inherits all members of TypeDescription
+    */
+    public TypeDescription                 aBase;
+    
+    /** position of member in the interface including the number of members of
+        any base interfaces
+    */
+    public int                             nPosition;
+    /** name of member
+    */
+    public uno.rtl.UString *               pMemberName;
+}
+
+/** Type description of an interface method. The type class of this description is
+    TypeClass_INTERFACE_METHOD. The size and the alignment are 0.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceMethodTypeDescription
+{
+    /** inherits all members of InterfaceMemberTypeDescription
+    */
+    public InterfaceMemberTypeDescription  aBase;
+    
+    /** type of the return value
+    */
+    public TypeDescriptionReference *      pReturnTypeRef;
+    /** number of parameters
+    */
+    public int                             nParams;
+    /** array of parameters
+    */
+    public MethodParameter *               pParams;
+    /** number of exceptions
+    */
+    public int                             nExceptions;
+    /** array of exception types
+    */
+    public TypeDescriptionReference **     ppExceptions;
+    /** determines whether method is declared oneway
+    */
+    public byte                            bOneWay;
+
+    /** the interface description this method is a member of
+
+        @since #i21150#
+    */
+    public InterfaceTypeDescription *      pInterface;
+    /** the inherited direct base method (null for a method that is not
+        inherited)
+
+        @since UDK 3.2.0
+    */
+    public TypeDescriptionReference *      pBaseRef;
+    /** if pBaseRef is null, the member position of this method within
+        pInterface, not counting members inherited from bases; if pBaseRef is
+        not null, the index of the direct base within pInterface from which this
+        method is inherited
+
+        @since UDK 3.2.0
+    */
+    public int                             nIndex;
+}
+
+/** The description of an interface attribute. The type class of this description is
+    TypeClass_INTERFACE_ATTRIBUTE. The size and the alignment are 0.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceAttributeTypeDescription
+{
+    /** inherits all members of InterfaceMemberTypeDescription
+    */
+    public InterfaceMemberTypeDescription  aBase;
+    
+    /** determines whether attribute is read only
+    */
+    public byte                            bReadOnly;     
+    /** type of the attribute
+    */
+    public TypeDescriptionReference *      pAttributeTypeRef;
+
+    /** the interface description this attribute is a member of
+
+        @since #i21150#
+    */
+    public InterfaceTypeDescription *      pInterface;
+    /** the inherited direct base attribute (null for an attribute that is not
+        inherited)
+
+        @since UDK 3.2.0
+    */
+    public TypeDescriptionReference *      pBaseRef;
+    /** if pBaseRef is null, the member position of this attribute within
+        pInterface, not counting members inherited from bases; if pBaseRef is
+        not null, the index of the direct base within pInterface from which this
+        attribute is inherited
+
+        @since UDK 3.2.0
+    */
+    public int                             nIndex;
+    /** number of getter exceptions
+
+        @since UDK 3.2.0
+    */
+    public int                             nGetExceptions;
+    /** array of getter exception types
+
+        @since UDK 3.2.0
+    */
+    public TypeDescriptionReference **     ppGetExceptions;
+    /** number of setter exceptions
+
+        @since UDK 3.2.0
+    */
+    public int                             nSetExceptions;
+    /** array of setter exception types
+
+        @since UDK 3.2.0
+    */
+    public TypeDescriptionReference **     ppSetExceptions;
+}
+
+/// @HTML
+/** Type description of an interface.
+
+    <p>Not all members are always initialized (not yet initialized members being
+    null); there are three levels:</p>
+    <ul>
+        <li>Minimally, only <code>aBase</code>,
+        <code>pBaseTypeDescription</code>, <code>aUik</code>,
+        <code>nBaseTypes</code>, and <code>ppBaseTypes</code> are initialized;
+        <code>aBase.bComplete</code> is false.  This only happens when an
+        interface type description is created with
+        <code>static_mi_interface_type_init</code> or
+        <code>static_interface_type_init</code>.</li>
+
+        <li>At the next level, <code>nMembers</code>, <code>ppMembers</code>,
+        <code>nAllMembers</code>, <code>ppAllMembers</code> are also
+        initialized; <code>aBase.bComplete</code> is still false.  This happens
+        when an interface type description is created with
+        <code>typedescription_newMIInterface</cocde> or
+        <code>typedescription_newInterface</code>.</li>
+
+        <li>At the final level, <code>pMapMemberIndexToFunctionIndex</code>,
+        <code>nMapFunctionIndexToMemberIndex</code>, and
+        <code>pMapFunctionIndexToMemberIndex</code> are also initialized;
+        <code>aBase.bComplete</code> is true.  This happens after a call to
+        <code>typedescription_complete</code>.</li>
+    </ul>
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceTypeDescription
+/// @NOHTML
+{
+    /** inherits all members of TypeDescription
+    */
+    public TypeDescription                 aBase;
+    
+    /** pointer to base type description, else 0
+
+        @deprecated
+        use nBaseTypes and ppBaseTypes instead
+    */
+    public InterfaceTypeDescription *      pBaseTypeDescription;
+    /** unique identifier of interface
+    */
+    public Uik                             aUik;
+    /** number of members
+    */
+    public int                             nMembers;
+    /** array of members; references attributes or methods
+    */
+    public TypeDescriptionReference **     ppMembers;
+    /** number of members including members of base interface
+    */
+    public int                             nAllMembers;
+    /** array of members including members of base interface; references attributes or methods
+    */
+    public TypeDescriptionReference **     ppAllMembers;
+    /** array mapping index of the member description to an index doubling for read-write
+        attributes (called function index); size of array is nAllMembers
+    */
+    public int *                           pMapMemberIndexToFunctionIndex;
+    /** number of members plus number of read-write attributes
+    */
+    public int                             nMapFunctionIndexToMemberIndex;
+    /** array mapping function index to member index; size of arry is nMapFunctionIndexToMemberIndex
+    */
+    public int *                           pMapFunctionIndexToMemberIndex;
+    /** number of base types
+
+        @since UDK 3.2.0
+    */
+    public int                             nBaseTypes;
+    /** array of base type descriptions
+
+        @since UDK 3.2.0
+    */
+    public InterfaceTypeDescription **     ppBaseTypes;
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_release") ]
+    public static extern void Release(/* InterfaceTypeDescription */ void *td);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_acquire") ]
+    public static extern void Acquire(/* InterfaceTypeDescription */ void *td);
+
+    [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_equals") ]
+    public static extern bool Equal(/* InterfaceTypeDescription */ void *td1, /* InterfaceTypeDescription */ void *td2);
+}
+
+/** Init struct of compound members for typedescription_new().
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct CompoundMember_Init
+{
+    /** type class of compound member
+    */
+    public int                             eTypeClass;
+    /** name of type of compound member
+
+        For a member of an instantiated polymorphic struct type that is of
+        parameterized type, this will be a null pointer.
+    */
+    public uno.rtl.UString *               pTypeName;
+    /** name of compound member
+    */
+    public uno.rtl.UString *               pMemberName;
+}
+
+/**
+   Init struct of members for typedescription_newStruct().
+
+   @since UDK 3.2.0
+ */
+[ StructLayout(LayoutKind.Sequential) ]
+public struct StructMember_Init
+{
+    /**
+       Derived from CompoundMember_Init;
+     */
+    public CompoundMember_Init             aBase;
+
+    /**
+       Flag specifying whether the member is of parameterized type (true) or
+       explict type (false).
+     */
+    public byte                            bParameterizedType;
+}
+
+/** Init struct of interface methods for typedescription_new().
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct Parameter_Init
+{
+    /** type class of parameter
+    */
+    public int                             eTypeClass;
+    /** name of parameter
+    */
+    public uno.rtl.UString *               pTypeName;
+    /** name of parameter
+    */
+    public uno.rtl.UString *               pParamName;
+    /** true, if parameter is [in] or [inout]
+    */
+    public byte                            bIn;
+    /** true, if parameter is [out] or [inout]
+    */
+    public byte                            bOut;
+}
+
+/** Init struct of union types for typedescription_newUnion().
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct Union_Init
+{
+    /** union member discriminant
+    */
+    public long                            nDiscriminant;
+    /** union member name
+    */
+    public uno.rtl.UString *               pMemberName;
+    /** union member type
+    */
+    public TypeDescriptionReference *      pTypeRef;
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/uik.cs cli_ure/source/mono_bridge/uik.cs
--- cli_ure-orig/source/mono_bridge/uik.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/uik.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+namespace uno.Typelib {
+
+using System.Runtime.InteropServices;
+
+/** Binary typelib uik struct.  Internally not used anymore.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public struct Uik
+{
+    int     m_Data1;
+    short   m_Data2;
+    short   m_Data3;
+    int     m_Data4;
+    int     m_Data5;
+}
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/uno_glue.cxx cli_ure/source/mono_bridge/uno_glue.cxx
--- cli_ure-orig/source/mono_bridge/uno_glue.cxx	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/uno_glue.cxx	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "rtl/ustring.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include <stdio.h>
+
+extern "C" {
+
+/* uno_Interface */
+
+void SAL_CALL cli_uno_interface_acquire( uno_Interface *pInterface )
+    SAL_THROW_EXTERN_C()
+{
+    (*pInterface->acquire)( pInterface );
+}
+
+void SAL_CALL cli_uno_interface_release( uno_Interface *pInterface )
+    SAL_THROW_EXTERN_C()
+{
+    (*pInterface->release)( pInterface );
+}
+
+void SAL_CALL cli_uno_interface_dispatch(
+    uno_Interface *pInterface, const struct _typelib_TypeDescription *pMemberType,
+    void *pReturn, void *pArgs[], uno_Any **ppException )
+    SAL_THROW_EXTERN_C()
+{
+    (*pInterface->pDispatcher)( pInterface, pMemberType, pReturn, pArgs, ppException );
+}
+
+/* uno_ExtEnvironment */
+
+void SAL_CALL cli_uno_environment_getObjectIdentifier(
+    uno_ExtEnvironment *pUnoEnv, rtl_uString **ppOId, uno_Interface *pUnoI )
+    SAL_THROW_EXTERN_C()
+{
+    (*pUnoEnv->getObjectIdentifier)( pUnoEnv, ppOId, pUnoI );
+}
+
+void SAL_CALL cli_uno_environment_registerInterface(
+    uno_ExtEnvironment *pUnoEnv, void **ppInterface, rtl_uString *pOId,
+    struct _typelib_InterfaceTypeDescription *pTypeDescr )
+    SAL_THROW_EXTERN_C()
+{
+    (*pUnoEnv->registerInterface)( pUnoEnv, ppInterface, pOId, pTypeDescr );
+}
+
+void SAL_CALL cli_uno_environment_getRegisteredInterface(
+    uno_ExtEnvironment *pUnoEnv, void **ppInterface, rtl_uString *pOId,
+    struct _typelib_InterfaceTypeDescription *pTypeDescr )
+    SAL_THROW_EXTERN_C()
+{
+    (*pUnoEnv->getRegisteredInterface)( pUnoEnv, ppInterface, pOId, pTypeDescr );
+}
+
+
+}
diff -ruNp cli_ure-orig/source/mono_bridge/uno_proxy.cs cli_ure/source/mono_bridge/uno_proxy.cs
--- cli_ure-orig/source/mono_bridge/uno_proxy.cs	1970-01-01 01:00:00.000000000 +0100
+++ cli_ure/source/mono_bridge/uno_proxy.cs	2007-07-20 11:27:39.000000000 +0200
@@ -0,0 +1,598 @@
+/*************************************************************************
+ *
+ *  $RCSfile: $
+ *
+ *  $Revision: $
+ *
+ *  last change: $Author: $ $Date: $
+ *
+ *  The Contents of this file are made available subject to the terms of
+ *  either of the following licenses
+ *
+ *         - GNU Lesser General Public License Version 2.1
+ *         - Sun Industry Standards Source License Version 1.1
+ *
+ *  Sun Microsystems Inc., October, 2000
+ *
+ *  GNU Lesser General Public License Version 2.1
+ *  =============================================
+ *  Copyright 2000 by Sun Microsystems, Inc.
+ *  901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License version 2.1, as published by the Free Software Foundation.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ *  MA  02111-1307  USA
+ *
+ *
+ *  Sun Industry Standards Source License Version 1.1
+ *  =================================================
+ *  The contents of this file are subject to the Sun Industry Standards
+ *  Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ *  Software provided under this License is provided on an "AS IS" basis,
+ *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ *  See the License for the specific provisions governing your rights and
+ *  obligations concerning the Software.
+ *
+ *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ *  Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ *  All Rights Reserved.
+ *
+ *  Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Proxies;
+
+using uno.Binary;
+using uno.Typelib;
+using uno.rtl;
+
+namespace com.sun.star.bridges.mono_uno /* FIXME use some uno.foo namespace ? */
+{
+
+public unsafe class UnoInterfaceInfo
+{
+    public IntPtr UnoInterface; // wrapped interface
+    public Type Type; // mapped type
+    public com.sun.star.bridges.mono_uno.Bridge Bridge;
+    public InterfaceTypeDescription *TypeDesc;
+
+    public UnoInterfaceInfo(com.sun.star.bridges.mono_uno.Bridge bridge,
+                            IntPtr unoInterface,
+                            InterfaceTypeDescription *td)
+    {
+        Bridge = bridge;
+        UnoInterface = unoInterface;
+        Type = Bridge.MapUnoType((TypeDescription *)td);
+        uno.Binary.Interface.Acquire(UnoInterface);
+        TypeDesc = td;
+        InterfaceTypeDescription.Acquire(TypeDesc);
+        
+        fixed (InterfaceTypeDescription **ppTypeDesc = &TypeDesc)
+            if (((TypeDescription *)TypeDesc)->bComplete == 0 &&
+                TypeDescription.Complete((TypeDescription **)ppTypeDesc))
+            {
+                // FIXME throw a uno runtime exception
+            }
+    }
+
+    ~UnoInterfaceInfo()
+    {
+        Bridge.RevokeFromUnoEnvironment(UnoInterface);
+        uno.Binary.Interface.Release(UnoInterface);
+        InterfaceTypeDescription.Release(TypeDesc);        
+    }
+}
+
+public unsafe class UnoInterfaceProxy: RealProxy, IRemotingTypeInfo
+{
+    /** used for IRemotingTypeInfo.TypeName
+     */
+    string typeName = "System.Object";
+
+    /** The list is filled with UnoInterfaceInfo objects. The list can only
+        grow and elements are never changed. If an element was added it
+        must not be changed!
+    */
+    ArrayList interfaces = new ArrayList(10); // of UnoInterfaceInfo
+
+    /** The list is filled with additional UnoInterfaceProxy object due
+        to aggregation via bridges.  Though the latter is strongly
+        discouraged, this has to be supported.
+    */
+    ArrayList additionalProxies = new ArrayList();
+
+    Bridge bridge;
+    string oid;
+
+    private unsafe UnoInterfaceProxy(Bridge bridge, IntPtr unoInterface,
+                                     InterfaceTypeDescription *TD, string oid)
+        : base(typeof(MarshalByRefObject)) // FIXME is there a better type?
+    {
+        this.bridge = bridge;
+        this.oid = oid;
+        AddUnoInterface(unoInterface, TD);
+    }
+
+    ~UnoInterfaceProxy()
+    {
+        // FIXME should revokeInterface from environment, but can't
+        // access managed string oid any longer.
+    }
+
+    public static unsafe object Create(Bridge bridge, IntPtr unoInterface,
+                                       InterfaceTypeDescription *TD, string oid)
+    {
+        UnoInterfaceProxy realProxy = new UnoInterfaceProxy(bridge, unoInterface,
+                                                            TD, oid);
+        object proxy = realProxy.GetTransparentProxy();
+        bridge.RegisterWithCliEnvironment(proxy, oid);
+        return proxy;
+    }
+
+    // RealProxy members
+    public unsafe override IMessage Invoke(IMessage request)
+    {
+        IMethodCallMessage callmsg = (IMethodCallMessage)request;
+
+        // Find out which UNO interface is being called
+        string typeName = callmsg.TypeName;
+        typeName = typeName.Substring(0, typeName.IndexOf(','));
+
+        // Special Handling for System.Object methods
+        if (typeName.IndexOf("System.Object") != -1)
+        {
+            return InvokeObjectMethod(request);
+        }
+
+        Type typeBeingCalled = Bridge.LoadCliType(typeName);
+        UnoInterfaceInfo info = FindInfo(typeBeingCalled);
+
+        Trace.Assert(info != null);
+        
+        string methodName = callmsg.MethodName;
+        TypeDescriptionReference **ppAllMembers =
+        info.TypeDesc->ppAllMembers;
+        int numMembers = info.TypeDesc->nAllMembers;
+        for (int i = numMembers - 1; i >= 0; --i)
+        {
+            TypeDescriptionReference *memberTD = *(ppAllMembers + i);
+
+            // FIXME do without string conversion?
+            string memberTypeName = UString.UStringToString(memberTD->pTypeName);
+            // check methodName against fully qualified memberTypeName
+            // of memberTD; memberTypeName is of the form
+            //  <name> "::" <methodName> *(":@" <idx> "," <idx> ":" <name>)
+
+            int offset = memberTypeName.IndexOf(':') + 2;
+            int remainder = memberTypeName.Length - offset;
+            if (memberTD->eTypeClass == TypeClass.INTERFACE_METHOD)
+            {
+                if ((methodName.Length == remainder ||
+                     (methodName.Length < remainder &&
+                      memberTypeName[offset + methodName.Length] == ':')) &&
+                    String.Compare(memberTypeName, offset,
+                                   methodName, 0, methodName.Length) == 0)
+                {
+                    TypeDescription *methodTD = null;
+		    // FIXME release it
+		    TypeDescriptionReference.GetDescription(&methodTD, memberTD);
+
+                    uno.Any exception;
+                    uno.Any result =
+                        bridge.CallUno(info.UnoInterface,
+                                       methodTD,
+                                       ((InterfaceMethodTypeDescription *)methodTD)->pReturnTypeRef,
+                                       ((InterfaceMethodTypeDescription *)methodTD)->nParams,
+				       ((InterfaceMethodTypeDescription *)methodTD)->pParams,
+                                       callmsg.Args,
+                                       /* FIXME this is an implementation detail,
+                                          documented on MSDN, but still an implementation
+                                          detail. cli_uno does the same */
+                                       (System.Type[])callmsg.MethodSignature,
+                                       out exception);
+                    return ConstructReturnMessage(result, callmsg.Args,
+						   (InterfaceMethodTypeDescription *)methodTD,
+                                                  callmsg, exception);
+                }
+            }
+            else // INTERFACE_ATTRIBUTE
+            {
+                if (methodName.Length > 4 &&
+                    (methodName.Length - 4 == remainder ||
+                     (methodName.Length - 4 <  remainder &&
+                      memberTypeName[offset + methodName.Length - 4] == ':')) &&
+                    methodName[1] == 'e' && methodName[2] == 't' &&
+                    String.Compare(memberTypeName, offset,
+                                   methodName, 4, methodName.Length - 4) == 0)
+                {
+					InterfaceAttributeTypeDescription *attributeTD = null;
+		    // FIXME release it
+					TypeDescriptionReference.GetDescription( (TypeDescription **)&attributeTD, 
+															 memberTD );
+                    uno.Any exception;
+                    uno.Any result;
+
+                    if (methodName[0] == 'g') // "get"
+                    {
+                        result = bridge.CallUno(info.UnoInterface,
+                                                (TypeDescription *)attributeTD,
+                                                attributeTD->pAttributeTypeRef,
+                                                0, null, null, null,
+                                                out exception);
+                        return ConstructReturnMessage(result, null, null,
+                                                      callmsg, exception);
+                    }
+                    else if (methodName[0] == 's') // "set"
+                    {
+                        if (attributeTD->bReadOnly != 0)
+                            /* FIXME should we generate an exception? */
+                            return ConstructReturnMessage(uno.Any.VOID, null, null,
+                                                          callmsg, uno.Any.VOID);
+
+                        MethodParameter param;
+                        param.pTypeRef = attributeTD->pAttributeTypeRef;
+                        param.bIn = 1;
+                        param.bOut = 0;
+
+                        result =
+                            bridge.CallUno(info.UnoInterface,
+                                           (TypeDescription *)attributeTD,
+                                           TypeDescription.VoidType,
+                                           1, &param,
+                                           callmsg.Args, null, /* FIXME ??? from cli_uno */
+                                           out exception);
+                        return ConstructReturnMessage(uno.Any.VOID, null, null,
+                                                      callmsg, exception);
+                    }
+                    break;
+                }                                   
+            }
+        }
+        // FIXME check if the message of the exception is not crippled
+
+        // the thing that should not be... no method info found!
+        // FIXME throw unoidl.com.sun.star.uno.RuntimeException
+
+        return null;
+    }
+
+    // IRemotingTypeInfo members
+    public string TypeName
+    {
+        get { return typeName; }
+        set { typeName = value; }
+    }
+
+    public unsafe bool CanCastTo(Type fromType, object o)
+    {
+        if (fromType == typeof(Object))
+        return true;
+
+        lock (this) {
+            if (FindInfo(fromType) != null)
+                // type is already in our list of Interfaces
+                return true;
+            
+            // queryInterface for the required type
+            // there is always a least one interface in our list
+            UnoInterfaceInfo info = (UnoInterfaceInfo)interfaces[0];
+            // ppAllMembers[0] corresponds to queryInterface
+            TypeDescription *queryI = null;
+
+            TypeDescriptionReference.GetDescription( // FIXME release it when you're done
+                &queryI, *(info.TypeDesc->ppAllMembers));
+        
+            object[] args = new object[] { fromType };
+            uno.Any exception;
+
+            uno.Any result = bridge.CallUno(info.UnoInterface,
+                                            queryI,
+                                            ((InterfaceMethodTypeDescription *)queryI)->pReturnTypeRef,
+                                            1, ((InterfaceMethodTypeDescription *)queryI)->pParams, args, null,
+                                            out exception);
+
+            // queryInterface doesn't throw exceptions.
+            
+            if (result.Type != typeof(void)) // result has a value
+            {
+                if (FindInfo(fromType) != null)
+                {
+                    // the proxy supports the requested interface now
+                    return true;
+                }
+                
+                // via aggregation: it is possible that queryInterface() returns
+                //                  and interface with a different oid.
+                //                  That way, this type is supported for the CLI
+                //                  interpreter (CanCastTo() returns true)
+                object obj = result.Value;
+                if (RemotingServices.IsTransparentProxy(obj))
+                {
+                    UnoInterfaceProxy proxy =
+                        (UnoInterfaceProxy)RemotingServices.GetRealProxy(obj);
+                    additionalProxies.Add(proxy);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // internals
+    public unsafe void AddUnoInterface(IntPtr unoInterface, InterfaceTypeDescription *TD)
+    {
+        lock (this)
+        {
+            foreach (UnoInterfaceInfo info in interfaces)
+            {
+                if (InterfaceTypeDescription.Equal(info.TypeDesc, TD))
+                    return;
+            }
+            // This proxy does not contain the unoInterface. Add it.
+            bridge.RegisterWithUnoEnvironment(ref unoInterface,
+                                              oid, TD);
+            interfaces.Add(new UnoInterfaceInfo(bridge, unoInterface, TD));         
+        }
+    }
+
+    UnoInterfaceInfo FindInfo(Type type)
+    {
+        foreach (UnoInterfaceInfo info in interfaces)
+        {
+            if (type.IsAssignableFrom(info.Type))
+                return info;
+        }
+        foreach (UnoInterfaceProxy proxy in additionalProxies)
+        {
+            UnoInterfaceInfo info = proxy.FindInfo(type);
+            if (info != null)
+                return info;
+        }
+        return null;
+    }
+
+    static Type MapUnoType(TypeDescription *TD)
+    {
+        return MapUnoType(TD->pWeakRef);
+    }
+    
+    static Type MapUnoType(TypeDescriptionReference *TD)
+    {
+        Type result;
+
+        switch(TD->eTypeClass)
+        {
+        case TypeClass.VOID:
+            result = typeof(void);
+            break;
+        case TypeClass.CHAR:
+            result = typeof(char);
+            break;
+        case TypeClass.BOOLEAN:
+            result = typeof(bool);
+            break;
+        case TypeClass.BYTE:
+            result = typeof(byte);
+            break;
+        case TypeClass.SHORT:
+            result = typeof(short);
+            break;
+        case TypeClass.UNSIGNED_SHORT:
+            result = typeof(ushort);
+            break;
+        case TypeClass.LONG:
+            result = typeof(int);
+            break;
+        case TypeClass.UNSIGNED_LONG:
+            result = typeof(uint);
+            break;
+        case TypeClass.HYPER:
+            result = typeof(long);
+            break;
+        case TypeClass.UNSIGNED_HYPER:
+            result = typeof(ulong);
+            break;
+        case TypeClass.FLOAT:
+            result = typeof(float);
+            break;
+        case TypeClass.DOUBLE:
+            result = typeof(double);
+            break;
+        case TypeClass.STRING:
+            result = typeof(string);
+            break;
+        case TypeClass.TYPE:
+            result = typeof(Type);
+            break;
+        case TypeClass.ANY:
+            result = typeof(uno.Any);
+            break;
+        case TypeClass.ENUM:
+        case TypeClass.STRUCT:
+        case TypeClass.EXCEPTION:
+            result = Bridge.LoadCliType(TD->pTypeName);
+            break;
+        case TypeClass.INTERFACE:
+            // special handling for XInterface, since it does not exist in cli.
+            if (UString.UStringToString(TD->pTypeName) == "com.sun.star.uno.XInterface")
+                result = typeof(object);
+            else
+                result = Bridge.LoadCliType(TD->pTypeName);
+            break;
+        case TypeClass.SEQUENCE:
+        {
+            // FIXME do something with TD here?
+            TypeDescriptionReference *elementTDRef =
+                ((IndirectTypeDescription *)TD)->pType;
+            switch (elementTDRef->eTypeClass)
+            {
+            case TypeClass.CHAR:
+                result = Type.GetType("System.Char[]");
+                break;
+            case TypeClass.BOOLEAN:
+                result = Type.GetType("System.Boolean[]");
+                break;
+            case TypeClass.BYTE:
+                result = Type.GetType("System.Byte[]");
+                break;
+            case TypeClass.SHORT:
+                result = Type.GetType("System.Int16[]");
+                break;
+            case TypeClass.UNSIGNED_SHORT:
+                result = Type.GetType("System.UInt16[]");
+                break;
+            case TypeClass.LONG:
+                result = Type.GetType("System.Int32[]");
+                break;
+            case TypeClass.UNSIGNED_LONG:
+                result = Type.GetType("System.UInt32[]");
+                break;
+            case TypeClass.HYPER:
+                result = Type.GetType("System.Int64[]");
+                break;
+            case TypeClass.UNSIGNED_HYPER:
+                result = Type.GetType("System.UInt64[]");
+                break;
+            case TypeClass.FLOAT:
+                result = Type.GetType("System.Single[]");
+                break;
+            case TypeClass.DOUBLE:
+                result = Type.GetType("System.Double[]");
+                break;
+            case TypeClass.STRING:
+                result = Type.GetType("System.String[]");
+                break;
+            case TypeClass.TYPE:
+                result = Type.GetType("System.Type[]");
+                break;
+            case TypeClass.ANY:
+            case TypeClass.ENUM:
+            case TypeClass.EXCEPTION:
+            case TypeClass.STRUCT:
+            case TypeClass.INTERFACE:
+            case TypeClass.SEQUENCE:
+                result = Bridge.LoadCliType(TD->pTypeName);
+                break;
+            default:
+                // FIXME can't happen
+                result = null;
+                break;
+            }
+            break;
+        }
+        default:
+            // FIXME can't happen
+            result = null;
+            break;
+        }
+        return result;
+    }
+
+    IMessage InvokeObjectMethod(IMessage request)
+    {
+        IMethodMessage methodmsg = (IMethodMessage)request;
+        object ret;
+        switch (methodmsg.MethodName)
+        {
+        case "Equals":
+            ret = false;
+
+            if (RemotingServices.IsTransparentProxy(methodmsg.Args[0]))
+            {
+                UnoInterfaceProxy unoProxy =
+                    RemotingServices.GetRealProxy(methodmsg.Args[0]) as UnoInterfaceProxy;
+
+                if (unoProxy != null)
+                {
+                    ret = oid.Equals(unoProxy.Oid);
+                    break;
+                }
+            }
+            break;
+        case "GetHashCode":
+            ret = oid.GetHashCode();
+            break;
+        case "GetType":
+            ret = typeof(System.Object);
+            break;
+        case "ToString":
+            ret = String.Format("Uno object proxy. OID: {0}", oid);
+            break;
+        default:
+            // Cannot happen
+            ret = null;
+            break;
+        }
+
+        return new ReturnMessage(ret, new object[0], 0,
+                                 methodmsg.LogicalCallContext,
+                                 (IMethodCallMessage)methodmsg);
+    }
+
+    public string Oid {
+        get { return oid; }
+    }
+
+    IMessage ConstructReturnMessage(uno.Any result, object[] args,
+                                    InterfaceMethodTypeDescription *methodTD,
+                                    IMethodCallMessage callmsg, uno.Any exception)
+    {
+        if (exception.hasValue())
+        {
+            throw (System.Exception)exception.Value;
+        }
+        else
+        {
+            if (args != null)
+            {
+                object[] outArgs = new object[methodTD->nParams];
+                int numOutArgs = 0;
+                for (int i = 0; i < methodTD->nParams; ++i)
+                {
+                    if (methodTD->pParams[i].bOut == 1)
+                    {
+                        outArgs[i] = args[i];
+                        ++numOutArgs;
+                    }
+                }
+                return new ReturnMessage(result.Value, outArgs, numOutArgs,
+                                         callmsg.LogicalCallContext,
+                                         callmsg);
+            }
+            else
+            {
+                return new ReturnMessage(result.Value, null, 0,
+                                         callmsg.LogicalCallContext,
+                                         callmsg);
+            }
+        }
+    }
+}
+
+}
