/**************************************************************
 * 
 * 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_comphelper.hxx"
#include "comphelper/accessiblewrapper.hxx"
#include <com/sun/star/reflection/XProxyFactory.hpp>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>

#include <algorithm>

using namespace	::comphelper;
using namespace	::com::sun::star::accessibility;
using namespace	::com::sun::star::uno;
using namespace	::com::sun::star::lang;

//.............................................................................
namespace comphelper
{
//.............................................................................

	//=========================================================================
	//= OWrappedAccessibleChildrenManager
	//=========================================================================
	//--------------------------------------------------------------------
	struct RemoveEventListener
			: public ::std::unary_function< AccessibleMap::value_type, void >
	{
	private:
		Reference< XEventListener >	m_xListener;

	public:
		RemoveEventListener( const Reference< XEventListener >& _rxListener )
			:m_xListener( _rxListener  )
		{
		}

		void operator()( const AccessibleMap::value_type& _rMapEntry ) const
		{
			Reference< XComponent > xComp( _rMapEntry.first, UNO_QUERY );
			if ( xComp.is() )
				xComp->removeEventListener( m_xListener );
		}
	};

	//--------------------------------------------------------------------
	struct DisposeMappedChild
			: public ::std::unary_function< AccessibleMap::value_type, void >
	{
		void operator()( const AccessibleMap::value_type& _rMapEntry ) const
		{
            Reference< XComponent > xContextComponent;
            if ( _rMapEntry.second.is() )
                xContextComponent = xContextComponent.query( _rMapEntry.second->getAccessibleContext() );
			if ( xContextComponent.is() )
				xContextComponent->dispose();
		}
	};

	//-------------------------------------------------------------------------
	OWrappedAccessibleChildrenManager::OWrappedAccessibleChildrenManager( const Reference< XMultiServiceFactory >& _rxORB )
		:m_xORB( _rxORB )
		,m_bTransientChildren( sal_True )
	{
	}

	//-------------------------------------------------------------------------
	OWrappedAccessibleChildrenManager::~OWrappedAccessibleChildrenManager( )
	{
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::setTransientChildren( sal_Bool _bSet )
	{
		m_bTransientChildren = _bSet;
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::setOwningAccessible( const Reference< XAccessible >& _rxAcc )
	{
		OSL_ENSURE( !m_aOwningAccessible.get().is(), "OWrappedAccessibleChildrenManager::setOwningAccessible: to be called only once!" );
		m_aOwningAccessible = WeakReference< XAccessible >( _rxAcc );
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::removeFromCache( const Reference< XAccessible >& _rxKey )
	{
		AccessibleMap::iterator aRemovedPos = m_aChildrenMap.find( _rxKey );
		if ( m_aChildrenMap.end() != aRemovedPos )
		{	// it was cached
			// remove ourself as event listener
			RemoveEventListener aOperator( this );
			aOperator( *aRemovedPos );
			// and remove the entry from the map
			m_aChildrenMap.erase( aRemovedPos );
		}
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::invalidateAll( )
	{
		// remove as event listener from the map elements
		::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) );
		// clear the map
		AccessibleMap aMap;
		m_aChildrenMap.swap( aMap );
	}

	//-------------------------------------------------------------------------
	Reference< XAccessible > OWrappedAccessibleChildrenManager::getAccessibleWrapperFor(
		const Reference< XAccessible >& _rxKey,	sal_Bool _bCreate )
	{
		Reference< XAccessible > xValue;

		if( !_rxKey.is() )
		{
			// fprintf( stderr, "It was this path that was crashing stuff\n" );
			return xValue;
		}

		// do we have this child in the cahce?
		AccessibleMap::const_iterator aPos = m_aChildrenMap.find( _rxKey );
		if ( m_aChildrenMap.end() != aPos )
		{
			xValue = aPos->second;
		}
		else if ( _bCreate )
		{	// not found in the cache, and allowed to create
			// -> new wrapper
			xValue = new OAccessibleWrapper( m_xORB, _rxKey, (Reference< XAccessible >)m_aOwningAccessible );

			// see if we do cache children
			if ( !m_bTransientChildren )
			{
				if (!m_aChildrenMap.insert(
                        AccessibleMap::value_type( _rxKey, xValue ) ).second)
                {
                    OSL_ENSURE(
                        false,
                        "OWrappedAccessibleChildrenManager::"
                            "getAccessibleWrapperFor: element was already"
                            " inserted!" );
                }

				// listen for disposals of inner children - this may happen when the inner context
				// is the owner for the inner children (it will dispose these children, and of course
				// not our wrapper for these children)
				Reference< XComponent > xComp( _rxKey, UNO_QUERY );
				if ( xComp.is() )
					xComp->addEventListener( this );
			}
		}

		return xValue;
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::dispose()
	{
		// dispose our children
		::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), RemoveEventListener( this ) );
		::std::for_each( m_aChildrenMap.begin(), m_aChildrenMap.end(), DisposeMappedChild( ) );
		// clear our children
		AccessibleMap aMap;
		m_aChildrenMap.swap( aMap );
	}

	//--------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::implTranslateChildEventValue( const Any& _rInValue, Any& _rOutValue )
	{
		_rOutValue.clear();
		Reference< XAccessible > xChild;
		if ( _rInValue >>= xChild )
			_rOutValue <<= getAccessibleWrapperFor( xChild, sal_True );
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::translateAccessibleEvent( const AccessibleEventObject& _rEvent, AccessibleEventObject& _rTranslatedEvent )
	{
		// just in case we can't translate some of the values:
		_rTranslatedEvent.NewValue = _rEvent.NewValue;
		_rTranslatedEvent.OldValue = _rEvent.OldValue;

		switch ( _rEvent.EventId )
		{
			case AccessibleEventId::CHILD:
			case AccessibleEventId::ACTIVE_DESCENDANT_CHANGED:
			case AccessibleEventId::CONTROLLED_BY_RELATION_CHANGED:
			case AccessibleEventId::CONTROLLER_FOR_RELATION_CHANGED:
			case AccessibleEventId::LABEL_FOR_RELATION_CHANGED:
			case AccessibleEventId::LABELED_BY_RELATION_CHANGED:
			case AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED:
			case AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED:
				// these are events where both the old and the new value contain child references
				implTranslateChildEventValue( _rEvent.OldValue, _rTranslatedEvent.OldValue );
				implTranslateChildEventValue( _rEvent.NewValue, _rTranslatedEvent.NewValue );
				break;

            case AccessibleEventId::NAME_CHANGED:
            case AccessibleEventId::DESCRIPTION_CHANGED:
            case AccessibleEventId::ACTION_CHANGED:
            case AccessibleEventId::STATE_CHANGED:
            case AccessibleEventId::BOUNDRECT_CHANGED:
            case AccessibleEventId::INVALIDATE_ALL_CHILDREN:
            case AccessibleEventId::SELECTION_CHANGED:
            case AccessibleEventId::VISIBLE_DATA_CHANGED:
            case AccessibleEventId::VALUE_CHANGED:
            case AccessibleEventId::MEMBER_OF_RELATION_CHANGED:
            case AccessibleEventId::CARET_CHANGED:
            case AccessibleEventId::TEXT_CHANGED:
            case AccessibleEventId::HYPERTEXT_CHANGED:
            case AccessibleEventId::TABLE_CAPTION_CHANGED:
			case AccessibleEventId::TABLE_COLUMN_DESCRIPTION_CHANGED:
			case AccessibleEventId::TABLE_COLUMN_HEADER_CHANGED:
			case AccessibleEventId::TABLE_MODEL_CHANGED:
			case AccessibleEventId::TABLE_ROW_DESCRIPTION_CHANGED:
			case AccessibleEventId::TABLE_ROW_HEADER_CHANGED:
			case AccessibleEventId::TABLE_SUMMARY_CHANGED:
            // --> PB 2006-03-21 #130798# EventId TEXT_SELECTION_CHANGED was missed
            // these Ids are also missed: SUB_WINDOW_OF_RELATION_CHANGED & TEXT_ATTRIBUTE_CHANGED
            case AccessibleEventId::TEXT_SELECTION_CHANGED:
            // <--
                // nothing to translate
				break;

			default:
				OSL_ENSURE( sal_False, "OWrappedAccessibleChildrenManager::translateAccessibleEvent: unknown (or unexpected) event id!" );
				break;
		}
	}

	//-------------------------------------------------------------------------
	void OWrappedAccessibleChildrenManager::handleChildNotification( const AccessibleEventObject& _rEvent )
	{
		if ( AccessibleEventId::INVALIDATE_ALL_CHILDREN == _rEvent.EventId )
		{	// clear our child map
			invalidateAll( );
		}
		else if ( AccessibleEventId::CHILD == _rEvent.EventId )
		{
			// check if the removed or replaced element is cached
			Reference< XAccessible > xRemoved;
			if ( _rEvent.OldValue >>= xRemoved )
				removeFromCache( xRemoved );
		}
	}

	//--------------------------------------------------------------------
	void SAL_CALL OWrappedAccessibleChildrenManager::disposing( const EventObject& _rSource ) throw (RuntimeException)
	{
		// this should come from one of the inner XAccessible's of our children
		Reference< XAccessible > xSource( _rSource.Source, UNO_QUERY );
		AccessibleMap::iterator aDisposedPos = m_aChildrenMap.find( xSource );
#if OSL_DEBUG_LEVEL > 0
        if ( m_aChildrenMap.end() == aDisposedPos )
        {
       		OSL_ENSURE( sal_False,
	    		"OWrappedAccessibleChildrenManager::disposing: where did this come from?" );
            // helper for dignostics
            Reference< XAccessible > xOwningAccessible( m_aOwningAccessible );
            Reference< XAccessibleContext > xContext;
            try
            {
                if ( xOwningAccessible.is() )
                    xContext = xOwningAccessible->getAccessibleContext();
                if ( xContext.is() )
                {
                    ::rtl::OUString sName = xContext->getAccessibleName();
                    ::rtl::OUString sDescription = xContext->getAccessibleDescription();
//                  sal_Int32 nPlaceYourBreakpointHere = 0;
                }
            }
            catch( const Exception& /*e*/ )
            {
                // silent this, it's only diagnostics which failed
            }
        }
#endif
		if ( m_aChildrenMap.end() != aDisposedPos )
		{
			m_aChildrenMap.erase( aDisposedPos );
		}
	}

	//=========================================================================
	//= OAccessibleWrapper (implementation)
	//=========================================================================
	//-------------------------------------------------------------------------
	OAccessibleWrapper::OAccessibleWrapper( const Reference< XMultiServiceFactory >& _rxORB,
			const Reference< XAccessible >& _rxInnerAccessible, const Reference< XAccessible >& _rxParentAccessible )
		:OAccessibleWrapper_Base( )
		,OComponentProxyAggregation( _rxORB, Reference< XComponent >( _rxInnerAccessible, UNO_QUERY ) )
		,m_xParentAccessible( _rxParentAccessible )
		,m_xInnerAccessible( _rxInnerAccessible )
	{
	}

	//--------------------------------------------------------------------
	OAccessibleWrapper::~OAccessibleWrapper( )
	{
		if ( !m_rBHelper.bDisposed )
		{
			acquire();	// to prevent duplicate dtor calls
			dispose();
		}
	}

	//--------------------------------------------------------------------
	IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleWrapper, OComponentProxyAggregation, OAccessibleWrapper_Base )
    IMPLEMENT_FORWARD_REFCOUNT( OAccessibleWrapper, OComponentProxyAggregation )

	//--------------------------------------------------------------------
	Any OAccessibleWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
	{
        // #111089# instead of the inner XAccessible the proxy XAccessible must be returned
		Any aReturn = OAccessibleWrapper_Base::queryInterface( _rType );
		if ( !aReturn.hasValue() )
			aReturn = OComponentProxyAggregation::queryInterface( _rType );

		return aReturn;
	}

	//--------------------------------------------------------------------
	Reference< XAccessibleContext > OAccessibleWrapper::getContextNoCreate( ) const
	{
		return (Reference< XAccessibleContext >)m_aContext;
	}

	//--------------------------------------------------------------------
	OAccessibleContextWrapper* OAccessibleWrapper::createAccessibleContext( const Reference< XAccessibleContext >& _rxInnerContext )
	{
		return new OAccessibleContextWrapper( getORB(), _rxInnerContext, this, m_xParentAccessible );
	}

	//--------------------------------------------------------------------
	Reference< XAccessibleContext > SAL_CALL OAccessibleWrapper::getAccessibleContext(  ) throw (RuntimeException)
	{
		// see if the context is still alive (we cache it)
		Reference< XAccessibleContext > xContext = (Reference< XAccessibleContext >)m_aContext;
		if ( !xContext.is() )
		{
			// create a new context
			Reference< XAccessibleContext > xInnerContext = m_xInnerAccessible->getAccessibleContext( );
			if ( xInnerContext.is() )
			{
				xContext = createAccessibleContext( xInnerContext );
				// cache it
				m_aContext = WeakReference< XAccessibleContext >( xContext );
			}
		}

		return xContext;
	}

	//=========================================================================
	//= OAccessibleWrapper (implementation)
	//=========================================================================
	//-------------------------------------------------------------------------
	OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper(
				const Reference< XMultiServiceFactory >& _rxORB,
				::cppu::OBroadcastHelper& _rBHelper,
				const Reference< XAccessibleContext >& _rxInnerAccessibleContext,
				const Reference< XAccessible >& _rxOwningAccessible,
				const Reference< XAccessible >& _rxParentAccessible )
		:OComponentProxyAggregationHelper( _rxORB, _rBHelper )
		,m_xInnerContext( _rxInnerAccessibleContext )
		,m_xOwningAccessible( _rxOwningAccessible )
		,m_xParentAccessible( _rxParentAccessible )
		,m_pChildMapper( NULL )
	{
		// initialize the mapper for our children
		m_pChildMapper = new OWrappedAccessibleChildrenManager( getORB() );
		m_pChildMapper->acquire();

		// determine if we're allowed to cache children
		Reference< XAccessibleStateSet > xStates( m_xInnerContext->getAccessibleStateSet( ) );
		OSL_ENSURE( xStates.is(), "OAccessibleContextWrapperHelper::OAccessibleContextWrapperHelper: no inner state set!" );
		m_pChildMapper->setTransientChildren( !xStates.is() || xStates->contains( AccessibleStateType::MANAGES_DESCENDANTS) );

		m_pChildMapper->setOwningAccessible( m_xOwningAccessible );
	}

	//--------------------------------------------------------------------
	void OAccessibleContextWrapperHelper::aggregateProxy( oslInterlockedCount& _rRefCount, ::cppu::OWeakObject& _rDelegator )
	{
		Reference< XComponent > xInnerComponent( m_xInnerContext, UNO_QUERY );
		OSL_ENSURE( xInnerComponent.is(), "OComponentProxyAggregation::aggregateProxy: accessible is no XComponent!" );
        if ( xInnerComponent.is() )
		    componentAggregateProxyFor( xInnerComponent, _rRefCount, _rDelegator );

		// add as event listener to the inner context, because we want to multiplex the AccessibleEvents
		osl_incrementInterlockedCount( &_rRefCount );
		{
			Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
			if ( xBroadcaster.is() )
				xBroadcaster->addEventListener( this );
		}
		osl_decrementInterlockedCount( &_rRefCount );
	}

	//--------------------------------------------------------------------
	OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper( )
	{
		OSL_ENSURE( m_rBHelper.bDisposed, "OAccessibleContextWrapperHelper::~OAccessibleContextWrapperHelper: you should ensure (in your dtor) that the object is disposed!" );

		m_pChildMapper->release();
		m_pChildMapper = NULL;
	}

	//--------------------------------------------------------------------
	Any SAL_CALL OAccessibleContextWrapperHelper::queryInterface( const Type& _rType ) throw (RuntimeException)
	{
		Any aReturn = OComponentProxyAggregationHelper::queryInterface( _rType );
		if ( !aReturn.hasValue() )
			aReturn = OAccessibleContextWrapperHelper_Base::queryInterface( _rType );
		return aReturn;
	}

	//--------------------------------------------------------------------
	IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapperHelper, OComponentProxyAggregationHelper, OAccessibleContextWrapperHelper_Base )

	//--------------------------------------------------------------------
	sal_Int32 SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChildCount(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleChildCount();
	}

	//--------------------------------------------------------------------
	Reference< XAccessible > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
	{
		// get the child of the wrapped component
		Reference< XAccessible > xInnerChild = m_xInnerContext->getAccessibleChild( i );
		return m_pChildMapper->getAccessibleWrapperFor( xInnerChild );
	}

	//--------------------------------------------------------------------
	Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapperHelper::getAccessibleRelationSet(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleRelationSet();
			// TODO: if this relation set would contain relations to siblings, we would normally need
			// to wrap them, too ....
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapperHelper::notifyEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException)
	{
#if OSL_DEBUG_LEVEL > 0
		if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId )
		{
			sal_Bool bChildTransienceChanged = sal_False;
			sal_Int16 nChangeState = 0;
			if ( _rEvent.OldValue >>= nChangeState )
				bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState;
			if ( _rEvent.NewValue >>= nChangeState )
				bChildTransienceChanged = bChildTransienceChanged || AccessibleStateType::MANAGES_DESCENDANTS == nChangeState;
			OSL_ENSURE( !bChildTransienceChanged, "OAccessibleContextWrapperHelper::notifyEvent: MANAGES_DESCENDANTS is not expected to change during runtime!" );
				// if this asserts, then we would need to update our m_bTransientChildren flag here,
				// as well as (potentially) our child cache
		}
#endif
		AccessibleEventObject aTranslatedEvent( _rEvent );

		{
			::osl::MutexGuard aGuard( m_rBHelper.rMutex );

            // translate the event
			queryInterface( ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ) ) >>= aTranslatedEvent.Source;
			m_pChildMapper->translateAccessibleEvent( _rEvent, aTranslatedEvent );

            // see if any of these notifications affect our child manager
			m_pChildMapper->handleChildNotification( _rEvent );

            if ( aTranslatedEvent.NewValue == m_xInner )
				aTranslatedEvent.NewValue = makeAny(aTranslatedEvent.Source);
			if ( aTranslatedEvent.OldValue == m_xInner )
				aTranslatedEvent.OldValue = makeAny(aTranslatedEvent.Source);
		}

		notifyTranslatedEvent( aTranslatedEvent );
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapperHelper::dispose() throw( RuntimeException )
	{
		::osl::MutexGuard aGuard( m_rBHelper.rMutex );

		// stop multiplexing events
		Reference< XAccessibleEventBroadcaster > xBroadcaster( m_xInner, UNO_QUERY );
		OSL_ENSURE( xBroadcaster.is(), "OAccessibleContextWrapperHelper::disposing(): inner context is no broadcaster!" );
		if ( xBroadcaster.is() )
			xBroadcaster->removeEventListener( this );

		// dispose the child cache/map
		m_pChildMapper->dispose();

		// let the base class dispose the inner component
		OComponentProxyAggregationHelper::dispose();
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapperHelper::disposing( const EventObject& _rEvent )  throw (RuntimeException)
	{
		// simply disambiguate this
		OComponentProxyAggregationHelper::disposing( _rEvent );
	}

	//====================================================================
	//= OAccessibleContextWrapper
	//====================================================================
	//--------------------------------------------------------------------
	IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )

	//--------------------------------------------------------------------
	IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleContextWrapper, OAccessibleContextWrapper_CBase, OAccessibleContextWrapperHelper )

	//--------------------------------------------------------------------
	OAccessibleContextWrapper::OAccessibleContextWrapper( const Reference< XMultiServiceFactory >& _rxORB,
			const Reference< XAccessibleContext >& _rxInnerAccessibleContext, const Reference< XAccessible >& _rxOwningAccessible,
			const Reference< XAccessible >& _rxParentAccessible )
		:OAccessibleContextWrapper_CBase( m_aMutex )
		,OAccessibleContextWrapperHelper( _rxORB, rBHelper, _rxInnerAccessibleContext, _rxOwningAccessible, _rxParentAccessible )
		,m_nNotifierClient( 0 )
	{
		aggregateProxy( m_refCount, *this );
	}

	//--------------------------------------------------------------------
	OAccessibleContextWrapper::~OAccessibleContextWrapper()
	{
	}

	//--------------------------------------------------------------------
	sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleChildCount(  ) throw (RuntimeException)
	{
		return OAccessibleContextWrapperHelper::getAccessibleChildCount();
	}

	//--------------------------------------------------------------------
	Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
	{
		return OAccessibleContextWrapperHelper::getAccessibleChild( i );
	}

	//--------------------------------------------------------------------
	Reference< XAccessible > SAL_CALL OAccessibleContextWrapper::getAccessibleParent(  ) throw (RuntimeException)
	{
		return m_xParentAccessible;
	}

	//--------------------------------------------------------------------
	sal_Int32 SAL_CALL OAccessibleContextWrapper::getAccessibleIndexInParent(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleIndexInParent();
	}

	//--------------------------------------------------------------------
	sal_Int16 SAL_CALL OAccessibleContextWrapper::getAccessibleRole(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleRole();
	}

	//--------------------------------------------------------------------
	::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleDescription(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleDescription();
	}

	//--------------------------------------------------------------------
	::rtl::OUString SAL_CALL OAccessibleContextWrapper::getAccessibleName(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleName();
	}

	//--------------------------------------------------------------------
	Reference< XAccessibleRelationSet > SAL_CALL OAccessibleContextWrapper::getAccessibleRelationSet(  ) throw (RuntimeException)
	{
		return OAccessibleContextWrapperHelper::getAccessibleRelationSet();
	}

	//--------------------------------------------------------------------
	Reference< XAccessibleStateSet > SAL_CALL OAccessibleContextWrapper::getAccessibleStateSet(  ) throw (RuntimeException)
	{
		return m_xInnerContext->getAccessibleStateSet();
	}

	//--------------------------------------------------------------------
	Locale SAL_CALL OAccessibleContextWrapper::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
	{
		return m_xInnerContext->getLocale();
	}

	//--------------------------------------------------------------------
	void OAccessibleContextWrapper::notifyTranslatedEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException)
	{
		if ( m_nNotifierClient )
			AccessibleEventNotifier::addEvent( m_nNotifierClient, _rEvent );
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapper::addEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException)
	{
		::osl::MutexGuard aGuard( m_aMutex );
		if ( !m_nNotifierClient )
			m_nNotifierClient = AccessibleEventNotifier::registerClient( );
		AccessibleEventNotifier::addEventListener( m_nNotifierClient, _rxListener );
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapper::removeEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException)
	{
		::osl::MutexGuard aGuard( m_aMutex );
		if ( m_nNotifierClient )
		{
			if ( 0 == AccessibleEventNotifier::removeEventListener( m_nNotifierClient, _rxListener ) )
			{
				AccessibleEventNotifier::TClientId nId( m_nNotifierClient );
				m_nNotifierClient = 0;
				AccessibleEventNotifier::revokeClient( nId );
			}
		}
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapper::disposing()  throw (RuntimeException)
	{
		AccessibleEventNotifier::TClientId nClientId( 0 );

		// --- <mutex lock> -----------------------------------------
		{
			::osl::MutexGuard aGuard( m_aMutex );

			// prepare notifying our AccessibleListeners
			if ( m_nNotifierClient )
			{
				nClientId = m_nNotifierClient;
				m_nNotifierClient = 0;
			}
		}
		// --- </mutex lock> -----------------------------------------

		// let the base class do
		OAccessibleContextWrapperHelper::dispose();

		// notify the disposal
		if ( nClientId )
			AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
	}

	//--------------------------------------------------------------------
	void SAL_CALL OAccessibleContextWrapper::dispose() throw( RuntimeException )
	{
		// simply disambiguate
		OComponentProxyAggregation_CBase::dispose();
	}

//.............................................................................
}	// namespace accessibility
//.............................................................................
