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



//#include <stdlib.h>
//#include <sal/alloca.h>

#include <boost/scoped_ptr.hpp>

#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>

#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/xml/sax/XFastContextHandler.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/xml/sax/FastToken.hpp>

#include "fastparser.hxx"

#include <string.h>

using ::rtl::OString;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using namespace ::std;
using namespace ::osl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::xml::sax;
//using namespace ::com::sun::star::util;
using namespace ::com::sun::star::io;

namespace sax_fastparser {

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

struct SaxContextImpl
{
	Reference< XFastContextHandler >	mxContext;
	sal_uInt32		mnNamespaceCount;
	sal_Int32		mnElementToken;
	OUString		maNamespace;
	OUString		maElementName;

	SaxContextImpl() { mnNamespaceCount = 0; mnElementToken = 0; }
	SaxContextImpl( const SaxContextImplPtr& p ) { mnNamespaceCount = p->mnNamespaceCount; mnElementToken = p->mnElementToken; maNamespace = p->maNamespace; }
};

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

struct NamespaceDefine
{
	OString		maPrefix;
	sal_Int32	mnToken;
	OUString	maNamespaceURL;

	NamespaceDefine( const OString& rPrefix, sal_Int32 nToken, const OUString& rNamespaceURL ) : maPrefix( rPrefix ), mnToken( nToken ), maNamespaceURL( rNamespaceURL ) {}
};

// --------------------------------------------------------------------
// FastLocatorImpl
// --------------------------------------------------------------------

class FastSaxParser;

class FastLocatorImpl : public WeakImplHelper1< XLocator >
{
public:
	FastLocatorImpl( FastSaxParser *p ) : mpParser(p) {}

	void dispose() { mpParser = 0; }
	void checkDispose() throw (RuntimeException) { if( !mpParser ) throw DisposedException(); }

	//XLocator
    virtual sal_Int32 SAL_CALL getColumnNumber(void) throw (RuntimeException);
	virtual sal_Int32 SAL_CALL getLineNumber(void) throw (RuntimeException);
    virtual OUString SAL_CALL getPublicId(void) throw (RuntimeException);
    virtual OUString SAL_CALL getSystemId(void) throw (RuntimeException);

private:
	FastSaxParser *mpParser;
};

// --------------------------------------------------------------------
// FastSaxParser
// --------------------------------------------------------------------

//---------------------------------------------
// the implementation part
//---------------------------------------------

extern "C" {

static void call_callbackStartElement(void *userData, const XML_Char *name , const XML_Char **atts)
{
    FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData );
    pFastParser->callbackStartElement( name, atts );
}

static void call_callbackEndElement(void *userData, const XML_Char *name)
{
    FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData );
    pFastParser->callbackEndElement( name );
}

static void call_callbackCharacters( void *userData , const XML_Char *s , int nLen )
{
    FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( userData );
    pFastParser->callbackCharacters( s, nLen );
}

static int call_callbackExternalEntityRef( XML_Parser parser,
        const XML_Char *openEntityNames, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId )
{
    FastSaxParser* pFastParser = reinterpret_cast< FastSaxParser* >( XML_GetUserData( parser ) );
    return pFastParser->callbackExternalEntityRef( parser, openEntityNames, base, systemId, publicId );
}

} // extern "C"

// --------------------------------------------------------------------
// FastLocatorImpl implementation
// --------------------------------------------------------------------

sal_Int32 SAL_CALL FastLocatorImpl::getColumnNumber(void) throw (RuntimeException)
{
	checkDispose();
	return XML_GetCurrentColumnNumber( mpParser->getEntity().mpParser );
}

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

sal_Int32 SAL_CALL FastLocatorImpl::getLineNumber(void) throw (RuntimeException)
{
	checkDispose();
	return XML_GetCurrentLineNumber( mpParser->getEntity().mpParser );
}

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

OUString SAL_CALL FastLocatorImpl::getPublicId(void) throw (RuntimeException)
{
	checkDispose();
	return mpParser->getEntity().maStructSource.sPublicId;
}
// --------------------------------------------------------------------

OUString SAL_CALL FastLocatorImpl::getSystemId(void) throw (RuntimeException)
{
	checkDispose();
	return mpParser->getEntity().maStructSource.sSystemId;
}

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

ParserData::ParserData()
{
}

ParserData::~ParserData()
{
}

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

Entity::Entity( const ParserData& rData ) :
    ParserData( rData )
{
	// performance-Improvment. Reference is needed when calling the startTag callback.
	// Handing out the same object with every call is allowed (see sax-specification)
	mxAttributes.set( new FastAttributeList( mxTokenHandler ) );
}

Entity::~Entity()
{
}

// --------------------------------------------------------------------
// FastSaxParser implementation
// --------------------------------------------------------------------

FastSaxParser::FastSaxParser()
{
	mxDocumentLocator.set( new FastLocatorImpl( this ) );
}

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

FastSaxParser::~FastSaxParser()
{
	if( mxDocumentLocator.is() )
		mxDocumentLocator->dispose();
}

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

void FastSaxParser::pushContext()
{
    Entity& rEntity = getEntity();
	if( rEntity.maContextStack.empty() )
	{
        rEntity.maContextStack.push( SaxContextImplPtr( new SaxContextImpl ) );
		DefineNamespace( OString("xml"), "http://www.w3.org/XML/1998/namespace");
	}
	else
	{
        rEntity.maContextStack.push( SaxContextImplPtr( new SaxContextImpl( rEntity.maContextStack.top() ) ) );
	}
}

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

void FastSaxParser::popContext()
{
    Entity& rEntity = getEntity();
	OSL_ENSURE( !rEntity.maContextStack.empty(), "sax::FastSaxParser::popContext(), pop without push?" );
	if( !rEntity.maContextStack.empty() )
		rEntity.maContextStack.pop();
}

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

void FastSaxParser::DefineNamespace( const OString& rPrefix, const sal_Char* pNamespaceURL )
{
    Entity& rEntity = getEntity();
	OSL_ENSURE( !rEntity.maContextStack.empty(), "sax::FastSaxParser::DefineNamespace(), I need a context!" );
	if( !rEntity.maContextStack.empty() )
	{
		sal_uInt32 nOffset = rEntity.maContextStack.top()->mnNamespaceCount++;

		if( rEntity.maNamespaceDefines.size() <= nOffset )
			rEntity.maNamespaceDefines.resize( rEntity.maNamespaceDefines.size() + 64 );

		const OUString aNamespaceURL( pNamespaceURL, strlen( pNamespaceURL ), RTL_TEXTENCODING_UTF8 );
		rEntity.maNamespaceDefines[nOffset].reset( new NamespaceDefine( rPrefix, GetNamespaceToken( aNamespaceURL ), aNamespaceURL ) );
	}
}

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

sal_Int32 FastSaxParser::GetToken( const OString& rToken )
{
    Sequence< sal_Int8 > aSeq( (sal_Int8*)rToken.getStr(), rToken.getLength() );

    return getEntity().mxTokenHandler->getTokenFromUTF8( aSeq );
}

sal_Int32 FastSaxParser::GetToken( const sal_Char* pToken, sal_Int32 nLen /* = 0 */ )
{
	if( !nLen )
		nLen = strlen( pToken );

	Sequence< sal_Int8 > aSeq( (sal_Int8*)pToken, nLen );

	return getEntity().mxTokenHandler->getTokenFromUTF8( aSeq );
}

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

sal_Int32 FastSaxParser::GetTokenWithPrefix( const OString& rPrefix, const OString& rName ) throw (SAXException)
{
    sal_Int32 nNamespaceToken = FastToken::DONTKNOW;

    Entity& rEntity = getEntity();
    sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount;
    while( nNamespace-- )
    {
        if( rEntity.maNamespaceDefines[nNamespace]->maPrefix == rPrefix )
        {
            nNamespaceToken = rEntity.maNamespaceDefines[nNamespace]->mnToken;
            break;
        }

        if( !nNamespace )
            throw SAXException(); // prefix that has no defined namespace url
    }

    if( nNamespaceToken != FastToken::DONTKNOW )
    {
        sal_Int32 nNameToken = GetToken( rName.getStr(), rName.getLength() );
        if( nNameToken != FastToken::DONTKNOW )
            return nNamespaceToken | nNameToken;
    }

    return FastToken::DONTKNOW;
}

sal_Int32 FastSaxParser::GetTokenWithPrefix( const sal_Char*pPrefix, int nPrefixLen, const sal_Char* pName, int nNameLen ) throw (SAXException)
{
	sal_Int32 nNamespaceToken = FastToken::DONTKNOW;

    Entity& rEntity = getEntity();
	sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount;
	while( nNamespace-- )
	{
		const OString& rPrefix( rEntity.maNamespaceDefines[nNamespace]->maPrefix );
		if( (rPrefix.getLength() == nPrefixLen) &&
			(strncmp( rPrefix.getStr(), pPrefix, nPrefixLen ) == 0 ) )
		{
			nNamespaceToken = rEntity.maNamespaceDefines[nNamespace]->mnToken;
			break;
		}

		if( !nNamespace )
			throw SAXException(); // prefix that has no defined namespace url
	}

	if( nNamespaceToken != FastToken::DONTKNOW )
	{
		sal_Int32 nNameToken = GetToken( pName, nNameLen );
		if( nNameToken != FastToken::DONTKNOW )
			return nNamespaceToken | nNameToken;
	}

	return FastToken::DONTKNOW;
}

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

sal_Int32 FastSaxParser::GetNamespaceToken( const OUString& rNamespaceURL )
{
	NamespaceMap::iterator aIter( maNamespaceMap.find( rNamespaceURL ) );
	if( aIter != maNamespaceMap.end() )
		return (*aIter).second;
	else
		return FastToken::DONTKNOW;
}

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

OUString FastSaxParser::GetNamespaceURL( const OString& rPrefix ) throw (SAXException)
{
    Entity& rEntity = getEntity();
    if( !rEntity.maContextStack.empty() )
    {
        sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount;
        while( nNamespace-- )
            if( rEntity.maNamespaceDefines[nNamespace]->maPrefix == rPrefix )
                return rEntity.maNamespaceDefines[nNamespace]->maNamespaceURL;
    }

    throw SAXException(); // prefix that has no defined namespace url
}

OUString FastSaxParser::GetNamespaceURL( const sal_Char*pPrefix, int nPrefixLen ) throw(SAXException)
{
    Entity& rEntity = getEntity();
	if( pPrefix && !rEntity.maContextStack.empty() )
	{
		sal_uInt32 nNamespace = rEntity.maContextStack.top()->mnNamespaceCount;
		while( nNamespace-- )
		{
			const OString& rPrefix( rEntity.maNamespaceDefines[nNamespace]->maPrefix );
			if( (rPrefix.getLength() == nPrefixLen) &&
				(strncmp( rPrefix.getStr(), pPrefix, nPrefixLen ) == 0 ) )
			{
				return rEntity.maNamespaceDefines[nNamespace]->maNamespaceURL;
			}
		}
	}

	throw SAXException(); // prefix that has no defined namespace url
}

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

sal_Int32 FastSaxParser::GetTokenWithNamespaceURL( const OUString& rNamespaceURL, const sal_Char* pName, int nNameLen )
{
	sal_Int32 nNamespaceToken = GetNamespaceToken( rNamespaceURL );

	if( nNamespaceToken != FastToken::DONTKNOW )
	{
		sal_Int32 nNameToken = GetToken( pName, nNameLen );
		if( nNameToken != FastToken::DONTKNOW )
			return nNamespaceToken | nNameToken;
	}

	return FastToken::DONTKNOW;
}

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

void FastSaxParser::splitName( const XML_Char *pwName, const XML_Char *&rpPrefix, sal_Int32 &rPrefixLen, const XML_Char *&rpName, sal_Int32 &rNameLen )
{
	XML_Char *p;
	for( p = const_cast< XML_Char* >( pwName ), rNameLen = 0, rPrefixLen = 0; *p; p++ )
	{
		if( *p == ':' )
		{
			rPrefixLen = p - pwName;
			rNameLen = 0;
		}
		else
		{
			rNameLen++;
		}
	}
	if( rPrefixLen )
	{
		rpPrefix = pwName;
		rpName = &pwName[ rPrefixLen + 1 ];
	}
	else
	{
		rpPrefix = 0;
		rpName = pwName;
	}
}

/***************
*
* parseStream does Parser-startup initializations. The FastSaxParser::parse() method does
* the file-specific initialization work. (During a parser run, external files may be opened)
*
****************/
void FastSaxParser::parseStream( const InputSource& maStructSource)	throw (SAXException, IOException, RuntimeException)
{
	// Only one text at one time
	MutexGuard guard( maMutex );

	Entity entity( maData );
	entity.maStructSource = maStructSource;

	if( !entity.maStructSource.aInputStream.is() )
		throw SAXException( OUString( RTL_CONSTASCII_USTRINGPARAM( "No input source" ) ), Reference< XInterface >(), Any() );

	entity.maConverter.setInputStream( entity.maStructSource.aInputStream );
	if( entity.maStructSource.sEncoding.getLength() )
		entity.maConverter.setEncoding(	OUStringToOString( entity.maStructSource.sEncoding, RTL_TEXTENCODING_ASCII_US ) );

	// create parser with proper encoding
	entity.mpParser = XML_ParserCreate( 0 );
	if( !entity.mpParser )
		throw SAXException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Couldn't create parser" ) ), Reference< XInterface >(), Any() );

	// set all necessary C-Callbacks
	XML_SetUserData( entity.mpParser, this );
	XML_SetElementHandler( entity.mpParser,	call_callbackStartElement, call_callbackEndElement );
	XML_SetCharacterDataHandler( entity.mpParser, call_callbackCharacters );
	XML_SetExternalEntityRefHandler( entity.mpParser, call_callbackExternalEntityRef );

	pushEntity( entity );
	try
	{
		// start the document
		if( entity.mxDocumentHandler.is() )
		{
			Reference< XLocator > xLoc( mxDocumentLocator.get() );
			entity.mxDocumentHandler->setDocumentLocator( xLoc );
			entity.mxDocumentHandler->startDocument();
		}

		parse();

		// finish document
		if( entity.mxDocumentHandler.is() )
		{
			entity.mxDocumentHandler->endDocument();
		}
	}
	catch( SAXException & )
	{
		popEntity();
		XML_ParserFree( entity.mpParser );
  		throw;
	}
	catch( IOException & )
	{
		popEntity();
		XML_ParserFree( entity.mpParser );
		throw;
	}
	catch( RuntimeException & )
	{
		popEntity();
		XML_ParserFree( entity.mpParser );
		throw;
	}

	popEntity();
	XML_ParserFree( entity.mpParser );
}

void FastSaxParser::setFastDocumentHandler( const Reference< XFastDocumentHandler >& Handler ) throw (RuntimeException)
{
	maData.mxDocumentHandler = Handler;
}

void SAL_CALL FastSaxParser::setTokenHandler( const Reference< XFastTokenHandler >& Handler ) throw (RuntimeException)
{
	maData.mxTokenHandler = Handler;
}

void SAL_CALL FastSaxParser::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken ) throw (IllegalArgumentException, RuntimeException)
{
	if( NamespaceToken >= FastToken::NAMESPACE )
	{
		if( GetNamespaceToken( NamespaceURL ) == FastToken::DONTKNOW )
		{
			maNamespaceMap[ NamespaceURL ] = NamespaceToken;
			return;
		}
	}
	throw IllegalArgumentException();
}

void FastSaxParser::setErrorHandler(const Reference< XErrorHandler > & Handler) throw (RuntimeException)
{
	maData.mxErrorHandler = Handler;
}

void FastSaxParser::setEntityResolver(const Reference < XEntityResolver > & Resolver) throw (RuntimeException)
{
	maData.mxEntityResolver = Resolver;
}

void FastSaxParser::setLocale( const Locale & Locale ) throw (RuntimeException)
{
	maData.maLocale = Locale;
}

Sequence< OUString > FastSaxParser::getSupportedServiceNames_Static(void)
{
	Sequence<OUString> aRet(1);
	aRet.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(PARSER_SERVICE_NAME) );
	return aRet;
}

// XServiceInfo
OUString FastSaxParser::getImplementationName() throw (RuntimeException)
{
    return OUString::createFromAscii( PARSER_IMPLEMENTATION_NAME );
}

// XServiceInfo
sal_Bool FastSaxParser::supportsService(const OUString& ServiceName) throw (RuntimeException)
{
    Sequence< OUString > aSNL = getSupportedServiceNames();
    const OUString * pArray = aSNL.getConstArray();

    for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
        if( pArray[i] == ServiceName )
            return sal_True;

    return sal_False;
}

// XServiceInfo
Sequence< OUString > FastSaxParser::getSupportedServiceNames(void) throw (RuntimeException)
{

    Sequence<OUString> seq(1);
    seq.getArray()[0] = OUString::createFromAscii( PARSER_SERVICE_NAME );
    return seq;
}


/*---------------------------------------
*
* Helper functions and classes
*
*-------------------------------------------*/

namespace {

OUString lclGetErrorMessage( XML_Error xmlE, const OUString& sSystemId, sal_Int32 nLine )
{
	const sal_Char* pMessage = "";
	switch( xmlE )
	{
        case XML_ERROR_NONE:                            pMessage = "No";                                    break;
        case XML_ERROR_NO_MEMORY:                       pMessage = "no memory";                             break;
        case XML_ERROR_SYNTAX:                          pMessage = "syntax";                                break;
        case XML_ERROR_NO_ELEMENTS:                     pMessage = "no elements";                           break;
        case XML_ERROR_INVALID_TOKEN:                   pMessage = "invalid token";                         break;
        case XML_ERROR_UNCLOSED_TOKEN:                  pMessage = "unclosed token";                        break;
        case XML_ERROR_PARTIAL_CHAR:                    pMessage = "partial char";                          break;
        case XML_ERROR_TAG_MISMATCH:                    pMessage = "tag mismatch";                          break;
        case XML_ERROR_DUPLICATE_ATTRIBUTE:             pMessage = "duplicate attribute";                   break;
        case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:          pMessage = "junk after doc element";                break;
        case XML_ERROR_PARAM_ENTITY_REF:                pMessage = "parameter entity reference";            break;
        case XML_ERROR_UNDEFINED_ENTITY:                pMessage = "undefined entity";                      break;
        case XML_ERROR_RECURSIVE_ENTITY_REF:            pMessage = "recursive entity reference";            break;
        case XML_ERROR_ASYNC_ENTITY:                    pMessage = "async entity";                          break;
        case XML_ERROR_BAD_CHAR_REF:                    pMessage = "bad char reference";                    break;
        case XML_ERROR_BINARY_ENTITY_REF:               pMessage = "binary entity reference";               break;
        case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:   pMessage = "attribute external entity reference";   break;
        case XML_ERROR_MISPLACED_XML_PI:                pMessage = "misplaced xml processing instruction";  break;
        case XML_ERROR_UNKNOWN_ENCODING:                pMessage = "unknown encoding";                      break;
        case XML_ERROR_INCORRECT_ENCODING:              pMessage = "incorrect encoding";                    break;
        case XML_ERROR_UNCLOSED_CDATA_SECTION:          pMessage = "unclosed cdata section";                break;
        case XML_ERROR_EXTERNAL_ENTITY_HANDLING:        pMessage = "external entity reference";             break;
        case XML_ERROR_NOT_STANDALONE:                  pMessage = "not standalone";                        break;
        default:;
    }

	OUStringBuffer aBuffer( sal_Unicode( '[' ) );
	aBuffer.append( sSystemId );
	aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " line " ) );
	aBuffer.append( nLine );
	aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "]: " ) );
	aBuffer.appendAscii( pMessage );
	aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " error" ) );
	return aBuffer.makeStringAndClear();
}

} // namespace

// starts parsing with actual parser !
void FastSaxParser::parse()
{
	const int BUFFER_SIZE = 16 * 1024;
	Sequence< sal_Int8 > seqOut( BUFFER_SIZE );

    Entity& rEntity = getEntity();
	int nRead = 0;
    do
	{
		nRead = rEntity.maConverter.readAndConvert( seqOut, BUFFER_SIZE );
		if( nRead <= 0 )
		{
			XML_Parse( rEntity.mpParser, (const char*) seqOut.getConstArray(), 0, 1 );
			break;
		}

		bool bContinue = XML_Parse( rEntity.mpParser, (const char*) seqOut.getConstArray(), nRead, 0 ) != 0;
		// callbacks used inside XML_Parse may have caught an exception
		if( !bContinue || rEntity.maSavedException.hasValue() )
		{
			// Error during parsing !
			XML_Error xmlE = XML_GetErrorCode( rEntity.mpParser );
			OUString sSystemId = mxDocumentLocator->getSystemId();
			sal_Int32 nLine = mxDocumentLocator->getLineNumber();

			SAXParseException aExcept(
				lclGetErrorMessage( xmlE, sSystemId, nLine ),
				Reference< XInterface >(),
				Any( &rEntity.maSavedException, getCppuType( &rEntity.maSavedException ) ),
				mxDocumentLocator->getPublicId(),
				mxDocumentLocator->getSystemId(),
				mxDocumentLocator->getLineNumber(),
				mxDocumentLocator->getColumnNumber()
			);

            // error handler is set, it may throw the exception
			if( rEntity.mxErrorHandler.is() )
				rEntity.mxErrorHandler->fatalError( Any( aExcept ) );

			// error handler has not thrown, but parsing cannot go on, the
            // exception MUST be thrown
			throw aExcept;
		}
	}
	while( nRead > 0 );
}

//------------------------------------------
//
// The C-Callbacks
//
//-----------------------------------------

namespace {

struct AttributeData
{
    OString             maPrefix;
    OString             maName;
    OString             maValue;
};

} // namespace

void FastSaxParser::callbackStartElement( const XML_Char* pwName, const XML_Char** awAttributes )
{
	Reference< XFastContextHandler > xParentContext;
	Entity& rEntity = getEntity();
	if( !rEntity.maContextStack.empty() )
	{
		xParentContext = rEntity.maContextStack.top()->mxContext;
		if( !xParentContext.is() )
		{
			// we ignore current elements, so no processing needed
			pushContext();
			return;
		}
	}

	pushContext();

	rEntity.mxAttributes->clear();

	// create attribute map and process namespace instructions
	int i = 0;
	sal_Int32 nNameLen, nPrefixLen;
	const XML_Char *pName;
	const XML_Char *pPrefix;

	try
	{
        /*  #158414# Each element may define new namespaces, also for attribues.
            First, process all namespace attributes and cache other attributes in a
            vector. Second, process the attributes after namespaces have been
            initialized. */
        ::std::vector< AttributeData > aAttribs;

        // #158414# first: get namespaces
    	for( ; awAttributes[i]; i += 2 )
    	{
    		OSL_ASSERT( awAttributes[i+1] );

    		splitName( awAttributes[i], pPrefix, nPrefixLen, pName, nNameLen );
    		if( nPrefixLen )
    		{
    			if( (nPrefixLen == 5) && (strncmp( pPrefix, "xmlns", 5 ) == 0) )
    			{
    				DefineNamespace( OString( pName, nNameLen ), awAttributes[i+1] );
    			}
    			else
    			{
                    aAttribs.resize( aAttribs.size() + 1 );
                    aAttribs.back().maPrefix = OString( pPrefix, nPrefixLen );
                    aAttribs.back().maName = OString( pName, nNameLen );
                    aAttribs.back().maValue = OString( awAttributes[i+1] );
                }
    		}
    		else
    		{
    			if( (nNameLen == 5) && (strcmp( pName, "xmlns" ) == 0) )
    			{
    				// namespace of the element found
    				rEntity.maContextStack.top()->maNamespace = OUString( awAttributes[i+1], strlen( awAttributes[i+1] ), RTL_TEXTENCODING_UTF8 );
    			}
    			else
    			{
                    aAttribs.resize( aAttribs.size() + 1 );
                    aAttribs.back().maName = OString( pName, nNameLen );
                    aAttribs.back().maValue = OString( awAttributes[i+1] );
    			}
    		}
    	}

        // #158414# second: fill attribute list with other attributes
        for( ::std::vector< AttributeData >::const_iterator aIt = aAttribs.begin(), aEnd = aAttribs.end(); aIt != aEnd; ++aIt )
        {
            if( aIt->maPrefix.getLength() > 0 )
            {
                sal_Int32 nAttributeToken = GetTokenWithPrefix( aIt->maPrefix, aIt->maName );
                if( nAttributeToken != FastToken::DONTKNOW )
                    rEntity.mxAttributes->add( nAttributeToken, aIt->maValue );
                else
                    rEntity.mxAttributes->addUnknown( GetNamespaceURL( aIt->maPrefix ), aIt->maName, aIt->maValue );
            }
            else
            {
                sal_Int32 nAttributeToken = GetToken( aIt->maName );
                if( nAttributeToken != FastToken::DONTKNOW )
                    rEntity.mxAttributes->add( nAttributeToken, aIt->maValue );
                else
                    rEntity.mxAttributes->addUnknown( aIt->maName, aIt->maValue );
            }
        }

    	sal_Int32 nElementToken;
    	splitName( pwName, pPrefix, nPrefixLen, pName, nNameLen );
    	if( nPrefixLen > 0 )
    		nElementToken = GetTokenWithPrefix( pPrefix, nPrefixLen, pName, nNameLen );
    	else if( rEntity.maContextStack.top()->maNamespace.getLength() > 0 )
    		nElementToken = GetTokenWithNamespaceURL( rEntity.maContextStack.top()->maNamespace, pName, nNameLen );
    	else
    		nElementToken = GetToken( pName );
    	rEntity.maContextStack.top()->mnElementToken = nElementToken;

		Reference< XFastAttributeList > xAttr( rEntity.mxAttributes.get() );
		Reference< XFastContextHandler > xContext;
		if( nElementToken == FastToken::DONTKNOW )
		{
			if( nPrefixLen > 0 )
				rEntity.maContextStack.top()->maNamespace = GetNamespaceURL( pPrefix, nPrefixLen );

			const OUString aNamespace( rEntity.maContextStack.top()->maNamespace );
			const OUString aElementName( pPrefix, nPrefixLen, RTL_TEXTENCODING_UTF8 );
			rEntity.maContextStack.top()->maElementName = aElementName;

			if( xParentContext.is() )
				xContext = xParentContext->createUnknownChildContext( aNamespace, aElementName, xAttr );
			else
				xContext = rEntity.mxDocumentHandler->createUnknownChildContext( aNamespace, aElementName, xAttr );

			if( xContext.is() )
			{
				rEntity.maContextStack.top()->mxContext = xContext;
				xContext->startUnknownElement( aNamespace, aElementName, xAttr );
			}
		}
		else
		{
			if( xParentContext.is() )
				xContext = xParentContext->createFastChildContext( nElementToken, xAttr );
			else
				xContext = rEntity.mxDocumentHandler->createFastChildContext( nElementToken, xAttr );


			if( xContext.is() )
			{
				rEntity.maContextStack.top()->mxContext = xContext;
				xContext->startFastElement( nElementToken, xAttr );
			}
		}
	}
	catch( Exception& e )
	{
		rEntity.maSavedException <<= e;
	}
}

void FastSaxParser::callbackEndElement( const XML_Char* )
{
    Entity& rEntity = getEntity();
    OSL_ENSURE( !rEntity.maContextStack.empty(), "FastSaxParser::callbackEndElement - no context" );
	if( !rEntity.maContextStack.empty() )
	{
		SaxContextImplPtr pContext = rEntity.maContextStack.top();
		const Reference< XFastContextHandler >& xContext( pContext->mxContext );
		if( xContext.is() ) try
		{
			sal_Int32 nElementToken = pContext->mnElementToken;
			if( nElementToken != FastToken::DONTKNOW )
				xContext->endFastElement( nElementToken );
			else
				xContext->endUnknownElement( pContext->maNamespace, pContext->maElementName );
		}
		catch( Exception& e )
		{
			rEntity.maSavedException <<= e;
		}

		popContext();
	}
}


void FastSaxParser::callbackCharacters( const XML_Char* s, int nLen )
{
    Entity& rEntity = getEntity();
	const Reference< XFastContextHandler >& xContext( rEntity.maContextStack.top()->mxContext );
	if( xContext.is() ) try
	{
		xContext->characters( OUString( s, nLen, RTL_TEXTENCODING_UTF8 ) );
	}
	catch( Exception& e )
	{
		rEntity.maSavedException <<= e;
	}
}

int FastSaxParser::callbackExternalEntityRef( XML_Parser parser,
        const XML_Char *context, const XML_Char * /*base*/, const XML_Char *systemId, const XML_Char *publicId )
{
	bool bOK = true;
	InputSource source;

    Entity& rCurrEntity = getEntity();
	Entity aNewEntity( rCurrEntity );

	if( rCurrEntity.mxEntityResolver.is() ) try
	{
    	aNewEntity.maStructSource = rCurrEntity.mxEntityResolver->resolveEntity(
			OUString( publicId, strlen( publicId ), RTL_TEXTENCODING_UTF8 ) ,
			OUString( systemId, strlen( systemId ), RTL_TEXTENCODING_UTF8 ) );
    }
    catch( SAXParseException & e )
	{
    	rCurrEntity.maSavedException <<= e;
    	bOK = false;
    }
    catch( SAXException & e )
	{
    	rCurrEntity.maSavedException <<= SAXParseException(
			e.Message, e.Context, e.WrappedException,
			mxDocumentLocator->getPublicId(),
			mxDocumentLocator->getSystemId(),
			mxDocumentLocator->getLineNumber(),
			mxDocumentLocator->getColumnNumber() );
		bOK = false;
    }

	if( aNewEntity.maStructSource.aInputStream.is() )
	{
		aNewEntity.mpParser = XML_ExternalEntityParserCreate( parser, context, 0 );
		if( !aNewEntity.mpParser )
		{
			return false;
		}

		aNewEntity.maConverter.setInputStream( aNewEntity.maStructSource.aInputStream );
		pushEntity( aNewEntity );
		try
		{
			parse();
		}
		catch( SAXParseException & e )
		{
			rCurrEntity.maSavedException <<= e;
			bOK = false;
		}
		catch( IOException &e )
		{
			SAXException aEx;
			aEx.WrappedException <<= e;
			rCurrEntity.maSavedException <<= aEx;
			bOK = false;
		}
		catch( RuntimeException &e )
		{
			SAXException aEx;
			aEx.WrappedException <<= e;
			rCurrEntity.maSavedException <<= aEx;
			bOK = false;
		}

		popEntity();
		XML_ParserFree( aNewEntity.mpParser );
	}

	return bOK;
}

} // namespace sax_fastparser
