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

#include <cachedcontentresultset.hxx>
#include <com/sun/star/sdbc/FetchDirection.hpp>
#include <com/sun/star/ucb/FetchError.hpp>
#include <com/sun/star/ucb/ResultSetException.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <rtl/ustring.hxx>
#include <osl/diagnose.h>

using namespace com::sun::star::beans;
using namespace com::sun::star::lang;
using namespace com::sun::star::script;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;
using namespace com::sun::star::util;
using namespace cppu;
using namespace rtl;

#define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
#define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//define for getXXX methods of interface XRow
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

//if you change this macro please pay attention to
//function ::getObject, where this is similar implemented

#define XROW_GETXXX( getXXX, Type )						\
impl_EnsureNotDisposed();								\
ReacquireableGuard aGuard( m_aMutex );					\
sal_Int32 nRow = m_nRow;								\
sal_Int32 nFetchSize = m_nFetchSize;					\
sal_Int32 nFetchDirection = m_nFetchDirection;			\
if( !m_aCache.hasRow( nRow ) )							\
{														\
	if( !m_aCache.hasCausedException( nRow ) )			\
{														\
		if( !m_xFetchProvider.is() )					\
		{												\
			OSL_ENSURE( sal_False, "broadcaster was disposed already" );	\
			throw SQLException();						\
		}												\
		aGuard.clear();									\
		if( impl_isForwardOnly() )						\
			applyPositionToOrigin( nRow );				\
														\
		impl_fetchData( nRow, nFetchSize, nFetchDirection ); \
	}													\
	aGuard.reacquire();									\
	if( !m_aCache.hasRow( nRow ) )						\
	{													\
		m_bLastReadWasFromCache = sal_False;			\
		aGuard.clear();									\
		applyPositionToOrigin( nRow );					\
		impl_init_xRowOrigin();							\
		return m_xRowOrigin->getXXX( columnIndex );		\
	}													\
}														\
const Any& rValue = m_aCache.getAny( nRow, columnIndex );\
Type aRet = Type();                                     \
m_bLastReadWasFromCache = sal_True;						\
m_bLastCachedReadWasNull = !( rValue >>= aRet );		\
/* Last chance. Try type converter service... */        \
if ( m_bLastCachedReadWasNull && rValue.hasValue() )    \
{                                                       \
    Reference< XTypeConverter > xConverter              \
                                = getTypeConverter();   \
    if ( xConverter.is() )                              \
    {                                                   \
        try                                             \
        {                                               \
            Any aConvAny = xConverter->convertTo(       \
                rValue,                                 \
                getCppuType( static_cast<               \
                    const Type * >( 0 ) ) );            \
            m_bLastCachedReadWasNull = !( aConvAny >>= aRet ); \
        }                                               \
        catch ( IllegalArgumentException )              \
        {                                               \
        }                                               \
        catch ( CannotConvertException )                \
        {                                               \
        }                                               \
    }                                                   \
}                                                       \
return aRet;

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// CCRS_Cache methoeds.
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

CachedContentResultSet::CCRS_Cache::CCRS_Cache(
	const Reference< XContentIdentifierMapping > & xMapping )
	: m_pResult( NULL )
	, m_xContentIdentifierMapping( xMapping )
	, m_pMappedReminder( NULL )
{
}

CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
{
	delete m_pResult;
}

void SAL_CALL CachedContentResultSet::CCRS_Cache
	::clear()
{
	if( m_pResult )
	{
		delete m_pResult;
		m_pResult = NULL;
	}
	clearMappedReminder();
}

void SAL_CALL CachedContentResultSet::CCRS_Cache
	::loadData( const FetchResult& rResult )
{
	clear();
	m_pResult = new FetchResult( rResult );
}

sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
	::hasRow( sal_Int32 row )
{
	if( !m_pResult )
		return sal_False;
	long nStart = m_pResult->StartIndex;
	long nEnd = nStart;
	if( m_pResult->Orientation )
		nEnd += m_pResult->Rows.getLength() - 1;
	else
		nStart -= m_pResult->Rows.getLength() + 1;

	return nStart <= row && row <= nEnd;
}

sal_Int32 SAL_CALL CachedContentResultSet::CCRS_Cache
	::getMaxRow()
{
	if( !m_pResult )
		return 0;
	long nEnd = m_pResult->StartIndex;
	if( m_pResult->Orientation )
		return nEnd += m_pResult->Rows.getLength() - 1;
	else
		return nEnd;
}

sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
	::hasKnownLast()
{
	if( !m_pResult )
		return sal_False;

	if( ( m_pResult->FetchError & FetchError::ENDOFDATA )
		&& m_pResult->Orientation
		&& m_pResult->Rows.getLength() )
		return sal_True;

	return sal_False;
}

sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
	::hasCausedException( sal_Int32 nRow )
{
	if( !m_pResult )
		return sal_False;
	if( !( m_pResult->FetchError & FetchError::EXCEPTION ) )
		return sal_False;

	long nEnd = m_pResult->StartIndex;
	if( m_pResult->Orientation )
		nEnd += m_pResult->Rows.getLength();

	return nRow == nEnd+1;
}

Any& SAL_CALL CachedContentResultSet::CCRS_Cache
	::getRowAny( sal_Int32 nRow )
	throw( SQLException,
	RuntimeException )
{
	if( !nRow )
		throw SQLException();
	if( !m_pResult )
		throw SQLException();
	if( !hasRow( nRow ) )
		throw SQLException();

	long nDiff = nRow - m_pResult->StartIndex;
	if( nDiff < 0 )
		nDiff *= -1;

	return (m_pResult->Rows)[nDiff];
}

void SAL_CALL CachedContentResultSet::CCRS_Cache
	::remindMapped( sal_Int32 nRow )
{
	//remind that this row was mapped
	if( !m_pResult )
		return;
	long nDiff = nRow - m_pResult->StartIndex;
	if( nDiff < 0 )
		nDiff *= -1;
	Sequence< sal_Bool >* pMappedReminder = getMappedReminder();
	if( nDiff < pMappedReminder->getLength() )
		(*pMappedReminder)[nDiff] = sal_True;
}

sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
	::isRowMapped( sal_Int32 nRow )
{
	if( !m_pMappedReminder || !m_pResult )
		return sal_False;
	long nDiff = nRow - m_pResult->StartIndex;
	if( nDiff < 0 )
		nDiff *= -1;
	if( nDiff < m_pMappedReminder->getLength() )
		return (*m_pMappedReminder)[nDiff];
	return sal_False;
}

void SAL_CALL CachedContentResultSet::CCRS_Cache
	::clearMappedReminder()
{
	delete m_pMappedReminder;
	m_pMappedReminder = NULL;
}

Sequence< sal_Bool >* SAL_CALL CachedContentResultSet::CCRS_Cache
	::getMappedReminder()
{
	if( !m_pMappedReminder )
	{
		sal_Int32 nCount = m_pResult->Rows.getLength();
		m_pMappedReminder = new Sequence< sal_Bool >( nCount );
		for( ;nCount; nCount-- )
			(*m_pMappedReminder)[nCount] = sal_False;
	}
	return m_pMappedReminder;
}

const Any& SAL_CALL CachedContentResultSet::CCRS_Cache
	::getAny( sal_Int32 nRow, sal_Int32 nColumnIndex )
	throw( SQLException,
	RuntimeException )
{
	if( !nColumnIndex )
		throw SQLException();
	if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
	{
		Any& rRow = getRowAny( nRow );
		Sequence< Any > aValue;
		rRow >>= aValue;
		if( m_xContentIdentifierMapping->mapRow( aValue ) )
		{
			rRow <<= aValue;
			remindMapped( nRow );
		}
		else
			m_xContentIdentifierMapping.clear();
	}
	const Sequence< Any >& rRow =
		(* reinterpret_cast< const Sequence< Any > * >
		(getRowAny( nRow ).getValue() ));

	if( nColumnIndex > rRow.getLength() )
		throw SQLException();
	return rRow[nColumnIndex-1];
}

const rtl::OUString& SAL_CALL CachedContentResultSet::CCRS_Cache
	::getContentIdentifierString( sal_Int32 nRow )
	throw( com::sun::star::uno::RuntimeException )
{
	try
	{
		if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
		{
			Any& rRow = getRowAny( nRow );
			rtl::OUString aValue;
			rRow >>= aValue;
			rRow <<= m_xContentIdentifierMapping->mapContentIdentifierString( aValue );
			remindMapped( nRow );
		}
		return (* reinterpret_cast< const rtl::OUString * >
				(getRowAny( nRow ).getValue() ));
	}
	catch( SQLException )
	{
		throw RuntimeException();
	}
}

const Reference< XContentIdentifier >& SAL_CALL CachedContentResultSet::CCRS_Cache
	::getContentIdentifier( sal_Int32 nRow )
	throw( com::sun::star::uno::RuntimeException )
{
	try
	{
		if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
		{
			Any& rRow = getRowAny( nRow );
			Reference< XContentIdentifier > aValue;
			rRow >>= aValue;
			rRow <<= m_xContentIdentifierMapping->mapContentIdentifier( aValue );
			remindMapped( nRow );
		}
		return (* reinterpret_cast< const Reference< XContentIdentifier > * >
				(getRowAny( nRow ).getValue() ));
	}
	catch( SQLException )
	{
		throw RuntimeException();
	}
}

const Reference< XContent >& SAL_CALL CachedContentResultSet::CCRS_Cache
	::getContent( sal_Int32 nRow )
	throw( com::sun::star::uno::RuntimeException )
{
	try
	{
		if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
		{
			Any& rRow = getRowAny( nRow );
			Reference< XContent > aValue;
			rRow >>= aValue;
			rRow <<= m_xContentIdentifierMapping->mapContent( aValue );
			remindMapped( nRow );
		}
		return (* reinterpret_cast< const Reference< XContent > * >
				(getRowAny( nRow ).getValue() ));
	}
	catch( SQLException )
	{
		throw RuntimeException();
	}
}

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// class CCRS_PropertySetInfo
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

class CCRS_PropertySetInfo :
				public cppu::OWeakObject,
				public com::sun::star::lang::XTypeProvider,
				public com::sun::star::beans::XPropertySetInfo
{
    friend class CachedContentResultSet;

	//my Properties
	Sequence< com::sun::star::beans::Property >*
							m_pProperties;

	//some helping variables ( names for my special properties )
	static rtl::OUString	m_aPropertyNameForCount;
	static rtl::OUString	m_aPropertyNameForFinalCount;
	static rtl::OUString	m_aPropertyNameForFetchSize;
	static rtl::OUString	m_aPropertyNameForFetchDirection;

	long					m_nFetchSizePropertyHandle;
	long					m_nFetchDirectionPropertyHandle;

private:
	sal_Int32 SAL_CALL
	impl_getRemainedHandle() const;

    sal_Bool SAL_CALL
	impl_queryProperty(
			const rtl::OUString& rName
			, com::sun::star::beans::Property& rProp ) const;
	sal_Int32 SAL_CALL
	impl_getPos( const rtl::OUString& rName ) const;

	static sal_Bool SAL_CALL
	impl_isMyPropertyName( const rtl::OUString& rName );

public:
	CCRS_PropertySetInfo(	Reference<
			XPropertySetInfo > xPropertySetInfoOrigin );

	virtual ~CCRS_PropertySetInfo();

	// XInterface
	XINTERFACE_DECL()

	// XTypeProvider
	XTYPEPROVIDER_DECL()

	// XPropertySetInfo
    virtual Sequence< com::sun::star::beans::Property > SAL_CALL
	getProperties()
		throw( RuntimeException );

    virtual com::sun::star::beans::Property SAL_CALL
	getPropertyByName( const rtl::OUString& aName )
		throw( com::sun::star::beans::UnknownPropertyException, RuntimeException );

    virtual sal_Bool SAL_CALL
	hasPropertyByName( const rtl::OUString& Name )
		throw( RuntimeException );
};

OUString	CCRS_PropertySetInfo::m_aPropertyNameForCount( OUString::createFromAscii( "RowCount" ) );
OUString	CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( OUString::createFromAscii( "IsRowCountFinal" ) );
OUString	CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) );
OUString	CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) );

CCRS_PropertySetInfo::CCRS_PropertySetInfo(
		Reference< XPropertySetInfo > xInfo )
		: m_pProperties( NULL )
		, m_nFetchSizePropertyHandle( -1 )
		, m_nFetchDirectionPropertyHandle( -1 )
{
	//initialize list of properties:

	// it is required, that the received xInfo contains the two
	// properties with names 'm_aPropertyNameForCount' and
	// 'm_aPropertyNameForFinalCount'

	if( xInfo.is() )
	{
		Sequence<Property> aProps = xInfo->getProperties();
		m_pProperties = new Sequence<Property> ( aProps );
	}
	else
	{
		OSL_ENSURE( sal_False, "The received XPropertySetInfo doesn't contain required properties" );
		m_pProperties = new Sequence<Property>;
	}

	//ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
	sal_Int32 nFetchSize = impl_getPos( m_aPropertyNameForFetchSize );
	sal_Int32 nFetchDirection = impl_getPos( m_aPropertyNameForFetchDirection );
	sal_Int32 nDeleted = 0;
	if( nFetchSize != -1 )
		nDeleted++;
	if( nFetchDirection != -1 )
		nDeleted++;

	Sequence< Property >* pOrigProps = new Sequence<Property> ( *m_pProperties );
	sal_Int32 nOrigProps = pOrigProps->getLength();

	m_pProperties->realloc( nOrigProps + 2 - nDeleted );//note that nDeleted is <= 2
	for( sal_Int32 n = 0, m = 0; n < nOrigProps; n++, m++ )
	{
		if( n == nFetchSize || n == nFetchDirection )
			m--;
		else
			(*m_pProperties)[ m ] = (*pOrigProps)[ n ];
	}
	{
		Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted ];
		rMyProp.Name = m_aPropertyNameForFetchSize;
		rMyProp.Type = getCppuType( static_cast< const sal_Int32 * >( 0 ) );
		rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;

		if( nFetchSize != -1 )
			m_nFetchSizePropertyHandle = (*pOrigProps)[nFetchSize].Handle;
		else
			m_nFetchSizePropertyHandle = impl_getRemainedHandle();

		rMyProp.Handle = m_nFetchSizePropertyHandle;

	}
	{
		Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted + 1 ];
		rMyProp.Name = m_aPropertyNameForFetchDirection;
		rMyProp.Type = getCppuType( static_cast< const sal_Bool * >( 0 ) );
		rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;

		if( nFetchSize != -1 )
			m_nFetchDirectionPropertyHandle = (*pOrigProps)[nFetchDirection].Handle;
		else
			m_nFetchDirectionPropertyHandle = impl_getRemainedHandle();

		m_nFetchDirectionPropertyHandle = rMyProp.Handle;
	}
	delete pOrigProps;
}

CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
{
	delete m_pProperties;
}

//--------------------------------------------------------------------------
// XInterface methods.
//--------------------------------------------------------------------------
//list all interfaces inclusive baseclasses of interfaces
XINTERFACE_IMPL_2( CCRS_PropertySetInfo
				  , XTypeProvider
				  , XPropertySetInfo
				  );

//--------------------------------------------------------------------------
// XTypeProvider methods.
//--------------------------------------------------------------------------
//list all interfaces exclusive baseclasses
XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
					, XTypeProvider
					, XPropertySetInfo
					);
//--------------------------------------------------------------------------
// XPropertySetInfo methods.
//--------------------------------------------------------------------------
//virtual
Sequence< Property > SAL_CALL CCRS_PropertySetInfo
	::getProperties() throw( RuntimeException )
{
	return *m_pProperties;
}

//virtual
Property SAL_CALL CCRS_PropertySetInfo
	::getPropertyByName( const rtl::OUString& aName )
		throw( UnknownPropertyException, RuntimeException )
{
	if ( !aName.getLength() )
		throw UnknownPropertyException();

	Property aProp;
	if ( impl_queryProperty( aName, aProp ) )
		return aProp;

	throw UnknownPropertyException();
}

//virtual
sal_Bool SAL_CALL CCRS_PropertySetInfo
	::hasPropertyByName( const rtl::OUString& Name )
		throw( RuntimeException )
{
	return ( impl_getPos( Name ) != -1 );
}

//--------------------------------------------------------------------------
// impl_ methods.
//--------------------------------------------------------------------------

sal_Int32 SAL_CALL CCRS_PropertySetInfo
			::impl_getPos( const OUString& rName ) const
{
	for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
	{
		const Property& rMyProp = (*m_pProperties)[nN];
		if( rMyProp.Name == rName )
			return nN;
	}
	return -1;
}

sal_Bool SAL_CALL CCRS_PropertySetInfo
		::impl_queryProperty( const OUString& rName, Property& rProp ) const
{
	for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
	{
		const Property& rMyProp = (*m_pProperties)[nN];
		if( rMyProp.Name == rName )
		{
			rProp.Name = rMyProp.Name;
			rProp.Handle = rMyProp.Handle;
			rProp.Type = rMyProp.Type;
			rProp.Attributes = rMyProp.Attributes;

			return sal_True;
		}
	}
	return sal_False;
}

//static
sal_Bool SAL_CALL CCRS_PropertySetInfo
		::impl_isMyPropertyName( const OUString& rPropertyName )
{
	return ( rPropertyName == m_aPropertyNameForCount
	|| rPropertyName == m_aPropertyNameForFinalCount
	|| rPropertyName == m_aPropertyNameForFetchSize
	|| rPropertyName == m_aPropertyNameForFetchDirection );
}

sal_Int32 SAL_CALL CCRS_PropertySetInfo
			::impl_getRemainedHandle( ) const
{
	sal_Int32 nHandle = 1;

	if( !m_pProperties )
	{
		OSL_ENSURE( sal_False, "Properties not initialized yet" );
		return nHandle;
	}
	sal_Bool bFound = sal_True;
	while( bFound )
	{
		bFound = sal_False;
		for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
		{
			if( nHandle == (*m_pProperties)[nN].Handle )
			{
				bFound = sal_True;
				nHandle++;
				break;
			}
		}
	}
	return nHandle;
}

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// class CachedContentResultSet
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

CachedContentResultSet::CachedContentResultSet(
                  const Reference< XMultiServiceFactory > & xSMgr
                , const Reference< XResultSet > & xOrigin
                , const Reference< XContentIdentifierMapping > &
					xContentIdentifierMapping )
				: ContentResultSetWrapper( xOrigin )

                , m_xSMgr( xSMgr )
				, m_xFetchProvider( NULL )
				, m_xFetchProviderForContentAccess( NULL )

				, m_xMyPropertySetInfo( NULL )
				, m_pMyPropSetInfo( NULL )

				, m_xContentIdentifierMapping( xContentIdentifierMapping )
				, m_nRow( 0 ) // Position is one-based. Zero means: before first element.
				, m_bAfterLast( sal_False )
				, m_nLastAppliedPos( 0 )
				, m_bAfterLastApplied( sal_False )
				, m_nKnownCount( 0 )
				, m_bFinalCount( sal_False )
				, m_nFetchSize(
					COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE )
				, m_nFetchDirection(
					COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION )

				, m_bLastReadWasFromCache( sal_False )
				, m_bLastCachedReadWasNull( sal_True )
				, m_aCache( m_xContentIdentifierMapping )
				, m_aCacheContentIdentifierString( m_xContentIdentifierMapping )
				, m_aCacheContentIdentifier( m_xContentIdentifierMapping )
				, m_aCacheContent( m_xContentIdentifierMapping )
                , m_bTriedToGetTypeConverter( sal_False )
                , m_xTypeConverter( NULL )
{
	m_xFetchProvider = Reference< XFetchProvider >( m_xResultSetOrigin, UNO_QUERY );
	OSL_ENSURE( m_xFetchProvider.is(), "interface XFetchProvider is required" );

	m_xFetchProviderForContentAccess = Reference< XFetchProviderForContentAccess >( m_xResultSetOrigin, UNO_QUERY );
	OSL_ENSURE( m_xFetchProviderForContentAccess.is(), "interface XFetchProviderForContentAccess is required" );

	impl_init();
};

CachedContentResultSet::~CachedContentResultSet()
{
	impl_deinit();
	//do not delete m_pMyPropSetInfo, cause it is hold via reference
};

//--------------------------------------------------------------------------
// impl_ methods.
//--------------------------------------------------------------------------

sal_Bool SAL_CALL CachedContentResultSet
	::applyPositionToOrigin( sal_Int32 nRow )
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();
	//-------------------------------------------------------------------------
    /**
	@returns
		<TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
		the result set.
	*/

	ReacquireableGuard aGuard( m_aMutex );
	OSL_ENSURE( nRow >= 0, "only positive values supported" );
	if( !m_xResultSetOrigin.is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		return sal_False;
	}
//	OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );

	sal_Int32 nLastAppliedPos = m_nLastAppliedPos;
	sal_Bool bAfterLastApplied = m_bAfterLastApplied;
	sal_Bool bAfterLast = m_bAfterLast;
	sal_Int32 nForwardOnly = m_nForwardOnly;

	aGuard.clear();

	if( bAfterLastApplied || nLastAppliedPos != nRow )
	{
		if( nForwardOnly == 1 )
		{
			if( bAfterLastApplied || bAfterLast || !nRow || nRow < nLastAppliedPos )
				throw SQLException();

			sal_Int32 nN = nRow - nLastAppliedPos;
			sal_Int32 nM;
			for( nM = 0; nN--; nM++ )
			{
				if( !m_xResultSetOrigin->next() )
					break;
			}

			aGuard.reacquire();
			m_nLastAppliedPos += nM;
			m_bAfterLastApplied = nRow != m_nLastAppliedPos;
			return nRow == m_nLastAppliedPos;
		}

		if( !nRow ) //absolute( 0 ) will throw exception
		{
			m_xResultSetOrigin->beforeFirst();

			aGuard.reacquire();
			m_nLastAppliedPos = 0;
			m_bAfterLastApplied = sal_False;
			return sal_False;
		}
		try
		{
			//move absolute, if !nLastAppliedPos
			//because move relative would throw exception
			if( !nLastAppliedPos || bAfterLast || bAfterLastApplied )
			{
				sal_Bool bValid = m_xResultSetOrigin->absolute( nRow );

				aGuard.reacquire();
				m_nLastAppliedPos = nRow;
				m_bAfterLastApplied = !bValid;
				return bValid;
			}
			else
			{
				sal_Bool bValid = m_xResultSetOrigin->relative( nRow - nLastAppliedPos );

				aGuard.reacquire();
				m_nLastAppliedPos += ( nRow - nLastAppliedPos );
				m_bAfterLastApplied = !bValid;
				return bValid;
			}
		}
		catch( SQLException& rEx )
		{
			if( !bAfterLastApplied && !bAfterLast && nRow > nLastAppliedPos && impl_isForwardOnly() )
			{
				sal_Int32 nN = nRow - nLastAppliedPos;
				sal_Int32 nM;
				for( nM = 0; nN--; nM++ )
				{
					if( !m_xResultSetOrigin->next() )
						break;
				}

				aGuard.reacquire();
				m_nLastAppliedPos += nM;
				m_bAfterLastApplied = nRow != m_nLastAppliedPos;
			}
			else
				throw rEx;
		}

		return nRow == m_nLastAppliedPos;
	}
    return sal_True;
};

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//define for fetching data
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#define FETCH_XXX( aCache, fetchInterface, fetchMethod )			\
sal_Bool bDirection = !!(											\
	nFetchDirection != FetchDirection::REVERSE );					\
FetchResult aResult =												\
	fetchInterface->fetchMethod( nRow, nFetchSize, bDirection );	\
osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex );				\
aCache.loadData( aResult );											\
sal_Int32 nMax = aCache.getMaxRow();								\
sal_Int32 nCurCount = m_nKnownCount;								\
sal_Bool bIsFinalCount = aCache.hasKnownLast();						\
sal_Bool bCurIsFinalCount = m_bFinalCount;							\
aGuard2.clear();													\
if( nMax > nCurCount )												\
	impl_changeRowCount( nCurCount, nMax );							\
if( bIsFinalCount && !bCurIsFinalCount )							\
	impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );

void SAL_CALL CachedContentResultSet
	::impl_fetchData( sal_Int32 nRow
		, sal_Int32 nFetchSize, sal_Int32 nFetchDirection )
		throw( com::sun::star::uno::RuntimeException )
{
	FETCH_XXX( m_aCache, m_xFetchProvider, fetch );
}

void SAL_CALL CachedContentResultSet
	::impl_changeRowCount( sal_Int32 nOld, sal_Int32 nNew )
{
	OSL_ENSURE( nNew > nOld, "RowCount only can grow" );
	if( nNew <= nOld )
		return;

	//create PropertyChangeEvent and set value
	PropertyChangeEvent aEvt;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		aEvt.Source =  static_cast< XPropertySet * >( this );
		aEvt.Further = sal_False;
		aEvt.OldValue <<= nOld;
		aEvt.NewValue <<= nNew;

		m_nKnownCount = nNew;
	}

	//send PropertyChangeEvent to listeners
	impl_notifyPropertyChangeListeners( aEvt );
}

void SAL_CALL CachedContentResultSet
	::impl_changeIsRowCountFinal( sal_Bool bOld, sal_Bool bNew )
{
	OSL_ENSURE( !bOld && bNew, "This change is not allowed for IsRowCountFinal" );
	if( ! (!bOld && bNew ) )
		return;

	//create PropertyChangeEvent and set value
	PropertyChangeEvent aEvt;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		aEvt.Source =  static_cast< XPropertySet * >( this );
		aEvt.Further = sal_False;
		aEvt.OldValue <<= bOld;
		aEvt.NewValue <<= bNew;

		m_bFinalCount = bNew;
	}

	//send PropertyChangeEvent to listeners
	impl_notifyPropertyChangeListeners( aEvt );
}

sal_Bool SAL_CALL CachedContentResultSet
	::impl_isKnownValidPosition( sal_Int32 nRow )
{
	return m_nKnownCount && nRow
			&& nRow <= m_nKnownCount;
}

sal_Bool SAL_CALL CachedContentResultSet
	::impl_isKnownInvalidPosition( sal_Int32 nRow )
{
	if( !nRow )
		return sal_True;
	if( !m_bFinalCount )
		return sal_False;
	return nRow > m_nKnownCount;
}


//virtual
void SAL_CALL CachedContentResultSet
	::impl_initPropertySetInfo()
{
	ContentResultSetWrapper::impl_initPropertySetInfo();

	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	if( m_pMyPropSetInfo )
		return;
	m_pMyPropSetInfo = new CCRS_PropertySetInfo( m_xPropertySetInfo );
	m_xMyPropertySetInfo = m_pMyPropSetInfo;
	m_xPropertySetInfo = m_xMyPropertySetInfo;
}

//--------------------------------------------------------------------------
// XInterface methods. ( inherited )
//--------------------------------------------------------------------------
XINTERFACE_COMMON_IMPL( CachedContentResultSet )

Any SAL_CALL CachedContentResultSet
	::queryInterface( const Type&  rType )
	throw ( RuntimeException )
{
	//list all interfaces inclusive baseclasses of interfaces

	Any aRet = ContentResultSetWrapper::queryInterface( rType );
	if( aRet.hasValue() )
		return aRet;

	aRet = cppu::queryInterface( rType,
				static_cast< XTypeProvider* >( this ),
				static_cast< XServiceInfo* >( this ) );

	return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}

//--------------------------------------------------------------------------
// XTypeProvider methods.
//--------------------------------------------------------------------------
//list all interfaces exclusive baseclasses
XTYPEPROVIDER_IMPL_11( CachedContentResultSet
					, XTypeProvider
					, XServiceInfo
					, XComponent
					, XCloseable
					, XResultSetMetaDataSupplier
					, XPropertySet

					, XPropertyChangeListener
					, XVetoableChangeListener

					, XContentAccess

					, XResultSet
					, XRow );

//--------------------------------------------------------------------------
// XServiceInfo methods.
//--------------------------------------------------------------------------

XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet,
		 		   		   OUString::createFromAscii(
							"com.sun.star.comp.ucb.CachedContentResultSet" ),
					 	   OUString::createFromAscii(
							CACHED_CONTENT_RESULTSET_SERVICE_NAME ) );

//--------------------------------------------------------------------------
// XPropertySet methods. ( inherited )
//--------------------------------------------------------------------------

// virtual
void SAL_CALL CachedContentResultSet
	::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
	throw( UnknownPropertyException,
		   PropertyVetoException,
		   IllegalArgumentException,
		   WrappedTargetException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( !getPropertySetInfo().is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		throw UnknownPropertyException();
	}

	Property aProp = m_pMyPropSetInfo->getPropertyByName( aPropertyName );
		//throws UnknownPropertyException, if so

	if( aProp.Attributes & PropertyAttribute::READONLY )
	{
		//It is assumed, that the properties
		//'RowCount' and 'IsRowCountFinal' are readonly!
		throw IllegalArgumentException();
	}
	if( aProp.Name == CCRS_PropertySetInfo
						::m_aPropertyNameForFetchDirection )
	{
		//check value
		sal_Int32 nNew;
		if( !( aValue >>= nNew ) )
		{
			throw IllegalArgumentException();
		}

		if( nNew == FetchDirection::UNKNOWN )
		{
			nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION;
		}
		else if( !(	nNew == FetchDirection::FORWARD
				|| nNew == FetchDirection::REVERSE ) )
		{
			throw IllegalArgumentException();
		}

		//create PropertyChangeEvent and set value
		PropertyChangeEvent aEvt;
		{
			osl::Guard< osl::Mutex > aGuard( m_aMutex );
			aEvt.Source =  static_cast< XPropertySet * >( this );
			aEvt.PropertyName = aPropertyName;
			aEvt.Further = sal_False;
			aEvt.PropertyHandle = m_pMyPropSetInfo->
									m_nFetchDirectionPropertyHandle;
			aEvt.OldValue <<= m_nFetchDirection;
			aEvt.NewValue <<= nNew;

			m_nFetchDirection = nNew;
		}

		//send PropertyChangeEvent to listeners
		impl_notifyPropertyChangeListeners( aEvt );
	}
	else if( aProp.Name == CCRS_PropertySetInfo
						::m_aPropertyNameForFetchSize )
	{
		//check value
		sal_Int32 nNew;
		if( !( aValue >>= nNew ) )
		{
			throw IllegalArgumentException();
		}

		if( nNew < 0 )
		{
			nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE;
		}

		//create PropertyChangeEvent and set value
		PropertyChangeEvent aEvt;
		{
			osl::Guard< osl::Mutex > aGuard( m_aMutex );
			aEvt.Source =  static_cast< XPropertySet * >( this );
			aEvt.PropertyName = aPropertyName;
			aEvt.Further = sal_False;
			aEvt.PropertyHandle = m_pMyPropSetInfo->
									m_nFetchSizePropertyHandle;
			aEvt.OldValue <<= m_nFetchSize;
			aEvt.NewValue <<= nNew;

			m_nFetchSize = nNew;
		}

		//send PropertyChangeEvent to listeners
		impl_notifyPropertyChangeListeners( aEvt );
	}
	else
	{
		impl_init_xPropertySetOrigin();
		{
			osl::Guard< osl::Mutex > aGuard( m_aMutex );
			if( !m_xPropertySetOrigin.is() )
			{
				OSL_ENSURE( sal_False, "broadcaster was disposed already" );
				return;
			}
		}
		m_xPropertySetOrigin->setPropertyValue( aPropertyName, aValue );
	}
}

//--------------------------------------------------------------------------
// virtual
Any SAL_CALL CachedContentResultSet
	::getPropertyValue( const OUString& rPropertyName )
	throw( UnknownPropertyException,
		   WrappedTargetException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( !getPropertySetInfo().is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		throw UnknownPropertyException();
	}

	Property aProp = m_pMyPropSetInfo->getPropertyByName( rPropertyName );
		//throws UnknownPropertyException, if so

	Any aValue;
	if( rPropertyName == CCRS_PropertySetInfo
						::m_aPropertyNameForCount )
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		aValue <<= m_nKnownCount;
	}
	else if( rPropertyName == CCRS_PropertySetInfo
							::m_aPropertyNameForFinalCount )
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		aValue <<= m_bFinalCount;
	}
	else if( rPropertyName == CCRS_PropertySetInfo
							::m_aPropertyNameForFetchSize )
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		aValue <<= m_nFetchSize;
	}
	else if( rPropertyName == CCRS_PropertySetInfo
							::m_aPropertyNameForFetchDirection )
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		aValue <<= m_nFetchDirection;
	}
	else
	{
		impl_init_xPropertySetOrigin();
		{
			osl::Guard< osl::Mutex > aGuard( m_aMutex );
			if( !m_xPropertySetOrigin.is() )
			{
				OSL_ENSURE( sal_False, "broadcaster was disposed already" );
				throw UnknownPropertyException();
			}
		}
		aValue = m_xPropertySetOrigin->getPropertyValue( rPropertyName );
	}
	return aValue;
}

//--------------------------------------------------------------------------
// own methods.  ( inherited )
//--------------------------------------------------------------------------

//virtual
void SAL_CALL CachedContentResultSet
	::impl_disposing( const EventObject& rEventObject )
	throw( RuntimeException )
{
	{
		impl_EnsureNotDisposed();
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		//release all references to the broadcaster:
		m_xFetchProvider.clear();
		m_xFetchProviderForContentAccess.clear();
	}
	ContentResultSetWrapper::impl_disposing( rEventObject );
}

//virtual
void SAL_CALL CachedContentResultSet
	::impl_propertyChange( const PropertyChangeEvent& rEvt )
	throw( RuntimeException )
{
	impl_EnsureNotDisposed();

	PropertyChangeEvent aEvt( rEvt );
	aEvt.Source = static_cast< XPropertySet * >( this );
	aEvt.Further = sal_False;
	//---------

	if( CCRS_PropertySetInfo
			::impl_isMyPropertyName( rEvt.PropertyName ) )
	{
		//don't notify foreign events on fetchsize and fetchdirection
		if( aEvt.PropertyName == CCRS_PropertySetInfo
								::m_aPropertyNameForFetchSize
		|| aEvt.PropertyName == CCRS_PropertySetInfo
								::m_aPropertyNameForFetchDirection )
			return;

		//adjust my props 'RowCount' and 'IsRowCountFinal'
		if( aEvt.PropertyName == CCRS_PropertySetInfo
							::m_aPropertyNameForCount )
		{//RowCount changed

			//check value
			sal_Int32 nNew = 0;
			if( !( aEvt.NewValue >>= nNew ) )
			{
				OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" );
				return;
			}

			impl_changeRowCount( m_nKnownCount, nNew );
		}
		else if( aEvt.PropertyName == CCRS_PropertySetInfo
								::m_aPropertyNameForFinalCount )
		{//IsRowCountFinal changed

			//check value
			sal_Bool bNew = sal_False;
			if( !( aEvt.NewValue >>= bNew ) )
			{
				OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" );
				return;
			}
			impl_changeIsRowCountFinal( m_bFinalCount, bNew );
		}
		return;
	}

	//-----------
	impl_notifyPropertyChangeListeners(	aEvt );
}


//virtual
void SAL_CALL CachedContentResultSet
	::impl_vetoableChange( const PropertyChangeEvent& rEvt )
	throw( PropertyVetoException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	//don't notify events on my properties, cause they are not vetoable
	if( CCRS_PropertySetInfo
			::impl_isMyPropertyName( rEvt.PropertyName ) )
	{
		return;
	}


	PropertyChangeEvent aEvt( rEvt );
	aEvt.Source = static_cast< XPropertySet * >( this );
	aEvt.Further = sal_False;

	impl_notifyVetoableChangeListeners( aEvt );
}

//--------------------------------------------------------------------------
// XContentAccess methods. ( inherited ) ( -- position dependent )
//--------------------------------------------------------------------------

#define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE )				\
impl_EnsureNotDisposed();									\
ReacquireableGuard aGuard( m_aMutex );						\
sal_Int32 nRow = m_nRow;									\
sal_Int32 nFetchSize = m_nFetchSize;						\
sal_Int32 nFetchDirection = m_nFetchDirection;				\
if( !m_aCache##XXX.hasRow( nRow ) )							\
{															\
	if( !m_aCache##XXX.hasCausedException( nRow ) )			\
{															\
		if( !m_xFetchProviderForContentAccess.is() )		\
		{													\
			OSL_ENSURE( sal_False, "broadcaster was disposed already" );\
			throw RuntimeException();						\
		}													\
		aGuard.clear();										\
		if( impl_isForwardOnly() )							\
			applyPositionToOrigin( nRow );					\
															\
		FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
	}														\
	aGuard.reacquire();										\
	if( !m_aCache##XXX.hasRow( nRow ) )						\
	{														\
		aGuard.clear();										\
		applyPositionToOrigin( nRow );						\
		TYPE aRet = ContentResultSetWrapper::queryXXX();	\
		if( m_xContentIdentifierMapping.is() )				\
			return m_xContentIdentifierMapping->map##XXX( aRet );\
		return aRet;										\
	}														\
}															\
return m_aCache##XXX.get##XXX( nRow );

//--------------------------------------------------------------------------
// virtual
OUString SAL_CALL CachedContentResultSet
	::queryContentIdentifierString()
	throw( RuntimeException )
{
	XCONTENTACCESS_queryXXX( queryContentIdentifierString, ContentIdentifierString, OUString )
}

//--------------------------------------------------------------------------
// virtual
Reference< XContentIdentifier > SAL_CALL CachedContentResultSet
	::queryContentIdentifier()
	throw( RuntimeException )
{
	XCONTENTACCESS_queryXXX( queryContentIdentifier, ContentIdentifier, Reference< XContentIdentifier > )
}

//--------------------------------------------------------------------------
// virtual
Reference< XContent > SAL_CALL CachedContentResultSet
	::queryContent()
	throw( RuntimeException )
{
	XCONTENTACCESS_queryXXX( queryContent, Content, Reference< XContent > )
}

//-----------------------------------------------------------------
// XResultSet methods. ( inherited )
//-----------------------------------------------------------------
//virtual

sal_Bool SAL_CALL CachedContentResultSet
	::next()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	ReacquireableGuard aGuard( m_aMutex );
	//after last
	if( m_bAfterLast )
		return sal_False;
	//last
	aGuard.clear();
	if( isLast() )
	{
		aGuard.reacquire();
		m_nRow++;
		m_bAfterLast = sal_True;
		return sal_False;
	}
	aGuard.reacquire();
	//known valid position
	if( impl_isKnownValidPosition( m_nRow + 1 ) )
	{
		m_nRow++;
		return sal_True;
	}

	//unknown position
	sal_Int32 nRow = m_nRow;
	aGuard.clear();

	sal_Bool bValid = applyPositionToOrigin( nRow + 1 );

	aGuard.reacquire();
	m_nRow = nRow + 1;
	m_bAfterLast = !bValid;
	return bValid;
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::previous()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( impl_isForwardOnly() )
		throw SQLException();

	ReacquireableGuard aGuard( m_aMutex );
	//before first ?:
	if( !m_bAfterLast && !m_nRow )
		return sal_False;
	//first ?:
	if( !m_bAfterLast && m_nKnownCount && m_nRow == 1 )
	{
		m_nRow--;
		m_bAfterLast = sal_False;
		return sal_False;
	}
	//known valid position ?:
	if( impl_isKnownValidPosition( m_nRow - 1 ) )
	{
		m_nRow--;
		m_bAfterLast = sal_False;
		return sal_True;
	}
	//unknown position:
	sal_Int32 nRow = m_nRow;
	aGuard.clear();

	sal_Bool bValid = applyPositionToOrigin( nRow - 1  );

	aGuard.reacquire();
	m_nRow = nRow - 1;
	m_bAfterLast = sal_False;
	return bValid;
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::absolute( sal_Int32 row )
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( !row )
		throw SQLException();

	if( impl_isForwardOnly() )
		throw SQLException();

	ReacquireableGuard aGuard( m_aMutex );

	if( !m_xResultSetOrigin.is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		return sal_False;
	}
	if( row < 0 )
	{
		if( m_bFinalCount )
		{
			sal_Int32 nNewRow = m_nKnownCount + 1 + row;
			sal_Bool bValid = sal_True;
			if( nNewRow <= 0 )
			{
				nNewRow = 0;
				bValid = sal_False;
			}
			m_nRow = nNewRow;
			m_bAfterLast = sal_False;
			return bValid;
		}
		//unknown final count:
		aGuard.clear();

		// Solaris has problems catching or propagating derived exceptions
		// when only the base class is known, so make ResultSetException
		// (derived from SQLException) known here:
		sal_Bool bValid;
		try
		{
			bValid = m_xResultSetOrigin->absolute( row );
		}
		catch (ResultSetException &)
		{
			throw;
		}

		aGuard.reacquire();
		if( m_bFinalCount )
		{
			sal_Int32 nNewRow = m_nKnownCount + 1 + row;
			if( nNewRow < 0 )
				nNewRow = 0;
			m_nLastAppliedPos = nNewRow;
			m_nRow = nNewRow;
			m_bAfterLastApplied = m_bAfterLast = sal_False;
			return bValid;
		}
		aGuard.clear();

		sal_Int32 nCurRow = m_xResultSetOrigin->getRow();

		aGuard.reacquire();
		m_nLastAppliedPos = nCurRow;
		m_nRow = nCurRow;
		m_bAfterLast = sal_False;
		return nCurRow != 0;
	}
	//row > 0:
	if( m_bFinalCount )
	{
		if( row > m_nKnownCount )
		{
			m_nRow = m_nKnownCount + 1;
			m_bAfterLast = sal_True;
			return sal_False;
		}
		m_nRow = row;
		m_bAfterLast = sal_False;
		return sal_True;
	}
	//unknown new position:
	aGuard.clear();

	sal_Bool bValid = m_xResultSetOrigin->absolute( row );

	aGuard.reacquire();
	if( m_bFinalCount )
	{
		sal_Int32 nNewRow = row;
		if( nNewRow > m_nKnownCount )
		{
			nNewRow = m_nKnownCount + 1;
			m_bAfterLastApplied = m_bAfterLast = sal_True;
		}
		else
			m_bAfterLastApplied = m_bAfterLast = sal_False;

		m_nLastAppliedPos = nNewRow;
		m_nRow = nNewRow;
		return bValid;
	}
	aGuard.clear();

	sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
	sal_Bool bIsAfterLast = m_xResultSetOrigin->isAfterLast();

	aGuard.reacquire();
	m_nLastAppliedPos = nCurRow;
	m_nRow = nCurRow;
	m_bAfterLastApplied = m_bAfterLast = bIsAfterLast;
	return nCurRow && !bIsAfterLast;
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::relative( sal_Int32 rows )
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( impl_isForwardOnly() )
		throw SQLException();

	ReacquireableGuard aGuard( m_aMutex );
	if( m_bAfterLast || impl_isKnownInvalidPosition( m_nRow ) )
		throw SQLException();

	if( !rows )
		return sal_True;

	sal_Int32 nNewRow = m_nRow + rows;
		if( nNewRow < 0 )
			nNewRow = 0;

	if( impl_isKnownValidPosition( nNewRow ) )
	{
		m_nRow = nNewRow;
		m_bAfterLast = sal_False;
		return sal_True;
	}
	else
	{
		//known invalid new position:
		if( nNewRow == 0 )
		{
			m_bAfterLast = sal_False;
			m_nRow = 0;
			return sal_False;
		}
		if( m_bFinalCount && nNewRow > m_nKnownCount )
		{
			m_bAfterLast = sal_True;
			m_nRow = m_nKnownCount + 1;
			return sal_False;
		}
		//unknown new position:
		aGuard.clear();
		sal_Bool bValid = applyPositionToOrigin( nNewRow );

		aGuard.reacquire();
		m_nRow = nNewRow;
		m_bAfterLast = !bValid && nNewRow > 0;
		return bValid;
	}
}


//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::first()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( impl_isForwardOnly() )
		throw SQLException();

	ReacquireableGuard aGuard( m_aMutex );
	if( impl_isKnownValidPosition( 1 ) )
	{
		m_nRow = 1;
		m_bAfterLast = sal_False;
		return sal_True;
	}
	if( impl_isKnownInvalidPosition( 1 ) )
	{
		m_nRow = 1;
		m_bAfterLast = sal_False;
		return sal_False;
	}
	//unknown position
	aGuard.clear();

	sal_Bool bValid = applyPositionToOrigin( 1 );

	aGuard.reacquire();
	m_nRow = 1;
	m_bAfterLast = sal_False;
	return bValid;
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::last()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( impl_isForwardOnly() )
		throw SQLException();

	ReacquireableGuard aGuard( m_aMutex );
	if( m_bFinalCount )
	{
		m_nRow = m_nKnownCount;
		m_bAfterLast = sal_False;
		return m_nKnownCount != 0;
	}
	//unknown position
	if( !m_xResultSetOrigin.is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		return sal_False;
	}
	aGuard.clear();

	sal_Bool bValid = m_xResultSetOrigin->last();

	aGuard.reacquire();
	m_bAfterLastApplied = m_bAfterLast = sal_False;
	if( m_bFinalCount )
	{
		m_nLastAppliedPos = m_nKnownCount;
		m_nRow = m_nKnownCount;
		return bValid;
	}
	aGuard.clear();

	sal_Int32 nCurRow = m_xResultSetOrigin->getRow();

	aGuard.reacquire();
	m_nLastAppliedPos = nCurRow;
	m_nRow = nCurRow;
	OSL_ENSURE( nCurRow >= m_nKnownCount, "position of last row < known Count, that could not be" );
	m_nKnownCount = nCurRow;
	m_bFinalCount = sal_True;
	return nCurRow != 0;
}

//virtual
void SAL_CALL CachedContentResultSet
	::beforeFirst()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( impl_isForwardOnly() )
		throw SQLException();

	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	m_nRow = 0;
	m_bAfterLast = sal_False;
}

//virtual
void SAL_CALL CachedContentResultSet
	::afterLast()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	if( impl_isForwardOnly() )
		throw SQLException();

	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	m_nRow = 1;
	m_bAfterLast = sal_True;
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::isAfterLast()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	ReacquireableGuard aGuard( m_aMutex );
	if( !m_bAfterLast )
		return sal_False;
	if( m_nKnownCount )
		return m_bAfterLast;
	if( m_bFinalCount )
		return sal_False;

	if( !m_xResultSetOrigin.is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		return sal_False;
	}
	aGuard.clear();

	//find out whethter the original resultset contains rows or not
	m_xResultSetOrigin->afterLast();

	aGuard.reacquire();
	m_bAfterLastApplied = sal_True;
	aGuard.clear();

	return m_xResultSetOrigin->isAfterLast();
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::isBeforeFirst()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	ReacquireableGuard aGuard( m_aMutex );
	if( m_bAfterLast )
		return sal_False;
	if( m_nRow )
		return sal_False;
	if( m_nKnownCount )
		return !m_nRow;
	if( m_bFinalCount )
		return sal_False;

	if( !m_xResultSetOrigin.is() )
	{
		OSL_ENSURE( sal_False, "broadcaster was disposed already" );
		return sal_False;
	}
	aGuard.clear();

	//find out whethter the original resultset contains rows or not
	m_xResultSetOrigin->beforeFirst();

	aGuard.reacquire();
	m_bAfterLastApplied = sal_False;
	m_nLastAppliedPos = 0;
	aGuard.clear();

	return m_xResultSetOrigin->isBeforeFirst();
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::isFirst()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	sal_Int32 nRow = 0;
	Reference< XResultSet > xResultSetOrigin;

	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		if( m_bAfterLast )
			return sal_False;
		if( m_nRow != 1 )
			return sal_False;
		if( m_nKnownCount )
			return m_nRow == 1;
		if( m_bFinalCount )
			return sal_False;

		nRow = m_nRow;
		xResultSetOrigin = m_xResultSetOrigin;
	}

	//need to ask origin
	{
		if( applyPositionToOrigin( nRow ) )
			return xResultSetOrigin->isFirst();
		else
			return sal_False;
	}
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::isLast()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	sal_Int32 nRow = 0;
	Reference< XResultSet > xResultSetOrigin;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		if( m_bAfterLast )
			return sal_False;
		if( m_nRow < m_nKnownCount )
			return sal_False;
		if( m_bFinalCount )
			return m_nKnownCount && m_nRow == m_nKnownCount;

		nRow = m_nRow;
		xResultSetOrigin = m_xResultSetOrigin;
	}

	//need to ask origin
	{
		if( applyPositionToOrigin( nRow ) )
			return xResultSetOrigin->isLast();
		else
			return sal_False;
	}
}


//virtual
sal_Int32 SAL_CALL CachedContentResultSet
	::getRow()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	if( m_bAfterLast )
		return 0;
	return m_nRow;
}

//virtual
void SAL_CALL CachedContentResultSet
	::refreshRow()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	//the ContentResultSet is static and will not change
	//therefore we don't need to reload anything
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::rowUpdated()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	//the ContentResultSet is static and will not change
	return sal_False;
}
//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::rowInserted()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	//the ContentResultSet is static and will not change
	return sal_False;
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::rowDeleted()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();

	//the ContentResultSet is static and will not change
	return sal_False;
}

//virtual
Reference< XInterface > SAL_CALL CachedContentResultSet
	::getStatement()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();
	//@todo ?return anything
	return Reference< XInterface >();
}

//-----------------------------------------------------------------
// XRow methods. ( inherited )
//-----------------------------------------------------------------

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::wasNull()
	throw( SQLException,
		   RuntimeException )
{
	impl_EnsureNotDisposed();
	impl_init_xRowOrigin();
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		if( m_bLastReadWasFromCache )
			return m_bLastCachedReadWasNull;
		if( !m_xRowOrigin.is() )
		{
			OSL_ENSURE( sal_False, "broadcaster was disposed already" );
			return sal_False;
		}
	}
	return m_xRowOrigin->wasNull();
}

//virtual
rtl::OUString SAL_CALL CachedContentResultSet
	::getString( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getString, OUString );
}

//virtual
sal_Bool SAL_CALL CachedContentResultSet
	::getBoolean( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getBoolean, sal_Bool );
}

//virtual
sal_Int8 SAL_CALL CachedContentResultSet
	::getByte( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getByte, sal_Int8 );
}

//virtual
sal_Int16 SAL_CALL CachedContentResultSet
	::getShort( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getShort, sal_Int16 );
}

//virtual
sal_Int32 SAL_CALL CachedContentResultSet
	::getInt( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getInt, sal_Int32 );
}

//virtual
sal_Int64 SAL_CALL CachedContentResultSet
	::getLong( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getLong, sal_Int64 );
}

//virtual
float SAL_CALL CachedContentResultSet
	::getFloat( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getFloat, float );
}

//virtual
double SAL_CALL CachedContentResultSet
	::getDouble( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getDouble, double );
}

//virtual
Sequence< sal_Int8 > SAL_CALL CachedContentResultSet
	::getBytes( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getBytes, Sequence< sal_Int8 > );
}

//virtual
Date SAL_CALL CachedContentResultSet
	::getDate( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getDate, Date );
}

//virtual
Time SAL_CALL CachedContentResultSet
	::getTime( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getTime, Time );
}

//virtual
DateTime SAL_CALL CachedContentResultSet
	::getTimestamp( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getTimestamp, DateTime );
}

//virtual
Reference< com::sun::star::io::XInputStream >
	SAL_CALL CachedContentResultSet
	::getBinaryStream( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getBinaryStream, Reference< com::sun::star::io::XInputStream > );
}

//virtual
Reference< com::sun::star::io::XInputStream >
	SAL_CALL CachedContentResultSet
	::getCharacterStream( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getCharacterStream, Reference< com::sun::star::io::XInputStream > );
}

//virtual
Any SAL_CALL CachedContentResultSet
	::getObject( sal_Int32 columnIndex,
		   const Reference<
			com::sun::star::container::XNameAccess >& typeMap )
	throw( SQLException,
		   RuntimeException )
{
	//if you change this macro please pay attention to
	//define XROW_GETXXX, where this is similar implemented

	ReacquireableGuard aGuard( m_aMutex );
	sal_Int32 nRow = m_nRow;
	sal_Int32 nFetchSize = m_nFetchSize;
	sal_Int32 nFetchDirection = m_nFetchDirection;
	if( !m_aCache.hasRow( nRow ) )
	{
		if( !m_aCache.hasCausedException( nRow ) )
		{
			if( !m_xFetchProvider.is() )
			{
				OSL_ENSURE( sal_False, "broadcaster was disposed already" );
				return Any();
			}
			aGuard.clear();

			impl_fetchData( nRow, nFetchSize, nFetchDirection );
		}
		aGuard.reacquire();
		if( !m_aCache.hasRow( nRow ) )
		{
			m_bLastReadWasFromCache = sal_False;
			aGuard.clear();
			applyPositionToOrigin( nRow );
			impl_init_xRowOrigin();
			return m_xRowOrigin->getObject( columnIndex, typeMap );
		}
	}
	//@todo: pay attention to typeMap
	const Any& rValue = m_aCache.getAny( nRow, columnIndex );
	Any aRet;
	m_bLastReadWasFromCache = sal_True;
	m_bLastCachedReadWasNull = !( rValue >>= aRet );
	return aRet;
}

//virtual
Reference< XRef > SAL_CALL CachedContentResultSet
	::getRef( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getRef, Reference< XRef > );
}

//virtual
Reference< XBlob > SAL_CALL CachedContentResultSet
	::getBlob( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getBlob, Reference< XBlob > );
}

//virtual
Reference< XClob > SAL_CALL CachedContentResultSet
	::getClob( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getClob, Reference< XClob > );
}

//virtual
Reference< XArray > SAL_CALL CachedContentResultSet
	::getArray( sal_Int32 columnIndex )
	throw( SQLException,
		   RuntimeException )
{
	XROW_GETXXX( getArray, Reference< XArray > );
}

//-----------------------------------------------------------------
// Type Converter Support
//-----------------------------------------------------------------

const Reference< XTypeConverter >& CachedContentResultSet::getTypeConverter()
{
    osl::Guard< osl::Mutex > aGuard( m_aMutex );

	if ( !m_bTriedToGetTypeConverter && !m_xTypeConverter.is() )
	{
		m_bTriedToGetTypeConverter = sal_True;
		m_xTypeConverter = Reference< XTypeConverter >(
								m_xSMgr->createInstance(
									OUString::createFromAscii(
										"com.sun.star.script.Converter" ) ),
								UNO_QUERY );

        OSL_ENSURE( m_xTypeConverter.is(),
					"PropertyValueSet::getTypeConverter() - "
					"Service 'com.sun.star.script.Converter' n/a!" );
	}
	return m_xTypeConverter;
}

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// class CachedContentResultSetFactory
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

CachedContentResultSetFactory::CachedContentResultSetFactory(
		const Reference< XMultiServiceFactory > & rSMgr )
{
	m_xSMgr = rSMgr;
}

CachedContentResultSetFactory::~CachedContentResultSetFactory()
{
}

//--------------------------------------------------------------------------
// CachedContentResultSetFactory XInterface methods.
//--------------------------------------------------------------------------

XINTERFACE_IMPL_3( CachedContentResultSetFactory,
				   XTypeProvider,
				   XServiceInfo,
				   XCachedContentResultSetFactory );

//--------------------------------------------------------------------------
// CachedContentResultSetFactory XTypeProvider methods.
//--------------------------------------------------------------------------

XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory,
					  XTypeProvider,
				   	  XServiceInfo,
					  XCachedContentResultSetFactory );

//--------------------------------------------------------------------------
// CachedContentResultSetFactory XServiceInfo methods.
//--------------------------------------------------------------------------

XSERVICEINFO_IMPL_1( CachedContentResultSetFactory,
					 OUString::createFromAscii(
			   			"com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
	 		   		 OUString::createFromAscii(
					 	CACHED_CONTENT_RESULTSET_FACTORY_NAME ) );

//--------------------------------------------------------------------------
// Service factory implementation.
//--------------------------------------------------------------------------

ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory );

//--------------------------------------------------------------------------
// CachedContentResultSetFactory XCachedContentResultSetFactory methods.
//--------------------------------------------------------------------------

	//virtual
Reference< XResultSet > SAL_CALL CachedContentResultSetFactory
	::createCachedContentResultSet(
			const Reference< XResultSet > & xSource,
			const Reference< XContentIdentifierMapping > & xMapping )
			throw( com::sun::star::uno::RuntimeException )
{
	Reference< XResultSet > xRet;
    xRet = new CachedContentResultSet( m_xSMgr, xSource, xMapping );
	return xRet;
}

