/**************************************************************
 *
 * 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_cppuhelper.hxx"

#include "osl/diagnose.h"
#include "cppuhelper/implbase1.hxx"
#include "cppuhelper/weak.hxx"
#include "cppuhelper/propshlp.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "com/sun/star/beans/PropertyAttribute.hpp"
#include "com/sun/star/lang/DisposedException.hpp"


using namespace osl;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::lang;
using namespace rtl;
using namespace cppu;

namespace cppu {

IPropertyArrayHelper::~IPropertyArrayHelper()
{
}

inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW( () )
{
	return ::getCppuType( (Reference< XPropertyChangeListener > *)0 );
}
inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW( () )
{
	return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 );
}
inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW( () )
{
	return ::getCppuType( (Reference< XVetoableChangeListener > *)0 );
}

extern "C" {

static int compare_OUString_Property_Impl( const void *arg1, const void *arg2 )
    SAL_THROW_EXTERN_C()
{
   return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name );
}

}

/**
 * The class which implements the PropertySetInfo interface.
 */

class OPropertySetHelperInfo_Impl
	: public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
{
	Sequence < Property > aInfos;

public:
	OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) SAL_THROW( () );

	// XPropertySetInfo-Methoden
    virtual Sequence< Property > SAL_CALL getProperties(void) throw(::com::sun::star::uno::RuntimeException);
    virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) throw(::com::sun::star::uno::RuntimeException);
};


/**
 * Create an object that implements XPropertySetInfo IPropertyArrayHelper.
 */
OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(
	IPropertyArrayHelper & rHelper_ )
	SAL_THROW( () )
	:aInfos( rHelper_.getProperties() )
{
}

/**
 * Return the sequence of properties, which are provided throug the constructor.
 */
Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException)

{
	return aInfos;
}

/**
 * Return the sequence of properties, which are provided throug the constructor.
 */
Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
{
	Property * pR;
	pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
                              sizeof( Property ),
							  compare_OUString_Property_Impl );
	if( !pR ) {
		throw UnknownPropertyException();
	}

	return *pR;
}

/**
 * Return the sequence of properties, which are provided throug the constructor.
 */
sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
	Property * pR;
	pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
                              sizeof( Property ),
							  compare_OUString_Property_Impl );
	return pR != NULL;
}

//	----------------------------------------------------
//	class PropertySetHelper_Impl
//	----------------------------------------------------
class OPropertySetHelper::Impl {

public:
    Impl(   bool i_bIgnoreRuntimeExceptionsWhileFiring,
            IEventNotificationHook *i_pFireEvents
        )
        :m_bIgnoreRuntimeExceptionsWhileFiring( i_bIgnoreRuntimeExceptionsWhileFiring )
        ,m_pFireEvents( i_pFireEvents )
    {
    }

    bool m_bIgnoreRuntimeExceptionsWhileFiring;
    class IEventNotificationHook * const m_pFireEvents;

    ::std::vector< sal_Int32 >  m_handles;
    ::std::vector< Any >        m_newValues;
    ::std::vector< Any >        m_oldValues;
};


//	----------------------------------------------------
//	class PropertySetHelper
//	----------------------------------------------------
OPropertySetHelper::OPropertySetHelper(
    OBroadcastHelper  & rBHelper_ ) SAL_THROW( () )
	: rBHelper( rBHelper_ ),
      aBoundLC( rBHelper_.rMutex ),
      aVetoableLC( rBHelper_.rMutex ),
      m_pReserved( new Impl(false, 0) )
{
}

OPropertySetHelper::OPropertySetHelper(
	OBroadcastHelper  & rBHelper_, bool bIgnoreRuntimeExceptionsWhileFiring )
	: rBHelper( rBHelper_ ),
      aBoundLC( rBHelper_.rMutex ),
      aVetoableLC( rBHelper_.rMutex ),
      m_pReserved( new Impl( bIgnoreRuntimeExceptionsWhileFiring, 0 ) )
{
}

OPropertySetHelper::OPropertySetHelper(
	OBroadcastHelper  & rBHelper_, IEventNotificationHook * i_pFireEvents,
    bool bIgnoreRuntimeExceptionsWhileFiring)
	: rBHelper( rBHelper_ ),
      aBoundLC( rBHelper_.rMutex ),
      aVetoableLC( rBHelper_.rMutex ),
      m_pReserved(
        new Impl( bIgnoreRuntimeExceptionsWhileFiring, i_pFireEvents) )
{
}

/**
 * You must call disposing before.
 */
OPropertySetHelper::~OPropertySetHelper() SAL_THROW( () )
{
}

/**
 * These method is called from queryInterface, if no delegator is set.
 * Otherwise this method is called from the delegator.
 */
// XAggregation
Any OPropertySetHelper::queryInterface( const ::com::sun::star::uno::Type & rType )
	throw (RuntimeException)
{
	return ::cppu::queryInterface(
		rType,
		static_cast< XPropertySet * >( this ),
		static_cast< XMultiPropertySet * >( this ),
		static_cast< XFastPropertySet * >( this ) );
}

/**
 * called from the derivee's XTypeProvider::getTypes implementation
 */
::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > OPropertySetHelper::getTypes()
    throw (RuntimeException)
{
    Sequence< ::com::sun::star::uno::Type > aTypes( 3 );
    aTypes[ 0 ] = XPropertySet::static_type();
    aTypes[ 1 ] = XMultiPropertySet::static_type();
    aTypes[ 2 ] = XFastPropertySet::static_type();
    return aTypes;
}

// ComponentHelper
void OPropertySetHelper::disposing() SAL_THROW( () )
{
	// Create an event with this as sender
	Reference < XPropertySet  > rSource( SAL_STATIC_CAST( XPropertySet * , this ) , UNO_QUERY );
	EventObject aEvt;
	aEvt.Source = rSource;

	// inform all listeners to reelease this object
	// The listener container are automatically cleared
	aBoundLC.disposeAndClear( aEvt );
	aVetoableLC.disposeAndClear( aEvt );
}

Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo(
	IPropertyArrayHelper & rProperties ) SAL_THROW( () )
{
	return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) );
}

// XPropertySet
void OPropertySetHelper::setPropertyValue(
	const OUString& rPropertyName, const Any& rValue )
	throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	// get the map table
	IPropertyArrayHelper & rPH = getInfoHelper();
	// map the name to the handle
	sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
	// call the method of the XFastPropertySet interface
	setFastPropertyValue( nHandle, rValue );
}

// XPropertySet
Any OPropertySetHelper::getPropertyValue(
	const OUString& rPropertyName )
	throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	// get the map table
	IPropertyArrayHelper & rPH = getInfoHelper();
	// map the name to the handle
	sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
	// call the method of the XFastPropertySet interface
	return getFastPropertyValue( nHandle );
}

// XPropertySet
void OPropertySetHelper::addPropertyChangeListener(
	const OUString& rPropertyName,
	const Reference < XPropertyChangeListener > & rxListener )
     throw(::com::sun::star::beans::UnknownPropertyException,
		   ::com::sun::star::lang::WrappedTargetException,
		   ::com::sun::star::uno::RuntimeException)
{
	MutexGuard aGuard( rBHelper.rMutex );
	OSL_ENSURE( !rBHelper.bInDispose, "do not addPropertyChangeListener in the dispose call" );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
	if( !rBHelper.bInDispose && !rBHelper.bDisposed )
	{
		// only add listeners if you are not disposed
		// a listener with no name means all properties
		if( rPropertyName.getLength() )
		{
			// get the map table
			IPropertyArrayHelper & rPH = getInfoHelper();
			// map the name to the handle
			sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
			if( nHandle == -1 ) {
				// property not known throw exception
				throw  UnknownPropertyException() ;
			}

			sal_Int16 nAttributes;
			rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
			if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) )
			{
				OSL_ENSURE( sal_False, "add listener to an unbound property" );
				// silent ignore this
				return;
			}
			// add the change listener to the helper container

			aBoundLC.addInterface( (sal_Int32)nHandle, rxListener );
		}
		else
			// add the change listener to the helper container
			rBHelper.aLC.addInterface(
							getPropertyTypeIdentifier(  ),
							rxListener
									 );
	}
}


// XPropertySet
void OPropertySetHelper::removePropertyChangeListener(
	const OUString& rPropertyName,
	const Reference < XPropertyChangeListener >& rxListener )
	throw(::com::sun::star::beans::UnknownPropertyException,
		  ::com::sun::star::lang::WrappedTargetException,
		  ::com::sun::star::uno::RuntimeException)
{
	MutexGuard aGuard( rBHelper.rMutex );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
	// all listeners are automatically released in a dispose call
	if( !rBHelper.bInDispose && !rBHelper.bDisposed )
	{
		if( rPropertyName.getLength() )
		{
			// get the map table
			IPropertyArrayHelper & rPH = getInfoHelper();
			// map the name to the handle
			sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
			if( nHandle == -1 )
				// property not known throw exception
				throw UnknownPropertyException();
			aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener );
		}
		else {
			// remove the change listener to the helper container
			rBHelper.aLC.removeInterface(
							getPropertyTypeIdentifier(  ),
							rxListener
										);
		}
	}
}

// XPropertySet
void OPropertySetHelper::addVetoableChangeListener(
	const OUString& rPropertyName,
	const Reference< XVetoableChangeListener > & rxListener )
	throw(::com::sun::star::beans::UnknownPropertyException,
		  ::com::sun::star::lang::WrappedTargetException,
		  ::com::sun::star::uno::RuntimeException)
{
	MutexGuard aGuard( rBHelper.rMutex );
	OSL_ENSURE( !rBHelper.bInDispose, "do not addVetoableChangeListener in the dispose call" );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
	if( !rBHelper.bInDispose && !rBHelper.bDisposed )
	{
		// only add listeners if you are not disposed
		// a listener with no name means all properties
		if( rPropertyName.getLength() )
		{
			// get the map table
			IPropertyArrayHelper & rPH = getInfoHelper();
			// map the name to the handle
			sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
			if( nHandle == -1 ) {
				// property not known throw exception
				throw UnknownPropertyException();
			}

			sal_Int16 nAttributes;
			rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
			if( !(nAttributes & PropertyAttribute::CONSTRAINED) )
			{
				OSL_ENSURE( sal_False, "addVetoableChangeListener, and property is not constrained" );
				// silent ignore this
				return;
			}
			// add the vetoable listener to the helper container
			aVetoableLC.addInterface( (sal_Int32)nHandle, rxListener );
		}
		else
			// add the vetoable listener to the helper container
			rBHelper.aLC.addInterface(
								getVetoableTypeIdentifier(  ),
								rxListener
									 );
	}
}

// XPropertySet
void OPropertySetHelper::removeVetoableChangeListener(
	const OUString& rPropertyName,
	const Reference < XVetoableChangeListener > & rxListener )
	throw(::com::sun::star::beans::UnknownPropertyException,
		  ::com::sun::star::lang::WrappedTargetException,
		  ::com::sun::star::uno::RuntimeException)
{
	MutexGuard aGuard( rBHelper.rMutex );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
	// all listeners are automatically released in a dispose call
	if( !rBHelper.bInDispose && !rBHelper.bDisposed )
	{
		if( rPropertyName.getLength() )
		{
			// get the map table
			IPropertyArrayHelper & rPH = getInfoHelper();
			// map the name to the handle
			sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
			if( nHandle == -1 ) {
				// property not known throw exception
				throw UnknownPropertyException();
			}
			// remove the vetoable listener to the helper container
			aVetoableLC.removeInterface( (sal_Int32)nHandle, rxListener );
		}
		else
			// add the vetoable listener to the helper container
			rBHelper.aLC.removeInterface(
								getVetoableTypeIdentifier( ),
								rxListener
										);
	}
}

void OPropertySetHelper::setDependentFastPropertyValue( sal_Int32 i_handle, const ::com::sun::star::uno::Any& i_value )
{
    //OSL_PRECOND( rBHelper.rMutex.isAcquired(), "OPropertySetHelper::setDependentFastPropertyValue: to be called with a locked mutex only!" );
        // there is no such thing as Mutex.isAcquired, sadly ...

	sal_Int16 nAttributes(0);
	IPropertyArrayHelper& rInfo = getInfoHelper();
	if ( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, i_handle ) )
		// unknown property
		throw UnknownPropertyException();

    // no need to check for READONLY-ness of the property. The method is intended to be called internally, which
    // implies it might be invoked for properties which are read-only to the instance's clients, but well allowed
    // to change their value.

    Any aConverted, aOld;
    sal_Bool bChanged = convertFastPropertyValue( aConverted, aOld, i_handle, i_value );
    if ( !bChanged )
        return;

    // don't fire vetoable events. This method is called with our mutex locked, so calling into listeners would not be
    // a good idea. The caler is responsible for not invoking this for constrained properties.
    OSL_ENSURE( ( nAttributes & PropertyAttribute::CONSTRAINED ) == 0,
        "OPropertySetHelper::setDependentFastPropertyValue: not to be used for constrained properties!" );
    (void)nAttributes;

	// actually set the new value
	try
	{
		setFastPropertyValue_NoBroadcast( i_handle, aConverted );
	}
	catch (const UnknownPropertyException& )    { throw;	/* allowed to leave */ }
	catch (const PropertyVetoException& )       { throw;	/* allowed to leave */ }
	catch (const IllegalArgumentException& )    { throw;	/* allowed to leave */ }
	catch (const WrappedTargetException& )      { throw;	/* allowed to leave */ }
	catch (const RuntimeException& )            { throw;	/* allowed to leave */ }
	catch (const Exception& )
	{
		// not allowed to leave this method
		WrappedTargetException aWrapped;
        aWrapped.TargetException <<= ::cppu::getCaughtException();
		aWrapped.Context = static_cast< XPropertySet* >( this );
		throw aWrapped;
	}

    // remember the handle/values, for the events to be fired later
    m_pReserved->m_handles.push_back( i_handle );
    m_pReserved->m_newValues.push_back( aConverted );   // TODO: setFastPropertyValue notifies the unconverted value here ...?
    m_pReserved->m_oldValues.push_back( aOld );
}

// XFastPropertySet
void OPropertySetHelper::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
	 throw(::com::sun::star::beans::UnknownPropertyException,
		   ::com::sun::star::beans::PropertyVetoException,
		   ::com::sun::star::lang::IllegalArgumentException,
		   ::com::sun::star::lang::WrappedTargetException,
		   ::com::sun::star::uno::RuntimeException)
{
	OSL_ENSURE( !rBHelper.bInDispose, "do not setFastPropertyValue in the dispose call" );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );

	IPropertyArrayHelper & rInfo = getInfoHelper();
	sal_Int16 nAttributes;
	if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) {
		// unknown property
		throw UnknownPropertyException();
	}
	if( nAttributes & PropertyAttribute::READONLY )
		throw PropertyVetoException();

	Any	aConvertedVal;
	Any	aOldVal;

	// Will the property change?
	sal_Bool bChanged;
	{
		MutexGuard aGuard( rBHelper.rMutex );
		bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue );
		// release guard to fire events
	}
	if( bChanged )
	{
		// Is it a constrained property?
		if( nAttributes & PropertyAttribute::CONSTRAINED )
		{
			// In aValue is the converted rValue
			// fire a constarined event
			// second parameter NULL means constrained
			fire( &nHandle, &rValue, &aOldVal, 1, sal_True );
		}

		{
			MutexGuard aGuard( rBHelper.rMutex );
			try
			{
				// set the property to the new value
				setFastPropertyValue_NoBroadcast( nHandle, aConvertedVal );
			}
			catch (const ::com::sun::star::beans::UnknownPropertyException& )	{ throw;	/* allowed to leave */ }
			catch (const ::com::sun::star::beans::PropertyVetoException& )		{ throw;	/* allowed to leave */ }
			catch (const ::com::sun::star::lang::IllegalArgumentException& )	{ throw;	/* allowed to leave */ }
			catch (const ::com::sun::star::lang::WrappedTargetException& )		{ throw;	/* allowed to leave */ }
			catch (const ::com::sun::star::uno::RuntimeException& )				{ throw;	/* allowed to leave */ }
			catch (const ::com::sun::star::uno::Exception& e )
			{
				// not allowed to leave this method
				::com::sun::star::lang::WrappedTargetException aWrap;
				aWrap.Context = static_cast< ::com::sun::star::beans::XPropertySet* >( this );
				aWrap.TargetException <<= e;

				throw ::com::sun::star::lang::WrappedTargetException( aWrap );
			}

			// release guard to fire events
		}
		// file a change event, if the value changed
		impl_fireAll( &nHandle, &rValue, &aOldVal, 1 );
	}
}

// XFastPropertySet
Any OPropertySetHelper::getFastPropertyValue( sal_Int32 nHandle )
	 throw(::com::sun::star::beans::UnknownPropertyException,
		   ::com::sun::star::lang::WrappedTargetException,
		   ::com::sun::star::uno::RuntimeException)

{
	IPropertyArrayHelper & rInfo = getInfoHelper();
	if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) )
		// unknown property
		throw UnknownPropertyException();

	Any aRet;
	MutexGuard aGuard( rBHelper.rMutex );
	getFastPropertyValue( aRet, nHandle );
	return aRet;
}

//--------------------------------------------------------------------------
void OPropertySetHelper::impl_fireAll( sal_Int32* i_handles, const Any* i_newValues, const Any* i_oldValues, sal_Int32 i_count )
{
    ClearableMutexGuard aGuard( rBHelper.rMutex );
    if ( m_pReserved->m_handles.empty() )
    {
        aGuard.clear();
        fire( i_handles, i_newValues, i_oldValues, i_count, sal_False );
        return;
    }

    const size_t additionalEvents = m_pReserved->m_handles.size();
    OSL_ENSURE( additionalEvents == m_pReserved->m_newValues.size()
            &&  additionalEvents == m_pReserved->m_oldValues.size(),
            "OPropertySetHelper::impl_fireAll: inconsistency!" );

    ::std::vector< sal_Int32 > allHandles( additionalEvents + i_count );
    ::std::copy( m_pReserved->m_handles.begin(), m_pReserved->m_handles.end(), allHandles.begin() );
    ::std::copy( i_handles, i_handles + i_count, allHandles.begin() + additionalEvents );

    ::std::vector< Any > allNewValues( additionalEvents + i_count );
    ::std::copy( m_pReserved->m_newValues.begin(), m_pReserved->m_newValues.end(), allNewValues.begin() );
    ::std::copy( i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents );

    ::std::vector< Any > allOldValues( additionalEvents + i_count );
    ::std::copy( m_pReserved->m_oldValues.begin(), m_pReserved->m_oldValues.end(), allOldValues.begin() );
    ::std::copy( i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents );

    m_pReserved->m_handles.clear();
    m_pReserved->m_newValues.clear();
    m_pReserved->m_oldValues.clear();

    aGuard.clear();
    fire( &allHandles[0], &allNewValues[0], &allOldValues[0], additionalEvents + i_count, sal_False );
}

//--------------------------------------------------------------------------
void OPropertySetHelper::fire
(
	sal_Int32 * pnHandles,
	const Any * pNewValues,
	const Any * pOldValues,
	sal_Int32 nHandles, // These is the Count of the array
	sal_Bool bVetoable
)
{
    OSL_ENSURE( m_pReserved.get(), "No OPropertySetHelper::Impl" );
    if (m_pReserved->m_pFireEvents) {
        m_pReserved->m_pFireEvents->fireEvents(
            pnHandles, nHandles, bVetoable,
            m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring);
    }

	// Only fire, if one or more properties changed
	if( nHandles )
	{
		// create the event sequence of all changed properties
		Sequence< PropertyChangeEvent > aEvts( nHandles );
		PropertyChangeEvent * pEvts = aEvts.getArray();
		Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
		sal_Int32 i;
		sal_Int32 nChangesLen = 0;
		// Loop over all changed properties to fill the event struct
		for( i = 0; i < nHandles; i++ )
		{
			// Vetoable fire and constrained attribute set or
			// Change fire and Changed and bound attribute set
			IPropertyArrayHelper & rInfo = getInfoHelper();
			sal_Int16	nAttributes;
			OUString aPropName;
			rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] );

			if(
               (bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) ||
               (!bVetoable && (nAttributes & PropertyAttribute::BOUND))
              )
			{
				pEvts[nChangesLen].Source = xSource;
				pEvts[nChangesLen].PropertyName = aPropName;
				pEvts[nChangesLen].PropertyHandle = pnHandles[i];
				pEvts[nChangesLen].OldValue = pOldValues[i];
				pEvts[nChangesLen].NewValue = pNewValues[i];
				nChangesLen++;
			}
		}

        bool bIgnoreRuntimeExceptionsWhileFiring =
                m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring;

		// fire the events for all changed properties
		for( i = 0; i < nChangesLen; i++ )
		{
			// get the listener container for the property name
			OInterfaceContainerHelper * pLC;
			if( bVetoable ) // fire change Events?
				pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle );
			else
				pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle );
			if( pLC )
			{
				// Ueber alle Listener iterieren und Events senden
				OInterfaceIteratorHelper aIt( *pLC);
				while( aIt.hasMoreElements() )
				{
					XInterface * pL = aIt.next();
                    try
                    {
                        try
                        {
                            if( bVetoable ) // fire change Events?
                            {
                                ((XVetoableChangeListener *)pL)->vetoableChange(
                                    pEvts[i] );
                            }
                            else
                            {
                                ((XPropertyChangeListener *)pL)->propertyChange(
                                    pEvts[i] );
                            }
                        }
                        catch (DisposedException & exc)
                        {
                            OSL_ENSURE( exc.Context.is(),
                                        "DisposedException without Context!" );
                            if (exc.Context == pL)
                                aIt.remove();
                            else
                                throw;
                        }
                    }
                    catch (RuntimeException & exc)
                    {
                        OSL_TRACE(
                            OUStringToOString(
                                OUString( RTL_CONSTASCII_USTRINGPARAM(
                                              "caught RuntimeException while "
                                              "firing listeners: ") ) +
                                exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
                        if (! bIgnoreRuntimeExceptionsWhileFiring)
                            throw;
                    }
				}
			}
			// broadcast to all listeners with "" property name
			if( bVetoable ){
				// fire change Events?
				pLC = rBHelper.aLC.getContainer(
							getVetoableTypeIdentifier()
												);
			}
			else {
				pLC = rBHelper.aLC.getContainer(
							getPropertyTypeIdentifier(  )
												);
			}
			if( pLC )
			{
				// Ueber alle Listener iterieren und Events senden
				OInterfaceIteratorHelper aIt( *pLC);
				while( aIt.hasMoreElements() )
				{
					XInterface * pL = aIt.next();
                    try
                    {
                        try
                        {
                            if( bVetoable ) // fire change Events?
                            {
                                ((XVetoableChangeListener *)pL)->vetoableChange(
                                    pEvts[i] );
                            }
                            else
                            {
                                ((XPropertyChangeListener *)pL)->propertyChange(
                                    pEvts[i] );
                            }
                        }
                        catch (DisposedException & exc)
                        {
                            OSL_ENSURE( exc.Context.is(),
                                        "DisposedException without Context!" );
                            if (exc.Context == pL)
                                aIt.remove();
                            else
                                throw;
                        }
                    }
                    catch (RuntimeException & exc)
                    {
                        OSL_TRACE(
                            OUStringToOString(
                                OUString( RTL_CONSTASCII_USTRINGPARAM(
                                              "caught RuntimeException while "
                                              "firing listeners: ") ) +
                                exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
                        if (! bIgnoreRuntimeExceptionsWhileFiring)
                            throw;
                    }
				}
			}
		}

		// reduce array to changed properties
		aEvts.realloc( nChangesLen );

		if( !bVetoable )
		{
			OInterfaceContainerHelper * pCont = 0;
			pCont = rBHelper.aLC.getContainer(
								getPropertiesTypeIdentifier(  )
											 );
			if( pCont )
			{
				// Here is a Bug, unbound properties are also fired
				OInterfaceIteratorHelper aIt( *pCont );
				while( aIt.hasMoreElements() )
				{
					XPropertiesChangeListener * pL =
                        (XPropertiesChangeListener *)aIt.next();
                    try
                    {
                        try
                        {
                            // fire the hole event sequence to the
                            // XPropertiesChangeListener's
                            pL->propertiesChange( aEvts );
                        }
                        catch (DisposedException & exc)
                        {
                            OSL_ENSURE( exc.Context.is(),
                                        "DisposedException without Context!" );
                            if (exc.Context == pL)
                                aIt.remove();
                            else
                                throw;
                        }
                    }
                    catch (RuntimeException & exc)
                    {
                        OSL_TRACE(
                            OUStringToOString(
                                OUString( RTL_CONSTASCII_USTRINGPARAM(
                                              "caught RuntimeException while "
                                              "firing listeners: ") ) +
                                exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
                        if (! bIgnoreRuntimeExceptionsWhileFiring)
                            throw;
                    }
				}
			}
		}
	}
}

// OPropertySetHelper
void OPropertySetHelper::setFastPropertyValues(
	sal_Int32 nSeqLen,
	sal_Int32 * pHandles,
	const Any * pValues,
	sal_Int32 nHitCount )
	SAL_THROW( (::com::sun::star::uno::Exception) )
{
	OSL_ENSURE( !rBHelper.bInDispose, "do not getFastPropertyValue in the dispose call" );
	OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );

	Any * pConvertedValues = NULL;
	Any * pOldValues = NULL;

	try
	{
		// get the map table
		IPropertyArrayHelper & rPH = getInfoHelper();

		pConvertedValues = new Any[ nHitCount ];
		pOldValues = new Any[ nHitCount ];
		sal_Int32 n = 0;
		sal_Int32 i;

		{
		// must lock the mutex outside the loop. So all values are consistent.
		MutexGuard aGuard( rBHelper.rMutex );
		for( i = 0; i < nSeqLen; i++ )
		{
			if( pHandles[i] != -1 )
			{
				sal_Int16 nAttributes;
				rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] );
				if( nAttributes & PropertyAttribute::READONLY ) {
					throw PropertyVetoException();
				}
				// Will the property change?
				if( convertFastPropertyValue( pConvertedValues[ n ], pOldValues[n],
											pHandles[i], pValues[i] ) )
				{
					// only increment if the property really change
					pHandles[n]			= pHandles[i];
					n++;
				}
			}
		}
		// release guard to fire events
		}

		// fire vetoable events
		fire( pHandles, pConvertedValues, pOldValues, n, sal_True );

		{
		// must lock the mutex outside the loop.
		MutexGuard aGuard( rBHelper.rMutex );
		// Loop over all changed properties
		for( i = 0; i < n; i++ )
		{
			// Will the property change?
			setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
		}
		// release guard to fire events
		}

		// fire change events
		impl_fireAll( pHandles, pConvertedValues, pOldValues, n );
	}
	catch( ... )
	{
		delete [] pOldValues;
		delete [] pConvertedValues;
		throw;
	}
	delete [] pOldValues;
	delete [] pConvertedValues;
}

// XMultiPropertySet
/**
 * The sequence may contain not known properties. The implementation
 * must ignore these properties.
 */
void OPropertySetHelper::setPropertyValues(
	const Sequence<OUString>& rPropertyNames,
	const Sequence<Any>& rValues )
	throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
{
	sal_Int32 * pHandles = NULL;
	try
	{
		sal_Int32	nSeqLen = rPropertyNames.getLength();
		pHandles = new sal_Int32[ nSeqLen ];
		// get the map table
		IPropertyArrayHelper & rPH = getInfoHelper();
		// fill the handle array
		sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames );
		if( nHitCount != 0 )
			setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount );
	}
	catch( ... )
	{
		delete [] pHandles;
		throw;
	}
	delete [] pHandles;
}

// XMultiPropertySet
Sequence<Any> OPropertySetHelper::getPropertyValues( const Sequence<OUString>& rPropertyNames )
	throw(::com::sun::star::uno::RuntimeException)
{
	sal_Int32	nSeqLen = rPropertyNames.getLength();
	sal_Int32 *	pHandles = new sal_Int32[ nSeqLen ];
	Sequence< Any > aValues( nSeqLen );

	// get the map table
	IPropertyArrayHelper & rPH = getInfoHelper();
	// fill the handle array
	rPH.fillHandles( pHandles, rPropertyNames );

	Any * pValues = aValues.getArray();

	MutexGuard aGuard( rBHelper.rMutex );
	// fill the sequence with the values
	for( sal_Int32 i = 0; i < nSeqLen; i++ )
		getFastPropertyValue( pValues[i], pHandles[i] );

	delete [] pHandles;
	return aValues;
}

// XMultiPropertySet
void OPropertySetHelper::addPropertiesChangeListener(
	const Sequence<OUString> & ,
	const Reference < XPropertiesChangeListener > & rListener )
	throw(::com::sun::star::uno::RuntimeException)
{
	rBHelper.addListener( getCppuType(&rListener) , rListener );
}

// XMultiPropertySet
void OPropertySetHelper::removePropertiesChangeListener(
	const Reference < XPropertiesChangeListener > & rListener )
	throw(::com::sun::star::uno::RuntimeException)
{
	rBHelper.removeListener( getCppuType(&rListener) , rListener );
}

// XMultiPropertySet
void OPropertySetHelper::firePropertiesChangeEvent(
	const Sequence<OUString>& rPropertyNames,
	const Reference < XPropertiesChangeListener >& rListener )
	throw(::com::sun::star::uno::RuntimeException)
{
	sal_Int32 nLen = rPropertyNames.getLength();
	sal_Int32 * pHandles = new sal_Int32[nLen];
	IPropertyArrayHelper & rPH = getInfoHelper();
	rPH.fillHandles( pHandles, rPropertyNames );
	const OUString* pNames = rPropertyNames.getConstArray();

	// get the count of matching properties
	sal_Int32 nFireLen = 0;
	sal_Int32 i;
	for( i = 0; i < nLen; i++ )
		if( pHandles[i] != -1 )
			nFireLen++;

	Sequence<PropertyChangeEvent> aChanges( nFireLen );
	PropertyChangeEvent* pChanges = aChanges.getArray();

	sal_Int32 nFirePos = 0;
	{
	// must lock the mutex outside the loop. So all values are consistent.
	MutexGuard aGuard( rBHelper.rMutex );
	Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
	for( i = 0; i < nLen; i++ )
	{
		if( pHandles[i] != -1 )
		{
			pChanges[nFirePos].Source = xSource;
			pChanges[nFirePos].PropertyName = pNames[i];
			pChanges[nFirePos].PropertyHandle = pHandles[i];
			getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] );
			pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue;
			nFirePos++;
		}
	}
	// release guard to fire events
	}
	if( nFireLen )
		rListener->propertiesChange( aChanges );

	delete [] pHandles;
}

#ifdef xdvnsdfln
// XPropertyState
PropertyState OPropertySetHelper::getPropertyState( const OUString& PropertyName )
{
	PropertyState aState;
	return aState;
}

// XPropertyState
Sequence< PropertyState > OPropertySetHelper::getPropertyStates( const Sequence< OUString >& PropertyNames )
{
	ULONG nNames = PropertyNames.getLength();
	const OUString* pNames = PropertyNames.getConstArray();

	Sequence< PropertyState > aStates( nNames );
	return aStates;

}

void OPropertySetHelper::setPropertyToDefault( const OUString& aPropertyName )
{
	setPropertyValue( aPropertyName, Any() );
}

Any OPropertySetHelper::getPropertyDefault( const OUString& aPropertyName ) const
{
	return Any();
}

void OPropertySetHelper::addPropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener )
{
}

void OPropertySetHelper::removePropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener )
{
}
#endif

//========================================================================
//== OPropertyArrayHelper ================================================
//========================================================================

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

//  static OUString makeOUString( sal_Char *p )
//  {
//  	sal_Int32 nLen = strlen(p);
//  	sal_Unicode *pw = new sal_Unicode[nLen];

//  	for( int i = 0 ; i < nLen ; i ++ ) {

//  		// Only ascii strings allowed with this helper !
//  		OSL_ASSERT( p[i] < 127 );
//  		pw[i] = p[i];
//  	}
//  	OUString ow( pw , nLen );
//  	delete pw;
//  	return ow;
//  }

extern "C" {

static int compare_Property_Impl( const void *arg1, const void *arg2 )
    SAL_THROW_EXTERN_C()
{
   return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name );
}

}

void OPropertyArrayHelper::init( sal_Bool bSorted ) SAL_THROW( () )
{
	sal_Int32 i, nElements = aInfos.getLength();
	const Property* pProperties = aInfos.getConstArray();

	for( i = 1; i < nElements; i++ )
	{
		if(  pProperties[i-1].Name >= pProperties[i].Name )
		{
#ifndef OS2 // YD disabled, too many troubles with debug builds!
            if (bSorted) {
                OSL_ENSURE( false, "Property array is not sorted" );
            }
#endif
			// not sorted
			qsort( aInfos.getArray(), nElements, sizeof( Property ),
					compare_Property_Impl );
			break;
		}
	}
	// may be that the array is resorted
	pProperties = aInfos.getConstArray();
	for( i = 0; i < nElements; i++ )
		if( pProperties[i].Handle != i )
			return;
	// The handle is the index
	bRightOrdered = sal_True;
}

OPropertyArrayHelper::OPropertyArrayHelper(
	Property * pProps,
	sal_Int32 nEle,
	sal_Bool bSorted )
	SAL_THROW( () )
	: aInfos(pProps, nEle)
	, bRightOrdered( sal_False )
{
	init( bSorted );
}

OPropertyArrayHelper::OPropertyArrayHelper(
	const Sequence< Property > & aProps,
	sal_Bool bSorted )
	SAL_THROW( () )
	: aInfos(aProps)
	, bRightOrdered( sal_False )
{
	init( bSorted );
}

//========================================================================
sal_Int32 OPropertyArrayHelper::getCount() const
{
	return aInfos.getLength();
}

//========================================================================
sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle
(
	OUString * pPropName,
	sal_Int16 * pAttributes,
	sal_Int32 nHandle
)
{
	const Property* pProperties = aInfos.getConstArray();
	sal_Int32 nElements = aInfos.getLength();

	if( bRightOrdered )
	{
		if( nHandle < 0 || nHandle >= nElements )
			return sal_False;
		if( pPropName )
			*pPropName = pProperties[ nHandle ].Name;
		if( pAttributes )
			*pAttributes = pProperties[ nHandle ].Attributes;
		return sal_True;
	}
	else
	{
		// normally the array is sorted
		for( sal_Int32 i = 0; i < nElements; i++ )
		{
			if( pProperties[i].Handle == nHandle )
			{
				if( pPropName )
					*pPropName = pProperties[ i ].Name;
				if( pAttributes )
					*pAttributes = pProperties[ i ].Attributes;
				return sal_True;
			}
		}
	}
	return sal_False;
}

//========================================================================
Sequence< Property > OPropertyArrayHelper::getProperties(void)
{
	/*if( aInfos.getLength() != nElements )
	{
		((OPropertyArrayHelper *)this)->aInfos.realloc( nElements );
		Property * pProps = ((OPropertyArrayHelper *)this)->aInfos.getArray();
		for( sal_Int32 i = 0; i < nElements; i++ )
		{
			pProps[i].Name = pProperties[i].Name;
			pProps[i].Handle = pProperties[i].Handle;
			pProps[i].Type = pProperties[i].Type;
			pProps[i].Attributes = pProperties[i].Attributes;
		}
	}*/
	return aInfos;
}

//========================================================================
Property OPropertyArrayHelper::getPropertyByName(const OUString& aPropertyName)
		throw (UnknownPropertyException)
{
	Property * pR;
	pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(),
                              sizeof( Property ),
							  compare_OUString_Property_Impl );
	if( !pR ) {
		throw UnknownPropertyException();
	}

	/*Property aProp;
	aProp.Name = pR->Name;
	aProp.Handle = pR->Handle;
	aProp.Type = pR->Type;
	aProp.Attributes = pR->Attributes;
	return aProp;*/
	return *pR;
}

//========================================================================
sal_Bool OPropertyArrayHelper::hasPropertyByName(const OUString& aPropertyName)
{
	Property * pR;
	pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(),
                              sizeof( Property ),
							  compare_OUString_Property_Impl );
	return pR != NULL;
}

//========================================================================
sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName )
{
	Property * pR;
	pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(),
                              sizeof( Property ),
							  compare_OUString_Property_Impl );
	return pR ? pR->Handle : -1;
}

//========================================================================
sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames )
{
	sal_Int32 nHitCount = 0;
	const OUString * pReqProps = rPropNames.getConstArray();
	sal_Int32 nReqLen = rPropNames.getLength();
	const Property * pCur = aInfos.getConstArray();
	const Property * pEnd = pCur + aInfos.getLength();

	for( sal_Int32 i = 0; i < nReqLen; i++ )
	{
		// Logarithmus ermitteln
		sal_Int32 n = (sal_Int32)(pEnd - pCur);
		sal_Int32 nLog = 0;
		while( n )
		{
			nLog += 1;
			n = n >> 1;
		}

		// Anzahl der noch zu suchenden Properties * dem Log2 der verbleibenden
		// zu dursuchenden Properties.
		if( (nReqLen - i) * nLog >= pEnd - pCur )
		{
			// linear search is better
			while( pCur < pEnd && pReqProps[i] > pCur->Name )
			{
				pCur++;
			}
			if( pCur < pEnd && pReqProps[i] == pCur->Name )
			{
				pHandles[i] = pCur->Handle;
				nHitCount++;
			}
			else
				pHandles[i] = -1;
		}
		else
		{
			// binary search is better
			sal_Int32	nCompVal = 1;
			const Property * pOldEnd = pEnd--;
			const Property * pMid = pCur;

			while( nCompVal != 0 && pCur <= pEnd )
			{
				pMid = (pEnd - pCur) / 2 + pCur;

				nCompVal = pReqProps[i].compareTo( pMid->Name );

				if( nCompVal > 0 )
					pCur = pMid + 1;
				else
					pEnd = pMid - 1;
			}

			if( nCompVal == 0 )
			{
				pHandles[i] = pMid->Handle;
				nHitCount++;
				pCur = pMid +1;
			}
			else if( nCompVal > 0 )
			{
				pHandles[i] = -1;
				pCur = pMid +1;
			}
			else
			{
				pHandles[i] = -1;
				pCur = pMid;
			}
			pEnd = pOldEnd;
		}
	}
	return nHitCount;
}

} // end namespace cppu
