/*
 * xslt.c: Implemetation of an XSL Transformation 1.0 engine
 *
 * Reference:
 *   XSLT specification
 *   http://www.w3.org/TR/1999/REC-xslt-19991116
 *
 *   Associating Style Sheets with XML documents
 *   http://www.w3.org/1999/06/REC-xml-stylesheet-19990629
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

#define IN_LIBXSLT
#include "libxslt.h"

#include <string.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/valid.h>
#include <libxml/hash.h>
#include <libxml/uri.h>
#include <libxml/xmlerror.h>
#include <libxml/parserInternals.h>
#include <libxml/xpathInternals.h>
#include <libxml/xpath.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "pattern.h"
#include "variables.h"
#include "namespaces.h"
#include "attributes.h"
#include "xsltutils.h"
#include "imports.h"
#include "keys.h"
#include "documents.h"
#include "extensions.h"
#include "preproc.h"
#include "extra.h"
#include "security.h"

#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_PARSING
/* #define WITH_XSLT_DEBUG_BLANKS */
#endif

const char *xsltEngineVersion = LIBXSLT_VERSION_STRING LIBXSLT_VERSION_EXTRA;
const int xsltLibxsltVersion = LIBXSLT_VERSION;
const int xsltLibxmlVersion = LIBXML_VERSION;

#ifdef XSLT_REFACTORED

const xmlChar *xsltConstNamespaceNameXSLT = (const xmlChar *) XSLT_NAMESPACE;

#define XSLT_ELEMENT_CATEGORY_XSLT 0
#define XSLT_ELEMENT_CATEGORY_EXTENSION 1
#define XSLT_ELEMENT_CATEGORY_LRE 2

/*
* xsltLiteralResultMarker:
* Marker for Literal result elements, in order to avoid multiple attempts
* to recognize such elements in the stylesheet's tree.
* This marker is set on node->psvi during the initial traversal
* of a stylesheet's node tree.
*
const xmlChar *xsltLiteralResultMarker =
    (const xmlChar *) "Literal Result Element";
*/

/*
* xsltXSLTTextMarker:
* Marker for xsl:text elements. Used to recognize xsl:text elements
* for post-processing of the stylesheet's tree, where those
* elements are removed from the tree.
*/
const xmlChar *xsltXSLTTextMarker = (const xmlChar *) "XSLT Text Element";

/*
* xsltXSLTAttrMarker:
* Marker for XSLT attribute on Literal Result Elements.
*/
const xmlChar *xsltXSLTAttrMarker = (const xmlChar *) "LRE XSLT Attr";

#endif

#ifdef XSLT_LOCALE_WINAPI
extern xmlRMutexPtr xsltLocaleMutex;
#endif
/*
 * Harmless but avoiding a problem when compiling against a
 * libxml <= 2.3.11 without LIBXML_DEBUG_ENABLED
 */
#ifndef LIBXML_DEBUG_ENABLED
double xmlXPathStringEvalNumber(const xmlChar *str);
#endif
/*
 * Useful macros
 */

#ifdef  IS_BLANK
#undef	IS_BLANK
#endif
#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) ||	\
                     ((c) == 0x0D))

#ifdef	IS_BLANK_NODE
#undef	IS_BLANK_NODE
#endif
#define IS_BLANK_NODE(n)						\
    (((n)->type == XML_TEXT_NODE) && (xsltIsBlank((n)->content)))

/**
 * xsltParseContentError:
 *
 * @style: the stylesheet
 * @node: the node where the error occured
 *
 * Compile-time error function.
 */
static void
xsltParseContentError(xsltStylesheetPtr style,
		       xmlNodePtr node)
{
    if ((style == NULL) || (node == NULL))
	return;

    if (IS_XSLT_ELEM(node))
	xsltTransformError(NULL, style, node,
	    "The XSLT-element '%s' is not allowed at this position.\n",
	    node->name);
    else
	xsltTransformError(NULL, style, node,
	    "The element '%s' is not allowed at this position.\n",
	    node->name);
    style->errors++;
}

#ifdef XSLT_REFACTORED
#else
/**
 * exclPrefixPush:
 * @style: the transformation stylesheet
 * @value:  the excluded namespace name to push on the stack
 *
 * Push an excluded namespace name on the stack
 *
 * Returns the new index in the stack or -1 if already present or
 * in case of error
 */
static int
exclPrefixPush(xsltStylesheetPtr style, xmlChar * value)
{
    int i;

    if (style->exclPrefixMax == 0) {
        style->exclPrefixMax = 4;
        style->exclPrefixTab =
            (xmlChar * *)xmlMalloc(style->exclPrefixMax *
                                   sizeof(style->exclPrefixTab[0]));
        if (style->exclPrefixTab == NULL) {
            xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
            return (-1);
        }
    }
    /* do not push duplicates */
    for (i = 0;i < style->exclPrefixNr;i++) {
        if (xmlStrEqual(style->exclPrefixTab[i], value))
	    return(-1);
    }
    if (style->exclPrefixNr >= style->exclPrefixMax) {
        style->exclPrefixMax *= 2;
        style->exclPrefixTab =
            (xmlChar * *)xmlRealloc(style->exclPrefixTab,
                                    style->exclPrefixMax *
                                    sizeof(style->exclPrefixTab[0]));
        if (style->exclPrefixTab == NULL) {
            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
            return (-1);
        }
    }
    style->exclPrefixTab[style->exclPrefixNr] = value;
    style->exclPrefix = value;
    return (style->exclPrefixNr++);
}
/**
 * exclPrefixPop:
 * @style: the transformation stylesheet
 *
 * Pop an excluded prefix value from the stack
 *
 * Returns the stored excluded prefix value
 */
static xmlChar *
exclPrefixPop(xsltStylesheetPtr style)
{
    xmlChar *ret;

    if (style->exclPrefixNr <= 0)
        return (0);
    style->exclPrefixNr--;
    if (style->exclPrefixNr > 0)
        style->exclPrefix = style->exclPrefixTab[style->exclPrefixNr - 1];
    else
        style->exclPrefix = NULL;
    ret = style->exclPrefixTab[style->exclPrefixNr];
    style->exclPrefixTab[style->exclPrefixNr] = 0;
    return (ret);
}
#endif

/************************************************************************
 *									*
 *			Helper functions				*
 *									*
 ************************************************************************/

static int initialized = 0;
/**
 * xsltInit:
 *
 * Initializes the processor (e.g. registers built-in extensions,
 * etc.)
 */
void
xsltInit (void) {
    if (initialized == 0) {
	initialized = 1;
#ifdef XSLT_LOCALE_WINAPI
	xsltLocaleMutex = xmlNewRMutex();
#endif
        xsltRegisterAllExtras();
    }
}

/**
 * xsltUninit:
 *
 * Uninitializes the processor.
 */
void
xsltUninit (void) {
    initialized = 0;
}

/**
 * xsltIsBlank:
 * @str:  a string
 *
 * Check if a string is ignorable
 *
 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
 */
int
xsltIsBlank(xmlChar *str) {
    if (str == NULL)
	return(1);
    while (*str != 0) {
	if (!(IS_BLANK(*str))) return(0);
	str++;
    }
    return(1);
}

/************************************************************************
 *									*
 *		Routines to handle XSLT data structures			*
 *									*
 ************************************************************************/
static xsltDecimalFormatPtr
xsltNewDecimalFormat(xmlChar *name)
{
    xsltDecimalFormatPtr self;
    /* UTF-8 for 0x2030 */
    static const xmlChar permille[4] = {0xe2, 0x80, 0xb0, 0};

    self = xmlMalloc(sizeof(xsltDecimalFormat));
    if (self != NULL) {
	self->next = NULL;
	self->name = name;
	
	/* Default values */
	self->digit = xmlStrdup(BAD_CAST("#"));
	self->patternSeparator = xmlStrdup(BAD_CAST(";"));
	self->decimalPoint = xmlStrdup(BAD_CAST("."));
	self->grouping = xmlStrdup(BAD_CAST(","));
	self->percent = xmlStrdup(BAD_CAST("%"));
	self->permille = xmlStrdup(BAD_CAST(permille));
	self->zeroDigit = xmlStrdup(BAD_CAST("0"));
	self->minusSign = xmlStrdup(BAD_CAST("-"));
	self->infinity = xmlStrdup(BAD_CAST("Infinity"));
	self->noNumber = xmlStrdup(BAD_CAST("NaN"));
    }
    return self;
}

static void
xsltFreeDecimalFormat(xsltDecimalFormatPtr self)
{
    if (self != NULL) {
	if (self->digit)
	    xmlFree(self->digit);
	if (self->patternSeparator)
	    xmlFree(self->patternSeparator);
	if (self->decimalPoint)
	    xmlFree(self->decimalPoint);
	if (self->grouping)
	    xmlFree(self->grouping);
	if (self->percent)
	    xmlFree(self->percent);
	if (self->permille)
	    xmlFree(self->permille);
	if (self->zeroDigit)
	    xmlFree(self->zeroDigit);
	if (self->minusSign)
	    xmlFree(self->minusSign);
	if (self->infinity)
	    xmlFree(self->infinity);
	if (self->noNumber)
	    xmlFree(self->noNumber);
	if (self->name)
	    xmlFree(self->name);
	xmlFree(self);
    }
}

static void
xsltFreeDecimalFormatList(xsltStylesheetPtr self)
{
    xsltDecimalFormatPtr iter;
    xsltDecimalFormatPtr tmp;

    if (self == NULL)
	return;
    
    iter = self->decimalFormat;
    while (iter != NULL) {
	tmp = iter->next;
	xsltFreeDecimalFormat(iter);
	iter = tmp;
    }
}

/**
 * xsltDecimalFormatGetByName:
 * @style: the XSLT stylesheet
 * @name: the decimal-format name to find
 *
 * Find decimal-format by name
 *
 * Returns the xsltDecimalFormatPtr
 */
xsltDecimalFormatPtr
xsltDecimalFormatGetByName(xsltStylesheetPtr style, xmlChar *name)
{
    xsltDecimalFormatPtr result = NULL;

    if (name == NULL)
	return style->decimalFormat;

    while (style != NULL) {
	for (result = style->decimalFormat->next;
	     result != NULL;
	     result = result->next) {
	    if (xmlStrEqual(name, result->name))
		return result;
	}
	style = xsltNextImport(style);
    }
    return result;
}


/**
 * xsltNewTemplate:
 *
 * Create a new XSLT Template
 *
 * Returns the newly allocated xsltTemplatePtr or NULL in case of error
 */
static xsltTemplatePtr
xsltNewTemplate(void) {
    xsltTemplatePtr cur;

    cur = (xsltTemplatePtr) xmlMalloc(sizeof(xsltTemplate));
    if (cur == NULL) {
	xsltTransformError(NULL, NULL, NULL,
		"xsltNewTemplate : malloc failed\n");
	return(NULL);
    }
    memset(cur, 0, sizeof(xsltTemplate));
    cur->priority = XSLT_PAT_NO_PRIORITY;
    return(cur);
}

/**
 * xsltFreeTemplate:
 * @template:  an XSLT template
 *
 * Free up the memory allocated by @template
 */
static void
xsltFreeTemplate(xsltTemplatePtr template) {
    if (template == NULL)
	return;
    if (template->match) xmlFree(template->match);
/*
*   NOTE: @name and @nameURI are put into the string dict now.
*   if (template->name) xmlFree(template->name);
*   if (template->nameURI) xmlFree(template->nameURI);
*/
/*
    if (template->mode) xmlFree(template->mode);
    if (template->modeURI) xmlFree(template->modeURI);
 */
    if (template->inheritedNs) xmlFree(template->inheritedNs);
    memset(template, -1, sizeof(xsltTemplate));
    xmlFree(template);
}

/**
 * xsltFreeTemplateList:
 * @template:  an XSLT template list
 *
 * Free up the memory allocated by all the elements of @template
 */
static void
xsltFreeTemplateList(xsltTemplatePtr template) {
    xsltTemplatePtr cur;

    while (template != NULL) {
	cur = template;
	template = template->next;
	xsltFreeTemplate(cur);
    }
}

#ifdef XSLT_REFACTORED

static void
xsltFreeNsAliasList(xsltNsAliasPtr item)
{
    xsltNsAliasPtr tmp;
    
    while (item) {
	tmp = item;
	item = item->next;
	xmlFree(tmp);
    } 
    return;
}

#ifdef XSLT_REFACTORED_XSLT_NSCOMP
static void
xsltFreeNamespaceMap(xsltNsMapPtr item)
{
    xsltNsMapPtr tmp;
    
    while (item) {
	tmp = item;
	item = item->next;
	xmlFree(tmp);
    } 
    return;
}

static xsltNsMapPtr
xsltNewNamespaceMapItem(xsltCompilerCtxtPtr cctxt,
			xmlDocPtr doc,
			xmlNsPtr ns,
			xmlNodePtr elem)
{
    xsltNsMapPtr ret;

    if ((cctxt == NULL) || (doc == NULL) || (ns == NULL))
	return(NULL);

    ret = (xsltNsMapPtr) xmlMalloc(sizeof(xsltNsMap));
    if (ret == NULL) {
	xsltTransformError(NULL, cctxt->style, elem,
	    "Internal error: (xsltNewNamespaceMapItem) "
	    "memory allocation failed.\n");
	return(NULL);
    }
    memset(ret, 0, sizeof(xsltNsMap));
    ret->doc = doc;
    ret->ns = ns;
    ret->origNsName = ns->href;
    /*
    * Store the item at current stylesheet-level.
    */
    if (cctxt->psData->nsMap != NULL)
	ret->next = cctxt->psData->nsMap;
    cctxt->psData->nsMap = ret;

    return(ret);
}
#endif /* XSLT_REFACTORED_XSLT_NSCOMP */

/**
 * xsltCompilerVarInfoFree: 
 * @cctxt: the compilation context
 * 
 * Frees the list of information for vars/params.
 */
static void
xsltCompilerVarInfoFree(xsltCompilerCtxtPtr cctxt)
{
    xsltVarInfoPtr ivar = cctxt->ivars, ivartmp;    

    while (ivar) {
	ivartmp = ivar;
	ivar = ivar->next;
	xmlFree(ivartmp);
    }
}

/**
 * xsltCompilerCtxtFree:
 *
 * Free an XSLT compiler context. 
 */
static void
xsltCompilationCtxtFree(xsltCompilerCtxtPtr cctxt)
{    
    if (cctxt == NULL)
	return;
#ifdef WITH_XSLT_DEBUG_PARSING
    xsltGenericDebug(xsltGenericDebugContext,
	"Freeing compilation context\n");
    xsltGenericDebug(xsltGenericDebugContext,
	"### Max inodes: %d\n", cctxt->maxNodeInfos);
    xsltGenericDebug(xsltGenericDebugContext,
	"### Max LREs  : %d\n", cctxt->maxLREs);
#endif
    /*
    * Free node-infos.
    */
    if (cctxt->inodeList != NULL) {
	xsltCompilerNodeInfoPtr tmp, cur = cctxt->inodeList;
	while (cur != NULL) {
	    tmp = cur;
	    cur = cur->next;
	    xmlFree(tmp);
	}
    }
    if (cctxt->tmpList != NULL)
	xsltPointerListFree(cctxt->tmpList);
#ifdef XSLT_REFACTORED_XPATHCOMP
    if (cctxt->xpathCtxt != NULL)
	xmlXPathFreeContext(cctxt->xpathCtxt);
#endif
    if (cctxt->nsAliases != NULL)
	xsltFreeNsAliasList(cctxt->nsAliases);

    if (cctxt->ivars)
	xsltCompilerVarInfoFree(cctxt);

    xmlFree(cctxt);
}

/**
 * xsltCompilerCreate:
 *
 * Creates an XSLT compiler context.
 *
 * Returns the pointer to the created xsltCompilerCtxt or
 *         NULL in case of an internal error.
 */
static xsltCompilerCtxtPtr
xsltCompilationCtxtCreate(xsltStylesheetPtr style) {
    xsltCompilerCtxtPtr ret;

    ret = (xsltCompilerCtxtPtr) xmlMalloc(sizeof(xsltCompilerCtxt));
    if (ret == NULL) {
	xsltTransformError(NULL, style, NULL,
	    "xsltCompilerCreate: allocation of compiler "
	    "context failed.\n");
	return(NULL);
    }
    memset(ret, 0, sizeof(xsltCompilerCtxt));

    ret->errSeverity = XSLT_ERROR_SEVERITY_ERROR;
    ret->tmpList = xsltPointerListCreate(20);
    if (ret->tmpList == NULL) {
	goto internal_err;
    }
#ifdef XSLT_REFACTORED_XPATHCOMP
    /*
    * Create the XPath compilation context in order
    * to speed up precompilation of XPath expressions.
    */
    ret->xpathCtxt = xmlXPathNewContext(NULL);
    if (ret->xpathCtxt == NULL)
	goto internal_err;
#endif
    
    return(ret);

internal_err:
    xsltCompilationCtxtFree(ret);
    return(NULL);
}

static void
xsltLREEffectiveNsNodesFree(xsltEffectiveNsPtr first)
{
    xsltEffectiveNsPtr tmp;

    while (first != NULL) {
	tmp = first;
	first = first->nextInStore;
	xmlFree(tmp);
    }
}

static void
xsltFreePrincipalStylesheetData(xsltPrincipalStylesheetDataPtr data)
{
    if (data == NULL)
	return;

    if (data->inScopeNamespaces != NULL) {
	int i;
	xsltNsListContainerPtr nsi;
	xsltPointerListPtr list =
	    (xsltPointerListPtr) data->inScopeNamespaces;

	for (i = 0; i < list->number; i++) {
	    /*
	    * REVISIT TODO: Free info of in-scope namespaces.
	    */
	    nsi = (xsltNsListContainerPtr) list->items[i];
	    if (nsi->list != NULL)
		xmlFree(nsi->list);
	    xmlFree(nsi);
	}
	xsltPointerListFree(list);
	data->inScopeNamespaces = NULL;
    }

    if (data->exclResultNamespaces != NULL) {
	int i;
	xsltPointerListPtr list = (xsltPointerListPtr)
	    data->exclResultNamespaces;	
	
	for (i = 0; i < list->number; i++)
	    xsltPointerListFree((xsltPointerListPtr) list->items[i]);
	
	xsltPointerListFree(list);
	data->exclResultNamespaces = NULL;
    }

    if (data->extElemNamespaces != NULL) {
	xsltPointerListPtr list = (xsltPointerListPtr)
	    data->extElemNamespaces;
	int i;

	for (i = 0; i < list->number; i++)
	    xsltPointerListFree((xsltPointerListPtr) list->items[i]);

	xsltPointerListFree(list);
	data->extElemNamespaces = NULL;
    }
    if (data->effectiveNs) {
	xsltLREEffectiveNsNodesFree(data->effectiveNs);
	data->effectiveNs = NULL;
    }
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
    xsltFreeNamespaceMap(data->nsMap);
#endif
    xmlFree(data);
}

static xsltPrincipalStylesheetDataPtr
xsltNewPrincipalStylesheetData(void)
{
    xsltPrincipalStylesheetDataPtr ret;

    ret = (xsltPrincipalStylesheetDataPtr)
	xmlMalloc(sizeof(xsltPrincipalStylesheetData));
    if (ret == NULL) {
	xsltTransformError(NULL, NULL, NULL,
	    "xsltNewPrincipalStylesheetData: memory allocation failed.\n");
	return(NULL);
    }
    memset(ret, 0, sizeof(xsltPrincipalStylesheetData));
    
    /*
    * Global list of in-scope namespaces.
    */    
    ret->inScopeNamespaces = xsltPointerListCreate(-1);
    if (ret->inScopeNamespaces == NULL)
	goto internal_err;
    /*
    * Global list of excluded result ns-decls.
    */
    ret->exclResultNamespaces = xsltPointerListCreate(-1);
    if (ret->exclResultNamespaces == NULL)
	goto internal_err;
    /*
    * Global list of extension instruction namespace names.
    */    
    ret->extElemNamespaces = xsltPointerListCreate(-1);
    if (ret->extElemNamespaces == NULL)
	goto internal_err;

    return(ret);

internal_err:

    return(NULL);
}

#endif

/**
 * xsltNewStylesheet:
 *
 * Create a new XSLT Stylesheet
 *
 * Returns the newly allocated xsltStylesheetPtr or NULL in case of error
 */
xsltStylesheetPtr
xsltNewStylesheet(void) {
    xsltStylesheetPtr ret = NULL;    

    ret = (xsltStylesheetPtr) xmlMalloc(sizeof(xsltStylesheet));
    if (ret == NULL) {
	xsltTransformError(NULL, NULL, NULL,
		"xsltNewStylesheet : malloc failed\n");
	goto internal_err;
    }
    memset(ret, 0, sizeof(xsltStylesheet));

    ret->omitXmlDeclaration = -1;
    ret->standalone = -1;
    ret->decimalFormat = xsltNewDecimalFormat(NULL);
    ret->indent = -1;
    ret->errors = 0;
    ret->warnings = 0;
    ret->exclPrefixNr = 0;
    ret->exclPrefixMax = 0;
    ret->exclPrefixTab = NULL;
    ret->extInfos = NULL;
    ret->extrasNr = 0;
    ret->internalized = 1;
    ret->literal_result = 0;
    ret->dict = xmlDictCreate();
#ifdef WITH_XSLT_DEBUG
    xsltGenericDebug(xsltGenericDebugContext,
	"creating dictionary for stylesheet\n");
#endif

    xsltInit();

    return(ret);

internal_err:
    if (ret != NULL)
	xsltFreeStylesheet(ret);
    return(NULL);
}

/**
 * xsltAllocateExtra:
 * @style:  an XSLT stylesheet
 *
 * Allocate an extra runtime information slot statically while compiling
 * the stylesheet and return its number
 *
 * Returns the number of the slot
 */
int
xsltAllocateExtra(xsltStylesheetPtr style)
{
    return(style->extrasNr++);
}

/**
 * xsltAllocateExtraCtxt:
 * @ctxt:  an XSLT transformation context
 *
 * Allocate an extra runtime information slot at run-time
 * and return its number
 * This make sure there is a slot ready in the transformation context
 *
 * Returns the number of the slot
 */
int
xsltAllocateExtraCtxt(xsltTransformContextPtr ctxt)
{
    if (ctxt->extrasNr >= ctxt->extrasMax) {
	int i;
	if (ctxt->extrasNr == 0) {
	    ctxt->extrasMax = 20;
	    ctxt->extras = (xsltRuntimeExtraPtr)
		xmlMalloc(ctxt->extrasMax * sizeof(xsltRuntimeExtra));
	    if (ctxt->extras == NULL) {
		xmlGenericError(xmlGenericErrorContext,
			"xsltAllocateExtraCtxt: out of memory\n");
		ctxt->state = XSLT_STATE_ERROR;
		return(0);
	    }
	    for (i = 0;i < ctxt->extrasMax;i++) {
		ctxt->extras[i].info = NULL;
		ctxt->extras[i].deallocate = NULL;
		ctxt->extras[i].val.ptr = NULL;
	    }

	} else {
	    xsltRuntimeExtraPtr tmp;

	    ctxt->extrasMax += 100;
	    tmp = (xsltRuntimeExtraPtr) xmlRealloc(ctxt->extras,
		            ctxt->extrasMax * sizeof(xsltRuntimeExtra));
	    if (tmp == NULL) {
		xmlGenericError(xmlGenericErrorContext,
			"xsltAllocateExtraCtxt: out of memory\n");
		ctxt->state = XSLT_STATE_ERROR;
		return(0);
	    }
	    ctxt->extras = tmp;
	    for (i = ctxt->extrasNr;i < ctxt->extrasMax;i++) {
		ctxt->extras[i].info = NULL;
		ctxt->extras[i].deallocate = NULL;
		ctxt->extras[i].val.ptr = NULL;
	    }
	}
    }
    return(ctxt->extrasNr++);
}

/**
 * xsltFreeStylesheetList:
 * @style:  an XSLT stylesheet list
 *
 * Free up the memory allocated by the list @style
 */
static void
xsltFreeStylesheetList(xsltStylesheetPtr style) {
    xsltStylesheetPtr next;

    while (style != NULL) {
	next = style->next;
	xsltFreeStylesheet(style);
	style = next;
    }
}

/**
 * xsltCleanupStylesheetTree:
 *
 * @doc: the document-node
 * @node: the element where the stylesheet is rooted at
 *
 * Actually @node need not be the document-element, but
 * currently Libxslt does not support embedded stylesheets.
 *
 * Returns 0 if OK, -1 on API or internal errors.
 */
static int
xsltCleanupStylesheetTree(xmlDocPtr doc ATTRIBUTE_UNUSED,
			  xmlNodePtr rootElem ATTRIBUTE_UNUSED)
{    
#if 0 /* TODO: Currently disabled, since probably not needed. */
    xmlNodePtr cur;

    if ((doc == NULL) || (rootElem == NULL) ||
	(rootElem->type != XML_ELEMENT_NODE) ||
	(doc != rootElem->doc))
	return(-1);

    /*
    * Cleanup was suggested by Aleksey Sanin:
    * Clear the PSVI field to avoid problems if the
    * node-tree of the stylesheet is intended to be used for
    * further processing by the user (e.g. for compiling it
    * once again - although not recommended).
    */

    cur = rootElem;
    while (cur != NULL) {
	if (cur->type == XML_ELEMENT_NODE) {
	    /*
	    * Clear the PSVI field.
	    */
	    cur->psvi = NULL;
	    if (cur->children) {
		cur = cur->children;
		continue;
	    }
	}

leave_node:
	if (cur == rootElem)
	    break;
	if (cur->next != NULL)
	    cur = cur->next;
	else {
	    cur = cur->parent;
	    if (cur == NULL)
		break;
	    goto leave_node;
	}
    }
#endif /* #if 0 */
    return(0);
}

/**
 * xsltFreeStylesheet:
 * @style:  an XSLT stylesheet
 *
 * Free up the memory allocated by @style
 */
void
xsltFreeStylesheet(xsltStylesheetPtr style)
{
    if (style == NULL)
        return;
    
#ifdef XSLT_REFACTORED
    /*
    * Start with a cleanup of the main stylesheet's doc.
    */
    if ((style->principal == style) && (style->doc))
	xsltCleanupStylesheetTree(style->doc,
	    xmlDocGetRootElement(style->doc));
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
    /*
    * Restore changed ns-decls before freeing the document.
    */
    if ((style->doc != NULL) &&
	XSLT_HAS_INTERNAL_NSMAP(style))
    {
	xsltRestoreDocumentNamespaces(XSLT_GET_INTERNAL_NSMAP(style),
	    style->doc);	
    }
#endif /* XSLT_REFACTORED_XSLT_NSCOMP */
#else
    /*
    * Start with a cleanup of the main stylesheet's doc.
    */
    if ((style->parent == NULL) && (style->doc))
	xsltCleanupStylesheetTree(style->doc,
	    xmlDocGetRootElement(style->doc));
#endif /* XSLT_REFACTORED */

    xsltFreeKeys(style);
    xsltFreeExts(style);
    xsltFreeTemplateHashes(style);
    xsltFreeDecimalFormatList(style);
    xsltFreeTemplateList(style->templates);
    xsltFreeAttributeSetsHashes(style);
    xsltFreeNamespaceAliasHashes(style);
    xsltFreeStylePreComps(style);
    /*
    * Free documents of all included stylsheet modules of this
    * stylesheet level.
    */
    xsltFreeStyleDocuments(style);
    /*
    * TODO: Best time to shutdown extension stuff?
    */
    xsltShutdownExts(style);
       
    if (style->variables != NULL)
        xsltFreeStackElemList(style->variables);
    if (style->cdataSection != NULL)
        xmlHashFree(style->cdataSection, NULL);
    if (style->stripSpaces != NULL)
        xmlHashFree(style->stripSpaces, NULL);
    if (style->nsHash != NULL)
        xmlHashFree(style->nsHash, NULL);
    if (style->exclPrefixTab != NULL)
        xmlFree(style->exclPrefixTab);
    if (style->method != NULL)
        xmlFree(style->method);
    if (style->methodURI != NULL)
        xmlFree(style->methodURI);
    if (style->version != NULL)
        xmlFree(style->version);
    if (style->encoding != NULL)
        xmlFree(style->encoding);
    if (style->doctypePublic != NULL)
        xmlFree(style->doctypePublic);
    if (style->doctypeSystem != NULL)
        xmlFree(style->doctypeSystem);
    if (style->mediaType != NULL)
        xmlFree(style->mediaType);
    if (style->attVTs)
        xsltFreeAVTList(style->attVTs);
    if (style->imports != NULL)
        xsltFreeStylesheetList(style->imports);

#ifdef XSLT_REFACTORED
    /*
    * If this is the principal stylesheet, then
    * free its internal data.
    */
    if (style->principal == style) {
	if (style->principalData) {
	    xsltFreePrincipalStylesheetData(style->principalData);
	    style->principalData = NULL;
	}
    }    
#endif
    /*
    * Better to free the main document of this stylesheet level
    * at the end - so here.
    */
    if (style->doc != NULL) {	
        xmlFreeDoc(style->doc);
    }

#ifdef WITH_XSLT_DEBUG
    xsltGenericDebug(xsltGenericDebugContext,
                     "freeing dictionary from stylesheet\n");
#endif
    xmlDictFree(style->dict);

    memset(style, -1, sizeof(xsltStylesheet));
    xmlFree(style);
}

/************************************************************************
 *									*
 *		Parsing of an XSLT Stylesheet				*
 *									*
 ************************************************************************/

#ifdef XSLT_REFACTORED
    /*
    * This is now performed in an optimized way in xsltParseXSLTTemplate.
    */
#else
/**
 * xsltGetInheritedNsList:
 * @style:  the stylesheet
 * @template: the template
 * @node:  the current node
 *
 * Search all the namespace applying to a given element except the ones 
 * from excluded output prefixes currently in scope. Initialize the
 * template inheritedNs list with it.
 *
 * Returns the number of entries found
 */
static int
xsltGetInheritedNsList(xsltStylesheetPtr style,
	               xsltTemplatePtr template,
	               xmlNodePtr node)
{
    xmlNsPtr cur;
    xmlNsPtr *ret = NULL;
    int nbns = 0;
    int maxns = 10;
    int i;    

    if ((style == NULL) || (template == NULL) || (node == NULL) ||
	(template->inheritedNsNr != 0) || (template->inheritedNs != NULL))
	return(0);
    while (node != NULL) {
        if (node->type == XML_ELEMENT_NODE) {
            cur = node->nsDef;
            while (cur != NULL) {
		if (xmlStrEqual(cur->href, XSLT_NAMESPACE))
		    goto skip_ns;

		if ((cur->prefix != NULL) &&
		    (xsltCheckExtPrefix(style, cur->prefix)))
		    goto skip_ns;
		/*
		* Check if this namespace was excluded.
		* Note that at this point only the exclusions defined
		* on the topmost stylesheet element are in the exclusion-list.
		*/
		for (i = 0;i < style->exclPrefixNr;i++) {
		    if (xmlStrEqual(cur->href, style->exclPrefixTab[i]))
			goto skip_ns;
		}
                if (ret == NULL) {
                    ret =
                        (xmlNsPtr *) xmlMalloc((maxns + 1) *
                                               sizeof(xmlNsPtr));
                    if (ret == NULL) {
                        xmlGenericError(xmlGenericErrorContext,
                                        "xsltGetInheritedNsList : out of memory!\n");
                        return(0);
                    }
                    ret[nbns] = NULL;
                }
		/*
		* Skip shadowed namespace bindings.
		*/
                for (i = 0; i < nbns; i++) {
                    if ((cur->prefix == ret[i]->prefix) ||
                        (xmlStrEqual(cur->prefix, ret[i]->prefix)))
                        break;
                }
                if (i >= nbns) {
                    if (nbns >= maxns) {
                        maxns *= 2;
                        ret = (xmlNsPtr *) xmlRealloc(ret,
                                                      (maxns +
                                                       1) *
                                                      sizeof(xmlNsPtr));
                        if (ret == NULL) {
                            xmlGenericError(xmlGenericErrorContext,
                                            "xsltGetInheritedNsList : realloc failed!\n");
                            return(0);
                        }
                    }
                    ret[nbns++] = cur;
                    ret[nbns] = NULL;
                }
skip_ns:
                cur = cur->next;
            }
        }
        node = node->parent;
    }
    if (nbns != 0) {
#ifdef WITH_XSLT_DEBUG_PARSING
        xsltGenericDebug(xsltGenericDebugContext,
                         "template has %d inherited namespaces\n", nbns);
#endif
	template->inheritedNsNr = nbns;
	template->inheritedNs = ret;
    }
    return (nbns);
}
#endif /* else of XSLT_REFACTORED */

/**
 * xsltParseStylesheetOutput:
 * @style:  the XSLT stylesheet
 * @cur:  the "output" element
 *
 * parse an XSLT stylesheet output element and record
 * information related to the stylesheet output
 */

void
xsltParseStylesheetOutput(xsltStylesheetPtr style, xmlNodePtr cur)
{
    xmlChar *elements,
     *prop;
    xmlChar *element,
     *end;

    if ((cur == NULL) || (style == NULL))
        return;
   
    prop = xmlGetNsProp(cur, (const xmlChar *) "version", NULL);
    if (prop != NULL) {
        if (style->version != NULL)
            xmlFree(style->version);
        style->version = prop;
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "encoding", NULL);
    if (prop != NULL) {
        if (style->encoding != NULL)
            xmlFree(style->encoding);
        style->encoding = prop;
    }

    /* relaxed to support xt:document
    * TODO KB: What does "relaxed to support xt:document" mean?
    */
    prop = xmlGetNsProp(cur, (const xmlChar *) "method", NULL);
    if (prop != NULL) {
        const xmlChar *URI;

        if (style->method != NULL)
            xmlFree(style->method);
        style->method = NULL;
        if (style->methodURI != NULL)
            xmlFree(style->methodURI);
        style->methodURI = NULL;

	/*
	* TODO: Don't use xsltGetQNameURI().
	*/
	URI = xsltGetQNameURI(cur, &prop);
	if (prop == NULL) {
	    if (style != NULL) style->errors++;
	} else if (URI == NULL) {
            if ((xmlStrEqual(prop, (const xmlChar *) "xml")) ||
                (xmlStrEqual(prop, (const xmlChar *) "html")) ||
                (xmlStrEqual(prop, (const xmlChar *) "text"))) {
                style->method = prop;
            } else {
		xsltTransformError(NULL, style, cur,
                                 "invalid value for method: %s\n", prop);
                if (style != NULL) style->warnings++;
            }
	} else {
	    style->method = prop;
	    style->methodURI = xmlStrdup(URI);
	}
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "doctype-system", NULL);
    if (prop != NULL) {
        if (style->doctypeSystem != NULL)
            xmlFree(style->doctypeSystem);
        style->doctypeSystem = prop;
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "doctype-public", NULL);
    if (prop != NULL) {
        if (style->doctypePublic != NULL)
            xmlFree(style->doctypePublic);
        style->doctypePublic = prop;
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "standalone", NULL);
    if (prop != NULL) {
        if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
            style->standalone = 1;
        } else if (xmlStrEqual(prop, (const xmlChar *) "no")) {
            style->standalone = 0;
        } else {
	    xsltTransformError(NULL, style, cur,
                             "invalid value for standalone: %s\n", prop);
            style->errors++;
        }
        xmlFree(prop);
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "indent", NULL);
    if (prop != NULL) {
        if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
            style->indent = 1;
        } else if (xmlStrEqual(prop, (const xmlChar *) "no")) {
            style->indent = 0;
        } else {
	    xsltTransformError(NULL, style, cur,
                             "invalid value for indent: %s\n", prop);
            style->errors++;
        }
        xmlFree(prop);
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "omit-xml-declaration", NULL);
    if (prop != NULL) {
        if (xmlStrEqual(prop, (const xmlChar *) "yes")) {
            style->omitXmlDeclaration = 1;
        } else if (xmlStrEqual(prop, (const xmlChar *) "no")) {
            style->omitXmlDeclaration = 0;
        } else {
	    xsltTransformError(NULL, style, cur,
                             "invalid value for omit-xml-declaration: %s\n",
                             prop);
            style->errors++;
        }
        xmlFree(prop);
    }

    elements = xmlGetNsProp(cur, (const xmlChar *) "cdata-section-elements",
	NULL);
    if (elements != NULL) {
        if (style->cdataSection == NULL)
            style->cdataSection = xmlHashCreate(10);
        if (style->cdataSection == NULL)
            return;

        element = elements;
        while (*element != 0) {
            while (IS_BLANK(*element))
                element++;
            if (*element == 0)
                break;
            end = element;
            while ((*end != 0) && (!IS_BLANK(*end)))
                end++;
            element = xmlStrndup(element, end - element);
            if (element) {		
#ifdef WITH_XSLT_DEBUG_PARSING
                xsltGenericDebug(xsltGenericDebugContext,
                                 "add cdata section output element %s\n",
                                 element);
#endif
		if (xmlValidateQName(BAD_CAST element, 0) != 0) {
		    xsltTransformError(NULL, style, cur,
			"Attribute 'cdata-section-elements': The value "
			"'%s' is not a valid QName.\n", element);
		    xmlFree(element);
		    style->errors++;
		} else {
		    const xmlChar *URI;

		    /*
		    * TODO: Don't use xsltGetQNameURI().
		    */
		    URI = xsltGetQNameURI(cur, &element);
		    if (element == NULL) {
			/*
			* TODO: We'll report additionally an error
			*  via the stylesheet's error handling.			
			*/
			xsltTransformError(NULL, style, cur,
			    "Attribute 'cdata-section-elements': The value "
			    "'%s' is not a valid QName.\n", element);
			style->errors++;
		    } else {
			xmlNsPtr ns;
			
			/*
			* XSLT-1.0 "Each QName is expanded into an
			*  expanded-name using the namespace declarations in
			*  effect on the xsl:output element in which the QName
			*  occurs; if there is a default namespace, it is used
			*  for QNames that do not have a prefix"
			* NOTE: Fix of bug #339570.
			*/
			if (URI == NULL) {
			    ns = xmlSearchNs(style->doc, cur, NULL);
			    if (ns != NULL)
				URI = ns->href;
			}		   
			xmlHashAddEntry2(style->cdataSection, element, URI,
			    (void *) "cdata");
			xmlFree(element);
		    }
		}
            }
            element = end;
        }
        xmlFree(elements);
    }

    prop = xmlGetNsProp(cur, (const xmlChar *) "media-type", NULL);
    if (prop != NULL) {
	if (style->mediaType)
	    xmlFree(style->mediaType);
	style->mediaType = prop;
    }
    if (cur->children != NULL) {
	xsltParseContentError(style, cur->children);
    }
}

/**
 * xsltParseStylesheetDecimalFormat:
 * @style:  the XSLT stylesheet
 * @cur:  the "decimal-format" element
 *
 * <!-- Category: top-level-element -->
 * <xsl:decimal-format
 *   name = qname, decimal-separator = char, grouping-separator = char,
 *   infinity = string, minus-sign = char, NaN = string, percent = char
 *   per-mille = char, zero-digit = char, digit = char,
 * pattern-separator = char />
 *
 * parse an XSLT stylesheet decimal-format element and
 * and record the formatting characteristics
 */
static void
xsltParseStylesheetDecimalFormat(xsltStylesheetPtr style, xmlNodePtr cur)
{
    xmlChar *prop;
    xsltDecimalFormatPtr format;
    xsltDecimalFormatPtr iter;
    
    if ((cur == NULL) || (style == NULL))
	return;

    format = style->decimalFormat;
    
    prop = xmlGetNsProp(cur, BAD_CAST("name"), NULL);
    if (prop != NULL) {
	format = xsltDecimalFormatGetByName(style, prop);
	if (format != NULL) {
	    xsltTransformError(NULL, style, cur,
	 "xsltParseStylestyleDecimalFormat: %s already exists\n", prop);
	    if (style != NULL) style->warnings++;
	    return;
	}
	format = xsltNewDecimalFormat(prop);
	if (format == NULL) {
	    xsltTransformError(NULL, style, cur,
     "xsltParseStylestyleDecimalFormat: failed creating new decimal-format\n");
	    if (style != NULL) style->errors++;
	    return;
	}
	/* Append new decimal-format structure */
	for (iter = style->decimalFormat; iter->next; iter = iter->next)
	    ;
	if (iter)
	    iter->next = format;
    }

    prop = xmlGetNsProp(cur, (const xmlChar *)"decimal-separator", NULL);
    if (prop != NULL) {
	if (format->decimalPoint != NULL) xmlFree(format->decimalPoint);
	format->decimalPoint  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"grouping-separator", NULL);
    if (prop != NULL) {
	if (format->grouping != NULL) xmlFree(format->grouping);
	format->grouping  = prop;
    }

    prop = xmlGetNsProp(cur, (const xmlChar *)"infinity", NULL);
    if (prop != NULL) {
	if (format->infinity != NULL) xmlFree(format->infinity);
	format->infinity  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"minus-sign", NULL);
    if (prop != NULL) {
	if (format->minusSign != NULL) xmlFree(format->minusSign);
	format->minusSign  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"NaN", NULL);
    if (prop != NULL) {
	if (format->noNumber != NULL) xmlFree(format->noNumber);
	format->noNumber  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"percent", NULL);
    if (prop != NULL) {
	if (format->percent != NULL) xmlFree(format->percent);
	format->percent  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"per-mille", NULL);
    if (prop != NULL) {
	if (format->permille != NULL) xmlFree(format->permille);
	format->permille  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"zero-digit", NULL);
    if (prop != NULL) {
	if (format->zeroDigit != NULL) xmlFree(format->zeroDigit);
	format->zeroDigit  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"digit", NULL);
    if (prop != NULL) {
	if (format->digit != NULL) xmlFree(format->digit);
	format->digit  = prop;
    }
    
    prop = xmlGetNsProp(cur, (const xmlChar *)"pattern-separator", NULL);
    if (prop != NULL) {
	if (format->patternSeparator != NULL) xmlFree(format->patternSeparator);
	format->patternSeparator  = prop;
    }
    if (cur->children != NULL) {
	xsltParseContentError(style, cur->children);
    }
}

/**
 * xsltParseStylesheetPreserveSpace:
 * @style:  the XSLT stylesheet
 * @cur:  the "preserve-space" element
 *
 * parse an XSLT stylesheet preserve-space element and record
 * elements needing preserving
 */

static void
xsltParseStylesheetPreserveSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
    xmlChar *elements;
    xmlChar *element, *end;

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

    elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL);
    if (elements == NULL) {
	xsltTransformError(NULL, style, cur,
	    "xsltParseStylesheetPreserveSpace: missing elements attribute\n");
	if (style != NULL) style->warnings++;
	return;
    }

    if (style->stripSpaces == NULL)
	style->stripSpaces = xmlHashCreate(10);
    if (style->stripSpaces == NULL)
	return;

    element = elements;
    while (*element != 0) {
	while (IS_BLANK(*element)) element++;
	if (*element == 0)
	    break;
        end = element;
	while ((*end != 0) && (!IS_BLANK(*end))) end++;
	element = xmlStrndup(element, end - element);
	if (element) {
#ifdef WITH_XSLT_DEBUG_PARSING
	    xsltGenericDebug(xsltGenericDebugContext,
		"add preserved space element %s\n", element);
#endif
	    if (xmlStrEqual(element, (const xmlChar *)"*")) {
		style->stripAll = -1;
	    } else {
		const xmlChar *URI;

		/*
		* TODO: Don't use xsltGetQNameURI().
		*/
                URI = xsltGetQNameURI(cur, &element);

		xmlHashAddEntry2(style->stripSpaces, element, URI,
				(xmlChar *) "preserve");
	    }
	    xmlFree(element);
	}
	element = end;
    }
    xmlFree(elements);
    if (cur->children != NULL) {
	xsltParseContentError(style, cur->children);
    }
}

#ifdef XSLT_REFACTORED
#else
/**
 * xsltParseStylesheetExtPrefix:
 * @style:  the XSLT stylesheet
 * @template:  the "extension-element-prefixes" prefix
 *
 * parse an XSLT stylesheet's "extension-element-prefix" attribute value
 * and register the namespaces of extension instruction.
 * SPEC "A namespace is designated as an extension namespace by using
 *   an extension-element-prefixes attribute on:
 *   1) an xsl:stylesheet element
 *   2) an xsl:extension-element-prefixes attribute on a
 *      literal result element 
 *   3) an extension instruction."
 */
static void
xsltParseStylesheetExtPrefix(xsltStylesheetPtr style, xmlNodePtr cur,
			     int isXsltElem) {
    xmlChar *prefixes;
    xmlChar *prefix, *end;

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

    if (isXsltElem) {
	/* For xsl:stylesheet/xsl:transform. */
	prefixes = xmlGetNsProp(cur,
	    (const xmlChar *)"extension-element-prefixes", NULL);
    } else {
	/* For literal result elements and extension instructions. */
	prefixes = xmlGetNsProp(cur,
	    (const xmlChar *)"extension-element-prefixes", XSLT_NAMESPACE);
    }
    if (prefixes == NULL) {
	return;
    }

    prefix = prefixes;
    while (*prefix != 0) {
	while (IS_BLANK(*prefix)) prefix++;
	if (*prefix == 0)
	    break;
        end = prefix;
	while ((*end != 0) && (!IS_BLANK(*end))) end++;
	prefix = xmlStrndup(prefix, end - prefix);
	if (prefix) {
	    xmlNsPtr ns;

	    if (xmlStrEqual(prefix, (const xmlChar *)"#default"))
		ns = xmlSearchNs(style->doc, cur, NULL);
	    else
		ns = xmlSearchNs(style->doc, cur, prefix);
	    if (ns == NULL) {
		xsltTransformError(NULL, style, cur,
	    "xsl:extension-element-prefix : undefined namespace %s\n",
	                         prefix);
		if (style != NULL) style->warnings++;
	    } else {
#ifdef WITH_XSLT_DEBUG_PARSING
		xsltGenericDebug(xsltGenericDebugContext,
		    "add extension prefix %s\n", prefix);
#endif
		xsltRegisterExtPrefix(style, prefix, ns->href);
	    }
	    xmlFree(prefix);
	}
	prefix = end;
    }
    xmlFree(prefixes);
}
#endif /* else of XSLT_REFACTORED */

/**
 * xsltParseStylesheetStripSpace:
 * @style:  the XSLT stylesheet
 * @cur:  the "strip-space" element
 *
 * parse an XSLT stylesheet's strip-space element and record
 * the elements needing stripping
 */

static void
xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
    xmlChar *elements;
    xmlChar *element, *end;

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

    elements = xmlGetNsProp(cur, (const xmlChar *)"elements", NULL);
    if (elements == NULL) {
	xsltTransformError(NULL, style, cur,
	    "xsltParseStylesheetStripSpace: missing elements attribute\n");
	if (style != NULL) style->warnings++;
	return;
    }

    if (style->stripSpaces == NULL)
	style->stripSpaces = xmlHashCreate(10);
    if (style->stripSpaces == NULL)
	return;

    element = elements;
    while (*element != 0) {
	while (IS_BLANK(*element)) element++;
	if (*element == 0)
	    break;
        end = element;
	while ((*end != 0) && (!IS_BLANK(*end))) end++;
	element = xmlStrndup(element, end - element);
	if (element) {
#ifdef WITH_XSLT_DEBUG_PARSING
	    xsltGenericDebug(xsltGenericDebugContext,
		"add stripped space element %s\n", element);
#endif
	    if (xmlStrEqual(element, (const xmlChar *)"*")) {
		style->stripAll = 1;
	    } else {
		const xmlChar *URI;

		/*
		* TODO: Don't use xsltGetQNameURI().
		*/
                URI = xsltGetQNameURI(cur, &element);

		xmlHashAddEntry2(style->stripSpaces, element, URI,
			        (xmlChar *) "strip");
	    }
	    xmlFree(element);
	}
	element = end;
    }
    xmlFree(elements);
    if (cur->children != NULL) {
	xsltParseContentError(style, cur->children);
    }
}

#ifdef XSLT_REFACTORED
#else
/**
 * xsltParseStylesheetExcludePrefix:
 * @style:  the XSLT stylesheet
 * @cur:  the current point in the stylesheet
 *
 * parse an XSLT stylesheet exclude prefix and record
 * namespaces needing stripping
 *
 * Returns the number of Excluded prefixes added at that level
 */

static int
xsltParseStylesheetExcludePrefix(xsltStylesheetPtr style, xmlNodePtr cur,
				 int isXsltElem)
{
    int nb = 0;
    xmlChar *prefixes;
    xmlChar *prefix, *end;

    if ((cur == NULL) || (style == NULL))
	return(0);

    if (isXsltElem)
	prefixes = xmlGetNsProp(cur,
	    (const xmlChar *)"exclude-result-prefixes", NULL);
    else
	prefixes = xmlGetNsProp(cur,
	    (const xmlChar *)"exclude-result-prefixes", XSLT_NAMESPACE);

    if (prefixes == NULL) {
	return(0);
    }

    prefix = prefixes;
    while (*prefix != 0) {
	while (IS_BLANK(*prefix)) prefix++;
	if (*prefix == 0)
	    break;
        end = prefix;
	while ((*end != 0) && (!IS_BLANK(*end))) end++;
	prefix = xmlStrndup(prefix, end - prefix);
	if (prefix) {
	    xmlNsPtr ns;

	    if (xmlStrEqual(prefix, (const xmlChar *)"#default"))
		ns = xmlSearchNs(style->doc, cur, NULL);
	    else
		ns = xmlSearchNs(style->doc, cur, prefix);
	    if (ns == NULL) {
		xsltTransformError(NULL, style, cur,
	    "xsl:exclude-result-prefixes : undefined namespace %s\n",
	                         prefix);
		if (style != NULL) style->warnings++;
	    } else {
		if (exclPrefixPush(style, (xmlChar *) ns->href) >= 0) {
#ifdef WITH_XSLT_DEBUG_PARSING
		    xsltGenericDebug(xsltGenericDebugContext,
			"exclude result prefix %s\n", prefix);
#endif
		    nb++;
		}
	    }
	    xmlFree(prefix);
	}
	prefix = end;
    }
    xmlFree(prefixes);
    return(nb);
}
#endif /* else of XSLT_REFACTORED */

#ifdef XSLT_REFACTORED

/*
* xsltTreeEnsureXMLDecl:
* @doc: the doc
* 
* BIG NOTE:
*  This was copy&pasted from Libxml2's xmlTreeEnsureXMLDecl() in "tree.c".
* Ensures that there is an XML namespace declaration on the doc.
* 
* Returns the XML ns-struct or NULL on API and internal errors.
*/
static xmlNsPtr
xsltTreeEnsureXMLDecl(xmlDocPtr doc)
{
    if (doc == NULL)
	return (NULL);
    if (doc->oldNs != NULL)
	return (doc->oldNs);
    {
	xmlNsPtr ns;
	ns = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
	if (ns == NULL) {
	    xmlGenericError(xmlGenericErrorContext,
		"xsltTreeEnsureXMLDecl: Failed to allocate "
		"the XML namespace.\n");	
	    return (NULL);
	}
	memset(ns, 0, sizeof(xmlNs));
	ns->type = XML_LOCAL_NAMESPACE;
	/*
	* URGENT TODO: revisit this.
	*/
#ifdef LIBXML_NAMESPACE_DICT
	if (doc->dict)
	    ns->href = xmlDictLookup(doc->dict, XML_XML_NAMESPACE, -1);
	else
	    ns->href = xmlStrdup(XML_XML_NAMESPACE);
#else
	ns->href = xmlStrdup(XML_XML_NAMESPACE); 
#endif
	ns->prefix = xmlStrdup((const xmlChar *)"xml");
	doc->oldNs = ns;
	return (ns);
    }
}

/*
* xsltTreeAcquireStoredNs:
* @doc: the doc
* @nsName: the namespace name
* @prefix: the prefix
* 
* BIG NOTE:
*  This was copy&pasted from Libxml2's xmlDOMWrapStoreNs() in "tree.c".
* Creates or reuses an xmlNs struct on doc->oldNs with
* the given prefix and namespace name.
* 
* Returns the aquired ns struct or NULL in case of an API
*         or internal error.
*/
static xmlNsPtr
xsltTreeAcquireStoredNs(xmlDocPtr doc,
			const xmlChar *nsName,
			const xmlChar *prefix)
{
    xmlNsPtr ns;

    if (doc == NULL)
	return (NULL);
    if (doc->oldNs != NULL)
	ns = doc->oldNs;
    else
	ns = xsltTreeEnsureXMLDecl(doc);
    if (ns == NULL)
	return (NULL);
    if (ns->next != NULL) {
	/* Reuse. */
	ns = ns->next;
	while (ns != NULL) {
	    if ((ns->prefix == NULL) != (prefix == NULL)) {
		/* NOP */
	    } else if (prefix == NULL) {
		if (xmlStrEqual(ns->href, nsName))
		    return (ns);
	    } else {
		if ((ns->prefix[0] == prefix[0]) &&
		     xmlStrEqual(ns->prefix, prefix) &&
		     xmlStrEqual(ns->href, nsName))
		    return (ns);
		
	    }
	    if (ns->next == NULL)
		break;
	    ns = ns->next;
	}
    }
    /* Create. */
    ns->next = xmlNewNs(NULL, nsName, prefix);
    return (ns->next);
}

/**
 * xsltLREBuildEffectiveNs:
 *
 * Apply ns-aliasing on the namespace of the given @elem and
 * its attributes.
 */
static int
xsltLREBuildEffectiveNs(xsltCompilerCtxtPtr cctxt,
			xmlNodePtr elem)
{
    xmlNsPtr ns;
    xsltNsAliasPtr alias;

    if ((cctxt == NULL) || (elem == NULL))
	return(-1);
    if ((cctxt->nsAliases == NULL) || (! cctxt->hasNsAliases))
	return(0);

    alias = cctxt->nsAliases;    		
    while (alias != NULL) {
	if ( /* If both namespaces are NULL... */
	    ( (elem->ns == NULL) &&
	    ((alias->literalNs == NULL) ||
	    (alias->literalNs->href == NULL)) ) ||
	    /* ... or both namespace are equal */
	    ( (elem->ns != NULL) &&
	    (alias->literalNs != NULL) &&
	    xmlStrEqual(elem->ns->href, alias->literalNs->href) ) )
	{
	    if ((alias->targetNs != NULL) &&
		(alias->targetNs->href != NULL))
	    {
		/*
		* Convert namespace.
		*/
		if (elem->doc == alias->docOfTargetNs) {
		    /*
		    * This is the nice case: same docs.
		    * This will eventually assign a ns-decl which
		    * is shadowed, but this has no negative effect on
		    * the generation of the result tree.
		    */
		    elem->ns = alias->targetNs;
		} else {
		    /*
		    * This target xmlNs originates from a different
		    * stylesheet tree. Try to locate it in the
		    * in-scope namespaces.
		    * OPTIMIZE TODO: Use the compiler-node-info inScopeNs.
		    */
		    ns = xmlSearchNs(elem->doc, elem,
			alias->targetNs->prefix);		    
		    /*
		    * If no matching ns-decl found, then assign a
		    * ns-decl stored in xmlDoc.
		    */
		    if ((ns == NULL) ||
			(! xmlStrEqual(ns->href, alias->targetNs->href)))
		    {
			/*
			* BIG NOTE: The use of xsltTreeAcquireStoredNs()
			*  is not very efficient, but currently I don't
			*  see an other way of *safely* changing a node's
			*  namespace, since the xmlNs struct in
			*  alias->targetNs might come from an other
			*  stylesheet tree. So we need to anchor it in the
			*  current document, without adding it to the tree,
			*  which would otherwise change the in-scope-ns
			*  semantic of the tree.
			*/
			ns = xsltTreeAcquireStoredNs(elem->doc,
			    alias->targetNs->href,
			    alias->targetNs->prefix);
			
			if (ns == NULL) {
			    xsltTransformError(NULL, cctxt->style, elem,
				"Internal error in "
				"xsltLREBuildEffectiveNs(): "
				"failed to acquire a stored "
				"ns-declaration.\n");
			    cctxt->style->errors++;
			    return(-1);
			    
			}
		    }
		    elem->ns = ns;
		}		   
	    } else {
		/*
		* Move into or leave in the NULL namespace.
		*/
		elem->ns = NULL;
	    }
	    break;
	}
	alias = alias->next;
    }
    /*
    * Same with attributes of literal result elements.
    */
    if (elem->properties != NULL) {
	xmlAttrPtr attr = elem->properties;
	
	while (attr != NULL) {
	    if (attr->ns == NULL) {
		attr = attr->next;
		continue;
	    }
	    alias = cctxt->nsAliases;
	    while (alias != NULL) {
		if ( /* If both namespaces are NULL... */
		    ( (elem->ns == NULL) &&
		    ((alias->literalNs == NULL) ||
		    (alias->literalNs->href == NULL)) ) ||
		    /* ... or both namespace are equal */
		    ( (elem->ns != NULL) &&
		    (alias->literalNs != NULL) &&
		    xmlStrEqual(elem->ns->href, alias->literalNs->href) ) )
		{
		    if ((alias->targetNs != NULL) &&
			(alias->targetNs->href != NULL))
		    {		    
			if (elem->doc == alias->docOfTargetNs) {
			    elem->ns = alias->targetNs;
			} else {
			    ns = xmlSearchNs(elem->doc, elem,
				alias->targetNs->prefix);
			    if ((ns == NULL) ||
				(! xmlStrEqual(ns->href, alias->targetNs->href)))
			    {
				ns = xsltTreeAcquireStoredNs(elem->doc,
				    alias->targetNs->href,
				    alias->targetNs->prefix);
				
				if (ns == NULL) {
				    xsltTransformError(NULL, cctxt->style, elem,
					"Internal error in "
					"xsltLREBuildEffectiveNs(): "
					"failed to acquire a stored "
					"ns-declaration.\n");
				    cctxt->style->errors++;
				    return(-1);
				    
				}
			    }
			    elem->ns = ns;
			}
		    } else {
		    /*
		    * Move into or leave in the NULL namespace.
			*/
			elem->ns = NULL;
		    }
		    break;
		}
		alias = alias->next;
	    }
	    
	    attr = attr->next;
	}
    }
    return(0);
}

/**
 * xsltLREBuildEffectiveNsNodes:
 *
 * Computes the effective namespaces nodes for a literal result
 * element.
 * @effectiveNs is the set of effective ns-nodes
 *  on the literal result element, which will be added to the result
 *  element if not already existing in the result tree.
 *  This means that excluded namespaces (via exclude-result-prefixes,
 *  extension-element-prefixes and the XSLT namespace) not added
 *  to the set.
 *  Namespace-aliasing was applied on the @effectiveNs.
 */
static int
xsltLREBuildEffectiveNsNodes(xsltCompilerCtxtPtr cctxt,
			     xsltStyleItemLRElementInfoPtr item,
			     xmlNodePtr elem,
			     int isLRE)
{
    xmlNsPtr ns, tmpns;
    xsltEffectiveNsPtr effNs, lastEffNs = NULL;
    int i, j, holdByElem;
    xsltPointerListPtr extElemNs = cctxt->inode->extElemNs;
    xsltPointerListPtr exclResultNs = cctxt->inode->exclResultNs;

    if ((cctxt == NULL) || (cctxt->inode == NULL) || (elem == NULL) ||
	(item == NULL) || (item->effectiveNs != NULL))
	return(-1);

    if (item->inScopeNs == NULL)    
	return(0);

    extElemNs = cctxt->inode->extElemNs;
    exclResultNs = cctxt->inode->exclResultNs;

    for (i = 0; i < item->inScopeNs->totalNumber; i++) {
	ns = item->inScopeNs->list[i];
	/*
	* Skip namespaces designated as excluded namespaces
	* -------------------------------------------------
	*
	* XSLT-20 TODO: In XSLT 2.0 we need to keep namespaces
	*  which are target namespaces of namespace-aliases
	*  regardless if designated as excluded.
	*
	* Exclude the XSLT namespace.
	*/
	if (xmlStrEqual(ns->href, XSLT_NAMESPACE))
	    goto skip_ns;

	/*
	* Apply namespace aliasing
	* ------------------------
	*
	* SPEC XSLT 2.0
	*  "- A namespace node whose string value is a literal namespace
	*     URI is not copied to the result tree.
	*   - A namespace node whose string value is a target namespace URI
	*     is copied to the result tree, whether or not the URI
	*     identifies an excluded namespace."
	* 
	* NOTE: The ns-aliasing machanism is non-cascading.
	*  (checked with Saxon, Xalan and MSXML .NET).
	* URGENT TODO: is style->nsAliases the effective list of
	*  ns-aliases, or do we need to lookup the whole
	*  import-tree?
	* TODO: Get rid of import-tree lookup.
	*/
	if (cctxt->hasNsAliases) {
	    xsltNsAliasPtr alias;
	    /*
	    * First check for being a target namespace.
	    */
	    alias = cctxt->nsAliases;
	    do {
		/*
		* TODO: Is xmlns="" handled already?
		*/
		if ((alias->targetNs != NULL) &&
		    (xmlStrEqual(alias->targetNs->href, ns->href)))
		{
		    /*
		    * Recognized as a target namespace; use it regardless
		    * if excluded otherwise.
		    */
		    goto add_effective_ns;
		}
		alias = alias->next;
	    } while (alias != NULL);

	    alias = cctxt->nsAliases;
	    do {
		/*
		* TODO: Is xmlns="" handled already?
		*/
		if ((alias->literalNs != NULL) &&
		    (xmlStrEqual(alias->literalNs->href, ns->href)))
		{
		    /*
		    * Recognized as an namespace alias; do not use it.
		    */
		    goto skip_ns;
		}
		alias = alias->next;
	    } while (alias != NULL);
	}
	
	/*
	* Exclude excluded result namespaces.
	*/
	if (exclResultNs) {
	    for (j = 0; j < exclResultNs->number; j++)
		if (xmlStrEqual(ns->href, BAD_CAST exclResultNs->items[j]))
		    goto skip_ns;
	}
	/*
	* Exclude extension-element namespaces.
	*/
	if (extElemNs) {
	    for (j = 0; j < extElemNs->number; j++)
		if (xmlStrEqual(ns->href, BAD_CAST extElemNs->items[j]))
		    goto skip_ns;
	}

add_effective_ns:
	/*
	* OPTIMIZE TODO: This information may not be needed.
	*/
	if (isLRE && (elem->nsDef != NULL)) {
	    holdByElem = 0;
	    tmpns = elem->nsDef;
	    do {
		if (tmpns == ns) {
		    holdByElem = 1;
		    break;
		}
		tmpns = tmpns->next;
	    } while (tmpns != NULL);	    
	} else
	    holdByElem = 0;
	
	
	/*
	* Add the effective namespace declaration.
	*/
	effNs = (xsltEffectiveNsPtr) xmlMalloc(sizeof(xsltEffectiveNs));
	if (effNs == NULL) {
	    xsltTransformError(NULL, cctxt->style, elem,
		"Internal error in xsltLREBuildEffectiveNs(): "
		"failed to allocate memory.\n");
	    cctxt->style->errors++;
	    return(-1);
	}
	if (cctxt->psData->effectiveNs == NULL) {
	    cctxt->psData->effectiveNs = effNs;
	    effNs->nextInStore = NULL;	 
	} else {
	    effNs->nextInStore = cctxt->psData->effectiveNs;
	    cctxt->psData->effectiveNs = effNs;
	}

	effNs->next = NULL;
	effNs->prefix = ns->prefix;
	effNs->nsName = ns->href;
	effNs->holdByElem = holdByElem;
	
	if (lastEffNs == NULL)
	    item->effectiveNs = effNs;
	else
	    lastEffNs->next = effNs;
	lastEffNs = effNs;
	
skip_ns:
	{}
    }
    return(0);
}


/**
 * xsltLREInfoCreate:
 *
 * @isLRE: indicates if the given @elem is a literal result element
 *
 * Creates a new info for a literal result element.
 */
static int
xsltLREInfoCreate(xsltCompilerCtxtPtr cctxt,
		  xmlNodePtr elem,
		  int isLRE)
{
    xsltStyleItemLRElementInfoPtr item;

    if ((cctxt == NULL) || (cctxt->inode == NULL))
	return(-1);

    item = (xsltStyleItemLRElementInfoPtr)
	xmlMalloc(sizeof(xsltStyleItemLRElementInfo));
    if (item == NULL) {
	xsltTransformError(NULL, cctxt->style, NULL,
	    "Internal error in xsltLREInfoCreate(): "
	    "memory allocation failed.\n");
	cctxt->style->errors++;
	return(-1);
    }
    memset(item, 0, sizeof(xsltStyleItemLRElementInfo));
    item->type = XSLT_FUNC_LITERAL_RESULT_ELEMENT;
    /*
    * Store it in the stylesheet.
    */
    item->next = cctxt->style->preComps;
    cctxt->style->preComps = (xsltElemPreCompPtr) item;
    /*
    * @inScopeNs are used for execution of XPath expressions
    *  in AVTs.
    */
    item->inScopeNs = cctxt->inode->inScopeNs;
    
    if (elem)
	xsltLREBuildEffectiveNsNodes(cctxt, item, elem, isLRE);

    cctxt->inode->litResElemInfo = item;
    cctxt->inode->nsChanged = 0;
    cctxt->maxLREs++;
    return(0);
}

/**
 * xsltCompilerVarInfoPush: 
 * @cctxt: the compilation context
 * 
 * Pushes a new var/param info onto the stack.
 *
 * Returns the acquired variable info.
 */ 
static xsltVarInfoPtr
xsltCompilerVarInfoPush(xsltCompilerCtxtPtr cctxt,
				  xmlNodePtr inst,
				  const xmlChar *name,
				  const xmlChar *nsName)
{
    xsltVarInfoPtr ivar;

    if ((cctxt->ivar != NULL) && (cctxt->ivar->next != NULL)) {
	ivar = cctxt->ivar->next;
    } else if ((cctxt->ivar == NULL) && (cctxt->ivars != NULL)) {
	ivar = cctxt->ivars;
    } else {
	ivar = (xsltVarInfoPtr) xmlMalloc(sizeof(xsltVarInfo));
	if (ivar == NULL) {
	    xsltTransformError(NULL, cctxt->style, inst,
		"xsltParseInScopeVarPush: xmlMalloc() failed!\n");
	    cctxt->style->errors++;
	    return(NULL);
	}
	/* memset(retVar, 0, sizeof(xsltInScopeVar)); */
	if (cctxt->ivars == NULL) {
	    cctxt->ivars = ivar;
	    ivar->prev = NULL;
	} else {
	    cctxt->ivar->next = ivar;
	    ivar->prev = cctxt->ivar;
	}
	cctxt->ivar = ivar;
	ivar->next = NULL;
    }
    ivar->depth = cctxt->depth;
    ivar->name = name;
    ivar->nsName = nsName;
    return(ivar);
}

/**
 * xsltCompilerVarInfoPop: 
 * @cctxt: the compilation context
 * 
 * Pops all var/param infos from the stack, which
 * have the current depth.
 */ 
static void
xsltCompilerVarInfoPop(xsltCompilerCtxtPtr cctxt)
{

    while ((cctxt->ivar != NULL) &&
	(cctxt->ivar->depth > cctxt->depth))
    {
	cctxt->ivar = cctxt->ivar->prev;
    }
}

/*
* xsltCompilerNodePush:
*
* @cctxt: the compilation context
* @node: the node to be pushed (this can also be the doc-node)
*
* 
*
* Returns the current node info structure or
*         NULL in case of an internal error.
*/
static xsltCompilerNodeInfoPtr
xsltCompilerNodePush(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{    
    xsltCompilerNodeInfoPtr inode, iprev;

    if ((cctxt->inode != NULL) && (cctxt->inode->next != NULL)) {	
	inode = cctxt->inode->next;
    } else if ((cctxt->inode == NULL) && (cctxt->inodeList != NULL)) {
	inode = cctxt->inodeList;	
    } else {
	/*
	* Create a new node-info.
	*/
	inode = (xsltCompilerNodeInfoPtr)
	    xmlMalloc(sizeof(xsltCompilerNodeInfo));
	if (inode == NULL) {
	    xsltTransformError(NULL, cctxt->style, NULL,
		"xsltCompilerNodePush: malloc failed.\n");
	    return(NULL);
	}
	memset(inode, 0, sizeof(xsltCompilerNodeInfo));
	if (cctxt->inodeList == NULL)
	    cctxt->inodeList = inode;
	else {
	    cctxt->inodeLast->next = inode;
	    inode->prev = cctxt->inodeLast;
	}
	cctxt->inodeLast = inode;
	cctxt->maxNodeInfos++;	
	if (cctxt->inode == NULL) {
	    cctxt->inode = inode;
	    /*
	    * Create an initial literal result element info for
	    * the root of the stylesheet.
	    */
	    xsltLREInfoCreate(cctxt, NULL, 0);
	} 
    }       
    cctxt->depth++;
    cctxt->inode = inode;
    /*
    * REVISIT TODO: Keep the reset always complete.    
    * NOTE: Be carefull with the @node, since it might be
    *  a doc-node.
    */
    inode->node = node;
    inode->depth = cctxt->depth;
    inode->templ = NULL;
    inode->category = XSLT_ELEMENT_CATEGORY_XSLT;
    inode->type = 0;
    inode->item = NULL;
    inode->curChildType = 0;
    inode->extContentHandled = 0;
    inode->isRoot = 0;
    
    if (inode->prev != NULL) {
	iprev = inode->prev;
	/*
	* Inherit the following information:
	* ---------------------------------
	*
	* In-scope namespaces
	*/
	inode->inScopeNs = iprev->inScopeNs;
	/*
	* Info for literal result elements
	*/
	inode->litResElemInfo = iprev->litResElemInfo;
	inode->nsChanged = iprev->nsChanged;
	/*
	* Excluded result namespaces
	*/
	inode->exclResultNs = iprev->exclResultNs;
	/*
	* Extension instruction namespaces
	*/
	inode->extElemNs = iprev->extElemNs;
	/*
	* Whitespace preservation
	*/
	inode->preserveWhitespace = iprev->preserveWhitespace;
	/*
	* Forwards-compatible mode
	*/
	inode->forwardsCompat = iprev->forwardsCompat;	
    } else {
	inode->inScopeNs = NULL;
	inode->exclResultNs = NULL;
	inode->extElemNs = NULL;
	inode->preserveWhitespace = 0;
	inode->forwardsCompat = 0;
    }
    
    return(inode);
}

/*
* xsltCompilerNodePop:
*
* @cctxt: the compilation context
* @node: the node to be pushed (this can also be the doc-node)
*
* Pops the current node info.
*/
static void
xsltCompilerNodePop(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{    
    if (cctxt->inode == NULL) {
	xmlGenericError(xmlGenericErrorContext,
	    "xsltCompilerNodePop: Top-node mismatch.\n");
	return;
    }
    /*
    * NOTE: Be carefull with the @node, since it might be
    *  a doc-node.
    */
    if (cctxt->inode->node != node) {
	xmlGenericError(xmlGenericErrorContext,
	"xsltCompilerNodePop: Node mismatch.\n");
	goto mismatch;
    }
    if (cctxt->inode->depth != cctxt->depth) {
	xmlGenericError(xmlGenericErrorContext,
	"xsltCompilerNodePop: Depth mismatch.\n");
	goto mismatch;
    }
    /*
    * Pop information of variables.
    */
    if ((cctxt->ivar) && (cctxt->ivar->depth > cctxt->depth))
	xsltCompilerVarInfoPop(cctxt);

    cctxt->depth--;
    cctxt->inode = cctxt->inode->prev;
    if (cctxt->inode != NULL)
	cctxt->inode->curChildType = 0;
    return;

mismatch:
    {
	const xmlChar *nsName = NULL, *name = NULL;
	const xmlChar *infnsName = NULL, *infname = NULL;
	
	if (node) {
	    if (node->type == XML_ELEMENT_NODE) {
		name = node->name;
		if (node->ns != NULL)
		    nsName = node->ns->href;
		else
		    nsName = BAD_CAST "";
	    } else {
		name = BAD_CAST "#document";
		nsName = BAD_CAST "";
	    }
	} else
	    name = BAD_CAST "Not given";

	if (cctxt->inode->node) {
	    if (node->type == XML_ELEMENT_NODE) {
		infname = cctxt->inode->node->name;
		if (cctxt->inode->node->ns != NULL)
		    infnsName = cctxt->inode->node->ns->href;
		else
		    infnsName = BAD_CAST "";
	    } else {
		infname = BAD_CAST "#document";
		infnsName = BAD_CAST "";
	    }
	} else
	    infname = BAD_CAST "Not given";

	
	xmlGenericError(xmlGenericErrorContext,
	    "xsltCompilerNodePop: Given   : '%s' URI '%s'\n",
	    name, nsName);
	xmlGenericError(xmlGenericErrorContext,
	    "xsltCompilerNodePop: Expected: '%s' URI '%s'\n",
	    infname, infnsName);
    }
}

/*
* xsltCompilerBuildInScopeNsList:
*
* Create and store the list of in-scope namespaces for the given
* node in the stylesheet. If there are no changes in the in-scope
* namespaces then the last ns-info of the ancestor axis will be returned.
* Compilation-time only.
*
* Returns the ns-info or NULL if there are no namespaces in scope.
*/
static xsltNsListContainerPtr
xsltCompilerBuildInScopeNsList(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{
    xsltNsListContainerPtr nsi = NULL;
    xmlNsPtr *list = NULL, ns;
    int i, maxns = 5;
    /*
    * Create a new ns-list for this position in the node-tree.
    * xmlGetNsList() will return NULL, if there are no ns-decls in the
    * tree. Note that the ns-decl for the XML namespace is not added
    * to the resulting list; the XPath module handles the XML namespace
    * internally.
    */
    while (node != NULL) {
        if (node->type == XML_ELEMENT_NODE) {
            ns = node->nsDef;
            while (ns != NULL) {
                if (nsi == NULL) {
		    nsi = (xsltNsListContainerPtr)
			xmlMalloc(sizeof(xsltNsListContainer));
		    if (nsi == NULL) {
			xsltTransformError(NULL, cctxt->style, NULL,
			    "xsltCompilerBuildInScopeNsList: "
			    "malloc failed!\n");
			goto internal_err;
		    }
		    memset(nsi, 0, sizeof(xsltNsListContainer));
                    nsi->list =
                        (xmlNsPtr *) xmlMalloc(maxns * sizeof(xmlNsPtr));
                    if (nsi->list == NULL) {
			xsltTransformError(NULL, cctxt->style, NULL,
			    "xsltCompilerBuildInScopeNsList: "
			    "malloc failed!\n");
			goto internal_err;
                    }
                    nsi->list[0] = NULL;
                }
		/*
		* Skip shadowed namespace bindings.
		*/
                for (i = 0; i < nsi->totalNumber; i++) {
                    if ((ns->prefix == nsi->list[i]->prefix) ||
                        (xmlStrEqual(ns->prefix, nsi->list[i]->prefix)))
		    break;
                }
                if (i >= nsi->totalNumber) {
                    if (nsi->totalNumber +1 >= maxns) {
                        maxns *= 2;
			nsi->list =
			    (xmlNsPtr *) xmlRealloc(nsi->list,
				maxns * sizeof(xmlNsPtr));
                        if (nsi->list == NULL) {
                            xsltTransformError(NULL, cctxt->style, NULL,
				"xsltCompilerBuildInScopeNsList: "
				"realloc failed!\n");
				goto internal_err;
                        }
                    }
                    nsi->list[nsi->totalNumber++] = ns;
                    nsi->list[nsi->totalNumber] = NULL;
                }

                ns = ns->next;
            }
        }
        node = node->parent;
    }
    if (nsi == NULL)
	return(NULL);
    /*
    * Move the default namespace to last position.
    */
    nsi->xpathNumber = nsi->totalNumber;
    for (i = 0; i < nsi->totalNumber; i++) {
	if (nsi->list[i]->prefix == NULL) {
	    ns = nsi->list[i];
	    nsi->list[i] = nsi->list[nsi->totalNumber-1];
	    nsi->list[nsi->totalNumber-1] = ns;
	    nsi->xpathNumber--;
	    break;
	}
    }
    /*
    * Store the ns-list in the stylesheet.
    */
    if (xsltPointerListAddSize(
	(xsltPointerListPtr)cctxt->psData->inScopeNamespaces,
	(void *) nsi, 5) == -1)
    {	
	xmlFree(nsi);
	nsi = NULL;
	xsltTransformError(NULL, cctxt->style, NULL,
	    "xsltCompilerBuildInScopeNsList: failed to add ns-info.\n");
	goto internal_err;
    }
    /*
    * Notify of change in status wrt namespaces.
    */
    if (cctxt->inode != NULL)
	cctxt->inode->nsChanged = 1;

    return(nsi);

internal_err:
    if (list != NULL)
	xmlFree(list);    
    cctxt->style->errors++;
    return(NULL);
}

static int
xsltParseNsPrefixList(xsltCompilerCtxtPtr cctxt,
		      xsltPointerListPtr list,
		      xmlNodePtr node,
		      const xmlChar *value)
{
    xmlChar *cur, *end;
    xmlNsPtr ns;
    
    if ((cctxt == NULL) || (value == NULL) || (list == NULL))
	return(-1);

    list->number = 0;

    cur = (xmlChar *) value;
    while (*cur != 0) {
	while (IS_BLANK(*cur)) cur++;
	if (*cur == 0)
	    break;
	end = cur;
	while ((*end != 0) && (!IS_BLANK(*end))) end++;
	cur = xmlStrndup(cur, end - cur);
	if (cur == NULL) {
	    cur = end;
	    continue;
	}		
	/*
	* TODO: Export and use xmlSearchNsByPrefixStrict()
	*   in Libxml2, tree.c, since xmlSearchNs() is in most
	*   cases not efficient and in some cases not correct.
	*
	* XSLT-2 TODO: XSLT 2.0 allows an additional "#all" value.
	*/
	if ((cur[0] == '#') &&
	    xmlStrEqual(cur, (const xmlChar *)"#default"))
	    ns = xmlSearchNs(cctxt->style->doc, node, NULL);
	else
	    ns = xmlSearchNs(cctxt->style->doc, node, cur);	    

	if (ns == NULL) {
	    /*
	    * TODO: Better to report the attr-node, otherwise
	    *  the user won't know which attribute was invalid.
	    */
	    xsltTransformError(NULL, cctxt->style, node,
		"No namespace binding in scope for prefix '%s'.\n", cur);
	    /*
	    * XSLT-1.0: "It is an error if there is no namespace
	    *  bound to the prefix on the element bearing the
	    *  exclude-result-prefixes or xsl:exclude-result-prefixes
	    *  attribute."
	    */
	    cctxt->style->errors++;
	} else {
#ifdef WITH_XSLT_DEBUG_PARSING
	    xsltGenericDebug(xsltGenericDebugContext,
		"resolved prefix '%s'\n", cur);
#endif
	    /*
	    * Note that we put the namespace name into the dict.
	    */
	    if (xsltPointerListAddSize(list,
		(void *) xmlDictLookup(cctxt->style->dict,
		ns->href, -1), 5) == -1)
	    {
		xmlFree(cur);
		goto internal_err;
	    }
	}
	xmlFree(cur);
		
	cur = end;
    }
    return(0);

internal_err:
    cctxt->style->errors++;
    return(-1);
}

/**
 * xsltCompilerUtilsCreateMergedList:
 * @dest: the destination list (optional)
 * @first: the first list
 * @second: the second list (optional)
 *
 * Appends the content of @second to @first into @destination.
 * If @destination is NULL a new list will be created.
 *
 * Returns the merged list of items or NULL if there's nothing to merge.
 */
static xsltPointerListPtr
xsltCompilerUtilsCreateMergedList(xsltPointerListPtr first,
			    xsltPointerListPtr second)
{
    xsltPointerListPtr ret;
    size_t num;

    if (first)
	num = first->number;
    else
	num = 0;
    if (second)
	num += second->number;    
    if (num == 0)
	return(NULL);
    ret = xsltPointerListCreate(num);
    if (ret == NULL)
	return(NULL);
    /*
    * Copy contents.
    */
    if ((first != NULL) &&  (first->number != 0)) {
	memcpy(ret->items, first->items,
	    first->number * sizeof(void *));
	if ((second != NULL) && (second->number != 0))
	    memcpy(ret->items + first->number, second->items,
		second->number * sizeof(void *));
    } else if ((second != NULL) && (second->number != 0))
	memcpy(ret->items, (void *) second->items,
	    second->number * sizeof(void *));
    ret->number = num;
    return(ret);
}

/*
* xsltParseExclResultPrefixes:
*
* Create and store the list of in-scope namespaces for the given
* node in the stylesheet. If there are no changes in the in-scope
* namespaces then the last ns-info of the ancestor axis will be returned.
* Compilation-time only.
*
* Returns the ns-info or NULL if there are no namespaces in scope.
*/
static xsltPointerListPtr
xsltParseExclResultPrefixes(xsltCompilerCtxtPtr cctxt, xmlNodePtr node,
			    xsltPointerListPtr def,
			    int instrCategory)
{    
    xsltPointerListPtr list = NULL;
    xmlChar *value;
    xmlAttrPtr attr;

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

    if (instrCategory == XSLT_ELEMENT_CATEGORY_XSLT)
	attr = xmlHasNsProp(node, BAD_CAST "exclude-result-prefixes", NULL);
    else
	attr = xmlHasNsProp(node, BAD_CAST "exclude-result-prefixes",
	    XSLT_NAMESPACE);
    if (attr == NULL)	
	return(def);

    if (attr && (instrCategory == XSLT_ELEMENT_CATEGORY_LRE)) {
	/*
	* Mark the XSLT attr.
	*/
	attr->psvi = (void *) xsltXSLTAttrMarker;
    }

    if ((attr->children != NULL) &&	
	(attr->children->content != NULL))
	value = attr->children->content;
    else {
	xsltTransformError(NULL, cctxt->style, node,
	    "Attribute 'exclude-result-prefixes': Invalid value.\n");
	cctxt->style->errors++;
	return(def);
    }        

    if (xsltParseNsPrefixList(cctxt, cctxt->tmpList, node,
	BAD_CAST value) != 0)
	goto exit;
    if (cctxt->tmpList->number == 0)	
	goto exit;    
    /*
    * Merge the list with the inherited list.
    */
    list = xsltCompilerUtilsCreateMergedList(def, cctxt->tmpList);
    if (list == NULL)
	goto exit;    
    /*
    * Store the list in the stylesheet/compiler context.
    */
    if (xsltPointerListAddSize(
	cctxt->psData->exclResultNamespaces, list, 5) == -1)
    {
	xsltPointerListFree(list);
	list = NULL;
	goto exit;
    }
    /*
    * Notify of change in status wrt namespaces.
    */
    if (cctxt->inode != NULL)
	cctxt->inode->nsChanged = 1;

exit:    
    if (list != NULL)
	return(list);
    else
	return(def);
}

/*
* xsltParseExtElemPrefixes:
*
* Create and store the list of in-scope namespaces for the given
* node in the stylesheet. If there are no changes in the in-scope
* namespaces then the last ns-info of the ancestor axis will be returned.
* Compilation-time only.
*
* Returns the ns-info or NULL if there are no namespaces in scope.
*/
static xsltPointerListPtr
xsltParseExtElemPrefixes(xsltCompilerCtxtPtr cctxt, xmlNodePtr node,
			 xsltPointerListPtr def,
			 int instrCategory)
{    
    xsltPointerListPtr list = NULL;
    xmlAttrPtr attr;
    xmlChar *value;
    int i;

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

    if (instrCategory == XSLT_ELEMENT_CATEGORY_XSLT)
	attr = xmlHasNsProp(node, BAD_CAST "extension-element-prefixes", NULL);
    else
	attr = xmlHasNsProp(node, BAD_CAST "extension-element-prefixes",
	    XSLT_NAMESPACE);
    if (attr == NULL)	
	return(def);

    if (attr && (instrCategory == XSLT_ELEMENT_CATEGORY_LRE)) {
	/*
	* Mark the XSLT attr.
	*/
	attr->psvi = (void *) xsltXSLTAttrMarker;
    }

    if ((attr->children != NULL) &&	
	(attr->children->content != NULL))
	value = attr->children->content;
    else {
	xsltTransformError(NULL, cctxt->style, node,
	    "Attribute 'extension-element-prefixes': Invalid value.\n");
	cctxt->style->errors++;
	return(def);
    }


    if (xsltParseNsPrefixList(cctxt, cctxt->tmpList, node,
	BAD_CAST value) != 0)
	goto exit;

    if (cctxt->tmpList->number == 0)
	goto exit;    
    /*
    * REVISIT: Register the extension namespaces.
    */
    for (i = 0; i < cctxt->tmpList->number; i++)
	xsltRegisterExtPrefix(cctxt->style, NULL,
	BAD_CAST cctxt->tmpList->items[i]);
    /*
    * Merge the list with the inherited list.
    */
    list = xsltCompilerUtilsCreateMergedList(def, cctxt->tmpList);
    if (list == NULL)
	goto exit;
    /*
    * Store the list in the stylesheet.
    */
    if (xsltPointerListAddSize(
	cctxt->psData->extElemNamespaces, list, 5) == -1)
    {
	xsltPointerListFree(list);
	list = NULL;
	goto exit;
    }
    /*
    * Notify of change in status wrt namespaces.
    */
    if (cctxt->inode != NULL)
	cctxt->inode->nsChanged = 1;

exit:    
    if (list != NULL)
	return(list);
    else
	return(def);
}

/*
* xsltParseAttrXSLTVersion:
*
* @cctxt: the compilation context
* @node: the element-node
* @isXsltElem: whether this is an XSLT element
*
* Parses the attribute xsl:version.
*
* Returns 1 if there was such an attribute, 0 if not and
*         -1 if an internal or API error occured.
*/
static int
xsltParseAttrXSLTVersion(xsltCompilerCtxtPtr cctxt, xmlNodePtr node,			 
			 int instrCategory)
{
    xmlChar *value;
    xmlAttrPtr attr;

    if ((cctxt == NULL) || (node == NULL))
	return(-1);

    if (instrCategory == XSLT_ELEMENT_CATEGORY_XSLT)
	attr = xmlHasNsProp(node, BAD_CAST "version", NULL);
    else
	attr = xmlHasNsProp(node, BAD_CAST "version", XSLT_NAMESPACE);

    if (attr == NULL)	
	return(0);

    attr->psvi = (void *) xsltXSLTAttrMarker;

    if ((attr->children != NULL) &&	
	(attr->children->content != NULL))
	value = attr->children->content;
    else {
	xsltTransformError(NULL, cctxt->style, node,
	    "Attribute 'version': Invalid value.\n");
	cctxt->style->errors++;
	return(1);
    }
    
    if (! xmlStrEqual(value, (const xmlChar *)"1.0")) {
	cctxt->inode->forwardsCompat = 1;
	/*
	* TODO: To what extent do we support the
	*  forwards-compatible mode?
	*/
	/*
	* Report this only once per compilation episode.
	*/
	if (! cctxt->hasForwardsCompat) {
	    cctxt->hasForwardsCompat = 1;
	    cctxt->errSeverity = XSLT_ERROR_SEVERITY_WARNING;
	    xsltTransformError(NULL, cctxt->style, node,
		"Warning: the attribute xsl:version specifies a value "
		"different from '1.0'. Switching to forwards-compatible "
		"mode. Only features of XSLT 1.0 are supported by this "
		"processor.\n");
	    cctxt->style->warnings++;
	    cctxt->errSeverity = XSLT_ERROR_SEVERITY_ERROR;
	}	
    } else {
	cctxt->inode->forwardsCompat = 0;
    }

    if (attr && (instrCategory == XSLT_ELEMENT_CATEGORY_LRE)) {
	/*
	* Set a marker on XSLT attributes.
	*/
	attr->psvi = (void *) xsltXSLTAttrMarker;
    }
    return(1);
}

static int
xsltParsePreprocessStylesheetTree(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{
    xmlNodePtr deleteNode, cur, txt, textNode = NULL;
    xmlDocPtr doc;
    xsltStylesheetPtr style;
    int internalize = 0, findSpaceAttr;
    int xsltStylesheetElemDepth;
    xmlAttrPtr attr;
    xmlChar *value;
    const xmlChar *name, *nsNameXSLT = NULL;
    int strictWhitespace, inXSLText = 0;
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
    xsltNsMapPtr nsMapItem;
#endif

    if ((cctxt == NULL) || (cctxt->style == NULL) ||
	(node == NULL) || (node->type != XML_ELEMENT_NODE))
        return(-1);

    doc = node->doc;
    if (doc == NULL)
	goto internal_err;

    style = cctxt->style;
    if ((style->dict != NULL) && (doc->dict == style->dict))
	internalize = 1;
    else
        style->internalized = 0;

    /*
    * Init value of xml:space. Since this might be an embedded
    * stylesheet, this is needed to be performed on the element
    * where the stylesheet is rooted at, taking xml:space of
    * ancestors into account.
    */
    if (! cctxt->simplified)
	xsltStylesheetElemDepth = cctxt->depth +1;
    else
	xsltStylesheetElemDepth = 0;

    if (xmlNodeGetSpacePreserve(node) != 1)
	cctxt->inode->preserveWhitespace = 0;
    else
	cctxt->inode->preserveWhitespace = 1; 
    
    /*
    * Eval if we should keep the old incorrect behaviour.
    */
    strictWhitespace = (cctxt->strict != 0) ? 1 : 0;

    nsNameXSLT = xsltConstNamespaceNameXSLT;

    deleteNode = NULL;
    cur = node;
    while (cur != NULL) {
	if (deleteNode != NULL)	{

#ifdef WITH_XSLT_DEBUG_BLANKS
	    xsltGenericDebug(xsltGenericDebugContext,
	     "xsltParsePreprocessStylesheetTree: removing node\n");
#endif
	    xmlUnlinkNode(deleteNode);
	    xmlFreeNode(deleteNode);
	    deleteNode = NULL;
	}
	if (cur->type == XML_ELEMENT_NODE) {
	    
	    /*
	    * Clear the PSVI field.
	    */
	    cur->psvi = NULL;

	    xsltCompilerNodePush(cctxt, cur);

	    inXSLText = 0;
	    textNode = NULL;	    
	    findSpaceAttr = 1;	    
	    cctxt->inode->stripWhitespace = 0;
	    /*
	    * TODO: I'd love to use a string pointer comparison here :-/
	    */
	    if (IS_XSLT_ELEM(cur)) {
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
		if (cur->ns->href != nsNameXSLT) {
		    nsMapItem = xsltNewNamespaceMapItem(cctxt,
			doc, cur->ns, cur);
		    if (nsMapItem == NULL)
			goto internal_err;
		    cur->ns->href = nsNameXSLT;
		}
#endif

		if (cur->name == NULL)
		    goto process_attributes;
		/*
		* Mark the XSLT element for later recognition.
		* TODO: Using the marker is still too dangerous, since if
		*   the parsing mechanism leaves out an XSLT element, then
		*   this might hit the transformation-mechanism, which
		*   will break if it doesn't expect such a marker.
		*/
		/* cur->psvi = (void *) xsltXSLTElemMarker; */

		/*
		* XSLT 2.0: "Any whitespace text node whose parent is
		* one of the following elements is removed from the "
		* tree, regardless of any xml:space attributes:..."
		* xsl:apply-imports, 
		* xsl:apply-templates,
		* xsl:attribute-set,
		* xsl:call-template, 
		* xsl:choose,
		* xsl:stylesheet, xsl:transform.
		* XSLT 2.0: xsl:analyze-string,
		*           xsl:character-map,
		*           xsl:next-match		
		*
		* TODO: I'd love to use a string pointer comparison here :-/
		*/		
		name = cur->name;
		switch (*name) {
		    case 't':
			if ((name[0] == 't') && (name[1] == 'e') &&
			    (name[2] == 'x') && (name[3] == 't') &&
			    (name[4] == 0))
			{
			    /*
			    * Process the xsl:text element.
			    * ----------------------------
			    * Mark it for later recognition.
			    */
			    cur->psvi = (void *) xsltXSLTTextMarker;
			    /*
			    * For stylesheets, the set of
			    * whitespace-preserving element names
			    * consists of just xsl:text.
			    */
			    findSpaceAttr = 0;
			    cctxt->inode->preserveWhitespace = 1;
			    inXSLText = 1;
			}			    
			break;
		    case 'c':
			if (xmlStrEqual(name, BAD_CAST "choose") ||
			    xmlStrEqual(name, BAD_CAST "call-template"))
			    cctxt->inode->stripWhitespace = 1;
			break;
		    case 'a':
			if (xmlStrEqual(name, BAD_CAST "apply-templates") ||
			    xmlStrEqual(name, BAD_CAST "apply-imports") ||
			    xmlStrEqual(name, BAD_CAST "attribute-set"))

			    cctxt->inode->stripWhitespace = 1;
			break;
		    default:
			if (xsltStylesheetElemDepth == cctxt->depth) {
			    /*
			    * This is a xsl:stylesheet/xsl:transform.
			    */
			    cctxt->inode->stripWhitespace = 1;
			    break;
			}

			if ((cur->prev != NULL) &&
			    (cur->prev->type == XML_TEXT_NODE))
			{
			    /*
			    * XSLT 2.0 : "Any whitespace text node whose
			    *  following-sibling node is an xsl:param or
			    *  xsl:sort element is removed from the tree,
			    *  regardless of any xml:space attributes."
			    */
			    if (((*name == 'p') || (*name == 's')) &&
				(xmlStrEqual(name, BAD_CAST "param") ||
				 xmlStrEqual(name, BAD_CAST "sort")))
			    {
				do {
				    if (IS_BLANK_NODE(cur->prev)) {
					txt = cur->prev;
					xmlUnlinkNode(txt);
					xmlFreeNode(txt);
				    } else {
					/*
					* This will result in a content
					* error, when hitting the parsing
					* functions.
					*/
					break;
				    }
				} while (cur->prev);				    
			    }
			}
			break;
		}
	    }

process_attributes:
	    /*
	    * Process attributes.
	    * ------------------
	    */
	    if (cur->properties != NULL) {
		if (cur->children == NULL)
		    findSpaceAttr = 0;
		attr = cur->properties;
		do {
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
		    if ((attr->ns) && (attr->ns->href != nsNameXSLT) &&
			xmlStrEqual(attr->ns->href, nsNameXSLT))
		    {			
			nsMapItem = xsltNewNamespaceMapItem(cctxt,
			    doc, attr->ns, cur);
			if (nsMapItem == NULL)
			    goto internal_err;
			attr->ns->href = nsNameXSLT;
		    }		    
#endif
		    if (internalize) {
			/*
			* Internalize the attribute's value; the goal is to
			* speed up operations and minimize used space by
			* compiled stylesheets.
			*/
			txt = attr->children;
			/*
			* NOTE that this assumes only one
			*  text-node in the attribute's content.
			*/
			if ((txt != NULL) && (txt->content != NULL) &&
			    (!xmlDictOwns(style->dict, txt->content)))
			{
			    value = (xmlChar *) xmlDictLookup(style->dict,
				txt->content, -1);
			    xmlNodeSetContent(txt, NULL);
			    txt->content = value;
			}
		    }
		    /*
		    * Process xml:space attributes.
		    * ----------------------------
		    */
		    if ((findSpaceAttr != 0) &&
			(attr->ns != NULL) &&
			(attr->name != NULL) &&
			(attr->name[0] == 's') &&			
			(attr->ns->prefix != NULL) &&
			(attr->ns->prefix[0] == 'x') &&
			(attr->ns->prefix[1] == 'm') &&
			(attr->ns->prefix[2] == 'l') &&
			(attr->ns->prefix[3] == 0))
		    {
			value = xmlGetNsProp(cur, BAD_CAST "space",
			    XML_XML_NAMESPACE);
			if (value != NULL) {
			    if (xmlStrEqual(value, BAD_CAST "preserve")) {
				cctxt->inode->preserveWhitespace = 1;				
			    } else if (xmlStrEqual(value, BAD_CAST "default")) {
				cctxt->inode->preserveWhitespace = 0;
			    } else {
				/* Invalid value for xml:space. */
				xsltTransformError(NULL, style, cur,
				    "Attribute xml:space: Invalid value.\n");
				cctxt->style->warnings++;
			    }
			    findSpaceAttr = 0;
			    xmlFree(value);
			}
			
		    }
		    attr = attr->next;
		} while (attr != NULL);
	    }
	    /*
	    * We'll descend into the children of element nodes only.
	    */
	    if (cur->children != NULL) {
		cur = cur->children;
		continue;
	    }
	} else if ((cur->type == XML_TEXT_NODE) ||
		(cur->type == XML_CDATA_SECTION_NODE))
	{
	    /*
	    * Merge adjacent text/CDATA-section-nodes
	    * ---------------------------------------	    
	    * In order to avoid breaking of existing stylesheets,
	    * if the old behaviour is wanted (strictWhitespace == 0),
	    * then we *won't* merge adjacent text-nodes
	    * (except in xsl:text); this will ensure that whitespace-only
	    * text nodes are (incorrectly) not stripped in some cases.
	    * 
	    * Example:               : <foo>  <!-- bar -->zoo</foo>
	    * Corrent (strict) result: <foo>  zoo</foo>
	    * Incorrect (old) result : <foo>zoo</foo>
	    *    
	    * NOTE that we *will* merge adjacent text-nodes if
	    * they are in xsl:text.
	    * Example, the following:
	    * <xsl:text>  <!-- bar -->zoo<xsl:text>
	    * will result in both cases in:
	    * <xsl:text>  zoo<xsl:text>
	    */
	    cur->type = XML_TEXT_NODE;
	    if ((strictWhitespace != 0) || (inXSLText != 0)) {
		/*
		* New behaviour; merge nodes.
		*/
		if (textNode == NULL)
		    textNode = cur;
		else {
		    if (cur->content != NULL)
			xmlNodeAddContent(textNode, cur->content);
		    deleteNode = cur;
		}
		if ((cur->next == NULL) ||
		    (cur->next->type == XML_ELEMENT_NODE))
		    goto end_of_text;
		else
		    goto next_sibling;
	    } else {
		/*
		* Old behaviour.
		*/
		if (textNode == NULL)
		    textNode = cur;
		goto end_of_text;
	    }	    	   
	} else if ((cur->type == XML_COMMENT_NODE) ||
	    (cur->type == XML_PI_NODE))
	{	    
	    /*
	    * Remove processing instructions and comments.
	    */
	    deleteNode = cur;
	    if ((cur->next == NULL) ||
		(cur->next->type == XML_ELEMENT_NODE))
		goto end_of_text;
	    else
		goto next_sibling;
	} else {
	    textNode = NULL;
	    /*
	    * Invalid node-type for this data-model.
	    */
	    xsltTransformError(NULL, style, cur,
		"Invalid type of node for the XSLT data model.\n");
	    cctxt->style->errors++;
	    goto next_sibling;
	}

end_of_text:
	if (textNode) {
	    value = textNode->content;
	    /*
	    * At this point all adjacent text/CDATA-section nodes
	    * have been merged.
	    *
	    * Strip whitespace-only text-nodes.
	    * (cctxt->inode->stripWhitespace)
	    */
	    if ((value == NULL) || (*value == 0) ||
		(((cctxt->inode->stripWhitespace) ||
		  (! cctxt->inode->preserveWhitespace)) &&
		 IS_BLANK(*value) &&
		 xsltIsBlank(value)))
	    {		
		if (textNode != cur) {
		    xmlUnlinkNode(textNode);
		    xmlFreeNode(textNode);
		} else
		    deleteNode = textNode;
		textNode = NULL;
		goto next_sibling;
	    }
	    /*
	    * Convert CDATA-section nodes to text-nodes.
	    * TODO: Can this produce problems?
	    */
	    if (textNode->type != XML_TEXT_NODE) {
		textNode->type = XML_TEXT_NODE;
		textNode->name = xmlStringText;
	    }
	    if (internalize &&
		(textNode->content != NULL) &&
		(!xmlDictOwns(style->dict, textNode->content)))
	    {
		/*
		* Internalize the string.
		*/
		value = (xmlChar *) xmlDictLookup(style->dict,
		    textNode->content, -1);
		xmlNodeSetContent(textNode, NULL);
		textNode->content = value;
	    }
	    textNode = NULL;
	    /*
	    * Note that "disable-output-escaping" of the xsl:text
	    * element will be applied at a later level, when
	    * XSLT elements are processed.
	    */
	}

next_sibling:
	if (cur->type == XML_ELEMENT_NODE) {
	    xsltCompilerNodePop(cctxt, cur);
	}
	if (cur == node)
	    break;
	if (cur->next != NULL) {
	    cur = cur->next;
	} else {
	    cur = cur->parent;
	    inXSLText = 0;
	    goto next_sibling;
	};
    }
    if (deleteNode != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
	 "xsltParsePreprocessStylesheetTree: removing node\n");
#endif
	xmlUnlinkNode(deleteNode);
	xmlFreeNode(deleteNode);
    }
    return(0);

internal_err:
    return(-1);
}

#endif /* XSLT_REFACTORED */

#ifdef XSLT_REFACTORED
#else
static void
xsltPrecomputeStylesheet(xsltStylesheetPtr style, xmlNodePtr cur)
{
    xmlNodePtr deleteNode, styleelem;
    int internalize = 0;

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

    if ((cur->doc != NULL) && (style->dict != NULL) &&
        (cur->doc->dict == style->dict))
	internalize = 1;
    else
        style->internalized = 0;

    if ((cur != NULL) && (IS_XSLT_ELEM(cur)) &&
        (IS_XSLT_NAME(cur, "stylesheet"))) {
	styleelem = cur;
    } else {
        styleelem = NULL;
    }

    /*
     * This content comes from the stylesheet
     * For stylesheets, the set of whitespace-preserving
     * element names consists of just xsl:text.
     */
    deleteNode = NULL;
    while (cur != NULL) {
	if (deleteNode != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
	    xsltGenericDebug(xsltGenericDebugContext,
	     "xsltPrecomputeStylesheet: removing ignorable blank node\n");
#endif
	    xmlUnlinkNode(deleteNode);
	    xmlFreeNode(deleteNode);
	    deleteNode = NULL;
	}
	if (cur->type == XML_ELEMENT_NODE) {
	    int exclPrefixes;
	    /*
	     * Internalize attributes values.
	     */
	    if ((internalize) && (cur->properties != NULL)) {
	        xmlAttrPtr attr = cur->properties;
		xmlNodePtr txt;

		while (attr != NULL) {
		    txt = attr->children;
		    if ((txt != NULL) && (txt->type == XML_TEXT_NODE) &&
		        (txt->content != NULL) &&
			(!xmlDictOwns(style->dict, txt->content)))
		    {
			xmlChar *tmp;

			/*
			 * internalize the text string, goal is to speed
			 * up operations and minimize used space by compiled
			 * stylesheets.
			 */
			tmp = (xmlChar *) xmlDictLookup(style->dict,
			                                txt->content, -1);
			if (tmp != txt->content) {
			    xmlNodeSetContent(txt, NULL);
			    txt->content = tmp;
			}
		    }
		    attr = attr->next;
		}
	    }
	    if (IS_XSLT_ELEM(cur)) {
		exclPrefixes = 0;
		xsltStylePreCompute(style, cur);
		if (IS_XSLT_NAME(cur, "text")) {
		    for (;exclPrefixes > 0;exclPrefixes--)
			exclPrefixPop(style);
		    goto skip_children;
		}
	    } else {
		exclPrefixes = xsltParseStylesheetExcludePrefix(style, cur, 0);
	    }
	    	     
	    if ((cur->nsDef != NULL) && (style->exclPrefixNr > 0)) {
		xmlNsPtr ns = cur->nsDef, prev = NULL, next;
		xmlNodePtr root = NULL;
		int i, moved;

		root = xmlDocGetRootElement(cur->doc);
		if ((root != NULL) && (root != cur)) {
		    while (ns != NULL) {
			moved = 0;
			next = ns->next;
			for (i = 0;i < style->exclPrefixNr;i++) {
			    if ((ns->prefix != NULL) && 
			        (xmlStrEqual(ns->href,
					     style->exclPrefixTab[i]))) {
				/*
				 * Move the namespace definition on the root
				 * element to avoid duplicating it without
				 * loosing it.
				 */
				if (prev == NULL) {
				    cur->nsDef = ns->next;
				} else {
				    prev->next = ns->next;
				}
				ns->next = root->nsDef;
				root->nsDef = ns;
				moved = 1;
				break;
			    }
			}
			if (moved == 0)
			    prev = ns;
			ns = next;
		    }
		}
	    }
	    /*
	     * If we have prefixes locally, recurse and pop them up when
	     * going back
	     */
	    if (exclPrefixes > 0) {
		xsltPrecomputeStylesheet(style, cur->children);
		for (;exclPrefixes > 0;exclPrefixes--)
		    exclPrefixPop(style);
		goto skip_children;
	    }
	} else if (cur->type == XML_TEXT_NODE) {
	    if (IS_BLANK_NODE(cur)) {
		if (xmlNodeGetSpacePreserve(cur) != 1) {
		    deleteNode = cur;
		}
	    } else if ((cur->content != NULL) && (internalize) &&
	               (!xmlDictOwns(style->dict, cur->content))) {
		xmlChar *tmp;

		/*
		 * internalize the text string, goal is to speed
		 * up operations and minimize used space by compiled
		 * stylesheets.
		 */
		tmp = (xmlChar *) xmlDictLookup(style->dict, cur->content, -1);
		xmlNodeSetContent(cur, NULL);
		cur->content = tmp;
	    }
	} else if ((cur->type != XML_ELEMENT_NODE) &&
		   (cur->type != XML_CDATA_SECTION_NODE)) {
	    deleteNode = cur;
	    goto skip_children;
	}

	/*
	 * Skip to next node. In case of a namespaced element children of
	 * the stylesheet and not in the XSLT namespace and not an extension
	 * element, ignore its content.
	 */
	if ((cur->type == XML_ELEMENT_NODE) && (cur->ns != NULL) &&
	    (styleelem != NULL) && (cur->parent == styleelem) &&
	    (!xmlStrEqual(cur->ns->href, XSLT_NAMESPACE)) &&
	    (!xsltCheckExtURI(style, cur->ns->href))) {
	    goto skip_children;
	} else if (cur->children != NULL) {
	    if ((cur->children->type != XML_ENTITY_DECL) &&
		(cur->children->type != XML_ENTITY_REF_NODE) &&
		(cur->children->type != XML_ENTITY_NODE)) {
		cur = cur->children;
		continue;
	    }
	}

skip_children:
	if (cur->next != NULL) {
	    cur = cur->next;
	    continue;
	}
	do {

	    cur = cur->parent;
	    if (cur == NULL)
		break;
	    if (cur == (xmlNodePtr) style->doc) {
		cur = NULL;
		break;
	    }
	    if (cur->next != NULL) {
		cur = cur->next;
		break;
	    }
	} while (cur != NULL);
    }
    if (deleteNode != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
	 "xsltPrecomputeStylesheet: removing ignorable blank node\n");
#endif
	xmlUnlinkNode(deleteNode);
	xmlFreeNode(deleteNode);
    }
}
#endif /* end of else XSLT_REFACTORED */

/**
 * xsltGatherNamespaces:
 * @style:  the XSLT stylesheet
 *
 * Browse the stylesheet and build the namspace hash table which
 * will be used for XPath interpretation. If needed do a bit of normalization
 */

static void
xsltGatherNamespaces(xsltStylesheetPtr style) {
    xmlNodePtr cur;
    const xmlChar *URI;

    if (style == NULL)
        return;
    /* 
     * TODO: basically if the stylesheet uses the same prefix for different
     *       patterns, well they may be in problem, hopefully they will get
     *       a warning first.
     */
    /*
    * TODO: Eliminate the use of the hash for XPath expressions.
    *   An expression should be evaluated in the context of the in-scope
    *   namespaces; eliminate the restriction of an XML document to contain
    *   no duplicate prefixes for different namespace names.
    * 
    */
    cur = xmlDocGetRootElement(style->doc);
    while (cur != NULL) {
	if (cur->type == XML_ELEMENT_NODE) {
	    xmlNsPtr ns = cur->nsDef;
	    while (ns != NULL) {
		if (ns->prefix != NULL) {
		    if (style->nsHash == NULL) {
			style->nsHash = xmlHashCreate(10);
			if (style->nsHash == NULL) {
			    xsltTransformError(NULL, style, cur,
		 "xsltGatherNamespaces: failed to create hash table\n");
			    style->errors++;
			    return;
			}
		    }
		    URI = xmlHashLookup(style->nsHash, ns->prefix);
		    if ((URI != NULL) && (!xmlStrEqual(URI, ns->href))) {
			xsltTransformError(NULL, style, cur,
	     "Namespaces prefix %s used for multiple namespaces\n",ns->prefix);
			style->warnings++;
		    } else if (URI == NULL) {
			xmlHashUpdateEntry(style->nsHash, ns->prefix,
			    (void *) ns->href, (xmlHashDeallocator)xmlFree);

#ifdef WITH_XSLT_DEBUG_PARSING
			xsltGenericDebug(xsltGenericDebugContext,
		 "Added namespace: %s mapped to %s\n", ns->prefix, ns->href);
#endif
		    }
		}
		ns = ns->next;
	    }
	}

	/*
	 * Skip to next node
	 */
	if (cur->children != NULL) {
	    if (cur->children->type != XML_ENTITY_DECL) {
		cur = cur->children;
		continue;
	    }
	}
	if (cur->next != NULL) {
	    cur = cur->next;
	    continue;
	}
	
	do {
	    cur = cur->parent;
	    if (cur == NULL)
		break;
	    if (cur == (xmlNodePtr) style->doc) {
		cur = NULL;
		break;
	    }
	    if (cur->next != NULL) {
		cur = cur->next;
		break;
	    }
	} while (cur != NULL);
    }
}

#ifdef XSLT_REFACTORED

static xsltStyleType
xsltGetXSLTElementTypeByNode(xsltCompilerCtxtPtr cctxt,
			     xmlNodePtr node)
{
    if ((node == NULL) || (node->type != XML_ELEMENT_NODE) ||
	(node->name == NULL))
	return(0);

    if (node->name[0] == 'a') {
	if (IS_XSLT_NAME(node, "apply-templates"))
	    return(XSLT_FUNC_APPLYTEMPLATES);
	else if (IS_XSLT_NAME(node, "attribute"))
	    return(XSLT_FUNC_ATTRIBUTE);
	else if (IS_XSLT_NAME(node, "apply-imports"))
	    return(XSLT_FUNC_APPLYIMPORTS);
	else if (IS_XSLT_NAME(node, "attribute-set"))
	    return(0);

    } else if (node->name[0] == 'c') {
	if (IS_XSLT_NAME(node, "choose"))
	    return(XSLT_FUNC_CHOOSE);
	else if (IS_XSLT_NAME(node, "copy"))
	    return(XSLT_FUNC_COPY);
	else if (IS_XSLT_NAME(node, "copy-of"))
	    return(XSLT_FUNC_COPYOF);
	else if (IS_XSLT_NAME(node, "call-template"))
	    return(XSLT_FUNC_CALLTEMPLATE);
	else if (IS_XSLT_NAME(node, "comment"))
	    return(XSLT_FUNC_COMMENT);

    } else if (node->name[0] == 'd') {
	if (IS_XSLT_NAME(node, "document"))
	    return(XSLT_FUNC_DOCUMENT);
	else if (IS_XSLT_NAME(node, "decimal-format"))
	    return(0);

    } else if (node->name[0] == 'e') {
	if (IS_XSLT_NAME(node, "element"))
	    return(XSLT_FUNC_ELEMENT);

    } else if (node->name[0] == 'f') {
	if (IS_XSLT_NAME(node, "for-each"))
	    return(XSLT_FUNC_FOREACH);
	else if (IS_XSLT_NAME(node, "fallback"))
	    return(XSLT_FUNC_FALLBACK);

    } else if (*(node->name) == 'i') {
	if (IS_XSLT_NAME(node, "if"))
	    return(XSLT_FUNC_IF);
	else if (IS_XSLT_NAME(node, "include"))
	    return(0);
	else if (IS_XSLT_NAME(node, "import"))
	    return(0);

    } else if (*(node->name) == 'k') {
	if (IS_XSLT_NAME(node, "key"))
	    return(0);

    } else if (*(node->name) == 'm') {
	if (IS_XSLT_NAME(node, "message"))
	    return(XSLT_FUNC_MESSAGE);

    } else if (*(node->name) == 'n') {
	if (IS_XSLT_NAME(node, "number"))
	    return(XSLT_FUNC_NUMBER);
	else if (IS_XSLT_NAME(node, "namespace-alias"))
	    return(0);

    } else if (*(node->name) == 'o') {
	if (IS_XSLT_NAME(node, "otherwise"))
	    return(XSLT_FUNC_OTHERWISE);
	else if (IS_XSLT_NAME(node, "output"))
	    return(0);

    } else if (*(node->name) == 'p') {
	if (IS_XSLT_NAME(node, "param"))
	    return(XSLT_FUNC_PARAM);
	else if (IS_XSLT_NAME(node, "processing-instruction"))
	    return(XSLT_FUNC_PI);
	else if (IS_XSLT_NAME(node, "preserve-space"))
	    return(0);

    } else if (*(node->name) == 's') {
	if (IS_XSLT_NAME(node, "sort"))
	    return(XSLT_FUNC_SORT);
	else if (IS_XSLT_NAME(node, "strip-space"))
	    return(0);
	else if (IS_XSLT_NAME(node, "stylesheet"))
	    return(0);

    } else if (node->name[0] == 't') {
	if (IS_XSLT_NAME(node, "text"))
	    return(XSLT_FUNC_TEXT);
	else if (IS_XSLT_NAME(node, "template"))
	    return(0);
	else if (IS_XSLT_NAME(node, "transform"))
	    return(0);

    } else if (*(node->name) == 'v') {
	if (IS_XSLT_NAME(node, "value-of"))
	    return(XSLT_FUNC_VALUEOF);
	else if (IS_XSLT_NAME(node, "variable"))
	    return(XSLT_FUNC_VARIABLE);

    } else if (*(node->name) == 'w') {
	if (IS_XSLT_NAME(node, "when"))
	    return(XSLT_FUNC_WHEN);
	if (IS_XSLT_NAME(node, "with-param"))
	    return(XSLT_FUNC_WITHPARAM);
    }
    return(0);
}

/**
 * xsltParseAnyXSLTElem:
 *
 * @cctxt: the compilation context
 * @elem: the element node of the XSLT instruction
 *
 * Parses, validates the content models and compiles XSLT instructions.
 *
 * Returns 0 if everything's fine;
 *         -1 on API or internal errors.
 */ 
int
xsltParseAnyXSLTElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr elem)
{
    if ((cctxt == NULL) || (elem == NULL) ||
	(elem->type != XML_ELEMENT_NODE))
	return(-1);

    elem->psvi = NULL;

    if (! (IS_XSLT_ELEM_FAST(elem)))
	return(-1);
    /*
    * Detection of handled content of extension instructions.
    */
    if (cctxt->inode->category == XSLT_ELEMENT_CATEGORY_EXTENSION) {
	cctxt->inode->extContentHandled = 1;
    }
    
    xsltCompilerNodePush(cctxt, elem);
    /*
    * URGENT TODO: Find a way to speed up this annoying redundant
    *  textual node-name and namespace comparison.
    */
    if (cctxt->inode->prev->curChildType != 0)
	cctxt->inode->type = cctxt->inode->prev->curChildType;
    else
	cctxt->inode->type = xsltGetXSLTElementTypeByNode(cctxt, elem);    
    /*
    * Update the in-scope namespaces if needed.
    */
    if (elem->nsDef != NULL)
	cctxt->inode->inScopeNs =
	    xsltCompilerBuildInScopeNsList(cctxt, elem);
    /*
    * xsltStylePreCompute():
    *  This will compile the information found on the current
    *  element's attributes. NOTE that this won't process the
    *  children of the instruction.
    */
    xsltStylePreCompute(cctxt->style, elem);
    /*
    * TODO: How to react on errors in xsltStylePreCompute() ?
    */

    /*
    * Validate the content model of the XSLT-element.
    */
    switch (cctxt->inode->type) {	
	case XSLT_FUNC_APPLYIMPORTS:
	    /* EMPTY */
	    goto empty_content;
	case XSLT_FUNC_APPLYTEMPLATES:
	    /* <!-- Content: (xsl:sort | xsl:with-param)* --> */
	    goto apply_templates;	    
	case XSLT_FUNC_ATTRIBUTE:	    
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_CALLTEMPLATE:
	    /* <!-- Content: xsl:with-param* --> */
	    goto call_template;
	case XSLT_FUNC_CHOOSE:	    
	    /* <!-- Content: (xsl:when+, xsl:otherwise?) --> */
	    goto choose;
	case XSLT_FUNC_COMMENT:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;	    
	case XSLT_FUNC_COPY:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;	    
	case XSLT_FUNC_COPYOF:
	    /* EMPTY */
	    goto empty_content;	   
	case XSLT_FUNC_DOCUMENT: /* Extra one */
	    /* ?? template ?? */
	    goto sequence_constructor;
	case XSLT_FUNC_ELEMENT:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_FALLBACK:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_FOREACH:
	    /* <!-- Content: (xsl:sort*, template) --> */
	    goto for_each;
	case XSLT_FUNC_IF:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_OTHERWISE:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_MESSAGE:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_NUMBER:
	    /* EMPTY */
	    goto empty_content;
	case XSLT_FUNC_PARAM:
	    /*
	    * Check for redefinition.
	    */
	    if ((elem->psvi != NULL) && (cctxt->ivar != NULL)) {
		xsltVarInfoPtr ivar = cctxt->ivar;

		do {
		    if ((ivar->name ==
			 ((xsltStyleItemParamPtr) elem->psvi)->name) &&
			(ivar->nsName ==
			 ((xsltStyleItemParamPtr) elem->psvi)->ns))
		    {
			elem->psvi = NULL;
			xsltTransformError(NULL, cctxt->style, elem,
			    "Redefinition of variable or parameter '%s'.\n",
			    ivar->name);
			cctxt->style->errors++;
			goto error;
		    }
		    ivar = ivar->prev;
		} while (ivar != NULL);
	    }
	    /*  <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_PI:
	    /*  <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_SORT:
	    /* EMPTY */
	    goto empty_content;
	case XSLT_FUNC_TEXT:
	    /* <!-- Content: #PCDATA --> */
	    goto text;
	case XSLT_FUNC_VALUEOF:
	    /* EMPTY */
	    goto empty_content;
	case XSLT_FUNC_VARIABLE:
	    /*
	    * Check for redefinition.
	    */
	    if ((elem->psvi != NULL) && (cctxt->ivar != NULL)) {
		xsltVarInfoPtr ivar = cctxt->ivar;		

		do {
		    if ((ivar->name ==
			 ((xsltStyleItemVariablePtr) elem->psvi)->name) &&
			(ivar->nsName ==
			 ((xsltStyleItemVariablePtr) elem->psvi)->ns))
		    {
			elem->psvi = NULL;
			xsltTransformError(NULL, cctxt->style, elem,
			    "Redefinition of variable or parameter '%s'.\n",
			    ivar->name);
			cctxt->style->errors++;
			goto error;
		    }
		    ivar = ivar->prev;
		} while (ivar != NULL);
	    }
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_WHEN:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	case XSLT_FUNC_WITHPARAM:
	    /* <!-- Content: template --> */
	    goto sequence_constructor;
	default:
#ifdef WITH_XSLT_DEBUG_PARSING
	    xsltGenericDebug(xsltGenericDebugContext,
		"xsltParseXSLTNode: Unhandled XSLT element '%s'.\n",
		elem->name);	    
#endif
	    xsltTransformError(NULL, cctxt->style, elem,
		"xsltParseXSLTNode: Internal error; "
		"unhandled XSLT element '%s'.\n", elem->name);
	    cctxt->style->errors++;
	    goto internal_err;
    }

apply_templates:
    /* <!-- Content: (xsl:sort | xsl:with-param)* --> */
    if (elem->children != NULL) {
	xmlNodePtr child = elem->children;
	do {
	    if (child->type == XML_ELEMENT_NODE) {
		if (IS_XSLT_ELEM_FAST(child)) {
		    if (xmlStrEqual(child->name, BAD_CAST "with-param")) {
			cctxt->inode->curChildType = XSLT_FUNC_WITHPARAM;
			xsltParseAnyXSLTElem(cctxt, child);
		    } else if (xmlStrEqual(child->name, BAD_CAST "sort")) {
			cctxt->inode->curChildType = XSLT_FUNC_SORT;
			xsltParseAnyXSLTElem(cctxt, child);
		    } else
			xsltParseContentError(cctxt->style, child);
		} else
		    xsltParseContentError(cctxt->style, child);
	    }
	    child = child->next;
	} while (child != NULL);
    }    
    goto exit;

call_template:
    /* <!-- Content: xsl:with-param* --> */
    if (elem->children != NULL) {
	xmlNodePtr child = elem->children;
	do {
	    if (child->type == XML_ELEMENT_NODE) {
		if (IS_XSLT_ELEM_FAST(child)) {
		    xsltStyleType type;

		    type = xsltGetXSLTElementTypeByNode(cctxt, child);
		    if (type == XSLT_FUNC_WITHPARAM) {
			cctxt->inode->curChildType = XSLT_FUNC_WITHPARAM;
			xsltParseAnyXSLTElem(cctxt, child);
		    } else {
			xsltParseContentError(cctxt->style, child);
		    }
		} else
		    xsltParseContentError(cctxt->style, child);
	    }
	    child = child->next;
	} while (child != NULL);
    }    
    goto exit;

text:
    if (elem->children != NULL) {
	xmlNodePtr child = elem->children;
	do {
	    if ((child->type != XML_TEXT_NODE) &&
		(child->type != XML_CDATA_SECTION_NODE))
	    {
		xsltTransformError(NULL, cctxt->style, elem,
		    "The XSLT 'text' element must have only character "
		    "data as content.\n");
	    }
	    child = child->next;
	} while (child != NULL);
    }
    goto exit;

empty_content:
    if (elem->children != NULL) {
	xmlNodePtr child = elem->children;
	/*
	* Relaxed behaviour: we will allow whitespace-only text-nodes.
	*/
	do {
	    if (((child->type != XML_TEXT_NODE) &&
		 (child->type != XML_CDATA_SECTION_NODE)) ||
		(! IS_BLANK_NODE(child)))
	    {
		xsltTransformError(NULL, cctxt->style, elem,
		    "This XSLT element must have no content.\n");
		cctxt->style->errors++;
		break;
	    }
	    child = child->next;
	} while (child != NULL);		
    }
    goto exit;

choose:
    /* <!-- Content: (xsl:when+, xsl:otherwise?) --> */
    /*
    * TODO: text-nodes in between are *not* allowed in XSLT 1.0.
    *   The old behaviour did not check this.
    * NOTE: In XSLT 2.0 they are stripped beforehand
    *  if whitespace-only (regardless of xml:space).
    */
    if (elem->children != NULL) {
	xmlNodePtr child = elem->children;
	int nbWhen = 0, nbOtherwise = 0, err = 0;
	do {
	    if (child->type == XML_ELEMENT_NODE) {
		if (IS_XSLT_ELEM_FAST(child)) {
		    xsltStyleType type;
		
		    type = xsltGetXSLTElementTypeByNode(cctxt, child);
		    if (type == XSLT_FUNC_WHEN) {
			nbWhen++;
			if (nbOtherwise) {
			    xsltParseContentError(cctxt->style, child);
			    err = 1;
			    break;
			}
			cctxt->inode->curChildType = XSLT_FUNC_WHEN;
			xsltParseAnyXSLTElem(cctxt, child);
		    } else if (type == XSLT_FUNC_OTHERWISE) {
			if (! nbWhen) {
			    xsltParseContentError(cctxt->style, child);
			    err = 1;
			    break;
			}			
			if (nbOtherwise) {
			    xsltTransformError(NULL, cctxt->style, elem,
				"The XSLT 'choose' element must not contain "
				"more than one XSLT 'otherwise' element.\n");
			    cctxt->style->errors++;
			    err = 1;
			    break;
			}
			nbOtherwise++;
			cctxt->inode->curChildType = XSLT_FUNC_OTHERWISE;
			xsltParseAnyXSLTElem(cctxt, child);
		    } else
			xsltParseContentError(cctxt->style, child);
		} else
		    xsltParseContentError(cctxt->style, child);
	    } 
	    /*
		else
		    xsltParseContentError(cctxt, child);
	    */
	    child = child->next;
	} while (child != NULL);
	if ((! err) && (! nbWhen)) {
	    xsltTransformError(NULL, cctxt->style, elem,
		"The XSLT element 'choose' must contain at least one "
		"XSLT element 'when'.\n");
		cctxt->style->errors++;
	}	
    }    
    goto exit;

for_each:
    /* <!-- Content: (xsl:sort*, template) --> */
    /*
    * NOTE: Text-nodes before xsl:sort are *not* allowed in XSLT 1.0.
    *   The old behaviour did not allow this, but it catched this
    *   only at transformation-time.
    *   In XSLT 2.0 they are stripped beforehand if whitespace-only
    *   (regardless of xml:space).
    */
    if (elem->children != NULL) {
	xmlNodePtr child = elem->children;
	/*
	* Parse xsl:sort first.
	*/
	do {	    
	    if ((child->type == XML_ELEMENT_NODE) &&
		IS_XSLT_ELEM_FAST(child))
	    {		
		if (xsltGetXSLTElementTypeByNode(cctxt, child) ==
		    XSLT_FUNC_SORT)
		{		
		    cctxt->inode->curChildType = XSLT_FUNC_SORT;
		    xsltParseAnyXSLTElem(cctxt, child);
		} else
		    break;
	    } else
		break;
	    child = child->next;
	} while (child != NULL);
	/*
	* Parse the sequece constructor.
	*/
	if (child != NULL)
	    xsltParseSequenceConstructor(cctxt, child);
    }    
    goto exit;

sequence_constructor:
    /*
    * Parse the sequence constructor.
    */
    if (elem->children != NULL)
	xsltParseSequenceConstructor(cctxt, elem->children);

    /*
    * Register information for vars/params. Only needed if there
    * are any following siblings.
    */
    if ((elem->next != NULL) &&
	((cctxt->inode->type == XSLT_FUNC_VARIABLE) ||
	 (cctxt->inode->type == XSLT_FUNC_PARAM)))
    {	
	if ((elem->psvi != NULL) &&
	    (((xsltStyleBasicItemVariablePtr) elem->psvi)->name))
	{	
	    xsltCompilerVarInfoPush(cctxt, elem,
		((xsltStyleBasicItemVariablePtr) elem->psvi)->name,
		((xsltStyleBasicItemVariablePtr) elem->psvi)->ns);
	}
    }

error:
exit:
    xsltCompilerNodePop(cctxt, elem);
    return(0);

internal_err:
    xsltCompilerNodePop(cctxt, elem);
    return(-1);
}

/**
 * xsltForwardsCompatUnkownItemCreate:
 *
 * @cctxt: the compilation context 
 *
 * Creates a compiled representation of the unknown
 * XSLT instruction.
 *
 * Returns the compiled representation.
 */ 
static xsltStyleItemUknownPtr
xsltForwardsCompatUnkownItemCreate(xsltCompilerCtxtPtr cctxt)
{
    xsltStyleItemUknownPtr item;

    item = (xsltStyleItemUknownPtr) xmlMalloc(sizeof(xsltStyleItemUknown));
    if (item == NULL) {
	xsltTransformError(NULL, cctxt->style, NULL,
	    "Internal error in xsltForwardsCompatUnkownItemCreate(): "
	    "Failed to allocate memory.\n");
	cctxt->style->errors++;
	return(NULL);
    }
    memset(item, 0, sizeof(xsltStyleItemUknown));
    item->type = XSLT_FUNC_UNKOWN_FORWARDS_COMPAT;
    /*
    * Store it in the stylesheet.
    */
    item->next = cctxt->style->preComps;
    cctxt->style->preComps = (xsltElemPreCompPtr) item;
    return(item);
}

/**
 * xsltParseUnknownXSLTElem:
 *
 * @cctxt: the compilation context
 * @node: the element of the unknown XSLT instruction
 *
 * Parses an unknown XSLT element.
 * If forwards compatible mode is enabled this will allow
 * such an unknown XSLT and; otherwise it is rejected.
 *
 * Returns 1 in the unknown XSLT instruction is rejected,
 *         0 if everything's fine and
 *         -1 on API or internal errors.
 */ 
static int
xsltParseUnknownXSLTElem(xsltCompilerCtxtPtr cctxt,
			    xmlNodePtr node)
{
    if ((cctxt == NULL) || (node == NULL))
	return(-1);

    /*
    * Detection of handled content of extension instructions.
    */
    if (cctxt->inode->category == XSLT_ELEMENT_CATEGORY_EXTENSION) {
	cctxt->inode->extContentHandled = 1;
    }    
    if (cctxt->inode->forwardsCompat == 0) {	
	/*
	* We are not in forwards-compatible mode, so raise an error.
	*/
	xsltTransformError(NULL, cctxt->style, node,
	    "Unknown XSLT element '%s'.\n", node->name);
	cctxt->style->errors++;
	return(1);
    }
    /*
    * Forwards-compatible mode.
    * ------------------------
    *    
    * Parse/compile xsl:fallback elements.
    *
    * QUESTION: Do we have to raise an error if there's no xsl:fallback?
    * ANSWER: No, since in the stylesheet the fallback behaviour might
    *  also be provided by using the XSLT function "element-available".
    */
    if (cctxt->unknownItem == NULL) {
	/*
	* Create a singleton for all unknown XSLT instructions.
	*/
	cctxt->unknownItem = xsltForwardsCompatUnkownItemCreate(cctxt);
	if (cctxt->unknownItem == NULL) {
	    node->psvi = NULL;
	    return(-1);
	}
    }
    node->psvi = cctxt->unknownItem;
    if (node->children == NULL)
	return(0);
    else {
	xmlNodePtr child = node->children;

	xsltCompilerNodePush(cctxt, node);
	/*
	* Update the in-scope namespaces if needed.
	*/
	if (node->nsDef != NULL)
	    cctxt->inode->inScopeNs =
		xsltCompilerBuildInScopeNsList(cctxt, node);
	/*
	* Parse all xsl:fallback children.
	*/
	do {
	    if ((child->type == XML_ELEMENT_NODE) &&
		IS_XSLT_ELEM_FAST(child) &&
		IS_XSLT_NAME(child, "fallback"))
	    {
		cctxt->inode->curChildType = XSLT_FUNC_FALLBACK;
		xsltParseAnyXSLTElem(cctxt, child);
	    }
	    child = child->next;
	} while (child != NULL);
	
	xsltCompilerNodePop(cctxt, node);
    }
    return(0);
}

/**
 * xsltParseSequenceConstructor:
 *
 * @cctxt: the compilation context
 * @cur: the start-node of the content to be parsed
 *
 * Parses a "template" content (or "sequence constructor" in XSLT 2.0 terms).
 * This will additionally remove xsl:text elements from the tree.
 */ 
void
xsltParseSequenceConstructor(xsltCompilerCtxtPtr cctxt, xmlNodePtr cur)
{
    xsltStyleType type;
    xmlNodePtr deleteNode = NULL;

    if (cctxt == NULL) {
	xmlGenericError(xmlGenericErrorContext,
	    "xsltParseSequenceConstructor: Bad arguments\n");
	cctxt->style->errors++;
	return;
    }
    /*
    * Detection of handled content of extension instructions.
    */
    if (cctxt->inode->category == XSLT_ELEMENT_CATEGORY_EXTENSION) {
	cctxt->inode->extContentHandled = 1;
    }
    if (cur == NULL)
	return;
    /*
    * This is the content reffered to as a "template".
    * E.g. an xsl:element has such content model:
    * <xsl:element
    *   name = { qname }
    *   namespace = { uri-reference }
    *   use-attribute-sets = qnames>
    * <!-- Content: template -->
    *
    * NOTE that in XSLT-2 the term "template" was abandoned due to
    *  confusion with xsl:template and the term "sequence constructor"
    *  was introduced instead.
    *
    * The following XSLT-instructions are allowed to appear:
    *  xsl:apply-templates, xsl:call-template, xsl:apply-imports,
    *  xsl:for-each, xsl:value-of, xsl:copy-of, xsl:number,
    *  xsl:choose, xsl:if, xsl:text, xsl:copy, xsl:variable,
    *  xsl:message, xsl:fallback,
    *  xsl:processing-instruction, xsl:comment, xsl:element
    *  xsl:attribute. 
    * Additional allowed content:
    * 1) extension instructions
    * 2) literal result elements
    * 3) PCDATA
    *
    * NOTE that this content model does *not* allow xsl:param.
    */    
    while (cur != NULL) {
	if (deleteNode != NULL)	{
#ifdef WITH_XSLT_DEBUG_BLANKS
	    xsltGenericDebug(xsltGenericDebugContext,
	     "xsltParseSequenceConstructor: removing xsl:text element\n");
#endif
	    xmlUnlinkNode(deleteNode);
	    xmlFreeNode(deleteNode);
	    deleteNode = NULL;
	}
	if (cur->type == XML_ELEMENT_NODE) {	    
	    
	    if (cur->psvi == xsltXSLTTextMarker) {
		/*
		* xsl:text elements
		* --------------------------------------------------------
		*/
		xmlNodePtr tmp;

		cur->psvi = NULL;
		/*
		* Mark the xsl:text element for later deletion.
		*/
		deleteNode = cur;
		/*
		* Validate content.
		*/
		tmp = cur->children;
		if (tmp) {
		    /*
		    * We don't expect more than one text-node in the
		    * content, since we already merged adjacent
		    * text/CDATA-nodes and eliminated PI/comment-nodes.
		    */
		    if ((tmp->type == XML_TEXT_NODE) ||
			(tmp->next == NULL))
		    {
			/*
			* Leave the contained text-node in the tree.
			*/
			xmlUnlinkNode(tmp);
			xmlAddPrevSibling(cur, tmp);
		    } else {
			tmp = NULL;
			xsltTransformError(NULL, cctxt->style, cur,
			    "Element 'xsl:text': Invalid type "
			    "of node found in content.\n");
			cctxt->style->errors++;
		    } 
		}
		if (cur->properties) {
		    xmlAttrPtr attr;
		    /*
		    * TODO: We need to report errors for
		    *  invalid attrs.
		    */
		    attr = cur->properties;
		    do {
			if ((attr->ns == NULL) &&
			    (attr->name != NULL) &&
			    (attr->name[0] == 'd') &&
			    xmlStrEqual(attr->name,
			    BAD_CAST "disable-output-escaping"))
			{
			    /*
			    * Attr "disable-output-escaping".
			    * XSLT-2: This attribute is deprecated.
			    */
			    if ((attr->children != NULL) &&
				xmlStrEqual(attr->children->content,
				BAD_CAST "yes"))
			    {
				/*
				* Disable output escaping for this
				* text node.
				*/
				if (tmp)
				    tmp->name = xmlStringTextNoenc;
			    } else if ((attr->children == NULL) ||
				(attr->children->content == NULL) ||
				(!xmlStrEqual(attr->children->content,
				BAD_CAST "no")))
			    {
				xsltTransformError(NULL, cctxt->style,
				    cur,
				    "Attribute 'disable-output-escaping': "
				    "Invalid value. Expected is "
				    "'yes' or 'no'.\n");
				cctxt->style->errors++;
			    }
			    break;
			}
			attr = attr->next;
		    } while (attr != NULL);
		}
	    } else if (IS_XSLT_ELEM_FAST(cur)) {
		/*
		* TODO: Using the XSLT-marker is still not stable yet.
		*/
		/* if (cur->psvi == xsltXSLTElemMarker) { */	    
		/*
		* XSLT instructions
		* --------------------------------------------------------
		*/
		cur->psvi = NULL;
		type = xsltGetXSLTElementTypeByNode(cctxt, cur);
		switch (type) {
		    case XSLT_FUNC_APPLYIMPORTS:
		    case XSLT_FUNC_APPLYTEMPLATES:
		    case XSLT_FUNC_ATTRIBUTE:
		    case XSLT_FUNC_CALLTEMPLATE:
		    case XSLT_FUNC_CHOOSE:
		    case XSLT_FUNC_COMMENT:
		    case XSLT_FUNC_COPY:
		    case XSLT_FUNC_COPYOF:
		    case XSLT_FUNC_DOCUMENT: /* Extra one */
		    case XSLT_FUNC_ELEMENT:
		    case XSLT_FUNC_FALLBACK:
		    case XSLT_FUNC_FOREACH:
		    case XSLT_FUNC_IF:
		    case XSLT_FUNC_MESSAGE:
		    case XSLT_FUNC_NUMBER:
		    case XSLT_FUNC_PI:
		    case XSLT_FUNC_TEXT:
		    case XSLT_FUNC_VALUEOF:
		    case XSLT_FUNC_VARIABLE:
			/*
			* Parse the XSLT element.
			*/
			cctxt->inode->curChildType = type;
			xsltParseAnyXSLTElem(cctxt, cur);
			break;
		    default:
			xsltParseUnknownXSLTElem(cctxt, cur);			
			cur = cur->next;
			continue;
		}
	    } else {
		/*
		* Non-XSLT elements
		* -----------------
		*/
		xsltCompilerNodePush(cctxt, cur);
		/*
		* Update the in-scope namespaces if needed.
		*/
		if (cur->nsDef != NULL)
		    cctxt->inode->inScopeNs =
			xsltCompilerBuildInScopeNsList(cctxt, cur);
		/*
		* The current element is either a literal result element
		* or an extension instruction.
		*
		* Process attr "xsl:extension-element-prefixes".
		* FUTURE TODO: IIRC in XSLT 2.0 this attribute must be
		* processed by the implementor of the extension function;
		* i.e., it won't be handled by the XSLT processor.
		*/
		/* SPEC 1.0:
		*   "exclude-result-prefixes" is only allowed on literal
		*   result elements and "xsl:exclude-result-prefixes"
		*   on xsl:stylesheet/xsl:transform.
		* SPEC 2.0:
		*   "There are a number of standard attributes
		*   that may appear on any XSLT element: specifically
		*   version, exclude-result-prefixes,
		*   extension-element-prefixes, xpath-default-namespace,
		*   default-collation, and use-when."
		*
		* SPEC 2.0:
		*   For literal result elements:
		*   "xsl:version, xsl:exclude-result-prefixes,
		*    xsl:extension-element-prefixes,
		*    xsl:xpath-default-namespace,
		*    xsl:default-collation, or xsl:use-when."
		*/
		if (cur->properties)
		    cctxt->inode->extElemNs =
			xsltParseExtElemPrefixes(cctxt,
			    cur, cctxt->inode->extElemNs,
			    XSLT_ELEMENT_CATEGORY_LRE);
		/*
		* Eval if we have an extension instruction here.
		*/
		if ((cur->ns != NULL) &&
		    (cctxt->inode->extElemNs != NULL) &&
		    (xsltCheckExtPrefix(cctxt->style, cur->ns->href) == 1))
		{
		    /*
		    * Extension instructions
		    * ----------------------------------------------------
		    * Mark the node information.
		    */
		    cctxt->inode->category = XSLT_ELEMENT_CATEGORY_EXTENSION;
		    cctxt->inode->extContentHandled = 0;
		    if (cur->psvi != NULL) {
			cur->psvi = NULL;
			/*
			* TODO: Temporary sanity check.
			*/
			xsltTransformError(NULL, cctxt->style, cur,
			    "Internal error in xsltParseSequenceConstructor(): "
			    "Occupied PSVI field.\n");
			cctxt->style->errors++;
			cur = cur->next;
			continue;
		    }
		    cur->psvi = (void *)
			xsltPreComputeExtModuleElement(cctxt->style, cur);
		    
		    if (cur->psvi == NULL) {
			/*
			* OLD COMMENT: "Unknown element, maybe registered
			*  at the context level. Mark it for later
			*  recognition."
			* QUESTION: What does the xsltExtMarker mean?
			*  ANSWER: It is used in
			*   xsltApplySequenceConstructor() at
			*   transformation-time to look out for extension
			*   registered in the transformation context.
			*/
			cur->psvi = (void *) xsltExtMarker;
		    }
		    /*
		    * BIG NOTE: Now the ugly part. In previous versions
		    *  of Libxslt (until 1.1.16), all the content of an
		    *  extension instruction was processed and compiled without
		    *  the need of the extension-author to explicitely call
		    *  such a processing;.We now need to mimic this old
		    *  behaviour in order to avoid breaking old code
		    *  on the extension-author's side.
		    * The mechanism:
		    *  1) If the author does *not* set the
		    *    compile-time-flag @extContentHandled, then we'll
		    *    parse the content assuming that it's a "template"
		    *    (or "sequence constructor in XSLT 2.0 terms).
		    *    NOTE: If the extension is registered at
		    *    transformation-time only, then there's no way of
		    *    knowing that content shall be valid, and we'll
		    *    process the content the same way.
		    *  2) If the author *does* set the flag, then we'll assume
		    *   that the author has handled the parsing him/herself
		    *   (e.g. called xsltParseSequenceConstructor(), etc.
		    *   explicitely in his/her code).
		    */
		    if ((cur->children != NULL) &&
			(cctxt->inode->extContentHandled == 0))
		    {
			/*
			* Default parsing of the content using the
			* sequence-constructor model.
			*/
			xsltParseSequenceConstructor(cctxt, cur->children);
		    }
		} else {
		    /*
		    * Literal result element
		    * ----------------------------------------------------
		    * Allowed XSLT attributes:
		    *  xsl:extension-element-prefixes CDATA #IMPLIED
		    *  xsl:exclude-result-prefixes CDATA #IMPLIED
		    *  TODO: xsl:use-attribute-sets %qnames; #IMPLIED
		    *  xsl:version NMTOKEN #IMPLIED
		    */
		    cur->psvi = NULL;
		    cctxt->inode->category = XSLT_ELEMENT_CATEGORY_LRE;
		    if (cur->properties != NULL) {
			xmlAttrPtr attr = cur->properties;
			/*
			* Attribute "xsl:exclude-result-prefixes".
			*/
			cctxt->inode->exclResultNs =
			    xsltParseExclResultPrefixes(cctxt, cur,
				cctxt->inode->exclResultNs,
				XSLT_ELEMENT_CATEGORY_LRE);
			/*
			* Attribute "xsl:version".
			*/
			xsltParseAttrXSLTVersion(cctxt, cur,
			    XSLT_ELEMENT_CATEGORY_LRE);
			/*
			* Report invalid XSLT attributes.			
			* For XSLT 1.0 only xsl:use-attribute-sets is allowed
			* next to xsl:version, xsl:exclude-result-prefixes and
			* xsl:extension-element-prefixes.
			*
			* Mark all XSLT attributes, in order to skip such
			* attributes when instantiating the LRE.
			*/
			do {
			    if ((attr->psvi != xsltXSLTAttrMarker) &&
				IS_XSLT_ATTR_FAST(attr))
			    {				    
				if (! xmlStrEqual(attr->name,
				    BAD_CAST "use-attribute-sets"))
				{				
				    xsltTransformError(NULL, cctxt->style,
					cur,
					"Unknown XSLT attribute '%s'.\n",
					attr->name);
				    cctxt->style->errors++;
				} else {
				    /*
				    * XSLT attr marker.
				    */
				    attr->psvi = (void *) xsltXSLTAttrMarker;
				}
			    }
			    attr = attr->next;
			} while (attr != NULL);
		    }
		    /*
		    * Create/reuse info for the literal result element.
		    */
		    if (cctxt->inode->nsChanged)
			xsltLREInfoCreate(cctxt, cur, 1);
		    cur->psvi = cctxt->inode->litResElemInfo;
		    /*
		    * Apply ns-aliasing on the element and on its attributes.
		    */
		    if (cctxt->hasNsAliases)
			xsltLREBuildEffectiveNs(cctxt, cur);
		    /*
		    * Compile attribute value templates (AVT).
		    */
		    if (cur->properties) {
			xmlAttrPtr attr = cur->properties;
			
			while (attr != NULL) {
			    xsltCompileAttr(cctxt->style, attr);
			    attr = attr->next;
			}
		    }
		    /*
		    * Parse the content, which is defined to be a "template"
		    * (or "sequence constructor" in XSLT 2.0 terms).
		    */
		    if (cur->children != NULL) {
			xsltParseSequenceConstructor(cctxt, cur->children);
		    }
		}
		/*
		* Leave the non-XSLT element.
		*/
		xsltCompilerNodePop(cctxt, cur);
	    }
	}
	cur = cur->next;
    }
    if (deleteNode != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
	xsltGenericDebug(xsltGenericDebugContext,
	    "xsltParseSequenceConstructor: removing xsl:text element\n");
#endif
	xmlUnlinkNode(deleteNode);
	xmlFreeNode(deleteNode);
	deleteNode = NULL;
    }
}

/**
 * xsltParseTemplateContent:
 * @style:  the XSLT stylesheet
 * @templ:  the node containing the content to be parsed
 *
 * Parses and compiles the content-model of an xsl:template element.
 * Note that this is *not* the "template" content model (or "sequence
 *  constructor" in XSLT 2.0); it it allows addional xsl:param
 *  elements as immediate children of @templ.
 *
 * Called by: 
 *   exsltFuncFunctionComp() (EXSLT, functions.c)
 *   So this is intended to be called from extension functions.
 */
void
xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
    if ((style == NULL) || (templ == NULL))
	return;

    /*
    * Detection of handled content of extension instructions.
    */
    if (XSLT_CCTXT(style)->inode->category == XSLT_ELEMENT_CATEGORY_EXTENSION) {
	XSLT_CCTXT(style)->inode->extContentHandled = 1;
    }

    if (templ->children != NULL) {	
	xmlNodePtr child = templ->children;
	/*
	* Process xsl:param elements, which can only occur as the
	* immediate children of xsl:template (well, and of any
	* user-defined extension instruction if needed).
	*/	
	do {
	    if ((child->type == XML_ELEMENT_NODE) &&
		IS_XSLT_ELEM_FAST(child) &&
		IS_XSLT_NAME(child, "param"))
	    {
		XSLT_CCTXT(style)->inode->curChildType = XSLT_FUNC_PARAM;
		xsltParseAnyXSLTElem(XSLT_CCTXT(style), child);
	    } else
		break;
	    child = child->next;
	} while (child != NULL);
	/*
	* Parse the content and register the pattern.
	*/
	xsltParseSequenceConstructor(XSLT_CCTXT(style), child);
    }
}

#else /* XSLT_REFACTORED */

/**
 * xsltParseTemplateContent:
 * @style:  the XSLT stylesheet
 * @templ:  the container node (can be a document for literal results)
 *
 * parse a template content-model
 * Clean-up the template content from unwanted ignorable blank nodes
 * and process xslt:text
 */
void
xsltParseTemplateContent(xsltStylesheetPtr style, xmlNodePtr templ) {
    xmlNodePtr cur, delete;
    /*
     * This content comes from the stylesheet
     * For stylesheets, the set of whitespace-preserving
     * element names consists of just xsl:text.
     */
    cur = templ->children;
    delete = NULL;
    while (cur != NULL) {
	if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_BLANKS
	    xsltGenericDebug(xsltGenericDebugContext,
	     "xsltParseTemplateContent: removing text\n");
#endif
	    xmlUnlinkNode(delete);
	    xmlFreeNode(delete);
	    delete = NULL;
	}
	if (IS_XSLT_ELEM(cur)) {
	    if (IS_XSLT_NAME(cur, "text")) {
		/*
		* TODO: Processing of xsl:text should be moved to
		*   xsltPrecomputeStylesheet(), since otherwise this
		*   will be performed for every multiply included
		*   stylesheet; i.e. this here is not skipped with
		*   the use of the style->nopreproc flag.
		*/
		if (cur->children != NULL) {
		    xmlChar *prop;
		    xmlNodePtr text = cur->children, next;
		    int noesc = 0;
			
		    prop = xmlGetNsProp(cur,
			(const xmlChar *)"disable-output-escaping",
			NULL);
		    if (prop != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
			xsltGenericDebug(xsltGenericDebugContext,
			     "Disable escaping: %s\n", text->content);
#endif
			if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
			    noesc = 1;
			} else if (!xmlStrEqual(prop,
						(const xmlChar *)"no")){
			    xsltTransformError(NULL, style, cur,
	     "xsl:text: disable-output-escaping allows only yes or no\n");
			    style->warnings++;

			}
			xmlFree(prop);
		    }

		    while (text != NULL) {
			if (text->type == XML_COMMENT_NODE) {
			    text = text->next;
			    continue;
			}
			if ((text->type != XML_TEXT_NODE) &&
			     (text->type != XML_CDATA_SECTION_NODE)) {
			    xsltTransformError(NULL, style, cur,
		 "xsltParseTemplateContent: xslt:text content problem\n");
			    style->errors++;
			    break;
			}
			if ((noesc) && (text->type != XML_CDATA_SECTION_NODE))
			    text->name = xmlStringTextNoenc;
			text = text->next;
		    }

		    /*
		     * replace xsl:text by the list of childs
		     */
		    if (text == NULL) {
			text = cur->children;
			while (text != NULL) {
			    if ((style->internalized) &&
			        (text->content != NULL) &&
			        (!xmlDictOwns(style->dict, text->content))) {

				/*
				 * internalize the text string
				 */
				if (text->doc->dict != NULL) {
				    const xmlChar *tmp;
				    
				    tmp = xmlDictLookup(text->doc->dict,
				                        text->content, -1);
				    if (tmp != text->content) {
				        xmlNodeSetContent(text, NULL);
					text->content = (xmlChar *) tmp;
				    }
				}
			    }

			    next = text->next;
			    xmlUnlinkNode(text);
			    xmlAddPrevSibling(cur, text);
			    text = next;
			}
		    }
		}
		delete = cur;
		goto skip_children;
	    }
	}
	else if ((cur->ns != NULL) && (style->nsDefs != NULL) &&
	    (xsltCheckExtPrefix(style, cur->ns->prefix)))
	{
	    /*
	     * okay this is an extension element compile it too
	     */
	    xsltStylePreCompute(style, cur);
	}
	else if (cur->type == XML_ELEMENT_NODE)
	{
	    /*
	     * This is an element which will be output as part of the
	     * template exectution, precompile AVT if found.
	     */
	    if ((cur->ns == NULL) && (style->defaultAlias != NULL)) {
		cur->ns = xmlSearchNsByHref(cur->doc, cur,
			style->defaultAlias);
	    }
	    if (cur->properties != NULL) {
	        xmlAttrPtr attr = cur->properties;

		while (attr != NULL) {
		    xsltCompileAttr(style, attr);
		    attr = attr->next;
		}
	    }
	}
	/*
	 * Skip to next node
	 */
	if (cur->children != NULL) {
	    if (cur->children->type != XML_ENTITY_DECL) {
		cur = cur->children;
		continue;
	    }
	}
skip_children:
	if (cur->next != NULL) {
	    cur = cur->next;
	    continue;
	}
	
	do {
	    cur = cur->parent;
	    if (cur == NULL)
		break;
	    if (cur == templ) {
		cur = NULL;
		break;
	    }
	    if (cur->next != NULL) {
		cur = cur->next;
		break;
	    }
	} while (cur != NULL);
    }
    if (delete != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
	 "xsltParseTemplateContent: removing text\n");
#endif
	xmlUnlinkNode(delete);
	xmlFreeNode(delete);
	delete = NULL;
    }

    /*
     * Skip the first params
     */
    cur = templ->children;
    while (cur != NULL) {
	if ((IS_XSLT_ELEM(cur)) && (!(IS_XSLT_NAME(cur, "param"))))
	    break;
	cur = cur->next;
    }

    /*
     * Browse the remainder of the template
     */
    while (cur != NULL) {
	if ((IS_XSLT_ELEM(cur)) && (IS_XSLT_NAME(cur, "param"))) {
	    xmlNodePtr param = cur;

	    xsltTransformError(NULL, style, cur,
		"xsltParseTemplateContent: ignoring misplaced param element\n");
	    if (style != NULL) style->warnings++;
            cur = cur->next;
	    xmlUnlinkNode(param);
	    xmlFreeNode(param);
	} else
	    break;
    }
}

#endif /* else XSLT_REFACTORED */

/**
 * xsltParseStylesheetKey:
 * @style:  the XSLT stylesheet
 * @key:  the "key" element
 *
 * <!-- Category: top-level-element -->
 * <xsl:key name = qname, match = pattern, use = expression />
 *
 * parse an XSLT stylesheet key definition and register it
 */

static void
xsltParseStylesheetKey(xsltStylesheetPtr style, xmlNodePtr key) {
    xmlChar *prop = NULL;
    xmlChar *use = NULL;
    xmlChar *match = NULL;
    xmlChar *name = NULL;
    xmlChar *nameURI = NULL;

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

    /*
     * Get arguments
     */
    prop = xmlGetNsProp(key, (const xmlChar *)"name", NULL);
    if (prop != NULL) {
        const xmlChar *URI;

	/*
	* TODO: Don't use xsltGetQNameURI().
	*/
	URI = xsltGetQNameURI(key, &prop);
	if (prop == NULL) {
	    if (style != NULL) style->errors++;
	    goto error;
	} else {
	    name = prop;
	    if (URI != NULL)
		nameURI = xmlStrdup(URI);
	}
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
	     "xsltParseStylesheetKey: name %s\n", name);
#endif
    } else {
	xsltTransformError(NULL, style, key,
	    "xsl:key : error missing name\n");
	if (style != NULL) style->errors++;
	goto error;
    }

    match = xmlGetNsProp(key, (const xmlChar *)"match", NULL);
    if (match == NULL) {
	xsltTransformError(NULL, style, key,
	    "xsl:key : error missing match\n");
	if (style != NULL) style->errors++;
	goto error;
    }

    use = xmlGetNsProp(key, (const xmlChar *)"use", NULL);
    if (use == NULL) {
	xsltTransformError(NULL, style, key,
	    "xsl:key : error missing use\n");
	if (style != NULL) style->errors++;
	goto error;
    }

    /*
     * register the keys
     */
    xsltAddKey(style, name, nameURI, match, use, key);


error:
    if (use != NULL)
	xmlFree(use);
    if (match != NULL)
	xmlFree(match);
    if (name != NULL)
	xmlFree(name);
    if (nameURI != NULL)
	xmlFree(nameURI);

    if (key->children != NULL) {
	xsltParseContentError(style, key->children);
    }
}

#ifdef XSLT_REFACTORED
/**
 * xsltParseXSLTTemplate:
 * @style:  the XSLT stylesheet
 * @template:  the "template" element
 *
 * parse an XSLT stylesheet template building the associated structures
 * TODO: Is @style ever expected to be NULL?
 *
 * Called from:
 *   xsltParseXSLTStylesheet()
 *   xsltParseStylesheetTop()
 */

static void
xsltParseXSLTTemplate(xsltCompilerCtxtPtr cctxt, xmlNodePtr templNode) {
    xsltTemplatePtr templ;
    xmlChar *prop;    
    double  priority;    

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

    /*
     * Create and link the structure
     */
    templ = xsltNewTemplate();
    if (templ == NULL)
	return;

    xsltCompilerNodePush(cctxt, templNode);
    if (templNode->nsDef != NULL)
	cctxt->inode->inScopeNs =
	    xsltCompilerBuildInScopeNsList(cctxt, templNode);

    templ->next = cctxt->style->templates;
    cctxt->style->templates = templ;
    templ->style = cctxt->style;  

    /*
    * Attribute "mode".
    */
    prop = xmlGetNsProp(templNode, (const xmlChar *)"mode", NULL);
    if (prop != NULL) {	
        const xmlChar *modeURI;

	/*
	* TODO: We need a standardized function for extraction
	*  of namespace names and local names from QNames.
	*  Don't use xsltGetQNameURI() as it cannot channel
	*  reports through the context.
	*/
	modeURI = xsltGetQNameURI(templNode, &prop);
	if (prop == NULL) {
	    cctxt->style->errors++;
	    goto error;
	}
	templ->mode = xmlDictLookup(cctxt->style->dict, prop, -1);
	xmlFree(prop);
	prop = NULL;
	if (xmlValidateNCName(templ->mode, 0)) {
	    xsltTransformError(NULL, cctxt->style, templNode,
		"xsl:template: Attribute 'mode': The local part '%s' "
		"of the value is not a valid NCName.\n", templ->name);
	    cctxt->style->errors++;
	    goto error;
	}
	if (modeURI != NULL)
	    templ->modeURI = xmlDictLookup(cctxt->style->dict, modeURI, -1);
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
	     "xsltParseXSLTTemplate: mode %s\n", templ->mode);
#endif
    }
    /*
    * Attribute "match".
    */
    prop = xmlGetNsProp(templNode, (const xmlChar *)"match", NULL);
    if (prop != NULL) {
	templ->match  = prop;
	prop = NULL;
    }
    /*
    * Attribute "priority".
    */
    prop = xmlGetNsProp(templNode, (const xmlChar *)"priority", NULL);
    if (prop != NULL) {
	priority = xmlXPathStringEvalNumber(prop);
	templ->priority = (float) priority;
	xmlFree(prop);
	prop = NULL;
    }
    /*
    * Attribute "name".
    */
    prop = xmlGetNsProp(templNode, (const xmlChar *)"name", NULL);
    if (prop != NULL) {
        const xmlChar *nameURI;
	xsltTemplatePtr curTempl;
	
	/*
	* TODO: Don't use xsltGetQNameURI().
	*/
	nameURI = xsltGetQNameURI(templNode, &prop);
	if (prop == NULL) {
	    cctxt->style->errors++;
	    goto error;
	}
	templ->name = xmlDictLookup(cctxt->style->dict, prop, -1);
	xmlFree(prop);
	prop = NULL;
	if (xmlValidateNCName(templ->name, 0)) {
	    xsltTransformError(NULL, cctxt->style, templNode,
		"xsl:template: Attribute 'name': The local part '%s' of "
		"the value is not a valid NCName.\n", templ->name);
	    cctxt->style->errors++;
	    goto error;
	} 	
	if (nameURI != NULL)
	    templ->nameURI = xmlDictLookup(cctxt->style->dict, nameURI, -1);
	curTempl = templ->next;
	while (curTempl != NULL) {
	    if ((nameURI != NULL && xmlStrEqual(curTempl->name, templ->name) &&
		xmlStrEqual(curTempl->nameURI, nameURI) ) ||
		(nameURI == NULL && curTempl->nameURI == NULL &&
		xmlStrEqual(curTempl->name, templ->name)))
	    {
		xsltTransformError(NULL, cctxt->style, templNode,
		    "xsl:template: error duplicate name '%s'\n", templ->name);
		cctxt->style->errors++;
		goto error;
	    }
	    curTempl = curTempl->next;
	}
    }
    if (templNode->children != NULL) {
	xsltParseTemplateContent(cctxt->style, templNode);	
	/*
	* MAYBE TODO: Custom behaviour: In order to stay compatible with
	* Xalan and MSXML(.NET), we could allow whitespace
	* to appear before an xml:param element; this whitespace
	* will additionally become part of the "template".
	* NOTE that this is totally deviates from the spec, but
	* is the de facto behaviour of Xalan and MSXML(.NET).
	* Personally I wouldn't allow this, since if we have:
	* <xsl:template ...xml:space="preserve">
	*   <xsl:param name="foo"/>
	*   <xsl:param name="bar"/>
	*   <xsl:param name="zoo"/>
	* ... the whitespace between every xsl:param would be
	* added to the result tree.
	*/		
    }    
    
    templ->elem = templNode;
    templ->content = templNode->children;
    xsltAddTemplate(cctxt->style, templ, templ->mode, templ->modeURI);

error:
    xsltCompilerNodePop(cctxt, templNode);
    return;
}

#else /* XSLT_REFACTORED */

/**
 * xsltParseStylesheetTemplate:
 * @style:  the XSLT stylesheet
 * @template:  the "template" element
 *
 * parse an XSLT stylesheet template building the associated structures
 */

static void
xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
    xsltTemplatePtr ret;
    xmlChar *prop;
    xmlChar *mode = NULL;
    xmlChar *modeURI = NULL;
    double  priority;

    if (template == NULL)
	return;

    /*
     * Create and link the structure
     */
    ret = xsltNewTemplate();
    if (ret == NULL)
	return;
    ret->next = style->templates;
    style->templates = ret;
    ret->style = style;
   
    /*
     * Get inherited namespaces
     */
    /*
    * TODO: Apply the optimized in-scope-namespace mechanism
    *   as for the other XSLT instructions.
    */
    xsltGetInheritedNsList(style, ret, template);

    /*
     * Get arguments
     */
    prop = xmlGetNsProp(template, (const xmlChar *)"mode", NULL);
    if (prop != NULL) {
        const xmlChar *URI;

	/*
	* TODO: Don't use xsltGetQNameURI().
	*/
	URI = xsltGetQNameURI(template, &prop);
	if (prop == NULL) {
	    if (style != NULL) style->errors++;
	    goto error;
	} else {
	    mode = prop;
	    if (URI != NULL)
		modeURI = xmlStrdup(URI);
	}
	ret->mode = xmlDictLookup(style->dict, mode, -1);
	ret->modeURI = xmlDictLookup(style->dict, modeURI, -1);
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
	     "xsltParseStylesheetTemplate: mode %s\n", mode);
#endif
        if (mode != NULL) xmlFree(mode);
	if (modeURI != NULL) xmlFree(modeURI);
    }
    prop = xmlGetNsProp(template, (const xmlChar *)"match", NULL);
    if (prop != NULL) {
	if (ret->match != NULL) xmlFree(ret->match);
	ret->match  = prop;
    }

    prop = xmlGetNsProp(template, (const xmlChar *)"priority", NULL);
    if (prop != NULL) {
	priority = xmlXPathStringEvalNumber(prop);
	ret->priority = (float) priority;
	xmlFree(prop);
    }

    prop = xmlGetNsProp(template, (const xmlChar *)"name", NULL);
    if (prop != NULL) {
        const xmlChar *URI;
	xsltTemplatePtr cur;
	
	/*
	* TODO: Don't use xsltGetQNameURI().
	*/
	URI = xsltGetQNameURI(template, &prop);
	if (prop == NULL) {
	    if (style != NULL) style->errors++;
	    goto error;
	} else {
	    if (xmlValidateNCName(prop,0)) {
	        xsltTransformError(NULL, style, template,
	            "xsl:template : error invalid name '%s'\n", prop);
		if (style != NULL) style->errors++;
		goto error;
	    }
	    ret->name = xmlDictLookup(style->dict, BAD_CAST prop, -1);
	    xmlFree(prop);
	    prop = NULL;
	    if (URI != NULL)
		ret->nameURI = xmlDictLookup(style->dict, BAD_CAST URI, -1);
	    else
		ret->nameURI = NULL;
	    cur = ret->next;
	    while (cur != NULL) {
	        if ((URI != NULL && xmlStrEqual(cur->name, ret->name) &&
				xmlStrEqual(cur->nameURI, URI) ) ||
		    (URI == NULL && cur->nameURI == NULL &&
				xmlStrEqual(cur->name, ret->name))) {
		    xsltTransformError(NULL, style, template,
		        "xsl:template: error duplicate name '%s'\n", ret->name);
		    style->errors++;
		    goto error;
		}
		cur = cur->next;
	    }
	}
    }

    /*
     * parse the content and register the pattern
     */
    xsltParseTemplateContent(style, template);
    ret->elem = template;
    ret->content = template->children;
    xsltAddTemplate(style, ret, ret->mode, ret->modeURI);

error:
    return;
}

#endif /* else XSLT_REFACTORED */

#ifdef XSLT_REFACTORED

/**
 * xsltIncludeComp:
 * @cctxt: the compilation contenxt
 * @node:  the xsl:include node
 *
 * Process the xslt include node on the source node
 */
static xsltStyleItemIncludePtr
xsltCompileXSLTIncludeElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr node) {
    xsltStyleItemIncludePtr item;

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

    node->psvi = NULL;
    item = (xsltStyleItemIncludePtr) xmlMalloc(sizeof(xsltStyleItemInclude));
    if (item == NULL) {
	xsltTransformError(NULL, cctxt->style, node,
		"xsltIncludeComp : malloc failed\n");
	cctxt->style->errors++;
	return(NULL);
    }
    memset(item, 0, sizeof(xsltStyleItemInclude));

    node->psvi = item;
    item->inst = node;
    item->type = XSLT_FUNC_INCLUDE;

    item->next = cctxt->style->preComps;
    cctxt->style->preComps = (xsltElemPreCompPtr) item;

    return(item);
}

/**
 * xsltParseFindTopLevelElem:
 */
static int
xsltParseFindTopLevelElem(xsltCompilerCtxtPtr cctxt,
			      xmlNodePtr cur,
			      const xmlChar *name,
			      const xmlChar *namespaceURI,
			      int breakOnOtherElem,			      
			      xmlNodePtr *resultNode)
{
    if (name == NULL)
	return(-1);

    *resultNode = NULL;
    while (cur != NULL) {
	if (cur->type == XML_ELEMENT_NODE) {
	    if ((cur->ns != NULL) && (cur->name != NULL)) {
		if ((*(cur->name) == *name) &&
		    xmlStrEqual(cur->name, name) &&
		    xmlStrEqual(cur->ns->href, namespaceURI))		    
		{
		    *resultNode = cur;
		    return(1);
		}
	    }
	    if (breakOnOtherElem)
		break;
	}
	cur = cur->next;
    }
    *resultNode = cur;
    return(0);
}

static int
xsltParseTopLevelXSLTElem(xsltCompilerCtxtPtr cctxt,
			  xmlNodePtr node,
			  xsltStyleType type)
{
    int ret = 0;

    /*
    * TODO: The reason why this function exists:
    *  due to historical reasons some of the
    *  top-level declarations are processed by functions
    *  in other files. Since we need still to set
    *  up the node-info and generate information like
    *  in-scope namespaces, this is a wrapper around
    *  those old parsing functions.
    */
    xsltCompilerNodePush(cctxt, node);
    if (node->nsDef != NULL)
	cctxt->inode->inScopeNs =
	    xsltCompilerBuildInScopeNsList(cctxt, node);
    cctxt->inode->type = type;

    switch (type) {
	case XSLT_FUNC_INCLUDE:
	    {
		int oldIsInclude;

		if (xsltCompileXSLTIncludeElem(cctxt, node) == NULL)
		    goto exit;		
		/*
		* Mark this stylesheet tree as being currently included.
		*/
		oldIsInclude = cctxt->isInclude;
		cctxt->isInclude = 1;
						
		if (xsltParseStylesheetInclude(cctxt->style, node) != 0) {
		    cctxt->style->errors++;
		}
		cctxt->isInclude = oldIsInclude;
	    }
	    break;
	case XSLT_FUNC_PARAM:
	    xsltStylePreCompute(cctxt->style, node);
	    xsltParseGlobalParam(cctxt->style, node);
	    break;
	case XSLT_FUNC_VARIABLE:
	    xsltStylePreCompute(cctxt->style, node);
	    xsltParseGlobalVariable(cctxt->style, node);
	    break;
	case XSLT_FUNC_ATTRSET:
	    xsltParseStylesheetAttributeSet(cctxt->style, node);
	    break;
	default:
	    xsltTransformError(NULL, cctxt->style, node,
		"Internal error: (xsltParseTopLevelXSLTElem) "
		"Cannot handle this top-level declaration.\n");
	    cctxt->style->errors++;
	    ret = -1;
    }

exit:
    xsltCompilerNodePop(cctxt, node);

    return(ret);
}

#if 0
static int
xsltParseRemoveWhitespace(xmlNodePtr node)
{
    if ((node == NULL) || (node->children == NULL))
	return(0);
    else {
	xmlNodePtr delNode = NULL, child = node->children;

	do {
	    if (delNode) {
		xmlUnlinkNode(delNode);
		xmlFreeNode(delNode);
		delNode = NULL;
	    }
	    if (((child->type == XML_TEXT_NODE) ||
		 (child->type == XML_CDATA_SECTION_NODE)) &&
		(IS_BLANK_NODE(child)))
		delNode = child;	    
	    child = child->next;
	} while (child != NULL);
	if (delNode) {
	    xmlUnlinkNode(delNode);
	    xmlFreeNode(delNode);
	    delNode = NULL;
	}
    }
    return(0);
}
#endif

static int
xsltParseXSLTStylesheetElemCore(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{
#ifdef WITH_XSLT_DEBUG_PARSING
    int templates = 0;
#endif
    xmlNodePtr cur, start = NULL;
    xsltStylesheetPtr style;

    if ((cctxt == NULL) || (node == NULL) ||
	(node->type != XML_ELEMENT_NODE))
	return(-1);    

    style = cctxt->style;    
    /*
    * At this stage all import declarations of all stylesheet modules
    * with the same stylesheet level have been processed.
    * Now we can safely parse the rest of the declarations.
    */
    if (IS_XSLT_ELEM_FAST(node) && IS_XSLT_NAME(node, "include"))
    {
	xsltDocumentPtr include;
	/*
	* URGENT TODO: Make this work with simplified stylesheets!
	*   I.e., when we won't find an xsl:stylesheet element.
	*/
	/*
	* This is as include declaration.
	*/
	include = ((xsltStyleItemIncludePtr) node->psvi)->include;
	if (include == NULL) {
	    /* TODO: raise error? */
	    return(-1);
	}
	/*
	* TODO: Actually an xsl:include should locate an embedded
	*  stylesheet as well; so the document-element won't always
	*  be the element where the actual stylesheet is rooted at.
	*  But such embedded stylesheets are not supported by Libxslt yet.
	*/
	node = xmlDocGetRootElement(include->doc);
	if (node == NULL) {
	    return(-1);
	}
    }    
    
    if (node->children == NULL)
	return(0);
    /*
    * Push the xsl:stylesheet/xsl:transform element.
    */  
    xsltCompilerNodePush(cctxt, node);
    cctxt->inode->isRoot = 1;
    cctxt->inode->nsChanged = 0;
    /*
    * Start with the naked dummy info for literal result elements.
    */
    cctxt->inode->litResElemInfo = cctxt->inodeList->litResElemInfo;

    /*
    * In every case, we need to have
    * the in-scope namespaces of the element, where the
    * stylesheet is rooted at, regardless if it's an XSLT
    * instruction or a literal result instruction (or if
    * this is an embedded stylesheet).
    */		
    cctxt->inode->inScopeNs =
	xsltCompilerBuildInScopeNsList(cctxt, node);

    /*
    * Process attributes of xsl:stylesheet/xsl:transform.
    * --------------------------------------------------
    * Allowed are:
    *  id = id
    *  extension-element-prefixes = tokens
    *  exclude-result-prefixes = tokens
    *  version = number (mandatory)    
    */
    if (xsltParseAttrXSLTVersion(cctxt, node,
	XSLT_ELEMENT_CATEGORY_XSLT) == 0)
    {    
	/*
	* Attribute "version".
	* XSLT 1.0: "An xsl:stylesheet element *must* have a version
	*  attribute, indicating the version of XSLT that the
	*  stylesheet requires".
	* The root element of a simplified stylesheet must also have
	* this attribute.
	*/
#ifdef XSLT_REFACTORED_MANDATORY_VERSION
	if (isXsltElem)
	    xsltTransformError(NULL, cctxt->style, node,
		"The attribute 'version' is missing.\n");
	cctxt->style->errors++;	
#else
	/* OLD behaviour. */
	xsltTransformError(NULL, cctxt->style, node,
	    "xsl:version is missing: document may not be a stylesheet\n");
	cctxt->style->warnings++;
#endif
    }    
    /*
    * The namespaces declared by the attributes
    *  "extension-element-prefixes" and
    *  "exclude-result-prefixes" are local to *this*
    *  stylesheet tree; i.e., they are *not* visible to
    *  other stylesheet-modules, whether imported or included.
    * 
    * Attribute "extension-element-prefixes".
    */
    cctxt->inode->extElemNs =
	xsltParseExtElemPrefixes(cctxt, node, NULL,
	    XSLT_ELEMENT_CATEGORY_XSLT);
    /*
    * Attribute "exclude-result-prefixes".
    */
    cctxt->inode->exclResultNs =
	xsltParseExclResultPrefixes(cctxt, node, NULL,
	    XSLT_ELEMENT_CATEGORY_XSLT);
    /*
    * Create/reuse info for the literal result element.
    */
    if (cctxt->inode->nsChanged)
	xsltLREInfoCreate(cctxt, node, 0);
    /*
    * Processed top-level elements:
    * ----------------------------
    *  xsl:variable, xsl:param (QName, in-scope ns,
    *    expression (vars allowed))
    *  xsl:attribute-set (QName, in-scope ns)
    *  xsl:strip-space, xsl:preserve-space (XPath NameTests,
    *    in-scope ns)
    *    I *think* global scope, merge with includes
    *  xsl:output (QName, in-scope ns)
    *  xsl:key (QName, in-scope ns, pattern,
    *    expression (vars *not* allowed))
    *  xsl:decimal-format (QName, needs in-scope ns)
    *  xsl:namespace-alias (in-scope ns)
    *    global scope, merge with includes
    *  xsl:template (last, QName, pattern)
    *
    * (whitespace-only text-nodes have *not* been removed
    *  yet; this will be done in xsltParseSequenceConstructor)
    *
    * Report misplaced child-nodes first.
    */
    cur = node->children;
    while (cur != NULL) {
	if (cur->type == XML_TEXT_NODE) {
	    xsltTransformError(NULL, style, cur,
		"Misplaced text node (content: '%s').\n",
		(cur->content != NULL) ? cur->content : BAD_CAST "");
	    style->errors++;
	} else if (cur->type != XML_ELEMENT_NODE) {
	    xsltTransformError(NULL, style, cur, "Misplaced node.\n");
	    style->errors++;
	}
	cur = cur->next;
    }
    /*
    * Skip xsl:import elements; they have been processed
    * already.
    */
    cur = node->children;
    while ((cur != NULL) && xsltParseFindTopLevelElem(cctxt, cur,
	    BAD_CAST "import", XSLT_NAMESPACE, 1, &cur) == 1)
	cur = cur->next;
    if (cur == NULL)
	goto exit;

    start = cur;
    /*
    * Process all top-level xsl:param elements.
    */
    while ((cur != NULL) &&
	xsltParseFindTopLevelElem(cctxt, cur,
	BAD_CAST "param", XSLT_NAMESPACE, 0, &cur) == 1)
    {
	xsltParseTopLevelXSLTElem(cctxt, cur, XSLT_FUNC_PARAM);	
	cur = cur->next;
    }  
    /*
    * Process all top-level xsl:variable elements.
    */
    cur = start;
    while ((cur != NULL) &&
	xsltParseFindTopLevelElem(cctxt, cur,
	BAD_CAST "variable", XSLT_NAMESPACE, 0, &cur) == 1)
    {
	xsltParseTopLevelXSLTElem(cctxt, cur, XSLT_FUNC_VARIABLE);
	cur = cur->next;
    }   
    /*
    * Process all the rest of top-level elements.
    */
    cur = start;
    while (cur != NULL) {	
	/*
	* Process element nodes.
	*/
	if (cur->type == XML_ELEMENT_NODE) {	    
	    if (cur->ns == NULL) {
		xsltTransformError(NULL, style, cur,
		    "Unexpected top-level element in no namespace.\n");
		style->errors++;
		cur = cur->next;
		continue;
	    }
	    /*
	    * Process all XSLT elements.
	    */
	    if (IS_XSLT_ELEM_FAST(cur)) {
		/*
		* xsl:import is only allowed at the beginning.
		*/
		if (IS_XSLT_NAME(cur, "import")) {
		    xsltTransformError(NULL, style, cur,
			"Misplaced xsl:import element.\n");
		    style->errors++;
		    cur = cur->next;
		    continue;
		}
		/* 
		* TODO: Change the return type of the parsing functions
		*  to int.
		*/
		if (IS_XSLT_NAME(cur, "template")) {
#ifdef WITH_XSLT_DEBUG_PARSING
		    templates++;
#endif
		    /*
		    * TODO: Is the position of xsl:template in the
		    *  tree significant? If not it would be easier to
		    *  parse them at a later stage.
		    */
		    xsltParseXSLTTemplate(cctxt, cur);
		} else if (IS_XSLT_NAME(cur, "variable")) {
		    /* NOP; done already */
		} else if (IS_XSLT_NAME(cur, "param")) {
		    /* NOP; done already */
		} else if (IS_XSLT_NAME(cur, "include")) {		    
		    if (cur->psvi != NULL)		    
			xsltParseXSLTStylesheetElemCore(cctxt, cur);
		    else {
			xsltTransformError(NULL, style, cur,
			    "Internal error: "
			    "(xsltParseXSLTStylesheetElemCore) "
			    "The xsl:include element was not compiled.\n");
			style->errors++;
		    }
		} else if (IS_XSLT_NAME(cur, "strip-space")) {
		    /* No node info needed. */
		    xsltParseStylesheetStripSpace(style, cur);
		} else if (IS_XSLT_NAME(cur, "preserve-space")) {
		    /* No node info needed. */
		    xsltParseStylesheetPreserveSpace(style, cur);
		} else if (IS_XSLT_NAME(cur, "output")) {
		    /* No node-info needed. */
		    xsltParseStylesheetOutput(style, cur);
		} else if (IS_XSLT_NAME(cur, "key")) {
		    /* TODO: node-info needed for expressions ? */
		    xsltParseStylesheetKey(style, cur);
		} else if (IS_XSLT_NAME(cur, "decimal-format")) {
		    /* No node-info needed. */		     
		    xsltParseStylesheetDecimalFormat(style, cur);
		} else if (IS_XSLT_NAME(cur, "attribute-set")) {		    
		    xsltParseTopLevelXSLTElem(cctxt, cur,
			XSLT_FUNC_ATTRSET);		
		} else if (IS_XSLT_NAME(cur, "namespace-alias")) {
		    /* NOP; done already */		    
		} else {
		    if (cctxt->inode->forwardsCompat) {
			/*
			* Forwards-compatible mode:
			*
			* XSLT-1: "if it is a top-level element and
			*  XSLT 1.0 does not allow such elements as top-level
			*  elements, then the element must be ignored along
			*  with its content;"
			*/
			/*
			* TODO: I don't think we should generate a warning.
			*/
			xsltTransformError(NULL, style, cur,
			    "Forwards-compatible mode: Ignoring unknown XSLT "
			    "element '%s'.\n", cur->name);
			style->warnings++;
		    } else {
			xsltTransformError(NULL, style, cur,
			    "Unknown XSLT element '%s'.\n", cur->name);
			style->errors++;
		    }
		}
	    } else {
		xsltTopLevelFunction function;

		/*
		* Process non-XSLT elements, which are in a
		*  non-NULL namespace.
		*/
		/*
		* QUESTION: What does xsltExtModuleTopLevelLookup()
		*  do exactly?
		*/
		function = xsltExtModuleTopLevelLookup(cur->name,
		    cur->ns->href);
		if (function != NULL)
		    function(style, cur);
#ifdef WITH_XSLT_DEBUG_PARSING
		xsltGenericDebug(xsltGenericDebugContext,
		    "xsltParseXSLTStylesheetElemCore : User-defined "
		    "data element '%s'.\n", cur->name);
#endif
	    }
	}
	cur = cur->next;
    }

exit:

#ifdef WITH_XSLT_DEBUG_PARSING
    xsltGenericDebug(xsltGenericDebugContext,
	"### END of parsing top-level elements of doc '%s'.\n",
	node->doc->URL);
    xsltGenericDebug(xsltGenericDebugContext,
	"### Templates: %d\n", templates);
#ifdef XSLT_REFACTORED
    xsltGenericDebug(xsltGenericDebugContext,
	"### Max inodes: %d\n", cctxt->maxNodeInfos);
    xsltGenericDebug(xsltGenericDebugContext,
	"### Max LREs  : %d\n", cctxt->maxLREs);
#endif /* XSLT_REFACTORED */
#endif /* WITH_XSLT_DEBUG_PARSING */

    xsltCompilerNodePop(cctxt, node);
    return(0);
}

/**
 * xsltParseXSLTStylesheet:
 * @cctxt: the compiler context
 * @node: the xsl:stylesheet/xsl:transform element-node
 *
 * Parses the xsl:stylesheet and xsl:transform element. 
 *
 * <xsl:stylesheet
 *  id = id
 *  extension-element-prefixes = tokens
 *  exclude-result-prefixes = tokens
 *  version = number>
 *  <!-- Content: (xsl:import*, top-level-elements) -->
 * </xsl:stylesheet>
 *
 * BIG TODO: The xsl:include stuff.
 * 
 * Called by xsltParseStylesheetTree()
 *
 * Returns 0 on success, a positive result on errors and
 *         -1 on API or internal errors.
 */
static int
xsltParseXSLTStylesheetElem(xsltCompilerCtxtPtr cctxt, xmlNodePtr node)
{
    xmlNodePtr cur, start;

    if ((cctxt == NULL) || (node == NULL))
	return(-1);
    
    if (node->children == NULL)
	goto exit;

    /*
    * Process top-level elements:
    *  xsl:import (must be first)
    *  xsl:include (this is just a pre-processing)
    */
    cur = node->children;
    /*
    * Process xsl:import elements.
    * XSLT 1.0: "The xsl:import element children must precede all
    *  other element children of an xsl:stylesheet element,
    *  including any xsl:include element children."
    */    
    while ((cur != NULL) &&
	xsltParseFindTopLevelElem(cctxt, cur,
	    BAD_CAST "import", XSLT_NAMESPACE, 1, &cur) == 1)
    {
	if (xsltParseStylesheetImport(cctxt->style, cur) != 0) {
	    cctxt->style->errors++;
	}
	cur = cur->next;
    }
    if (cur == NULL)
	goto exit;
    start = cur;
    /*
    * Pre-process all xsl:include elements.
    */
    cur = start;
    while ((cur != NULL) &&
	xsltParseFindTopLevelElem(cctxt, cur,
	    BAD_CAST "include", XSLT_NAMESPACE, 0, &cur) == 1)
    {
	xsltParseTopLevelXSLTElem(cctxt, cur, XSLT_FUNC_INCLUDE);
	cur = cur->next;
    }
    /*
    * Pre-process all xsl:namespace-alias elements.
    * URGENT TODO: This won't work correctly: the order of included
    *  aliases and aliases defined here is significant.
    */
    cur = start;
    while ((cur != NULL) &&
	xsltParseFindTopLevelElem(cctxt, cur,
	    BAD_CAST "namespace-alias", XSLT_NAMESPACE, 0, &cur) == 1)
    {
	xsltNamespaceAlias(cctxt->style, cur);
	cur = cur->next;
    }

    if (cctxt->isInclude) {
	/*
	* If this stylesheet is intended for inclusion, then
	* we will process only imports and includes. 
	*/
	goto exit;
    } 
    /*
    * Now parse the rest of the top-level elements.
    */
    xsltParseXSLTStylesheetElemCore(cctxt, node); 	
exit:

    return(0);
}

#else /* XSLT_REFACTORED */

/**
 * xsltParseStylesheetTop:
 * @style:  the XSLT stylesheet
 * @top:  the top level "stylesheet" or "transform" element
 *
 * scan the top level elements of an XSL stylesheet
 */
static void
xsltParseStylesheetTop(xsltStylesheetPtr style, xmlNodePtr top) {
    xmlNodePtr cur;
    xmlChar *prop;
#ifdef WITH_XSLT_DEBUG_PARSING
    int templates = 0;
#endif

    if (top == NULL)
	return;

    prop = xmlGetNsProp(top, (const xmlChar *)"version", NULL);
    if (prop == NULL) {
	xsltTransformError(NULL, style, top,
	    "xsl:version is missing: document may not be a stylesheet\n");
	if (style != NULL) style->warnings++;
    } else {
	if ((!xmlStrEqual(prop, (const xmlChar *)"1.0")) &&
            (!xmlStrEqual(prop, (const xmlChar *)"1.1"))) {
	    xsltTransformError(NULL, style, top,
		"xsl:version: only 1.0 features are supported\n");
	     /* TODO set up compatibility when not XSLT 1.0 */
	    if (style != NULL) style->warnings++;
	}
	xmlFree(prop);
    }

    /*
     * process xsl:import elements
     */
    cur = top->children;
    while (cur != NULL) {
	    if (IS_BLANK_NODE(cur)) {
		    cur = cur->next;
		    continue;
	    }
	    if (IS_XSLT_ELEM(cur) && IS_XSLT_NAME(cur, "import")) {
		    if (xsltParseStylesheetImport(style, cur) != 0)
			    if (style != NULL) style->errors++;
	    } else
		    break;
	    cur = cur->next;
    }

    /*
     * process other top-level elements
     */
    while (cur != NULL) {
	if (IS_BLANK_NODE(cur)) {
	    cur = cur->next;
	    continue;
	}
	if (cur->type == XML_TEXT_NODE) {
	    if (cur->content != NULL) {
		xsltTransformError(NULL, style, cur,
		    "misplaced text node: '%s'\n", cur->content);
	    }
	    if (style != NULL) style->errors++;
            cur = cur->next;
	    continue;
	}
	if ((cur->type == XML_ELEMENT_NODE) && (cur->ns == NULL)) {
	    xsltGenericError(xsltGenericErrorContext,
		     "Found a top-level element %s with null namespace URI\n",
		     cur->name);
	    if (style != NULL) style->errors++;
	    cur = cur->next;
	    continue;
	}
	if ((cur->type == XML_ELEMENT_NODE) && (!(IS_XSLT_ELEM(cur)))) {
	    xsltTopLevelFunction function;

	    function = xsltExtModuleTopLevelLookup(cur->name,
						   cur->ns->href);
	    if (function != NULL)
		function(style, cur);

#ifdef WITH_XSLT_DEBUG_PARSING
	    xsltGenericDebug(xsltGenericDebugContext,
		    "xsltParseStylesheetTop : found foreign element %s\n",
		    cur->name);
#endif
            cur = cur->next;
	    continue;
	}
	if (IS_XSLT_NAME(cur, "import")) {
	    xsltTransformError(NULL, style, cur,
			"xsltParseStylesheetTop: ignoring misplaced import element\n");
	    if (style != NULL) style->errors++;
    } else if (IS_XSLT_NAME(cur, "include")) {
	    if (xsltParseStylesheetInclude(style, cur) != 0)
		if (style != NULL) style->errors++;
    } else if (IS_XSLT_NAME(cur, "strip-space")) {
	    xsltParseStylesheetStripSpace(style, cur);
    } else if (IS_XSLT_NAME(cur, "preserve-space")) {
	    xsltParseStylesheetPreserveSpace(style, cur);
    } else if (IS_XSLT_NAME(cur, "output")) {
	    xsltParseStylesheetOutput(style, cur);
    } else if (IS_XSLT_NAME(cur, "key")) {
	    xsltParseStylesheetKey(style, cur);
    } else if (IS_XSLT_NAME(cur, "decimal-format")) {
	    xsltParseStylesheetDecimalFormat(style, cur);
    } else if (IS_XSLT_NAME(cur, "attribute-set")) {
	    xsltParseStylesheetAttributeSet(style, cur);
    } else if (IS_XSLT_NAME(cur, "variable")) {
	    xsltParseGlobalVariable(style, cur);
    } else if (IS_XSLT_NAME(cur, "param")) {
	    xsltParseGlobalParam(style, cur);
    } else if (IS_XSLT_NAME(cur, "template")) {
#ifdef WITH_XSLT_DEBUG_PARSING
	    templates++;
#endif
	    xsltParseStylesheetTemplate(style, cur);
    } else if (IS_XSLT_NAME(cur, "namespace-alias")) {
	    xsltNamespaceAlias(style, cur);
	} else {
	    /*
	    * BUG TODO: The version of the *doc* is irrelevant for
	    *  the forwards-compatible mode.
	    */
            if ((style != NULL) && (style->doc->version != NULL) &&
	        (!strncmp((const char *) style->doc->version, "1.0", 3))) {
	        xsltTransformError(NULL, style, cur,
			"xsltParseStylesheetTop: unknown %s element\n",
			cur->name);
	        if (style != NULL) style->errors++;
	    }
	    else {
                /* do Forwards-Compatible Processing */
	        xsltTransformError(NULL, style, cur,
			"xsltParseStylesheetTop: ignoring unknown %s element\n",
			cur->name);
	        if (style != NULL) style->warnings++;
            }
	}
	cur = cur->next;
    }
#ifdef WITH_XSLT_DEBUG_PARSING
    xsltGenericDebug(xsltGenericDebugContext,
		    "parsed %d templates\n", templates);
#endif
}

#endif /* else of XSLT_REFACTORED */

#ifdef XSLT_REFACTORED
/**
 * xsltParseSimplifiedStylesheetTree:
 *
 * @style: the stylesheet (TODO: Change this to the compiler context)
 * @doc: the document containing the stylesheet.
 * @node: the node where the stylesheet is rooted at
 *
 * Returns 0 in case of success, a positive result if an error occurred
 *         and -1 on API and internal errors.
 */
static int
xsltParseSimplifiedStylesheetTree(xsltCompilerCtxtPtr cctxt,
				  xmlDocPtr doc,
				  xmlNodePtr node)
{
    xsltTemplatePtr templ;
    
    if ((cctxt == NULL) || (node == NULL))
	return(-1);

    if (xsltParseAttrXSLTVersion(cctxt, node, 0) == XSLT_ELEMENT_CATEGORY_LRE)
    {
	/*
	* TODO: Adjust report, since this might be an
	* embedded stylesheet.
	*/
	xsltTransformError(NULL, cctxt->style, node,
	    "The attribute 'xsl:version' is missing; cannot identify "
	    "this document as an XSLT stylesheet document.\n");
	cctxt->style->errors++;
	return(1);
    }
    
#ifdef WITH_XSLT_DEBUG_PARSING
    xsltGenericDebug(xsltGenericDebugContext,
	"xsltParseSimplifiedStylesheetTree: document is stylesheet\n");
#endif        
    
    /*
    * Create and link the template
    */
    templ = xsltNewTemplate();
    if (templ == NULL) {
	return(-1);
    }
    templ->next = cctxt->style->templates;
    cctxt->style->templates = templ;
    templ->match = xmlStrdup(BAD_CAST "/");

    /*
    * Note that we push the document-node in this special case.
    */
    xsltCompilerNodePush(cctxt, (xmlNodePtr) doc);
    /*
    * In every case, we need to have
    * the in-scope namespaces of the element, where the
    * stylesheet is rooted at, regardless if it's an XSLT
    * instruction or a literal result instruction (or if
    * this is an embedded stylesheet).
    */
    cctxt->inode->inScopeNs =
	xsltCompilerBuildInScopeNsList(cctxt, node);
    /*
    * Parse the content and register the match-pattern.
    */
    xsltParseSequenceConstructor(cctxt, node);
    xsltCompilerNodePop(cctxt, (xmlNodePtr) doc);

    templ->elem = (xmlNodePtr) doc;
    templ->content = node;
    xsltAddTemplate(cctxt->style, templ, NULL, NULL);
    cctxt->style->literal_result = 1;
    return(0);
}

#ifdef XSLT_REFACTORED_XSLT_NSCOMP
/**
 * xsltRestoreDocumentNamespaces:
 * @ns: map of namespaces
 * @doc: the document
 *
 * Restore the namespaces for the document
 *
 * Returns 0 in case of success, -1 in case of failure
 */
int
xsltRestoreDocumentNamespaces(xsltNsMapPtr ns, xmlDocPtr doc)
{
    if (doc == NULL)
	return(-1);
    /*
    * Revert the changes we have applied to the namespace-URIs of
    * ns-decls.
    */    
    while (ns != NULL) {
	if ((ns->doc == doc) && (ns->ns != NULL)) {
	    ns->ns->href = ns->origNsName;
	    ns->origNsName = NULL;
	    ns->ns = NULL;	    
	}
	ns = ns->next;
    }
    return(0);
}
#endif /* XSLT_REFACTORED_XSLT_NSCOMP */

/**
 * xsltParseStylesheetProcess:
 * @style:  the XSLT stylesheet (the current stylesheet-level)
 * @doc:  and xmlDoc parsed XML
 *
 * Parses an XSLT stylesheet, adding the associated structures.
 * Called by:
 *  xsltParseStylesheetImportedDoc() (xslt.c)
 *  xsltParseStylesheetInclude() (imports.c)
 *
 * Returns the value of the @style parameter if everything
 * went right, NULL if something went amiss.
 */
xsltStylesheetPtr
xsltParseStylesheetProcess(xsltStylesheetPtr style, xmlDocPtr doc)
{
    xsltCompilerCtxtPtr cctxt;
    xmlNodePtr cur;
    int oldIsSimplifiedStylesheet;

    xsltInitGlobals();

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

    cctxt = XSLT_CCTXT(style);

    cur = xmlDocGetRootElement(doc);
    if (cur == NULL) {
	xsltTransformError(NULL, style, (xmlNodePtr) doc,
		"xsltParseStylesheetProcess : empty stylesheet\n");
	return(NULL);
    }
    oldIsSimplifiedStylesheet = cctxt->simplified;

    if ((IS_XSLT_ELEM(cur)) && 
	((IS_XSLT_NAME(cur, "stylesheet")) ||
	 (IS_XSLT_NAME(cur, "transform")))) {	
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
		"xsltParseStylesheetProcess : found stylesheet\n");
#endif
	cctxt->simplified = 0;
	style->literal_result = 0;
    } else {
	cctxt->simplified = 1;
	style->literal_result = 1;
    }
    /*
    * Pre-process the stylesheet if not already done before.
    *  This will remove PIs and comments, merge adjacent
    *  text nodes, internalize strings, etc.
    */
    if (! style->nopreproc)
	xsltParsePreprocessStylesheetTree(cctxt, cur);
    /*
    * Parse and compile the stylesheet.
    */
    if (style->literal_result == 0) {
	if (xsltParseXSLTStylesheetElem(cctxt, cur) != 0)
	    return(NULL);
    } else {
	if (xsltParseSimplifiedStylesheetTree(cctxt, doc, cur) != 0)
	    return(NULL);
    }    

    cctxt->simplified = oldIsSimplifiedStylesheet;

    return(style);
}

#else /* XSLT_REFACTORED */

/**
 * xsltParseStylesheetProcess:
 * @ret:  the XSLT stylesheet (the current stylesheet-level)
 * @doc:  and xmlDoc parsed XML
 *
 * Parses an XSLT stylesheet, adding the associated structures.
 * Called by:
 *  xsltParseStylesheetImportedDoc() (xslt.c)
 *  xsltParseStylesheetInclude() (imports.c)
 *
 * Returns the value of the @style parameter if everything
 * went right, NULL if something went amiss.
 */
xsltStylesheetPtr
xsltParseStylesheetProcess(xsltStylesheetPtr ret, xmlDocPtr doc) {
    xmlNodePtr cur;

    xsltInitGlobals();

    if (doc == NULL)
	return(NULL);
    if (ret == NULL)
	return(ret);
    
    /*
     * First steps, remove blank nodes,
     * locate the xsl:stylesheet element and the
     * namespace declaration.
     */
    cur = xmlDocGetRootElement(doc);
    if (cur == NULL) {
	xsltTransformError(NULL, ret, (xmlNodePtr) doc,
		"xsltParseStylesheetProcess : empty stylesheet\n");
	return(NULL);
    }

    if ((IS_XSLT_ELEM(cur)) && 
	((IS_XSLT_NAME(cur, "stylesheet")) ||
	 (IS_XSLT_NAME(cur, "transform")))) {	
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
		"xsltParseStylesheetProcess : found stylesheet\n");
#endif
	ret->literal_result = 0;
	xsltParseStylesheetExcludePrefix(ret, cur, 1);
	xsltParseStylesheetExtPrefix(ret, cur, 1);
    } else {
	xsltParseStylesheetExcludePrefix(ret, cur, 0);
	xsltParseStylesheetExtPrefix(ret, cur, 0);
	ret->literal_result = 1;
    }
    if (!ret->nopreproc) {
	xsltPrecomputeStylesheet(ret, cur);
    }
    if (ret->literal_result == 0) {
	xsltParseStylesheetTop(ret, cur);
    } else {
	xmlChar *prop;
	xsltTemplatePtr template;

	/*
	 * the document itself might be the template, check xsl:version
	 */
	prop = xmlGetNsProp(cur, (const xmlChar *)"version", XSLT_NAMESPACE);
	if (prop == NULL) {
	    xsltTransformError(NULL, ret, cur,
		"xsltParseStylesheetProcess : document is not a stylesheet\n");
	    return(NULL);
	}

#ifdef WITH_XSLT_DEBUG_PARSING
        xsltGenericDebug(xsltGenericDebugContext,
		"xsltParseStylesheetProcess : document is stylesheet\n");
#endif
	
	if (!xmlStrEqual(prop, (const xmlChar *)"1.0")) {
	    xsltTransformError(NULL, ret, cur,
		"xsl:version: only 1.0 features are supported\n");
	     /* TODO set up compatibility when not XSLT 1.0 */
	    ret->warnings++;
	}
	xmlFree(prop);

	/*
	 * Create and link the template
	 */
	template = xsltNewTemplate();
	if (template == NULL) {
	    return(NULL);
	}
	template->next = ret->templates;
	ret->templates = template;
	template->match = xmlStrdup((const xmlChar *)"/");

	/*
	 * parse the content and register the pattern
	 */
	xsltParseTemplateContent(ret, (xmlNodePtr) doc);
	template->elem = (xmlNodePtr) doc;
	template->content = doc->children;
	xsltAddTemplate(ret, template, NULL, NULL);
	ret->literal_result = 1;	
    }

    return(ret);
}

#endif /* else of XSLT_REFACTORED */

/**
 * xsltParseStylesheetImportedDoc:
 * @doc:  an xmlDoc parsed XML
 * @parentStyle: pointer to the parent stylesheet (if it exists)
 *
 * parse an XSLT stylesheet building the associated structures
 * except the processing not needed for imported documents.
 *
 * Returns a new XSLT stylesheet structure.
 */

xsltStylesheetPtr
xsltParseStylesheetImportedDoc(xmlDocPtr doc,
			       xsltStylesheetPtr parentStyle) {
    xsltStylesheetPtr retStyle;

    if (doc == NULL)
	return(NULL);

    retStyle = xsltNewStylesheet();
    if (retStyle == NULL)
	return(NULL);
    /*
    * Set the importing stylesheet module; also used to detect recursion.
    */
    retStyle->parent = parentStyle;
    /*
    * Adjust the string dict.
    */
    if (doc->dict != NULL) {
        xmlDictFree(retStyle->dict);
	retStyle->dict = doc->dict;
#ifdef WITH_XSLT_DEBUG
        xsltGenericDebug(xsltGenericDebugContext,
	    "reusing dictionary from %s for stylesheet\n",
	    doc->URL);
#endif
	xmlDictReference(retStyle->dict);
    }    	
    
    /*
    * TODO: Eliminate xsltGatherNamespaces(); we must not restrict
    *  the stylesheet to containt distinct namespace prefixes.
    */
    xsltGatherNamespaces(retStyle);

#ifdef XSLT_REFACTORED
    {
	xsltCompilerCtxtPtr cctxt;
	xsltStylesheetPtr oldCurSheet;
	    
	if (parentStyle == NULL) {
	    xsltPrincipalStylesheetDataPtr principalData;
	    /*
	    * Principal stylesheet
	    * --------------------
	    */
	    retStyle->principal = retStyle;
	    /*
	    * Create extra data for the principal stylesheet.
	    */
	    principalData = xsltNewPrincipalStylesheetData();
	    if (principalData == NULL) {
		xsltFreeStylesheet(retStyle);
		return(NULL);
	    }
	    retStyle->principalData = principalData;
	    /*
	    * Create the compilation context
	    * ------------------------------
	    * (only once; for the principal stylesheet).
	    * This is currently the only function where the
	    * compilation context is created.
	    */
	    cctxt = xsltCompilationCtxtCreate(retStyle);
	    if (cctxt == NULL) {
		xsltFreeStylesheet(retStyle);
		return(NULL);
	    }	    	    
	    retStyle->compCtxt = (void *) cctxt;
	    cctxt->style = retStyle;
	    cctxt->dict = retStyle->dict;
	    cctxt->psData = principalData;
	    /*
	    * Push initial dummy node info.
	    */
	    cctxt->depth = -1;
	    xsltCompilerNodePush(cctxt, (xmlNodePtr) doc);
	} else {
	    /*
	    * Imported stylesheet.
	    */
	    retStyle->principal = parentStyle->principal;
	    cctxt = parentStyle->compCtxt;
	    retStyle->compCtxt = cctxt;
	}
	/*
	* Save the old and set the current stylesheet structure in the
	* compilation context.
	*/
	oldCurSheet = cctxt->style;
	cctxt->style = retStyle;
	
	retStyle->doc = doc;
	xsltParseStylesheetProcess(retStyle, doc);
	
	cctxt->style = oldCurSheet;
	if (parentStyle == NULL) {
	    /*
	    * Pop the initial dummy node info.
	    */
	    xsltCompilerNodePop(cctxt, (xmlNodePtr) doc);
	} else {
	    /*
	    * Clear the compilation context of imported
	    * stylesheets.
	    * TODO: really?
	    */
	    /* retStyle->compCtxt = NULL; */
	}
	/*
	* Free the stylesheet if there were errors.
	*/
	if (retStyle != NULL) {
	    if (retStyle->errors != 0) {
#ifdef XSLT_REFACTORED_XSLT_NSCOMP
		/*
		* Restore all changes made to namespace URIs of ns-decls.
		*/
		if (cctxt->psData->nsMap)		
		    xsltRestoreDocumentNamespaces(cctxt->psData->nsMap, doc);
#endif
		/*
		* Detach the doc from the stylesheet; otherwise the doc
		* will be freed in xsltFreeStylesheet().
		*/
		retStyle->doc = NULL;
		/*
		* Cleanup the doc if its the main stylesheet.
		*/
		if (parentStyle == NULL) {
		    xsltCleanupStylesheetTree(doc, xmlDocGetRootElement(doc));
		    if (retStyle->compCtxt != NULL) {			
			xsltCompilationCtxtFree(retStyle->compCtxt);
			retStyle->compCtxt = NULL;
		    }
		}

		xsltFreeStylesheet(retStyle);
		retStyle = NULL;
	    }
	}
    }
        
#else /* XSLT_REFACTORED */
    /*
    * Old behaviour.
    */
    retStyle->doc = doc;
    if (xsltParseStylesheetProcess(retStyle, doc) == NULL) {
		retStyle->doc = NULL;
		xsltFreeStylesheet(retStyle);
		retStyle = NULL;
    }
    if (retStyle != NULL) {
	if (retStyle->errors != 0) {
	    retStyle->doc = NULL;
	    if (parentStyle == NULL)
		xsltCleanupStylesheetTree(doc,
		    xmlDocGetRootElement(doc));
	    xsltFreeStylesheet(retStyle);
	    retStyle = NULL;
	}
    }
#endif /* else of XSLT_REFACTORED */
        
    return(retStyle);
}

/**
 * xsltParseStylesheetDoc:
 * @doc:  and xmlDoc parsed XML
 *
 * parse an XSLT stylesheet, building the associated structures.  doc
 * is kept as a reference within the returned stylesheet, so changes
 * to doc after the parsing will be reflected when the stylesheet
 * is applied, and the doc is automatically freed when the
 * stylesheet is closed.
 *
 * Returns a new XSLT stylesheet structure.
 */

xsltStylesheetPtr
xsltParseStylesheetDoc(xmlDocPtr doc) {
    xsltStylesheetPtr ret;

    xsltInitGlobals();

    ret = xsltParseStylesheetImportedDoc(doc, NULL);
    if (ret == NULL)
	return(NULL);

    xsltResolveStylesheetAttributeSet(ret);
#ifdef XSLT_REFACTORED
    /*
    * Free the compilation context.
    * TODO: Check if it's better to move this cleanup to
    *   xsltParseStylesheetImportedDoc().
    */
    if (ret->compCtxt != NULL) {
	xsltCompilationCtxtFree(XSLT_CCTXT(ret));
	ret->compCtxt = NULL;
    }
#endif
    return(ret);
}

/**
 * xsltParseStylesheetFile:
 * @filename:  the filename/URL to the stylesheet
 *
 * Load and parse an XSLT stylesheet
 *
 * Returns a new XSLT stylesheet structure.
 */

xsltStylesheetPtr
xsltParseStylesheetFile(const xmlChar* filename) {
    xsltSecurityPrefsPtr sec;
    xsltStylesheetPtr ret;
    xmlDocPtr doc;
    
    xsltInitGlobals();

    if (filename == NULL)
	return(NULL);

#ifdef WITH_XSLT_DEBUG_PARSING
    xsltGenericDebug(xsltGenericDebugContext,
	    "xsltParseStylesheetFile : parse %s\n", filename);
#endif

    /*
     * Security framework check
     */
    sec = xsltGetDefaultSecurityPrefs();
    if (sec != NULL) {
	int res;

	res = xsltCheckRead(sec, NULL, filename);
	if (res == 0) {
	    xsltTransformError(NULL, NULL, NULL,
		 "xsltParseStylesheetFile: read rights for %s denied\n",
			     filename);
	    return(NULL);
	}
    }

    doc = xsltDocDefaultLoader(filename, NULL, XSLT_PARSE_OPTIONS,
                               NULL, XSLT_LOAD_START);
    if (doc == NULL) {
	xsltTransformError(NULL, NULL, NULL,
		"xsltParseStylesheetFile : cannot parse %s\n", filename);
	return(NULL);
    }
    ret = xsltParseStylesheetDoc(doc);
    if (ret == NULL) {
	xmlFreeDoc(doc);
	return(NULL);
    }

    return(ret);
}

/************************************************************************
 *									*
 *			Handling of Stylesheet PI			*
 *									*
 ************************************************************************/

#define CUR (*cur)
#define SKIP(val) cur += (val)
#define NXT(val) cur[(val)]
#define SKIP_BLANKS						\
    while (IS_BLANK(CUR)) NEXT
#define NEXT ((*cur) ?  cur++ : cur)

/**
 * xsltParseStylesheetPI:
 * @value: the value of the PI
 *
 * This function checks that the type is text/xml and extracts
 * the URI-Reference for the stylesheet
 *
 * Returns the URI-Reference for the stylesheet or NULL (it need to
 *         be freed by the caller)
 */
static xmlChar *
xsltParseStylesheetPI(const xmlChar *value) {
    const xmlChar *cur;
    const xmlChar *start;
    xmlChar *val;
    xmlChar tmp;
    xmlChar *href = NULL;
    int isXml = 0;

    if (value == NULL)
	return(NULL);

    cur = value;
    while (CUR != 0) {
	SKIP_BLANKS;
	if ((CUR == 't') && (NXT(1) == 'y') && (NXT(2) == 'p') &&
	    (NXT(3) == 'e')) {
	    SKIP(4);
	    SKIP_BLANKS;
	    if (CUR != '=')
		continue;
	    NEXT;
	    if ((CUR != '\'') && (CUR != '"'))
		continue;
	    tmp = CUR;
	    NEXT;
	    start = cur;
	    while ((CUR != 0) && (CUR != tmp))
		NEXT;
	    if (CUR != tmp)
		continue;
	    val = xmlStrndup(start, cur - start);
	    NEXT;
	    if (val == NULL) 
		return(NULL);
	    if ((xmlStrcasecmp(val, BAD_CAST "text/xml")) &&
		(xmlStrcasecmp(val, BAD_CAST "text/xsl"))) {
                xmlFree(val);
		break;
	    }
	    isXml = 1;
	    xmlFree(val);
	} else if ((CUR == 'h') && (NXT(1) == 'r') && (NXT(2) == 'e') &&
	    (NXT(3) == 'f')) {
	    SKIP(4);
	    SKIP_BLANKS;
	    if (CUR != '=')
		continue;
	    NEXT;
	    if ((CUR != '\'') && (CUR != '"'))
		continue;
	    tmp = CUR;
	    NEXT;
	    start = cur;
	    while ((CUR != 0) && (CUR != tmp))
		NEXT;
	    if (CUR != tmp)
		continue;
	    if (href == NULL)
		href = xmlStrndup(start, cur - start);
	    NEXT;
	} else {
	    while ((CUR != 0) && (!IS_BLANK(CUR)))
		NEXT;
	}
            
    }

    if (!isXml) {
	if (href != NULL)
	    xmlFree(href);
	href = NULL;
    }
    return(href);
}

/**
 * xsltLoadStylesheetPI:
 * @doc:  a document to process
 *
 * This function tries to locate the stylesheet PI in the given document
 * If found, and if contained within the document, it will extract 
 * that subtree to build the stylesheet to process @doc (doc itself will
 * be modified). If found but referencing an external document it will
 * attempt to load it and generate a stylesheet from it. In both cases,
 * the resulting stylesheet and the document need to be freed once the
 * transformation is done.
 *
 * Returns a new XSLT stylesheet structure or NULL if not found.
 */
xsltStylesheetPtr
xsltLoadStylesheetPI(xmlDocPtr doc) {
    xmlNodePtr child;
    xsltStylesheetPtr ret = NULL;
    xmlChar *href = NULL;
    xmlURIPtr URI;

    xsltInitGlobals();

    if (doc == NULL)
	return(NULL);

    /*
     * Find the text/xml stylesheet PI id any before the root
     */
    child = doc->children;
    while ((child != NULL) && (child->type != XML_ELEMENT_NODE)) {
	if ((child->type == XML_PI_NODE) &&
	    (xmlStrEqual(child->name, BAD_CAST "xml-stylesheet"))) {
	    href = xsltParseStylesheetPI(child->content);
	    if (href != NULL)
		break;
	}
	child = child->next;
    }

    /*
     * If found check the href to select processing
     */
    if (href != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
	xsltGenericDebug(xsltGenericDebugContext,
		"xsltLoadStylesheetPI : found PI href=%s\n", href);
#endif
	URI = xmlParseURI((const char *) href);
	if (URI == NULL) {
	    xsltTransformError(NULL, NULL, child,
		    "xml-stylesheet : href %s is not valid\n", href);
	    xmlFree(href);
	    return(NULL);
	}
	if ((URI->fragment != NULL) && (URI->scheme == NULL) &&
            (URI->opaque == NULL) && (URI->authority == NULL) &&
            (URI->server == NULL) && (URI->user == NULL) &&
            (URI->path == NULL) && (URI->query == NULL)) {
	    xmlAttrPtr ID;

#ifdef WITH_XSLT_DEBUG_PARSING
	    xsltGenericDebug(xsltGenericDebugContext,
		    "xsltLoadStylesheetPI : Reference to ID %s\n", href);
#endif
	    if (URI->fragment[0] == '#')
		ID = xmlGetID(doc, (const xmlChar *) &(URI->fragment[1]));
	    else
		ID = xmlGetID(doc, (const xmlChar *) URI->fragment);
	    if (ID == NULL) {
		xsltTransformError(NULL, NULL, child,
		    "xml-stylesheet : no ID %s found\n", URI->fragment);
	    } else {
		xmlDocPtr fake;
		xmlNodePtr subtree, newtree;
		xmlNsPtr ns;

#ifdef WITH_XSLT_DEBUG
		xsltGenericDebug(xsltGenericDebugContext,
		    "creating new document from %s for embedded stylesheet\n",
		    doc->URL);
#endif
		/*
		 * move the subtree in a new document passed to
		 * the stylesheet analyzer
		 */
		subtree = ID->parent;
		fake = xmlNewDoc(NULL);
		if (fake != NULL) {
		    /*
		    * Should the dictionary still be shared even though
		    * the nodes are being copied rather than moved?
		    */
		    fake->dict = doc->dict;
		    xmlDictReference(doc->dict);
#ifdef WITH_XSLT_DEBUG
		    xsltGenericDebug(xsltGenericDebugContext,
			"reusing dictionary from %s for embedded stylesheet\n",
			doc->URL);
#endif

		    newtree = xmlDocCopyNode(subtree, fake, 1);

		    fake->URL = xmlNodeGetBase(doc, subtree->parent);
#ifdef WITH_XSLT_DEBUG
		    xsltGenericDebug(xsltGenericDebugContext,
			"set base URI for embedded stylesheet as %s\n",
			fake->URL);
#endif

		    /*
		    * Add all namespaces in scope of embedded stylesheet to
		    * root element of newly created stylesheet document
		    */
		    while ((subtree = subtree->parent) != (xmlNodePtr)doc) {
			for (ns = subtree->ns; ns; ns = ns->next) {
			    xmlNewNs(newtree,  ns->href, ns->prefix);
			}
		    }

		    xmlAddChild((xmlNodePtr)fake, newtree);
		    ret = xsltParseStylesheetDoc(fake);
		    if (ret == NULL)
			xmlFreeDoc(fake);
		}
	    }
	} else {
	    xmlChar *URL, *base;

	    /*
	     * Reference to an external stylesheet
	     */

	    base = xmlNodeGetBase(doc, (xmlNodePtr) doc);
	    URL = xmlBuildURI(href, base);
	    if (URL != NULL) {
#ifdef WITH_XSLT_DEBUG_PARSING
		xsltGenericDebug(xsltGenericDebugContext,
			"xsltLoadStylesheetPI : fetching %s\n", URL);
#endif
		ret = xsltParseStylesheetFile(URL);
		xmlFree(URL);
	    } else {
#ifdef WITH_XSLT_DEBUG_PARSING
		xsltGenericDebug(xsltGenericDebugContext,
			"xsltLoadStylesheetPI : fetching %s\n", href);
#endif
		ret = xsltParseStylesheetFile(href);
	    }
	    if (base != NULL)
		xmlFree(base);
	}
	xmlFreeURI(URI);
	xmlFree(href);
    }
    return(ret);
}
