/*
 * namespaces.c: Implementation of the XSLT namespaces handling
 *
 * Reference:
 *   http://www.w3.org/TR/1999/REC-xslt-19991116
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

#define IN_LIBXSLT
#include "libxslt.h"

#include <string.h>

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#ifdef HAVE_NAN_H
#include <nan.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifndef	XSLT_NEED_TRIO
#include <stdio.h>
#else
#include <trio.h>
#endif

#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
#include <libxml/xmlerror.h>
#include <libxml/uri.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "namespaces.h"
#include "imports.h"

/************************************************************************
 *									*
 *			Module interfaces				*
 *									*
 ************************************************************************/

#ifdef XSLT_REFACTORED  
static xsltNsAliasPtr
xsltNewNsAlias(xsltCompilerCtxtPtr cctxt)
{
    xsltNsAliasPtr ret;

    if (cctxt == NULL)
	return(NULL);

    ret = (xsltNsAliasPtr) xmlMalloc(sizeof(xsltNsAlias));
    if (ret == NULL) {
	xsltTransformError(NULL, cctxt->style, NULL,
	    "Internal error in xsltNewNsAlias(): Memory allocation failed.\n");
	cctxt->style->errors++;
	return(NULL);
    }
    memset(ret, 0, sizeof(xsltNsAlias));    
    /*
    * TODO: Store the item at current stylesheet-level.
    */
    ret->next = cctxt->nsAliases;
    cctxt->nsAliases = ret;       

    return(ret);
}
#endif /* XSLT_REFACTORED */
/**
 * xsltNamespaceAlias:
 * @style:  the XSLT stylesheet
 * @node:  the xsl:namespace-alias node
 *
 * Read the stylesheet-prefix and result-prefix attributes, register
 * them as well as the corresponding namespace.
 */
void
xsltNamespaceAlias(xsltStylesheetPtr style, xmlNodePtr node)
{
    xmlChar *resultPrefix = NULL;
    xmlChar *stylePrefix = NULL;
    xmlNsPtr literalNs = NULL;
    xmlNsPtr targetNs = NULL;
 
#ifdef XSLT_REFACTORED 
    xsltNsAliasPtr alias;

    if ((style == NULL) || (node == NULL))
	return;

    /*
    * SPEC XSLT 1.0:
    *  "If a namespace URI is declared to be an alias for multiple
    *  different namespace URIs, then the declaration with the highest
    *  import precedence is used. It is an error if there is more than
    *  one such declaration. An XSLT processor may signal the error;
    *  if it does not signal the error, it must recover by choosing,
    *  from amongst the declarations with the highest import precedence,
    *  the one that occurs last in the stylesheet."
    *
    * SPEC TODO: Check for the errors mentioned above.
    */
    /*
    * NOTE that the XSLT 2.0 also *does* use the NULL namespace if
    *  "#default" is used and there's no default namespace is scope.
    *  I.e., this is *not* an error. 
    *  Most XSLT 1.0 implementations work this way.
    *  The XSLT 1.0 spec has nothing to say on the subject. 
    */
    /*
    * Attribute "stylesheet-prefix".
    */
    stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
    if (stylePrefix == NULL) {
	xsltTransformError(NULL, style, node,
	    "The attribute 'stylesheet-prefix' is missing.\n");
	return;
    }
    if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default"))
	literalNs = xmlSearchNs(node->doc, node, NULL);	
    else {
	literalNs = xmlSearchNs(node->doc, node, stylePrefix);
	if (literalNs == NULL) {
	    xsltTransformError(NULL, style, node,
	        "Attribute 'stylesheet-prefix': There's no namespace "
		"declaration in scope for the prefix '%s'.\n",
		    stylePrefix);
	    goto error;
	}
    }
    /*
    * Attribute "result-prefix".
    */
    resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
    if (resultPrefix == NULL) {
	xsltTransformError(NULL, style, node,
	    "The attribute 'result-prefix' is missing.\n");
	goto error;
    }        
    if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default"))
	targetNs = xmlSearchNs(node->doc, node, NULL);
    else {
	targetNs = xmlSearchNs(node->doc, node, resultPrefix);

        if (targetNs == NULL) {
	   xsltTransformError(NULL, style, node,
	        "Attribute 'result-prefix': There's no namespace "
		"declaration in scope for the prefix '%s'.\n",
		    stylePrefix);
	    goto error;
	}
    }
    /*
     *
     * Same alias for multiple different target namespace URIs:
     *  TODO: The one with the highest import precedence is used.
     *  Example:
     *  <xsl:namespace-alias stylesheet-prefix="foo"
     *                       result-prefix="bar"/>
     *
     *  <xsl:namespace-alias stylesheet-prefix="foo"
     *                       result-prefix="zar"/>
     *
     * Same target namespace URI for multiple different aliases:
     *  All alias-definitions will be used.
     *  Example:
     *  <xsl:namespace-alias stylesheet-prefix="bar"
     *                       result-prefix="foo"/>
     *
     *  <xsl:namespace-alias stylesheet-prefix="zar"
     *                       result-prefix="foo"/>
     * Cases using #default:
     *  <xsl:namespace-alias stylesheet-prefix="#default"
     *                       result-prefix="#default"/>
     *  TODO: Has this an effect at all?
     *
     *  <xsl:namespace-alias stylesheet-prefix="foo"
     *                       result-prefix="#default"/>
     *  From namespace to no namespace.
     *
     *  <xsl:namespace-alias stylesheet-prefix="#default"
     *                       result-prefix="foo"/>
     *  From no namespace to namespace.
     */
    
	
     /*
     * Store the ns-node in the alias-object.
    */
    alias = xsltNewNsAlias(XSLT_CCTXT(style));
    if (alias == NULL)
	return;
    alias->literalNs = literalNs;
    alias->targetNs = targetNs;
    XSLT_CCTXT(style)->hasNsAliases = 1;


#else /* XSLT_REFACTORED */
    const xmlChar *literalNsName;
    const xmlChar *targetNsName;
    

    if ((style == NULL) || (node == NULL))
	return;

    stylePrefix = xmlGetNsProp(node, (const xmlChar *)"stylesheet-prefix", NULL);
    if (stylePrefix == NULL) {
	xsltTransformError(NULL, style, node,
	    "namespace-alias: stylesheet-prefix attribute missing\n");
	return;
    }
    resultPrefix = xmlGetNsProp(node, (const xmlChar *)"result-prefix", NULL);
    if (resultPrefix == NULL) {
	xsltTransformError(NULL, style, node,
	    "namespace-alias: result-prefix attribute missing\n");
	goto error;
    }
    
    if (xmlStrEqual(stylePrefix, (const xmlChar *)"#default")) {
	literalNs = xmlSearchNs(node->doc, node, NULL);
	if (literalNs == NULL) {
	    literalNsName = NULL;
	} else
	    literalNsName = literalNs->href; /* Yes - set for nsAlias table */
    } else {
	literalNs = xmlSearchNs(node->doc, node, stylePrefix);
 
	if ((literalNs == NULL) || (literalNs->href == NULL)) {
	    xsltTransformError(NULL, style, node,
	        "namespace-alias: prefix %s not bound to any namespace\n",
					stylePrefix);
	    goto error;
	} else
	    literalNsName = literalNs->href;
    }

    /*
     * When "#default" is used for result, if a default namespace has not
     * been explicitly declared the special value UNDEFINED_DEFAULT_NS is
     * put into the nsAliases table
     */
    if (xmlStrEqual(resultPrefix, (const xmlChar *)"#default")) {
	targetNs = xmlSearchNs(node->doc, node, NULL);
	if (targetNs == NULL) {
	    targetNsName = UNDEFINED_DEFAULT_NS;
	} else
	    targetNsName = targetNs->href;
    } else {
	targetNs = xmlSearchNs(node->doc, node, resultPrefix);

        if ((targetNs == NULL) || (targetNs->href == NULL)) {
	    xsltTransformError(NULL, style, node,
	        "namespace-alias: prefix %s not bound to any namespace\n",
					resultPrefix);
	    goto error;
	} else
	    targetNsName = targetNs->href;
    }
    /*
     * Special case: if #default is used for
     *  the stylesheet-prefix (literal namespace) and there's no default
     *  namespace in scope, we'll use style->defaultAlias for this.
     */   
    if (literalNsName == NULL) {
        if (targetNs != NULL) {
	    /*
	    * BUG TODO: Is it not sufficient to have only 1 field for
	    *  this, since subsequently alias declarations will
	    *  overwrite this.	    
	    *  Example:
	    *   <xsl:namespace-alias result-prefix="foo"
	    *                        stylesheet-prefix="#default"/>
	    *   <xsl:namespace-alias result-prefix="bar"
	    *                        stylesheet-prefix="#default"/>
	    *  The mapping for "foo" won't be visible anymore.
	    */
            style->defaultAlias = targetNs->href;
	}
    } else {
        if (style->nsAliases == NULL)
	    style->nsAliases = xmlHashCreate(10);
        if (style->nsAliases == NULL) {
	    xsltTransformError(NULL, style, node,
	        "namespace-alias: cannot create hash table\n");
	    goto error;
        }
	xmlHashAddEntry((xmlHashTablePtr) style->nsAliases,
	    literalNsName, (void *) targetNsName);
    }
#endif /* else of XSLT_REFACTORED */

error:
    if (stylePrefix != NULL)
	xmlFree(stylePrefix);
    if (resultPrefix != NULL)
	xmlFree(resultPrefix);
}

/**
 * xsltGetSpecialNamespace:
 * @ctxt:  the transformation context
 * @invocNode: the invoking node; e.g. a literal result element/attr;
 *             only used for error reports
 * @nsName:  the namespace name (or NULL)
 * @nsPrefix:  the suggested namespace prefix (or NULL)
 * @target:  the result element on which to anchor a namespace
 *
 * Find a matching (prefix and ns-name) ns-declaration
 * for the requested @nsName and @nsPrefix in the result tree.
 * If none is found then a new ns-declaration will be
 * added to @resultElem. If, in this case, the given prefix is
 * already in use, then a ns-declaration with a modified ns-prefix
 * be we created. Note that this function's priority is to
 * preserve ns-prefixes; it will only change a prefix if there's
 * a namespace clash.
 * If both @nsName and @nsPrefix are NULL, then this will try to
 * "undeclare" a default namespace by declaring an xmlns="".
 *
 * Returns a namespace declaration or NULL.
 */
xmlNsPtr
xsltGetSpecialNamespace(xsltTransformContextPtr ctxt, xmlNodePtr invocNode,
		const xmlChar *nsName, const xmlChar *nsPrefix,
		xmlNodePtr target)
{
    xmlNsPtr ns;
    int prefixOccupied = 0;

    if ((ctxt == NULL) || (target == NULL) ||
	(target->type != XML_ELEMENT_NODE))
	return(NULL);

    /*
    * NOTE: Namespace exclusion and ns-aliasing is performed at
    *  compilation-time in the refactored code; so this need not be done
    *  here (it was in the old code).
    * NOTE: @invocNode was named @cur in the old code and was documented to
    *  be an input node; since it was only used to anchor an error report
    *  somewhere, we can safely change this to @invocNode, which now
    *  will be the XSLT instruction (also a literal result element/attribute),
    *  which was responsible for this call.
    */
    /*
    * OPTIMIZE TODO: This all could be optimized by keeping track of
    *  the ns-decls currently in-scope via a specialized context.
    */    
    if ((nsPrefix == NULL) && ((nsName == NULL) || (nsName[0] == 0))) {
	/*
	* NOTE: the "undeclaration" of the default namespace was
	* part of the logic of the old xsltGetSpecialNamespace() code,
	* so we'll keep that mechanism.
	* Related to the old code: bug #302020:
	*/
	/*
	* OPTIMIZE TODO: This all could be optimized by keeping track of
	*  the ns-decls currently in-scope via a specialized context.
	*/
	/*
	* Search on the result element itself.
	*/
	if (target->nsDef != NULL) {
	    ns = target->nsDef;
	    do {
		if (ns->prefix == NULL) {
		    if ((ns->href != NULL) && (ns->href[0] != 0)) {
			/*
			* Raise a namespace normalization error.
			*/
			xsltTransformError(ctxt, NULL, invocNode,
			    "Namespace normalization error: Cannot undeclare "
			    "the default namespace, since the default namespace "
			    "'%s' is already declared on the result element "
			    "'%s'.\n", ns->href, target->name);
			return(NULL);
		    } else {
			/*
			* The default namespace was undeclared on the
			* result element.
			*/
			return(NULL);
		    }
		    break;
		}
		ns = ns->next;
	    } while (ns != NULL);
	}	
	if ((target->parent != NULL) &&
	    (target->parent->type == XML_ELEMENT_NODE))
	{
	    /*
	    * The parent element is in no namespace, so assume
	    * that there is no default namespace in scope.
	    */
	    if (target->parent->ns == NULL)
		return(NULL);
	    
	    ns = xmlSearchNs(target->doc, target->parent,
		NULL);
	    /*
	    * Fine if there's no default ns is scope, or if the
	    * default ns was undeclared.
	    */
	    if ((ns == NULL) || (ns->href == NULL) || (ns->href[0] == 0))
		return(NULL);
	    
	    /*
	    * Undeclare the default namespace.
	    */
	    xmlNewNs(target, BAD_CAST "", NULL);
	    /* TODO: Check result */	
	    return(NULL);
	}
	return(NULL);
    }
    /*
    * Handle the XML namespace.
    * QUESTION: Is this faster than using xmlStrEqual() anyway?
    */
    if ((nsPrefix != NULL) &&
	(nsPrefix[0] == 'x') && (nsPrefix[1] == 'm') &&
	(nsPrefix[2] == 'l') && (nsPrefix[3] == 0))
    {
	return(xmlSearchNs(target->doc, target, nsPrefix));
    }
    /*
    * First: search on the result element itself.
    */
    if (target->nsDef != NULL) {
	ns = target->nsDef;
	do {
	    if ((ns->prefix == NULL) == (nsPrefix == NULL)) {
		if (ns->prefix == nsPrefix) {
		    if (xmlStrEqual(ns->href, nsName))
			return(ns);
		    prefixOccupied = 1;
		    break;
		} else if (xmlStrEqual(ns->prefix, nsPrefix)) {
		    if (xmlStrEqual(ns->href, nsName))
			return(ns);
		    prefixOccupied = 1;
		    break;
		}
	    }
	    ns = ns->next;
	} while (ns != NULL);
    }
    if (prefixOccupied) {
	/*
	* If the ns-prefix is occupied by an other ns-decl on the
	* result element, then this means:
	* 1) The desired prefix is shadowed
	* 2) There's no way around changing the prefix	
	*
	* Try a desperate search for an in-scope ns-decl
	* with a matching ns-name before we use the last option,
	* which is to recreate the ns-decl with a modified prefix.
	*/
	ns = xmlSearchNsByHref(target->doc, target, nsName);
	if (ns != NULL)
	    return(ns);

	/*
	* Fallback to changing the prefix.
	*/    
    } else if ((target->parent != NULL) &&
	(target->parent->type == XML_ELEMENT_NODE))
    {
	/*
	* Try to find a matching ns-decl in the ancestor-axis.
	*
	* Check the common case: The parent element of the current
	* result element is in the same namespace (with an equal ns-prefix).
	*/     
	if ((target->parent->ns != NULL) &&
	    ((target->parent->ns->prefix != NULL) == (nsPrefix != NULL)))
	{
	    ns = target->parent->ns;
	    
	    if (nsPrefix == NULL) {
		if (xmlStrEqual(ns->href, nsName))
		    return(ns);
	    } else if (xmlStrEqual(ns->prefix, nsPrefix) &&
		xmlStrEqual(ns->href, nsName))
	    {
		return(ns);
	    }
	}
	/*
	* Lookup the remaining in-scope namespaces.
	*/    
	ns = xmlSearchNs(target->doc, target->parent, nsPrefix);
	if (ns != NULL) {
	    if (xmlStrEqual(ns->href, nsName))
		return(ns);	    
	    /*
	    * Now check for a nasty case: We need to ensure that the new
	    * ns-decl won't shadow a prefix in-use by an existing attribute.
	    * <foo xmlns:a="urn:test:a">
	    *   <bar a:a="val-a">
	    *     <xsl:attribute xmlns:a="urn:test:b" name="a:b">
	    *        val-b</xsl:attribute>
	    *   </bar>
	    * </foo>
	    */
	    if (target->properties) {
		xmlAttrPtr attr = target->properties;
		do {
		    if ((attr->ns) &&
			xmlStrEqual(attr->ns->prefix, nsPrefix))
		    {
			/*
			* Bad, this prefix is already in use.
			* Since we'll change the prefix anyway, try
			* a search for a matching ns-decl based on the
			* namespace name.
			*/
			ns = xmlSearchNsByHref(target->doc, target, nsName);
			if (ns != NULL)
			    return(ns);
			goto declare_new_prefix;
		    }
		    attr = attr->next;
		} while (attr != NULL);
	    }
	} else {
	    /*
	    * Either no matching ns-prefix was found or the namespace is
	    * shadowed.
	    * Create a new ns-decl on the current result element.
	    *
	    * Hmm, we could also try to reuse an in-scope
	    * namespace with a matching ns-name but a different
	    * ns-prefix.
	    * What has higher priority?
	    *  1) If keeping the prefix: create a new ns-decl.
	    *  2) If reusal: first lookup ns-names; then fallback
	    *     to creation of a new ns-decl.
	    * REVISIT: this currently uses case 1) although
	    *  the old way was use xmlSearchNsByHref() and to let change
	    *  the prefix.
	    */
#if 0
	    ns = xmlSearchNsByHref(target->doc, target, nsName);
	    if (ns != NULL)
		return(ns);
#endif
	}
	/*
	* Create the ns-decl on the current result element.
	*/
	ns = xmlNewNs(target, nsName, nsPrefix);
	/* TODO: check errors */
	return(ns);
    } else {
	/*
	* This is either the root of the tree or something weird is going on.
	*/
	ns = xmlNewNs(target, nsName, nsPrefix);
	/* TODO: Check result */
	return(ns);
    }

declare_new_prefix:
    /*
    * Fallback: we need to generate a new prefix and declare the namespace
    * on the result element.
    */
    {
	xmlChar pref[30];
	int counter = 1;

	if (nsPrefix == NULL) {
	    nsPrefix = "ns";
	}

	do {
	    snprintf((char *) pref, 30, "%s_%d", nsPrefix, counter++);
	    ns = xmlSearchNs(target->doc, target, BAD_CAST pref);
	    if (counter > 1000) {
		xsltTransformError(ctxt, NULL, invocNode,
		    "Internal error in xsltAcquireResultInScopeNs(): "
		    "Failed to compute a unique ns-prefix for the "
		    "generated element");
		return(NULL);
	    }
	} while (ns != NULL);
	ns = xmlNewNs(target, nsName, BAD_CAST pref);
	/* TODO: Check result */
	return(ns);
    }
    return(NULL);
}

/**
 * xsltGetNamespace:
 * @ctxt:  a transformation context
 * @cur:  the input node
 * @ns:  the namespace
 * @out:  the output node (or its parent)
 *
 * Find a matching (prefix and ns-name) ns-declaration
 * for the requested @ns->prefix and @ns->href in the result tree.
 * If none is found then a new ns-declaration will be
 * added to @resultElem. If, in this case, the given prefix is
 * already in use, then a ns-declaration with a modified ns-prefix
 * be we created.
 *
 * Called by:
 *  - xsltCopyPropList() (*not*  anymore)
 *  - xsltShallowCopyElement()
 *  - xsltCopyTreeInternal() (*not*  anymore)
 *  - xsltApplySequenceConstructor() (*not* in the refactored code),
 *  - xsltElement() (*not* anymore)
 *
 * Returns a namespace declaration or NULL in case of
 *         namespace fixup failures or API or internal errors.
 */
xmlNsPtr
xsltGetNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur, xmlNsPtr ns,
	         xmlNodePtr out)
{    
    
    if (ns == NULL)
	return(NULL);

#ifdef XSLT_REFACTORED
    /*
    * Namespace exclusion and ns-aliasing is performed at
    * compilation-time in the refactored code.
    * Additionally, aliasing is not intended for non Literal
    * Result Elements.
    */
    return(xsltGetSpecialNamespace(ctxt, cur, ns->href, ns->prefix, out));
#else
    {
	xsltStylesheetPtr style;
	const xmlChar *URI = NULL; /* the replacement URI */

	if ((ctxt == NULL) || (cur == NULL) || (out == NULL))
	    return(NULL);

	style = ctxt->style;
	while (style != NULL) {
	    if (style->nsAliases != NULL)
		URI = (const xmlChar *) 
		xmlHashLookup(style->nsAliases, ns->href);
	    if (URI != NULL)
		break;
	    
	    style = xsltNextImport(style);
	}
	
	
	if (URI == UNDEFINED_DEFAULT_NS) {
	    return(xsltGetSpecialNamespace(ctxt, cur, NULL, NULL, out));
#if 0
	    /*
	    * TODO: Removed, since wrong. If there was no default
	    * namespace in the stylesheet then this must resolve to
	    * the NULL namespace.
	    */
	    xmlNsPtr dflt;	    
	    dflt = xmlSearchNs(cur->doc, cur, NULL);
	    if (dflt != NULL)
		URI = dflt->href;
	    else
		return NULL;
#endif
	} else if (URI == NULL)
	    URI = ns->href;

	return(xsltGetSpecialNamespace(ctxt, cur, URI, ns->prefix, out));
    }
#endif
}

/**
 * xsltGetPlainNamespace:
 * @ctxt:  a transformation context
 * @cur:  the input node
 * @ns:  the namespace
 * @out:  the result element
 *
 * Obsolete. 
 * *Not* called by any Libxslt/Libexslt function.
 * Exaclty the same as xsltGetNamespace(). 
 *
 * Returns a namespace declaration or NULL in case of
 *         namespace fixup failures or API or internal errors.
 */
xmlNsPtr
xsltGetPlainNamespace(xsltTransformContextPtr ctxt, xmlNodePtr cur,
                      xmlNsPtr ns, xmlNodePtr out)
{    
    return(xsltGetNamespace(ctxt, cur, ns, out));
}

/**
 * xsltCopyNamespaceList:
 * @ctxt:  a transformation context
 * @node:  the target node
 * @cur:  the first namespace
 *
 * Do a copy of an namespace list. If @node is non-NULL the
 * new namespaces are added automatically. This handles namespaces
 * aliases.
 * This function is intended only for *internal* use at
 * transformation-time for copying ns-declarations of Literal
 * Result Elements.
 * 
 * Called by:
 *   xsltCopyTreeInternal() (transform.c)
 *   xsltShallowCopyElem() (transform.c)
 *
 * REVISIT: This function won't be used in the refactored code.
 *
 * Returns: a new xmlNsPtr, or NULL in case of error.
 */
xmlNsPtr
xsltCopyNamespaceList(xsltTransformContextPtr ctxt, xmlNodePtr node,
	              xmlNsPtr cur) {
    xmlNsPtr ret = NULL, tmp;
    xmlNsPtr p = NULL,q;    

    if (cur == NULL)
	return(NULL);
    if (cur->type != XML_NAMESPACE_DECL)
	return(NULL);

    /*
     * One can add namespaces only on element nodes
     */
    if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
	node = NULL;

    while (cur != NULL) {
	if (cur->type != XML_NAMESPACE_DECL)
	    break;

	/*
	 * Avoid duplicating namespace declarations in the tree if
	 * a matching declaration is in scope.
	 */
	if (node != NULL) {
	    if ((node->ns != NULL) &&
		(xmlStrEqual(node->ns->prefix, cur->prefix)) &&
        	(xmlStrEqual(node->ns->href, cur->href))) {
		cur = cur->next;
		continue;
	    }
	    tmp = xmlSearchNs(node->doc, node, cur->prefix);
	    if ((tmp != NULL) && (xmlStrEqual(tmp->href, cur->href))) {
		cur = cur->next;
		continue;
	    }
	}
#ifdef XSLT_REFACTORED
	/*
	* Namespace exclusion and ns-aliasing is performed at
	* compilation-time in the refactored code.
	*/
	q = xmlNewNs(node, cur->href, cur->prefix);
	if (p == NULL) {
	    ret = p = q;
	} else {
	    p->next = q;
	    p = q;
	}
#else
	/*
	* TODO: Remove this if the refactored code gets enabled.
	*/
	if (!xmlStrEqual(cur->href, XSLT_NAMESPACE)) {
	    const xmlChar *URI;
	    /* TODO apply cascading */
	    URI = (const xmlChar *) xmlHashLookup(ctxt->style->nsAliases,
		                                  cur->href);
	    if (URI == UNDEFINED_DEFAULT_NS)
	        continue;
	    if (URI != NULL) {
		q = xmlNewNs(node, URI, cur->prefix);
	    } else {
		q = xmlNewNs(node, cur->href, cur->prefix);
	    }
	    if (p == NULL) {
		ret = p = q;
	    } else {
		p->next = q;
		p = q;
	    }
	}
#endif
	cur = cur->next;
    }
    return(ret);
}

/**
 * xsltCopyNamespace:
 * @ctxt:  a transformation context
 * @elem:  the target element node
 * @ns:  the namespace node
 *
 * Copies a namespace node (declaration). If @elem is not NULL,
 * then the new namespace will be declared on @elem.
 *
 * Returns: a new xmlNsPtr, or NULL in case of an error.
 */
xmlNsPtr
xsltCopyNamespace(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
		  xmlNodePtr elem, xmlNsPtr ns)
{    
    if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
	return(NULL);
    /*
     * One can add namespaces only on element nodes
     */
    if ((elem != NULL) && (elem->type != XML_ELEMENT_NODE))
	return(xmlNewNs(NULL, ns->href, ns->prefix));
    else
	return(xmlNewNs(elem, ns->href, ns->prefix));
}


/**
 * xsltFreeNamespaceAliasHashes:
 * @style: an XSLT stylesheet
 *
 * Free up the memory used by namespaces aliases
 */
void
xsltFreeNamespaceAliasHashes(xsltStylesheetPtr style) {
    if (style->nsAliases != NULL)
	xmlHashFree((xmlHashTablePtr) style->nsAliases, NULL);
    style->nsAliases = NULL;
}
