/**************************************************************
 *
 * 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_stoc.hxx"
#include <osl/mutex.hxx>
#include <cppuhelper/queryinterface.hxx>
#ifndef _CPPUHELER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#include <cppuhelper/factory.hxx>
#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX__
#include <cppuhelper/implementationentry.hxx>
#endif
#include <cppuhelper/typeprovider.hxx>
#include <cppuhelper/implbase2.hxx>

#include <com/sun/star/uno/DeploymentException.hpp>
#include <com/sun/star/script/FailReason.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <com/sun/star/script/XInvocation2.hpp>
#include <com/sun/star/reflection/XIdlReflection.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/beans/XExactName.hpp>
#include <com/sun/star/beans/XMaterialHolder.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/MethodConcept.hpp>
#include <com/sun/star/beans/PropertyConcept.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/lang/XTypeProvider.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <boost/scoped_array.hpp>
#include <rtl/ustrbuf.hxx>
#include <rtl/strbuf.hxx>

#define SERVICENAME "com.sun.star.script.Invocation"
#define IMPLNAME	 "com.sun.star.comp.stoc.Invocation"

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::script;
using namespace com::sun::star::reflection;
using namespace com::sun::star::beans;
using namespace com::sun::star::registry;
using namespace com::sun::star::container;
using namespace cppu;
using namespace rtl;
using namespace osl;


namespace stoc_inv
{
static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;

static Sequence< OUString > inv_getSupportedServiceNames()
{
	static Sequence < OUString > *pNames = 0;
	if( ! pNames )
	{
		MutexGuard guard( Mutex::getGlobalMutex() );
		if( !pNames )
		{
			static Sequence< OUString > seqNames(1);
			seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
			pNames = &seqNames;
		}
	}
	return *pNames;
}

static OUString inv_getImplementationName()
{
	static OUString *pImplName = 0;
	if( ! pImplName )
	{
		MutexGuard guard( Mutex::getGlobalMutex() );
		if( ! pImplName )
		{
			static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
			pImplName = &implName;
		}
	}
	return *pImplName;
}

// TODO: Zentral implementieren
inline Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XIdlReflection > & xRefl )
{
	return xRefl->forName( rType.getTypeName() );
}


//==================================================================================================
class Invocation_Impl
	: public OWeakObject
	, public XInvocation2
	, public XNameContainer
	, public XIndexContainer
	, public XEnumerationAccess
	, public XExactName
	, public XMaterialHolder
    , public XTypeProvider
{
public:
	Invocation_Impl( const Any & rAdapted, const Reference<XTypeConverter> &,
										   const Reference<XIntrospection> &,
										   const Reference<XIdlReflection> & );
	virtual ~Invocation_Impl();

	// XInterface
    virtual Any	        SAL_CALL queryInterface( const Type & aType) throw( RuntimeException );
	virtual void		SAL_CALL acquire() throw() { OWeakObject::acquire(); }
	virtual void		SAL_CALL release() throw() { OWeakObject::release(); }


	// XTypeProvider
    virtual Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes(  )
	   throw(RuntimeException);
    virtual Sequence< sal_Int8 > SAL_CALL getImplementationId(  )
	   throw( RuntimeException);

    // Methoden von XMaterialHolder
	virtual Any			SAL_CALL getMaterial(void) throw(RuntimeException);

	// ? XTool
	virtual void		SAL_CALL setMaterial( const Any& rMaterial );

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

    // XInvocation2
    virtual Sequence< OUString > SAL_CALL getMemberNames(  )
		throw( RuntimeException );
    virtual Sequence< InvocationInfo > SAL_CALL getInfo(  )
		throw( RuntimeException );
    virtual InvocationInfo SAL_CALL getInfoForName( const OUString& aName, sal_Bool bExact )
		throw( IllegalArgumentException, RuntimeException );

	// All Access and Container methods are not thread save
	// XElementAccess
	virtual Type SAL_CALL getElementType(void) throw( RuntimeException )
		{ return _xElementAccess->getElementType(); }

	virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException )
		{ return _xElementAccess->hasElements(); }

	// XNameContainer
    virtual void SAL_CALL insertByName( const OUString& Name, const Any& Element )
		throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
		{ _xNameContainer->insertByName( Name, Element ); }

    virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element )
		throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
		{ _xNameContainer->replaceByName( Name, Element ); }

    virtual void SAL_CALL removeByName( const OUString& Name )
		throw( NoSuchElementException, WrappedTargetException, RuntimeException )
		{ _xNameContainer->removeByName( Name ); }

	// XNameAccess
    virtual Any SAL_CALL getByName( const OUString& Name )
		throw( NoSuchElementException, WrappedTargetException, RuntimeException )
		{ return _xNameAccess->getByName( Name ); }

    virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException )
		{ return _xNameAccess->getElementNames(); }

    virtual sal_Bool SAL_CALL hasByName( const OUString& Name ) throw( RuntimeException )
		{ return _xNameAccess->hasByName( Name ); }

	// XIndexContainer
    virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element )
		throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
		{ _xIndexContainer->insertByIndex( Index, Element ); }

    virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element )
		throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
		{ _xIndexContainer->replaceByIndex( Index, Element ); }

    virtual void SAL_CALL removeByIndex( sal_Int32 Index )
		throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
		{ _xIndexContainer->removeByIndex( Index ); }

	// XIndexAccess
    virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException )
		{ return _xIndexAccess->getCount(); }

    virtual Any SAL_CALL getByIndex( sal_Int32 Index )
		throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
		{ return _xIndexAccess->getByIndex( Index ); }

	// XEnumerationAccess
    virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException )
		{ return _xEnumerationAccess->createEnumeration(); }

	// XExactName
    virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );


	//=====================================================================================================
private:
	void getInfoSequenceImpl( Sequence< OUString >* pStringSeq, Sequence< InvocationInfo >* pInfoSeq );
	void fillInfoForNameAccess( InvocationInfo& rInfo, const OUString& aName );
	void fillInfoForProperty( InvocationInfo& rInfo, const Property& rProp );
	void fillInfoForMethod( InvocationInfo& rInfo, const Reference< XIdlMethod > xMethod );

	Reference<XTypeConverter>			xTypeConverter;
	Reference<XIntrospection>			xIntrospection;
	Reference<XIdlReflection>			xCoreReflection;

	Any								_aMaterial;
	// _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
	Reference<XInvocation>				_xDirect;
	Reference<XInvocation2>				_xDirect2;
	Reference<XPropertySet>				_xPropertySet;
	Reference<XIntrospectionAccess>		_xIntrospectionAccess;

	// supplied Interfaces
	Reference<XNameContainer>			_xNameContainer;
	Reference<XNameAccess>				_xNameAccess;
	Reference<XIndexContainer>			_xIndexContainer;
	Reference<XIndexAccess>				_xIndexAccess;
	Reference<XEnumerationAccess>		_xEnumerationAccess;
	Reference<XElementAccess>			_xElementAccess;

	//
	Reference<XExactName>				_xENDirect, _xENIntrospection, _xENNameAccess;
};


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

//--------------------------------------------------------------------------------------------------
Invocation_Impl::Invocation_Impl
(
	const Any & rAdapted,
	const Reference<XTypeConverter> & rTC,
	const Reference<XIntrospection>	& rI,
	const Reference<XIdlReflection> & rCR
)
	: xTypeConverter( rTC )
	, xIntrospection( rI )
	, xCoreReflection( rCR )
{
	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
	setMaterial( rAdapted );
}

Invocation_Impl::~Invocation_Impl()
{
	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}

//##################################################################################################
//### INTERFACE IMPLEMENTATIONS ####################################################################
//##################################################################################################


Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType )
	throw( RuntimeException )
{
	// PropertySet-Implementation
	Any a = ::cppu::queryInterface( aType,
								   SAL_STATIC_CAST(XInvocation*, this),
								   SAL_STATIC_CAST(XMaterialHolder*, this),
								   SAL_STATIC_CAST(XTypeProvider *,this)	);
	if( a.hasValue() )
	{
		return a;
	}

	if( aType  == getCppuType( (Reference<XExactName>*) NULL ) )
	{
		// Ivocation does not support XExactName, if direct object supports
		// XInvocation, but not XExactName.
		if ((_xDirect.is() && _xENDirect.is()) ||
			(!_xDirect.is() && (_xENIntrospection.is() || _xENNameAccess.is())))
		{
			return makeAny( Reference< XExactName >( SAL_STATIC_CAST(XExactName*, this) ) );
		}
	}
	else if ( aType == getCppuType( (Reference<XNameContainer>*) NULL ) )
	{
		if( _xNameContainer.is() )
			return makeAny( Reference< XNameContainer >( SAL_STATIC_CAST(XNameContainer*, this) ) );
	}
	else if ( aType == getCppuType( (Reference<XNameAccess>*) NULL ) )
	{
		if( _xNameAccess.is() )
			return makeAny( Reference< XNameAccess >( SAL_STATIC_CAST(XNameAccess*, this) ) );
	}
	else if ( aType == getCppuType( (Reference<XIndexContainer>*) NULL ) )
	{
		if (_xIndexContainer.is())
			return makeAny( Reference< XIndexContainer >( SAL_STATIC_CAST(XIndexContainer*, this) ) );
	}
	else if ( aType == getCppuType( (Reference<XIndexAccess>*) NULL ) )
	{
		if (_xIndexAccess.is())
			return makeAny( Reference< XIndexAccess >( SAL_STATIC_CAST(XIndexAccess*, this) ) );
	}
	else if ( aType == getCppuType( (Reference<XEnumerationAccess>*) NULL ) )
	{
		if (_xEnumerationAccess.is())
			return makeAny( Reference< XEnumerationAccess >( SAL_STATIC_CAST(XEnumerationAccess*, this) ) );
	}
	else if ( aType == getCppuType( (Reference<XElementAccess>*) NULL ) )
	{
		if (_xElementAccess.is())
		{
			return makeAny( Reference< XElementAccess >(
				SAL_STATIC_CAST(XElementAccess*, SAL_STATIC_CAST(XNameContainer*, this) ) ) );
		}
	}
	else if ( aType == getCppuType( (Reference<XInvocation2>*) NULL ) )
	{
		// Invocation does not support XInvocation2, if direct object supports
		// XInvocation, but not XInvocation2.
		if ( ( _xDirect.is() && _xDirect2.is()) ||
			 (!_xDirect.is() && _xIntrospectionAccess.is() ) )
		{
			return makeAny( Reference< XInvocation2 >( SAL_STATIC_CAST(XInvocation2*, this) ) );
		}
	}

	return OWeakObject::queryInterface( aType );
}


//--------------------------------------------------------------------------------------------------
Any Invocation_Impl::getMaterial(void) throw(RuntimeException)
{
	// AB, 12.2.1999  Sicherstellen, dass das Material wenn moeglich
	// aus der direkten Invocation bzw. von der Introspection geholt
	// wird, da sonst Structs nicht korrekt behandelt werden
	Reference<XMaterialHolder> xMaterialHolder;
	if( _xDirect.is() )
	{
		xMaterialHolder = Reference<XMaterialHolder>::query( _xDirect );
		//_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
	}
	else if( _xIntrospectionAccess.is() )
	{
		xMaterialHolder = Reference<XMaterialHolder>::query( _xIntrospectionAccess );
		//_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
	}
	if( xMaterialHolder.is() )
	{
		return xMaterialHolder->getMaterial();
	}
	return _aMaterial;
}

//--------------------------------------------------------------------------------------------------
void Invocation_Impl::setMaterial( const Any& rMaterial )
{
	// set the material first and only once
	Reference<XInterface> xObj;

	if (rMaterial.getValueType().getTypeClass() == TypeClass_INTERFACE)
		xObj = *(Reference<XInterface>*)rMaterial.getValue();
	_aMaterial = rMaterial;

	// Ersteinmal alles ausserhalb des guards machen
	_xDirect = Reference<XInvocation>::query( xObj );

	if( _xDirect.is() )
	{
		// Objekt direkt befragen
		_xElementAccess		= Reference<XElementAccess>::query( _xDirect );
		_xEnumerationAccess = Reference<XEnumerationAccess>::query( _xDirect );
		_xIndexAccess		= Reference<XIndexAccess>::query( _xDirect );
		_xIndexContainer	= Reference<XIndexContainer>::query( _xDirect );
		_xNameAccess		= Reference<XNameAccess>::query( _xDirect );
		_xNameContainer		= Reference<XNameContainer>::query( _xDirect );
		_xENDirect			= Reference<XExactName>::query( _xDirect );
		_xDirect2			= Reference<XInvocation2>::query( _xDirect );

		// only once!!!
		//_xIntrospectionAccess = XIntrospectionAccessRef();
		//_xPropertySet			= XPropertySetRef();
	}
	else
	{
		// Invocation ueber die Introspection machen
		if (xIntrospection.is())
		{
			_xIntrospectionAccess = xIntrospection->inspect( _aMaterial );
			if( _xIntrospectionAccess.is() )
			{

				_xElementAccess = Reference<XElementAccess>::query(
					  _xIntrospectionAccess->queryAdapter(
						 	    getCppuType( (Reference<XElementAccess>*) NULL ) ) );

				_xEnumerationAccess = Reference<XEnumerationAccess>::query(
						   _xIntrospectionAccess->queryAdapter(
								getCppuType( (Reference<XEnumerationAccess>*) NULL )) );

				_xIndexAccess = Reference<XIndexAccess>::query(
					   _xIntrospectionAccess->queryAdapter(
							    getCppuType( (Reference<XIndexAccess>*) NULL ) ) );

				_xIndexContainer = Reference<XIndexContainer>::query(
					 _xIntrospectionAccess->queryAdapter(
								getCppuType( (Reference<XIndexContainer>*) NULL ) ) );

				_xNameAccess = Reference<XNameAccess>::query(
					 _xIntrospectionAccess->queryAdapter(
								getCppuType( (Reference<XNameAccess>*) NULL ) ) );

				_xNameContainer = Reference<XNameContainer>::query(
						   _xIntrospectionAccess->queryAdapter(
							   getCppuType( (Reference<XNameContainer>*) NULL ) ) );

				_xPropertySet = Reference<XPropertySet>::query(
						   _xIntrospectionAccess->queryAdapter(
                               getCppuType( (Reference<XPropertySet>*) NULL )) );

				_xENIntrospection = Reference<XExactName>::query( _xIntrospectionAccess );
				if (_xNameAccess.is())
					_xENNameAccess = Reference<XExactName>::query( _xNameAccess );
			}
		}
		/* only once !!!
		_xDirect = XInvocationRef();
		if( !_xIntrospectionAccess.is() )
		{
			// reset
			_xElementAccess		= XElementAccessRef();
			_xEnumerationAccess = XEnumerationAccessRef();
			_xIndexAccess		= XIndexAccessRef();
			_xIndexContainer	= XIndexContainerRef();
			_xNameAccess		= XNameAccessRef();
			_xNameContainer		= XNameContainerRef();
			_xPropertySet		= XPropertySetRef();
		}
		*/
	}
}

//--------------------------------------------------------------------------------------------------
OUString Invocation_Impl::getExactName( const OUString& rApproximateName )
	throw( RuntimeException )
{
	if (_xENDirect.is())
		return _xENDirect->getExactName( rApproximateName );

	OUString aRet;
	if (_xENIntrospection.is())
		aRet = _xENIntrospection->getExactName( rApproximateName );
	if (!aRet.getLength() && _xENNameAccess.is())
		aRet = _xENNameAccess->getExactName( rApproximateName );
	return aRet;
}

//--------------------------------------------------------------------------------------------------
Reference<XIntrospectionAccess>	Invocation_Impl::getIntrospection(void)
	throw( RuntimeException )
{
	if( _xDirect.is() )
		return _xDirect->getIntrospection();
	else
		return _xIntrospectionAccess;
}

//--------------------------------------------------------------------------------------------------
sal_Bool Invocation_Impl::hasMethod( const OUString& Name )
	throw( RuntimeException )
{
	if (_xDirect.is())
		return _xDirect->hasMethod( Name );
	if( _xIntrospectionAccess.is() )
		return _xIntrospectionAccess->hasMethod( Name, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
	return sal_False;
}

//--------------------------------------------------------------------------------------------------
sal_Bool Invocation_Impl::hasProperty( const OUString& Name )
	throw( RuntimeException )
{
	if (_xDirect.is())
		return _xDirect->hasProperty( Name );
	// PropertySet
	if( _xIntrospectionAccess.is()
		&& _xIntrospectionAccess->hasProperty( Name, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
		return sal_True;
	// NameAccess
	if( _xNameAccess.is() )
		return _xNameAccess->hasByName( Name );
	return sal_False;
}

//--------------------------------------------------------------------------------------------------
Any Invocation_Impl::getValue( const OUString& PropertyName )
	throw( UnknownPropertyException, RuntimeException )
{
    if (_xDirect.is())
        return _xDirect->getValue( PropertyName );
    try
    {
        // PropertySet
        if( _xIntrospectionAccess.is() && _xPropertySet.is()
            && _xIntrospectionAccess->hasProperty
            ( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
        {
            return _xPropertySet->getPropertyValue( PropertyName );
        }
        // NameAccess
        if( _xNameAccess.is() && _xNameAccess->hasByName( PropertyName ) )
            return _xNameAccess->getByName( PropertyName );
    }
    catch (UnknownPropertyException &)
    {
        throw;
    }
    catch (RuntimeException &)
    {
        throw;
    }
    catch (Exception &)
    {
    }

	throw UnknownPropertyException(
        OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get value ") ) + PropertyName,
        Reference< XInterface >() );
}

//--------------------------------------------------------------------------------------------------
void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value )
	throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException )
{
	if (_xDirect.is())
		_xDirect->setValue( PropertyName, Value );
	else
	{
        try
        {
            // Properties
            if( _xIntrospectionAccess.is() && _xPropertySet.is()
                && _xIntrospectionAccess->hasProperty(
                    PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
            {
                Property aProp = _xIntrospectionAccess->getProperty(
                    PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS );
                Reference < XIdlClass > r = TypeToIdlClass( aProp.Type, xCoreReflection );
                if( r->isAssignableFrom( TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
                    _xPropertySet->setPropertyValue( PropertyName, Value );
                else if( xTypeConverter.is() )
                    _xPropertySet->setPropertyValue(
                        PropertyName, xTypeConverter->convertTo( Value, aProp.Type ) );
                else
                    throw RuntimeException(
                        OUString( RTL_CONSTASCII_USTRINGPARAM("no type converter service!") ),
                        Reference< XInterface >() );
            }
            // NameContainer
            else if( _xNameContainer.is() )
            {
                Any aConv;
                Reference < XIdlClass > r =
                    TypeToIdlClass( _xNameContainer->getElementType(), xCoreReflection );
                if( r->isAssignableFrom(TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
                    aConv = Value;
                else if( xTypeConverter.is() )
                    aConv = xTypeConverter->convertTo( Value, _xNameContainer->getElementType() );
                else
                    throw RuntimeException(
                        OUString( RTL_CONSTASCII_USTRINGPARAM("no type converter service!") ),
                        Reference< XInterface >() );

                // bei Vorhandensein ersetzen, ansonsten einfuegen
                if (_xNameContainer->hasByName( PropertyName ))
                    _xNameContainer->replaceByName( PropertyName, aConv );
                else
                    _xNameContainer->insertByName( PropertyName, aConv );
            }
            else
                throw UnknownPropertyException(
                    OUString( RTL_CONSTASCII_USTRINGPARAM("no introspection nor name container!") ),
                    Reference< XInterface >() );
        }
        catch (UnknownPropertyException &)
        {
            throw;
        }
        catch (CannotConvertException &)
        {
            throw;
        }
        catch (InvocationTargetException &)
        {
            throw;
        }
        catch (RuntimeException &)
        {
            throw;
        }
        catch (Exception & exc)
        {
            throw InvocationTargetException(
                OUString( RTL_CONSTASCII_USTRINGPARAM("exception occurred in setValue(): ") ) +
                exc.Message, Reference< XInterface >(), makeAny( exc /* though sliced */ ) );
        }
	}
}

//--------------------------------------------------------------------------------------------------
Any Invocation_Impl::invoke( const OUString& FunctionName, const Sequence<Any>& InParams,
								Sequence<sal_Int16>& OutIndizes, Sequence<Any>& OutParams )
	throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException )
{
	if (_xDirect.is())
		return _xDirect->invoke( FunctionName, InParams, OutIndizes, OutParams );

	if (_xIntrospectionAccess.is())
	{
		// throw NoSuchMethodException if not exist
		Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod(
			FunctionName, MethodConcept::ALL ^ MethodConcept::DANGEROUS );

		// ParameterInfos
		Sequence<ParamInfo> aFParams		= xMethod->getParameterInfos();
		const ParamInfo* pFParams			= aFParams.getConstArray();
		sal_Int32 nFParamsLen				= aFParams.getLength();
		if (nFParamsLen != InParams.getLength())
        {
            throw IllegalArgumentException(
                OUString( RTL_CONSTASCII_USTRINGPARAM("incorrect number of parameters passed invoking function ") ) + FunctionName,
                (OWeakObject *) this, (sal_Int16) 1 );
        }

		// IN Parameter
		const Any* pInParams				= InParams.getConstArray();

		// Introspection Invoke Parameter
		Sequence<Any> aInvokeParams( nFParamsLen );
		Any* pInvokeParams					= aInvokeParams.getArray();

		// OUT Indizes
		OutIndizes.realloc( nFParamsLen );
		sal_Int16* pOutIndizes				= OutIndizes.getArray();
		sal_uInt32 nOutIndex				= 0;

        for ( sal_Int32 nPos = 0; nPos < nFParamsLen; ++nPos )
		{
            try
			{
				const ParamInfo& rFParam = pFParams[nPos];
				const Reference<XIdlClass>& rDestType = rFParam.aType;

				// is IN/INOUT parameter?
				if (rFParam.aMode != ParamMode_OUT)
				{
					if (rDestType->isAssignableFrom( TypeToIdlClass( pInParams[nPos].getValueType(), xCoreReflection ) ))
					{
						pInvokeParams[nPos]	= pInParams[nPos];
					}
					else if (xTypeConverter.is())
					{
						Type aDestType( rDestType->getTypeClass(), rDestType->getName() );
						pInvokeParams[nPos]	= xTypeConverter->convertTo( pInParams[nPos], aDestType );
					}
					else
					{
						CannotConvertException aExc;
						aExc.Context = *this;
						aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("invocation type mismatch!") );
						throw aExc;
					}
				}

				// is OUT/INOUT parameter?
				if (rFParam.aMode != ParamMode_IN)
				{
					pOutIndizes[nOutIndex] = (sal_Int16)nPos;
					if (rFParam.aMode == ParamMode_OUT)
						rDestType->createObject( pInvokeParams[nPos] );		// default init
					++nOutIndex;
				}
			}
            catch( CannotConvertException& rExc )
            {
                rExc.ArgumentIndex = nPos;	// optionalen Parameter Index hinzufuegen
                throw rExc;
            }
		}

        // execute Method
        Any aRet = xMethod->invoke( _aMaterial, aInvokeParams );

        // OUT Params
        OutIndizes.realloc( nOutIndex );
        pOutIndizes		   = OutIndizes.getArray();
        OutParams.realloc( nOutIndex );
        Any* pOutParams = OutParams.getArray();

        while (nOutIndex--)
        {
            pOutParams[nOutIndex] = pInvokeParams[ pOutIndizes[nOutIndex] ];
        }

        return aRet;
	}

	RuntimeException aExc;
	aExc.Context = *this;
	aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("invocation lacking of introspection access!") );
	throw aExc;
}

//--------------------------------------------------------------------------------------------------

// Struct to optimize sorting
struct MemberItem
{
	OUString aName;

	// Defines where the member comes from
	enum Mode { NAMEACCESS, PROPERTYSET, METHOD } eMode;

	// Index to respective sequence
	// (Index to NameAccess sequence for eMode==NAMEACCESS etc.)
	sal_Int32 nIndex;
};

// Implementation of getting name or info
// String sequence will be filled when pStringSeq != NULL
// Info sequence will be filled when pInfoSeq != NULL
void Invocation_Impl::getInfoSequenceImpl
(
	Sequence< OUString >* pStringSeq,
	Sequence< InvocationInfo >* pInfoSeq
)
{
	//Sequence< OUString > aStrSeq;
	//if( !pStringSeq )
		//pStringSeq = &aStrSeq;


	// Get all needed sequences
	Sequence<OUString> aNameAccessNames;
	Sequence<Property> aPropertySeq;
	Sequence< Reference< XIdlMethod > > aMethodSeq;

	if( _xNameAccess.is() )
	{
		aNameAccessNames = _xNameAccess->getElementNames();
	}

	if( _xIntrospectionAccess.is() )
	{
		aPropertySeq = _xIntrospectionAccess->getProperties
			( PropertyConcept::ALL - PropertyConcept::DANGEROUS );

		aMethodSeq = _xIntrospectionAccess->getMethods
			( MethodConcept::ALL - MethodConcept::DANGEROUS );
	}

	sal_Int32 nNameAccessCount = aNameAccessNames.getLength();
	sal_Int32 nPropertyCount = aPropertySeq.getLength();
	sal_Int32 nMethodCount = aMethodSeq.getLength();
	sal_Int32 nTotalCount = nNameAccessCount + nPropertyCount + nMethodCount;

	// Create and fill array of MemberItems
    boost::scoped_array< MemberItem > pItems( new MemberItem[ nTotalCount ] );
	const OUString* pStrings = aNameAccessNames.getConstArray();
	const Property* pProps = aPropertySeq.getConstArray();
	const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();

	// Fill array of MemberItems
	sal_Int32 i, iTotal = 0;

	// Name Access
	for( i = 0 ; i < nNameAccessCount ; i++, iTotal++ )
	{
		MemberItem& rItem = pItems[ iTotal ];
		rItem.aName = pStrings[ i ];
		rItem.eMode = MemberItem::NAMEACCESS;
		rItem.nIndex = i;
	}

	// Property set
	for( i = 0 ; i < nPropertyCount ; i++, iTotal++ )
	{
		MemberItem& rItem = pItems[ iTotal ];
		rItem.aName = pProps[ i ].Name;
		rItem.eMode = MemberItem::PROPERTYSET;
		rItem.nIndex = i;
	}

	// Methods
	for( i = 0 ; i < nMethodCount ; i++, iTotal++ )
	{
		MemberItem& rItem = pItems[ iTotal ];
		Reference< XIdlMethod > xMethod = pMethods[ i ];
		rItem.aName = xMethod->getName();
		rItem.eMode = MemberItem::METHOD;
		rItem.nIndex = i;
	}

	// Setting up result sequences
	OUString* pRetStrings = NULL;
	if( pStringSeq )
	{
		pStringSeq->realloc( nTotalCount );
		pRetStrings = pStringSeq->getArray();
	}

	InvocationInfo* pRetInfos = NULL;
	if( pInfoSeq )
	{
		pInfoSeq->realloc( nTotalCount );
		pRetInfos = pInfoSeq->getArray();
	}

	// Fill result sequences in the correct order of members
	for( iTotal = 0 ; iTotal < nTotalCount ; iTotal++ )
	{
		MemberItem& rItem = pItems[ iTotal ];
		if( pRetStrings )
		{
			pRetStrings[ iTotal ] = rItem.aName;
		}

		if( pRetInfos )
		{
			if( rItem.eMode == MemberItem::NAMEACCESS )
			{
				fillInfoForNameAccess( pRetInfos[ iTotal ], rItem.aName );
			}
			else if( rItem.eMode == MemberItem::PROPERTYSET )
			{
				fillInfoForProperty( pRetInfos[ iTotal ], pProps[ rItem.nIndex ] );
			}
			else if( rItem.eMode == MemberItem::METHOD )
			{
				fillInfoForMethod( pRetInfos[ iTotal ], pMethods[ rItem.nIndex ] );
			}
		}
	}
}

// XInvocation2
Sequence< OUString > SAL_CALL Invocation_Impl::getMemberNames(  )
	throw( RuntimeException )
{
	if( _xDirect2.is() )
	{
		return _xDirect2->getMemberNames();
	}
	Sequence< OUString > aRetSeq;
	getInfoSequenceImpl( &aRetSeq, NULL );
	return aRetSeq;
}

Sequence< InvocationInfo > SAL_CALL Invocation_Impl::getInfo(  )
	throw( RuntimeException )
{
	if( _xDirect2.is() )
	{
		return _xDirect2->getInfo();
	}
	Sequence< InvocationInfo > aRetSeq;
	getInfoSequenceImpl( NULL, &aRetSeq );
	return aRetSeq;
}

InvocationInfo SAL_CALL Invocation_Impl::getInfoForName( const OUString& aName, sal_Bool bExact )
	throw( IllegalArgumentException, RuntimeException )
{
	if( _xDirect2.is() )
	{
		return _xDirect2->getInfoForName( aName, bExact );
	}

	sal_Bool bFound = sal_False;
	OUString aExactName = aName;
	InvocationInfo aRetInfo;

	if( bExact )
		aExactName = getExactName( aName );
	if( aExactName.getLength() > 0 )
	{
		if( _xIntrospectionAccess->hasMethod( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS ) )
		{
			Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod
				( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
			fillInfoForMethod( aRetInfo, xMethod );
			bFound = sal_True;
		}
		else
		{
			if( _xIntrospectionAccess.is() && _xIntrospectionAccess->hasProperty
				 ( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
			{
 				Property aProp = _xIntrospectionAccess->getProperty
					( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS );
				fillInfoForProperty( aRetInfo, aProp );
				bFound = sal_True;
			}
			// NameAccess
			else if( _xNameAccess.is() && _xNameAccess->hasByName( aExactName ) )
			{
				fillInfoForNameAccess( aRetInfo, aExactName );
				bFound = sal_True;
			}
		}
	}
	if( !bFound )
	{
		throw IllegalArgumentException(
			OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown name, getExactName() failed!") ),
			(XWeak *)(OWeakObject *)this, 0 );
	}
	return aRetInfo;
}

// Helper functions to fill InvocationInfo for XNameAccess
void Invocation_Impl::fillInfoForNameAccess
(
	InvocationInfo& rInfo,
	const OUString& aName
)
{
	rInfo.aName = aName;
    rInfo.eMemberType = MemberType_PROPERTY;
    rInfo.PropertyAttribute = 0;
	if( !_xNameContainer.is() )
	{
		rInfo.PropertyAttribute = PropertyAttribute::READONLY;
	}
    rInfo.aType = _xNameAccess->getElementType();
}

void Invocation_Impl::fillInfoForProperty
(
	InvocationInfo& rInfo,
	const Property& rProp
)
{
	rInfo.aName = rProp.Name;
    rInfo.eMemberType = MemberType_PROPERTY;
    rInfo.PropertyAttribute = rProp.Attributes;
    rInfo.aType = rProp.Type;
}

void Invocation_Impl::fillInfoForMethod
(
	InvocationInfo& rInfo,
	const Reference< XIdlMethod > xMethod
)
{
	rInfo.aName = xMethod->getName();
    rInfo.eMemberType = MemberType_METHOD;
	Reference< XIdlClass > xReturnClass = xMethod->getReturnType();
	Type aReturnType( xReturnClass->getTypeClass(), xReturnClass->getName() );
    rInfo.aType = aReturnType;
	Sequence<ParamInfo> aParamInfos = xMethod->getParameterInfos();
	sal_Int32 nParamCount = aParamInfos.getLength();
	if( nParamCount > 0 )
	{
		const ParamInfo* pInfos = aParamInfos.getConstArray();

		rInfo.aParamTypes.realloc( nParamCount );
		Type* pParamTypes = rInfo.aParamTypes.getArray();
		rInfo.aParamModes.realloc( nParamCount );
		ParamMode* pParamModes = rInfo.aParamModes.getArray();

		for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
		{
			Reference< XIdlClass > xParamClass = pInfos[i].aType;
			Type aParamType( xParamClass->getTypeClass(), xParamClass->getName() );
			pParamTypes[ i ] = aParamType;
			pParamModes[ i ] = pInfos[i].aMode;
		}
	}
}


// XTypeProvider
Sequence< Type > SAL_CALL Invocation_Impl::getTypes(void) throw( RuntimeException )
{
    static Sequence< Type > const * s_pTypes = 0;
    if (! s_pTypes)
    {
        Sequence< Type > types( 4 +8 );
        Type * pTypes = types.getArray();
        sal_Int32 n = 0;

        pTypes[ n++ ] = ::getCppuType( (Reference< XTypeProvider > const *)0 );
        pTypes[ n++ ] = ::getCppuType( (Reference< XWeak > const *)0 );
        pTypes[ n++ ] = ::getCppuType( (Reference< XInvocation > const *)0 );
        pTypes[ n++ ] = ::getCppuType( (Reference< XMaterialHolder > const *)0 );

		// Ivocation does not support XExactName, if direct object supports
		// XInvocation, but not XExactName.
		if ((_xDirect.is() && _xENDirect.is()) ||
			(!_xDirect.is() && (_xENIntrospection.is() || _xENNameAccess.is())))
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XExactName > const *)0 );
		}
		if( _xNameContainer.is() )
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XNameContainer > const *)0 );
		}
		if( _xNameAccess.is() )
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XNameAccess > const *)0 );
		}
		if (_xIndexContainer.is())
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XIndexContainer > const *)0 );
		}
		if (_xIndexAccess.is())
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XIndexAccess > const *)0 );
		}
		if (_xEnumerationAccess.is())
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XEnumerationAccess > const *)0 );
		}
		if (_xElementAccess.is())
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XElementAccess > const *)0 );
		}
		// Invocation does not support XInvocation2, if direct object supports
		// XInvocation, but not XInvocation2.
		if ( ( _xDirect.is() && _xDirect2.is()) ||
			 (!_xDirect.is() && _xIntrospectionAccess.is() ) )
		{
            pTypes[ n++ ] = ::getCppuType( (Reference< XInvocation2 > const *)0 );
		}

        types.realloc( n );

        // store types
        MutexGuard guard( Mutex::getGlobalMutex() );
        if (! s_pTypes)
        {
            static Sequence< Type > s_types( types );
            s_pTypes = &s_types;
        }
    }
    return *s_pTypes;
}

Sequence< sal_Int8 > SAL_CALL Invocation_Impl::getImplementationId(  ) throw( RuntimeException)
{
    static OImplementationId *pId = 0;
    if( ! pId )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( ! pId )
        {
            static OImplementationId id( sal_False );
            pId = &id;
        }
    }
    return pId->getImplementationId();
}

//==================================================================================================
//==================================================================================================
//==================================================================================================
class InvocationService
	: public WeakImplHelper2< XSingleServiceFactory, XServiceInfo >
{
public:
	InvocationService( const Reference<XComponentContext> & xCtx );
	virtual ~InvocationService();

	// XServiceInfo
	OUString 					SAL_CALL getImplementationName() throw( RuntimeException );
    sal_Bool 						SAL_CALL supportsService(const OUString& ServiceName) throw( RuntimeException );
    Sequence< OUString > 		SAL_CALL getSupportedServiceNames(void) throw( RuntimeException );

	// XSingleServiceFactory
    Reference<XInterface>		SAL_CALL createInstance(void) throw( Exception, RuntimeException );
    Reference<XInterface>		SAL_CALL createInstanceWithArguments(
		const Sequence<Any>& rArguments ) throw( Exception, RuntimeException );
private:
	Reference<XComponentContext> mxCtx;
	Reference<XMultiComponentFactory> mxSMgr;
	Reference<XTypeConverter> xTypeConverter;
	Reference<XIntrospection> xIntrospection;
	Reference<XIdlReflection> xCoreReflection;
};

InvocationService::InvocationService( const Reference<XComponentContext> & xCtx )
	: mxCtx( xCtx )
	, mxSMgr( xCtx->getServiceManager() )
{
	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
	xTypeConverter = Reference<XTypeConverter>(
		mxSMgr->createInstanceWithContext(
			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")),
			xCtx ),
		UNO_QUERY );
	xIntrospection = Reference<XIntrospection>(
		mxSMgr->createInstanceWithContext(
			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.Introspection")),
			xCtx),
		UNO_QUERY);
    mxCtx->getValueByName(
        OUString(
            RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection")) )
                >>= xCoreReflection;
    OSL_ENSURE( xCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
    if (! xCoreReflection.is())
    {
        throw DeploymentException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ),
            Reference< XInterface >() );
    }
//         xCoreReflection = Reference<XIdlReflection>(
// 		mxSMgr->createInstanceWithContext(
// 			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")),
// 			xCtx),
// 		UNO_QUERY);
}

InvocationService::~InvocationService()
{
	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}

// XServiceInfo
OUString InvocationService::getImplementationName() throw( RuntimeException )
{
	return inv_getImplementationName();
}

// XServiceInfo
sal_Bool InvocationService::supportsService(const OUString& ServiceName) throw( RuntimeException )
{
	Sequence< OUString > aSNL = getSupportedServiceNames();
	const OUString * pArray = aSNL.getConstArray();
	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
		if( pArray[i] == ServiceName )
			return sal_True;
	return sal_False;
}

// XServiceInfo
Sequence< OUString > InvocationService::getSupportedServiceNames(void) throw( RuntimeException )
{
	return inv_getSupportedServiceNames();
}

//--------------------------------------------------------------------------------------------------
Reference<XInterface> InvocationService::createInstance(void) throw( Exception, RuntimeException )
{
	//TODO:throw( Exception(OUString( RTL_CONSTASCII_USTRINGPARAM("no default construction of invocation adapter possible!")), *this) );
	return Reference<XInterface>(); // dummy
}

//--------------------------------------------------------------------------------------------------
Reference<XInterface> InvocationService::createInstanceWithArguments(
	const Sequence<Any>& rArguments ) throw( Exception, RuntimeException )
{
	if (rArguments.getLength() == 1)
	{
		return Reference< XInterface >
			( *new Invocation_Impl( *rArguments.getConstArray(),
			  xTypeConverter, xIntrospection, xCoreReflection ) );
	}
	else
	{
		//TODO:throw( Exception(OUString( RTL_CONSTASCII_USTRINGPARAM("no default construction of invocation adapter possible!")), *this) );
		return Reference<XInterface>();
	}
}


//*************************************************************************
Reference<XInterface> SAL_CALL InvocationService_CreateInstance( const Reference<XComponentContext> & xCtx )
	throw( RuntimeException )
{
	Reference<XInterface> xService = Reference< XInterface > ( *new InvocationService( xCtx ) );
	return xService;
}

}

using namespace stoc_inv;
static struct ImplementationEntry g_entries[] =
{
	{
		InvocationService_CreateInstance, inv_getImplementationName,
		inv_getSupportedServiceNames, createSingleComponentFactory,
		&g_moduleCount.modCnt , 0
	},
	{ 0, 0, 0, 0, 0, 0 }
};

extern "C"
{
sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
{
	return g_moduleCount.canUnload( &g_moduleCount , pTime );
}

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
	const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
void * SAL_CALL component_getFactory(
	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
	return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}
}
