/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
//#include <stl_queue.h>
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#ifndef _TOOLERR_HXX //autogen
#include <tools/errcode.hxx>
#endif
#include <svl/hint.hxx>

#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <cppuhelper/interfacecontainer.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/processfactory.hxx>

#include <rtl/ustrbuf.hxx>
#include <rtl/strbuf.hxx>

#include <com/sun/star/script/ArrayWrapper.hpp>
#include <com/sun/star/script/NativeObjectWrapper.hpp>

#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/DeploymentException.hpp>
#include <com/sun/star/lang/XTypeProvider.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/PropertyConcept.hpp>
#include <com/sun/star/beans/MethodConcept.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/script/BasicErrorException.hpp>
#include <com/sun/star/script/XAllListener.hpp>
#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/script/XDefaultProperty.hpp>
#include <com/sun/star/script/XDirectInvocation.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/reflection/XIdlArray.hpp>
#include <com/sun/star/reflection/XIdlReflection.hpp>
#include <com/sun/star/reflection/XIdlClassProvider.hpp>
#include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
#include <com/sun/star/bridge/oleautomation/NamedArgument.hpp>
#include <com/sun/star/bridge/oleautomation/Date.hpp>
#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
#include <com/sun/star/bridge/oleautomation/Currency.hpp>
#include <com/sun/star/bridge/oleautomation/XAutomationObject.hpp>


using com::sun::star::uno::Reference;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::reflection;
using namespace com::sun::star::beans;
using namespace com::sun::star::script;
using namespace com::sun::star::container;
using namespace com::sun::star::bridge;
using namespace cppu;


#include<basic/sbstar.hxx>
#include<basic/sbuno.hxx>
#include<basic/sberrors.hxx>
#include<sbunoobj.hxx>
#include"sbjsmod.hxx"
#include<basic/basmgr.hxx>
#include<sbintern.hxx>
#include<runtime.hxx>

#include<math.h>
#include <hash_map>
#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>

TYPEINIT1(SbUnoMethod,SbxMethod)
TYPEINIT1(SbUnoProperty,SbxProperty)
TYPEINIT1(SbUnoObject,SbxObject)
TYPEINIT1(SbUnoClass,SbxObject)
TYPEINIT1(SbUnoService,SbxObject)
TYPEINIT1(SbUnoServiceCtor,SbxMethod)
TYPEINIT1(SbUnoSingleton,SbxObject)

typedef WeakImplHelper1< XAllListener > BasicAllListenerHelper;

// Flag, um immer ueber Invocation zu gehen
//#define INVOCATION_ONLY


// Identifier fuer die dbg_-Properies als Strings anlegen
static char const ID_DBG_SUPPORTEDINTERFACES[] = "Dbg_SupportedInterfaces";
static char const ID_DBG_PROPERTIES[] = "Dbg_Properties";
static char const ID_DBG_METHODS[] = "Dbg_Methods";

static ::rtl::OUString aSeqLevelStr( RTL_CONSTASCII_USTRINGPARAM("[]") );
static ::rtl::OUString defaultNameSpace( RTL_CONSTASCII_USTRINGPARAM("ooo.vba") );

// Gets the default property for an uno object. Note: There is some
// redirection built in. The property name specifies the name
// of the default property.

bool SbUnoObject::getDefaultPropName( SbUnoObject* pUnoObj, String& sDfltProp )
{
	bool result = false;
	Reference< XDefaultProperty> xDefaultProp( pUnoObj->maTmpUnoObj, UNO_QUERY );
	if ( xDefaultProp.is() )
	{
		sDfltProp = xDefaultProp->getDefaultPropertyName();
		if ( sDfltProp.Len() )
			result = true;
	}
	return result;
}

SbxVariable* getDefaultProp( SbxVariable* pRef )
{
	SbxVariable* pDefaultProp = NULL;
	if ( pRef->GetType() == SbxOBJECT )
	{
  		SbxObject* pObj = PTR_CAST(SbxObject,(SbxVariable*) pRef);
		if ( !pObj )
		{
			SbxBase* pObjVarObj = pRef->GetObject();
			pObj = PTR_CAST(SbxObject,pObjVarObj);
		}
		if ( pObj && pObj->ISA(SbUnoObject) )
		{
			SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)pObj);
			pDefaultProp = pUnoObj->GetDfltProperty();
		}
	}
	return pDefaultProp;
}

Reference< XComponentContext > getComponentContext_Impl( void )
{
    static Reference< XComponentContext > xContext;

	// Haben wir schon CoreReflection, sonst besorgen
	if( !xContext.is() )
	{
		Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
        Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
        OSL_ASSERT( xProps.is() );
        if (xProps.is())
        {
            xProps->getPropertyValue(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
            OSL_ASSERT( xContext.is() );
        }
	}
	return xContext;
}

// CoreReflection statisch speichern
Reference< XIdlReflection > getCoreReflection_Impl( void )
{
	static Reference< XIdlReflection > xCoreReflection;

	// Haben wir schon CoreReflection, sonst besorgen
	if( !xCoreReflection.is() )
	{
        Reference< XComponentContext > xContext = getComponentContext_Impl();
        if( xContext.is() )
        {
            xContext->getValueByName(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) )
                    >>= xCoreReflection;
            OSL_ENSURE( xCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
        }
        if( !xCoreReflection.is() )
        {
            throw DeploymentException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ),
                Reference< XInterface >() );
        }
	}
	return xCoreReflection;
}

// CoreReflection statisch speichern
Reference< XHierarchicalNameAccess > getCoreReflection_HierarchicalNameAccess_Impl( void )
{
	static Reference< XHierarchicalNameAccess > xCoreReflection_HierarchicalNameAccess;

	if( !xCoreReflection_HierarchicalNameAccess.is() )
	{
		Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
		if( xCoreReflection.is() )
		{
			xCoreReflection_HierarchicalNameAccess =
				Reference< XHierarchicalNameAccess >( xCoreReflection, UNO_QUERY );
		}
	}
	return xCoreReflection_HierarchicalNameAccess;
}

// Hold TypeProvider statically
Reference< XHierarchicalNameAccess > getTypeProvider_Impl( void )
{
	static Reference< XHierarchicalNameAccess > xAccess;

	// Haben wir schon CoreReflection, sonst besorgen
	if( !xAccess.is() )
	{
        Reference< XComponentContext > xContext = getComponentContext_Impl();
        if( xContext.is() )
        {
            xContext->getValueByName(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) )
                    >>= xAccess;
            OSL_ENSURE( xAccess.is(), "### TypeDescriptionManager singleton not accessible!?" );
        }
        if( !xAccess.is() )
        {
            throw DeploymentException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM
                    ("/singletons/com.sun.star.reflection.theTypeDescriptionManager singleton not accessible") ),
                Reference< XInterface >() );
        }
	}
	return xAccess;
}

// Hold TypeConverter statically
Reference< XTypeConverter > getTypeConverter_Impl( void )
{
	static Reference< XTypeConverter > xTypeConverter;

	// Haben wir schon CoreReflection, sonst besorgen
	if( !xTypeConverter.is() )
	{
        Reference< XComponentContext > xContext = getComponentContext_Impl();
        if( xContext.is() )
        {
            Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
	        xTypeConverter = Reference<XTypeConverter>(
		        xSMgr->createInstanceWithContext(
			        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")),
			            xContext ), UNO_QUERY );
        }
        if( !xTypeConverter.is() )
        {
            throw DeploymentException(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM
                    ("com.sun.star.script.Converter service not accessible") ),
                Reference< XInterface >() );
        }
	}
	return xTypeConverter;
}


// #111851 factory function to create an OLE object
SbUnoObject* createOLEObject_Impl( const String& aType )
{
	static Reference< XMultiServiceFactory > xOLEFactory;
	static bool bNeedsInit = true;

	if( bNeedsInit )
	{
		bNeedsInit = false;

        Reference< XComponentContext > xContext = getComponentContext_Impl();
        if( xContext.is() )
        {
            Reference<XMultiComponentFactory> xSMgr = xContext->getServiceManager();
	        xOLEFactory = Reference<XMultiServiceFactory>(
		        xSMgr->createInstanceWithContext(
			        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.OleObjectFactory")),
			            xContext ), UNO_QUERY );
        }
	}

	SbUnoObject* pUnoObj = NULL;
	if( xOLEFactory.is() )
	{
        // some type names available in VBA can not be directly used in COM
        ::rtl::OUString aOLEType = aType;
        if ( aOLEType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SAXXMLReader30" ) ) ) )
            aOLEType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Msxml2.SAXXMLReader.3.0" ) );

		Reference< XInterface > xOLEObject = xOLEFactory->createInstance( aOLEType );
		if( xOLEObject.is() )
		{
			Any aAny;
			aAny <<= xOLEObject;
			pUnoObj = new SbUnoObject( aType, aAny );
		}
	}
	return pUnoObj;
}


namespace
{
    void lcl_indent( ::rtl::OUStringBuffer& _inout_rBuffer, sal_Int32 _nLevel )
    {
        while ( _nLevel-- > 0 )
            _inout_rBuffer.appendAscii( "  " );
    }
}

void implAppendExceptionMsg( ::rtl::OUStringBuffer& _inout_rBuffer, const Exception& _e, const ::rtl::OUString& _rExceptionType, sal_Int32 _nLevel )
{
    _inout_rBuffer.appendAscii( "\n" );
    lcl_indent( _inout_rBuffer, _nLevel );
    _inout_rBuffer.appendAscii( "Type: " );

    if ( _rExceptionType.isEmpty() )
        _inout_rBuffer.appendAscii( "Unknown" );
    else
        _inout_rBuffer.append( _rExceptionType );

    _inout_rBuffer.appendAscii( "\n" );
    lcl_indent( _inout_rBuffer, _nLevel );
    _inout_rBuffer.appendAscii( "Message: " );
    _inout_rBuffer.append( _e.Message );

}

// Fehlermeldungs-Message bei Exception zusammenbauen
::rtl::OUString implGetExceptionMsg( const Exception& e, const ::rtl::OUString& aExceptionType_ )
{
    ::rtl::OUStringBuffer aMessageBuf;
    implAppendExceptionMsg( aMessageBuf, e, aExceptionType_, 0 );
    return aMessageBuf.makeStringAndClear();
}

String implGetExceptionMsg( const Any& _rCaughtException )
{
    OSL_PRECOND( _rCaughtException.getValueTypeClass() == TypeClass_EXCEPTION, "implGetExceptionMsg: illegal argument!" );
    if ( _rCaughtException.getValueTypeClass() != TypeClass_EXCEPTION )
        return String();

    return implGetExceptionMsg( *static_cast< const Exception* >( _rCaughtException.getValue() ), _rCaughtException.getValueTypeName() );
}

Any convertAny( const Any& rVal, const Type& aDestType )
{
    Any aConvertedVal;
    Reference< XTypeConverter > xConverter = getTypeConverter_Impl();
	try
	{
        aConvertedVal = xConverter->convertTo( rVal, aDestType );
	}
	catch( const IllegalArgumentException& )
	{
		StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
            implGetExceptionMsg( ::cppu::getCaughtException() ) );
		return aConvertedVal;
	}
	catch( CannotConvertException& e2 )
	{
        String aCannotConvertExceptionName
            ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.IllegalArgumentException" ) );
		StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
            implGetExceptionMsg( e2, aCannotConvertExceptionName ) );
		return aConvertedVal;
	}
    return aConvertedVal;
}


// #105565 Special Object to wrap a strongly typed Uno Any
TYPEINIT1(SbUnoAnyObject,SbxObject)


// TODO: Spaeter auslagern
Reference<XIdlClass> TypeToIdlClass( const Type& rType )
{
	// void als Default-Klasse eintragen
	Reference<XIdlClass> xRetClass;
	typelib_TypeDescription * pTD = 0;
	rType.getDescription( &pTD );

	if( pTD )
	{
		::rtl::OUString sOWName( pTD->pTypeName );
		Reference< XIdlReflection > xRefl = getCoreReflection_Impl();
		xRetClass = xRefl->forName( sOWName );
	}
	return xRetClass;
}

// Exception type unknown
template< class EXCEPTION >
String implGetExceptionMsg( const EXCEPTION& e )
{
    return implGetExceptionMsg( e, ::getCppuType( &e ).getTypeName() );
}

// Error-Message fuer WrappedTargetExceptions
String implGetWrappedMsg( const WrappedTargetException& e )
{
    String aMsg;
	Any aWrappedAny = e.TargetException;
    Type aExceptionType = aWrappedAny.getValueType();

	// Really an Exception?
	if( aExceptionType.getTypeClass() == TypeClass_EXCEPTION )
	{
		Exception& e_ = *( (Exception*)aWrappedAny.getValue() );
		aMsg = implGetExceptionMsg( e_, String( aExceptionType.getTypeName() ) );
	}
	// Otherwise use WrappedTargetException itself
	else
	{
        aMsg = implGetExceptionMsg( e );
	}

	return aMsg;
}

void implHandleBasicErrorException( BasicErrorException& e )
{
    SbError nError = StarBASIC::GetSfxFromVBError( (sal_uInt16)e.ErrorCode );
    StarBASIC::Error( nError, e.ErrorMessageArgument );
}

void implHandleWrappedTargetException( const Any& _rWrappedTargetException )
{
    Any aExamine( _rWrappedTargetException );

    // completely strip the first InvocationTargetException, its error message isn't of any
    // interest to the user, it just says something like "invoking the UNO method went wrong.".
    InvocationTargetException aInvocationError;
    if ( aExamine >>= aInvocationError )
        aExamine = aInvocationError.TargetException;

    BasicErrorException aBasicError;

    SbError nError( ERRCODE_BASIC_EXCEPTION );
    ::rtl::OUStringBuffer aMessageBuf;

    // strip any other WrappedTargetException instances, but this time preserve the error messages.
    WrappedTargetException aWrapped;
    sal_Int32 nLevel = 0;
    while ( aExamine >>= aWrapped )
    {
        // special handling for BasicErrorException errors
        if ( aWrapped.TargetException >>= aBasicError )
        {
            nError = StarBASIC::GetSfxFromVBError( (sal_uInt16)aBasicError.ErrorCode );
            aMessageBuf.append( aBasicError.ErrorMessageArgument );
            aExamine.clear();
            break;
        }

        // append this round's message
        implAppendExceptionMsg( aMessageBuf, aWrapped, aExamine.getValueTypeName(), nLevel );
        if ( aWrapped.TargetException.getValueTypeClass() == TypeClass_EXCEPTION )
            // there is a next chain element
            aMessageBuf.appendAscii( "\nTargetException:" );

        // next round
        aExamine = aWrapped.TargetException;
        ++nLevel;
    }

    if ( aExamine.getValueTypeClass() == TypeClass_EXCEPTION )
    {
        // the last element in the chain is still an exception, but no WrappedTargetException
        implAppendExceptionMsg( aMessageBuf, *static_cast< const Exception* >( aExamine.getValue() ), aExamine.getValueTypeName(), nLevel );
    }

    StarBASIC::Error( nError, aMessageBuf.makeStringAndClear() );
}

static void implHandleAnyException( const Any& _rCaughtException )
{
    BasicErrorException aBasicError;
    WrappedTargetException aWrappedError;

    if ( _rCaughtException >>= aBasicError )
	{
		implHandleBasicErrorException( aBasicError );
	}
    else if ( _rCaughtException >>= aWrappedError )
	{
        implHandleWrappedTargetException( _rCaughtException );
	}
    else
	{
		StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( _rCaughtException ) );
	}
}


// NativeObjectWrapper handling
struct ObjectItem
{
	SbxObjectRef	m_xNativeObj;

	ObjectItem( void )
	{}
	ObjectItem( SbxObject* pNativeObj )
		: m_xNativeObj( pNativeObj )
	{}
};
static std::vector< ObjectItem >	GaNativeObjectWrapperVector;

void clearNativeObjectWrapperVector( void )
{
	GaNativeObjectWrapperVector.clear();
}

sal_uInt32 lcl_registerNativeObjectWrapper( SbxObject* pNativeObj )
{
	sal_uInt32 nIndex = GaNativeObjectWrapperVector.size();
	GaNativeObjectWrapperVector.push_back( ObjectItem( pNativeObj ) );
	return nIndex;
}

SbxObject* lcl_getNativeObject( sal_uInt32 nIndex )
{
	SbxObjectRef xRetObj;
	if( nIndex < GaNativeObjectWrapperVector.size() )
	{
		ObjectItem& rItem = GaNativeObjectWrapperVector[ nIndex ];
		xRetObj = rItem.m_xNativeObj;
	}
	return xRetObj;
}


// Von Uno nach Sbx wandeln
SbxDataType unoToSbxType( TypeClass eType )
{
	SbxDataType eRetType = SbxVOID;

	switch( eType )
	{
		case TypeClass_INTERFACE:
		case TypeClass_TYPE:
		case TypeClass_STRUCT:
		case TypeClass_EXCEPTION:		eRetType = SbxOBJECT;	break;

		/* folgende Typen lassen wir erstmal weg
		case TypeClass_SERVICE:			break;
		case TypeClass_CLASS:			break;
		case TypeClass_TYPEDEF:			break;
		case TypeClass_UNION:			break;
		case TypeClass_ARRAY:			break;
		*/
		case TypeClass_ENUM:			eRetType = SbxLONG;		break;
		case TypeClass_SEQUENCE:
			eRetType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
			break;

		/*
		case TypeClass_VOID:			break;
		case TypeClass_UNKNOWN:			break;
		*/

		case TypeClass_ANY:				eRetType = SbxVARIANT;	break;
		case TypeClass_BOOLEAN:			eRetType = SbxBOOL;		break;
		case TypeClass_CHAR:			eRetType = SbxCHAR;		break;
		case TypeClass_STRING:			eRetType = SbxSTRING;	break;
		case TypeClass_FLOAT:			eRetType = SbxSINGLE;	break;
		case TypeClass_DOUBLE:			eRetType = SbxDOUBLE;	break;
		//case TypeClass_OCTET:									break;
		case TypeClass_BYTE:			eRetType = SbxINTEGER;  break;
		//case TypeClass_INT:				eRetType = SbxINT;	break;
		case TypeClass_SHORT:			eRetType = SbxINTEGER;	break;
		case TypeClass_LONG:			eRetType = SbxLONG;		break;
		case TypeClass_HYPER:			eRetType = SbxSALINT64;	break;
		//case TypeClass_UNSIGNED_OCTET:						break;
		case TypeClass_UNSIGNED_SHORT:	eRetType = SbxUSHORT;	break;
		case TypeClass_UNSIGNED_LONG:	eRetType = SbxULONG;	break;
		case TypeClass_UNSIGNED_HYPER:  eRetType = SbxSALUINT64;break;
		//case TypeClass_UNSIGNED_INT:	eRetType = SbxUINT;		break;
		//case TypeClass_UNSIGNED_BYTE:	eRetType = SbxUSHORT;	break;
		default: break;
	}
	return eRetType;
}

SbxDataType unoToSbxType( const Reference< XIdlClass >& xIdlClass )
{
	SbxDataType eRetType = SbxVOID;
	if( xIdlClass.is() )
	{
		TypeClass eType = xIdlClass->getTypeClass();
        eRetType = unoToSbxType( eType );
    }
	return eRetType;
}

static void implSequenceToMultiDimArray( SbxDimArray*& pArray, Sequence< sal_Int32 >& indices, Sequence< sal_Int32 >& sizes, const Any& aValue, sal_Int32& dimension, sal_Bool bIsZeroIndex, Type* pType = NULL )
{
	Type aType = aValue.getValueType();
	TypeClass eTypeClass = aType.getTypeClass();

	sal_Int32 indicesIndex = indices.getLength() -1;
	sal_Int32 dimCopy = dimension;

	if ( eTypeClass == TypeClass_SEQUENCE )
	{
		Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
		Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
		typelib_TypeDescription * pTD = 0;
        aType.getDescription( &pTD );
		Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
		::typelib_typedescription_release( pTD );

		sal_Int32 nLen = xIdlArray->getLen( aValue );
		for ( sal_Int32 index = 0; index < nLen; ++index )
		{
			Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)index );
			// This detects the dimension were currently processing
			if ( dimCopy == dimension )
			{
				++dimCopy;
				if ( sizes.getLength() < dimCopy )
				{
					sizes.realloc( sizes.getLength() + 1 );
					sizes[ sizes.getLength() - 1 ] = nLen;
					indices.realloc( indices.getLength() + 1 );
					indicesIndex = indices.getLength() - 1;
				}
			}

			if ( bIsZeroIndex )
				indices[ dimCopy - 1 ] = index;
			else
				indices[ dimCopy - 1] = index + 1;

			implSequenceToMultiDimArray( pArray, indices, sizes, aElementAny, dimCopy, bIsZeroIndex, &aElementType );
		}

	}
	else
	{
		if ( indices.getLength() < 1 )
		{
			// Should never ever get here ( indices.getLength()
			// should equal number of dimensions in the array )
			// And that should at least be 1 !
			// #QUESTION is there a better error?
			StarBASIC::Error( SbERR_INVALID_OBJECT );
			return;
		}

		SbxDataType eSbxElementType = unoToSbxType( pType ? pType->getTypeClass() : aValue.getValueTypeClass() );
		if ( !pArray )
		{
			pArray = new SbxDimArray( eSbxElementType );
			sal_Int32 nIndexLen = indices.getLength();

			// Dimension the array
			for ( sal_Int32 index = 0; index < nIndexLen; ++index )
			{
				if ( bIsZeroIndex )
					pArray->unoAddDim32( 0, sizes[ index ] - 1);
				else
					pArray->unoAddDim32( 1, sizes[ index ] );

			}
		}

		if ( pArray )
		{
			SbxVariableRef xVar = new SbxVariable( eSbxElementType );
			unoToSbxValue( (SbxVariable*)xVar, aValue );

			sal_Int32* pIndices = indices.getArray();
			pArray->Put32( 	(SbxVariable*)xVar, pIndices );

		}
	}
}

void unoToSbxValue( SbxVariable* pVar, const Any& aValue )
{
	Type aType = aValue.getValueType();
	TypeClass eTypeClass = aType.getTypeClass();
	switch( eTypeClass )
	{
		case TypeClass_TYPE:
		{
			// Map Type to IdlClass
			Type aType_;
			aValue >>= aType_;
			Reference<XIdlClass> xClass = TypeToIdlClass( aType_ );
			Any aClassAny;
			aClassAny <<= xClass;

			// SbUnoObject instanzieren
			String aName;
			SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aClassAny );
			SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;

			// #51475 Wenn das Objekt ungueltig ist null liefern
			if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
			{
				pVar->PutObject( NULL );
			}
			else
			{
				pVar->PutObject( xWrapper );
			}
		}
		break;
		// Interfaces und Structs muessen in ein SbUnoObject gewrappt werden
		case TypeClass_INTERFACE:
		case TypeClass_STRUCT:
		case TypeClass_EXCEPTION:
		{
			if( eTypeClass == TypeClass_STRUCT )
			{
				ArrayWrapper aWrap;
				NativeObjectWrapper aNativeObjectWrapper;
				if ( (aValue >>= aWrap) )
				{
					SbxDimArray* pArray = NULL;
					Sequence< sal_Int32 > indices;
					Sequence< sal_Int32 > sizes;
					sal_Int32 dimension = 0;
					implSequenceToMultiDimArray( pArray, indices, sizes, aWrap.Array, dimension, aWrap.IsZeroIndex );
					if ( pArray )
					{
						SbxDimArrayRef xArray = pArray;
						sal_uInt16 nFlags = pVar->GetFlags();
						pVar->ResetFlag( SBX_FIXED );
						pVar->PutObject( (SbxDimArray*)xArray );
						pVar->SetFlags( nFlags );
					}
					else
						pVar->PutEmpty();
					break;
				}
				else if ( (aValue >>= aNativeObjectWrapper) )
				{
					sal_uInt32 nIndex = 0;
					if( (aNativeObjectWrapper.ObjectId >>= nIndex) )
					{
						SbxObject* pObj = lcl_getNativeObject( nIndex );
						pVar->PutObject( pObj );
					}
					else
						pVar->PutEmpty();
					break;
				}
				else
				{
					SbiInstance* pInst = pINST;
					if( pInst && pInst->IsCompatibility() )
					{
						oleautomation::Date aDate;
						if( (aValue >>= aDate) )
						{
							pVar->PutDate( aDate.Value );
							break;
						}
						else
						{
							oleautomation::Decimal aDecimal;
							if( (aValue >>= aDecimal) )
							{
								pVar->PutDecimal( aDecimal );
								break;
							}
							else
							{
								oleautomation::Currency aCurrency;
								if( (aValue >>= aCurrency) )
								{
									sal_Int64 nValue64 = aCurrency.Value;
									SbxINT64 aInt64;
									aInt64.nHigh =
                                        sal::static_int_cast< sal_Int32 >(
                                            nValue64 >> 32);
									aInt64.nLow = (sal_uInt32)( nValue64 & 0xffffffff );
									pVar->PutCurrency( aInt64 );
									break;
								}
							}
						}
					}
				}
			}
			// SbUnoObject instanzieren
			String aName;
			SbUnoObject* pSbUnoObject = new SbUnoObject( aName, aValue );
			//If this is called externally e.g. from the scripting
			//framework then there is no 'active' runtime the default property will not be set up
			//only a vba object will have XDefaultProp set anyway so... this
			//test seems a bit of overkill
			//if ( SbiRuntime::isVBAEnabled() )
			{
				String sDfltPropName;

				if ( SbUnoObject::getDefaultPropName( pSbUnoObject, sDfltPropName ) )
						pSbUnoObject->SetDfltProperty( sDfltPropName );
			}
			SbxObjectRef xWrapper = (SbxObject*)pSbUnoObject;

			// #51475 Wenn das Objekt ungueltig ist null liefern
			if( pSbUnoObject->getUnoAny().getValueType().getTypeClass() == TypeClass_VOID )
			{
				pVar->PutObject( NULL );
			}
			else
			{
				pVar->PutObject( xWrapper );
			}
		}
		break;

		/* folgende Typen lassen wir erstmal weg
		case TypeClass_SERVICE:			break;
		case TypeClass_CLASS:			break;
		case TypeClass_TYPEDEF:			break;
		case TypeClass_UNION:			break;
		case TypeClass_ENUM:			break;
		case TypeClass_ARRAY:			break;
		*/

		case TypeClass_ENUM:
		{
			sal_Int32 nEnum = 0;
			enum2int( nEnum, aValue );
			pVar->PutLong( nEnum );
		}
			break;

		case TypeClass_SEQUENCE:
		{
			Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aType );
			Reference< XIdlArray > xIdlArray = xIdlTargetClass->getArray();
			sal_Int32 i, nLen = xIdlArray->getLen( aValue );

            typelib_TypeDescription * pTD = 0;
            aType.getDescription( &pTD );
            OSL_ASSERT( pTD && pTD->eTypeClass == typelib_TypeClass_SEQUENCE );
            Type aElementType( ((typelib_IndirectTypeDescription *)pTD)->pType );
            ::typelib_typedescription_release( pTD );

			// In Basic Array anlegen
			SbxDimArrayRef xArray;
            SbxDataType eSbxElementType = unoToSbxType( aElementType.getTypeClass() );
    		xArray = new SbxDimArray( eSbxElementType );
			if( nLen > 0 )
            {
				xArray->unoAddDim32( 0, nLen - 1 );

			    // Elemente als Variablen eintragen
			    for( i = 0 ; i < nLen ; i++ )
			    {
				    // Elemente wandeln
				    Any aElementAny = xIdlArray->get( aValue, (sal_uInt32)i );
				    SbxVariableRef xVar = new SbxVariable( eSbxElementType );
				    unoToSbxValue( (SbxVariable*)xVar, aElementAny );

				    // Ins Array braten
				    xArray->Put32( (SbxVariable*)xVar, &i );
			    }
            }
            else
            {
    			xArray->unoAddDim( 0, -1 );
            }

			// Array zurueckliefern
			sal_uInt16 nFlags = pVar->GetFlags();
			pVar->ResetFlag( SBX_FIXED );
			pVar->PutObject( (SbxDimArray*)xArray );
			pVar->SetFlags( nFlags );

			// #54548, Die Parameter duerfen hier nicht weggehauen werden
			//pVar->SetParameters( NULL );
		}
		break;

		/*
		case TypeClass_VOID:			break;
		case TypeClass_UNKNOWN:			break;

		case TypeClass_ANY:
		{
			// Any rausholen und konvertieren
			//Any* pAny = (Any*)aValue.get();
			//if( pAny )
				//unoToSbxValue( pVar, *pAny );
		}
		break;
		*/

		case TypeClass_BOOLEAN:			pVar->PutBool( *(sal_Bool*)aValue.getValue() );	break;
		case TypeClass_CHAR:
		{
			pVar->PutChar( *(sal_Unicode*)aValue.getValue() );
			break;
		}
		case TypeClass_STRING:			{ ::rtl::OUString val; aValue >>= val; pVar->PutString( String( val ) ); }	break;
		case TypeClass_FLOAT:			{ float val = 0; aValue >>= val; pVar->PutSingle( val ); } break;
		case TypeClass_DOUBLE:			{ double val = 0; aValue >>= val; pVar->PutDouble( val ); } break;
		//case TypeClass_OCTET:			break;
		case TypeClass_BYTE:			{ sal_Int8 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
		//case TypeClass_INT:			break;
		case TypeClass_SHORT:			{ sal_Int16 val = 0; aValue >>= val; pVar->PutInteger( val ); } break;
		case TypeClass_LONG:			{ sal_Int32 val = 0; aValue >>= val; pVar->PutLong( val ); } break;
		case TypeClass_HYPER:			{ sal_Int64 val = 0; aValue >>= val; pVar->PutInt64( val ); } break;
		//case TypeClass_UNSIGNED_OCTET:break;
		case TypeClass_UNSIGNED_SHORT:	{ sal_uInt16 val = 0; aValue >>= val; pVar->PutUShort( val ); } break;
		case TypeClass_UNSIGNED_LONG:	{ sal_uInt32 val = 0; aValue >>= val; pVar->PutULong( val ); } break;
		case TypeClass_UNSIGNED_HYPER:	{ sal_uInt64 val = 0; aValue >>= val; pVar->PutUInt64( val ); } break;
		//case TypeClass_UNSIGNED_INT:	break;
		//case TypeClass_UNSIGNED_BYTE:	break;
		default:						pVar->PutEmpty();						break;
	}
}

// Reflection fuer Sbx-Typen liefern
Type getUnoTypeForSbxBaseType( SbxDataType eType )
{
	Type aRetType = getCppuVoidType();
	switch( eType )
	{
		//case SbxEMPTY:		eRet = TypeClass_VOID; break;
		case SbxNULL:		aRetType = ::getCppuType( (const Reference< XInterface > *)0 ); break;
		case SbxINTEGER:	aRetType = ::getCppuType( (sal_Int16*)0 ); break;
		case SbxLONG:		aRetType = ::getCppuType( (sal_Int32*)0 ); break;
		case SbxSINGLE:		aRetType = ::getCppuType( (float*)0 ); break;
		case SbxDOUBLE:		aRetType = ::getCppuType( (double*)0 ); break;
		case SbxCURRENCY:	aRetType = ::getCppuType( (oleautomation::Currency*)0 ); break;
		case SbxDECIMAL:	aRetType = ::getCppuType( (oleautomation::Decimal*)0 ); break;
		case SbxDATE:		{
							SbiInstance* pInst = pINST;
							if( pInst && pInst->IsCompatibility() )
								aRetType = ::getCppuType( (double*)0 );
							else
								aRetType = ::getCppuType( (oleautomation::Date*)0 );
							}
							break;
		// case SbxDATE:		aRetType = ::getCppuType( (double*)0 ); break;
		case SbxSTRING:		aRetType = ::getCppuType( (::rtl::OUString*)0 ); break;
		//case SbxOBJECT:	break;
		//case SbxERROR:	break;
		case SbxBOOL:		aRetType = ::getCppuType( (sal_Bool*)0 ); break;
		case SbxVARIANT:	aRetType = ::getCppuType( (Any*)0 ); break;
		//case SbxDATAOBJECT: break;
		case SbxCHAR:		aRetType = ::getCppuType( (sal_Unicode*)0 ); break;
		case SbxBYTE:		aRetType = ::getCppuType( (sal_Int8*)0 ); break;
		case SbxUSHORT:		aRetType = ::getCppuType( (sal_uInt16*)0 ); break;
		case SbxULONG:		aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
		//case SbxLONG64:	break;
		//case SbxULONG64:	break;
		// Maschinenabhaengige zur Sicherheit auf Hyper abbilden
		case SbxINT:		aRetType = ::getCppuType( (sal_Int32*)0 ); break;
		case SbxUINT:		aRetType = ::getCppuType( (sal_uInt32*)0 ); break;
		//case SbxVOID:		break;
		//case SbxHRESULT:	break;
		//case SbxPOINTER:	break;
		//case SbxDIMARRAY:	break;
		//case SbxCARRAY:	break;
		//case SbxUSERDEF:	break;
		//case SbxLPSTR:	break;
		//case SbxLPWSTR:	break;
		//case SbxCoreSTRING: break;
		default: break;
	}
	return aRetType;
}

// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
Type getUnoTypeForSbxValue( SbxValue* pVal )
{
	Type aRetType = getCppuVoidType();
	if( !pVal )
		return aRetType;

	// SbxType nach Uno wandeln
	SbxDataType eBaseType = pVal->SbxValue::GetType();
	if( eBaseType == SbxOBJECT )
	{
		SbxBaseRef xObj = (SbxBase*)pVal->GetObject();
		if( !xObj )
		{
			// #109936 No error any more
			// StarBASIC::Error( SbERR_INVALID_OBJECT );
			aRetType = getCppuType( static_cast<Reference<XInterface> *>(0) );
			return aRetType;
		}

		if( xObj->ISA(SbxDimArray) )
		{
			SbxBase* pObj = (SbxBase*)xObj;
			SbxDimArray* pArray = (SbxDimArray*)pObj;

			short nDims = pArray->GetDims();
			Type aElementType = getUnoTypeForSbxBaseType( (SbxDataType)(pArray->GetType() & 0xfff) );
			TypeClass eElementTypeClass = aElementType.getTypeClass();

			// Normal case: One dimensional array
			sal_Int32 nLower, nUpper;
			if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
			{
				if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
				{
					// Wenn alle Elemente des Arrays vom gleichen Typ sind, wird
					// der genommen, sonst wird das ganze als Any-Sequence betrachtet
					sal_Bool bNeedsInit = sal_True;

    				sal_Int32 nSize = nUpper - nLower + 1;
					sal_Int32 nIdx = nLower;
					for( sal_Int32 i = 0 ; i < nSize ; i++,nIdx++ )
					{
						SbxVariableRef xVar = pArray->Get32( &nIdx );
						Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
						if( bNeedsInit )
						{
							if( aType.getTypeClass() == TypeClass_VOID )
							{
								// #88522
								// if only first element is void: different types  -> []any
								// if all elements are void: []void is not allowed -> []any
								aElementType = getCppuType( (Any*)0 );
								break;
							}
							aElementType = aType;
							bNeedsInit = sal_False;
						}
						else if( aElementType != aType )
						{
							// Verschiedene Typen -> AnySequence
							aElementType = getCppuType( (Any*)0 );
							break;
						}
					}
				}

				::rtl::OUString aSeqTypeName( aSeqLevelStr );
				aSeqTypeName += aElementType.getTypeName();
				aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
			}
			// #i33795 Map also multi dimensional arrays to corresponding sequences
			else if( nDims > 1 )
			{
				if( eElementTypeClass == TypeClass_VOID || eElementTypeClass == TypeClass_ANY )
				{
					// For this check the array's dim structure does not matter
					sal_uInt32 nFlatArraySize = pArray->Count32();

					sal_Bool bNeedsInit = sal_True;
					for( sal_uInt32 i = 0 ; i < nFlatArraySize ; i++ )
					{
						SbxVariableRef xVar = pArray->SbxArray::Get32( i );
						Type aType = getUnoTypeForSbxValue( (SbxVariable*)xVar );
						if( bNeedsInit )
						{
							if( aType.getTypeClass() == TypeClass_VOID )
							{
								// if only first element is void: different types  -> []any
								// if all elements are void: []void is not allowed -> []any
								aElementType = getCppuType( (Any*)0 );
								break;
							}
							aElementType = aType;
							bNeedsInit = sal_False;
						}
						else if( aElementType != aType )
						{
							// Verschiedene Typen -> AnySequence
							aElementType = getCppuType( (Any*)0 );
							break;
						}
					}
				}

				::rtl::OUString aSeqTypeName;
				for( short iDim = 0 ; iDim < nDims ; iDim++ )
					aSeqTypeName += aSeqLevelStr;
				aSeqTypeName += aElementType.getTypeName();
				aRetType = Type( TypeClass_SEQUENCE, aSeqTypeName );
			}
		}
		// Kein Array, sondern...
		else if( xObj->ISA(SbUnoObject) )
		{
			aRetType = ((SbUnoObject*)(SbxBase*)xObj)->getUnoAny().getValueType();
		}
		// SbUnoAnyObject?
		else if( xObj->ISA(SbUnoAnyObject) )
		{
			aRetType = ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue().getValueType();
		}
		// Sonst ist es ein Nicht-Uno-Basic-Objekt -> default==void liefern
	}
	// Kein Objekt, Basistyp konvertieren
	else
	{
		aRetType = getUnoTypeForSbxBaseType( eBaseType );
	}
	return aRetType;
}

// Deklaration Konvertierung von Sbx nach Uno mit bekannter Zielklasse
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );

// Konvertierung von Sbx nach Uno ohne bekannte Zielklasse fuer TypeClass_ANY
Any sbxToUnoValueImpl( SbxVariable* pVar, bool bBlockConversionToSmallestType = false )
{
	SbxDataType eBaseType = pVar->SbxValue::GetType();
	if( eBaseType == SbxOBJECT )
    {
		SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
		if( xObj.Is() )
		{
			if( xObj->ISA(SbUnoAnyObject) )
				return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
			if( xObj->ISA(SbClassModuleObject) )
			{
				Any aRetAny;
				SbClassModuleObject* pClassModuleObj = (SbClassModuleObject*)(SbxBase*)xObj;
				SbModule* pClassModule = pClassModuleObj->getClassModule();
				if( pClassModule->createCOMWrapperForIface( aRetAny, pClassModuleObj ) )
					return aRetAny;
			}
			if( !xObj->ISA(SbUnoObject) )
			{
				// Create NativeObjectWrapper to identify object in case of callbacks
				SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
				if( pObj != NULL )
				{
					NativeObjectWrapper aNativeObjectWrapper;
					sal_uInt32 nIndex = lcl_registerNativeObjectWrapper( pObj );
					aNativeObjectWrapper.ObjectId <<= nIndex;
					Any aRetAny;
					aRetAny <<= aNativeObjectWrapper;
					return aRetAny;
				}
			}
		}
    }

	Type aType = getUnoTypeForSbxValue( pVar );
    TypeClass eType = aType.getTypeClass();

	if( !bBlockConversionToSmallestType )
	{
		// #79615 Choose "smallest" represention for int values
		// because up cast is allowed, downcast not
		switch( eType )
		{
			case TypeClass_FLOAT:
			case TypeClass_DOUBLE:
			{
				double d = pVar->GetDouble();
				if( d == floor( d ) )
				{
					if( d >= -128 && d <= 127 )
						aType = ::getCppuType( (sal_Int8*)0 );
					else if( d >= SbxMININT && d <= SbxMAXINT )
						aType = ::getCppuType( (sal_Int16*)0 );
					else if( d >= -SbxMAXLNG && d <= SbxMAXLNG )
						aType = ::getCppuType( (sal_Int32*)0 );
				}
				break;
			}
			case TypeClass_SHORT:
			{
				sal_Int16 n = pVar->GetInteger();
				if( n >= -128 && n <= 127 )
					aType = ::getCppuType( (sal_Int8*)0 );
				break;
			}
			case TypeClass_LONG:
			{
				sal_Int32 n = pVar->GetLong();
				if( n >= -128 && n <= 127 )
					aType = ::getCppuType( (sal_Int8*)0 );
				else if( n >= SbxMININT && n <= SbxMAXINT )
					aType = ::getCppuType( (sal_Int16*)0 );
				break;
			}
			case TypeClass_UNSIGNED_SHORT:
			{
				sal_uInt16 n = pVar->GetUShort();
				if( n <= 255 )
					aType = ::getCppuType( (sal_uInt8*)0 );
				break;
			}
			case TypeClass_UNSIGNED_LONG:
			{
				sal_uInt32 n = pVar->GetLong();
				if( n <= 255 )
					aType = ::getCppuType( (sal_uInt8*)0 );
				else if( n <= SbxMAXUINT )
					aType = ::getCppuType( (sal_uInt16*)0 );
				break;
			}
			default: break;
		}
	}

	return sbxToUnoValue( pVar, aType );
}



// Helper function for StepREDIMP
static Any implRekMultiDimArrayToSequence( SbxDimArray* pArray,
	const Type& aElemType, short nMaxDimIndex, short nActualDim,
	sal_Int32* pActualIndices, sal_Int32* pLowerBounds, sal_Int32* pUpperBounds )
{
	sal_Int32 nSeqLevel = nMaxDimIndex - nActualDim + 1;
	::rtl::OUString aSeqTypeName;
	sal_Int32 i;
	for( i = 0 ; i < nSeqLevel ; i++ )
		aSeqTypeName += aSeqLevelStr;

	aSeqTypeName += aElemType.getTypeName();
	Type aSeqType( TypeClass_SEQUENCE, aSeqTypeName );

	// Create Sequence instance
	Any aRetVal;
	Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( aSeqType );
	xIdlTargetClass->createObject( aRetVal );

	// Alloc sequence according to array bounds
	sal_Int32 nUpper = pUpperBounds[nActualDim];
	sal_Int32 nLower = pLowerBounds[nActualDim];
	sal_Int32 nSeqSize = nUpper - nLower + 1;
	Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
	xArray->realloc( aRetVal, nSeqSize );

	sal_Int32& ri = pActualIndices[nActualDim];

	for( ri = nLower,i = 0 ; ri <= nUpper ; ri++,i++ )
	{
		Any aElementVal;

		if( nActualDim < nMaxDimIndex )
		{
			aElementVal = implRekMultiDimArrayToSequence( pArray, aElemType,
				nMaxDimIndex, nActualDim + 1, pActualIndices, pLowerBounds, pUpperBounds );
		}
		else
		{
			SbxVariable* pSource = pArray->Get32( pActualIndices );
			aElementVal = sbxToUnoValue( pSource, aElemType );
		}

		try
		{
			// In die Sequence uebernehmen
			xArray->set( aRetVal, i, aElementVal );
		}
		catch( const IllegalArgumentException& )
		{
			StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
				implGetExceptionMsg( ::cppu::getCaughtException() ) );
		}
		catch (IndexOutOfBoundsException&)
		{
			StarBASIC::Error( SbERR_OUT_OF_RANGE );
		}
	}
	return aRetVal;
}

// Map old interface
Any sbxToUnoValue( SbxVariable* pVar )
{
	return sbxToUnoValueImpl( pVar );
}


// Funktion, um einen globalen Bezeichner im
// UnoScope zu suchen und fuer Sbx zu wrappen
static bool implGetTypeByName( const String& rName, Type& rRetType )
{
	bool bSuccess = false;

    Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    if( xTypeAccess->hasByHierarchicalName( rName ) )
    {
        Any aRet = xTypeAccess->getByHierarchicalName( rName );
		Reference< XTypeDescription > xTypeDesc;
		aRet >>= xTypeDesc;

        if( xTypeDesc.is() )
        {
			rRetType = Type( xTypeDesc->getTypeClass(), xTypeDesc->getName() );
			bSuccess = true;
        }
    }
	return bSuccess;
}


// Konvertierung von Sbx nach Uno mit bekannter Zielklasse
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty )
{
	Any aRetVal;

	// #94560 No conversion of empty/void for MAYBE_VOID properties
	if( pUnoProperty && pUnoProperty->Attributes & PropertyAttribute::MAYBEVOID )
	{
		if( pVar->IsEmpty() )
			return aRetVal;
	}

	SbxDataType eBaseType = pVar->SbxValue::GetType();
	if( eBaseType == SbxOBJECT )
    {
		SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
		if( xObj.Is() && xObj->ISA(SbUnoAnyObject) )
        {
            return ((SbUnoAnyObject*)(SbxBase*)xObj)->getValue();
        }
    }

    TypeClass eType = rType.getTypeClass();
	switch( eType )
	{
		case TypeClass_INTERFACE:
		case TypeClass_STRUCT:
		case TypeClass_EXCEPTION:
		{
			Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );

			// Null-Referenz?
			if( pVar->IsNull() && eType == TypeClass_INTERFACE )
			{
				Reference< XInterface > xRef;
				::rtl::OUString aClassName = xIdlTargetClass->getName();
				Type aClassType( xIdlTargetClass->getTypeClass(), aClassName.getStr() );
				aRetVal.setValue( &xRef, aClassType );
			}
			else
			{
				// #112368 Special conversion for Decimal, Currency and Date
				if( eType == TypeClass_STRUCT )
				{
					SbiInstance* pInst = pINST;
					if( pInst && pInst->IsCompatibility() )
					{
						if( rType == ::getCppuType( (oleautomation::Decimal*)0 ) )
						{
							oleautomation::Decimal aDecimal;
							pVar->fillAutomationDecimal( aDecimal );
							aRetVal <<= aDecimal;
							break;
						}
						else if( rType == ::getCppuType( (oleautomation::Currency*)0 ) )
						{
							SbxINT64 aInt64 = pVar->GetCurrency();
							oleautomation::Currency aCurrency;
							sal_Int64& rnValue64 = aCurrency.Value;
							rnValue64 = aInt64.nHigh;
							rnValue64 <<= 32;
							rnValue64 |= aInt64.nLow;
							aRetVal <<= aCurrency;
							break;
						}
						else if( rType == ::getCppuType( (oleautomation::Date*)0 ) )
						{
							oleautomation::Date aDate;
							aDate.Value = pVar->GetDate();
							aRetVal <<= aDate;
							break;
						}
					}
				}

				SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
				if( pObj && pObj->ISA(SbUnoObject) )
				{
					aRetVal = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
				}
				else
				{
					// #109936 NULL object -> NULL XInterface
					Reference<XInterface> xInt;
					aRetVal <<= xInt;
				}
			}
		}
		break;

		case TypeClass_TYPE:
		{
			if( eBaseType == SbxOBJECT )
			{
				// XIdlClass?
				Reference< XIdlClass > xIdlClass;

				SbxBaseRef pObj = (SbxBase*)pVar->GetObject();
				if( pObj && pObj->ISA(SbUnoObject) )
				{
					Any aUnoAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
					aUnoAny >>= xIdlClass;
				}

				if( xIdlClass.is() )
				{
					::rtl::OUString aClassName = xIdlClass->getName();
					Type aType( xIdlClass->getTypeClass(), aClassName.getStr() );
					aRetVal <<= aType;
				}
			}
			else if( eBaseType == SbxSTRING )
			{
				// String representing type?
				String aTypeName = pVar->GetString();
				Type aType;
				bool bSuccess = implGetTypeByName( aTypeName, aType );
				if( bSuccess )
					aRetVal <<= aType;
			}
		}
		break;

		/* folgende Typen lassen wir erstmal weg
		case TypeClass_SERVICE:			break;
		case TypeClass_CLASS:			break;
		case TypeClass_TYPEDEF:			break;
		case TypeClass_UNION:			break;
		case TypeClass_ENUM:			break;
		case TypeClass_ARRAY:			break;
		*/

		// Array -> Sequence
		case TypeClass_ENUM:
		{
			aRetVal = int2enum( pVar->GetLong(), rType );
		}
		break;

		case TypeClass_SEQUENCE:
		{
			SbxBaseRef xObj = (SbxBase*)pVar->GetObject();
			if( xObj && xObj->ISA(SbxDimArray) )
			{
				SbxBase* pObj = (SbxBase*)xObj;
				SbxDimArray* pArray = (SbxDimArray*)pObj;

				short nDims = pArray->GetDims();

				// Normal case: One dimensional array
				sal_Int32 nLower, nUpper;
				if( nDims == 1 && pArray->GetDim32( 1, nLower, nUpper ) )
				{
					sal_Int32 nSeqSize = nUpper - nLower + 1;

					// Instanz der geforderten Sequence erzeugen
					Reference< XIdlClass > xIdlTargetClass = TypeToIdlClass( rType );
					xIdlTargetClass->createObject( aRetVal );
					Reference< XIdlArray > xArray = xIdlTargetClass->getArray();
					xArray->realloc( aRetVal, nSeqSize );

					// Element-Type
					::rtl::OUString aClassName = xIdlTargetClass->getName();
					typelib_TypeDescription * pSeqTD = 0;
					typelib_typedescription_getByName( &pSeqTD, aClassName.pData );
					OSL_ASSERT( pSeqTD );
					Type aElemType( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
					// Reference< XIdlClass > xElementClass = TypeToIdlClass( aElemType );

					// Alle Array-Member umwandeln und eintragen
					sal_Int32 nIdx = nLower;
					for( sal_Int32 i = 0 ; i < nSeqSize ; i++,nIdx++ )
					{
						SbxVariableRef xVar = pArray->Get32( &nIdx );

						// Wert von Sbx nach Uno wandeln
						Any aAnyValue = sbxToUnoValue( (SbxVariable*)xVar, aElemType );

						try
						{
							// In die Sequence uebernehmen
							xArray->set( aRetVal, i, aAnyValue );
						}
						catch( const IllegalArgumentException& )
						{
							StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
                                implGetExceptionMsg( ::cppu::getCaughtException() ) );
						}
						catch (IndexOutOfBoundsException&)
						{
							StarBASIC::Error( SbERR_OUT_OF_RANGE );
						}
					}
				}
				// #i33795 Map also multi dimensional arrays to corresponding sequences
				else if( nDims > 1 )
				{
					// Element-Type
					typelib_TypeDescription * pSeqTD = 0;
					Type aCurType( rType );
					sal_Int32 nSeqLevel = 0;
					Type aElemType;
					do
					{
						::rtl::OUString aTypeName = aCurType.getTypeName();
						typelib_typedescription_getByName( &pSeqTD, aTypeName.pData );
						OSL_ASSERT( pSeqTD );
						if( pSeqTD->eTypeClass == typelib_TypeClass_SEQUENCE )
						{
							aCurType = Type( ((typelib_IndirectTypeDescription *)pSeqTD)->pType );
							nSeqLevel++;
						}
						else
						{
							aElemType = aCurType;
							break;
						}
					}
					while( true );

					if( nSeqLevel == nDims )
					{
						sal_Int32* pLowerBounds = new sal_Int32[nDims];
						sal_Int32* pUpperBounds = new sal_Int32[nDims];
						sal_Int32* pActualIndices = new sal_Int32[nDims];
						for( short i = 1 ; i <= nDims ; i++ )
						{
							sal_Int32 lBound, uBound;
							pArray->GetDim32( i, lBound, uBound );

							short j = i - 1;
							pActualIndices[j] = pLowerBounds[j] = lBound;
							pUpperBounds[j] = uBound;
						}

						aRetVal = implRekMultiDimArrayToSequence( pArray, aElemType,
							nDims - 1, 0, pActualIndices, pLowerBounds, pUpperBounds );

						delete[] pUpperBounds;
						delete[] pLowerBounds;
						delete[] pActualIndices;
					}
				}
			}
		}
		break;

		/*
		case TypeClass_VOID:			break;
		case TypeClass_UNKNOWN:			break;
		*/

		// Bei Any die Klassen-unabhaengige Konvertierungs-Routine nutzen
		case TypeClass_ANY:
		{
			aRetVal = sbxToUnoValueImpl( pVar );
		}
		break;

		case TypeClass_BOOLEAN:
		{
			sal_Bool b = pVar->GetBool();
			aRetVal.setValue( &b, getBooleanCppuType() );
			break;
		}
		case TypeClass_CHAR:
		{
			sal_Unicode c = pVar->GetChar();
			aRetVal.setValue( &c , getCharCppuType() );
			break;
		}
		case TypeClass_STRING:			aRetVal <<= pVar->GetOUString(); break;
		case TypeClass_FLOAT:			aRetVal <<= pVar->GetSingle(); break;
		case TypeClass_DOUBLE:			aRetVal <<= pVar->GetDouble(); break;
		//case TypeClass_OCTET:			break;

		case TypeClass_BYTE:
        {
            sal_Int16 nVal = pVar->GetInteger();
            sal_Bool bOverflow = sal_False;
            if( nVal < -128 )
            {
                bOverflow = sal_True;
                nVal = -128;
            }
            else if( nVal > 127 )
            {
                bOverflow = sal_True;
                nVal = 127;
            }
            if( bOverflow )
           		StarBASIC::Error( ERRCODE_BASIC_MATH_OVERFLOW );

            sal_Int8 nByteVal = (sal_Int8)nVal;
            aRetVal <<= nByteVal;
            break;
        }
		//case TypeClass_INT:			break;
		case TypeClass_SHORT:			aRetVal <<= (sal_Int16)( pVar->GetInteger() );	break;
		case TypeClass_LONG:			aRetVal <<= (sal_Int32)( pVar->GetLong() );     break;
		case TypeClass_HYPER:			aRetVal <<= (sal_Int64)( pVar->GetInt64() );    break;
		//case TypeClass_UNSIGNED_OCTET:break;
		case TypeClass_UNSIGNED_SHORT:	aRetVal <<= (sal_uInt16)( pVar->GetUShort() );	break;
		case TypeClass_UNSIGNED_LONG:	aRetVal <<= (sal_uInt32)( pVar->GetULong() );	break;
		case TypeClass_UNSIGNED_HYPER:  aRetVal <<= (sal_uInt64)( pVar->GetUInt64() );  break;
		//case TypeClass_UNSIGNED_INT:	break;
		//case TypeClass_UNSIGNED_BYTE:	break;
		default: break;
	}

	return aRetVal;
}

// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
String Impl_GetInterfaceInfo( const Reference< XInterface >& x, const Reference< XIdlClass >& xClass, sal_uInt16 nRekLevel )
{
	Type aIfaceType = ::getCppuType( (const Reference< XInterface > *)0 );
	static Reference< XIdlClass > xIfaceClass = TypeToIdlClass( aIfaceType );

	String aRetStr;
	for( sal_uInt16 i = 0 ; i < nRekLevel ; i++ )
		aRetStr.AppendAscii( "    " );
	aRetStr += String( xClass->getName() );
	::rtl::OUString aClassName = xClass->getName();
	Type aClassType( xClass->getTypeClass(), aClassName.getStr() );

	// Pruefen, ob das Interface wirklich unterstuetzt wird
	if( !x->queryInterface( aClassType ).hasValue() )
	{
		aRetStr.AppendAscii( " (ERROR: Not really supported!)\n" );
	}
	// Gibt es Super-Interfaces
	else
	{
		aRetStr.AppendAscii( "\n" );

		// Super-Interfaces holen
		Sequence< Reference< XIdlClass > > aSuperClassSeq = xClass->getSuperclasses();
		const Reference< XIdlClass >* pClasses = aSuperClassSeq.getConstArray();
		sal_uInt32 nSuperIfaceCount = aSuperClassSeq.getLength();
		for( sal_uInt32 j = 0 ; j < nSuperIfaceCount ; j++ )
		{
			const Reference< XIdlClass >& rxIfaceClass = pClasses[j];
			if( !rxIfaceClass->equals( xIfaceClass ) )
				aRetStr += Impl_GetInterfaceInfo( x, rxIfaceClass, nRekLevel + 1 );
		}
	}
	return aRetStr;
}

String getDbgObjectNameImpl( SbUnoObject* pUnoObj )
{
	String aName;
	if( pUnoObj )
	{
		aName = pUnoObj->GetClassName();
		if( !aName.Len() )
		{
			Any aToInspectObj = pUnoObj->getUnoAny();
			TypeClass eType = aToInspectObj.getValueType().getTypeClass();
			Reference< XInterface > xObj;
			if( eType == TypeClass_INTERFACE )
				xObj = *(Reference< XInterface >*)aToInspectObj.getValue();
			if( xObj.is() )
			{
				Reference< XServiceInfo > xServiceInfo( xObj, UNO_QUERY );
				if( xServiceInfo.is() )
					aName = xServiceInfo->getImplementationName();
			}
		}
	}
	return aName;
}

String getDbgObjectName( SbUnoObject* pUnoObj )
{
	String aName = getDbgObjectNameImpl( pUnoObj );
	if( !aName.Len() )
		aName.AppendAscii( "Unknown" );

	String aRet;
	if( aName.Len() > 20 )
		aRet.AppendAscii( "\n" );
	aRet.AppendAscii( "\"" );
	aRet += aName;
	aRet.AppendAscii( "\":" );
	return aRet;
}

String getBasicObjectTypeName( SbxObject* pObj )
{
	String aName;
	if( pObj )
	{
		SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
		if( pUnoObj )
			aName = getDbgObjectNameImpl( pUnoObj );
	}
	return aName;
}

bool checkUnoObjectType( SbUnoObject* pUnoObj, const ::rtl::OUString& rClass )
{
	Any aToInspectObj = pUnoObj->getUnoAny();
	TypeClass eType = aToInspectObj.getValueType().getTypeClass();
	if( eType != TypeClass_INTERFACE )
		return false;
	const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();

	// Return true for XInvocation based objects as interface type names don't count then
	Reference< XInvocation > xInvocation( x, UNO_QUERY );
	if( xInvocation.is() )
		return true;

	bool result = false;
	Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );
	if( xTypeProvider.is() )
	{
        /*  Although interfaces in the ooo.vba namespace obey the IDL rules and
            have a leading 'X', in Basic we want to be able to do something
            like 'Dim wb As Workbooks' or 'Dim lb As MSForms.Label'. Here we
            add a leading 'X' to the class name and a leading dot to the entire
            type name. This results e.g. in '.XWorkbooks' or '.MSForms.XLabel'
            which matches the interface names 'ooo.vba.excel.XWorkbooks' or
            'ooo.vba.msforms.XLabel'.
         */
        ::rtl::OUString aClassName( sal_Unicode( '.' ) );
        sal_Int32 nClassNameDot = rClass.lastIndexOf( '.' );
        if( nClassNameDot >= 0 )
            aClassName += rClass.copy( 0, nClassNameDot + 1 ) + ::rtl::OUString( sal_Unicode( 'X' ) ) + rClass.copy( nClassNameDot + 1 );
        else
            aClassName += ::rtl::OUString( sal_Unicode( 'X' ) ) + rClass;

		Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
		const Type* pTypeArray = aTypeSeq.getConstArray();
		sal_uInt32 nIfaceCount = aTypeSeq.getLength();
		for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
		{
			const Type& rType = pTypeArray[j];

			Reference<XIdlClass> xClass = TypeToIdlClass( rType );
			if( !xClass.is() )
			{
				DBG_ERROR("failed to get XIdlClass for type");
				break;
			}
			::rtl::OUString aInterfaceName = xClass->getName();
			if ( aInterfaceName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.oleautomation.XAutomationObject" ) ) ) )
			{
				// there is a hack in the extensions/source/ole/oleobj.cxx  to return the typename of the automation object, lets check if it
				// matches
				Reference< XInvocation > xInv( aToInspectObj, UNO_QUERY );
				if ( xInv.is() )
				{
					rtl::OUString sTypeName;
					xInv->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("$GetTypeName") ) ) >>= sTypeName;
					if ( sTypeName.isEmpty() || sTypeName.equals(  rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("IDispatch") ) ) )
						// can't check type, leave it pass
						result = true;
					else
						result = sTypeName.equals( rClass );
				}
				break; // finished checking automation object
			}

            // match interface name with passed class name
			OSL_TRACE("Checking if object implements %s", OUStringToOString( aClassName, RTL_TEXTENCODING_UTF8 ).getStr() );
			if ( (aClassName.getLength() < aInterfaceName.getLength()) &&
                    aInterfaceName.matchIgnoreAsciiCase( aClassName, aInterfaceName.getLength() - aClassName.getLength() ) )
			{
				result = true;
				break;
			}
		}
	}
	return result;
}

// Dbg-Hilfsmethode zum Auslesen der in einem Object implementierten Interfaces
String Impl_GetSupportedInterfaces( SbUnoObject* pUnoObj )
{
	Any aToInspectObj = pUnoObj->getUnoAny();

	// #54898: Nur TypeClass Interface zulasssen
	TypeClass eType = aToInspectObj.getValueType().getTypeClass();
	String aRet;
	if( eType != TypeClass_INTERFACE )
	{
		aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM(ID_DBG_SUPPORTEDINTERFACES) );
		aRet.AppendAscii( " not available.\n(TypeClass is not TypeClass_INTERFACE)\n" );
	}
	else
	{
		// Interface aus dem Any besorgen
		const Reference< XInterface > x = *(Reference< XInterface >*)aToInspectObj.getValue();

		// XIdlClassProvider-Interface ansprechen
		Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
		Reference< XTypeProvider > xTypeProvider( x, UNO_QUERY );

		aRet.AssignAscii( "Supported interfaces by object " );
		String aObjName = getDbgObjectName( pUnoObj );
		aRet += aObjName;
		aRet.AppendAscii( "\n" );
		if( xTypeProvider.is() )
		{
			// Interfaces der Implementation holen
			Sequence< Type > aTypeSeq = xTypeProvider->getTypes();
			const Type* pTypeArray = aTypeSeq.getConstArray();
			sal_uInt32 nIfaceCount = aTypeSeq.getLength();
			for( sal_uInt32 j = 0 ; j < nIfaceCount ; j++ )
			{
				const Type& rType = pTypeArray[j];

                Reference<XIdlClass> xClass = TypeToIdlClass( rType );
                if( xClass.is() )
                {
				    aRet += Impl_GetInterfaceInfo( x, xClass, 1 );
                }
                else
                {
	                typelib_TypeDescription * pTD = 0;
	                rType.getDescription( &pTD );
	                String TypeName( ::rtl::OUString( pTD->pTypeName ) );

                    aRet.AppendAscii( "*** ERROR: No IdlClass for type \"" );
                    aRet += TypeName;
                    aRet.AppendAscii( "\"\n*** Please check type library\n" );
                }
			}
		}
		else if( xClassProvider.is() )
		{

			DBG_ERROR( "XClassProvider not supported in UNO3" );
		}
	}
	return aRet;
}



// Dbg-Hilfsmethode SbxDataType -> String
String Dbg_SbxDataType2String( SbxDataType eType )
{
	String aRet( RTL_CONSTASCII_USTRINGPARAM("Unknown Sbx-Type!") );
	switch( +eType )
	{
		case SbxEMPTY:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxEMPTY") ); break;
		case SbxNULL:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxNULL") ); break;
		case SbxINTEGER:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINTEGER") ); break;
		case SbxLONG:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG") ); break;
		case SbxSINGLE:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSINGLE") ); break;
		case SbxDOUBLE:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDOUBLE") ); break;
		case SbxCURRENCY:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCURRENCY") ); break;
		case SbxDECIMAL:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDECIMAL") ); break;
		case SbxDATE:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATE") ); break;
		case SbxSTRING:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxSTRING") ); break;
		case SbxOBJECT:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxOBJECT") ); break;
		case SbxERROR:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxERROR") ); break;
		case SbxBOOL:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBOOL") ); break;
		case SbxVARIANT:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVARIANT") ); break;
		case SbxDATAOBJECT: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDATAOBJECT") ); break;
		case SbxCHAR:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCHAR") ); break;
		case SbxBYTE:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxBYTE") ); break;
		case SbxUSHORT:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSHORT") ); break;
		case SbxULONG:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG") ); break;
		case SbxLONG64:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLONG64") ); break;
		case SbxULONG64:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxULONG64") ); break;
		case SbxSALINT64:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT64") ); break;
		case SbxSALUINT64:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT64") ); break;
		case SbxINT:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxINT") ); break;
		case SbxUINT:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUINT") ); break;
		case SbxVOID:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxVOID") ); break;
		case SbxHRESULT:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxHRESULT") ); break;
		case SbxPOINTER:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxPOINTER") ); break;
		case SbxDIMARRAY:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxDIMARRAY") ); break;
		case SbxCARRAY:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCARRAY") ); break;
		case SbxUSERDEF:	aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxUSERDEF") ); break;
		case SbxLPSTR:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPSTR") ); break;
		case SbxLPWSTR:		aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxLPWSTR") ); break;
		case SbxCoreSTRING: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxCoreSTRING" ) ); break;
		case SbxOBJECT | SbxARRAY: aRet = String( RTL_CONSTASCII_USTRINGPARAM("SbxARRAY") ); break;
		default: break;
	}
	return aRet;
}

// Dbg-Hilfsmethode zum Anzeigen der Properties eines SbUnoObjects
String Impl_DumpProperties( SbUnoObject* pUnoObj )
{
	String aRet( RTL_CONSTASCII_USTRINGPARAM("Properties of object ") );
	String aObjName = getDbgObjectName( pUnoObj );
	aRet += aObjName;

	// Uno-Infos auswerten, um Arrays zu erkennen
	Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
	if( !xAccess.is() )
	{
		Reference< XInvocation > xInvok = pUnoObj->getInvocation();
		if( xInvok.is() )
			xAccess = xInvok->getIntrospection();
	}
	if( !xAccess.is() )
	{
		aRet.AppendAscii( "\nUnknown, no introspection available\n" );
		return aRet;
	}

	Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
	sal_uInt32 nUnoPropCount = props.getLength();
	const Property* pUnoProps = props.getConstArray();

	SbxArray* pProps = pUnoObj->GetProperties();
	sal_uInt16 nPropCount = pProps->Count();
	sal_uInt16 nPropsPerLine = 1 + nPropCount / 30;
	for( sal_uInt16 i = 0; i < nPropCount; i++ )
	{
		SbxVariable* pVar = pProps->Get( i );
		if( pVar )
		{
			String aPropStr;
			if( (i % nPropsPerLine) == 0 )
				aPropStr.AppendAscii( "\n" );

			// Typ und Namen ausgeben
			// Ist es in Uno eine Sequence?
			SbxDataType eType = pVar->GetFullType();

			sal_Bool bMaybeVoid = sal_False;
			if( i < nUnoPropCount )
			{
				const Property& rProp = pUnoProps[ i ];

				// #63133: Bei MAYBEVOID Typ aus Uno neu konvertieren,
				// damit nicht immer nur SbxEMPTY ausgegben wird.
				if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
				{
					eType = unoToSbxType( rProp.Type.getTypeClass() );
					bMaybeVoid = sal_True;
				}
				if( eType == SbxOBJECT )
				{
					Type aType = rProp.Type;
					if( aType.getTypeClass() == TypeClass_SEQUENCE )
						eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
				}
			}
			aPropStr += Dbg_SbxDataType2String( eType );
			if( bMaybeVoid )
				aPropStr.AppendAscii( "/void" );
			aPropStr.AppendAscii( " " );
			aPropStr += pVar->GetName();

			if( i == nPropCount - 1 )
				aPropStr.AppendAscii( "\n" );
			else
				aPropStr.AppendAscii( "; " );

			aRet += aPropStr;
		}
	}
	return aRet;
}

// Dbg-Hilfsmethode zum Anzeigen der Methoden eines SbUnoObjects
String Impl_DumpMethods( SbUnoObject* pUnoObj )
{
	String aRet( RTL_CONSTASCII_USTRINGPARAM("Methods of object ") );
	String aObjName = getDbgObjectName( pUnoObj );
	aRet += aObjName;

	// XIntrospectionAccess, um die Typen der Parameter auch ausgeben zu koennen
	Reference< XIntrospectionAccess > xAccess = pUnoObj->getIntrospectionAccess();
	if( !xAccess.is() )
	{
		Reference< XInvocation > xInvok = pUnoObj->getInvocation();
		if( xInvok.is() )
			xAccess = xInvok->getIntrospection();
	}
	if( !xAccess.is() )
	{
		aRet.AppendAscii( "\nUnknown, no introspection available\n" );
		return aRet;
	}
	Sequence< Reference< XIdlMethod > > methods = xAccess->getMethods
		( MethodConcept::ALL - MethodConcept::DANGEROUS );
	const Reference< XIdlMethod >* pUnoMethods = methods.getConstArray();

	SbxArray* pMethods = pUnoObj->GetMethods();
	sal_uInt16 nMethodCount = pMethods->Count();
	if( !nMethodCount )
	{
		aRet.AppendAscii( "\nNo methods found\n" );
		return aRet;
	}
	sal_uInt16 nPropsPerLine = 1 + nMethodCount / 30;
	for( sal_uInt16 i = 0; i < nMethodCount; i++ )
	{
		SbxVariable* pVar = pMethods->Get( i );
		if( pVar )
		{
			String aPropStr;
			if( (i % nPropsPerLine) == 0 )
				aPropStr.AppendAscii( "\n" );

			// Methode ansprechen
			const Reference< XIdlMethod >& rxMethod = pUnoMethods[i];

			// Ist es in Uno eine Sequence?
			SbxDataType eType = pVar->GetFullType();
			if( eType == SbxOBJECT )
			{
				Reference< XIdlClass > xClass = rxMethod->getReturnType();
				if( xClass.is() && xClass->getTypeClass() == TypeClass_SEQUENCE )
					eType = (SbxDataType) ( SbxOBJECT | SbxARRAY );
			}
			// Name und Typ ausgeben
			aPropStr += Dbg_SbxDataType2String( eType );
			aPropStr.AppendAscii( " " );
			aPropStr += pVar->GetName();
			aPropStr.AppendAscii( " ( " );

			// get-Methode darf keinen Parameter haben
			Sequence< Reference< XIdlClass > > aParamsSeq = rxMethod->getParameterTypes();
			sal_uInt32 nParamCount = aParamsSeq.getLength();
			const Reference< XIdlClass >* pParams = aParamsSeq.getConstArray();

			if( nParamCount > 0 )
			{
				for( sal_uInt16 j = 0; j < nParamCount; j++ )
				{
					String aTypeStr = Dbg_SbxDataType2String( unoToSbxType( pParams[ j ] ) );
					aPropStr += aTypeStr;

					if( j < nParamCount - 1 )
						aPropStr.AppendAscii( ", " );
				}
			}
			else
				aPropStr.AppendAscii( "void" );

			aPropStr.AppendAscii( " ) " );

			if( i == nMethodCount - 1 )
				aPropStr.AppendAscii( "\n" );
			else
				aPropStr.AppendAscii( "; " );

			aRet += aPropStr;
		}
	}
	return aRet;
}

TYPEINIT1(AutomationNamedArgsSbxArray,SbxArray)

// Implementation SbUnoObject
void SbUnoObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
						   const SfxHint& rHint, const TypeId& rHintType )
{
	if( bNeedIntrospection )
		doIntrospection();

	const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
	if( pHint )
	{
		SbxVariable* pVar = pHint->GetVar();
		SbxArray* pParams = pVar->GetParameters();
		SbUnoProperty* pProp = PTR_CAST(SbUnoProperty,pVar);
		SbUnoMethod* pMeth = PTR_CAST(SbUnoMethod,pVar);
		if( pProp )
		{
			bool bInvocation = pProp->isInvocationBased();
			if( pHint->GetId() == SBX_HINT_DATAWANTED )
			{
				// Test-Properties
				sal_Int32 nId = pProp->nId;
				if( nId < 0 )
				{
					// Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
					if( nId == -1 )		// Property ID_DBG_SUPPORTEDINTERFACES"
					{
						String aRetStr = Impl_GetSupportedInterfaces( this );
						pVar->PutString( aRetStr );
					}
					// Id == -2: Properties ausgeben
					else if( nId == -2 )		// Property ID_DBG_PROPERTIES
					{
						// Jetzt muessen alle Properties angelegt werden
						implCreateAll();
						String aRetStr = Impl_DumpProperties( this );
						pVar->PutString( aRetStr );
					}
					// Id == -3: Methoden ausgeben
					else if( nId == -3 )		// Property ID_DBG_METHODS
					{
						// Jetzt muessen alle Properties angelegt werden
						implCreateAll();
						String aRetStr = Impl_DumpMethods( this );
						pVar->PutString( aRetStr );
					}
					return;
				}

				if( !bInvocation && mxUnoAccess.is() )
				{
					try
					{
						// Wert holen
						Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
						Any aRetAny = xPropSet->getPropertyValue( pProp->GetName() );
						// Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
						// nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
						// Ansonsten kann auch FastPropertySet genutzt werden

						// Wert von Uno nach Sbx uebernehmen
						unoToSbxValue( pVar, aRetAny );
					}
					catch( const Exception& )
					{
                        implHandleAnyException( ::cppu::getCaughtException() );
					}
				}
				else if( bInvocation && mxInvocation.is() )
				{
					try
					{
						// Wert holen
						Any aRetAny = mxInvocation->getValue( pProp->GetName() );

						// Wert von Uno nach Sbx uebernehmen
						unoToSbxValue( pVar, aRetAny );
					}
					catch( const Exception& )
					{
                        implHandleAnyException( ::cppu::getCaughtException() );
					}
				}
			}
			else if( pHint->GetId() == SBX_HINT_DATACHANGED )
			{
				if( !bInvocation && mxUnoAccess.is() )
				{
					if( pProp->aUnoProp.Attributes & PropertyAttribute::READONLY )
					{
						StarBASIC::Error( SbERR_PROP_READONLY );
						return;
					}

					// Wert von Uno nach Sbx uebernehmen
					Any aAnyValue = sbxToUnoValue( pVar, pProp->aUnoProp.Type, &pProp->aUnoProp );
					try
					{
						// Wert setzen
						Reference< XPropertySet > xPropSet( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
						xPropSet->setPropertyValue( pProp->GetName(), aAnyValue );
						// Die Nutzung von getPropertyValue (statt ueber den Index zu gehen) ist
						// nicht optimal, aber die Umstellung auf XInvocation steht ja ohnehin an
						// Ansonsten kann auch FastPropertySet genutzt werden
					}
					catch( const Exception& )
					{
                        implHandleAnyException( ::cppu::getCaughtException() );
					}
				}
				else if( bInvocation && mxInvocation.is() )
				{
					// Wert von Uno nach Sbx uebernehmen
					Any aAnyValue = sbxToUnoValueImpl( pVar );
					try
					{
						// Wert setzen
						mxInvocation->setValue( pProp->GetName(), aAnyValue );
					}
					catch( const Exception& )
					{
                        implHandleAnyException( ::cppu::getCaughtException() );
					}
				}
			}
		}
		else if( pMeth )
		{
			bool bInvocation = pMeth->isInvocationBased();
			if( pHint->GetId() == SBX_HINT_DATAWANTED )
			{
				// Anzahl Parameter -1 wegen Param0 == this
				sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
				Sequence<Any> args;
				sal_Bool bOutParams = sal_False;
				sal_uInt32 i;

				if( !bInvocation && mxUnoAccess.is() )
				{
					// Infos holen
					const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
					const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
					sal_uInt32 nUnoParamCount = rInfoSeq.getLength();
					sal_uInt32 nAllocParamCount = nParamCount;

					// Ueberschuessige Parameter ignorieren, Alternative: Error schmeissen
					if( nParamCount > nUnoParamCount )
					{
						nParamCount = nUnoParamCount;
						nAllocParamCount = nParamCount;
					}
					else if( nParamCount < nUnoParamCount )
					{
						SbiInstance* pInst = pINST;
						if( pInst && pInst->IsCompatibility() )
						{
							// Check types
							bool bError = false;
							for( i = nParamCount ; i < nUnoParamCount ; i++ )
							{
								const ParamInfo& rInfo = pParamInfos[i];
								const Reference< XIdlClass >& rxClass = rInfo.aType;
								if( rxClass->getTypeClass() != TypeClass_ANY )
								{
									bError = true;
									StarBASIC::Error( SbERR_NOT_OPTIONAL );
								}
							}
							if( !bError )
								nAllocParamCount = nUnoParamCount;
						}
					}

					if( nAllocParamCount > 0 )
					{
						args.realloc( nAllocParamCount );
						Any* pAnyArgs = args.getArray();
						for( i = 0 ; i < nParamCount ; i++ )
						{
							const ParamInfo& rInfo = pParamInfos[i];
							const Reference< XIdlClass >& rxClass = rInfo.aType;
							//const XIdlClassRef& rxClass = pUnoParams[i];

							com::sun::star::uno::Type aType( rxClass->getTypeClass(), rxClass->getName() );

							// ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
							pAnyArgs[i] = sbxToUnoValue( pParams->Get( (sal_uInt16)(i+1) ), aType );

							// Wenn es nicht schon feststeht pruefen, ob Out-Parameter vorliegen
							if( !bOutParams )
							{
								ParamMode aParamMode = rInfo.aMode;
								if( aParamMode != ParamMode_IN )
									bOutParams = sal_True;
							}
						}
					}
				}
				else if( bInvocation && pParams && mxInvocation.is() )
				{
					bool bOLEAutomation = true;
					// TODO: bOLEAutomation = xOLEAutomation.is()

					AutomationNamedArgsSbxArray* pArgNamesArray = NULL;
					if( bOLEAutomation )
						pArgNamesArray = PTR_CAST(AutomationNamedArgsSbxArray,pParams);

					args.realloc( nParamCount );
					Any* pAnyArgs = args.getArray();
					bool bBlockConversionToSmallestType = pINST->IsCompatibility();
					if( pArgNamesArray )
					{
						Sequence< ::rtl::OUString >& rNameSeq = pArgNamesArray->getNames();
						::rtl::OUString* pNames = rNameSeq.getArray();

						Any aValAny;
						for( i = 0 ; i < nParamCount ; i++ )
						{
							sal_uInt16 iSbx = (sal_uInt16)(i+1);

							// ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
							aValAny = sbxToUnoValueImpl( pParams->Get( iSbx ),
														bBlockConversionToSmallestType );

							::rtl::OUString aParamName = pNames[iSbx];
							if( !aParamName.isEmpty() )
							{
								oleautomation::NamedArgument aNamedArgument;
								aNamedArgument.Name = aParamName;
								aNamedArgument.Value = aValAny;
								pAnyArgs[i] <<= aNamedArgument;
							}
							else
							{
								pAnyArgs[i] = aValAny;
							}
						}
					}
					else
					{
						for( i = 0 ; i < nParamCount ; i++ )
						{
							// ACHTUNG: Bei den Sbx-Parametern den Offset nicht vergessen!
							pAnyArgs[i] = sbxToUnoValueImpl( pParams->Get( (sal_uInt16)(i+1) ),
															bBlockConversionToSmallestType );
						}
					}
				}

				// Methode callen
                GetSbData()->bBlockCompilerError = sal_True;  // #106433 Block compiler errors for API calls
				try
				{
					if( !bInvocation && mxUnoAccess.is() )
					{
						Any aRetAny = pMeth->m_xUnoMethod->invoke( getUnoAny(), args );

						// Wert von Uno nach Sbx uebernehmen
						unoToSbxValue( pVar, aRetAny );

						// Muessen wir Out-Parameter zurueckkopieren?
						if( bOutParams )
						{
							const Any* pAnyArgs = args.getConstArray();

							// Infos holen
							const Sequence<ParamInfo>& rInfoSeq = pMeth->getParamInfos();
							const ParamInfo* pParamInfos = rInfoSeq.getConstArray();

							sal_uInt32 j;
							for( j = 0 ; j < nParamCount ; j++ )
							{
								const ParamInfo& rInfo = pParamInfos[j];
								ParamMode aParamMode = rInfo.aMode;
								if( aParamMode != ParamMode_IN )
									unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
							}
						}
					}
					else if( bInvocation && mxInvocation.is() )
					{
                        Reference< XDirectInvocation > xDirectInvoke;
                        if ( pMeth->needsDirectInvocation() )
                            xDirectInvoke.set( mxInvocation, UNO_QUERY );

                        Any aRetAny;
                        if ( xDirectInvoke.is() )
                            aRetAny = xDirectInvoke->directInvoke( pMeth->GetName(), args );
                        else
                        {
                            Sequence< sal_Int16 > OutParamIndex;
                            Sequence< Any > OutParam;
                            aRetAny = mxInvocation->invoke( pMeth->GetName(), args, OutParamIndex, OutParam );

                            const sal_Int16* pIndices = OutParamIndex.getConstArray();
                            sal_uInt32 nLen = OutParamIndex.getLength();
                            if( nLen )
                            {
                                const Any* pNewValues = OutParam.getConstArray();
                                for( sal_uInt32 j = 0 ; j < nLen ; j++ )
                                {
                                    sal_Int16 iTarget = pIndices[ j ];
                                    if( iTarget >= (sal_Int16)nParamCount )
                                        break;
                                    unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pNewValues[ j ] );
                                }
                            }
                        }

                        // Wert von Uno nach Sbx uebernehmen
                        unoToSbxValue( pVar, aRetAny );
					}

					// #55460, Parameter hier weghauen, da das in unoToSbxValue()
					// bei Arrays wegen #54548 nicht mehr gemacht wird
					if( pParams )
						pVar->SetParameters( NULL );
				}
				catch( const Exception& )
				{
                    implHandleAnyException( ::cppu::getCaughtException() );
				}
                GetSbData()->bBlockCompilerError = sal_False;  // #106433 Unblock compiler errors
			}
		}
		else
			SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
	}
}


#ifdef INVOCATION_ONLY
// Aus USR
Reference< XInvocation > createDynamicInvocationFor( const Any& aAny );
#endif

SbUnoObject::SbUnoObject( const String& aName_, const Any& aUnoObj_ )
	: SbxObject( aName_ )
	, bNeedIntrospection( sal_True )
	, bNativeCOMObject( sal_False )
{
	static Reference< XIntrospection > xIntrospection;

	// Default-Properties von Sbx wieder rauspruegeln
	Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_DONTCARE );
	Remove( XubString( RTL_CONSTASCII_USTRINGPARAM("Parent") ), SbxCLASS_DONTCARE );

	// Typ des Objekts pruefen
	TypeClass eType = aUnoObj_.getValueType().getTypeClass();
	Reference< XInterface > x;
	if( eType == TypeClass_INTERFACE )
	{
		// Interface aus dem Any besorgen
		x = *(Reference< XInterface >*)aUnoObj_.getValue();
		if( !x.is() )
			return;
	}

	Reference< XTypeProvider > xTypeProvider;
#ifdef INVOCATION_ONLY
	// Invocation besorgen
	mxInvocation = createDynamicInvocationFor( aUnoObj_ );
#else
	// Hat das Object selbst eine Invocation?
	mxInvocation = Reference< XInvocation >( x, UNO_QUERY );

	xTypeProvider = Reference< XTypeProvider >( x, UNO_QUERY );
#endif

	if( mxInvocation.is() )
	{
		// #94670: This is WRONG because then the MaterialHolder doesn't refer
		// to the object implementing XInvocation but to the object passed to
		// the invocation service!!!
		// mxMaterialHolder = Reference< XMaterialHolder >::query( mxInvocation );

		// ExactName holen
		mxExactNameInvocation = Reference< XExactName >::query( mxInvocation );

		// Rest bezieht sich nur auf Introspection
		if( !xTypeProvider.is() )
		{
			bNeedIntrospection = sal_False;
			return;
		}

		// Ignore introspection based members for COM objects to avoid
		// hiding of equally named COM symbols, e.g. XInvocation::getValue
		Reference< oleautomation::XAutomationObject > xAutomationObject( aUnoObj_, UNO_QUERY );
		if( xAutomationObject.is() )
			bNativeCOMObject = sal_True;
	}

	maTmpUnoObj = aUnoObj_;


	//*** Namen bestimmen ***
	sal_Bool bFatalError = sal_True;

	// Ist es ein Interface oder eine struct?
	sal_Bool bSetClassName = sal_False;
	String aClassName_;
	if( eType == TypeClass_STRUCT || eType == TypeClass_EXCEPTION )
	{
		// Struct ist Ok
		bFatalError = sal_False;

		// #67173 Echten Klassen-Namen eintragen
		if( aName_.Len() == 0 )
		{
			aClassName_ = String( aUnoObj_.getValueType().getTypeName() );
			bSetClassName = sal_True;
		}
	}
	else if( eType == TypeClass_INTERFACE )
	{
		// #70197 Interface geht immer durch Typ im Any
		bFatalError = sal_False;

		// Nach XIdlClassProvider-Interface fragen
		Reference< XIdlClassProvider > xClassProvider( x, UNO_QUERY );
		if( xClassProvider.is() )
		{
			// #67173 Echten Klassen-Namen eintragen
			if( aName_.Len() == 0 )
			{
				Sequence< Reference< XIdlClass > > szClasses = xClassProvider->getIdlClasses();
				sal_uInt32 nLen = szClasses.getLength();
				if( nLen )
				{
					const Reference< XIdlClass > xImplClass = szClasses.getConstArray()[ 0 ];
					if( xImplClass.is() )
					{
						aClassName_ = String( xImplClass->getName() );
						bSetClassName = sal_True;
					}
				}
			}
		}
	}
	if( bSetClassName )
		SetClassName( aClassName_ );

	// Weder Interface noch Struct -> FatalError
	if( bFatalError )
	{
		StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
		return;
	}

	// #67781 Introspection erst on demand durchfuehren
}

SbUnoObject::~SbUnoObject()
{
}


// #76470 Introspection on Demand durchfuehren
void SbUnoObject::doIntrospection( void )
{
	static Reference< XIntrospection > xIntrospection;

	if( !bNeedIntrospection )
		return;
	bNeedIntrospection = sal_False;

	if( !xIntrospection.is() )
	{
		// Introspection-Service holen
		Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
		if ( xFactory.is() )
		{
			Reference< XInterface > xI = xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection") );
			if (xI.is())
				xIntrospection = Reference< XIntrospection >::query( xI );
				//xI->queryInterface( ::getCppuType( (const Reference< XIntrospection > *)0 ), xIntrospection );
		}
	}
	if( !xIntrospection.is() )
	{
		StarBASIC::FatalError( ERRCODE_BASIC_EXCEPTION );
		return;
	}

	// Introspection durchfuehren
	try
	{
		mxUnoAccess = xIntrospection->inspect( maTmpUnoObj );
	}
	catch( RuntimeException& e )
	{
        StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
	}

	if( !mxUnoAccess.is() )
	{
		// #51475 Ungueltiges Objekt kennzeichnen (kein mxMaterialHolder)
		return;
	}

	// MaterialHolder vom Access holen
	mxMaterialHolder = Reference< XMaterialHolder >::query( mxUnoAccess );

	// ExactName vom Access holen
	mxExactName = Reference< XExactName >::query( mxUnoAccess );
}




// #67781 Start einer Liste aller SbUnoMethod-Instanzen
static SbUnoMethod* pFirst = NULL;

void clearUnoMethodsForBasic( StarBASIC* pBasic )
{
	SbUnoMethod* pMeth = pFirst;
	while( pMeth )
	{
        SbxObject* pObject = dynamic_cast< SbxObject* >( pMeth->GetParent() );
        if ( pObject )
        {
            StarBASIC* pModBasic = dynamic_cast< StarBASIC* >( pObject->GetParent() );
            if ( pModBasic == pBasic )
            {
                // for now the solution is to remove the method from the list and to clear it,
                // but in case the element should be correctly transferred to another StarBASIC,
                // we should either set module parent to NULL without clearing it, or even
                // set the new StarBASIC as the parent of the module
                // pObject->SetParent( NULL );

                if( pMeth == pFirst )
                    pFirst = pMeth->pNext;
                else if( pMeth->pPrev )
                    pMeth->pPrev->pNext = pMeth->pNext;
                if( pMeth->pNext )
                    pMeth->pNext->pPrev = pMeth->pPrev;

                pMeth->pPrev = NULL;
                pMeth->pNext = NULL;

                pMeth->SbxValue::Clear();
                pObject->SbxValue::Clear();

                // start from the beginning after object clearing, the cycle will end since the method is removed each time
                pMeth = pFirst;
            }
            else
                pMeth = pMeth->pNext;
        }
        else
            pMeth = pMeth->pNext;
	}
}

void clearUnoMethods( void )
{
	SbUnoMethod* pMeth = pFirst;
	while( pMeth )
	{
		pMeth->SbxValue::Clear();
		pMeth = pMeth->pNext;
	}
}


SbUnoMethod::SbUnoMethod
(
	const String& aName_,
	SbxDataType eSbxType,
	Reference< XIdlMethod > xUnoMethod_,
	bool bInvocation,
    bool bDirect
)
	: SbxMethod( aName_, eSbxType )
	, mbInvocation( bInvocation )
    , mbDirectInvocation( bDirect )
{
	m_xUnoMethod = xUnoMethod_;
	pParamInfoSeq = NULL;

	// #67781 Methode in Liste eintragen
	pNext = pFirst;
	pPrev = NULL;
	pFirst = this;
	if( pNext )
		pNext->pPrev = this;
}

SbUnoMethod::~SbUnoMethod()
{
	delete pParamInfoSeq;

	if( this == pFirst )
		pFirst = pNext;
	else if( pPrev )
		pPrev->pNext = pNext;
	if( pNext )
		pNext->pPrev = pPrev;
}

SbxInfo* SbUnoMethod::GetInfo()
{
	if( !pInfo && m_xUnoMethod.is() )
	{
		SbiInstance* pInst = pINST;
		if( pInst && pInst->IsCompatibility() )
		{
			pInfo = new SbxInfo();

			const Sequence<ParamInfo>& rInfoSeq = getParamInfos();
			const ParamInfo* pParamInfos = rInfoSeq.getConstArray();
			sal_uInt32 nParamCount = rInfoSeq.getLength();

			for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
			{
				const ParamInfo& rInfo = pParamInfos[i];
				::rtl::OUString aParamName = rInfo.aName;

				// const Reference< XIdlClass >& rxClass = rInfo.aType;
				SbxDataType t = SbxVARIANT;
				sal_uInt16 nFlags_ = SBX_READ;
				pInfo->AddParam( aParamName, t, nFlags_ );
			}
		}
	}
	return pInfo;
}

const Sequence<ParamInfo>& SbUnoMethod::getParamInfos( void )
{
	if( !pParamInfoSeq && m_xUnoMethod.is() )
	{
		Sequence<ParamInfo> aTmp = m_xUnoMethod->getParameterInfos() ;
		pParamInfoSeq = new Sequence<ParamInfo>( aTmp );
	}
	return *pParamInfoSeq;
}

SbUnoProperty::SbUnoProperty
(
	const String& aName_,
	SbxDataType eSbxType,
	const Property& aUnoProp_,
	sal_Int32 nId_,
	bool bInvocation
)
	: SbxProperty( aName_, eSbxType )
	, aUnoProp( aUnoProp_ )
	, nId( nId_ )
	, mbInvocation( bInvocation )
{
	// #54548, bei bedarf Dummy-Array einsetzen, damit SbiRuntime::CheckArray() geht
	static SbxArrayRef xDummyArray = new SbxArray( SbxVARIANT );
	if( eSbxType & SbxARRAY )
		PutObject( xDummyArray );
}

SbUnoProperty::~SbUnoProperty()
{}


SbxVariable* SbUnoObject::Find( const String& rName, SbxClassType t )
{
	static Reference< XIdlMethod > xDummyMethod;
	static Property aDummyProp;

	SbxVariable* pRes = SbxObject::Find( rName, t );

	if( bNeedIntrospection )
		doIntrospection();

	// Neu 4.3.1999: Properties on Demand anlegen, daher jetzt perIntrospectionAccess
	// suchen, ob doch eine Property oder Methode des geforderten Namens existiert
	if( !pRes )
	{
		::rtl::OUString aUName( rName );
		if( mxUnoAccess.is() && !bNativeCOMObject )
		{
			if( mxExactName.is() )
			{
				::rtl::OUString aUExactName = mxExactName->getExactName( aUName );
				if( !aUExactName.isEmpty() )
					aUName = aUExactName;
			}
			if( mxUnoAccess->hasProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS ) )
			{
				const Property& rProp = mxUnoAccess->
					getProperty( aUName, PropertyConcept::ALL - PropertyConcept::DANGEROUS );

				// #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
				SbxDataType eSbxType;
				if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
					eSbxType = SbxVARIANT;
				else
					eSbxType = unoToSbxType( rProp.Type.getTypeClass() );

				// Property anlegen und reinbraten
				SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, 0, false );
				QuickInsert( (SbxVariable*)xVarRef );
				pRes = xVarRef;
			}
			else if( mxUnoAccess->hasMethod( aUName,
				MethodConcept::ALL - MethodConcept::DANGEROUS ) )
			{
				// Methode ansprechen
				const Reference< XIdlMethod >& rxMethod = mxUnoAccess->
					getMethod( aUName, MethodConcept::ALL - MethodConcept::DANGEROUS );

				// SbUnoMethode anlegen und reinbraten
				SbxVariableRef xMethRef = new SbUnoMethod( rxMethod->getName(),
					unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
				QuickInsert( (SbxVariable*)xMethRef );
				pRes = xMethRef;
			}

			// Wenn immer noch nichts gefunden wurde, muss geprueft werden, ob NameAccess vorliegt
			if( !pRes )
			{
				try
				{
					Reference< XNameAccess > xNameAccess( mxUnoAccess->queryAdapter( ::getCppuType( (const Reference< XPropertySet > *)0 ) ), UNO_QUERY );
					::rtl::OUString aUName2( rName );

					if( xNameAccess.is() && xNameAccess->hasByName( aUName2 ) )
					{
						Any aAny = xNameAccess->getByName( aUName2 );

						// ACHTUNG: Die hier erzeugte Variable darf wegen bei XNameAccess
						// nicht als feste Property in das Object aufgenommen werden und
						// wird daher nirgendwo gehalten.
						// Wenn das Probleme gibt, muss das kuenstlich gemacht werden oder
						// es muss eine Klasse SbUnoNameAccessProperty geschaffen werden,
						// bei der die Existenz staendig neu ueberprueft und die ggf. weg-
						// geworfen wird, wenn der Name nicht mehr gefunden wird.
						pRes = new SbxVariable( SbxVARIANT );
						unoToSbxValue( pRes, aAny );
					}
				}
				catch( NoSuchElementException& e )
				{
					StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
				}
				catch( const Exception& )
				{
					// Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
					if( !pRes )
						pRes = new SbxVariable( SbxVARIANT );

                    implHandleAnyException( ::cppu::getCaughtException() );
				}
			}
		}
		if( !pRes && mxInvocation.is() )
		{
			if( mxExactNameInvocation.is() )
			{
				::rtl::OUString aUExactName = mxExactNameInvocation->getExactName( aUName );
				if( !aUExactName.isEmpty() )
					aUName = aUExactName;
			}

			try
			{
				if( mxInvocation->hasProperty( aUName ) )
				{
					// Property anlegen und reinbraten
					SbxVariableRef xVarRef = new SbUnoProperty( aUName, SbxVARIANT, aDummyProp, 0, true );
					QuickInsert( (SbxVariable*)xVarRef );
					pRes = xVarRef;
				}
				else if( mxInvocation->hasMethod( aUName ) )
				{
					// SbUnoMethode anlegen und reinbraten
					SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true );
					QuickInsert( (SbxVariable*)xMethRef );
					pRes = xMethRef;
				}
                else
                {
                    Reference< XDirectInvocation > xDirectInvoke( mxInvocation, UNO_QUERY );
                    if ( xDirectInvoke.is() && xDirectInvoke->hasMember( aUName ) )
                    {
                        SbxVariableRef xMethRef = new SbUnoMethod( aUName, SbxVARIANT, xDummyMethod, true, true );
                        QuickInsert( (SbxVariable*)xMethRef );
                        pRes = xMethRef;
                    }

                }
			}
			catch( RuntimeException& e )
			{
				// Anlegen, damit der Exception-Fehler nicht ueberschrieben wird
				if( !pRes )
					pRes = new SbxVariable( SbxVARIANT );

				StarBASIC::Error( ERRCODE_BASIC_EXCEPTION, implGetExceptionMsg( e ) );
			}
		}
	}

	// Ganz am Schluss noch pruefen, ob die Dbg_-Properties gemeint sind

	if( !pRes )
	{
		if( rName.EqualsIgnoreCaseAscii( ID_DBG_SUPPORTEDINTERFACES ) ||
			rName.EqualsIgnoreCaseAscii( ID_DBG_PROPERTIES ) ||
			rName.EqualsIgnoreCaseAscii( ID_DBG_METHODS ) )
		{
			// Anlegen
			implCreateDbgProperties();

			// Jetzt muessen sie regulaer gefunden werden
			pRes = SbxObject::Find( rName, SbxCLASS_DONTCARE );
		}
	}
	return pRes;
}


// Hilfs-Methode zum Anlegen der dbg_-Properties
void SbUnoObject::implCreateDbgProperties( void )
{
	Property aProp;

	// Id == -1: Implementierte Interfaces gemaess ClassProvider anzeigen
	SbxVariableRef xVarRef = new SbUnoProperty( String(RTL_CONSTASCII_USTRINGPARAM(ID_DBG_SUPPORTEDINTERFACES)), SbxSTRING, aProp, -1, false );
	QuickInsert( (SbxVariable*)xVarRef );

	// Id == -2: Properties ausgeben
	xVarRef = new SbUnoProperty( String(RTL_CONSTASCII_USTRINGPARAM(ID_DBG_PROPERTIES)), SbxSTRING, aProp, -2, false );
	QuickInsert( (SbxVariable*)xVarRef );

	// Id == -3: Methoden ausgeben
	xVarRef = new SbUnoProperty( String(RTL_CONSTASCII_USTRINGPARAM(ID_DBG_METHODS)), SbxSTRING, aProp, -3, false );
	QuickInsert( (SbxVariable*)xVarRef );
}

void SbUnoObject::implCreateAll( void )
{
	// Bestehende Methoden und Properties alle wieder wegwerfen
	pMethods   = new SbxArray;
	pProps     = new SbxArray;

	if( bNeedIntrospection ) doIntrospection();

	// Instrospection besorgen
	Reference< XIntrospectionAccess > xAccess = mxUnoAccess;
	if( !xAccess.is() || bNativeCOMObject )
	{
		if( mxInvocation.is() )
			xAccess = mxInvocation->getIntrospection();
		else if( bNativeCOMObject )
			return;
	}
	if( !xAccess.is() )
		return;

	// Properties anlegen
	Sequence<Property> props = xAccess->getProperties( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
	sal_uInt32 nPropCount = props.getLength();
	const Property* pProps_ = props.getConstArray();

	sal_uInt32 i;
	for( i = 0 ; i < nPropCount ; i++ )
	{
		const Property& rProp = pProps_[ i ];

		// #58455 Wenn die Property void sein kann, muss als Typ Variant gesetzt werden
		SbxDataType eSbxType;
		if( rProp.Attributes & PropertyAttribute::MAYBEVOID )
			eSbxType = SbxVARIANT;
		else
			eSbxType = unoToSbxType( rProp.Type.getTypeClass() );

		// Property anlegen und reinbraten
		SbxVariableRef xVarRef = new SbUnoProperty( rProp.Name, eSbxType, rProp, i, false );
		QuickInsert( (SbxVariable*)xVarRef );
	}

	// Dbg_-Properties anlegen
	implCreateDbgProperties();

	// Methoden anlegen
	Sequence< Reference< XIdlMethod > > aMethodSeq = xAccess->getMethods
		( MethodConcept::ALL - MethodConcept::DANGEROUS );
	sal_uInt32 nMethCount = aMethodSeq.getLength();
	const Reference< XIdlMethod >* pMethods_ = aMethodSeq.getConstArray();
	for( i = 0 ; i < nMethCount ; i++ )
	{
		// Methode ansprechen
		const Reference< XIdlMethod >& rxMethod = pMethods_[i];

		// SbUnoMethode anlegen und reinbraten
		SbxVariableRef xMethRef = new SbUnoMethod
			( rxMethod->getName(), unoToSbxType( rxMethod->getReturnType() ), rxMethod, false );
		QuickInsert( (SbxVariable*)xMethRef );
	}
}


// Wert rausgeben
Any SbUnoObject::getUnoAny( void )
{
	Any aRetAny;
	if( bNeedIntrospection ) doIntrospection();
	if( mxMaterialHolder.is() )
		aRetAny = mxMaterialHolder->getMaterial();
	else if( mxInvocation.is() )
		aRetAny <<= mxInvocation;
	return aRetAny;
}

// Hilfsmethode zum Anlegen einer Uno-Struct per CoreReflection
SbUnoObject* Impl_CreateUnoStruct( const String& aClassName )
{
	// CoreReflection holen
	Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
	if( !xCoreReflection.is() )
		return NULL;

	// Klasse suchen
	Reference< XIdlClass > xClass;
	Reference< XHierarchicalNameAccess > xHarryName =
		getCoreReflection_HierarchicalNameAccess_Impl();
	if( xHarryName.is() && xHarryName->hasByHierarchicalName( aClassName ) )
		xClass = xCoreReflection->forName( aClassName );
	if( !xClass.is() )
		return NULL;

	// Ist es ueberhaupt ein struct?
	TypeClass eType = xClass->getTypeClass();
	if ( ( eType != TypeClass_STRUCT ) && ( eType != TypeClass_EXCEPTION ) )
		return NULL;

	// Instanz erzeugen
	Any aNewAny;
	xClass->createObject( aNewAny );

	// SbUnoObject daraus basteln
	SbUnoObject* pUnoObj = new SbUnoObject( aClassName, aNewAny );
	return pUnoObj;
}


// Factory-Klasse fuer das Anlegen von Uno-Structs per DIM AS NEW
SbxBase* SbUnoFactory::Create( sal_uInt16, sal_uInt32 )
{
	// Ueber SbxId laeuft in Uno nix
	return NULL;
}

SbxObject* SbUnoFactory::CreateObject( const String& rClassName )
{
	return Impl_CreateUnoStruct( rClassName );
}


// Provisorische Schnittstelle fuer UNO-Anbindung
// Liefert ein SbxObject, das ein Uno-Interface wrappt
SbxObjectRef GetSbUnoObject( const String& aName, const Any& aUnoObj_ )
{
	return new SbUnoObject( aName, aUnoObj_ );
}

// Force creation of all properties for debugging
void createAllObjectProperties( SbxObject* pObj )
{
	if( !pObj )
		return;

	SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pObj);
	if( pUnoObj )
		pUnoObj->createAllProperties();
	else
		pObj->GetAll( SbxCLASS_DONTCARE );
}


void RTL_Impl_CreateUnoStruct( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen mindestens 1 Parameter
	if ( rPar.Count() < 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Klassen-Name der struct holen
	String aClassName = rPar.Get(1)->GetString();

	// Versuchen, gleichnamige Struct zu erzeugen
	SbUnoObjectRef xUnoObj = Impl_CreateUnoStruct( aClassName );
	if( !xUnoObj )
		return;

	// Objekt zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutObject( (SbUnoObject*)xUnoObj );
}

void RTL_Impl_CreateUnoService( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen mindestens 1 Parameter
	if ( rPar.Count() < 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Klassen-Name der struct holen
	String aServiceName = rPar.Get(1)->GetString();

	// Service suchen und instanzieren
	Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
	Reference< XInterface > xInterface;
	if ( xFactory.is() )
	{
		try
		{
			xInterface = xFactory->createInstance( aServiceName );
		}
		catch( const Exception& )
		{
            implHandleAnyException( ::cppu::getCaughtException() );
		}
	}

	SbxVariableRef refVar = rPar.Get(0);
	if( xInterface.is() )
	{
		Any aAny;
		aAny <<= xInterface;

		// SbUnoObject daraus basteln und zurueckliefern
		SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
		if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
		{
			// Objekt zurueckliefern
			refVar->PutObject( (SbUnoObject*)xUnoObj );
		}
		else
		{
			refVar->PutObject( NULL );
		}
	}
	else
	{
		refVar->PutObject( NULL );
	}
}

void RTL_Impl_CreateUnoServiceWithArguments( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen mindestens 2 Parameter
	if ( rPar.Count() < 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Klassen-Name der struct holen
	String aServiceName = rPar.Get(1)->GetString();
	Any aArgAsAny = sbxToUnoValue( rPar.Get(2),
				getCppuType( (Sequence<Any>*)0 ) );
	Sequence< Any > aArgs;
	aArgAsAny >>= aArgs;

	// Service suchen und instanzieren
	Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
	Reference< XInterface > xInterface;
	if ( xFactory.is() )
	{
		try
		{
			xInterface = xFactory->createInstanceWithArguments( aServiceName, aArgs );
		}
		catch( const Exception& )
		{
            implHandleAnyException( ::cppu::getCaughtException() );
		}
	}

	SbxVariableRef refVar = rPar.Get(0);
	if( xInterface.is() )
	{
		Any aAny;
		aAny <<= xInterface;

		// SbUnoObject daraus basteln und zurueckliefern
		SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
		if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
		{
			// Objekt zurueckliefern
			refVar->PutObject( (SbUnoObject*)xUnoObj );
		}
		else
		{
			refVar->PutObject( NULL );
		}
	}
	else
	{
		refVar->PutObject( NULL );
	}
}

void RTL_Impl_GetProcessServiceManager( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	SbxVariableRef refVar = rPar.Get(0);

	// Globalen Service-Manager holen
	Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
	if( xFactory.is() )
	{
		Any aAny;
		aAny <<= xFactory;

		// SbUnoObject daraus basteln und zurueckliefern
		SbUnoObjectRef xUnoObj = new SbUnoObject( String( RTL_CONSTASCII_USTRINGPARAM("ProcessServiceManager") ), aAny );
		refVar->PutObject( (SbUnoObject*)xUnoObj );
	}
	else
	{
		refVar->PutObject( NULL );
	}
}

void RTL_Impl_HasInterfaces( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen mindestens 2 Parameter
	sal_uInt16 nParCount = rPar.Count();
	if( nParCount < 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Variable fuer Rueckgabewert
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutBool( sal_False );

	// Uno-Objekt holen
	SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
	if( !(pObj && pObj->ISA(SbUnoObject)) )
		return;
	Any aAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
	TypeClass eType = aAny.getValueType().getTypeClass();
	if( eType != TypeClass_INTERFACE )
		return;

	// Interface aus dem Any besorgen
	Reference< XInterface > x = *(Reference< XInterface >*)aAny.getValue();

	// CoreReflection holen
	Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
	if( !xCoreReflection.is() )
		return;

	for( sal_uInt16 i = 2 ; i < nParCount ; i++ )
	{
		// Interface-Name der struct holen
		String aIfaceName = rPar.Get( i )->GetString();

		// Klasse suchen
		Reference< XIdlClass > xClass = xCoreReflection->forName( aIfaceName );
		if( !xClass.is() )
			return;

		// Pruefen, ob das Interface unterstuetzt wird
		::rtl::OUString aClassName = xClass->getName();
		Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
		if( !x->queryInterface( aClassType ).hasValue() )
			return;
	}

	// Alles hat geklappt, dann sal_True liefern
	refVar->PutBool( sal_True );
}

void RTL_Impl_IsUnoStruct( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	// Wir brauchen mindestens 1 Parameter
	if ( rPar.Count() < 2 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Variable fuer Rueckgabewert
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutBool( sal_False );

	// Uno-Objekt holen
	SbxVariableRef xParam = rPar.Get( 1 );
	if( !xParam->IsObject() )
		return;
	SbxBaseRef pObj = (SbxBase*)rPar.Get( 1 )->GetObject();
	if( !(pObj && pObj->ISA(SbUnoObject)) )
		return;
	Any aAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
	TypeClass eType = aAny.getValueType().getTypeClass();
	if( eType == TypeClass_STRUCT )
		refVar->PutBool( sal_True );
}


void RTL_Impl_EqualUnoObjects( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	if ( rPar.Count() < 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Variable fuer Rueckgabewert
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutBool( sal_False );

	// Uno-Objekte holen
	SbxVariableRef xParam1 = rPar.Get( 1 );
	if( !xParam1->IsObject() )
		return;
	SbxBaseRef pObj1 = (SbxBase*)xParam1->GetObject();
	if( !(pObj1 && pObj1->ISA(SbUnoObject)) )
		return;
	Any aAny1 = ((SbUnoObject*)(SbxBase*)pObj1)->getUnoAny();
	TypeClass eType1 = aAny1.getValueType().getTypeClass();
	if( eType1 != TypeClass_INTERFACE )
		return;
	Reference< XInterface > x1;
	aAny1 >>= x1;
	//XInterfaceRef x1 = *(XInterfaceRef*)aAny1.get();

	SbxVariableRef xParam2 = rPar.Get( 2 );
	if( !xParam2->IsObject() )
		return;
	SbxBaseRef pObj2 = (SbxBase*)xParam2->GetObject();
	if( !(pObj2 && pObj2->ISA(SbUnoObject)) )
		return;
	Any aAny2 = ((SbUnoObject*)(SbxBase*)pObj2)->getUnoAny();
	TypeClass eType2 = aAny2.getValueType().getTypeClass();
	if( eType2 != TypeClass_INTERFACE )
		return;
	Reference< XInterface > x2;
	aAny2 >>= x2;
	//XInterfaceRef x2 = *(XInterfaceRef*)aAny2.get();

	if( x1 == x2 )
		refVar->PutBool( sal_True );
}

typedef std::hash_map< ::rtl::OUString, std::vector< ::rtl::OUString >, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleHash;


// helper wrapper function to interact with TypeProvider and
// XTypeDescriptionEnumerationAccess.
// if it fails for whatever reason
// returned Reference<> be null e.g. .is() will be false

Reference< XTypeDescriptionEnumeration >
getTypeDescriptorEnumeration( const ::rtl::OUString& sSearchRoot,
	const Sequence< TypeClass >& types, TypeDescriptionSearchDepth depth )
{
	Reference< XTypeDescriptionEnumeration > xEnum;
	Reference< XTypeDescriptionEnumerationAccess> xTypeEnumAccess( getTypeProvider_Impl(), UNO_QUERY );
	if ( xTypeEnumAccess.is() )
	{
		try
		{
			xEnum = xTypeEnumAccess->createTypeDescriptionEnumeration(
				sSearchRoot, types, depth );
		}
		catch( NoSuchTypeNameException& /*nstne*/ ) {}
		catch( InvalidTypeNameException& /*nstne*/ ) {}
	}
	return xEnum;
}

typedef std::hash_map< ::rtl::OUString, Any, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > VBAConstantsHash;

SbxVariable* getVBAConstant( const String& rName )
{
	SbxVariable* pConst = NULL;
	static VBAConstantsHash aConstCache;
	static bool isInited = false;
	if ( !isInited )
	{
		Sequence< TypeClass > types(1);
		types[ 0 ] = TypeClass_CONSTANTS;
		Reference< XTypeDescriptionEnumeration > xEnum = getTypeDescriptorEnumeration( defaultNameSpace, types, TypeDescriptionSearchDepth_INFINITE  );

		if ( !xEnum.is() )
			return NULL;

		while ( xEnum->hasMoreElements() )
		{
			Reference< XConstantsTypeDescription > xConstants( xEnum->nextElement(), UNO_QUERY );
			if ( xConstants.is() )
			{
				Sequence< Reference< XConstantTypeDescription > > aConsts = xConstants->getConstants();
				Reference< XConstantTypeDescription >* pSrc = aConsts.getArray();
				sal_Int32 nLen = aConsts.getLength();
				for ( sal_Int32 index =0;  index<nLen; ++pSrc, ++index )
				{
					Reference< XConstantTypeDescription >& rXConst =
						*pSrc;
					::rtl::OUString sFullName = rXConst->getName();
					sal_Int32 indexLastDot = sFullName.lastIndexOf('.');
					::rtl::OUString sLeafName;
					if ( indexLastDot > -1 )
						sLeafName = sFullName.copy( indexLastDot + 1);
					aConstCache[ sLeafName.toAsciiLowerCase() ] = rXConst->getConstantValue();
				}
			}
		}
		isInited = true;
	}
	::rtl::OUString sKey( rName );
	VBAConstantsHash::const_iterator it = aConstCache.find( sKey.toAsciiLowerCase() );
	if ( it != aConstCache.end() )
	{
		pConst = new SbxVariable( SbxVARIANT );
		pConst->SetName( rName );
		unoToSbxValue( pConst, it->second );
	}
	return pConst;
}

// Funktion, um einen globalen Bezeichner im
// UnoScope zu suchen und fuer Sbx zu wrappen
SbUnoClass* findUnoClass( const String& rName )
{
    // #105550 Check if module exists
	SbUnoClass* pUnoClass = NULL;

    Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    if( xTypeAccess->hasByHierarchicalName( rName ) )
    {
        Any aRet = xTypeAccess->getByHierarchicalName( rName );
		Reference< XTypeDescription > xTypeDesc;
		aRet >>= xTypeDesc;

        if( xTypeDesc.is() )
        {
            TypeClass eTypeClass = xTypeDesc->getTypeClass();
            if( eTypeClass == TypeClass_MODULE || eTypeClass == TypeClass_CONSTANTS )
        		pUnoClass = new SbUnoClass( rName );
        }
    }
	return pUnoClass;
}

SbxVariable* SbUnoClass::Find( const XubString& rName, SbxClassType t )
{
    (void)t;

	SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_VARIABLE );

	// Wenn nichts gefunden wird, ist das Sub-Modul noch nicht bekannt
	if( !pRes )
	{
		// Wenn es schon eine Klasse ist, nach einen Feld fragen
		if( m_xClass.is() )
		{
			// Ist es ein Field
			::rtl::OUString aUStr( rName );
			Reference< XIdlField > xField = m_xClass->getField( aUStr );
			Reference< XIdlClass > xClass;
			if( xField.is() )
			{
				try
				{
					Any aAny;
					aAny = xField->get( aAny );

					// Nach Sbx wandeln
					pRes = new SbxVariable( SbxVARIANT );
					pRes->SetName( rName );
					unoToSbxValue( pRes, aAny );
				}
		        catch( const Exception& )
		        {
                    implHandleAnyException( ::cppu::getCaughtException() );
		        }
			}
		}
		else
		{
			// Vollqualifizierten Namen erweitern
			String aNewName = GetName();
			aNewName.AppendAscii( "." );
			aNewName += rName;

			// CoreReflection holen
			Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
			if( xCoreReflection.is() )
			{
				// Ist es eine Konstante?
				Reference< XHierarchicalNameAccess > xHarryName( xCoreReflection, UNO_QUERY );
				if( xHarryName.is() )
				{
					try
					{
						Any aValue = xHarryName->getByHierarchicalName( aNewName );
						TypeClass eType = aValue.getValueType().getTypeClass();

						// Interface gefunden? Dann ist es eine Klasse
						if( eType == TypeClass_INTERFACE )
						{
							Reference< XInterface > xIface = *(Reference< XInterface >*)aValue.getValue();
							Reference< XIdlClass > xClass( xIface, UNO_QUERY );
							if( xClass.is() )
							{
								pRes = new SbxVariable( SbxVARIANT );
								SbxObjectRef xWrapper = (SbxObject*)new SbUnoClass( aNewName, xClass );
								pRes->PutObject( xWrapper );
							}
						}
						else
						{
							pRes = new SbxVariable( SbxVARIANT );
							unoToSbxValue( pRes, aValue );
						}
					}
					catch( NoSuchElementException& e1 )
					{
						String aMsg = implGetExceptionMsg( e1 );
					}
				}

				// Sonst wieder als Klasse annehmen
				if( !pRes )
				{
                    SbUnoClass* pNewClass = findUnoClass( aNewName );
					if( pNewClass )
					{
						pRes = new SbxVariable( SbxVARIANT );
						SbxObjectRef xWrapper = (SbxObject*)pNewClass;
						pRes->PutObject( xWrapper );
					}
				}

				// An UNO service?
				if( !pRes )
				{
					SbUnoService* pUnoService = findUnoService( aNewName );
					if( pUnoService )
					{
						pRes = new SbxVariable( SbxVARIANT );
						SbxObjectRef xWrapper = (SbxObject*)pUnoService;
						pRes->PutObject( xWrapper );
					}
				}

				// An UNO singleton?
				if( !pRes )
				{
					SbUnoSingleton* pUnoSingleton = findUnoSingleton( aNewName );
					if( pUnoSingleton )
					{
						pRes = new SbxVariable( SbxVARIANT );
						SbxObjectRef xWrapper = (SbxObject*)pUnoSingleton;
						pRes->PutObject( xWrapper );
					}
				}
			}
		}

		if( pRes )
		{
			pRes->SetName( rName );

			// Variable einfuegen, damit sie spaeter im Find gefunden wird
			QuickInsert( pRes );

			// Uns selbst gleich wieder als Listener rausnehmen,
			// die Werte sind alle konstant
			if( pRes->IsBroadcaster() )
				EndListening( pRes->GetBroadcaster(), sal_True );
		}
	}
	return pRes;
}


SbUnoService* findUnoService( const String& rName )
{
	SbUnoService* pSbUnoService = NULL;

    Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    if( xTypeAccess->hasByHierarchicalName( rName ) )
    {
        Any aRet = xTypeAccess->getByHierarchicalName( rName );
	    Reference< XTypeDescription > xTypeDesc;
        aRet >>= xTypeDesc;

        if( xTypeDesc.is() )
        {
            TypeClass eTypeClass = xTypeDesc->getTypeClass();
            if( eTypeClass == TypeClass_SERVICE )
			{
				Reference< XServiceTypeDescription2 > xServiceTypeDesc( xTypeDesc, UNO_QUERY );
				if( xServiceTypeDesc.is() )
        			pSbUnoService = new SbUnoService( rName, xServiceTypeDesc );
			}
        }
    }
	return pSbUnoService;
}

SbxVariable* SbUnoService::Find( const String& rName, SbxClassType )
{
	SbxVariable* pRes = SbxObject::Find( rName, SbxCLASS_METHOD );

	if( !pRes )
	{
		// Wenn es schon eine Klasse ist, nach einen Feld fragen
		if( m_bNeedsInit && m_xServiceTypeDesc.is() )
		{
			m_bNeedsInit = false;

			Sequence< Reference< XServiceConstructorDescription > > aSCDSeq = m_xServiceTypeDesc->getConstructors();
			const Reference< XServiceConstructorDescription >* pCtorSeq = aSCDSeq.getConstArray();
			int nCtorCount = aSCDSeq.getLength();
			for( int i = 0 ; i < nCtorCount ; ++i )
			{
				Reference< XServiceConstructorDescription > xCtor = pCtorSeq[i];

				String aName( xCtor->getName() );
				if( !aName.Len() )
				{
					if( xCtor->isDefaultConstructor() )
						aName = String::CreateFromAscii( "create" );
				}

				if( aName.Len() )
				{
					// Create and insert SbUnoServiceCtor
					SbxVariableRef xSbCtorRef = new SbUnoServiceCtor( aName, xCtor );
					QuickInsert( (SbxVariable*)xSbCtorRef );
				}
			}

			pRes = SbxObject::Find( rName, SbxCLASS_METHOD );
		}
	}

	return pRes;
}

void SbUnoService::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
						   const SfxHint& rHint, const TypeId& rHintType )
{
	const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
	if( pHint )
	{
		SbxVariable* pVar = pHint->GetVar();
		SbxArray* pParams = pVar->GetParameters();
		SbUnoServiceCtor* pUnoCtor = PTR_CAST(SbUnoServiceCtor,pVar);
		if( pUnoCtor && pHint->GetId() == SBX_HINT_DATAWANTED )
		{
			// Parameter count -1 because of Param0 == this
			sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
			Sequence<Any> args;
			sal_Bool bOutParams = sal_False;

			Reference< XServiceConstructorDescription > xCtor = pUnoCtor->getServiceCtorDesc();
			Sequence< Reference< XParameter > > aParameterSeq = xCtor->getParameters();
			const Reference< XParameter >* pParameterSeq = aParameterSeq.getConstArray();
			sal_uInt32 nUnoParamCount = aParameterSeq.getLength();

			// Default: Ignore not needed parameters
			bool bParameterError = false;

			// Is the last parameter a rest parameter?
			bool bRestParameterMode = false;
			if( nUnoParamCount > 0 )
			{
				Reference< XParameter > xLastParam = pParameterSeq[ nUnoParamCount - 1 ];
				if( xLastParam.is() )
				{
					if( xLastParam->isRestParameter() )
						bRestParameterMode = true;
				}
			}

			// Too many parameters with context as first parameter?
			sal_uInt16 nSbxParameterOffset = 1;
			sal_uInt16 nParameterOffsetByContext = 0;
			Reference < XComponentContext > xFirstParamContext;
			if( nParamCount > nUnoParamCount )
			{
				// Check if first parameter is a context and use it
				// then in createInstanceWithArgumentsAndContext
				Any aArg0 = sbxToUnoValue( pParams->Get( nSbxParameterOffset ) );
				if( (aArg0 >>= xFirstParamContext) && xFirstParamContext.is() )
					nParameterOffsetByContext = 1;
			}

			sal_uInt32 nEffectiveParamCount = nParamCount - nParameterOffsetByContext;
			sal_uInt32 nAllocParamCount = nEffectiveParamCount;
			if( nEffectiveParamCount > nUnoParamCount )
			{
				if( !bRestParameterMode )
				{
					nEffectiveParamCount = nUnoParamCount;
					nAllocParamCount = nUnoParamCount;
				}
			}
			// Not enough parameters?
			else if( nUnoParamCount > nEffectiveParamCount )
			{
				// RestParameterMode only helps if one (the last) parameter is missing
				int nDiff = nUnoParamCount - nEffectiveParamCount;
				if( !bRestParameterMode || nDiff > 1 )
				{
					bParameterError = true;
					StarBASIC::Error( SbERR_NOT_OPTIONAL );
				}
			}

			if( !bParameterError )
			{
				if( nAllocParamCount > 0 )
				{
					args.realloc( nAllocParamCount );
					Any* pAnyArgs = args.getArray();
					for( sal_uInt32 i = 0 ; i < nEffectiveParamCount ; i++ )
					{
						sal_uInt16 iSbx = (sal_uInt16)(i + nSbxParameterOffset + nParameterOffsetByContext);

						// bRestParameterMode allows nEffectiveParamCount > nUnoParamCount
						Reference< XParameter > xParam;
						if( i < nUnoParamCount )
						{
							xParam = pParameterSeq[i];
							if( !xParam.is() )
								continue;

							Reference< XTypeDescription > xParamTypeDesc = xParam->getType();
							if( !xParamTypeDesc.is() )
								continue;
							com::sun::star::uno::Type aType( xParamTypeDesc->getTypeClass(), xParamTypeDesc->getName() );

							// sbx parameter needs offset 1
							pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ), aType );

							// Check for out parameter if not already done
							if( !bOutParams )
							{
								if( xParam->isOut() )
									bOutParams = sal_True;
							}
						}
						else
						{
							pAnyArgs[i] = sbxToUnoValue( pParams->Get( iSbx ) );
						}
					}
				}

				// "Call" ctor using createInstanceWithArgumentsAndContext
				Reference < XComponentContext > xContext;
				if( xFirstParamContext.is() )
				{
					xContext = xFirstParamContext;
				}
				else
				{
					Reference < XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
					xContext.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" )) ), UNO_QUERY_THROW );
				}
				Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );

				Any aRetAny;
				if( xServiceMgr.is() )
				{
					String aServiceName = GetName();
					Reference < XInterface > xRet;
					try
					{
						xRet = xServiceMgr->createInstanceWithArgumentsAndContext( aServiceName, args, xContext );
					}
					catch( const Exception& )
					{
						implHandleAnyException( ::cppu::getCaughtException() );
					}
					aRetAny <<= xRet;
				}
				unoToSbxValue( pVar, aRetAny );

				// Copy back out parameters?
				if( bOutParams )
				{
					const Any* pAnyArgs = args.getConstArray();

					for( sal_uInt32 j = 0 ; j < nUnoParamCount ; j++ )
					{
						Reference< XParameter > xParam = pParameterSeq[j];
						if( !xParam.is() )
							continue;

						if( xParam->isOut() )
							unoToSbxValue( (SbxVariable*)pParams->Get( (sal_uInt16)(j+1) ), pAnyArgs[ j ] );
					}
				}
			}
		}
		else
			SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
	}
}



static SbUnoServiceCtor* pFirstCtor = NULL;

void clearUnoServiceCtors( void )
{
	SbUnoServiceCtor* pCtor = pFirstCtor;
	while( pCtor )
	{
		pCtor->SbxValue::Clear();
		pCtor = pCtor->pNext;
	}
}

SbUnoServiceCtor::SbUnoServiceCtor( const String& aName_, Reference< XServiceConstructorDescription > xServiceCtorDesc )
	: SbxMethod( aName_, SbxOBJECT )
	, m_xServiceCtorDesc( xServiceCtorDesc )
{
}

SbUnoServiceCtor::~SbUnoServiceCtor()
{
}

SbxInfo* SbUnoServiceCtor::GetInfo()
{
	SbxInfo* pRet = NULL;

	return pRet;
}


SbUnoSingleton* findUnoSingleton( const String& rName )
{
	SbUnoSingleton* pSbUnoSingleton = NULL;

    Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    if( xTypeAccess->hasByHierarchicalName( rName ) )
    {
        Any aRet = xTypeAccess->getByHierarchicalName( rName );
	    Reference< XTypeDescription > xTypeDesc;
        aRet >>= xTypeDesc;

        if( xTypeDesc.is() )
        {
            TypeClass eTypeClass = xTypeDesc->getTypeClass();
            if( eTypeClass == TypeClass_SINGLETON )
			{
				Reference< XSingletonTypeDescription > xSingletonTypeDesc( xTypeDesc, UNO_QUERY );
				if( xSingletonTypeDesc.is() )
        			pSbUnoSingleton = new SbUnoSingleton( rName, xSingletonTypeDesc );
			}
        }
    }
	return pSbUnoSingleton;
}

SbUnoSingleton::SbUnoSingleton( const String& aName_,
	const Reference< XSingletonTypeDescription >& xSingletonTypeDesc )
		: SbxObject( aName_ )
		, m_xSingletonTypeDesc( xSingletonTypeDesc )
{
	SbxVariableRef xGetMethodRef =
		new SbxMethod( String( RTL_CONSTASCII_USTRINGPARAM( "get" ) ), SbxOBJECT );
	QuickInsert( (SbxVariable*)xGetMethodRef );
}

void SbUnoSingleton::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
						   const SfxHint& rHint, const TypeId& rHintType )
{
	const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
	if( pHint )
	{
		SbxVariable* pVar = pHint->GetVar();
		SbxArray* pParams = pVar->GetParameters();
		sal_uInt32 nParamCount = pParams ? ((sal_uInt32)pParams->Count() - 1) : 0;
		sal_uInt32 nAllowedParamCount = 1;

		Reference < XComponentContext > xContextToUse;
		if( nParamCount > 0 )
		{
			// Check if first parameter is a context and use it then
			Reference < XComponentContext > xFirstParamContext;
			Any aArg1 = sbxToUnoValue( pParams->Get( 1 ) );
			if( (aArg1 >>= xFirstParamContext) && xFirstParamContext.is() )
				xContextToUse = xFirstParamContext;
		}

		if( !xContextToUse.is() )
		{
			Reference < XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW );
			xContextToUse.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" )) ), UNO_QUERY_THROW );
			--nAllowedParamCount;
		}

		if( nParamCount > nAllowedParamCount )
		{
			StarBASIC::Error( SbERR_BAD_ARGUMENT );
			return;
		}

		Any aRetAny;
		if( xContextToUse.is() )
		{
			String aSingletonName( RTL_CONSTASCII_USTRINGPARAM("/singletons/") );
			aSingletonName += GetName();
			Reference < XInterface > xRet;
			xContextToUse->getValueByName( aSingletonName ) >>= xRet;
			aRetAny <<= xRet;
		}
		unoToSbxValue( pVar, aRetAny );
	}
	else
		SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
}


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

// Implementation eines EventAttacher-bezogenen AllListeners, der
// nur einzelne Events an einen allgemeinen AllListener weiterleitet
class BasicAllListener_Impl : public BasicAllListenerHelper
{
	virtual void firing_impl(const AllEventObject& Event, Any* pRet);

public:
	SbxObjectRef	xSbxObj;
	::rtl::OUString		aPrefixName;

	BasicAllListener_Impl( const ::rtl::OUString& aPrefixName );
	~BasicAllListener_Impl();

	// Methoden von XInterface
	//virtual sal_Bool queryInterface( Uik aUik, Reference< XInterface > & rOut );

	// Methoden von XAllListener
	virtual void SAL_CALL firing(const AllEventObject& Event) throw ( RuntimeException );
	virtual Any SAL_CALL approveFiring(const AllEventObject& Event) throw ( RuntimeException );

	// Methoden von XEventListener
	virtual void SAL_CALL disposing(const EventObject& Source) throw ( RuntimeException );
};


//========================================================================
BasicAllListener_Impl::BasicAllListener_Impl
(
	const ::rtl::OUString	& aPrefixName_
)
	: aPrefixName( aPrefixName_ )
{
}

//========================================================================
BasicAllListener_Impl::~BasicAllListener_Impl()
{
}

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

void BasicAllListener_Impl::firing_impl( const AllEventObject& Event, Any* pRet )
{
	vos::OGuard guard( Application::GetSolarMutex() );

	if( xSbxObj.Is() )
	{
		::rtl::OUString aMethodName = aPrefixName;
		aMethodName = aMethodName + Event.MethodName;

		SbxVariable * pP = xSbxObj;
		while( pP->GetParent() )
		{
			pP = pP->GetParent();
			StarBASIC * pLib = PTR_CAST(StarBASIC,pP);
			if( pLib )
			{
				// In Basic Array anlegen
				SbxArrayRef xSbxArray = new SbxArray( SbxVARIANT );
				const Any * pArgs = Event.Arguments.getConstArray();
				sal_Int32 nCount = Event.Arguments.getLength();
				for( sal_Int32 i = 0; i < nCount; i++ )
				{
					// Elemente wandeln
					SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
					unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
					xSbxArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
				}

				pLib->Call( aMethodName, xSbxArray );

				// Return-Wert aus dem Param-Array holen, wenn verlangt
				if( pRet )
				{
					SbxVariable* pVar = xSbxArray->Get( 0 );
					if( pVar )
					{
						// #95792 Avoid a second call
						sal_uInt16 nFlags = pVar->GetFlags();
						pVar->SetFlag( SBX_NO_BROADCAST );
						*pRet = sbxToUnoValueImpl( pVar );
						pVar->SetFlags( nFlags );
					}
				}
				break;
			}
		}
	}
}


// Methoden von XAllListener
void BasicAllListener_Impl::firing( const AllEventObject& Event ) throw ( RuntimeException )
{
	firing_impl( Event, NULL );
}

Any BasicAllListener_Impl::approveFiring( const AllEventObject& Event ) throw ( RuntimeException )
{
	Any aRetAny;
	firing_impl( Event, &aRetAny );
	return aRetAny;
}

//========================================================================
// Methoden von XEventListener
void BasicAllListener_Impl ::disposing(const EventObject& ) throw ( RuntimeException )
{
	vos::OGuard guard( Application::GetSolarMutex() );

	xSbxObj.Clear();
}



//*************************************************************************
//  class InvocationToAllListenerMapper
//  helper class to map XInvocation to XAllListener (also in project eventattacher!)
//*************************************************************************
class InvocationToAllListenerMapper : public WeakImplHelper1< XInvocation >
{
public:
	InvocationToAllListenerMapper( const Reference< XIdlClass >& ListenerType,
		const Reference< XAllListener >& AllListener, const Any& Helper );

	// XInvocation
    virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(void) throw( RuntimeException );
    virtual Any SAL_CALL invoke(const ::rtl::OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
		throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException );
    virtual void SAL_CALL setValue(const ::rtl::OUString& PropertyName, const Any& Value)
		throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException );
    virtual Any SAL_CALL getValue(const ::rtl::OUString& PropertyName) throw( UnknownPropertyException, RuntimeException );
    virtual sal_Bool SAL_CALL hasMethod(const ::rtl::OUString& Name) throw( RuntimeException );
    virtual sal_Bool SAL_CALL hasProperty(const ::rtl::OUString& Name) throw( RuntimeException );

private:
	Reference< XIdlReflection >  m_xCoreReflection;
	Reference< XAllListener >	 m_xAllListener;
	Reference< XIdlClass >  	 m_xListenerType;
	Any 						 m_Helper;
};


// Function to replace AllListenerAdapterService::createAllListerAdapter
Reference< XInterface > createAllListenerAdapter
(
	const Reference< XInvocationAdapterFactory >& xInvocationAdapterFactory,
	const Reference< XIdlClass >& xListenerType,
	const Reference< XAllListener >& xListener,
	const Any& Helper
)
{
	Reference< XInterface > xAdapter;
	if( xInvocationAdapterFactory.is() && xListenerType.is() && xListener.is() )
	{
	   Reference< XInvocation >	xInvocationToAllListenerMapper =
			(XInvocation*)new InvocationToAllListenerMapper( xListenerType, xListener, Helper );
		Type aListenerType( xListenerType->getTypeClass(), xListenerType->getName() );
		xAdapter = xInvocationAdapterFactory->createAdapter( xInvocationToAllListenerMapper, aListenerType );
	}
	return xAdapter;
}


//--------------------------------------------------------------------------------------------------
// InvocationToAllListenerMapper
InvocationToAllListenerMapper::InvocationToAllListenerMapper
	( const Reference< XIdlClass >& ListenerType, const Reference< XAllListener >& AllListener, const Any& Helper )
		: m_xAllListener( AllListener )
		, m_xListenerType( ListenerType )
		, m_Helper( Helper )
{
}

//*************************************************************************
Reference< XIntrospectionAccess > SAL_CALL InvocationToAllListenerMapper::getIntrospection(void)
	throw( RuntimeException )
{
	return Reference< XIntrospectionAccess >();
}

//*************************************************************************
Any SAL_CALL InvocationToAllListenerMapper::invoke(const ::rtl::OUString& FunctionName, const Sequence< Any >& Params,
	Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
		throw( IllegalArgumentException, CannotConvertException,
		InvocationTargetException, RuntimeException )
{
    (void)OutParamIndex;
    (void)OutParam     ;

	Any aRet;

	// Check if to firing or approveFiring has to be called
	Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( FunctionName );
	sal_Bool bApproveFiring = sal_False;
	if( !xMethod.is() )
		return aRet;
    Reference< XIdlClass > xReturnType = xMethod->getReturnType();
    Sequence< Reference< XIdlClass > > aExceptionSeq = xMethod->getExceptionTypes();
	if( ( xReturnType.is() && xReturnType->getTypeClass() != TypeClass_VOID ) ||
		aExceptionSeq.getLength() > 0 )
	{
		bApproveFiring = sal_True;
	}
	else
	{
	    Sequence< ParamInfo > aParamSeq = xMethod->getParameterInfos();
		sal_uInt32 nParamCount = aParamSeq.getLength();
		if( nParamCount > 1 )
		{
			const ParamInfo* pInfos = aParamSeq.getConstArray();
			for( sal_uInt32 i = 0 ; i < nParamCount ; i++ )
			{
				if( pInfos[ i ].aMode != ParamMode_IN )
				{
					bApproveFiring = sal_True;
					break;
				}
			}
		}
	}

    AllEventObject aAllEvent;
    aAllEvent.Source = (OWeakObject*) this;
    aAllEvent.Helper = m_Helper;
    aAllEvent.ListenerType = Type(m_xListenerType->getTypeClass(), m_xListenerType->getName() );
    aAllEvent.MethodName = FunctionName;
    aAllEvent.Arguments = Params;
	if( bApproveFiring )
		aRet = m_xAllListener->approveFiring( aAllEvent );
	else
		m_xAllListener->firing( aAllEvent );
	return aRet;
}

//*************************************************************************
void SAL_CALL InvocationToAllListenerMapper::setValue(const ::rtl::OUString& PropertyName, const Any& Value)
	throw( UnknownPropertyException, CannotConvertException,
		   InvocationTargetException, RuntimeException )
{
    (void)PropertyName;
    (void)Value;
}

//*************************************************************************
Any SAL_CALL InvocationToAllListenerMapper::getValue(const ::rtl::OUString& PropertyName)
	throw( UnknownPropertyException, RuntimeException )
{
    (void)PropertyName;

	return Any();
}

//*************************************************************************
sal_Bool SAL_CALL InvocationToAllListenerMapper::hasMethod(const ::rtl::OUString& Name)
	throw( RuntimeException )
{
	Reference< XIdlMethod > xMethod = m_xListenerType->getMethod( Name );
	return xMethod.is();
}

//*************************************************************************
sal_Bool SAL_CALL InvocationToAllListenerMapper::hasProperty(const ::rtl::OUString& Name)
	throw( RuntimeException )
{
	Reference< XIdlField > xField = m_xListenerType->getField( Name );
	return xField.is();
}

//========================================================================
// Uno-Service erzeugen
// 1. Parameter == Prefix-Name der Makros
// 2. Parameter == voll qualifizierter Name des Listeners
void SbRtl_CreateUnoListener( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
//RTLFUNC(CreateUnoListener)
{
    (void)bWrite;

	// Wir brauchen 2 Parameter
	if ( rPar.Count() != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Klassen-Name der struct holen
	String aPrefixName = rPar.Get(1)->GetString();
	String aListenerClassName = rPar.Get(2)->GetString();

	// CoreReflection holen
	Reference< XIdlReflection > xCoreReflection = getCoreReflection_Impl();
	if( !xCoreReflection.is() )
		return;

	// AllListenerAdapterService holen
	Reference< XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
	if( !xFactory.is() )
		return;

	// Klasse suchen
	Reference< XIdlClass > xClass = xCoreReflection->forName( aListenerClassName );
	if( !xClass.is() )
		return;

	// AB, 30.11.1999 InvocationAdapterFactory holen
	Reference< XInvocationAdapterFactory > xInvocationAdapterFactory = Reference< XInvocationAdapterFactory >(
		xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.script.InvocationAdapterFactory") ), UNO_QUERY );

	BasicAllListener_Impl * p;
	Reference< XAllListener > xAllLst = p = new BasicAllListener_Impl( aPrefixName );
	Any aTmp;
	Reference< XInterface > xLst = createAllListenerAdapter( xInvocationAdapterFactory, xClass, xAllLst, aTmp );
	if( !xLst.is() )
		return;

	::rtl::OUString aClassName = xClass->getName();
	Type aClassType( xClass->getTypeClass(), aClassName.getStr() );
	aTmp = xLst->queryInterface( aClassType );
	if( !aTmp.hasValue() )
		return;

	SbUnoObject* pUnoObj = new SbUnoObject( aListenerClassName, aTmp );
    p->xSbxObj = pUnoObj;
	p->xSbxObj->SetParent( pBasic );

    // #100326 Register listener object to set Parent NULL in Dtor
    SbxArrayRef xBasicUnoListeners = pBasic->getUnoListeners();
	xBasicUnoListeners->Insert( pUnoObj, xBasicUnoListeners->Count() );

	// Objekt zurueckliefern
	SbxVariableRef refVar = rPar.Get(0);
	refVar->PutObject( p->xSbxObj );
}

//========================================================================
// Represents the DefaultContext property of the ProcessServiceManager
// in the Basic runtime system.
void RTL_Impl_GetDefaultContext( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	SbxVariableRef refVar = rPar.Get(0);

	Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
	Reference< XPropertySet> xPSMPropertySet( xFactory, UNO_QUERY );
	if( xPSMPropertySet.is() )
	{
		Any aContextAny = xPSMPropertySet->getPropertyValue(
			String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) );

		SbUnoObjectRef xUnoObj = new SbUnoObject
			( String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ),
			  aContextAny );
		refVar->PutObject( (SbUnoObject*)xUnoObj );
	}
	else
	{
		refVar->PutObject( NULL );
	}
}

//========================================================================
// Creates a Basic wrapper object for a strongly typed Uno value
// 1. parameter: Uno type as full qualified type name, e.g. "byte[]"
void RTL_Impl_CreateUnoValue( StarBASIC* pBasic, SbxArray& rPar, sal_Bool bWrite )
{
    (void)pBasic;
    (void)bWrite;

	static String aTypeTypeString( RTL_CONSTASCII_USTRINGPARAM("type") );

	// 2 parameters needed
	if ( rPar.Count() != 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	// Klassen-Name der struct holen
	String aTypeName = rPar.Get(1)->GetString();
    SbxVariable* pVal = rPar.Get(2);

	if( aTypeName == aTypeTypeString )
	{
		SbxDataType eBaseType = pVal->SbxValue::GetType();
		String aValTypeName;
		if( eBaseType == SbxSTRING )
		{
			aValTypeName = pVal->GetString();
		}
		else if( eBaseType == SbxOBJECT )
		{
			// XIdlClass?
			Reference< XIdlClass > xIdlClass;

			SbxBaseRef pObj = (SbxBase*)pVal->GetObject();
			if( pObj && pObj->ISA(SbUnoObject) )
			{
				Any aUnoAny = ((SbUnoObject*)(SbxBase*)pObj)->getUnoAny();
				aUnoAny >>= xIdlClass;
			}

			if( xIdlClass.is() )
				aValTypeName = xIdlClass->getName();
		}
		Type aType;
		bool bSuccess = implGetTypeByName( aValTypeName, aType );
		if( bSuccess )
		{
			Any aTypeAny( aType );
			SbxVariableRef refVar = rPar.Get(0);
			SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aTypeAny );
			refVar->PutObject( xUnoAnyObject );
		}
		return;
	}

    // Check the type
    Reference< XHierarchicalNameAccess > xTypeAccess = getTypeProvider_Impl();
    Any aRet;
	try
	{
        aRet = xTypeAccess->getByHierarchicalName( aTypeName );
	}
	catch( NoSuchElementException& e1 )
	{
        String aNoSuchElementExceptionName
            ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.NoSuchElementException" ) );
		StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
            implGetExceptionMsg( e1, aNoSuchElementExceptionName ) );
		return;
	}
    Reference< XTypeDescription > xTypeDesc;
    aRet >>= xTypeDesc;
    TypeClass eTypeClass = xTypeDesc->getTypeClass();
	Type aDestType( eTypeClass, aTypeName );


    // Preconvert value
	Any aVal = sbxToUnoValueImpl( pVal );
    Any aConvertedVal = convertAny( aVal, aDestType );

    /*
    // Convert
    Reference< XTypeConverter > xConverter = getTypeConverter_Impl();
	try
	{
        aConvertedVal = xConverter->convertTo( aVal, aDestType );
	}
	catch( IllegalArgumentException& e1 )
	{
		StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
            implGetExceptionMsg( ::cppu::getCaughtException() ) );
		return;
	}
	catch( CannotConvertException& e2 )
	{
        String aCannotConvertExceptionName
            ( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.IllegalArgumentException" ) );
		StarBASIC::Error( ERRCODE_BASIC_EXCEPTION,
            implGetExceptionMsg( e2, aCannotConvertExceptionName ) );
		return;
	}
    */

	SbxVariableRef refVar = rPar.Get(0);
	SbxObjectRef xUnoAnyObject = new SbUnoAnyObject( aConvertedVal );
	refVar->PutObject( xUnoAnyObject );
}

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

namespace {
class OMutexBasis
{
protected:
    // this mutex is necessary for OInterfaceContainerHelper
    ::osl::Mutex m_aMutex;
};
} // namespace

typedef WeakImplHelper2< XInvocation, XComponent > ModuleInvocationProxyHelper;

class ModuleInvocationProxy : public OMutexBasis,
                              public ModuleInvocationProxyHelper
{
	::rtl::OUString		m_aPrefix;
	SbxObjectRef		m_xScopeObj;
	bool				m_bProxyIsClassModuleObject;

    ::cppu::OInterfaceContainerHelper m_aListeners;

public:
	ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj );
	~ModuleInvocationProxy()
	{}

	// XInvocation
    virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw();
    virtual void SAL_CALL setValue( const ::rtl::OUString& rProperty, const Any& rValue )
        throw( UnknownPropertyException );
    virtual Any SAL_CALL getValue( const ::rtl::OUString& rProperty )
        throw( UnknownPropertyException );
    virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& rName ) throw();
    virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& rProp ) throw();

    virtual Any SAL_CALL invoke( const ::rtl::OUString& rFunction,
                                 const Sequence< Any >& rParams,
                                 Sequence< sal_Int16 >& rOutParamIndex,
                                 Sequence< Any >& rOutParam )
        throw( CannotConvertException, InvocationTargetException );

    // XComponent
    virtual void SAL_CALL dispose() throw(RuntimeException);
    virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException);
    virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException);
};

ModuleInvocationProxy::ModuleInvocationProxy( const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj )
	: m_aPrefix( aPrefix + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") ) )
	, m_xScopeObj( xScopeObj )
    , m_aListeners( m_aMutex )
{
	m_bProxyIsClassModuleObject = xScopeObj.Is() ? xScopeObj->ISA(SbClassModuleObject) : false;
}

Reference< XIntrospectionAccess > SAL_CALL ModuleInvocationProxy::getIntrospection() throw()
{
    return Reference< XIntrospectionAccess >();
}

void SAL_CALL ModuleInvocationProxy::setValue( const ::rtl::OUString& rProperty, const Any& rValue ) throw( UnknownPropertyException )
{
	if( !m_bProxyIsClassModuleObject )
		throw UnknownPropertyException();

	vos::OGuard guard( Application::GetSolarMutex() );

	::rtl::OUString aPropertyFunctionName( RTL_CONSTASCII_USTRINGPARAM( "Property Set ") );
	aPropertyFunctionName += m_aPrefix;
	aPropertyFunctionName += rProperty;

	SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
	SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
	if( pMeth == NULL )
	{
		// TODO: Check vba behavior concernig missing function
		//StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
		throw UnknownPropertyException();
	}

	// Setup parameter
	SbxArrayRef xArray = new SbxArray;
	SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
	unoToSbxValue( (SbxVariable*)xVar, rValue );
	xArray->Put( xVar, 1 );

	// Call property method
	SbxVariableRef xValue = new SbxVariable;
	pMeth->SetParameters( xArray );
	pMeth->Call( xValue );
	//aRet = sbxToUnoValue( xValue );
	pMeth->SetParameters( NULL );

	// TODO: OutParameter?

	// throw InvocationTargetException();

    //return aRet;

}

Any SAL_CALL ModuleInvocationProxy::getValue( const ::rtl::OUString& rProperty ) throw( UnknownPropertyException )
{
	if( !m_bProxyIsClassModuleObject )
	    throw UnknownPropertyException();

	vos::OGuard guard( Application::GetSolarMutex() );

	::rtl::OUString aPropertyFunctionName( RTL_CONSTASCII_USTRINGPARAM( "Property Get ") );
	aPropertyFunctionName += m_aPrefix;
	aPropertyFunctionName += rProperty;

	SbxVariable* p = m_xScopeObj->Find( aPropertyFunctionName, SbxCLASS_METHOD );
	SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
	if( pMeth == NULL )
	{
		// TODO: Check vba behavior concernig missing function
		//StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
	    throw UnknownPropertyException();
	}

	// Call method
	SbxVariableRef xValue = new SbxVariable;
	pMeth->Call( xValue );
	Any aRet = sbxToUnoValue( xValue );
    return aRet;
}

sal_Bool SAL_CALL ModuleInvocationProxy::hasMethod( const ::rtl::OUString& ) throw()
{
    return sal_False;
}

sal_Bool SAL_CALL ModuleInvocationProxy::hasProperty( const ::rtl::OUString& ) throw()
{
    return sal_False;
}

Any SAL_CALL ModuleInvocationProxy::invoke( const ::rtl::OUString& rFunction,
											const Sequence< Any >& rParams,
											Sequence< sal_Int16 >&,
											Sequence< Any >& )
    throw( CannotConvertException, InvocationTargetException )
{
	vos::OGuard guard( Application::GetSolarMutex() );

    Any aRet;
	SbxObjectRef xScopeObj = m_xScopeObj;
	if( !xScopeObj.Is() )
		return aRet;

	::rtl::OUString aFunctionName = m_aPrefix;
	aFunctionName += rFunction;

    sal_Bool bSetRescheduleBack = sal_False;
    sal_Bool bOldReschedule = sal_True;
    SbiInstance* pInst = pINST;
    if( pInst && pInst->IsCompatibility() )
    {
        bOldReschedule = pInst->IsReschedule();
        if ( bOldReschedule )
        {
            pInst->EnableReschedule( sal_False );
            bSetRescheduleBack = sal_True;
        }
    }

	SbxVariable* p = xScopeObj->Find( aFunctionName, SbxCLASS_METHOD );
	SbMethod* pMeth = p != NULL ? PTR_CAST(SbMethod,p) : NULL;
	if( pMeth == NULL )
	{
		// TODO: Check vba behavior concernig missing function
		//StarBASIC::Error( SbERR_NO_METHOD, aFunctionName );
		return aRet;
	}

	// Setup parameters
	SbxArrayRef xArray;
	sal_Int32 nParamCount = rParams.getLength();
	if( nParamCount )
	{
		xArray = new SbxArray;
		const Any *pArgs = rParams.getConstArray();
		for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
		{
			SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
			unoToSbxValue( (SbxVariable*)xVar, pArgs[i] );
			xArray->Put( xVar, sal::static_int_cast< sal_uInt16 >(i+1) );
		}
	}

	// Call method
	SbxVariableRef xValue = new SbxVariable;
	if( xArray.Is() )
		pMeth->SetParameters( xArray );
	pMeth->Call( xValue );
	aRet = sbxToUnoValue( xValue );
	pMeth->SetParameters( NULL );

    if( bSetRescheduleBack )
        pInst->EnableReschedule( bOldReschedule );

	// TODO: OutParameter?

    return aRet;
}

void SAL_CALL ModuleInvocationProxy::dispose()
    throw(RuntimeException)
{
    ::osl::MutexGuard aGuard( m_aMutex );

    EventObject aEvent( (XComponent*)this );
    m_aListeners.disposeAndClear( aEvent );

    m_xScopeObj = NULL;
}

void SAL_CALL ModuleInvocationProxy::addEventListener( const Reference< XEventListener >& xListener )
    throw (RuntimeException)
{
    m_aListeners.addInterface( xListener );
}

void SAL_CALL ModuleInvocationProxy::removeEventListener( const Reference< XEventListener >& xListener )
    throw (RuntimeException)
{
    m_aListeners.removeInterface( xListener );
}


Reference< XInterface > createComListener( const Any& aControlAny, const ::rtl::OUString& aVBAType,
										   const ::rtl::OUString& aPrefix, SbxObjectRef xScopeObj )
{
	Reference< XInterface > xRet;

	Reference< XComponentContext > xContext = getComponentContext_Impl();
	Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );

	Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPrefix, xScopeObj );

	Sequence<Any> args( 3 );
	args[0] <<= aControlAny;
	args[1] <<= aVBAType;
	args[2] <<= xProxy;

	try
	{
		xRet = xServiceMgr->createInstanceWithArgumentsAndContext(
			::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.UnoComListener")),
			args, xContext );
	}
	catch( const Exception& )
	{
		implHandleAnyException( ::cppu::getCaughtException() );
	}

	return xRet;
}

typedef std::vector< WeakReference< XComponent > >	ComponentRefVector;

struct StarBasicDisposeItem
{
	StarBASIC*				m_pBasic;
	SbxArrayRef				m_pRegisteredVariables;
	ComponentRefVector		m_vComImplementsObjects;

	StarBasicDisposeItem( StarBASIC* pBasic )
		: m_pBasic( pBasic )
	{
		m_pRegisteredVariables = new SbxArray();
	}
};

typedef std::vector< StarBasicDisposeItem* > DisposeItemVector;

static DisposeItemVector GaDisposeItemVector;

DisposeItemVector::iterator lcl_findItemForBasic( StarBASIC* pBasic )
{
	DisposeItemVector::iterator it;
	for( it = GaDisposeItemVector.begin() ; it != GaDisposeItemVector.end() ; ++it )
	{
		StarBasicDisposeItem* pItem = *it;
		if( pItem->m_pBasic == pBasic )
			return it;
	}
	return GaDisposeItemVector.end();
}

StarBasicDisposeItem* lcl_getOrCreateItemForBasic( StarBASIC* pBasic )
{
	DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
	StarBasicDisposeItem* pItem = (it != GaDisposeItemVector.end()) ? *it : NULL;
	if( pItem == NULL )
	{
		pItem = new StarBasicDisposeItem( pBasic );
		GaDisposeItemVector.push_back( pItem );
	}
	return pItem;
}

void registerComponentToBeDisposedForBasic
	( Reference< XComponent > xComponent, StarBASIC* pBasic )
{
	StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
	pItem->m_vComImplementsObjects.push_back( xComponent );
}

void registerComListenerVariableForBasic( SbxVariable* pVar, StarBASIC* pBasic )
{
	StarBasicDisposeItem* pItem = lcl_getOrCreateItemForBasic( pBasic );
	SbxArray* pArray = pItem->m_pRegisteredVariables;
	pArray->Put( pVar, pArray->Count() );
}

void disposeComVariablesForBasic( StarBASIC* pBasic )
{
	DisposeItemVector::iterator it = lcl_findItemForBasic( pBasic );
	if( it != GaDisposeItemVector.end() )
	{
		StarBasicDisposeItem* pItem = *it;

		SbxArray* pArray = pItem->m_pRegisteredVariables;
		sal_uInt16 nCount = pArray->Count();
		for( sal_uInt16 i = 0 ; i < nCount ; ++i )
		{
			SbxVariable* pVar = pArray->Get( i );
			pVar->ClearComListener();
		}

		ComponentRefVector& rv = pItem->m_vComImplementsObjects;
		ComponentRefVector::iterator itCRV;
		for( itCRV = rv.begin() ; itCRV != rv.end() ; ++itCRV )
		{
            try
            {
                Reference< XComponent > xComponent( (*itCRV).get(), UNO_QUERY_THROW );
                xComponent->dispose();
            }
            catch( Exception& )
            {}
		}

		delete pItem;
		GaDisposeItemVector.erase( it );
	}
}


// Handle module implements mechanism for OLE types
bool SbModule::createCOMWrapperForIface( Any& o_rRetAny, SbClassModuleObject* pProxyClassModuleObject )
{
	// For now: Take first interface that allows to instantiate COM wrapper
	// TODO: Check if support for multiple interfaces is needed

	Reference< XComponentContext > xContext = getComponentContext_Impl();
	Reference< XMultiComponentFactory > xServiceMgr( xContext->getServiceManager() );
	Reference< XSingleServiceFactory > xComImplementsFactory
	(
        xServiceMgr->createInstanceWithContext(
	        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.custom.ComImplementsFactory")), xContext ),
		UNO_QUERY
	);
	if( !xComImplementsFactory.is() )
		return false;

	bool bSuccess = false;

	SbxArray* pModIfaces = pClassData->mxIfaces;
	sal_uInt16 nCount = pModIfaces->Count();
	for( sal_uInt16 i = 0 ; i < nCount ; ++i )
	{
		SbxVariable* pVar = pModIfaces->Get( i );
		::rtl::OUString aIfaceName = pVar->GetName();

		if( !aIfaceName.isEmpty() )
		{
			::rtl::OUString aPureIfaceName = aIfaceName;
			sal_Int32 indexLastDot = aIfaceName.lastIndexOf('.');
			if ( indexLastDot > -1 )
				aPureIfaceName = aIfaceName.copy( indexLastDot + 1 );

			Reference< XInvocation > xProxy = new ModuleInvocationProxy( aPureIfaceName, pProxyClassModuleObject );

			Sequence<Any> args( 2 );
			args[0] <<= aIfaceName;
			args[1] <<= xProxy;

			Reference< XInterface > xRet;
			bSuccess = false;
			try
			{
				xRet = xComImplementsFactory->createInstanceWithArguments( args );
				bSuccess = true;
			}
			catch( const Exception& )
			{
				implHandleAnyException( ::cppu::getCaughtException() );
			}

			if( bSuccess )
			{
				Reference< XComponent > xComponent( xProxy, UNO_QUERY );
				if( xComponent.is() )
				{
					StarBASIC* pParentBasic = NULL;
					SbxObject* pCurObject = this;
					do
					{
						SbxObject* pObjParent = pCurObject->GetParent();
						pParentBasic = PTR_CAST( StarBASIC, pObjParent );
						pCurObject = pObjParent;
					}
					while( pParentBasic == NULL && pCurObject != NULL );

					OSL_ASSERT( pParentBasic != NULL );
					registerComponentToBeDisposedForBasic( xComponent, pParentBasic );
				}

				o_rRetAny <<= xRet;
				break;
			}
		}
 	}

	return bSuccess;
}


// Due to an incorrect behavior IE returns an object instead of a string
// in some scenarios. Calling toString at the object may correct this.
// Helper function used in sbxvalue.cxx
bool handleToStringForCOMObjects( SbxObject* pObj, SbxValue* pVal )
{
	bool bSuccess = false;

	SbUnoObject* pUnoObj = NULL;
	if( pObj != NULL && (pUnoObj = PTR_CAST(SbUnoObject,(SbxObject*)pObj)) != NULL )
	{
		// Only for native COM objects
		if( pUnoObj->isNativeCOMObject() )
		{
			SbxVariableRef pMeth = pObj->Find( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "toString" ) ), SbxCLASS_METHOD );
			if ( pMeth.Is() )
			{
				SbxValues aRes;
				pMeth->Get( aRes );
				pVal->Put( aRes );
                bSuccess = true;
			}
		}
	}
	return bSuccess;
}
