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

#include "saxeventkeeperimpl.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp>

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxcsax = com::sun::star::xml::csax;
namespace cssxw = com::sun::star::xml::wrapper;
namespace cssxs = com::sun::star::xml::sax;

#define SERVICE_NAME "com.sun.star.xml.crypto.sax.SAXEventKeeper"
#define IMPLEMENTATION_NAME "com.sun.star.xml.security.framework.SAXEventKeeperImpl"

#define _USECOMPRESSEDDOCUMENTHANDLER

SAXEventKeeperImpl::SAXEventKeeperImpl( )
	:m_pRootBufferNode(NULL),
	 m_pCurrentBufferNode(NULL),
     m_nNextElementMarkId(1),
	 m_pNewBlocker(NULL),
	 m_pCurrentBlockingBufferNode(NULL),
	 m_bIsReleasing(false),
	 m_bIsForwarding(false)
{
	m_vElementMarkBuffers.reserve(2);
	m_vNewElementCollectors.reserve(2);
	m_vReleasedElementMarkBuffers.reserve(2);
}

SAXEventKeeperImpl::~SAXEventKeeperImpl()
{
	/*
	 * delete the BufferNode tree
	 */
	if (m_pRootBufferNode != NULL)
	{
        m_pRootBufferNode->freeAllChildren();
		delete m_pRootBufferNode;
	}
	
	m_pRootBufferNode = m_pCurrentBufferNode = m_pCurrentBlockingBufferNode = NULL;
	
	/*
	 * delete all unfreed ElementMarks
	 */
	m_vNewElementCollectors.clear();
	m_pNewBlocker = NULL;
	
	std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin();
	for( ; ii != m_vElementMarkBuffers.end(); ++ii ) 
	{
		delete (*ii);
	}
	m_vElementMarkBuffers.clear();
}

void SAXEventKeeperImpl::setCurrentBufferNode(BufferNode* pBufferNode)
/****** SAXEventKeeperImpl/setCurrentBufferNode ******************************
 *
 *   NAME
 *	setCurrentBufferNode -- set a new active BufferNode.
 *
 *   SYNOPSIS
 *	setCurrentBufferNode( pBufferNode );
 *
 *   FUNCTION
 *	connects this BufferNode into the BufferNode tree as a child of the
 *	current active BufferNode. Then makes this BufferNode as the current
 *	active BufferNode.
 *	If the previous active BufferNode points to the root
 *	BufferNode, which means that no buffering operation was proceeding,
 *	then notifies the status change listener that buffering  operation 
 *	will begin at once.
 *
 *   INPUTS
 *	pBufferNode - a BufferNode which will be the new active BufferNode
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (pBufferNode != m_pCurrentBufferNode)
	{
		if ( m_pCurrentBufferNode == m_pRootBufferNode &&
		     m_xSAXEventKeeperStatusChangeListener.is())
		{
			m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_True);
		}
			
		if (pBufferNode->getParent() == NULL)
		{
			m_pCurrentBufferNode->addChild(pBufferNode);
			pBufferNode->setParent(m_pCurrentBufferNode);
		}
		
		m_pCurrentBufferNode = pBufferNode;
	}
}

BufferNode* SAXEventKeeperImpl::addNewElementMarkBuffers()
/****** SAXEventKeeperImpl/addNewElementMarkBuffers **************************
 *
 *   NAME
 *	addNewElementMarkBuffers -- add new ElementCollectors and new Blocker.
 *
 *   SYNOPSIS
 *	pBufferNode = addNewElementMarkBuffers( );
 *
 *   FUNCTION
 *	if there are new ElementCollector or new Blocker to be added, then
 *	connect all of them with the current BufferNode. In case of the
 *	current BufferNode doesn't exist, creates one.
 *	Clears up the new ElementCollector list and the new Blocker pointer.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	pBufferNode - the BufferNode that has been connected with both new
 *	              ElementCollectors and new Blocker.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* pBufferNode = NULL;

	if ( (m_vNewElementCollectors.size()>0) ||
	     (m_pNewBlocker != NULL))
	{
		/*
		 * When the current BufferNode is right pointing to the current
		 * working element in the XMLDocumentWrapper component, then
		 * no new BufferNode is needed to create.
		 * This situation can only happen in the "Forwarding" mode.
		 */
		if ( (m_pCurrentBufferNode != NULL) && 
		     (m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement())))
		{
			pBufferNode = m_pCurrentBufferNode;
		}
		else
		{
			pBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
		}
			
		if (m_pNewBlocker != NULL)
		{
			pBufferNode->setBlocker(m_pNewBlocker);
			
			/*
			 * If no blocking before, then notify the status change listener that
			 * the SAXEventKeeper has entered "blocking" status, during which, no
			 * SAX events will be forwarded to the next document handler.
			 */
			if (m_pCurrentBlockingBufferNode == NULL)
			{
				m_pCurrentBlockingBufferNode = pBufferNode;
				
				if (m_xSAXEventKeeperStatusChangeListener.is())
				{
					m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_True);
				}
			}
			
			m_pNewBlocker = NULL;
		}
		
		if (m_vNewElementCollectors.size()>0)
		{
			std::vector< const ElementCollector* >::const_iterator ii = m_vNewElementCollectors.begin();
			
			for( ; ii != m_vNewElementCollectors.end(); ++ii ) 
			{
				pBufferNode->addElementCollector(*ii);
			}
		
			m_vNewElementCollectors.clear();
		}
	}
	
	return pBufferNode;
}

ElementMark* SAXEventKeeperImpl::findElementMarkBuffer(sal_Int32 nId) const
/****** SAXEventKeeperImpl/findElementMarkBuffer *****************************
 *
 *   NAME
 *	findElementMarkBuffer -- finds an ElementMark.
 *
 *   SYNOPSIS
 *	pElementMark = findElementMarkBuffer( nId );
 *
 *   FUNCTION
 *	searches an ElementMark with the particular Id in the ElementMark
 *	list.
 *
 *   INPUTS
 *	nId - the Id of the ElementMark to be searched.
 *
 *   RESULT
 *	pElementMark - the ElementMark with the particular Id, or NULL when 
 *	               no such Id exists.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	ElementMark* pElementMark = NULL;
	
	std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin();
			
	for( ; ii != m_vElementMarkBuffers.end(); ++ii ) 
	{
		if ( nId == (*ii)->getBufferId())
		{
			pElementMark = (ElementMark*)*ii;
			break;
		}
	}
	
	return pElementMark;
}

void SAXEventKeeperImpl::removeElementMarkBuffer(sal_Int32 nId)
/****** SAXEventKeeperImpl/removeElementMarkBuffer ***************************
 *
 *   NAME
 *	removeElementMarkBuffer -- removes an ElementMark
 *
 *   SYNOPSIS
 *	removeElementMarkBuffer( nId );
 *
 *   FUNCTION
 *	removes an ElementMark with the particular Id in the ElementMark list.
 *
 *   INPUTS
 *	nId - the Id of the ElementMark to be removed.
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	std::vector< const ElementMark* >::iterator ii = m_vElementMarkBuffers.begin();
			
	for( ; ii != m_vElementMarkBuffers.end(); ++ii ) 
	{
		if ( nId == (*ii)->getBufferId())
		{
			/*
			 * checks whether this ElementMark still in the new ElementCollect array
			 */
			std::vector< const ElementCollector* >::iterator jj = m_vNewElementCollectors.begin();
			for( ; jj != m_vNewElementCollectors.end(); ++jj ) 
			{
				if ((*ii) == (*jj))
				{
					m_vNewElementCollectors.erase(jj);
					break;
				}
			}
			
			/*
			 * checks whether this ElementMark is the new Blocker
			 */
			if ((*ii) == m_pNewBlocker)
			{
				m_pNewBlocker = NULL;
			}
			
			/*
			 * destory the ElementMark
			 */
			delete (*ii);
			
			m_vElementMarkBuffers.erase( ii );
			break;
		}
	}
}

rtl::OUString SAXEventKeeperImpl::printBufferNode(
	BufferNode* pBufferNode, sal_Int32 nIndent) const
/****** SAXEventKeeperImpl/printBufferNode ***********************************
 *
 *   NAME
 *	printBufferNode -- retrieves the information of a BufferNode and its
 *	branch.
 *
 *   SYNOPSIS
 *	info = printBufferNode( pBufferNode, nIndent );
 *
 *   FUNCTION
 *	all retrieved information includes:
 *	1. whether it is the current BufferNode;
 *	2. whether it is the current blocking BufferNode;
 *	3. the name of the parent element;
 *	4. the name of this element;
 *	5. all ElementCollectors working on this BufferNode;
 *	6. the Blocker working on this BufferNode;
 *	7. all child BufferNodes' information.
 *
 *   INPUTS
 *	pBufferNode - 	the BufferNode from where information will be retrieved.
 *	nIndent - 	how many space characters prefixed before the output
 *	          	message.
 *
 *   RESULT
 *	info - the information string
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	rtl::OUString rc;

	for ( int i=0; i<nIndent; ++i )
	{
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
	}

	if (pBufferNode == m_pCurrentBufferNode)
	{
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[%]" ));
	}
		
	if (pBufferNode == m_pCurrentBlockingBufferNode)
	{
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[B]" ));
	}

	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
	rc += m_xXMLDocument->getNodeName(pBufferNode->getXMLElement());
	
	BufferNode* pParent = (BufferNode*)pBufferNode->getParent();
	if (pParent != NULL)
	{
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[" ));
		rc += m_xXMLDocument->getNodeName(pParent->getXMLElement());
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "]" ));
	}
	
	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":EC=" ));
	rc += pBufferNode->printChildren();
	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " BR=" ));
		
	ElementMark * pBlocker = pBufferNode->getBlocker();
	if (pBlocker != NULL)
	{
		rc += rtl::OUString::valueOf( pBlocker->getBufferId() );
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(SecId=" ));
		rc += rtl::OUString::valueOf( pBlocker->getSecurityId() );
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ));
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
	}
	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
		
	std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
	std::vector< const BufferNode* >::const_iterator jj = vChildren->begin();
	for( ; jj != vChildren->end(); ++jj ) 
	{
		rc += printBufferNode((BufferNode *)*jj, nIndent+4);
	}
	
	delete vChildren;
	
	return rc;
}

cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > > 
	SAXEventKeeperImpl::collectChildWorkingElement(BufferNode* pBufferNode) const
/****** SAXEventKeeperImpl/collectChildWorkingElement ************************
 *
 *   NAME
 *	collectChildWorkingElement -- collects a BufferNode's all child
 *	Elements.
 *
 *   SYNOPSIS
 *	list = collectChildWorkingElement( pBufferNode );
 *
 *   FUNCTION
 *	see NAME.
 *
 *   INPUTS
 *	pBufferNode - the BufferNode whose child Elements will be collected.
 *
 *   RESULT
 *	list - the child Elements list.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
	
	cssu::Sequence < cssu::Reference< 
		cssxw::XXMLElementWrapper > > aChildrenCollection ( vChildren->size());
	
	std::vector< const BufferNode* >::const_iterator ii = vChildren->begin();
	
	sal_Int32 nIndex = 0;
	for( ; ii != vChildren->end(); ++ii ) 
	{
		aChildrenCollection[nIndex] = (*ii)->getXMLElement();
		nIndex++;
	}
	
	delete vChildren;
	
	return aChildrenCollection;
}

void SAXEventKeeperImpl::smashBufferNode(
	BufferNode* pBufferNode, bool bClearRoot) const
/****** SAXEventKeeperImpl/smashBufferNode ***********************************
 *
 *   NAME
 *	smashBufferNode -- removes a BufferNode along with its working
 *	element.
 *
 *   SYNOPSIS
 *	smashBufferNode( pBufferNode, bClearRoot );
 *
 *   FUNCTION
 *	removes the BufferNode's working element from the DOM document, while
 *	reserves all ancestor paths for its child BufferNodes.
 *	when any of the BufferNode's ancestor element is useless, removes it
 *	too.
 *	removes the BufferNode from the BufferNode tree.
 *
 *   INPUTS
 *	pBufferNode - 	the BufferNode to be removed
 *	bClearRoot - 	whether the root element also needs to be cleared up.
 *
 *   RESULT
 *	empty
 *
 *   NOTES
 *	when removeing a Blocker's BufferNode, the bClearRoot flag should be
 *	true. Because a Blocker can buffer many SAX events which are not used
 *	by any other ElementCollector or Blocker.
 *	When the bClearRoot is set to true, the root BufferNode will be first
 *	cleared, with a stop flag seting at the next Blocking BufferNode. This
 *	operation can delete all useless bufferred SAX events which are only
 *	needed by the Blocker to be deleted.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (!pBufferNode->hasAnything())
	{
		BufferNode* pParent = (BufferNode*)pBufferNode->getParent();
		
	        /*
	         * delete the XML data
	         */
		if (pParent == m_pRootBufferNode)
		{
			bool bIsNotBlocking = (m_pCurrentBlockingBufferNode == NULL);
			bool bIsBlockInside = false;
			bool bIsBlockingAfterward = false;
			
		        /*
		         * If this is a blocker, then remove any out-element data
		         * which caused by blocking. The removal process will stop
		         * at the next blokcer to avoid removing any useful data.
		         */
			if (bClearRoot)
			{
				cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > > 
					aChildElements = collectChildWorkingElement(m_pRootBufferNode);
				
			        /*
			         * the clearUselessData only clearup the content in the 
			         * node, not the node itself.
			         */
				m_xXMLDocument->clearUselessData(m_pRootBufferNode->getXMLElement(),
					aChildElements,
					bIsNotBlocking?(NULL):
					               (m_pCurrentBlockingBufferNode->getXMLElement()));
					
			        /*
			         * remove the node if it is empty, then if its parent is also
			         * empty, remove it, then if the next parent is also empty,
			         * remove it,..., until parent become null.
			         */
				m_xXMLDocument->collapse( m_pRootBufferNode->getXMLElement() );
			}
			
			/*
			 * if blocking, check the relationship between this BufferNode and 
			 * the current blocking BufferNode.
			 */
			if ( !bIsNotBlocking )
			{
				/*
				 * the current blocking BufferNode is a descendant of this BufferNode.
				 */
				bIsBlockInside = (NULL != pBufferNode->isAncestor(m_pCurrentBlockingBufferNode));
				
				/*
				 * the current blocking BufferNode locates behind this BufferNode in tree
				 * order.
				 */
				bIsBlockingAfterward = pBufferNode->isPrevious(m_pCurrentBlockingBufferNode);
			}
			
			/*
			 * this BufferNode's working element needs to be deleted only when
			 * 1. there is no blocking, or
			 * 2. the current blocking BufferNode is a descendant of this BufferNode, 
			 *    (then in the BufferNode's working element, the useless data before the blocking
			 *     element should be deleted.) or
			 * 3. the current blocking BufferNode is locates behind this BufferNode in tree,
			 *    (then the useless data between the blocking element and the working element
			 *     should be deleted.).
			 * Otherwise, this working element should not be deleted.
			 */
			if ( bIsNotBlocking || bIsBlockInside || bIsBlockingAfterward )
			{
				cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > > 
					aChildElements = collectChildWorkingElement(pBufferNode);
				
			        /*
			         * the clearUselessData only clearup the content in the 
			         * node, not the node itself.
			         */
				m_xXMLDocument->clearUselessData(pBufferNode->getXMLElement(),
					aChildElements,
					bIsBlockInside?(m_pCurrentBlockingBufferNode->getXMLElement()):
						       (NULL));
					
			        /*
			         * remove the node if it is empty, then if its parent is also
			         * empty, remove it, then if the next parent is also empty,
			         * remove it,..., until parent become null.
			         */
				m_xXMLDocument->collapse( pBufferNode->getXMLElement() );
			}
		}

		sal_Int32 nIndex = pParent->indexOfChild(pBufferNode);

		std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
		pParent->removeChild(pBufferNode);
		pBufferNode->setParent(NULL);
		
		std::vector< const BufferNode * >::const_iterator ii = vChildren->begin();
		for( ; ii != vChildren->end(); ++ii ) 
		{
			((BufferNode *)(*ii))->setParent(pParent);
			pParent->addChild(*ii, nIndex);
			nIndex++;
		}
		
		delete vChildren;
		
		/*
		 * delete the BufferNode
		 */
		delete pBufferNode;
	}
}

BufferNode* SAXEventKeeperImpl::findNextBlockingBufferNode(
	BufferNode* pStartBufferNode) const
/****** SAXEventKeeperImpl/findNextBlockingBufferNode ************************
 *
 *   NAME
 *	findNextBlockingBufferNode -- finds the next blocking BufferNode
 *	behind the particular BufferNode.
 *
 *   SYNOPSIS
 *	pBufferNode = findNextBlockingBufferNode( pStartBufferNode );
 *
 *   FUNCTION
 *	see NAME.
 *
 *   INPUTS
 *	pStartBufferNode - the BufferNode from where to search the next 
 *	                   blocking BufferNode.
 *
 *   RESULT
 *	pBufferNode - the next blocking BufferNode, or NULL if no such 
 *	              BufferNode exists.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* pNext = NULL;
	
	if (pStartBufferNode != NULL)
	{
		pNext = pStartBufferNode;
		
		while (NULL != (pNext = (BufferNode*)pNext->getNextNodeByTreeOrder()))
		{
			if (pNext->getBlocker() != NULL)
			{
				break;
			}
		}
	}
		
	return pNext;
}

void SAXEventKeeperImpl::diffuse(BufferNode* pBufferNode) const
/****** SAXEventKeeperImpl/diffuse *******************************************
 *
 *   NAME
 *	diffuse -- diffuse the notification.
 *
 *   SYNOPSIS
 *	diffuse( pBufferNode );
 *
 *   FUNCTION
 *	diffuse the collecting completion notification from the specific
 *	BufferNode along its parent link, until an ancestor which is not
 *	completely received is met.
 *
 *   INPUTS
 *	pBufferNode - the BufferNode from which the notification will be 
 *	              diffused.
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* pParent = pBufferNode;
	
	while(pParent->isAllReceived())
	{
		pParent->elementCollectorNotify();
		pParent = (BufferNode*)pParent->getParent();
	}
}

void SAXEventKeeperImpl::releaseElementMarkBuffer()
/****** SAXEventKeeperImpl/releaseElementMarkBuffer **************************
 *
 *   NAME
 *	releaseElementMarkBuffer -- releases useless ElementMarks 
 *
 *   SYNOPSIS
 *	releaseElementMarkBuffer( );
 *
 *   FUNCTION
 *	releases each ElementMark in the releasing list
 *	m_vReleasedElementMarkBuffers.
 *	The operation differs between an ElementCollector and a Blocker.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	m_bIsReleasing = true;
	while (m_vReleasedElementMarkBuffers.size()>0)
	{
		std::vector< sal_Int32 >::iterator pId = m_vReleasedElementMarkBuffers.begin();
		sal_Int32 nId = *pId;
		m_vReleasedElementMarkBuffers.erase( pId );
		
		ElementMark* pElementMark = findElementMarkBuffer(nId);

		if (pElementMark != NULL)
		{
			if (cssxc::sax::ElementMarkType_ELEMENTCOLLECTOR 
				== pElementMark->getType()) 
			/*
			 * it is a EC
			 */
			{
				ElementCollector* pElementCollector = (ElementCollector*)pElementMark;
					
				cssxc::sax::ElementMarkPriority nPriority = pElementCollector->getPriority();
				bool bToModify = pElementCollector->getModify();
				
				/*
			         * Delete the EC from the buffer node.
			         */
				BufferNode* pBufferNode = pElementCollector->getBufferNode();
				pBufferNode->removeElementCollector(pElementCollector);

				if ( nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY)
				{
					pBufferNode->notifyBranch();
				}
						
				if (bToModify)
				{
					pBufferNode->notifyAncestor();
				}
				
				/*
				 * delete the ElementMark
				 */		 
				pElementCollector = NULL;
				pElementMark = NULL;
				removeElementMarkBuffer(nId);			
				
				/*
				 * delete the BufferNode
				 */
				diffuse(pBufferNode);
				smashBufferNode(pBufferNode, false);
			}
			else 
			/*
			 * it is a Blocker
			 */
			{
			        /*
			         * Delete the TH from the buffer node.
			         */
				BufferNode *pBufferNode = pElementMark->getBufferNode();
				pBufferNode->setBlocker(NULL);
				
			        /*
			         * If there is a following handler and no blocking now, then
			         * forward this event
			         */
				if (m_pCurrentBlockingBufferNode == pBufferNode)
				{
				        /*
				         * Before forwarding, the next blocking point needs to be 
				         * found.
				         */
					m_pCurrentBlockingBufferNode = findNextBlockingBufferNode(pBufferNode);
							
				        /*
				         * Forward the blocked events between these two STHs.
				         */
	       				if (m_xNextHandler.is())
	       				{
       						BufferNode* pTempCurrentBufferNode = m_pCurrentBufferNode;
       						BufferNode* pTempCurrentBlockingBufferNode = m_pCurrentBlockingBufferNode;
				       					
       						m_pCurrentBufferNode = pBufferNode;
       						m_pCurrentBlockingBufferNode = NULL;
				       					
						m_bIsForwarding = true;

						m_xXMLDocument->generateSAXEvents(
							m_xNextHandler,
							this,
							pBufferNode->getXMLElement(),
							(pTempCurrentBlockingBufferNode == NULL)?NULL:(pTempCurrentBlockingBufferNode->getXMLElement()));

						m_bIsForwarding = false;
								
						m_pCurrentBufferNode = pTempCurrentBufferNode;
						if (m_pCurrentBlockingBufferNode == NULL)
						{
							m_pCurrentBlockingBufferNode = pTempCurrentBlockingBufferNode;
						}
					}
							
					if (m_pCurrentBlockingBufferNode == NULL && 
					    m_xSAXEventKeeperStatusChangeListener.is())
					{
						m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_False);
					}
				}

				/*
				 * delete the ElementMark
				 */		 
				pElementMark = NULL;
				removeElementMarkBuffer(nId);
						
				/*
				 * delete the BufferNode
				 */
				diffuse(pBufferNode);
				smashBufferNode(pBufferNode, true);
			}
		}
	}
		
	m_bIsReleasing = false;
		
	if (!m_pRootBufferNode->hasAnything() && 
		!m_pRootBufferNode->hasChildren() && 
		m_xSAXEventKeeperStatusChangeListener.is())
	{
		m_xSAXEventKeeperStatusChangeListener->bufferStatusChanged(sal_True);
	}
}

void SAXEventKeeperImpl::markElementMarkBuffer(sal_Int32 nId)
/****** SAXEventKeeperImpl/markElementMarkBuffer *****************************
 *
 *   NAME
 *	markElementMarkBuffer -- marks an ElementMark to be released
 *
 *   SYNOPSIS
 *	markElementMarkBuffer( nId );
 *
 *   FUNCTION
 *	puts the ElementMark with the particular Id into the releasing list,
 *	checks whether the releasing process is runing, if not then launch 
 *	this process.
 *
 *   INPUTS
 *	nId - the Id of the ElementMark which will be released
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	m_vReleasedElementMarkBuffers.push_back( nId );
	if ( !m_bIsReleasing )
	{
		releaseElementMarkBuffer();
	}
}

sal_Int32 SAXEventKeeperImpl::createElementCollector(
	sal_Int32 nSecurityId,
	cssxc::sax::ElementMarkPriority nPriority,
	bool bModifyElement,
	const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& xReferenceResolvedListener)
/****** SAXEventKeeperImpl/createElementCollector ****************************
 *
 *   NAME
 *	createElementCollector -- creates a new ElementCollector on the
 *	incoming element.
 *
 *   SYNOPSIS
 *	nId = createElementCollector( nSecurityId, nPriority,
 *	                             bModifyElement,
 *	                             xReferenceResolvedListener );
 *
 *   FUNCTION
 *	allocs a new Id, then create an ElementCollector with this Id value.
 *	Add the new created ElementCollector to the new ElementCollecotor list.
 *
 *   INPUTS
 *	nSecurityId - 	the security Id of the new ElementCollector
 *	nPriority - 	the prirority of the new ElementCollector
 *	bModifyElement -whether this BufferNode will modify the content of
 *	                the corresponding element it works on
 *	xReferenceResolvedListener - the listener for the new ElementCollector.
 *
 *   RESULT
 *	nId - the Id of the new ElementCollector
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	sal_Int32 nId = m_nNextElementMarkId;
	m_nNextElementMarkId ++;
	
	ElementCollector* pElementCollector 
		= new ElementCollector(
			nSecurityId,
			nId,
			nPriority,
			bModifyElement,
			xReferenceResolvedListener);
				
	m_vElementMarkBuffers.push_back( pElementCollector );
		
        /*
         * All the new EC to initial EC array.
         */
	m_vNewElementCollectors.push_back( pElementCollector );
		
	return nId;
}

	
sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId)
/****** SAXEventKeeperImpl/createBlocker *************************************
 *
 *   NAME
 *	createBlocker -- creates a new Blocker on the incoming element.
 *
 *   SYNOPSIS
 *	nId = createBlocker( nSecurityId );
 *
 *   FUNCTION
 *	see NAME.
 *
 *   INPUTS
 *	nSecurityId - 	the security Id of the new Blocker
 *
 *   RESULT
 *	nId - the Id of the new Blocker
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	sal_Int32 nId = m_nNextElementMarkId;
	m_nNextElementMarkId ++;

	OSL_ASSERT(m_pNewBlocker == NULL);

	m_pNewBlocker = new ElementMark(nSecurityId, nId);
	m_vElementMarkBuffers.push_back( m_pNewBlocker );
		
	return nId;
}

/* XSAXEventKeeper */
sal_Int32 SAL_CALL SAXEventKeeperImpl::addElementCollector(  )
	throw (cssu::RuntimeException)
{
	return createElementCollector(
		cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
		cssxc::sax::ElementMarkPriority_AFTERMODIFY,
		false,
		NULL);
}

void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id )
	throw (cssu::RuntimeException)
{
	markElementMarkBuffer(id);
}
	
sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker(  )
	throw (cssu::RuntimeException)
{
	return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID);
}
	
void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id )
	throw (cssu::RuntimeException)
{
	markElementMarkBuffer(id);
}
	
sal_Bool SAL_CALL SAXEventKeeperImpl::isBlocking(  )
	throw (cssu::RuntimeException)
{
	return (m_pCurrentBlockingBufferNode != NULL);
}
	
cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL 
	SAXEventKeeperImpl::getElement( sal_Int32 id )
	throw (cssu::RuntimeException)
{
	cssu::Reference< cssxw::XXMLElementWrapper > rc;
	
	ElementMark* pElementMark = findElementMarkBuffer(id);
	if (pElementMark != NULL)
	{
		rc = pElementMark->getBufferNode()->getXMLElement();
	}
	
	return rc;
}

void SAL_CALL SAXEventKeeperImpl::setElement( 
	sal_Int32 id, 
	const cssu::Reference< cssxw::XXMLElementWrapper >& aElement )
	throw (cssu::RuntimeException)
{
	if (aElement.is())
	{
		m_xXMLDocument->rebuildIDLink(aElement);
		
		ElementMark* pElementMark = findElementMarkBuffer(id);
	
		if (pElementMark != NULL)
		{
			BufferNode* pBufferNode = pElementMark->getBufferNode();
			if (pBufferNode != NULL)
			{
			        bool bIsCurrent = m_xXMLDocument->isCurrent(pBufferNode->getXMLElement());
				pBufferNode->setXMLElement(aElement);
				
				if (bIsCurrent)
				{
					m_xXMLDocument->setCurrentElement(aElement);
				}
			}
		}
	}
	else
	{
		removeElementCollector( id );
	}
}
	
cssu::Reference< cssxs::XDocumentHandler > SAL_CALL SAXEventKeeperImpl::setNextHandler(
	const cssu::Reference< cssxs::XDocumentHandler >& xNewHandler )
	throw (cssu::RuntimeException)
{
	cssu::Reference< cssxs::XDocumentHandler > xOldHandler = m_xNextHandler;
	
	m_xNextHandler = xNewHandler;
	return xOldHandler;
}
	
rtl::OUString SAL_CALL SAXEventKeeperImpl::printBufferNodeTree()
	throw (cssu::RuntimeException)
{
	rtl::OUString rc;
	
	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ElementMarkBuffers: size = " ));
	rc += rtl::OUString::valueOf((sal_Int32)m_vElementMarkBuffers.size());
	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\nCurrentBufferNode: " ));
	rc += m_xXMLDocument->getNodeName(m_pCurrentBufferNode->getXMLElement());
	rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
	rc += printBufferNode(m_pRootBufferNode, 0);
	
	return rc;
}
	
cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL SAXEventKeeperImpl::getCurrentBlockingNode()
	throw (cssu::RuntimeException)
{
	cssu::Reference< cssxw::XXMLElementWrapper > rc;
	
	if (m_pCurrentBlockingBufferNode != NULL)
	{
		rc = m_pCurrentBlockingBufferNode->getXMLElement();
	}
	
	return rc;
}

/* XSecuritySAXEventKeeper */
sal_Int32 SAL_CALL SAXEventKeeperImpl::addSecurityElementCollector( 
	cssxc::sax::ElementMarkPriority priority,
	sal_Bool modifyElement )
	throw (cssu::RuntimeException)
{
	return createElementCollector(
		cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
		priority,
		modifyElement,
		NULL);
}
	
sal_Int32 SAL_CALL SAXEventKeeperImpl::cloneElementCollector(
	sal_Int32 referenceId,
	cssxc::sax::ElementMarkPriority priority )
	throw (cssu::RuntimeException)
{
	sal_Int32 nId = -1;
	
	ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
	if (pElementCollector != NULL)
	{
		nId = m_nNextElementMarkId;
		m_nNextElementMarkId ++;
			
		ElementCollector* pClonedOne 
			= pElementCollector->clone(nId, priority);
			
	        /*
	         * add this EC into the security data buffer array.
	         */
		m_vElementMarkBuffers.push_back(pClonedOne);

	        /*
	         * If the reference EC is still in initial EC array, add
	         * this cloned one into the initial EC array too.
	         */
	        if (pElementCollector->getBufferNode() == NULL)
		{
			m_vNewElementCollectors.push_back(pClonedOne);
		}
	}
	
	return nId;
}
	
void SAL_CALL SAXEventKeeperImpl::setSecurityId( sal_Int32 id, sal_Int32 securityId )
	throw (cssu::RuntimeException)
{
	ElementMark* pElementMark = findElementMarkBuffer(id);
	if (pElementMark != NULL)
	{
		pElementMark->setSecurityId(securityId);
	}
}

	
/* XReferenceResolvedBroadcaster */
void SAL_CALL SAXEventKeeperImpl::addReferenceResolvedListener(
	sal_Int32 referenceId,
	const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& listener )
	throw (cssu::RuntimeException)
{
	ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
	if (pElementCollector != NULL)
	{
		pElementCollector->setReferenceResolvedListener(listener);
	}
}
	
void SAL_CALL SAXEventKeeperImpl::removeReferenceResolvedListener( 
	sal_Int32 /*referenceId*/, 
	const cssu::Reference< cssxc::sax::XReferenceResolvedListener >&)
	throw (cssu::RuntimeException)
{
}
	
/* XSAXEventKeeperStatusChangeBroadcaster */
void SAL_CALL SAXEventKeeperImpl::addSAXEventKeeperStatusChangeListener(
	const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >& listener )
	throw (cssu::RuntimeException)
{
	m_xSAXEventKeeperStatusChangeListener = listener;
}
	
void SAL_CALL SAXEventKeeperImpl::removeSAXEventKeeperStatusChangeListener(
	const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >&)
	throw (cssu::RuntimeException)
{
}
	
/* XDocumentHandler */
void SAL_CALL SAXEventKeeperImpl::startDocument(  )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	if ( m_xNextHandler.is())
	{
		m_xNextHandler->startDocument();
	}
}
	
void SAL_CALL SAXEventKeeperImpl::endDocument(  )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	if ( m_xNextHandler.is())
	{
		m_xNextHandler->endDocument();
	}
}
	
void SAL_CALL SAXEventKeeperImpl::startElement(
	const rtl::OUString& aName,
	const cssu::Reference< cssxs::XAttributeList >& xAttribs )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
        /*
         * If there is a following handler and no blocking now, then
         * forward this event
         */
	if ((m_pCurrentBlockingBufferNode == NULL) &&
	    (m_xNextHandler.is()) && 
	    (!m_bIsForwarding) && 
	    (m_pNewBlocker == NULL))
	{
		m_xNextHandler->startElement(aName, xAttribs);
	}

        /*
         * If not forwarding, buffer this startElement.
         */
       	if (!m_bIsForwarding)
       	{
	#ifndef _USECOMPRESSEDDOCUMENTHANDLER
		m_xDocumentHandler->startElement(aName, xAttribs);
	#else
		sal_Int32 nLength = xAttribs->getLength();
		cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
		
		for ( int i = 0; i<nLength; ++i ) 
		{
			aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
			aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
		}
		
		m_xCompressedDocumentHandler->_startElement(aName, aAttributes);
	#endif	       		
       		
	}
		
	BufferNode* pBufferNode = addNewElementMarkBuffers();
        if (pBufferNode != NULL)
        {
		setCurrentBufferNode(pBufferNode);
	}
}
	
void SAL_CALL SAXEventKeeperImpl::endElement( const rtl::OUString& aName ) 
	throw (cssxs::SAXException, cssu::RuntimeException)
{
        sal_Bool bIsCurrent = m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement());
	        
        /*
         * If there is a following handler and no blocking now, then
         * forward this event
         */
	if ((m_pCurrentBlockingBufferNode == NULL) && 
	    (m_xNextHandler.is()) && 
	    (!m_bIsForwarding))
	{
		m_xNextHandler->endElement(aName);
	}
		
	if ((m_pCurrentBlockingBufferNode != NULL) || 
	    (m_pCurrentBufferNode != m_pRootBufferNode) || 
	    (!m_xXMLDocument->isCurrentElementEmpty()))
	{
        	if (!m_bIsForwarding)
        	{
		#ifndef _USECOMPRESSEDDOCUMENTHANDLER
			m_xDocumentHandler->endElement(aName);
		#else
			m_xCompressedDocumentHandler->_endElement(aName);
		#endif	       		
		}
				
        /*
        * If the current buffer node has not notified yet, and 
        * the current buffer node is waiting for the current element,
        * then let it notify.
        */
       	if (bIsCurrent && (m_pCurrentBufferNode != m_pRootBufferNode))
		{
			BufferNode* pOldCurrentBufferNode = m_pCurrentBufferNode;
			m_pCurrentBufferNode = (BufferNode*)m_pCurrentBufferNode->getParent();
			
			pOldCurrentBufferNode->setReceivedAll();
				
			if ((m_pCurrentBufferNode == m_pRootBufferNode) && 
			    m_xSAXEventKeeperStatusChangeListener.is())
			{
				m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_False);
			}
		}
    }
    else
    {
        if (!m_bIsForwarding)
        {
            m_xXMLDocument->removeCurrentElement();
        }
    }
}
	
void SAL_CALL SAXEventKeeperImpl::characters( const rtl::OUString& aChars )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	if (!m_bIsForwarding)
	{
		if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
		{
			m_xNextHandler->characters(aChars);
		}
		
		if ((m_pCurrentBlockingBufferNode != NULL) || 
		    (m_pCurrentBufferNode != m_pRootBufferNode))
		{
		#ifndef _USECOMPRESSEDDOCUMENTHANDLER
        		m_xDocumentHandler->characters(aChars);
		#else
			m_xCompressedDocumentHandler->_characters(aChars);
		#endif	       		
        	}
        }
}
	
void SAL_CALL SAXEventKeeperImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	characters( aWhitespaces );
}
	
void SAL_CALL SAXEventKeeperImpl::processingInstruction( 
	const rtl::OUString& aTarget, const rtl::OUString& aData )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	if (!m_bIsForwarding)
	{
		if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
		{
			m_xNextHandler->processingInstruction(aTarget, aData);
		}
		
		if ((m_pCurrentBlockingBufferNode != NULL) || 
		    (m_pCurrentBufferNode != m_pRootBufferNode))
		{
		#ifndef _USECOMPRESSEDDOCUMENTHANDLER
			m_xDocumentHandler->processingInstruction(aTarget, aData);
		#else
			m_xCompressedDocumentHandler->_processingInstruction(aTarget, aData);
		#endif	       		
        	}
        }
}
	
void SAL_CALL SAXEventKeeperImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >&)
	throw (cssxs::SAXException, cssu::RuntimeException)
{
}
	
/* XInitialization */
void SAL_CALL SAXEventKeeperImpl::initialize( const cssu::Sequence< cssu::Any >& aArguments ) 
	throw (cssu::Exception, cssu::RuntimeException)
{
	OSL_ASSERT(aArguments.getLength() == 1);
	
	aArguments[0] >>= m_xXMLDocument;
	m_xDocumentHandler = cssu::Reference< cssxs::XDocumentHandler >( 
		m_xXMLDocument, cssu::UNO_QUERY );
	m_xCompressedDocumentHandler = cssu::Reference< cssxcsax::XCompressedDocumentHandler >( 
		m_xXMLDocument, cssu::UNO_QUERY );
	
	m_pRootBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
	m_pCurrentBufferNode = m_pRootBufferNode;
}
	
rtl::OUString SAXEventKeeperImpl_getImplementationName ()
	throw (cssu::RuntimeException)
{
	return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
}

sal_Bool SAL_CALL SAXEventKeeperImpl_supportsService( const rtl::OUString& ServiceName ) 
	throw (cssu::RuntimeException)
{
	return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
}

cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl_getSupportedServiceNames(  ) 
	throw (cssu::RuntimeException)
{
	cssu::Sequence < rtl::OUString > aRet(1);
	rtl::OUString* pArray = aRet.getArray();
	pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
	return aRet;
}
#undef SERVICE_NAME

cssu::Reference< cssu::XInterface > SAL_CALL SAXEventKeeperImpl_createInstance( 
	const cssu::Reference< cssl::XMultiServiceFactory > &)
	throw( cssu::Exception )
{
	return (cppu::OWeakObject*) new SAXEventKeeperImpl();
}

/* XServiceInfo */
rtl::OUString SAL_CALL SAXEventKeeperImpl::getImplementationName(  ) 
	throw (cssu::RuntimeException)
{
	return SAXEventKeeperImpl_getImplementationName();
}
sal_Bool SAL_CALL SAXEventKeeperImpl::supportsService( const rtl::OUString& rServiceName ) 
	throw (cssu::RuntimeException)
{
	return SAXEventKeeperImpl_supportsService( rServiceName );
}
cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl::getSupportedServiceNames(  ) 
	throw (cssu::RuntimeException)
{
	return SAXEventKeeperImpl_getSupportedServiceNames();
}

