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

/*
 * XSEC
 *
 * XSECC14n20010315 := Canonicaliser object to process XML document in line with
 *					     RFC 3076
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

//XSEC includes
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/canon/XSECC14n20010315.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>
#include <xsec/utils/XSECSafeBufferFormatter.hpp>

// Xerces includes
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_USE

#ifdef XSEC_HAVE_XALAN

// Xalan includes
#include <xalanc/XalanDOM/XalanDocument.hpp>
#include <xalanc/XercesParserLiaison/XercesDocumentWrapper.hpp>
#include <xalanc/XercesParserLiaison/XercesDOMSupport.hpp>
#include <xalanc/XercesParserLiaison/XercesParserLiaison.hpp>
#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XPath/NodeRefList.hpp>

// Namespace definitions
XALAN_USING_XALAN(XPathEvaluator)
XALAN_USING_XALAN(XercesDOMSupport)
XALAN_USING_XALAN(XercesParserLiaison)
XALAN_USING_XALAN(XalanDocument)
XALAN_USING_XALAN(XalanNode)
XALAN_USING_XALAN(XalanElement)
XALAN_USING_XALAN(XalanDOMString)
XALAN_USING_XALAN(XalanDOMChar)
XALAN_USING_XALAN(NodeRefList)
XALAN_USING_XALAN(XercesDocumentWrapper)
XALAN_USING_XALAN(XercesWrapperNavigator)
XALAN_USING_XALAN(c_wstr)

#endif

// General includes
#include <stdlib.h>
#include <string.h>

#include <iostream>


// --------------------------------------------------------------------------------
//           Some useful utilities
// --------------------------------------------------------------------------------

// Find a node in an XSECNodeList

bool NodeInList(const XSECNodeListElt * lst, const DOMNode * toFind) {

	const XSECNodeListElt * tmp = lst;

	while (tmp != NULL) {

		if (tmp->element == toFind)
			return true;

		tmp = tmp->next;

	}

	return false;

}

XSECNodeListElt * insertNodeIntoList(XSECNodeListElt * lst, XSECNodeListElt *toIns) {

	XSECNodeListElt *tmp, *last;

	if (lst == NULL) {

		// Goes at start
		toIns->next = NULL;
		toIns->last = NULL;

		return toIns;

	} /* if mp_attributes == NULL */

	// Need to run through start of list

	tmp = lst;
	last = NULL;
	int res = -1;   // Used to remove a gcc warning

	while ((tmp != NULL) &&
		((res = toIns->sortString.sbStrcmp(tmp->sortString)) >= 0)) {

		last = tmp;
		tmp = tmp->next;

	} /* while */

	if (res ==0) {

		// Already exists!
		delete toIns;
		return lst;

	}

	if (last == NULL) {

		// It sits before first element

		toIns->next = lst;
		toIns->last = NULL;
		lst->last = tmp;

		return toIns;

	} /* if last == NULL */

	// We have found where it goes

	toIns->next = tmp;
	toIns->last = last;

	if (tmp != NULL)
		tmp->last = toIns;

	last->next = toIns;

	return lst;

}

// --------------------------------------------------------------------------------
//           Exclusive Canonicalisation Methods
// --------------------------------------------------------------------------------


bool visiblyUtilises(DOMNode *node, safeBuffer &ns) {

	// Test whether the node uses the name space passed in

	if (strEquals(node->getPrefix(), (char *) ns.rawBuffer()))
		return true;

	if (ns.sbStrcmp("") == 0)
		return false;		// Attributes are never in default namespace

	// Check the attributes
	DOMNamedNodeMap *atts = node->getAttributes();
	if (atts == NULL)
		return false;

	XMLSize_t size = atts->getLength();

	for (XMLSize_t i = 0; i < size; ++i) {

		if (strEquals(atts->item(i)->getPrefix(), (char *) ns.rawBuffer()) &&
			!strEquals(atts->item(i)->getLocalName(), "xmlns"))
			return true;

	}

	return false;

}

bool XSECC14n20010315::inNonExclNSList(safeBuffer &ns) {

	int size = (int) m_exclNSList.size();

	for (int i = 0; i < size; ++i) {

		if (!strcmp((char *) ns.rawBuffer(), m_exclNSList[i]))
			return true;

	}

	return false;

}

void XSECC14n20010315::setInclusive11(void) {
    m_incl11 = true;
    m_exclusive = false;
    m_exclusiveDefault = false;
}

void XSECC14n20010315::setExclusive(void) {

	m_exclusive = true;
	m_exclusiveDefault = true;
	m_incl11 = false;
}

void XSECC14n20010315::setExclusive(char * xmlnsList) {

	char * nsBuf;

	setExclusive();

	// Set up the define non-exclusive prefixes

	nsBuf = new char [strlen(xmlnsList) + 1];

	if (nsBuf == NULL) {

		throw XSECException (XSECException::MemoryAllocationFail,
			"Error allocating a string buffer in XSECC14n20010315::setExclusive");

	}

	ArrayJanitor<char> j_nsBuf(nsBuf);

	int i, j;

	i = 0;

	while (xmlnsList[i] != '\0') {

		while (xmlnsList[i] == ' ' ||
			   xmlnsList[i] == '\t' ||
			   xmlnsList[i] == '\r' ||
			   xmlnsList[i] == '\n') {

			   ++i;	// Skip white space
		}

		j = 0;
		while (!(xmlnsList[i] == ' ' ||
			   xmlnsList[i] == '\0' ||
			   xmlnsList[i] == '\t' ||
			   xmlnsList[i] == '\r' ||
			   xmlnsList[i] == '\n')) {

			   nsBuf[j++] = xmlnsList[i++];	// Copy name
		}

		// Terminate the string
		nsBuf[j] = '\0';
		if (strcmp(nsBuf, "#default") == 0) {

			// Default is not to be exclusive
			m_exclusiveDefault = false;

		}

		else {

			// Add this to the list
			m_exclNSList.push_back(strdup(nsBuf));

		}

	}

}





// --------------------------------------------------------------------------------
//           XSECC14n20010315 methods
// --------------------------------------------------------------------------------


void XSECC14n20010315::stackInit(DOMNode * n) {

	if (n == NULL)
		return;

	stackInit(n->getParentNode());
	m_nsStack.pushElement(n);
	XMLSize_t size;

	DOMNamedNodeMap *tmpAtts = n->getAttributes();
	safeBuffer currentName;

	if (tmpAtts != NULL)
		size = tmpAtts->getLength();
	else
		size = 0;

	XMLSize_t i;

	for (i = 0; i < size; ++i) {

		currentName << (*mp_formatter << tmpAtts->item(i)->getNodeName());

		if (currentName.sbStrncmp("xmlns", 5) == 0)
			m_nsStack.addNamespace(tmpAtts->item(i));

	}

}


// Constructors

void XSECC14n20010315::init() {

	// This does the work of setting us up and checks to make sure everyhing is OK

	// Set up the Xerces formatter

	XSECnew(mp_formatter, XSECSafeBufferFormatter("UTF-8",XMLFormatter::NoEscapes,
												XMLFormatter::UnRep_CharRef));

	// Set up for first attribute list

	mp_attributes = mp_currentAttribute = mp_firstNonNsAttribute = NULL;

	// By default process comments
	m_processComments = true;

	// Set up for tree walking

	m_returnedFromChild = false;
	mp_firstElementNode = mp_startNode;
	m_firstElementProcessed = false;

	// XPath setup
	m_XPathSelection = false;
	m_XPathMap.clear();

	// Exclusive Canonicalisation setup

	m_exclNSList.clear();
	m_exclusive = false;
	m_exclusiveDefault = false;

	// Default to 1.0 mode
	m_incl11 = false;

	// Namespace handling
	m_useNamespaceStack = true;

	// INitialise the stack - even if we don't use it later, at least this sets us up
	if (mp_startNode != NULL) {
		stackInit(mp_startNode->getParentNode());
	}

}


XSECC14n20010315::XSECC14n20010315() {};
XSECC14n20010315::XSECC14n20010315(DOMDocument *newDoc) : XSECCanon(newDoc) {

	// Just call the init function;

	init();

};
XSECC14n20010315::XSECC14n20010315(DOMDocument *newDoc,
								   DOMNode *newStartNode) : XSECCanon(newDoc, newStartNode) {

	// Just call the init function

	init();

}

XSECC14n20010315::~XSECC14n20010315() {

	if (mp_formatter != NULL)
		delete mp_formatter;

	// Clear out the exclusive namespace list
	int size = (int) m_exclNSList.size();

	for (int i = 0; i < size; ++i) {

		free(m_exclNSList[i]);

	}

	m_exclNSList.clear();

    while (mp_attributes != NULL) {

        mp_currentAttribute = mp_attributes->next;
        delete mp_attributes;
        mp_attributes = mp_currentAttribute;
    }

    mp_attributes = mp_currentAttribute = mp_firstNonNsAttribute = NULL;
}

// --------------------------------------------------------------------------------
//           XSECC14n20010315 Comments procesing
// --------------------------------------------------------------------------------


void XSECC14n20010315::setCommentsProcessing(bool onoff) {

	m_processComments = onoff;

}

bool XSECC14n20010315::getCommentsProcessing(void) {

	return m_processComments;

}


// --------------------------------------------------------------------------------
//           XSECC14n20010315 XPathSelectNodes method
// --------------------------------------------------------------------------------

// Use an XPath expression to select a subset of nodes from the document


int XSECC14n20010315::XPathSelectNodes(const char * XPathExpr) {

#ifndef XSEC_HAVE_XPATH

	throw XSECException(XSECException::UnsupportedFunction,
		"This library has been compiled without XPath support");

#else

	XPathEvaluator::initialize();

	// We use Xalan to process the Xerces DOM tree and get the XPath nodes

	XercesParserLiaison theParserLiaison;
	XercesDOMSupport theDOMSupport(theParserLiaison);

	if (mp_doc == 0) {
		throw XSECException(XSECException::UnsupportedFunction,
			"XPath selection only supported in C14n for full documents");
	}

	DOMElement* theXercesNode = mp_doc->createElement(c_wstr(XalanDOMString("ns")));
	theXercesNode->setAttribute(c_wstr(XalanDOMString("xmlns:ietf")), c_wstr(XalanDOMString("http://www.ietf.org")));

	XalanDocument* theDoc = theParserLiaison.createDocument(mp_doc);

	// Set up the XPath evaluator

	XPathEvaluator	theEvaluator;

	// OK, let's find the context node...

	XalanDOMString cd = XalanDOMString("/");	// For the moment assume the root is the context

	const XalanDOMChar * cexpr = cd.c_str();

	XalanNode* const	theContextNode =
		theEvaluator.selectSingleNode(
		theDOMSupport,
		theDoc,
		cexpr,
		theDoc->getDocumentElement());

	if (theContextNode == 0)
	{

		// No appropriate nodes.
		return 0;

	}
	// OK, let's evaluate the expression...

	XalanDOMString ed = XalanDOMString(XPathExpr);
	const XalanDOMChar * expr = ed.c_str();

	NodeRefList output;

	NodeRefList theResult(
		theEvaluator.selectNodeList(
		output,
		theDOMSupport,
		theContextNode,
		expr,
		theDoc->getElementById(XalanDOMString("ns"))));


	XercesDocumentWrapper *theWrapper = theParserLiaison.mapDocumentToWrapper(theDoc);
	XercesWrapperNavigator theWrapperNavigator(theWrapper);

	int size = (int) theResult.getLength();
	const DOMNode *item;

	for (int i = 0; i < size; ++ i) {

		item = theWrapperNavigator.mapNode(theResult.item(i));
		m_XPathMap.addNode(item);
		//tmp->element = theBridgeNavigator.mapNode(theResult.item(i));
	}

	m_XPathSelection = true;
	return size;

#endif

}

void XSECC14n20010315::setXPathMap(const XSECXPathNodeList & map) {

	// XPath already done!

	m_XPathMap = map;
	m_XPathSelection = true;

}

// --------------------------------------------------------------------------------
//           XSECC14n20010315 processNextNode method
// --------------------------------------------------------------------------------

safeBuffer c14nCleanText(safeBuffer &input) {

	/* c14n Requires :

		& -> &amp
		< -> &lt
		> -> &gt
		LF -> &#xD

	*/

	XMLSize_t len = input.sbStrlen();
	safeBuffer ret;

	XMLSize_t i, j;
	unsigned char c;

	j = 0;
	for (i = 0; i < len; ++i) {

		c = input[i];

		switch (c) {

		case '&' :

			ret[j++] = '&';
			ret[j++] = 'a';
			ret[j++] = 'm';
			ret[j++] = 'p';
			ret[j++] = ';';

			break;

		case '<' :

			ret[j++] = '&';
			ret[j++] = 'l';
			ret[j++] = 't';
			ret[j++] = ';';

			break;

		case '>' :

			ret[j++] = '&';
			ret[j++] = 'g';
			ret[j++] = 't';
			ret[j++] = ';';

			break;

		case 0xD :

			ret[j++] = '&';
			ret[j++] = '#';
			ret[j++] = 'x';
			ret[j++] = 'D';
			ret[j++] = ';';

			break;

		default :

			ret[j++] = c;

		}

	}

	// final character:

	ret[j] = '\0';

	ret.setBufferType(safeBuffer::BUFFER_CHAR);

	return ret;

}

safeBuffer c14nCleanAttribute(safeBuffer &input) {

	/* c14n Requires :

		& -> &amp
		< -> &lt
		" -> &quot
		#x9 ->&#x9
		#xA ->&#xA
		LF -> &#xD

	*/

	XMLSize_t len = input.sbStrlen();
	safeBuffer ret;

	XMLSize_t i, j;
	unsigned char c;

	j = 0;
	for (i = 0; i < len; ++i) {

		c = input[i];

		switch (c) {

		case '&' :

			ret[j++] = '&';
			ret[j++] = 'a';
			ret[j++] = 'm';
			ret[j++] = 'p';
			ret[j++] = ';';

			break;

		case '"' :

			ret[j++] = '&';
			ret[j++] = 'q';
			ret[j++] = 'u';
			ret[j++] = 'o';
			ret[j++] = 't';
			ret[j++] = ';';

			break;

		case '<' :

			ret[j++] = '&';
			ret[j++] = 'l';
			ret[j++] = 't';
			ret[j++] = ';';

			break;

		case 0x9 :

			ret[j++] = '&';
			ret[j++] = '#';
			ret[j++] = 'x';
			ret[j++] = '9';
			ret[j++] = ';';

			break;

		case 0xA :

			ret[j++] = '&';
			ret[j++] = '#';
			ret[j++] = 'x';
			ret[j++] = 'A';
			ret[j++] = ';';

			break;

		case 0xD :

			ret[j++] = '&';
			ret[j++] = '#';
			ret[j++] = 'x';
			ret[j++] = 'D';
			ret[j++] = ';';

			break;

		default :

			ret[j++] = c;

		}

	}

	// final character:

	ret[j] = '\0';
	ret.setBufferType(safeBuffer::BUFFER_CHAR);

	return ret;

}

bool XSECC14n20010315::checkRenderNameSpaceNode(DOMNode *e, DOMNode *a) {

	DOMNode *parent;
	DOMNode *att;
	DOMNamedNodeMap *atts;

	// If XPath and node not selected, then never print
	if (m_XPathSelection && ! m_XPathMap.hasNode(a))
		return false;

	// BUGFIX: we need to skip xmlns:xml if the value is http://www.w3.org/XML/1998/namespace
	if (strEquals(a->getLocalName(), "xml") && strEquals(a->getNodeValue(), "http://www.w3.org/XML/1998/namespace"))
		return false;

	// First - are we exclusive?

	safeBuffer localName;
	bool processAsExclusive = false;

	if (m_exclusive) {

		if (strEquals(a->getNodeName(), "xmlns")) {
			processAsExclusive = m_exclusiveDefault;
		}
		else {
			localName << (*mp_formatter << a->getLocalName());
			processAsExclusive = !inNonExclNSList(localName);
		}

	}

	if (processAsExclusive) {

		// Is the parent in the  node-set?
		if (m_XPathSelection && !m_XPathMap.hasNode(e))
			return false;

		// Is the name space visibly utilised?
		localName << (*mp_formatter << a->getLocalName());

		if (localName.sbStrcmp("xmlns") == 0)
			localName[0] = '\0';			// Is this correct or should Xerces return "" for default?

		if (!visiblyUtilises(e, localName))
			return false;

		// If we are the top node, then this has never been printer
		if (e == mp_firstElementNode)
			return true;

		// Make sure previous nodes do not use the name space (and have it printed)
		parent = e->getParentNode();

		while (parent != NULL) {

			if (!m_XPathSelection || m_XPathMap.hasNode(parent)) {

				// An output ancestor
				if (visiblyUtilises(parent, localName)) {

					// Have a hit!
					while (parent != NULL) {
						atts = parent->getAttributes();
						att = (atts != NULL) ? atts->getNamedItem(a->getNodeName()) : NULL;
						if (att != NULL && (!m_XPathSelection || m_XPathMap.hasNode(att))) {

							// Check URI is the same
							if (strEquals(att->getNodeValue(), a->getNodeValue()))
								return false;

							return true;

						}

						// If we are using the namespace stack, we need to go up until
						// we found the defining attribute for this node
						if (m_useNamespaceStack) {
							parent = parent->getParentNode();
						}
						else

							return true;
					}
					// Even if we are using the namespace stack, we have never
					// printed this namespace
					return true;
				}
			}

			if (parent == mp_firstElementNode)
				parent = NULL;
			else
				parent = parent->getParentNode();

		}

		// Didn't find it rendered!
		return true;

	}

	// Either we are now in non-exclusive mode, or the name space in question
	// Is to be treated as non-exclusive

	// Never directly render a default
	if (strEquals(a->getNodeName(), "xmlns") && strEquals(a->getNodeValue(), ""))
		return false;

	// If using a namespace stack, then we need to check whether the current node is in the nodeset
	// Only really necessary for envelope txfms in boundary conditions

	if (m_useNamespaceStack && m_XPathSelection && !m_XPathMap.hasNode(e))
		return false;

	// Otherwise, of node is at base of selected document, then print
	if (e == mp_firstElementNode)
		return true;

	if (m_useNamespaceStack) {

		// In this case, we need to go up until we find the namespace definition
		// in question

		parent = e->getParentNode();
		while (parent != NULL) {

			if (!m_XPathSelection || m_XPathMap.hasNode(parent)) {
				DOMNamedNodeMap *pmap = parent->getAttributes();
				DOMNode *pns;
				if (pmap)
					pns = pmap->getNamedItem(a->getNodeName());
				else
					pns = NULL;

				if (pns != NULL) {

					// Note we don't check XPath inclusion, as we shouldn't be
					// using the namespace stack for XPath expressions

					if (strEquals(pns->getNodeValue(), a->getNodeValue()))
						return false;
					else
						return true;		// Was defined but differently
				}
			}
			parent = parent->getParentNode();
		}
		// Obviously we haven't found it!
		return true;
	}

	// Find the parent and check if the node is already defined or if the node
	// was out of scope
	parent = e->getParentNode();
//	if (m_XPathSelection && !m_XPathMap.hasNode(parent))
//		return true;

	while (m_XPathSelection && parent != NULL && !m_XPathMap.hasNode(parent))
		parent = parent->getParentNode();

	if (parent == NULL)
		return true;

	DOMNamedNodeMap *pmap = parent->getAttributes();

	DOMNode *pns = pmap->getNamedItem(a->getNodeName());

	if (pns != NULL) {

		if (m_XPathSelection && !m_XPathMap.hasNode(pns))
			return true;			// Not printed in previous node

		if (strEquals(pns->getNodeValue(), a->getNodeValue()))
			return false;
		else
			return true;		// Was defined but differently

	}

	return true;			// Not defined in previous node

}



	// Check an attribute to see if we should output


// This is the main worker function of this class

XMLSize_t XSECC14n20010315::processNextNode() {

	// The information currently in the buffer has all been used.  We now process the
	// next node.

	DOMNode *next;				// For working (had *ns)
	DOMNamedNodeMap *tmpAtts;	//  "     "
	safeBuffer currentName(128), currentValue(1024), sbWork;
	bool done, xmlnsFound;


	if (m_allNodesDone) {

		return 0;					// No bytes copied because nothing more to be done

	}

	// Always zeroise buffers to make work simpler
	m_bufferLength = m_bufferPoint = 0;
	m_buffer.sbStrcpyIn("");

	// Find out if this is a node to process
	bool processNode;
	int nodeT;

	if (mp_nextNode == 0) {

		// Dummy element - we need to insert a default namespace

		nodeT = DOMNode::ATTRIBUTE_NODE;
		processNode = true;

	}
	else {

		processNode = ((!m_XPathSelection) || (m_XPathMap.hasNode(mp_nextNode)));
		nodeT = mp_nextNode->getNodeType();

	}

	switch (nodeT) {

	case DOMNode::DOCUMENT_NODE : // Start of a document

		// Check if finished
		if (m_returnedFromChild) {

			// All done!
			m_allNodesDone = true;

			return 0;

		}

		// In c14n we don't actually do anything for a document node except
		// process the childeren

		mp_firstElementNode = ((DOMDocument *) mp_nextNode)->getDocumentElement();
		next = mp_nextNode->getFirstChild();

		if (next == NULL) {

			// Empty document?
			m_allNodesDone = true;

		}

		mp_nextNode = next;
		m_bufferLength = m_bufferPoint = 0;		// To ensure nobody copies "nothing"

		return 0;

	case DOMNode::DOCUMENT_TYPE_NODE : // Ignore me

		m_returnedFromChild = true;
		m_buffer.sbStrcpyIn("");
		break;

	case DOMNode::PROCESSING_INSTRUCTION_NODE : // Just print

		if (processNode) {
			if ((mp_nextNode->getParentNode() == mp_doc) && m_firstElementProcessed) {

				// this is a top level node and first element done
				m_buffer.sbStrcpyIn("\x00A<?");

			}
			else
				m_buffer.sbStrcpyIn("<?");

			m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeName());
			m_buffer.sbStrcatIn(m_formatBuffer);

			m_formatBuffer << (*mp_formatter << ((DOMProcessingInstruction *) mp_nextNode)->getData());
			if (m_formatBuffer.sbStrlen() > 0) {
				m_buffer.sbStrcatIn(" ");
				m_buffer.sbStrcatIn(m_formatBuffer);
			}

			m_buffer.sbStrcatIn("?>");

			if ((mp_nextNode->getParentNode() == mp_doc) && !m_firstElementProcessed) {

				// this is a top level node and first element done
				m_buffer.sbStrcatIn("\x00A");

			}
		}

		// Node fully processed
		m_returnedFromChild = true;

		break;


	case DOMNode::COMMENT_NODE : // Just print out

		if (processNode && m_processComments) {
			if ((mp_nextNode->getParentNode() == mp_doc) && m_firstElementProcessed) {

				// this is a top level node and first element done
				m_buffer.sbStrcpyIn("\x00A<!--");

			}
			else
				m_buffer.sbStrcpyIn("<!--");

			m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeValue());

			if (m_formatBuffer.sbStrlen() > 0) {
				m_buffer.sbStrcatIn(m_formatBuffer);
			}

			m_buffer.sbStrcatIn("-->");

			if ((mp_nextNode->getParentNode() == mp_doc) && !m_firstElementProcessed) {

				// this is a top level node and first element done
				m_buffer.sbStrcatIn("\x00A");

			}
		}

		m_returnedFromChild = true;	// Fool the tree processor

		break;

	case DOMNode::CDATA_SECTION_NODE :
	case DOMNode::TEXT_NODE : // Straight copy for now

		if (processNode) {
			m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeValue());

			// Do c14n cleaning on the text string

			m_buffer = c14nCleanText(m_formatBuffer);

		}

		// Fall through
		m_returnedFromChild = true;		// Fool the tree processor
		break;

	case DOMNode::ELEMENT_NODE : // This is an element that we can easily process

		// If we are going "up" then we simply close off the element

		if (m_returnedFromChild) {
			if (processNode) {
				m_buffer.sbStrcpyIn ("</");
				m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeName());
				m_buffer.sbStrcatIn(m_formatBuffer);
				m_buffer.sbStrcatIn(">");
			}

			if (m_useNamespaceStack)
				m_nsStack.popElement();

			break;
		}

		if (processNode) {

			m_buffer.sbStrcpyIn("<");
			m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeName());
			m_buffer.sbStrcatIn(m_formatBuffer);
		}

		// We now set up for attributes and name spaces
		if (m_useNamespaceStack)
			m_nsStack.pushElement(mp_nextNode);

		mp_attributes = NULL;
		tmpAtts = mp_nextNode->getAttributes();
		next = mp_nextNode;

		done = false;
		xmlnsFound = false;

		while (!done) {

			// Need to sort the attributes

			XMLSize_t size;

			if (tmpAtts != NULL)
				size = tmpAtts->getLength();
			else
				size = 0;

			XSECNodeListElt *toIns;
			XMLSize_t i;

			for (i = 0; i < size; ++i) {

				// Get the name and value of the attribute
				currentName << (*mp_formatter << tmpAtts->item(i)->getNodeName());
				currentValue << (*mp_formatter << tmpAtts->item(i)->getNodeValue());

				// Build the string used to sort this node

				if ((next == mp_nextNode) && currentName.sbStrncmp("xmlns", 5) == 0) {

					// Are we using the namespace stack?  If so - store this for later
					// processing
					if (m_useNamespaceStack) {
						m_nsStack.addNamespace(tmpAtts->item(i));
					}
					else {

						// Is this the default?
						if (currentName.sbStrcmp("xmlns") == 0 &&
							(!m_XPathSelection || m_XPathMap.hasNode(tmpAtts->item(i))) &&
							!currentValue.sbStrcmp("") == 0)
							xmlnsFound = true;

						// A namespace node - See if we need to output
						if (checkRenderNameSpaceNode(mp_nextNode, tmpAtts->item(i))) {

							// Add to the list

							m_formatBuffer << (*mp_formatter << tmpAtts->item(i)->getNodeName());
							if (m_formatBuffer[5] == ':')
								currentName.sbStrcpyIn((char *) &m_formatBuffer[6]);
							else
								currentName.sbStrcpyIn("");

							toIns = new XSECNodeListElt;
							toIns->element = tmpAtts->item(i);

							// Build and insert name space node
							toIns->sortString.sbStrcpyIn(XMLNS_PREFIX);
							toIns->sortString.sbStrcatIn(currentName);

							// Insert node
							mp_attributes = insertNodeIntoList(mp_attributes, toIns);

						}
					}

				}

				else {

					// A "normal" attribute - only process if selected or no XPath or is an
					// XML node from a previously un-printed Element node

					bool XMLElement = (next != mp_nextNode) && (!m_exclusive) && !currentName.sbStrncmp("xml:", 4) &&
                        (!m_incl11 || currentName.sbStrcmp("xml:id"));

					// If we have an XML element, make sure it was not printed between this
					// node and the node currently  being worked on

					if (XMLElement) {

						DOMNode *t = mp_nextNode->getParentNode();
						if (m_XPathSelection && m_XPathMap.hasNode(t))
							XMLElement = false;
						else {

							// This is a real node that we have to check

							t = mp_nextNode;
							while (t != next) {
								DOMNamedNodeMap *ta;
								XMLSize_t sz;

								ta = t->getAttributes();

								if (ta != NULL)
									sz = ta->getLength();
								else
									sz = 0;

								for (XMLSize_t j = 0; j < sz; ++j) {

									if (strEquals(ta->item(j)->getNodeName(),
										tmpAtts->item(i)->getNodeName()) == true) {

										XMLElement = false;
										break;

									}

								}

								t = t->getParentNode();

							}

						}

					}



					if ((!m_XPathSelection && next == mp_nextNode) || XMLElement || ((next == mp_nextNode) && m_XPathMap.hasNode(tmpAtts->item(i)))) {

						toIns = new XSECNodeListElt;
						toIns->element = tmpAtts->item(i);

						// First the correct prefix to ensure will be sorted
						// in correct placing against XMLNS nodes

						toIns->sortString.sbStrcpyIn(ATTRIBUTE_PREFIX);

						// Find the namespace URI
						const XMLCh * nsURI =
							tmpAtts->item(i)->getNamespaceURI();

						if (nsURI == NULL) {
							toIns->sortString.sbStrcatIn(NOURI_PREFIX);
						}
						else {
							m_formatBuffer << (*mp_formatter << nsURI);
							toIns->sortString.sbStrcatIn(HAVEURI_PREFIX);
							toIns->sortString.sbStrcatIn(m_formatBuffer);
						}

						// Append the local name as the secondary key
						const XMLCh * ln = tmpAtts->item(i)->getNodeName();
						int index = XMLString::indexOf(ln, chColon);
						if (index >= 0)
							ln = &ln[index+1];
						m_formatBuffer << (*mp_formatter << ln);
						toIns->sortString.sbStrcatIn(m_formatBuffer);

						// Insert node
						mp_attributes = insertNodeIntoList(mp_attributes, toIns);

					} /* else (sbStrCmp xmlns) */
				}
			} /* for */
#if 1
			// Now go upwards and find parent for xml name spaces
			if (processNode && (m_XPathSelection || mp_nextNode == mp_firstElementNode)) {
				next = next->getParentNode();

				if (next == 0) // || NodeInList(mp_XPathMap, next))
					done = true;
				else
					tmpAtts = next->getAttributes();
			}
			else
#endif
				done = true;

		} /* while tmpAtts != NULL */

		// Now add namespace nodes - but only if we are using the namespace stack
		// (They have already been added otherwise
		if (m_useNamespaceStack) {

			DOMNode * nsnode = m_nsStack.getFirstNamespace();
			while (nsnode != NULL) {
				// Get the name and value of the attribute
				currentName << (*mp_formatter << nsnode->getNodeName());
				currentValue << (*mp_formatter << nsnode->getNodeValue());

				// Is this the default?
				if (currentName.sbStrcmp("xmlns") == 0 &&
					(!m_XPathSelection || m_XPathMap.hasNode(nsnode)) &&
					!currentValue.sbStrcmp("") == 0)
					xmlnsFound = true;

				// A namespace node - See if we need to output
				if (checkRenderNameSpaceNode(mp_nextNode, nsnode)) {

					// Add to the list
					XSECNodeListElt *toIns;

					m_formatBuffer << (*mp_formatter << nsnode->getNodeName());
					if (m_formatBuffer[5] == ':')
						currentName.sbStrcpyIn((char *) &m_formatBuffer[6]);
					else
						currentName.sbStrcpyIn("");

					toIns = new XSECNodeListElt;
					toIns->element = nsnode;

					// Build and insert name space node
					toIns->sortString.sbStrcpyIn(XMLNS_PREFIX);
					toIns->sortString.sbStrcatIn(currentName);

					// Insert node
					mp_attributes = insertNodeIntoList(mp_attributes, toIns);

					// Mark as printed in the NS Stack
					m_nsStack.printNamespace(nsnode, mp_nextNode);

				}
				nsnode = m_nsStack.getNextNamespace();
			}

			// Fix for bug#47353, make sure we set xmlnsFound regardless of what the printing process saw.
	        if (!xmlnsFound)
	            xmlnsFound = m_nsStack.isNonEmptyDefaultNS();

		} /* if (m_useNamespaceStack) */


		// Check to see if we add xmlns=""
		if (processNode && !xmlnsFound && mp_nextNode != mp_firstElementNode) {

			// Is this exclusive?

			safeBuffer sbLocalName("");

			if (m_exclusiveDefault) {

				if (visiblyUtilises(mp_nextNode, sbLocalName)) {

					// May have to output!
					next = mp_nextNode->getParentNode();

					while (next != NULL) {

						if (!m_XPathSelection || m_useNamespaceStack || m_XPathMap.hasNode(next)) {

							DOMNode *tmpAtt;

							// An output ancestor
							if (visiblyUtilises(next, sbLocalName)) {
								DOMNode * nextAttParent = next;

								while (nextAttParent != NULL) {
									// Have a hit!
									tmpAtts = nextAttParent->getAttributes();
									if (tmpAtts != NULL)
										tmpAtt = tmpAtts->getNamedItem(DSIGConstants::s_unicodeStrXmlns);
									if (tmpAtts != NULL && tmpAtt != NULL && (!m_XPathSelection || m_useNamespaceStack || m_XPathMap.hasNode(tmpAtt))) {

										// Check URI is the same
										if (!strEquals(tmpAtt->getNodeValue(), "")) {
											xmlnsFound = true;
											nextAttParent = NULL;
										}
									}
									else {

										// Doesn't have a default namespace in the node-set
										next = nextAttParent = NULL;
										break;

									}

									if (m_useNamespaceStack && nextAttParent)
										nextAttParent = nextAttParent->getParentNode();
									else
										nextAttParent = NULL;
								}


							}
						}

						if (next)
							next = next->getParentNode();
					}

				}
			} /* m_exclusiveDefault */

			else {

				//DOM_Node next;

				next = mp_nextNode->getParentNode();
				while (!xmlnsFound && next != NULL) {
					while (next != NULL && !m_useNamespaceStack && (m_XPathSelection && !m_XPathMap.hasNode(next)))
						next = next->getParentNode();

					XMLSize_t size;
					if (next != NULL)
						tmpAtts = next->getAttributes();

					if (next != NULL && tmpAtts != NULL)
						size = tmpAtts->getLength();
					else
						size = 0;

					for (XMLSize_t i = 0; i < size; ++i) {

						currentName << (*mp_formatter << tmpAtts->item(i)->getNodeName());
						currentValue << (*mp_formatter << tmpAtts->item(i)->getNodeValue());

						if ((currentName.sbStrcmp("xmlns") == 0) &&
							(m_useNamespaceStack || !m_XPathSelection || m_XPathMap.hasNode(tmpAtts->item(i)))) {
							if (currentValue.sbStrcmp("") != 0) {
								xmlnsFound = true;
							}
							else {
								xmlnsFound = false;
								next = NULL;
							}
						}

					}
					if (m_useNamespaceStack && next != NULL)
						next = next->getParentNode();
					else
						next = NULL;
				}
			}

			// Did we find a non empty namespace?
			if (xmlnsFound) {

				currentName.sbStrcpyIn("");		// Don't include xmlns prefix
				XSECNodeListElt * toIns;

				toIns = new XSECNodeListElt;
				toIns->element = NULL;		// To trigger the state engine

				// Build and insert name space node
				toIns->sortString.sbStrcpyIn(XMLNS_PREFIX);
				toIns->sortString.sbStrcatIn(currentName);

				// Insert node
				mp_attributes = insertNodeIntoList(mp_attributes, toIns);
			}
		}


		if (mp_attributes != NULL) {

			// Now we have set up the attribute list, set next node and return!

			mp_attributeParent = mp_nextNode;
			mp_nextNode = mp_attributes->element;
			mp_currentAttribute = mp_attributes;
			m_bufferLength = m_buffer.sbStrlen();
			m_bufferPoint = 0;

			return m_bufferLength;

		} /* attrributes != NULL */


		if (processNode)
			m_buffer.sbStrcatIn(">");

		// Fall through to find next node

		break;

	case DOMNode::ATTRIBUTE_NODE : // Output attr_name="value"

		// Always process an attribute node as we have already checked they should
		// be printed

		m_buffer.sbStrcpyIn(" ");

		if (mp_nextNode != 0) {

			m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeName());
			m_buffer.sbStrcatIn(m_formatBuffer);

			m_buffer.sbStrcatIn("=\"");

			m_formatBuffer << (*mp_formatter << mp_nextNode->getNodeValue());
			sbWork = c14nCleanAttribute(m_formatBuffer);
			m_buffer.sbStrcatIn(sbWork);

			m_buffer.sbStrcatIn("\"");
		}
		else {
			m_buffer.sbStrcatIn("xmlns");
			m_buffer.sbStrcatIn("=\"");
			m_buffer.sbStrcatIn("\"");
		}


		// Now see if next node is an attribute

		mp_currentAttribute = mp_currentAttribute->next;
		if (mp_currentAttribute != NULL) {

			// Easy case
			mp_nextNode = mp_currentAttribute->element;
			m_bufferLength = m_buffer.sbStrlen();
			m_bufferPoint = 0;

			return m_bufferLength;


		} /* if mp_currentAttributes != NULL) */

		// need to clear out the node list
		while (mp_attributes != NULL) {

			mp_currentAttribute = mp_attributes->next;
			delete mp_attributes;
			mp_attributes = mp_currentAttribute;
		}

		mp_attributes = mp_currentAttribute = mp_firstNonNsAttribute = NULL;

		// return us to the element node
		mp_nextNode = mp_attributeParent;

		// End the element definition
		if (!m_XPathSelection || (m_XPathMap.hasNode(mp_nextNode)))
			m_buffer.sbStrcatIn(">");

		m_returnedFromChild = false;


		break;

	default:

		break;

	}

	// A node has fallen through to the default case for finding the next node.

	m_bufferLength = m_buffer.sbStrlen();;
	m_bufferPoint = 0;

	// Firstly, was the last piece of processing because we "came up" from a child node?

	if (m_returnedFromChild) {

		if (mp_nextNode == mp_startNode) {

			// we have closed off the document!
			m_allNodesDone = true;
			return m_bufferLength;

		}

		if (mp_nextNode == mp_firstElementNode) {

			// we have closed off the main mp_doc elt
			m_firstElementProcessed = true;

		}

	}

	else {

		// Going down - so check for children nodes
		next = mp_nextNode->getFirstChild();

		if (next != NULL)

			mp_nextNode = next;

		else

			// No children, so need to close this node off!
			m_returnedFromChild = true;

		return m_bufferLength;

	}

	// If we get here all childeren (if there are any) are done

	next = mp_nextNode->getNextSibling();
	if (next != NULL) {

		m_returnedFromChild = false;
		mp_nextNode = next;
		return m_bufferLength;

	}

	// No more nodes at this level either!

	mp_nextNode = mp_nextNode->getParentNode();
	m_returnedFromChild = true;
	return m_bufferLength;

}
