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

#include <vos/macros.hxx>
#include <vcl/svapp.hxx>
#include <tools/stream.hxx>
#include <svl/brdcst.hxx>
#include <tools/shl.hxx>
#include <basic/sbx.hxx>
#include "sbdiagnose.hxx"
#include "sb.hxx"
#include <sbjsmeth.hxx>
#include "sbjsmod.hxx"
#include "sbintern.hxx"
#include "image.hxx"
#include "opcodes.hxx"
#include "runtime.hxx"
#include "token.hxx"
#include "sbunoobj.hxx"
#include "sbtrace.hxx"


//#include <basic/hilight.hxx>
#include <svtools/syntaxhighlight.hxx>

#include <basic/basrdll.hxx>
#include <vos/mutex.hxx>
#include <basic/sbobjmod.hxx>
#include <basic/vbahelper.hxx>
#include <cppuhelper/implbase3.hxx>
#include <unotools/eventcfg.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/vba/XVBACompatibility.hpp>
#include <com/sun/star/script/vba/VBAScriptEventId.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/document/XEventBroadcaster.hpp>
#include <com/sun/star/document/XEventListener.hpp>

using namespace com::sun::star;

// for the bsearch
#ifdef WNT
#define CDECL _cdecl
#endif
#if defined(UNX) || defined(OS2)
#define CDECL
#endif
#ifdef UNX
#include <sys/resource.h>
#endif

#include <stdio.h>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <comphelper/processfactory.hxx>
#include <vcl/svapp.hxx>
#include <map>
#include <com/sun/star/reflection/XProxyFactory.hpp>
#include <cppuhelper/implbase1.hxx>
#include <basic/sbobjmod.hxx>
#include <com/sun/star/uno/XAggregation.hpp>
#include <com/sun/star/script/XInvocation.hpp>

using namespace com::sun::star::lang;
using namespace com::sun::star::reflection;
using namespace com::sun::star::beans;
using namespace com::sun::star::script;


#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/awt/XDialogProvider.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <cppuhelper/implbase1.hxx>
#include <comphelper/anytostring.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <ooo/vba/VbQueryClose.hpp>

typedef ::cppu::WeakImplHelper1< XInvocation > DocObjectWrapper_BASE;
typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;
::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );

class DocObjectWrapper : public DocObjectWrapper_BASE
{
    Reference< XAggregation >  m_xAggProxy;
    Reference< XInvocation >  m_xAggInv;
    Reference< XTypeProvider > m_xAggregateTypeProv;
    Sequence< Type >           m_Types;
    SbModule*                m_pMod;
    SbMethodRef getMethod( const rtl::OUString& aName ) throw (RuntimeException);
    SbPropertyRef getProperty( const rtl::OUString& aName ) throw (RuntimeException);
    String mName; // for debugging

public:
    DocObjectWrapper( SbModule* pMod );
    virtual ~DocObjectWrapper();

    virtual void SAL_CALL acquire() throw();
    virtual void SAL_CALL release() throw();

    virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (RuntimeException)
    {
        if( !m_xAggregateTypeProv.is() )
            throw RuntimeException();
        return m_xAggregateTypeProv->getImplementationId();
    }

    virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(  ) throw (RuntimeException);

    virtual Any SAL_CALL invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException);
    virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException);
    virtual Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException);
    virtual ::sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException);
    virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException);
    virtual  Any SAL_CALL queryInterface( const Type& aType ) throw ( RuntimeException );

    virtual Sequence< Type > SAL_CALL getTypes() throw ( RuntimeException );
};

DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ), mName( pVar->GetName() )
{
    SbObjModule* pMod = PTR_CAST(SbObjModule,pVar);
    if ( pMod )
    {
        if ( pMod->GetModuleType() == ModuleType::DOCUMENT )
        {
            Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
            // Use proxy factory service to create aggregatable proxy.
            SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pMod->GetObject() );
            Reference< XInterface > xIf;
            if ( pUnoObj )
            {
                   Any aObj = pUnoObj->getUnoAny();
                   aObj >>= xIf;
                   if ( xIf.is() )
                   {
                       m_xAggregateTypeProv.set( xIf, UNO_QUERY );
                       m_xAggInv.set( xIf, UNO_QUERY );
                   }
            }
            if ( xIf.is() )
            {
                try
                {
                    Reference< XMultiComponentFactory > xMFac( xFactory, UNO_QUERY_THROW );
                    Reference< XPropertySet> xPSMPropertySet( xMFac, UNO_QUERY_THROW );
                    Reference< XComponentContext >  xCtx;
                    xPSMPropertySet->getPropertyValue(
                    String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xCtx;
                    Reference< XProxyFactory > xProxyFac( xMFac->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ), xCtx  ), UNO_QUERY_THROW );
                    m_xAggProxy = xProxyFac->createProxy( xIf );
                }
                catch(  Exception& )
                {
                    OSL_ENSURE( false, "DocObjectWrapper::DocObjectWrapper: Caught exception!" );
                }
            }

            if ( m_xAggProxy.is() )
            {
                osl_incrementInterlockedCount( &m_refCount );

                /* i35609 - Fix crash on Solaris. The setDelegator call needs
                    to be in its own block to ensure that all temporary Reference
                    instances that are acquired during the call are released
                    before m_refCount is decremented again */
                {
                    m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) );
                }

                 osl_decrementInterlockedCount( &m_refCount );
            }
        }
    }
}

void SAL_CALL
DocObjectWrapper::acquire() throw ()
{
    osl_incrementInterlockedCount( &m_refCount );
    OSL_TRACE("DocObjectWrapper::acquire(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
}
void SAL_CALL
DocObjectWrapper::release() throw ()
{
    if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
    {
        OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
        delete this;
    }
    else
        OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
}

DocObjectWrapper::~DocObjectWrapper()
{
}

Sequence< Type > SAL_CALL DocObjectWrapper::getTypes()
    throw ( RuntimeException )
{
    if ( m_Types.getLength() == 0 )
    {
        Sequence< Type > sTypes;
        if ( m_xAggregateTypeProv.is() )
            sTypes = m_xAggregateTypeProv->getTypes();
        m_Types.realloc( sTypes.getLength() + 1 );
        Type* pPtr = m_Types.getArray();
        for ( int i=0; i<m_Types.getLength(); ++i, ++pPtr )
        {
            if ( i == 0 )
                *pPtr = XInvocation::static_type( NULL );
            else
                *pPtr = sTypes[ i - 1 ];
        }
    }
    return m_Types;
}

Reference< XIntrospectionAccess > SAL_CALL
DocObjectWrapper::getIntrospection(  ) throw (RuntimeException)
{
    return NULL;
}

Any SAL_CALL
DocObjectWrapper::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException)
{
    if ( m_xAggInv.is() &&  m_xAggInv->hasMethod( aFunctionName ) )
            return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam );
    SbMethodRef pMethod = getMethod( aFunctionName );
    if ( !pMethod )
        throw RuntimeException();
    // check number of parameters
    sal_Int32 nParamsCount = aParams.getLength();
    SbxInfo* pInfo = pMethod->GetInfo();
    if ( pInfo )
    {
        sal_Int32 nSbxOptional = 0;
        sal_uInt16 n = 1;
        for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
        {
            if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
                ++nSbxOptional;
            else
                nSbxOptional = 0;
        }
        sal_Int32 nSbxCount = n - 1;
        if ( nParamsCount < nSbxCount - nSbxOptional )
        {
            throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "wrong number of parameters!" ) ), Reference< XInterface >() );
        }
    }
    // set parameters
    SbxArrayRef xSbxParams;
    if ( nParamsCount > 0 )
    {
        xSbxParams = new SbxArray;
        const Any* pParams = aParams.getConstArray();
        for ( sal_Int32 i = 0; i < nParamsCount; ++i )
        {
            SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
            unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
            xSbxParams->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );

            // Enable passing by ref
            if ( xSbxVar->GetType() != SbxVARIANT )
                xSbxVar->SetFlag( SBX_FIXED );
        }
    }
    if ( xSbxParams.Is() )
        pMethod->SetParameters( xSbxParams );

    // call method
    SbxVariableRef xReturn = new SbxVariable;
    ErrCode nErr = SbxERR_OK;

    nErr = pMethod->Call( xReturn );
    Any aReturn;
    // get output parameters
    if ( xSbxParams.Is() )
    {
        SbxInfo* pInfo_ = pMethod->GetInfo();
        if ( pInfo_ )
        {
            OutParamMap aOutParamMap;
            for ( sal_uInt16 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
            {
                const SbxParamInfo* pParamInfo = pInfo_->GetParam( n );
                if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
                {
                    SbxVariable* pVar = xSbxParams->Get( n );
                    if ( pVar )
                    {
                        SbxVariableRef xVar = pVar;
                        aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
                    }
                }
            }
            sal_Int32 nOutParamCount = aOutParamMap.size();
            aOutParamIndex.realloc( nOutParamCount );
            aOutParam.realloc( nOutParamCount );
            sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
            Any* pOutParam = aOutParam.getArray();
            for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
            {
                *pOutParamIndex = aIt->first;
                *pOutParam = aIt->second;
            }
        }
    }

    // get return value
    aReturn = sbxToUnoValue( xReturn );

    pMethod->SetParameters( NULL );

    return aReturn;
}

void SAL_CALL
DocObjectWrapper::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException)
{
    if ( m_xAggInv.is() &&  m_xAggInv->hasProperty( aPropertyName ) )
            return m_xAggInv->setValue( aPropertyName, aValue );

    SbPropertyRef pProperty = getProperty( aPropertyName );
    if ( !pProperty.Is() )
       throw UnknownPropertyException();
    unoToSbxValue( (SbxVariable*) pProperty, aValue );
}

Any SAL_CALL
DocObjectWrapper::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException)
{
    if ( m_xAggInv.is() &&  m_xAggInv->hasProperty( aPropertyName ) )
            return m_xAggInv->getValue( aPropertyName );

    SbPropertyRef pProperty = getProperty( aPropertyName );
    if ( !pProperty.Is() )
       throw UnknownPropertyException();

    SbxVariable* pProp = ( SbxVariable* ) pProperty;
    if ( pProp->GetType() == SbxEMPTY )
        pProperty->Broadcast( SBX_HINT_DATAWANTED );

    Any aRet = sbxToUnoValue( pProp );
    return aRet;
}

::sal_Bool SAL_CALL
DocObjectWrapper::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException)
{
    if ( m_xAggInv.is() && m_xAggInv->hasMethod( aName ) )
        return sal_True;
    return getMethod( aName ).Is();
}

::sal_Bool SAL_CALL
DocObjectWrapper::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException)
{
    sal_Bool bRes = sal_False;
    if ( m_xAggInv.is() && m_xAggInv->hasProperty( aName ) )
        bRes = sal_True;
    else bRes = getProperty( aName ).Is();
    return bRes;
}

Any SAL_CALL DocObjectWrapper::queryInterface( const Type& aType )
    throw ( RuntimeException )
{
    Any aRet = DocObjectWrapper_BASE::queryInterface( aType );
    if ( aRet.hasValue() )
        return aRet;
    else if ( m_xAggProxy.is() )
        aRet = m_xAggProxy->queryAggregation( aType );
    return aRet;
}

SbMethodRef DocObjectWrapper::getMethod( const rtl::OUString& aName ) throw (RuntimeException)
{
    SbMethodRef pMethod = NULL;
    if ( m_pMod )
    {
        sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
        // Limit search to this module
        m_pMod->ResetFlag( SBX_GBLSEARCH );
        pMethod = (SbMethod*) m_pMod->SbModule::Find( aName,  SbxCLASS_METHOD );
        m_pMod->SetFlags( nSaveFlgs );
    }

    return pMethod;
}

SbPropertyRef DocObjectWrapper::getProperty( const rtl::OUString& aName ) throw (RuntimeException)
{
    SbPropertyRef pProperty = NULL;
    if ( m_pMod )
    {
        sal_uInt16 nSaveFlgs = m_pMod->GetFlags();
        // Limit search to this module.
        m_pMod->ResetFlag( SBX_GBLSEARCH );
        pProperty = (SbProperty*)m_pMod->SbModule::Find( aName,  SbxCLASS_PROPERTY );
        m_pMod->SetFlag( nSaveFlgs );
    }

    return pProperty;
}

TYPEINIT1(SbModule,SbxObject)
TYPEINIT1(SbMethod,SbxMethod)
TYPEINIT1(SbProperty,SbxProperty)
TYPEINIT1(SbProcedureProperty,SbxProperty)
TYPEINIT1(SbJScriptModule,SbModule)
TYPEINIT1(SbJScriptMethod,SbMethod)
TYPEINIT1(SbObjModule,SbModule)
TYPEINIT1(SbUserFormModule,SbObjModule)

typedef std::vector<HighlightPortion> HighlightPortions;

uno::Reference< frame::XModel > getDocumentModel( StarBASIC* pb )
{
    uno::Reference< frame::XModel > xModel;
    if( pb && pb->IsDocBasic() )
    {
        uno::Any aDoc;
        if( pb->GetUNOConstant( "ThisComponent", aDoc ) )
            xModel.set( aDoc, uno::UNO_QUERY );
    }
    return xModel;
}

uno::Reference< vba::XVBACompatibility > getVBACompatibility( const uno::Reference< frame::XModel >& rxModel )
{
    uno::Reference< vba::XVBACompatibility > xVBACompat;
    try
    {
        uno::Reference< beans::XPropertySet > xModelProps( rxModel, uno::UNO_QUERY_THROW );
        xVBACompat.set( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicLibraries" ) ) ), uno::UNO_QUERY );
    }
    catch( uno::Exception& )
    {
    }
    return xVBACompat;
}

bool getDefaultVBAMode( StarBASIC* pb )
{
    uno::Reference< vba::XVBACompatibility > xVBACompat = getVBACompatibility( getDocumentModel( pb ) );
    return xVBACompat.is() && xVBACompat->getVBACompatibilityMode();
}

class AsyncQuitHandler
{
    AsyncQuitHandler() {}
    AsyncQuitHandler( const AsyncQuitHandler&);
public:
    static AsyncQuitHandler& instance()
    {
        static AsyncQuitHandler dInst;
        return dInst;
    }

    void QuitApplication()
    {
        uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
        if ( xFactory.is() )
	{
            uno::Reference< frame::XDesktop > xDeskTop( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop") ) ), uno::UNO_QUERY );
           if ( xDeskTop.is() )
               xDeskTop->terminate();
        }
    }
    DECL_LINK( OnAsyncQuit, void* );
};

IMPL_LINK( AsyncQuitHandler, OnAsyncQuit, void*, /*pNull*/ )
{
    QuitApplication();
    return 0L;
}

/////////////////////////////////////////////////////////////////////////////

// Ein BASIC-Modul hat EXTSEARCH gesetzt, damit die im Modul enthaltenen
// Elemente von anderen Modulen aus gefunden werden koennen.

SbModule::SbModule( const String& rName,  sal_Bool bVBACompat )
		 : SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("StarBASICModule") ) ),
		   pImage( NULL ), pBreaks( NULL ), pClassData( NULL ), mbVBACompat( bVBACompat ),  pDocObject( NULL ), bIsProxyModule( false )
{
	SetName( rName );
	SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
	SetModuleType( script::ModuleType::NORMAL );

	// #i92642: Set name property to intitial name
	SbxVariable* pNameProp = pProps->Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
	if( pNameProp != NULL )
		pNameProp->PutString( GetName() );
}

SbModule::~SbModule()
{
    OSL_TRACE("Module named %s is destructing", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
	if( pImage )
		delete pImage;
	if( pBreaks )
		delete pBreaks;
	if( pClassData )
		delete pClassData;
        mxWrapper = NULL;
}

uno::Reference< script::XInvocation >
SbModule::GetUnoModule()
{
    if ( !mxWrapper.is() )
        mxWrapper = new DocObjectWrapper( this );

    OSL_TRACE("Module named %s returning wrapper mxWrapper (0x%x)", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mxWrapper.get() );
    return mxWrapper;
}

sal_Bool SbModule::IsCompiled() const
{
	return sal_Bool( pImage != 0 );
}

const SbxObject* SbModule::FindType( String aTypeName ) const
{
	return pImage ? pImage->FindType( aTypeName ) : NULL;
}


// Aus dem Codegenerator: Loeschen des Images und Invalidieren der Entries

void SbModule::StartDefinitions()
{
	delete pImage; pImage = NULL;
	if( pClassData )
		pClassData->clear();

	// Methoden und Properties bleiben erhalten, sind jedoch ungueltig
	// schliesslich sind ja u.U. die Infos belegt
	sal_uInt16 i;
	for( i = 0; i < pMethods->Count(); i++ )
	{
		SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
		if( p )
			p->bInvalid = sal_True;
	}
	for( i = 0; i < pProps->Count(); )
	{
		SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
		if( p )
			pProps->Remove( i );
		else
			i++;
	}
}

// Methode anfordern/anlegen

SbMethod* SbModule::GetMethod( const String& rName, SbxDataType t )
{
	SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
	SbMethod* pMeth = p ? PTR_CAST(SbMethod,p) : NULL;
	if( p && !pMeth )
		pMethods->Remove( p );
	if( !pMeth )
	{
		pMeth = new SbMethod( rName, t, this );
		pMeth->SetParent( this );
		pMeth->SetFlags( SBX_READ );
		pMethods->Put( pMeth, pMethods->Count() );
		StartListening( pMeth->GetBroadcaster(), sal_True );
	}
	// Per Default ist die Methode GUELTIG, da sie auch vom Compiler
	// (Codegenerator) erzeugt werden kann
	pMeth->bInvalid = sal_False;
	pMeth->ResetFlag( SBX_FIXED );
	pMeth->SetFlag( SBX_WRITE );
	pMeth->SetType( t );
	pMeth->ResetFlag( SBX_WRITE );
	if( t != SbxVARIANT )
		pMeth->SetFlag( SBX_FIXED );
	return pMeth;
}

// Property anfordern/anlegen

SbProperty* SbModule::GetProperty( const String& rName, SbxDataType t )
{
	SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
	SbProperty* pProp = p ? PTR_CAST(SbProperty,p) : NULL;
	if( p && !pProp )
		pProps->Remove( p );
	if( !pProp )
	{
		pProp = new SbProperty( rName, t, this );
		pProp->SetFlag( SBX_READWRITE );
		pProp->SetParent( this );
		pProps->Put( pProp, pProps->Count() );
		StartListening( pProp->GetBroadcaster(), sal_True );
	}
	return pProp;
}

SbProcedureProperty* SbModule::GetProcedureProperty
	( const String& rName, SbxDataType t )
{
	SbxVariable* p = pProps->Find( rName, SbxCLASS_PROPERTY );
	SbProcedureProperty* pProp = p ? PTR_CAST(SbProcedureProperty,p) : NULL;
	if( p && !pProp )
		pProps->Remove( p );
	if( !pProp )
	{
		pProp = new SbProcedureProperty( rName, t );
		pProp->SetFlag( SBX_READWRITE );
		pProp->SetParent( this );
		pProps->Put( pProp, pProps->Count() );
		StartListening( pProp->GetBroadcaster(), sal_True );
	}
	return pProp;
}

SbIfaceMapperMethod* SbModule::GetIfaceMapperMethod
	( const String& rName, SbMethod* pImplMeth )
{
	SbxVariable* p = pMethods->Find( rName, SbxCLASS_METHOD );
	SbIfaceMapperMethod* pMapperMethod = p ? PTR_CAST(SbIfaceMapperMethod,p) : NULL;
	if( p && !pMapperMethod )
		pMethods->Remove( p );
	if( !pMapperMethod )
	{
		pMapperMethod = new SbIfaceMapperMethod( rName, pImplMeth );
		pMapperMethod->SetParent( this );
		pMapperMethod->SetFlags( SBX_READ );
		pMethods->Put( pMapperMethod, pMethods->Count() );
	}
	pMapperMethod->bInvalid = sal_False;
	return pMapperMethod;
}

SbIfaceMapperMethod::~SbIfaceMapperMethod()
{
}

TYPEINIT1(SbIfaceMapperMethod,SbMethod)


// Aus dem Codegenerator: Ungueltige Eintraege entfernen

void SbModule::EndDefinitions( sal_Bool bNewState )
{
	for( sal_uInt16 i = 0; i < pMethods->Count(); )
	{
		SbMethod* p = PTR_CAST(SbMethod,pMethods->Get( i ) );
		if( p )
		{
			if( p->bInvalid )
				pMethods->Remove( p );
			else
			{
				p->bInvalid = bNewState;
				i++;
			}
		}
		else
			i++;
	}
	SetModified( sal_True );
}

void SbModule::Clear()
{
	delete pImage; pImage = NULL;
	if( pClassData )
		pClassData->clear();
	SbxObject::Clear();
}


SbxVariable* SbModule::Find( const XubString& rName, SbxClassType t )
{
	// make sure a search in an uninstatiated class module will fail
	SbxVariable* pRes = SbxObject::Find( rName, t );
	if ( bIsProxyModule && !GetSbData()->bRunInit )
		return NULL;
	if( !pRes && pImage )
	{
		SbiInstance* pInst = pINST;
		if( pInst && pInst->IsCompatibility() )
		{
			// Put enum types as objects into module,
			// allows MyEnum.First notation
			SbxArrayRef xArray = pImage->GetEnums();
			if( xArray.Is() )
			{
				SbxVariable* pEnumVar = xArray->Find( rName, SbxCLASS_DONTCARE );
				SbxObject* pEnumObject = PTR_CAST( SbxObject, pEnumVar );
				if( pEnumObject )
				{
					bool bPrivate = pEnumObject->IsSet( SBX_PRIVATE );
					String aEnumName = pEnumObject->GetName();

					pRes = new SbxVariable( SbxOBJECT );
					pRes->SetName( aEnumName );
					pRes->SetParent( this );
					pRes->SetFlag( SBX_READ );
					if( bPrivate )
						pRes->SetFlag( SBX_PRIVATE );
					pRes->PutObject( pEnumObject );
				}
			}
		}
	}
	return pRes;
}

const ::rtl::OUString& SbModule::GetSource32() const
{
	return aOUSource;
}

const String& SbModule::GetSource() const
{
    static String aRetStr;
    aRetStr = aOUSource;
	return aRetStr;
}

// Parent und BASIC sind eins!

void SbModule::SetParent( SbxObject* p )
{
	// #118083: Assertion is not valid any more
	// DBG_ASSERT( !p || p->IsA( TYPE(StarBASIC) ), "SbModules nur in BASIC eintragen" );
	pParent = p;
}

void SbModule::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();
		SbProperty* pProp = PTR_CAST(SbProperty,pVar);
		SbMethod* pMeth = PTR_CAST(SbMethod,pVar);
		if( pProp )
		{
			if( pProp->GetModule() != this )
				SetError( SbxERR_BAD_ACTION );
		}
		else if( pMeth )
		{
			if( pHint->GetId() == SBX_HINT_DATAWANTED )
			{
				if( pMeth->bInvalid && !Compile() )
					// Auto-Compile hat nicht geklappt!
					StarBASIC::Error( SbERR_BAD_PROP_VALUE );
				else
				{
					// Aufruf eines Unterprogramms
					SbModule* pOld = pMOD;
					pMOD = this;
					Run( (SbMethod*) pVar );
					pMOD = pOld;
				}
			}
		}
		else
		{
			// #i92642: Special handling for name property to avoid
			// side effects when using name as variable implicitly
			bool bForwardToSbxObject = true;

			sal_uIntPtr nId = pHint->GetId();
			if( (nId == SBX_HINT_DATAWANTED || nId == SBX_HINT_DATACHANGED) &&
				pVar->GetName().EqualsIgnoreCaseAscii( "name" ) )
					bForwardToSbxObject = false;

			if( bForwardToSbxObject )
				SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
		}
	}
}

// Das Setzen der Source macht das Image ungueltig
// und scant die Methoden-Definitionen neu ein

void SbModule::SetSource( const String& r )
{
    SetSource32( r );
}

void SbModule::SetSource32( const ::rtl::OUString& r )
{
	// Default basic mode to library container mode, but.. allow Option VBASupport 0/1 override
    SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) );
	aOUSource = r;
	StartDefinitions();
	SbiTokenizer aTok( r );
	while( !aTok.IsEof() )
	{
		SbiToken eEndTok = NIL;

		// Suchen nach SUB oder FUNCTION
		SbiToken eLastTok = NIL;
		while( !aTok.IsEof() )
		{
			// #32385: Nicht bei declare
			SbiToken eCurTok = aTok.Next();
			if( eLastTok != DECLARE )
			{
				if( eCurTok == SUB )
				{
					eEndTok = ENDSUB; break;
				}
				if( eCurTok == FUNCTION )
				{
					eEndTok = ENDFUNC; break;
				}
				if( eCurTok == PROPERTY )
				{
					eEndTok = ENDPROPERTY; break;
				}
				if( eCurTok == OPTION )
				{
					eCurTok = aTok.Next();
					if( eCurTok == COMPATIBLE )
						aTok.SetCompatible( true );
					else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) )
					{
        					sal_Bool bIsVBA = ( aTok.GetDbl()== 1 );
        					SetVBACompat( bIsVBA );
						aTok.SetCompatible( bIsVBA );
					}
				}
			}
			eLastTok = eCurTok;
		}
		// Definition der Methode
		SbMethod* pMeth = NULL;
		if( eEndTok != NIL )
		{
			sal_uInt16 nLine1 = aTok.GetLine();
			if( aTok.Next() == SYMBOL )
			{
				String aName_( aTok.GetSym() );
				SbxDataType t = aTok.GetType();
				if( t == SbxVARIANT && eEndTok == ENDSUB )
					t = SbxVOID;
				pMeth = GetMethod( aName_, t );
				pMeth->nLine1 = pMeth->nLine2 = nLine1;
				// Die Methode ist erst mal GUELTIG
				pMeth->bInvalid = sal_False;
			}
			else
				eEndTok = NIL;
		}
		// Skip bis END SUB/END FUNCTION
		if( eEndTok != NIL )
		{
			while( !aTok.IsEof() )
			{
				if( aTok.Next() == eEndTok )
				{
					pMeth->nLine2 = aTok.GetLine();
					break;
				}
			}
			if( aTok.IsEof() )
				pMeth->nLine2 = aTok.GetLine();
		}
	}
	EndDefinitions( sal_True );
}

void SbModule::SetComment( const String& r )
{
	aComment = r;
	SetModified( sal_True );
}

SbMethod* SbModule::GetFunctionForLine( sal_uInt16 nLine )
{
	for( sal_uInt16 i = 0; i < pMethods->Count(); i++ )
	{
		SbMethod* p = (SbMethod*) pMethods->Get( i );
		if( p->GetSbxId() == SBXID_BASICMETHOD )
		{
			if( nLine >= p->nLine1 && nLine <= p->nLine2 )
				return p;
		}
	}
	return NULL;
}

// Ausstrahlen eines Hints an alle Basics

static void _SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
{
	// Selbst ein BASIC?
	if( pObj->IsA( TYPE(StarBASIC) ) && pObj->IsBroadcaster() )
		pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) );
	// Dann die Unterobjekte fragen
	SbxArray* pObjs = pObj->GetObjects();
	for( sal_uInt16 i = 0; i < pObjs->Count(); i++ )
	{
		SbxVariable* pVar = pObjs->Get( i );
		if( pVar->IsA( TYPE(SbxObject) ) )
			_SendHint( PTR_CAST(SbxObject,pVar), nId, p );
	}
}

static void SendHint( SbxObject* pObj, sal_uIntPtr nId, SbMethod* p )
{
	while( pObj->GetParent() )
		pObj = pObj->GetParent();
	_SendHint( pObj, nId, p );
}

// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
// beim Programm-Ende freigeben, damit nichts gehalten wird.
void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic )
{
	// return-Wert von CreateUnoService loeschen
	static String aName( RTL_CONSTASCII_USTRINGPARAM("CreateUnoService") );
	SbxVariable* pVar = pBasic->GetRtl()->Find( aName, SbxCLASS_METHOD );
	if( pVar )
		pVar->SbxValue::Clear();

	// return-Wert von CreateUnoDialog loeschen
	static String aName2( RTL_CONSTASCII_USTRINGPARAM("CreateUnoDialog") );
	pVar = pBasic->GetRtl()->Find( aName2, SbxCLASS_METHOD );
	if( pVar )
		pVar->SbxValue::Clear();

	// return-Wert von CDec loeschen
	static String aName3( RTL_CONSTASCII_USTRINGPARAM("CDec") );
	pVar = pBasic->GetRtl()->Find( aName3, SbxCLASS_METHOD );
	if( pVar )
		pVar->SbxValue::Clear();

	// return-Wert von CreateObject loeschen
	static String aName4( RTL_CONSTASCII_USTRINGPARAM("CreateObject") );
	pVar = pBasic->GetRtl()->Find( aName4, SbxCLASS_METHOD );
	if( pVar )
		pVar->SbxValue::Clear();

	// Ueber alle Sub-Basics gehen
	SbxArray* pObjs = pBasic->GetObjects();
	sal_uInt16 nCount = pObjs->Count();
	for( sal_uInt16 i = 0 ; i < nCount ; i++ )
	{
		SbxVariable* pObjVar = pObjs->Get( i );
		StarBASIC* pSubBasic = PTR_CAST( StarBASIC, pObjVar );
		if( pSubBasic )
			ClearUnoObjectsInRTL_Impl_Rek( pSubBasic );
	}
}

void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic )
{
	// #67781 Rueckgabewerte der Uno-Methoden loeschen
	clearUnoMethods();
	clearUnoServiceCtors();

	ClearUnoObjectsInRTL_Impl_Rek( pBasic );

    // Oberstes Basic suchen
	SbxObject* p = pBasic;
	while( p->GetParent() )
		p = p->GetParent();
    if( ((StarBASIC*)p) != pBasic )
	    ClearUnoObjectsInRTL_Impl_Rek( (StarBASIC*)p );
}
sal_Bool SbModule::IsVBACompat() const
{
	return mbVBACompat;
}

void SbModule::SetVBACompat( sal_Bool bCompat )
{
    if( mbVBACompat != bCompat )
    {
        mbVBACompat = bCompat;
        // initialize VBA document API
        if( mbVBACompat ) try
        {
            StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
            uno::Reference< lang::XMultiServiceFactory > xFactory( getDocumentModel( pBasic ), uno::UNO_QUERY_THROW );
            xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
        }
        catch( Exception& )
        {
        }
    }
}

// Ausfuehren eines BASIC-Unterprogramms
sal_uInt16 SbModule::Run( SbMethod* pMeth )
{
	static sal_uInt16 nMaxCallLevel = 0;
	static String aMSOMacroRuntimeLibName = String::CreateFromAscii( "Launcher" );
	static String aMSOMacroRuntimeAppSymbol = String::CreateFromAscii( "Application" );

	sal_uInt16 nRes = 0;
	sal_Bool bDelInst = sal_Bool( pINST == NULL );
	StarBASICRef xBasic;
	uno::Reference< frame::XModel > xModel;
	uno::Reference< script::vba::XVBACompatibility > xVBACompat;
	if( bDelInst )
	{
#ifdef DBG_TRACE_BASIC
		dbg_InitTrace();
#endif
		// #32779: Basic waehrend der Ausfuehrung festhalten
		xBasic = (StarBASIC*) GetParent();

		pINST = new SbiInstance( (StarBASIC*) GetParent() );

        /*  If a VBA script in a document is started, get the VBA compatibility
            interface from the document Basic library container, and notify all
            VBA script listeners about the started script. */
        if( mbVBACompat )
        {
            StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() );
            if( pBasic && pBasic->IsDocBasic() ) try
            {
                xModel.set( getDocumentModel( pBasic ), uno::UNO_SET_THROW );
                xVBACompat.set( getVBACompatibility( xModel ), uno::UNO_SET_THROW );
                xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::SCRIPT_STARTED, GetName() );
            }
            catch( uno::Exception& )
            {
            }
        }

		// Launcher problem
        // i80726 The Find below will genarate an error in Testtool so we reset it unless there was one before already
        sal_Bool bWasError = SbxBase::GetError() != 0;
		SbxVariable* pMSOMacroRuntimeLibVar = Find( aMSOMacroRuntimeLibName, SbxCLASS_OBJECT );
        if ( !bWasError && (SbxBase::GetError() == SbxERR_PROC_UNDEFINED) )
            SbxBase::ResetError();
		if( pMSOMacroRuntimeLibVar )
		{
			StarBASIC* pMSOMacroRuntimeLib = PTR_CAST(StarBASIC,pMSOMacroRuntimeLibVar);
			if( pMSOMacroRuntimeLib )
			{
				sal_uInt16 nGblFlag = pMSOMacroRuntimeLib->GetFlags() & SBX_GBLSEARCH;
				pMSOMacroRuntimeLib->ResetFlag( SBX_GBLSEARCH );
				SbxVariable* pAppSymbol = pMSOMacroRuntimeLib->Find( aMSOMacroRuntimeAppSymbol, SbxCLASS_METHOD );
				pMSOMacroRuntimeLib->SetFlag( nGblFlag );
				if( pAppSymbol )
				{
					pMSOMacroRuntimeLib->SetFlag( SBX_EXTSEARCH );		// Could have been disabled before
					GetSbData()->pMSOMacroRuntimLib = pMSOMacroRuntimeLib;
				}
			}
		}

		// Error-Stack loeschen
		SbErrorStack*& rErrStack = GetSbData()->pErrStack;
		delete rErrStack;
		rErrStack = NULL;

		if( nMaxCallLevel == 0 )
		{
#ifdef UNX
		  struct rlimit rl;
		  getrlimit ( RLIMIT_STACK, &rl );
		  // printf( "RLIMIT_STACK = %ld\n", rl.rlim_cur );
#endif
#if defined LINUX
		  // Empiric value, 900 = needed bytes/Basic call level
		  // for Linux including 10% safety margin
		  nMaxCallLevel = rl.rlim_cur / 900;
#elif defined SOLARIS
		  // Empiric value, 1650 = needed bytes/Basic call level
		  // for Solaris including 10% safety margin
		  nMaxCallLevel = rl.rlim_cur / 1650;
#elif defined WIN32
		  nMaxCallLevel = 5800;
#else
		  nMaxCallLevel = MAXRECURSION;
#endif
		}
	}

	// Rekursion zu tief?
	if( ++pINST->nCallLvl <= nMaxCallLevel )
	{
		// Globale Variable in allen Mods definieren
		GlobalRunInit( /* bBasicStart = */ bDelInst );

		// Trat ein Compiler-Fehler auf? Dann starten wir nicht
		if( GetSbData()->bGlobalInitErr == sal_False )
		{
			if( bDelInst )
			{
				SendHint( GetParent(), SBX_HINT_BASICSTART, pMeth );

				// 16.10.96: #31460 Neues Konzept fuer StepInto/Over/Out
				// Erklaerung siehe runtime.cxx bei SbiInstance::CalcBreakCallLevel()
				// BreakCallLevel ermitteln
				pINST->CalcBreakCallLevel( pMeth->GetDebugFlags() );
			}

			SbModule* pOldMod = pMOD;
			pMOD = this;
			SbiRuntime* pRt = new SbiRuntime( this, pMeth, pMeth->nStart );

#ifdef DBG_TRACE_BASIC
			dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl );
#endif

			pRt->pNext = pINST->pRun;
			if( pRt->pNext )
				pRt->pNext->block();
			pINST->pRun = pRt;
			if ( mbVBACompat )
			{
				pINST->EnableCompatibility( sal_True );
			}
			while( pRt->Step() ) {}
			if( pRt->pNext )
				pRt->pNext->unblock();

#ifdef DBG_TRACE_BASIC
			bool bLeave = true;
			dbg_traceNotifyCall( this, pMeth, pINST->nCallLvl, bLeave );
#endif

			// #63710 Durch ein anderes Thread-Handling bei Events kann es passieren,
			// dass show-Aufruf an einem Dialog zurueckkehrt (durch schliessen des
			// Dialogs per UI), BEVOR ein per Event ausgeloester weitergehender Call,
			// der in Basic weiter oben im Stack steht und auf einen Basic-Breakpoint
			// gelaufen ist, zurueckkehrt. Dann wird unten die Instanz zerstoert und
			// wenn das noch im Call stehende Basic weiterlaeuft, gibt es einen GPF.
			// Daher muss hier gewartet werden, bis andere Call zurueckkehrt.
			if( bDelInst )
			{
				// Hier mit 1 statt 0 vergleichen, da vor nCallLvl--
				while( pINST->nCallLvl != 1 )
					GetpApp()->Yield();
			}

			nRes = sal_True;
			pINST->pRun = pRt->pNext;
			pINST->nCallLvl--;			// Call-Level wieder runter

			// Gibt es eine uebergeordnete Runtime-Instanz?
			// Dann SbDEBUG_BREAK uebernehmen, wenn gesetzt
			SbiRuntime* pRtNext = pRt->pNext;
			if( pRtNext && (pRt->GetDebugFlags() & SbDEBUG_BREAK) )
				pRtNext->SetDebugFlags( SbDEBUG_BREAK );

			delete pRt;
			pMOD = pOldMod;
			if( bDelInst )
			{
				// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
				// beim Programm-Ende freigeben, damit nichts gehalten wird.
				ClearUnoObjectsInRTL_Impl( xBasic );

				clearNativeObjectWrapperVector();

				DBG_ASSERT(pINST->nCallLvl==0,"BASIC-Call-Level > 0");
				delete pINST, pINST = NULL, bDelInst = sal_False;

				// #i30690
				vos::OGuard aSolarGuard( Application::GetSolarMutex() );
				SendHint( GetParent(), SBX_HINT_BASICSTOP, pMeth );

		        GlobalRunDeInit();

#ifdef DBG_UTIL
                ResetCapturedAssertions();
#endif

                if( xVBACompat.is() )
                {
                    // notify all VBA script listeners about the stopped script
                    try
                    {
                        xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::SCRIPT_STOPPED, GetName() );
                    }
                    catch( uno::Exception& )
                    {
                    }
                    // VBA always ensures screenupdating is enabled after completing
                    ::basic::vba::lockControllersOfAllDocuments( xModel, sal_False );
                    ::basic::vba::enableContainerWindowsOfAllDocuments( xModel, sal_True );
                }

#ifdef DBG_TRACE_BASIC
				dbg_DeInitTrace();
#endif
			}
        }
        else
   			pINST->nCallLvl--;			// Call-Level wieder runter
	}
	else
    {
		pINST->nCallLvl--;			// Call-Level wieder runter
		StarBASIC::FatalError( SbERR_STACK_OVERFLOW );
    }

	StarBASIC* pBasic = PTR_CAST(StarBASIC,GetParent());
	if( bDelInst )
	{
		// #57841 Uno-Objekte, die in RTL-Funktionen gehalten werden,
		// beim Programm-Ende freigeben, damit nichts gehalten wird.
		ClearUnoObjectsInRTL_Impl( xBasic );

		delete pINST;
		pINST = NULL;
	}
	if ( pBasic && pBasic->IsDocBasic() && pBasic->IsQuitApplication() && !pINST )
	{
		Application::PostUserEvent( LINK( &AsyncQuitHandler::instance(), AsyncQuitHandler, OnAsyncQuit ), NULL );
	}

	return nRes;
}

// Ausfuehren der Init-Methode eines Moduls nach dem Laden
// oder der Compilation

void SbModule::RunInit()
{
	if( pImage
	 && !pImage->bInit
	 && pImage->GetFlag( SBIMG_INITCODE ) )
	{
		// Flag setzen, dass RunInit aktiv ist (Testtool)
		GetSbData()->bRunInit = sal_True;

		// sal_Bool bDelInst = sal_Bool( pINST == NULL );
		// if( bDelInst )
			// pINST = new SbiInstance( (StarBASIC*) GetParent() );
		SbModule* pOldMod = pMOD;
		pMOD = this;
		// Der Init-Code beginnt immer hier
		SbiRuntime* pRt = new SbiRuntime( this, NULL, 0 );

#ifdef DBG_TRACE_BASIC
		dbg_traceNotifyCall( this, NULL, 0 );
#endif

		pRt->pNext = pINST->pRun;
		pINST->pRun = pRt;
		while( pRt->Step() ) {}

#ifdef DBG_TRACE_BASIC
		bool bLeave = true;
		dbg_traceNotifyCall( this, NULL, 0, bLeave );
#endif

		pINST->pRun = pRt->pNext;
		delete pRt;
		pMOD = pOldMod;
		// if( bDelInst )
			// delete pINST, pINST = NULL;
		pImage->bInit = sal_True;
        pImage->bFirstInit = sal_False;

		// RunInit ist nicht mehr aktiv
		GetSbData()->bRunInit = sal_False;
	}
}

// Mit private/dim deklarierte Variablen loeschen

void SbModule::AddVarName( const String& aName )
{
    // see if the name is added already
    std::vector< String >::iterator it_end = mModuleVariableNames.end();
    for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
    {
        if ( aName == *it )
            return;
    }
    mModuleVariableNames.push_back( aName );
}

void SbModule::RemoveVars()
{
    std::vector< String >::iterator it_end = mModuleVariableNames.end();
    for ( std::vector< String >::iterator it = mModuleVariableNames.begin(); it != it_end; ++it )
    {
    // We don't want a Find being called in a derived class ( e.g.
    // SbUserform because it could trigger say an initialise event
    // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile )
    SbxVariableRef p = SbModule::Find( *it, SbxCLASS_PROPERTY );
    if( p.Is() )
        Remove (p);
    }
}

void SbModule::ClearPrivateVars()
{
	for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
	{
		SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
		if( p )
		{
			// Arrays nicht loeschen, sondern nur deren Inhalt
			if( p->GetType() & SbxARRAY )
			{
				SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
				if( pArray )
				{
					for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
					{
						SbxVariable* pj = PTR_CAST(SbxVariable,pArray->Get( j ));
						pj->SbxValue::Clear();
						/*
						sal_uInt16 nFlags = pj->GetFlags();
						pj->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
						pj->PutEmpty();
						pj->SetFlags( nFlags );
						*/
					}
				}
			}
			else
			{
				p->SbxValue::Clear();
				/*
				sal_uInt16 nFlags = p->GetFlags();
				p->SetFlags( (nFlags | SBX_WRITE) & (~SBX_FIXED) );
				p->PutEmpty();
				p->SetFlags( nFlags );
				*/
			}
		}
	}
}

void SbModule::implClearIfVarDependsOnDeletedBasic( SbxVariable* pVar, StarBASIC* pDeletedBasic )
{
	if( pVar->SbxValue::GetType() != SbxOBJECT || pVar->ISA( SbProcedureProperty ) )
		return;

	SbxObject* pObj = PTR_CAST(SbxObject,pVar->GetObject());
	if( pObj != NULL )
	{
		SbxObject* p = pObj;

		SbModule* pMod = PTR_CAST( SbModule, p );
		if( pMod != NULL )
			pMod->ClearVarsDependingOnDeletedBasic( pDeletedBasic );

		while( (p = p->GetParent()) != NULL )
		{
			StarBASIC* pBasic = PTR_CAST( StarBASIC, p );
			if( pBasic != NULL && pBasic == pDeletedBasic )
			{
				pVar->SbxValue::Clear();
				break;
			}
		}
	}
}

void SbModule::ClearVarsDependingOnDeletedBasic( StarBASIC* pDeletedBasic )
{
	(void)pDeletedBasic;

	for( sal_uInt16 i = 0 ; i < pProps->Count() ; i++ )
	{
		SbProperty* p = PTR_CAST(SbProperty,pProps->Get( i ) );
		if( p )
		{
			if( p->GetType() & SbxARRAY )
			{
				SbxArray* pArray = PTR_CAST(SbxArray,p->GetObject());
				if( pArray )
				{
					for( sal_uInt16 j = 0 ; j < pArray->Count() ; j++ )
					{
						SbxVariable* pVar = PTR_CAST(SbxVariable,pArray->Get( j ));
						implClearIfVarDependsOnDeletedBasic( pVar, pDeletedBasic );
					}
				}
			}
			else
			{
				implClearIfVarDependsOnDeletedBasic( p, pDeletedBasic );
			}
		}
	}
}

// Zunaechst in dieses Modul, um 358-faehig zu bleiben
// (Branch in sb.cxx vermeiden)
void StarBASIC::ClearAllModuleVars( void )
{
	// Eigene Module initialisieren
	for ( sal_uInt16 nMod = 0; nMod < pModules->Count(); nMod++ )
	{
		SbModule* pModule = (SbModule*)pModules->Get( nMod );
		// Nur initialisieren, wenn der Startcode schon ausgefuehrt wurde
		if( pModule->pImage && pModule->pImage->bInit && !pModule->isProxyModule() && !pModule->ISA(SbObjModule) )
			pModule->ClearPrivateVars();
	}

    /* #88042 This code can delete already used public vars during runtime!
	// Alle Objekte ueberpruefen, ob es sich um ein Basic handelt
	// Wenn ja, auch dort initialisieren
	for ( sal_uInt16 nObj = 0; nObj < pObjs->Count(); nObj++ )
	{
		SbxVariable* pVar = pObjs->Get( nObj );
		StarBASIC* pBasic = PTR_CAST(StarBASIC,pVar);
		if( pBasic )
			pBasic->ClearAllModuleVars();
	}
    */
}

// Ausfuehren des Init-Codes aller Module
void SbModule::GlobalRunInit( sal_Bool bBasicStart )
{
	// Wenn kein Basic-Start, nur initialisieren, wenn Modul uninitialisiert
	if( !bBasicStart )
		if( !(pImage && !pImage->bInit) )
			return;

	// GlobalInitErr-Flag fuer Compiler-Error initialisieren
	// Anhand dieses Flags kann in SbModule::Run() nach dem Aufruf
	// von GlobalRunInit festgestellt werden, ob beim initialisieren
	// der Module ein Fehler auftrat. Dann wird nicht gestartet.
	GetSbData()->bGlobalInitErr = sal_False;

	// Parent vom Modul ist ein Basic
	StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
	if( pBasic )
	{
		pBasic->InitAllModules();

		SbxObject* pParent_ = pBasic->GetParent();
		if( pParent_ )
		{
			StarBASIC * pParentBasic = PTR_CAST(StarBASIC,pParent_);
			if( pParentBasic )
			{
				pParentBasic->InitAllModules( pBasic );

				// #109018 Parent can also have a parent (library in doc)
				SbxObject* pParentParent = pParentBasic->GetParent();
				if( pParentParent )
				{
					StarBASIC * pParentParentBasic = PTR_CAST(StarBASIC,pParentParent);
					if( pParentParentBasic )
						pParentParentBasic->InitAllModules( pParentBasic );
				}
			}
		}
	}
}

void SbModule::GlobalRunDeInit( void )
{
	StarBASIC *pBasic = PTR_CAST(StarBASIC,GetParent());
	if( pBasic )
	{
		pBasic->DeInitAllModules();

		SbxObject* pParent_ = pBasic->GetParent();
		if( pParent_ )
			pBasic = PTR_CAST(StarBASIC,pParent_);
		if( pBasic )
			pBasic->DeInitAllModules();
	}
}

// Suche nach dem naechsten STMNT-Befehl im Code. Wird vom STMNT-
// Opcode verwendet, um die Endspalte zu setzen.

const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol ) const
{
	return FindNextStmnt( p, nLine, nCol, sal_False );
}

const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol,
	sal_Bool bFollowJumps, const SbiImage* pImg ) const
{
	sal_uInt32 nPC = (sal_uInt32) ( p - (const sal_uInt8*) pImage->GetCode() );
	while( nPC < pImage->GetCodeSize() )
	{
		SbiOpcode eOp = (SbiOpcode ) ( *p++ );
		nPC++;
		if( bFollowJumps && eOp == _JUMP && pImg )
		{
			DBG_ASSERT( pImg, "FindNextStmnt: pImg==NULL with FollowJumps option" );
			sal_uInt32 nOp1 = *p++; nOp1 |= *p++ << 8;
			nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
			p = (const sal_uInt8*) pImg->GetCode() + nOp1;
		}
		else if( eOp >= SbOP1_START && eOp <= SbOP1_END )
			p += 4, nPC += 4;
		else if( eOp == _STMNT )
		{
			sal_uInt32 nl, nc;
			nl = *p++; nl |= *p++ << 8;
			nl |= *p++ << 16 ; nl |= *p++ << 24;
			nc = *p++; nc |= *p++ << 8;
			nc |= *p++ << 16 ; nc |= *p++ << 24;
			nLine = (sal_uInt16)nl; nCol = (sal_uInt16)nc;
			return p;
		}
		else if( eOp >= SbOP2_START && eOp <= SbOP2_END )
			p += 8, nPC += 8;
		else if( !( eOp >= SbOP0_START && eOp <= SbOP0_END ) )
		{
			StarBASIC::FatalError( SbERR_INTERNAL_ERROR );
			break;
		}
	}
	return NULL;
}

// Testen, ob eine Zeile STMNT-Opcodes enthaelt

sal_Bool SbModule::IsBreakable( sal_uInt16 nLine ) const
{
	if( !pImage )
		return sal_False;
	const sal_uInt8* p = (const sal_uInt8* ) pImage->GetCode();
	sal_uInt16 nl, nc;
	while( ( p = FindNextStmnt( p, nl, nc ) ) != NULL )
		if( nl == nLine )
			return sal_True;
	return sal_False;
}

size_t SbModule::GetBPCount() const
{
	return pBreaks ? pBreaks->size() : 0;
}

sal_uInt16 SbModule::GetBP( size_t n ) const
{
	if( pBreaks && n < pBreaks->size() )
		return pBreaks->operator[]( n );
	else
		return 0;
}

sal_Bool SbModule::IsBP( sal_uInt16 nLine ) const
{
	if( pBreaks )
	{
		for( size_t i = 0; i < pBreaks->size(); i++ )
		{
			sal_uInt16 b = pBreaks->operator[]( i );
			if( b == nLine )
				return sal_True;
			if( b < nLine )
				break;
		}
	}
	return sal_False;
}

sal_Bool SbModule::SetBP( sal_uInt16 nLine )
{
	if( !IsBreakable( nLine ) )
		return sal_False;
	if( !pBreaks )
		pBreaks = new SbiBreakpoints;
	size_t i;
	for( i = 0; i < pBreaks->size(); i++ )
	{
		sal_uInt16 b = pBreaks->operator[]( i );
		if( b == nLine )
			return sal_True;
		if( b < nLine )
			break;
	}
	pBreaks->insert( pBreaks->begin() + i, nLine );

	// #38568: Zur Laufzeit auch hier SbDEBUG_BREAK setzen
	if( pINST && pINST->pRun )
		pINST->pRun->SetDebugFlags( SbDEBUG_BREAK );

	return IsBreakable( nLine );
}

sal_Bool SbModule::ClearBP( sal_uInt16 nLine )
{
	sal_Bool bRes = sal_False;
	if( pBreaks )
	{
		for( size_t i = 0; i < pBreaks->size(); i++ )
		{
			sal_uInt16 b = pBreaks->operator[]( i );
			if( b == nLine )
			{
				pBreaks->erase( pBreaks->begin() + i );
				bRes = sal_True;
				break;
			}
			if( b < nLine )
				break;
		}
		if( pBreaks->empty() )
			delete pBreaks, pBreaks = NULL;
	}
	return bRes;
}

void SbModule::ClearAllBP()
{
	delete pBreaks;
	pBreaks = NULL;
}

void
SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const
{
		if ( !pImg )
			pImg = pImage;
		for( sal_uInt32 i = 0; i < pMethods->Count(); i++ )
		{
			SbMethod* pMeth = PTR_CAST(SbMethod,pMethods->Get( (sal_uInt16)i ) );
			if( pMeth )
			{
				//fixup method start positions
				if ( bCvtToLegacy )
					pMeth->nStart = pImg->CalcLegacyOffset( pMeth->nStart );
				else
					pMeth->nStart = pImg->CalcNewOffset( (sal_uInt16)pMeth->nStart );
			}
		}

}

sal_Bool SbModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
{
	Clear();
	if( !SbxObject::LoadData( rStrm, 1 ) )
		return sal_False;
	// Precaution...
	SetFlag( SBX_EXTSEARCH | SBX_GBLSEARCH );
	sal_uInt8 bImage;
	rStrm >> bImage;
	if( bImage )
	{
		SbiImage* p = new SbiImage;
		sal_uInt32 nImgVer = 0;

		if( !p->Load( rStrm, nImgVer ) )
		{
			delete p;
			return sal_False;
		}
		// If the image is in old format, we fix up the method start offsets
		if ( nImgVer < B_EXT_IMG_VERSION )
		{
			fixUpMethodStart( false, p );
			p->ReleaseLegacyBuffer();
		}
		aComment = p->aComment;
		SetName( p->aName );
		if( p->GetCodeSize() )
		{
			aOUSource = p->aOUSource;
			// Alte Version: Image weg
			if( nVer == 1 )
			{
				SetSource32( p->aOUSource );
				delete p;
			}
			else
				pImage = p;
		}
		else
		{
			SetSource32( p->aOUSource );
			delete p;
		}
	}
	return sal_True;
}

sal_Bool SbModule::StoreData( SvStream& rStrm ) const
{
	sal_Bool bFixup = ( pImage && !pImage->ExceedsLegacyLimits() );
	if ( bFixup )
		fixUpMethodStart( true );
	sal_Bool bRet = SbxObject::StoreData( rStrm );
	if ( !bRet )
		return sal_False;

	if( pImage )
	{
		pImage->aOUSource = aOUSource;
		pImage->aComment = aComment;
		pImage->aName = GetName();
		rStrm << (sal_uInt8) 1;
		// # PCode is saved only for legacy formats only
		// It should be noted that it probably isn't necessary
		// It would be better not to store the image ( more flexible with
		// formats )
		bool bRes = pImage->Save( rStrm, B_LEGACYVERSION );
		if ( bFixup )
			fixUpMethodStart( false ); // restore method starts
		return bRes;

	}
	else
	{
		SbiImage aImg;
		aImg.aOUSource = aOUSource;
		aImg.aComment = aComment;
		aImg.aName = GetName();
		rStrm << (sal_uInt8) 1;
		return aImg.Save( rStrm );
	}
}

sal_Bool SbModule::ExceedsLegacyModuleSize()
{
	if ( !IsCompiled() )
		Compile();
	if ( pImage && pImage->ExceedsLegacyLimits() )
		return true;
	return false;
}


// Store only image, no source
sal_Bool SbModule::StoreBinaryData( SvStream& rStrm )
{
	return StoreBinaryData( rStrm, 0 );
}

sal_Bool SbModule::StoreBinaryData( SvStream& rStrm, sal_uInt16 nVer )
{
    sal_Bool bRet = Compile();
    if( bRet )
    {
		sal_Bool bFixup = ( !nVer && !pImage->ExceedsLegacyLimits() );// save in old image format, fix up method starts

		if ( bFixup ) // save in old image format, fix up method starts
			fixUpMethodStart( true );
     	bRet = SbxObject::StoreData( rStrm );
        if( bRet )
        {
		    pImage->aOUSource = ::rtl::OUString();
		    pImage->aComment = aComment;
		    pImage->aName = GetName();

		    rStrm << (sal_uInt8) 1;
                    if ( nVer )
						bRet = pImage->Save( rStrm, B_EXT_IMG_VERSION );
                    else
                        bRet = pImage->Save( rStrm, B_LEGACYVERSION );
                    if ( bFixup )
                        fixUpMethodStart( false ); // restore method starts

		    pImage->aOUSource = aOUSource;
        }
    }
    return bRet;
}

// Called for >= OO 1.0 passwd protected libraries only
//

sal_Bool SbModule::LoadBinaryData( SvStream& rStrm )
{
	::rtl::OUString aKeepSource = aOUSource;
    bool bRet = LoadData( rStrm, 2 );
	LoadCompleted();
    aOUSource = aKeepSource;
    return bRet;
}


sal_Bool SbModule::LoadCompleted()
{
	SbxArray* p = GetMethods();
	sal_uInt16 i;
	for( i = 0; i < p->Count(); i++ )
	{
		SbMethod* q = PTR_CAST(SbMethod,p->Get( i ) );
		if( q )
			q->pMod = this;
	}
	p = GetProperties();
	for( i = 0; i < p->Count(); i++ )
	{
		SbProperty* q = PTR_CAST(SbProperty,p->Get( i ) );
		if( q )
			q->pMod = this;
	}
	return sal_True;
}

void SbModule::handleProcedureProperties( SfxBroadcaster& rBC, const SfxHint& rHint )
{
	bool bDone = false;

	const SbxHint* pHint = PTR_CAST(SbxHint,&rHint);
	if( pHint )
	{
		SbxVariable* pVar = pHint->GetVar();
		SbProcedureProperty* pProcProperty = PTR_CAST( SbProcedureProperty, pVar );
		if( pProcProperty )
		{
			bDone = true;

			if( pHint->GetId() == SBX_HINT_DATAWANTED )
			{
				String aProcName;
				aProcName.AppendAscii( "Property Get " );
				aProcName += pProcProperty->GetName();

				SbxVariable* pMeth = Find( aProcName, SbxCLASS_METHOD );
				if( pMeth )
				{
					SbxValues aVals;
					aVals.eType = SbxVARIANT;

					SbxArray* pArg = pVar->GetParameters();
					sal_uInt16 nVarParCount = (pArg != NULL) ? pArg->Count() : 0;
					if( nVarParCount > 1 )
					{
						SbxArrayRef xMethParameters = new SbxArray;
						xMethParameters->Put( pMeth, 0 );	// Method as parameter 0
						for( sal_uInt16 i = 1 ; i < nVarParCount ; ++i )
						{
							SbxVariable* pPar = pArg->Get( i );
							xMethParameters->Put( pPar, i );
						}

						pMeth->SetParameters( xMethParameters );
						pMeth->Get( aVals );
						pMeth->SetParameters( NULL );
					}
					else
					{
						pMeth->Get( aVals );
					}

					pVar->Put( aVals );
				}
			}
			else if( pHint->GetId() == SBX_HINT_DATACHANGED )
			{
				SbxVariable* pMeth = NULL;

				bool bSet = pProcProperty->isSet();
				if( bSet )
				{
					pProcProperty->setSet( false );

					String aProcName;
					aProcName.AppendAscii( "Property Set " );
					aProcName += pProcProperty->GetName();
					pMeth = Find( aProcName, SbxCLASS_METHOD );
				}
				if( !pMeth )	// Let
				{
					String aProcName;
					aProcName.AppendAscii( "Property Let " );
					aProcName += pProcProperty->GetName();
					pMeth = Find( aProcName, SbxCLASS_METHOD );
				}

				if( pMeth )
				{
					// Setup parameters
					SbxArrayRef xArray = new SbxArray;
					xArray->Put( pMeth, 0 );	// Method as parameter 0
					xArray->Put( pVar, 1 );
					pMeth->SetParameters( xArray );

					SbxValues aVals;
					pMeth->Get( aVals );
					pMeth->SetParameters( NULL );
				}
			}
		}
	}

	if( !bDone )
		SbModule::Notify( rBC, rHint );
}


/////////////////////////////////////////////////////////////////////////
// Implementation SbJScriptModule (Basic-Modul fuer JavaScript-Sourcen)
SbJScriptModule::SbJScriptModule( const String& rName )
	:SbModule( rName )
{
}

sal_Bool SbJScriptModule::LoadData( SvStream& rStrm, sal_uInt16 nVer )
{
    (void)nVer;

	Clear();
	if( !SbxObject::LoadData( rStrm, 1 ) )
		return sal_False;

	// Source-String holen
    String aTmp;
	rStrm.ReadByteString( aTmp, gsl_getSystemTextEncoding() );
    aOUSource = aTmp;
	//rStrm >> aSource;
	return sal_True;
}

sal_Bool SbJScriptModule::StoreData( SvStream& rStrm ) const
{
	if( !SbxObject::StoreData( rStrm ) )
		return sal_False;

	// Source-String schreiben
    String aTmp = aOUSource;
	rStrm.WriteByteString( aTmp, gsl_getSystemTextEncoding() );
	//rStrm << aSource;
	return sal_True;
}


/////////////////////////////////////////////////////////////////////////

SbMethod::SbMethod( const String& r, SbxDataType t, SbModule* p )
		: SbxMethod( r, t ), pMod( p )
{
	bInvalid	 = sal_True;
	nStart		 =
	nDebugFlags  =
	nLine1		 =
	nLine2		 = 0;
	refStatics = new SbxArray;
	// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
	SetFlag( SBX_NO_MODIFY );
}

SbMethod::SbMethod( const SbMethod& r )
    : SvRefBase( r ), SbxMethod( r )
{
    pMod         = r.pMod;
	bInvalid	 = r.bInvalid;
	nStart		 = r.nStart;
	nDebugFlags  = r.nDebugFlags;
	nLine1		 = r.nLine1;
	nLine2		 = r.nLine2;
        refStatics = r.refStatics;
	SetFlag( SBX_NO_MODIFY );
}

SbMethod::~SbMethod()
{
}

SbxArray* SbMethod::GetLocals()
{
	if( pINST )
		return pINST->GetLocals( this );
	else
		return NULL;
}

void SbMethod::ClearStatics()
{
	refStatics = new SbxArray;

}
SbxArray* SbMethod::GetStatics()
{
	return refStatics;
}

sal_Bool SbMethod::LoadData( SvStream& rStrm, sal_uInt16 nVer )
{
	if( !SbxMethod::LoadData( rStrm, 1 ) )
		return sal_False;
	sal_Int16 n;
	rStrm >> n;
	sal_Int16 nTempStart = (sal_Int16)nStart;
	// nDebugFlags = n; 	// AB 16.1.96: Nicht mehr uebernehmen
	if( nVer == 2 )
		rStrm >> nLine1 >> nLine2 >> nTempStart >> bInvalid;
	// AB: 2.7.1996: HACK wegen 'Referenz kann nicht gesichert werden'
	SetFlag( SBX_NO_MODIFY );
	nStart = nTempStart;
	return sal_True;
}

sal_Bool SbMethod::StoreData( SvStream& rStrm ) const
{
	if( !SbxMethod::StoreData( rStrm ) )
		return sal_False;
	rStrm << (sal_Int16) nDebugFlags
		  << (sal_Int16) nLine1
		  << (sal_Int16) nLine2
		  << (sal_Int16) nStart
		  << (sal_uInt8)  bInvalid;
	return sal_True;
}

void SbMethod::GetLineRange( sal_uInt16& l1, sal_uInt16& l2 )
{
	l1 = nLine1; l2 = nLine2;
}

// Kann spaeter mal weg

SbxInfo* SbMethod::GetInfo()
{
	return pInfo;
}

// Schnittstelle zum Ausfuehren einer Methode aus den Applikationen
// #34191# Mit speziellem RefCounting, damit das Basic nicht durch CloseDocument()
// abgeschossen werden kann. Rueckgabewert wird als String geliefert.
ErrCode SbMethod::Call( SbxValue* pRet )
{
	// RefCount vom Modul hochzaehlen
	SbModule* pMod_ = (SbModule*)GetParent();
	pMod_->AddRef();

	// RefCount vom Basic hochzaehlen
	StarBASIC* pBasic = (StarBASIC*)pMod_->GetParent();
	pBasic->AddRef();

	// Values anlegen, um Return-Wert zu erhalten
	SbxValues aVals;
	aVals.eType = SbxVARIANT;

    // #104083: Compile BEFORE get
	if( bInvalid && !pMod_->Compile() )
		StarBASIC::Error( SbERR_BAD_PROP_VALUE );

	Get( aVals );
	if ( pRet )
		pRet->Put( aVals );

	// Gab es einen Error
	ErrCode nErr = SbxBase::GetError();
	SbxBase::ResetError();

	// Objekte freigeben
	pMod_->ReleaseRef();
	pBasic->ReleaseRef();

	return nErr;
}


// #100883 Own Broadcast for SbMethod
void SbMethod::Broadcast( sal_uIntPtr nHintId )
{
	if( pCst && !IsSet( SBX_NO_BROADCAST ) && StaticIsEnabledBroadcasting() )
	{
		// Da die Methode von aussen aufrufbar ist, hier noch einmal
		// die Berechtigung testen
		if( nHintId & SBX_HINT_DATAWANTED )
			if( !CanRead() )
				return;
		if( nHintId & SBX_HINT_DATACHANGED )
			if( !CanWrite() )
				return;

        if( pMod && !pMod->IsCompiled() )
            pMod->Compile();

		// Block broadcasts while creating new method
		SfxBroadcaster* pSave = pCst;
		pCst = NULL;
		SbMethod* pThisCopy = new SbMethod( *this );
        SbMethodRef xHolder = pThisCopy;
		if( mpPar.Is() )
        {
			// this, als Element 0 eintragen, aber den Parent nicht umsetzen!
			if( GetType() != SbxVOID )
        		mpPar->PutDirect( pThisCopy, 0 );
       		SetParameters( NULL );
        }

		pCst = pSave;
		pSave->Broadcast( SbxHint( nHintId, pThisCopy ) );

		sal_uInt16 nSaveFlags = GetFlags();
		SetFlag( SBX_READWRITE );
        pCst = NULL;
        Put( pThisCopy->GetValues_Impl() );
		pCst = pSave;
		SetFlags( nSaveFlags );
	}
}

/////////////////////////////////////////////////////////////////////////

// Implementation SbJScriptMethod (Method-Klasse als Wrapper fuer JavaScript-Funktionen)

SbJScriptMethod::SbJScriptMethod( const String& r, SbxDataType t, SbModule* p )
		: SbMethod( r, t, p )
{
}

SbJScriptMethod::~SbJScriptMethod()
{}


/////////////////////////////////////////////////////////////////////////
SbObjModule::SbObjModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVbaCompatible )
    : SbModule( rName, bIsVbaCompatible )
{
    SetModuleType( mInfo.ModuleType );
    if ( mInfo.ModuleType == script::ModuleType::FORM )
    {
        SetClassName( rtl::OUString::createFromAscii( "Form" ) );
    }
    else if ( mInfo.ModuleObject.is() )
        SetUnoObject( uno::makeAny( mInfo.ModuleObject ) );
}

SbObjModule::~SbObjModule()
{
}

void
SbObjModule::SetUnoObject( const uno::Any& aObj ) throw ( uno::RuntimeException )
{
    SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,(SbxVariable*)pDocObject);
    if ( pUnoObj && pUnoObj->getUnoAny() == aObj ) // object is equal, nothing to do
        return;
    pDocObject = new SbUnoObject( GetName(), uno::makeAny( aObj ) );

    com::sun::star::uno::Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( aObj, com::sun::star::uno::UNO_QUERY_THROW );
    if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Worksheet" ) ) )
    {
        SetClassName( rtl::OUString::createFromAscii( "Worksheet" ) );
    }
    else if( xServiceInfo->supportsService( rtl::OUString::createFromAscii( "ooo.vba.excel.Workbook" ) ) )
    {
        SetClassName( rtl::OUString::createFromAscii( "Workbook" ) );
    }
}

SbxVariable*
SbObjModule::GetObject()
{
    return pDocObject;
}
SbxVariable*
SbObjModule::Find( const XubString& rName, SbxClassType t )
{
    //OSL_TRACE("SbObjectModule find for %s", rtl::OUStringToOString(  rName, RTL_TEXTENCODING_UTF8 ).getStr() );
    SbxVariable* pVar = NULL;
    if ( pDocObject)
        pVar = pDocObject->Find( rName, t );
    if ( !pVar )
        pVar = SbModule::Find( rName, t );
    return pVar;
}

void SbObjModule::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
						 const SfxHint& rHint, const TypeId& rHintType )
{
	SbModule::handleProcedureProperties( rBC, rHint );
}


typedef ::cppu::WeakImplHelper3<
    awt::XTopWindowListener,
    awt::XWindowListener,
    document::XEventListener > FormObjEventListener_BASE;

class FormObjEventListenerImpl : public FormObjEventListener_BASE
{
    SbUserFormModule* mpUserForm;
    uno::Reference< lang::XComponent > mxComponent;
    uno::Reference< frame::XModel > mxModel;
    bool mbDisposed;
    sal_Bool mbOpened;
    sal_Bool mbActivated;
    sal_Bool mbShowing;

    FormObjEventListenerImpl(const FormObjEventListenerImpl&); // not defined
    FormObjEventListenerImpl& operator=(const FormObjEventListenerImpl&); // not defined

public:
    FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent, const uno::Reference< frame::XModel >& xModel ) :
        mpUserForm( pUserForm ), mxComponent( xComponent), mxModel( xModel ),
        mbDisposed( false ), mbOpened( sal_False ), mbActivated( sal_False ), mbShowing( sal_False )
    {
        if ( mxComponent.is() )
        {
            OSL_TRACE("*********** Registering the listeners");
            try
            {
                uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->addTopWindowListener( this );
            }
            catch( uno::Exception& ) {}
            try
            {
                uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->addWindowListener( this );
            }
            catch( uno::Exception& ) {}
        }

        if ( mxModel.is() )
        {
            try
            {
                uno::Reference< document::XEventBroadcaster >( mxModel, uno::UNO_QUERY_THROW )->addEventListener( this );
            }
            catch( uno::Exception& ) {}
        }
    }

    virtual ~FormObjEventListenerImpl()
    {
        removeListener();
    }

    sal_Bool isShowing() const { return mbShowing; }

    void removeListener()
    {
        if ( mxComponent.is() && !mbDisposed )
        {
            OSL_TRACE("*********** Removing the listeners");
            try
            {
                uno::Reference< awt::XTopWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeTopWindowListener( this );
            }
            catch( uno::Exception& ) {}
            try
            {
                uno::Reference< awt::XWindow >( mxComponent, uno::UNO_QUERY_THROW )->removeWindowListener( this );
            }
            catch( uno::Exception& ) {}
        }
        mxComponent.clear();

        if ( mxModel.is() && !mbDisposed )
        {
            try
            {
                uno::Reference< document::XEventBroadcaster >( mxModel, uno::UNO_QUERY_THROW )->removeEventListener( this );
            }
            catch( uno::Exception& ) {}
        }
        mxModel.clear();
    }

    virtual void SAL_CALL windowOpened( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
        if ( mpUserForm )
        {
            mbOpened = sal_True;
            mbShowing = sal_True;
            if ( mbActivated )
            {
                mbOpened = mbActivated = sal_False;
                mpUserForm->triggerActivateEvent();
            }
        }
    }

    //liuchen 2009-7-21, support Excel VBA Form_QueryClose event
    virtual void SAL_CALL windowClosing( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
#if IN_THE_FUTURE
		uno::Reference< awt::XDialog > xDialog( e.Source, uno::UNO_QUERY );
		if ( xDialog.is() )
		{
			uno::Reference< awt::XControl > xControl( xDialog, uno::UNO_QUERY );
			if ( xControl->getPeer().is() )
			{
				uno::Reference< document::XVbaMethodParameter > xVbaMethodParameter( xControl->getPeer(), uno::UNO_QUERY );
				if ( xVbaMethodParameter.is() )
				{
#endif
					sal_Int8 nCancel = 0;
					sal_Int8 nCloseMode = ::ooo::vba::VbQueryClose::vbFormControlMenu;

					Sequence< Any > aParams;
					aParams.realloc(2);
					aParams[0] <<= nCancel;
					aParams[1] <<= nCloseMode;

					mpUserForm->triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ),
												aParams);
#if IN_THE_FUTURE
					xVbaMethodParameter->setVbaMethodParameter( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Cancel")), aParams[0]);
					return;

				}
			}
		}
#endif
    }
	//liuchen 2009-7-21

    virtual void SAL_CALL windowClosed( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
        mbOpened = sal_False;
        mbShowing = sal_False;
    }

    virtual void SAL_CALL windowMinimized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
    }

    virtual void SAL_CALL windowNormalized( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
    }

    virtual void SAL_CALL windowActivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
        if ( mpUserForm )
        {
            mbActivated = sal_True;
            if ( mbOpened )
            {
                mbOpened = mbActivated = sal_False;
                mpUserForm->triggerActivateEvent();
            }
        }
    }

    virtual void SAL_CALL windowDeactivated( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
        if ( mpUserForm )
            mpUserForm->triggerDeactivateEvent();
    }

    virtual void SAL_CALL windowResized( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
    {
        if ( mpUserForm )
        {
            mpUserForm->triggerResizeEvent();
            mpUserForm->triggerLayoutEvent();
        }
    }

    virtual void SAL_CALL windowMoved( const awt::WindowEvent& /*e*/ ) throw (uno::RuntimeException)
    {
        if ( mpUserForm )
            mpUserForm->triggerLayoutEvent();
    }

    virtual void SAL_CALL windowShown( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
    }

    virtual void SAL_CALL windowHidden( const lang::EventObject& /*e*/ ) throw (uno::RuntimeException)
    {
    }

    virtual void SAL_CALL notifyEvent( const document::EventObject& rEvent ) throw (uno::RuntimeException)
    {
        // early dosposing on document event "OnUnload", to be sure Basic still exists when calling VBA "UserForm_Terminate"
        if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) )
        {
            removeListener();
            mbDisposed = true;
            if ( mpUserForm )
                mpUserForm->ResetApiObj();   // will trigger "UserForm_Terminate"
        }
    }

    virtual void SAL_CALL disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
    {
        OSL_TRACE("** Userform/Dialog disposing");
        removeListener();
        mbDisposed = true;
        if ( mpUserForm )
            mpUserForm->ResetApiObj( false );   // pass false (too late to trigger VBA events here)
    }
};

SbUserFormModule::SbUserFormModule( const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsCompat )
	: SbObjModule( rName, mInfo, bIsCompat )
	, m_mInfo( mInfo )
	, mbInit( false )
{
    m_xModel.set( mInfo.ModuleObject, uno::UNO_QUERY_THROW );
}

SbUserFormModule::~SbUserFormModule()
{
}

void SbUserFormModule::ResetApiObj(  bool bTriggerTerminateEvent )
{
    if ( bTriggerTerminateEvent && m_xDialog.is() ) // probably someone close the dialog window
	{
        triggerTerminateEvent();
    }
    pDocObject = NULL;
	m_xDialog = NULL;
}

void SbUserFormModule::triggerMethod( const String& aMethodToRun )
{
	Sequence< Any > aArguments;
	triggerMethod( aMethodToRun, aArguments );
}

void SbUserFormModule::triggerMethod( const String& aMethodToRun, Sequence< Any >& aArguments )
{
	OSL_TRACE("*** trigger %s ***", rtl::OUStringToOString( aMethodToRun, RTL_TEXTENCODING_UTF8 ).getStr() );
	// Search method
	SbxVariable* pMeth = SbObjModule::Find( aMethodToRun, SbxCLASS_METHOD );
	if( pMeth )
	{
		if ( aArguments.getLength() > 0 )   // Setup parameters
		{
			SbxArrayRef xArray = new SbxArray;
			xArray->Put( pMeth, 0 );	// Method as parameter 0

			for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
			{
				SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
                unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), aArguments[i] );
                xArray->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );

				// Enable passing by ref
				if ( xSbxVar->GetType() != SbxVARIANT )
					xSbxVar->SetFlag( SBX_FIXED );
			}
			pMeth->SetParameters( xArray );

			SbxValues aVals;
			pMeth->Get( aVals );

			for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i )
			{
				aArguments[i] = sbxToUnoValue( xArray->Get( static_cast< sal_uInt16 >(i) + 1) );
			}
			pMeth->SetParameters( NULL );
		}
		else
		{
			SbxValues aVals;
			pMeth->Get( aVals );
		}
	}
}

void SbUserFormModule::triggerActivateEvent( void )
{
    OSL_TRACE("**** entering SbUserFormModule::triggerActivate");
	triggerMethod( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UserForm_Activate") ) );
    OSL_TRACE("**** leaving SbUserFormModule::triggerActivate");
}

void SbUserFormModule::triggerDeactivateEvent( void )
{
    OSL_TRACE("**** SbUserFormModule::triggerDeactivate");
	triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_Deactivate") ) );
}

void SbUserFormModule::triggerInitializeEvent( void )
{
	if ( mbInit )
		return;
    OSL_TRACE("**** SbUserFormModule::triggerInitializeEvent");
	static String aInitMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Initialize") );
	triggerMethod( aInitMethodName );
	mbInit = true;
}

void SbUserFormModule::triggerTerminateEvent( void )
{
    OSL_TRACE("**** SbUserFormModule::triggerTerminateEvent");
	static String aTermMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Terminate") );
	triggerMethod( aTermMethodName );
	mbInit=false;
}

void SbUserFormModule::triggerLayoutEvent( void )
{
	static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Layout") );
	triggerMethod( aMethodName );
}

void SbUserFormModule::triggerResizeEvent( void )
{
	static String aMethodName( RTL_CONSTASCII_USTRINGPARAM("Userform_Resize") );
	triggerMethod( aMethodName );
}

SbUserFormModuleInstance* SbUserFormModule::CreateInstance()
{
	SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() );
	return pInstance;
}

SbUserFormModuleInstance::SbUserFormModuleInstance( SbUserFormModule* pParentModule,
	const String& rName, const com::sun::star::script::ModuleInfo& mInfo, bool bIsVBACompat )
		: SbUserFormModule( rName, mInfo, bIsVBACompat )
		, m_pParentModule( pParentModule )
{
}

sal_Bool SbUserFormModuleInstance::IsClass( const XubString& rName ) const
{
	sal_Bool bParentNameMatches = m_pParentModule->GetName().EqualsIgnoreCaseAscii( rName );
	sal_Bool bRet = bParentNameMatches || SbxObject::IsClass( rName );
	return bRet;
}

SbxVariable* SbUserFormModuleInstance::Find( const XubString& rName, SbxClassType t )
{
	SbxVariable* pVar = m_pParentModule->Find( rName, t );
	return pVar;
}


void SbUserFormModule::Load()
{
    OSL_TRACE("** load() ");
    // forces a load
    if ( !pDocObject )
        InitObject();
}

//liuchen 2009-7-21 change to accmordate VBA's beheavior
void SbUserFormModule::Unload()
{
    OSL_TRACE("** Unload() ");

	sal_Int8 nCancel = 0;
	sal_Int8 nCloseMode = ::ooo::vba::VbQueryClose::vbFormCode;

	Sequence< Any > aParams;
	aParams.realloc(2);
	aParams[0] <<= nCancel;
	aParams[1] <<= nCloseMode;

	triggerMethod( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Userform_QueryClose") ), aParams);

	aParams[0] >>= nCancel;
	if (nCancel != 0)  // Basic returns -1 for "True"
	{
		return;
	}

    if ( m_xDialog.is() )
    {
		triggerTerminateEvent();
    }
	// Search method
	SbxVariable* pMeth = SbObjModule::Find( String( RTL_CONSTASCII_USTRINGPARAM( "UnloadObject" ) ), SbxCLASS_METHOD );
	if( pMeth )
	{
		OSL_TRACE("Attempting too run the UnloadObjectMethod");
        m_xDialog.clear(); //release ref to the uno object
		SbxValues aVals;
		bool bWaitForDispose = true; // assume dialog is showing
        if ( m_DialogListener.get() )
		{
			bWaitForDispose = m_DialogListener->isShowing();
			OSL_TRACE("Showing %d", bWaitForDispose );
		}
		pMeth->Get( aVals);
        if ( !bWaitForDispose )
        {
            // we've either already got a dispose or we'er never going to get one
		    ResetApiObj();
        } // else wait for dispose
		OSL_TRACE("UnloadObject completed ( we hope )");
	}
}
//liuchen

void registerComponentToBeDisposedForBasic( Reference< XComponent > xComponent, StarBASIC* pBasic );

void SbUserFormModule::InitObject()
{
    try
    {
        String aHook( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobals" ) );
        SbUnoObject* pGlobs = (SbUnoObject*)GetParent()->Find( aHook, SbxCLASS_DONTCARE );
        if ( m_xModel.is() && pGlobs )
        {
            // broadcast INITIALIZE_USERFORM script event before the dialog is created
            Reference< script::vba::XVBACompatibility > xVBACompat( getVBACompatibility( m_xModel ), uno::UNO_SET_THROW );
            xVBACompat->broadcastVBAScriptEvent( script::vba::VBAScriptEventId::INITIALIZE_USERFORM, GetName() );

            uno::Reference< lang::XMultiServiceFactory > xVBAFactory( pGlobs->getUnoAny(), uno::UNO_QUERY_THROW );
            uno::Reference< lang::XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
            uno::Sequence< uno::Any > aArgs(1);
            aArgs[ 0 ] <<= m_xModel;
            rtl::OUString sDialogUrl( RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.script:" ) );
            rtl::OUString sProjectName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
            if ( this->GetParent()->GetName().Len() )
                sProjectName = this->GetParent()->GetName();
            sDialogUrl = sDialogUrl.concat( sProjectName ).concat( rtl::OUString( '.') ).concat( GetName() ).concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("?location=document") ) );

            uno::Reference< awt::XDialogProvider > xProvider( xFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.DialogProvider")), aArgs  ), uno::UNO_QUERY_THROW );
            m_xDialog = xProvider->createDialog( sDialogUrl );

            // create vba api object
            aArgs.realloc( 4 );
            aArgs[ 0 ] = uno::Any();
            aArgs[ 1 ] <<= m_xDialog;
            aArgs[ 2 ] <<= m_xModel;
            aArgs[ 3 ] <<= rtl::OUString( GetParent()->GetName() );
            pDocObject = new SbUnoObject( GetName(), uno::makeAny( xVBAFactory->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.msforms.UserForm")), aArgs  ) ) );

            uno::Reference< lang::XComponent > xComponent( m_xDialog, uno::UNO_QUERY_THROW );

            // the dialog must be disposed at the end!
            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 );

            // if old listener object exists, remove it from dialog and document model
            if( m_DialogListener.is() )
                m_DialogListener->removeListener();
            m_DialogListener.set( new FormObjEventListenerImpl( this, xComponent, m_xModel ) );

            triggerInitializeEvent();
        }
    }
    catch( uno::Exception& )
    {
    }

}

SbxVariable*
SbUserFormModule::Find( const XubString& rName, SbxClassType t )
{
    if ( !pDocObject && !GetSbData()->bRunInit && pINST )
        InitObject();
    return SbObjModule::Find( rName, t );
}
/////////////////////////////////////////////////////////////////////////

SbProperty::SbProperty( const String& r, SbxDataType t, SbModule* p )
		: SbxProperty( r, t ), pMod( p )
{
	bInvalid = sal_False;
}

SbProperty::~SbProperty()
{}

/////////////////////////////////////////////////////////////////////////

SbProcedureProperty::~SbProcedureProperty()
{}
