/**************************************************************
 *
 * 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 "elementmark.hxx"
#include "elementcollector.hxx"
#include "buffernode.hxx"
#include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp>

namespace cssu = com::sun::star::uno;
namespace cssxw = com::sun::star::xml::wrapper;
namespace cssxc = com::sun::star::xml::crypto;

BufferNode::BufferNode( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
	:m_pParent(NULL),
	 m_pBlocker(NULL),
	 m_bAllReceived(false),
     m_xXMLElement(xXMLElement)
{
}

bool BufferNode::isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId) const
/****** BufferNode/isECOfBeforeModifyIncluded ********************************
 *
 *   NAME
 *	isECOfBeforeModifyIncluded -- checks whether there is some
 *	ElementCollector on this BufferNode, that has BEFORE-MODIFY priority.
 *
 *   SYNOPSIS
 *	bExist = isECOfBeforeModifyIncluded(nIgnoredSecurityId);
 *
 *   FUNCTION
 *	checks each ElementCollector on this BufferNode, if all following
 *	conditions are satisfied, then returns true:
 *	1. the ElementCollector's priority is BEFOREMODIFY;
 *	2. the ElementCollector's securityId can't be ignored.
 *	otherwise, returns false.
 *
 *   INPUTS
 *	nIgnoredSecurityId -	the security Id to be ignored. If it equals
 *	                        to UNDEFINEDSECURITYID, then no security Id
 *	                    	will be ignored.
 *
 *   RESULT
 *	bExist - true if a match found, false otherwise
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = false;
	std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();

	for( ; ii != m_vElementCollectors.end() ; ++ii )
	{
		ElementCollector* pElementCollector = (ElementCollector*)*ii;

		if ((nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
		 	pElementCollector->getSecurityId() != nIgnoredSecurityId) &&
		    (pElementCollector->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY))
		{
			rc = true;
			break;
		}
	}

	return rc;
}

void BufferNode::setReceivedAll()
/****** BufferNode/setReceiveAll *********************************************
 *
 *   NAME
 *	setReceivedAll -- indicates that the element in this BufferNode has
 *	been compeletely bufferred.
 *
 *   SYNOPSIS
 *	setReceivedAll();
 *
 *   FUNCTION
 *	sets the all-received flag and launches ElementCollector's notify
 *	process.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	m_bAllReceived = true;
	elementCollectorNotify();
}

bool BufferNode::isAllReceived() const
{
	return m_bAllReceived;
}

void BufferNode::addElementCollector(const ElementCollector* pElementCollector)
/****** BufferNode/addElementCollector ***************************************
 *
 *   NAME
 *	addElementCollector -- adds a new ElementCollector to this BufferNode.
 *
 *   SYNOPSIS
 *	addElementCollector(pElementCollector);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pElementCollector - the ElementCollector to be added
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	m_vElementCollectors.push_back( pElementCollector );
	((ElementCollector*)pElementCollector)->setBufferNode(this);
}

void BufferNode::removeElementCollector(const ElementCollector* pElementCollector)
/****** BufferNode/removeElementCollector ************************************
 *
 *   NAME
 *	removeElementCollector -- removes an ElementCollector from this
 *	BufferNode.
 *
 *   SYNOPSIS
 *	removeElementCollector(pElementCollector);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pElementCollector - the ElementCollector to be removed
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	std::vector< const ElementCollector* >::iterator ii = m_vElementCollectors.begin();

	for( ; ii != m_vElementCollectors.end() ; ++ii )
	{
		if( *ii == pElementCollector )
		{
			m_vElementCollectors.erase( ii );
			((ElementCollector*)pElementCollector)->setBufferNode(NULL);
			break;
		}
	}
}

ElementMark* BufferNode::getBlocker() const
{
	return m_pBlocker;
}

void BufferNode::setBlocker(const ElementMark* pBlocker)
/****** BufferNode/setBlocker ************************************************
 *
 *   NAME
 *	setBlocker -- adds a blocker to this BufferNode.
 *
 *   SYNOPSIS
 *	setBlocker(pBlocker);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pBlocker - the new blocker to be attached
 *
 *   RESULT
 *	empty
 *
 *   NOTES
 *	Because there is only one blocker permited for a BufferNode, so the
 *	old blocker on this BufferNode, if there is one, will be overcasted.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	OSL_ASSERT(!(m_pBlocker != NULL && pBlocker != NULL));

	m_pBlocker = (ElementMark*)pBlocker;
	if (m_pBlocker != NULL)
	{
		m_pBlocker->setBufferNode(this);
	}
}

rtl::OUString BufferNode::printChildren() const
/****** BufferNode/printChildren *********************************************
 *
 *   NAME
 *	printChildren -- prints children information into a string.
 *
 *   SYNOPSIS
 *	result = printChildren();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	result - the information string
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	rtl::OUString rc;
	std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();

	for( ; ii != m_vElementCollectors.end() ; ++ii )
	{
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BufID=" ));
		rc += rtl::OUString::valueOf((*ii)->getBufferId());

		if (((ElementCollector*)(*ii))->getModify())
		{
			rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[M]" ));
		}

		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ",Pri=" ));

		switch (((ElementCollector*)(*ii))->getPriority())
		{
			case cssxc::sax::ElementMarkPriority_BEFOREMODIFY:
				rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BEFOREMODIFY" ));
				break;
			case cssxc::sax::ElementMarkPriority_AFTERMODIFY:
				rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFTERMODIFY" ));
				break;
			default:
				rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNKNOWN" ));
				break;
		}

		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(" ));
		/*
		if (((ElementCollector*)(*ii))->isInternalNotificationSuppressed())
		{
			rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*IN-Suppressed* " ));
		}
		*/
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SecID=" ));
		rc += rtl::OUString::valueOf(((ElementCollector*)(*ii))->getSecurityId());
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ));
		rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
	}

	return rc;
}

bool BufferNode::hasAnything() const
/****** BufferNode/hasAnything ***********************************************
 *
 *   NAME
 *	hasAnything -- checks whether there is any ElementCollector or blocker
 *	on this BufferNode.
 *
 *   SYNOPSIS
 *	bExist = hasAnything();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	bExist - true if there is, false otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	return (m_pBlocker != NULL || m_vElementCollectors.size() > 0);
}

bool BufferNode::hasChildren() const
/****** BufferNode/hasChildren ***********************************************
 *
 *   NAME
 *	hasChildren -- checks whether this BufferNode has any child
 *	BufferNode.
 *
 *   SYNOPSIS
 *	bExist = hasChildren();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	bExist - true if there is, false otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	return (m_vChildren.size() > 0);
}

std::vector< const BufferNode* >* BufferNode::getChildren() const
{
	return new std::vector< const BufferNode* >( m_vChildren );
}

const BufferNode* BufferNode::getFirstChild() const
/****** BufferNode/getFirstChild *********************************************
 *
 *   NAME
 *	getFirstChild -- retrieves the first child BufferNode.
 *
 *   SYNOPSIS
 *	child = getFirstChild();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	child -	the first child BufferNode, or NULL if there is no child
 *	       	BufferNode.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* rc = NULL;

	if (m_vChildren.size() > 0)
	{
		rc = (BufferNode*)m_vChildren.front();
	}

	return (const BufferNode*)rc;
}

void BufferNode::addChild(const BufferNode* pChild, sal_Int32 nPosition)
/****** BufferNode/addChild(pChild,nPosition) ********************************
 *
 *   NAME
 *	addChild -- inserts a child BufferNode at specific position.
 *
 *   SYNOPSIS
 *	addChild(pChild, nPosition);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pChild - 	the child BufferNode to be added.
 *	nPosition -	the position where the new child locates.
 *
 *   RESULT
 *	empty
 *
 *   NOTES
 *	If the nPosition is -1, then the new child BufferNode is appended
 *	at the end.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (nPosition == -1)
	{
		m_vChildren.push_back( pChild );
	}
	else
	{
		std::vector< const BufferNode* >::iterator ii = m_vChildren.begin();
		ii += nPosition;
		m_vChildren.insert(ii, pChild);
	}
}

void BufferNode::addChild(const BufferNode* pChild)
/****** BufferNode/addChild() ************************************************
 *
 *   NAME
 *	addChild -- add a new child BufferNode.
 *
 *   SYNOPSIS
 *	addChild(pChild);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pChild - 	the child BufferNode to be added.
 *
 *   RESULT
 *	empty
 *
 *   NOTES
 *	The new child BufferNode is appended at the end.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	addChild(pChild, -1);
}

void BufferNode::removeChild(const BufferNode* pChild)
/****** BufferNode/removeChild ***********************************************
 *
 *   NAME
 *	removeChild -- removes a child BufferNode from the children list.
 *
 *   SYNOPSIS
 *	removeChild(pChild);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pChild - the child BufferNode to be removed
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	std::vector< const BufferNode* >::iterator ii = m_vChildren.begin();

	for( ; ii != m_vChildren.end() ; ++ii )
	{
		if( *ii == pChild )
		{
			m_vChildren.erase( ii );
			break;
		}
	}
}

sal_Int32 BufferNode::indexOfChild(const BufferNode* pChild) const
/****** BufferNode/indexOfChild **********************************************
 *
 *   NAME
 *	indexOfChild -- gets the index of a child BufferNode.
 *
 *   SYNOPSIS
 *	index = indexOfChild(pChild);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pChild - the child BufferNode whose index to be gotten
 *
 *   RESULT
 *	index -	the index of that child BufferNode. If that child BufferNode
 *	       	is not found, -1 is returned.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	sal_Int32 nIndex = 0;
	bool bFound = false;

	std::vector< const BufferNode * >::const_iterator ii = m_vChildren.begin();

	for( ; ii != m_vChildren.end() ; ++ii )
	{
		if( *ii == pChild )
		{
			bFound = true;
			break;
		}
		nIndex++;
	}

	if (!bFound )
	{
		nIndex = -1;
	}

	return nIndex;
}

const BufferNode* BufferNode::childAt(sal_Int32 nIndex) const
/****** BufferNode/childAt ***************************************************
 *
 *   NAME
 *	childAt -- retrieves the child BufferNode at specific position.
 *
 *   SYNOPSIS
 *	child = childAt(nIndex);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	nIndex - the index of the child BufferNode to be retrieved
 *
 *   RESULT
 *	child -	the child BufferNode at index position, or NULL if the index
 *	       	is out of the range of children.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* rc = NULL;

	if (nIndex < ((sal_Int32)m_vChildren.size()) && nIndex >= 0)
	{
		rc = (BufferNode*)m_vChildren[nIndex];
	}

	return (const BufferNode*)rc;
}

const BufferNode* BufferNode::getParent() const
{
	return m_pParent;
}

void BufferNode::setParent(const BufferNode* pParent)
{
	m_pParent = (BufferNode*)pParent;
}

const BufferNode* BufferNode::getNextSibling() const
/****** BufferNode/getNextSibling ********************************************
 *
 *   NAME
 *	getNextSibling -- retrieves the next sibling BufferNode.
 *
 *   SYNOPSIS
 *	sibling = getNextSibling();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	sibling - the next sibling BufferNode, or NULL if there is none.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* rc = NULL;

	if (m_pParent != NULL)
	{
		rc = (BufferNode*)m_pParent->getNextChild(this);
	}

	return (const BufferNode*)rc;
}

const BufferNode* BufferNode::isAncestor(const BufferNode* pDescendant) const
/****** BufferNode/isAncestor ************************************************
 *
 *   NAME
 *	isAncestor -- checks whether this BufferNode is an ancestor of another
 *	BufferNode.
 *
 *   SYNOPSIS
 *	bIs = isAncestor(pDescendant);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pDescendant -	the BufferNode to be checked as a descendant
 *
 *   RESULT
 *	bIs -	true if this BufferNode is an ancestor of the pDescendant,
 *	     	false otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* rc = NULL;

	if (pDescendant != NULL)
	{
		std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();

		for( ; ii != m_vChildren.end() ; ++ii )
		{
			BufferNode* pChild = (BufferNode*)*ii;

			if (pChild == pDescendant)
			{
				rc = pChild;
				break;
			}

			if (pChild->isAncestor(pDescendant) != NULL)
			{
				rc = pChild;
				break;
			}
		}
	}

	return (const BufferNode*)rc;
}

bool BufferNode::isPrevious(const BufferNode* pFollowing) const
/****** BufferNode/isPrevious ************************************************
 *
 *   NAME
 *	isPrevious -- checks whether this BufferNode is ahead of another
 *	BufferNode in the tree order.
 *
 *   SYNOPSIS
 *	bIs = isPrevious(pFollowing);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pFollowing -	the BufferNode to be checked as a following
 *
 *   RESULT
 *	bIs -	true if this BufferNode is ahead in the tree order, false
 *	     	otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = false;

	BufferNode* pNextBufferNode = (BufferNode*)getNextNodeByTreeOrder();
	while (pNextBufferNode != NULL)
	{
		if (pNextBufferNode == pFollowing)
		{
			rc = true;
			break;
		}

		pNextBufferNode = (BufferNode*)(pNextBufferNode->getNextNodeByTreeOrder());
	}

	return rc;
}

const BufferNode* BufferNode::getNextNodeByTreeOrder() const
/****** BufferNode/getNextNodeByTreeOrder ************************************
 *
 *   NAME
 *	getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree
 *	order.
 *
 *   SYNOPSIS
 *	next = getNextNodeByTreeOrder();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	next -	the BufferNode following this BufferNode in the tree order,
 *	      	or NULL if there is none.
 *
 *   NOTES
 *	The "next" node in tree order is defined as:
 *	1. If a node has children, then the first child is;
 *	2. otherwise, if it has a following sibling, then this sibling node is;
 *	3. otherwise, if it has a parent node, the parent's next sibling
 *	   node is;
 *	4. otherwise, no "next" node exists.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
        /*
         * If this buffer node has m_vChildren, then return the first
         * child.
         */
	if (hasChildren())
	{
		return getFirstChild();
	}

        /*
         * Otherwise, it this buffer node has a following sibling,
         * then return that sibling.
         */
	BufferNode* pNextSibling = (BufferNode*)getNextSibling();
	if (pNextSibling != NULL)
	{
		return pNextSibling;
	}

        /*
         * Otherwise, it this buffer node has parent, then return
         * its parent's following sibling.
         */
        BufferNode* pNode = (BufferNode*)this;
	BufferNode* pParent;
	BufferNode* pNextSiblingParent = NULL;

	do
	{
		if (pNode == NULL)
		{
			break;
		}

		pParent = (BufferNode*)pNode->getParent();
		if (pParent != NULL)
		{
			pNextSiblingParent = (BufferNode*)pParent->getNextSibling();
		}
		pNode = pParent;

	}while (pNextSiblingParent == NULL);

	return pNextSiblingParent;
}

cssu::Reference< cssxw::XXMLElementWrapper > BufferNode::getXMLElement() const
{
	return m_xXMLElement;
}

void BufferNode::setXMLElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
{
	m_xXMLElement = xXMLElement;
}

void BufferNode::notifyBranch()
/****** BufferNode/notifyBranch **********************************************
 *
 *   NAME
 *	notifyBranch -- notifies each BufferNode in the branch of this
 *	BufferNode in the tree order.
 *
 *   SYNOPSIS
 *	notifyBranch();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();

	for( ; ii != m_vChildren.end() ; ++ii )
	{
		BufferNode* pBufferNode = (BufferNode*)*ii;
		pBufferNode->elementCollectorNotify();
		pBufferNode->notifyBranch();
	}
}

void BufferNode::notifyAncestor()
/****** BufferNode/notifyAncestor ********************************************
 *
 *   NAME
 *	notifyAncestor -- notifies each ancestor BufferNode through the parent
 *	link.
 *
 *   SYNOPSIS
 *	notifyAncestor();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* pParent = m_pParent;
	while (pParent != NULL)
	{
		pParent->notifyAncestor();
		pParent = (BufferNode*)pParent->getParent();
	}
}

void BufferNode::elementCollectorNotify()
/****** BufferNode/elementCollectorNotify ************************************
 *
 *   NAME
 *	elementCollectorNotify -- notifies this BufferNode.
 *
 *   SYNOPSIS
 *	elementCollectorNotify();
 *
 *   FUNCTION
 *	Notifies this BufferNode if the notification is not suppressed.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	child -	the first child BufferNode, or NULL if there is no child
 *	       	BufferNode.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (m_vElementCollectors.size()>0)
	{
		cssxc::sax::ElementMarkPriority nMaxPriority = cssxc::sax::ElementMarkPriority_MINIMUM;
		cssxc::sax::ElementMarkPriority nPriority;

		/*
		 * get the max priority among ElementCollectors on this BufferNode
		 */
		std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
		for( ; ii != m_vElementCollectors.end() ; ++ii )
		{
			ElementCollector* pElementCollector = (ElementCollector*)*ii;
			nPriority = pElementCollector->getPriority();
			if (nPriority > nMaxPriority)
			{
				nMaxPriority = nPriority;
			}
		}

		std::vector< const ElementCollector* > vElementCollectors( m_vElementCollectors );
		ii = vElementCollectors.begin();

		for( ; ii != vElementCollectors.end() ; ++ii )
		{
			ElementCollector* pElementCollector = (ElementCollector*)*ii;
			nPriority = pElementCollector->getPriority();
			bool bToModify = pElementCollector->getModify();

			/*
			 * Only ElementCollector with the max priority can
			 * perform notify operation.
			 * Moreover, if any blocker exists in the subtree of
			 * this BufferNode, this ElementCollector can't do notify
			 * unless its priority is BEFOREMODIFY.
			 */
			if (nPriority == nMaxPriority &&
				(nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY ||
				 !isBlockerInSubTreeIncluded(pElementCollector->getSecurityId())))
			{
				/*
				 * If this ElementCollector will modify the bufferred element, then
				 * special attention must be paid.
				 *
				 * If there is any ElementCollector in the subtree or any ancestor
				 * ElementCollector with PRI_BEFPREMODIFY priority, this
				 * ElementCollector can't perform notify operation, otherwise, it
				 * will destroy the bufferred element, in turn, ElementCollectors
				 * mentioned above can't perform their mission.
				 */
				//if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY &&
				if (!(bToModify &&
				     (isECInSubTreeIncluded(pElementCollector->getSecurityId()) ||
				      isECOfBeforeModifyInAncestorIncluded(pElementCollector->getSecurityId()))
				   ))
				{
					pElementCollector->notifyListener();
				}
			}
		}
	}
}

bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
/****** BufferNode/isECInSubTreeIncluded *************************************
 *
 *   NAME
 *	isECInSubTreeIncluded -- checks whether there is any ElementCollector
 *	in the branch of this BufferNode.
 *
 *   SYNOPSIS
 *	bExist = isECInSubTreeIncluded(nIgnoredSecurityId);
 *
 *   FUNCTION
 *	checks each BufferNode in the branch of this BufferNode, if there is
 *	an ElementCollector whose signatureId is not ignored, then return
 *	true, otherwise, false returned.
 *
 *   INPUTS
 *	nIgnoredSecurityId -	the security Id to be ignored. If it equals
 *	                        to UNDEFINEDSECURITYID, then no security Id
 *	                    	will be ignored.
 *
 *   RESULT
 *	bExist - true if a match found, false otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = false;

	std::vector< const ElementCollector* >::const_iterator jj = m_vElementCollectors.begin();

	for( ; jj != m_vElementCollectors.end() ; ++jj )
	{
		ElementCollector* pElementCollector = (ElementCollector*)*jj;
		if (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
		 	pElementCollector->getSecurityId() != nIgnoredSecurityId)
		{
			rc = true;
			break;
		}
	}

	if ( !rc )
	{
		std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();

		for( ; ii != m_vChildren.end() ; ++ii )
		{
			BufferNode* pBufferNode = (BufferNode*)*ii;

			if ( pBufferNode->isECInSubTreeIncluded(nIgnoredSecurityId))
			{
				rc = true;
				break;
			}
		}
	}

	return rc;
}

bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const
/****** BufferNode/isECOfBeforeModifyInAncestorIncluded **********************
 *
 *   NAME
 *	isECOfBeforeModifyInAncestorIncluded -- checks whether there is some
 *	ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY
 *	priority.
 *
 *   SYNOPSIS
 *	bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId);
 *
 *   FUNCTION
 *	checks each ancestor BufferNode through the parent link, if there is
 *	an ElementCollector with PRI_BEFPREMODIFY priority and its
 *	signatureId is not ignored, then return true, otherwise, false
 *	returned.
 *
 *   INPUTS
 *	nIgnoredSecurityId -	the security Id to be ignored. If it equals
 *	                        to UNDEFINEDSECURITYID, then no security Id
 *	                    	will be ignored.
 *
 *   RESULT
 *	bExist - true if a match found, false otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = false;

	BufferNode* pParentNode = m_pParent;
	while (pParentNode != NULL)
	{
		if (pParentNode->isECOfBeforeModifyIncluded(nIgnoredSecurityId))
		{
			rc = true;
			break;
		}

		pParentNode = (BufferNode*)pParentNode->getParent();
	}

	return rc;
}

bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
/****** BufferNode/isBlockerInSubTreeIncluded ********************************
 *
 *   NAME
 *	isBlockerInSubTreeIncluded -- checks whether there is some BufferNode
 *	which has blocker on it
 *
 *   SYNOPSIS
 *	bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId);
 *
 *   FUNCTION
 *	checks each BufferNode in the branch of this BufferNode, if one has
 *	a blocker on it, and the blocker's securityId is not ignored, then
 *	returns true; otherwise, false returns.
 *
 *   INPUTS
 *	nIgnoredSecurityId -	the security Id to be ignored. If it equals
 *	                        to UNDEFINEDSECURITYID, then no security Id
 *	                    	will be ignored.
 *
 *   RESULT
 *	bExist - true if a match found, false otherwise.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = false;

	std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();

	for( ; ii != m_vChildren.end() ; ++ii )
	{
		BufferNode* pBufferNode = (BufferNode*)*ii;
		ElementMark* pBlocker = pBufferNode->getBlocker();

		if (pBlocker != NULL &&
			(nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
			pBlocker->getSecurityId() != nIgnoredSecurityId ))
		{
			rc = true;
			break;
		}

		if (rc || pBufferNode->isBlockerInSubTreeIncluded(nIgnoredSecurityId))
		{
			rc = true;
			break;
		}
	}

	return rc;
}

const BufferNode* BufferNode::getNextChild(const BufferNode* pChild) const
/****** BufferNode/getNextChild **********************************************
 *
 *   NAME
 *	getNextChild -- get the next child BufferNode.
 *
 *   SYNOPSIS
 *	nextChild = getNextChild();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pChild - the child BufferNode whose next node is retrieved.
 *
 *   RESULT
 *	nextChild -	the next child BufferNode after the pChild, or NULL if
 *	there is none.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	BufferNode* rc = NULL;
	bool bChildFound = false;

	std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
	for( ; ii != m_vChildren.end() ; ++ii )
	{
		if (bChildFound)
		{
			rc = (BufferNode*)*ii;
			break;
		}

		if( *ii == pChild )
		{
			bChildFound = true;
		}
	}

	return (const BufferNode*)rc;
}


void BufferNode::freeAllChildren()
/****** BufferNode/freeAllChildren *******************************************
 *
 *   NAME
 *	freeAllChildren -- free all his child BufferNode.
 *
 *   SYNOPSIS
 *	freeAllChildren();
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	30.03.2004 -	the correct the memory leak bug
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
	for( ; ii != m_vChildren.end() ; ++ii )
	{
		BufferNode *pChild = (BufferNode *)(*ii);
		pChild->freeAllChildren();
		delete pChild;
	}

	m_vChildren.clear();
}
