/*******************************************************************************
 * Copyright (C) 2004-2006 Intel Corp. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  - Neither the name of Intel Corp. nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

/**
 * @author Anas Nashif
 */
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#include <assert.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xmlstring.h>

#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>


#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"
#include "wsman-xml-binding.h"


static void destroy_attr_private_data(void *data)
{
	if (data)
		xmlFree(data);
}


static void destroy_node_private_data(void *_data)
{
	iWsNode *data = (iWsNode *) _data;
	if (data) {
		// ??? TBD data->nsQNameList;
		if (data->valText)
			xmlFree(data->valText);
		u_free(data);
	}
}

static void destroy_tree_private_data(xmlNode * node)
{
	while (node) {
		xmlAttrPtr attr = node->properties;

		if (node->_private) {
			destroy_node_private_data(node->_private);
			node->_private = NULL;
		}

		while (attr) {
			if (attr->_private) {
				destroy_attr_private_data(attr->_private);
				attr->_private = NULL;
			}
			attr = attr->next;
		}
		destroy_tree_private_data(node->children);
		node = node->next;
	}
}

static void
myXmlErrorReporting (void *ctx, const char* msg, ...)
{
	va_list args;
	char *string;
	va_start(args, msg);
	string = u_strdup_vprintf (msg, args);
	_warning (string);
	va_end(args);

	u_free(string);
}

void xml_parser_initialize()
{
	xmlSetGenericErrorFunc(NULL, myXmlErrorReporting);
}

void xml_parser_destroy()
{
}

int xml_parser_utf8_strlen(char *buf)
{
	return xmlUTF8Strlen(BAD_CAST buf);
}

void xml_parser_doc_to_memory(WsXmlDocH doc, char **buf,
		int *ptrSize, const char *encoding)
{
	if (doc && buf && ptrSize)
		xmlDocDumpMemoryEnc(doc->parserDoc,
				(xmlChar **) buf, ptrSize,
				(!encoding) ? "UTF-8" : encoding);
}

void xml_parser_free_memory(void *ptr)
{
	if (ptr)
		xmlFree(ptr);
}



int xml_parser_create_doc_by_import(WsXmlDocH wsDoc, WsXmlNodeH node)
{
	xmlDocPtr doc;
	xmlNodePtr rootNode;

	if ((doc = xmlNewDoc(BAD_CAST "1.0")) == NULL) {
		return 0;
	} else {
		doc->_private = wsDoc;
		wsDoc->parserDoc = doc;
		rootNode = xmlDocCopyNode((xmlNodePtr) node, doc, 1);
		xmlDocSetRootElement(doc, rootNode);
		return 1;
	}
}

int xml_parser_create_doc(WsXmlDocH wsDoc, const char *rootName)
{
	int retVal = 0;
	xmlDocPtr doc;
	xmlNodePtr rootNode;

	if ((doc = xmlNewDoc(BAD_CAST "1.0")) == NULL ||
			(rootNode = xmlNewNode(NULL, BAD_CAST rootName)) == NULL) {
		if (doc)
			xmlFreeDoc(doc);
	} else {
		doc->_private = wsDoc;
		wsDoc->parserDoc = doc;
		xmlDocSetRootElement(doc, rootNode);
		retVal = 1;
	}

	return retVal;
}



void xml_parser_destroy_doc(WsXmlDocH wsDoc)
{
	xmlDocPtr xmlDoc = (xmlDocPtr) wsDoc->parserDoc;
	if (xmlDoc != NULL) {
		destroy_tree_private_data(xmlDocGetRootElement(xmlDoc));
		xmlFreeDoc(xmlDoc);
	}
}


WsXmlDocH xml_parser_get_doc(WsXmlNodeH node)
{
	xmlDocPtr xmlDoc = ((xmlDocPtr) node)->doc;
	return (WsXmlDocH) (!xmlDoc ? NULL : xmlDoc->_private);
}


WsXmlNodeH xml_parser_get_root(WsXmlDocH doc)
{
	if (doc->parserDoc != NULL)
		return (WsXmlNodeH) xmlDocGetRootElement((xmlDocPtr) doc->
				parserDoc);
	return NULL;
}

WsXmlDocH
xml_parser_file_to_doc( const char *filename,
		const char *encoding, unsigned long options)
{
	xmlDocPtr xmlDoc;
	WsXmlDocH Doc = NULL;

	xmlDoc = xmlReadFile(filename, encoding,
			XML_PARSE_NONET | XML_PARSE_NSCLEAN);
	if (xmlDoc == NULL) {
		return NULL;
	}
	Doc = (WsXmlDocH) u_zalloc(sizeof(*Doc));
	if (Doc == NULL) {
		xmlFreeDoc(xmlDoc);
		return NULL;
	}
	xmlDoc->_private = Doc;
	Doc->parserDoc = xmlDoc;

	return Doc;

}

WsXmlDocH
xml_parser_memory_to_doc( const char *buf, size_t size,
		const char *encoding, unsigned long options)
{
	WsXmlDocH Doc = NULL;
	xmlDocPtr xmlDoc;
	if (!buf || !size ) {
		return NULL;
	}
	xmlDoc = xmlReadMemory(buf, (int) size, NULL, encoding,
			XML_PARSE_NONET | XML_PARSE_NSCLEAN);
	if (xmlDoc == NULL) {
		return NULL;
	}
	Doc = (WsXmlDocH) u_zalloc(sizeof(*Doc));
	if (Doc == NULL) {
		xmlFreeDoc(xmlDoc);
		return NULL;
	}

	xmlDoc->_private = Doc;
	Doc->parserDoc = xmlDoc;

	return Doc;
}


char *xml_parser_node_query(WsXmlNodeH node, int what)
{
	char *ptr = NULL;
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	iWsNode *wsNode = (iWsNode *) xmlNode->_private;

	switch (what) {
	case XML_TEXT_VALUE:
		if (wsNode == NULL)
			xmlNode->_private = wsNode =
				u_zalloc(sizeof(iWsNode));

		if (wsNode != NULL) {
			if (wsNode->valText == NULL) {
				wsNode->valText =
					(char *) xmlNodeGetContent(xmlNode);
			}
			ptr = wsNode->valText;
		}
		break;
	case XML_LOCAL_NAME:
		ptr = (char *) xmlNode->name;
		break;
	case XML_NS_URI:
		if (xmlNode->ns != NULL)
			ptr = (char *) xmlNode->ns->href;
		break;
	case XML_NS_PREFIX:
		if (xmlNode->ns != NULL)
			ptr = (char *) xmlNode->ns->prefix;
		break;
	default:
		break;
	}

	return ptr;
}


int xml_parser_node_set(WsXmlNodeH node, int what, const char *str)
{
	int retVal = -1;
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	iWsNode *wsNode = (iWsNode *) xmlNode->_private;
	xmlNsPtr xmlNs;

	switch (what) {
	case XML_TEXT_VALUE:
		if (wsNode == NULL)
			xmlNode->_private = wsNode =
				u_zalloc(sizeof(iWsNode));

		if (wsNode != NULL) {
			if (wsNode->valText != NULL) {
				xmlFree(wsNode->valText);
				wsNode->valText = NULL;
			}
			xmlNodeSetContent(xmlNode, BAD_CAST str);
			retVal = 0;
		}
		break;

	case XML_LOCAL_NAME:
		xmlNodeSetName(xmlNode, BAD_CAST str);
		retVal = 0;
		break;

	case XML_NS_URI:
		if ((xmlNs = (xmlNsPtr) xml_parser_ns_find(node, str, NULL, 1,
						1)) != NULL) {
			xmlNode->ns = xmlNs;
			retVal = 0;
		} else
			retVal = 1;
		break;
	default:
		retVal = 1;
		break;
	}

	return retVal;
}



WsXmlNodeH xml_parser_node_get(WsXmlNodeH node, int which)
{
	xmlNodePtr xmlNode = NULL;
	xmlNodePtr base = (xmlNodePtr) node;

	switch (which) {
	case XML_ELEMENT_PARENT:
		xmlNode = base->parent;
		break;
	case XML_ELEMENT_NEXT:
		if ((xmlNode = base->next) != NULL) {
			do {
				if (xmlNode->type == XML_ELEMENT_NODE)
					break;
			}
			while ((xmlNode = xmlNode->next) != NULL);
		}
		break;
	case XML_ELEMENT_PREV:
		if ((xmlNode = base->prev) != NULL) {
			do {
				if (xmlNode->type == XML_ELEMENT_NODE)
					break;
			}
			while ((xmlNode = xmlNode->prev) != NULL);
		}
		break;
	case XML_LAST_CHILD:
	default:
		if (which >= 0 || which == XML_LAST_CHILD) {
			int count = 0;
			xmlNode = base->children;

			while (xmlNode) {
				if (xmlNode->type == XML_ELEMENT_NODE) {
					if (which == XML_LAST_CHILD &&
							xmlNode->next == NULL)
						break;

					if (count == which)
						break;

					count++;
				}
				xmlNode = xmlNode->next;
			}
		} else {
			assert(which >= 0);
		}
		break;
	}
	return (WsXmlNodeH) xmlNode;
}

/* check if namespace is defined (at document root)
 * and evtl. (bAddAtRootIfNotFound!=0) add it to the root node
 */

WsXmlNsH
xml_parser_ns_find(WsXmlNodeH node,
		const char *uri,
		const char *prefix,
		int bWalkUpTree, int bAddAtRootIfNotFound)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlNsPtr xmlNs = NULL;

	while (xmlNode != NULL) {
		xmlNs = xmlNode->nsDef;
		while (xmlNs != NULL) {
			if (uri) {
				if (!strcmp((char *) xmlNs->href, uri))
					break;
			} else if (prefix == NULL) {
				if (xmlNs->prefix == NULL)
					break;
			} else
				if (xmlNs->prefix &&
						!strcmp((char *) xmlNs->prefix, prefix)) {
					break;
				}
			xmlNs = xmlNs->next;
		}
		if (xmlNs != NULL || !bWalkUpTree)
			break;
		xmlNode = xmlNode->parent;
	}

	if (node != NULL && xmlNs == NULL && bAddAtRootIfNotFound) {
		xmlNodePtr xmlRoot =
			xmlDocGetRootElement(((xmlDocPtr) node)->doc);
		char buf[12];

		if (prefix == NULL) {
			ws_xml_make_default_prefix((WsXmlNodeH) xmlRoot,
					uri, buf, sizeof(buf));
			prefix = buf;
		}
		xmlNs =
			(xmlNsPtr) xml_parser_ns_add((WsXmlNodeH) xmlRoot, uri,
					prefix);
	}
	return (WsXmlNsH) xmlNs;
}

char *xml_parser_ns_query(WsXmlNsH ns, int what)
{
	xmlNsPtr xmlNs = (xmlNsPtr) ns;
	char *ptr = NULL;

	switch (what) {
	case XML_NS_URI:
		ptr = (char *) xmlNs->href;
		break;
	case XML_NS_PREFIX:
		ptr = (char *) xmlNs->prefix;
		break;
	default:
		assert(what == XML_NS_URI);
		break;
	}
	return ptr;
}


WsXmlNsH
xml_parser_ns_add(WsXmlNodeH node, const char *uri, const char *prefix)
{
	xmlNsPtr xmlNs = NULL;
	if (node && uri) {
		if ((xmlNs = (xmlNsPtr) xml_parser_ns_find(node, uri, NULL, 0, 0)) != NULL) {
                        /* namespace is known */
			if (xmlNs->prefix != NULL) {
				xmlFree((char *) xmlNs->prefix);
				xmlNs->prefix = NULL;
			}
			if (prefix != NULL) {
				xmlNs->prefix = xmlStrdup(BAD_CAST prefix);
			}
		} else {
                        /* create new namespace entry */
			xmlNs =	xmlNewNs((xmlNodePtr) node, BAD_CAST uri, BAD_CAST prefix);
			/* since the 'xml:' name is supposed to be predefined, the above
                         * function will return NULL when prefix == xml && uri == XML_XML_NAMESPACE.
                         * Compensate for this here.
                         */
			if (xmlNs == NULL && strcmp(prefix,"xml") == 0
                            && strcmp(uri, (const char *)XML_XML_NAMESPACE) == 0) {
				xmlNs = (xmlNsPtr) u_zalloc(sizeof(*xmlNs));
				if (xmlNs == NULL) {
					error("Couldn't create a new Namespace structure");	
					return(NULL);
				}
				xmlNs->type = XML_LOCAL_NAMESPACE;
				xmlNs->href = xmlStrdup((const xmlChar *)uri);
				xmlNs->prefix = xmlStrdup((const xmlChar *)prefix);
			}
		}
	}
	return (WsXmlNsH) xmlNs;
}


int xml_parser_ns_remove(WsXmlNodeH node, const char *nsUri)
{
	int retVal = -1;

	if (node && nsUri) {
		xmlNodePtr xmlNode = (xmlNodePtr) node;
		xmlNsPtr xmlNs = xmlNode->nsDef;
		xmlNsPtr prevNs = NULL;

		while (xmlNs != NULL) {
			if ((xmlStrEqual(xmlNs->href, BAD_CAST nsUri))) {
				break;
			}
			prevNs = xmlNs;
			xmlNs = xmlNs->next;
		}

		if (xmlNs != NULL) {
			retVal = 0;
			if (prevNs == NULL)
				xmlNode->nsDef = xmlNs->next;
			else
				prevNs->next = xmlNs->next;
			xmlFreeNs(xmlNs);
		} else
			retVal = 1;
	}
	return retVal;
}



WsXmlNsH xml_parser_ns_get(WsXmlNodeH node, int which)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlNsPtr xmlNs = NULL;

	if (which >= 0) {
		int count = 0;
		xmlNs = xmlNode->nsDef;
		while (xmlNs != NULL) {
			if (which == count)
				break;
			count++;
			xmlNs = xmlNs->next;
		}
	} else {
		assert(which >= 0);
	}
	return (WsXmlNsH) xmlNs;
}


static
int get_ns_count_at_node(xmlNodePtr xmlNode)
{
	int count = 0;
	xmlNsPtr xmlNs = xmlNode->nsDef;

	while (xmlNs != NULL) {
		count++;
		xmlNs = xmlNs->next;
	}
	return count;
}


int xml_parser_get_count(WsXmlNodeH node, int what, int bWalkUpTree)
{
	int count = 0;
	xmlNodePtr xmlNode;
	xmlAttrPtr xmlAttr;

	switch (what) {
	case XML_COUNT_NODE:
		xmlNode = ((xmlNodePtr) node)->children;
		while (xmlNode) {
			if (xmlNode->type == XML_ELEMENT_NODE)
				count++;
			xmlNode = xmlNode->next;
		}
		break;
	case XML_COUNT_ATTR:
		xmlAttr = ((xmlNodePtr) node)->properties;
		while (xmlAttr) {
			count++;
			xmlAttr = xmlAttr->next;
		}
		break;
	case XML_COUNT_NS:
		xmlNode = (xmlNodePtr) node;
		while (xmlNode != NULL) {
			count += get_ns_count_at_node(xmlNode);
			if (!bWalkUpTree)
				break;
			xmlNode = xmlNode->parent;
		}
		break;
	default:
		assert(what == XML_COUNT_NODE || what == XML_COUNT_ATTR ||
				what == XML_COUNT_NS);
		break;
	}

	return count;
}

static xmlNodePtr
make_new_xml_node(xmlNodePtr base,
		const char *uri, const char *name, const char *value, int xmlescape)
{
	xmlNodePtr newNode = NULL;
	xmlNsPtr ns = NULL;
	if (uri == NULL ||
			(ns =
			 (xmlNsPtr) xml_parser_ns_find((WsXmlNodeH) base, uri, NULL, 1,
				 1)) != NULL) {
		if ((newNode = xmlNewNode(ns, BAD_CAST name)) != NULL) {
			if (value != NULL){		
				if (xmlescape == 1)
					xmlNodeAddContent(newNode, BAD_CAST value);
				else
					xmlNodeSetContent(newNode, BAD_CAST value);
			}
			newNode->_private = u_zalloc(sizeof(iWsNode));
		}
	}
	return newNode;
}






WsXmlNodeH
xml_parser_node_add(WsXmlNodeH base,
		int where,
		const char *nsUri,
		const char *localName, const char *value, int xmlescape)
{
	xmlNodePtr xmlBase = (xmlNodePtr) base;
	xmlNodePtr newNode =
		make_new_xml_node((where != XML_ELEMENT_NEXT &&
					where != XML_ELEMENT_PREV)
				? xmlBase : xmlBase->parent, nsUri,
				localName, value, xmlescape);
	if (newNode) {
		switch (where) {
		case XML_ELEMENT_NEXT:
			xmlAddNextSibling((xmlNodePtr) base, newNode);
			break;
		case XML_ELEMENT_PREV:
			xmlAddPrevSibling((xmlNodePtr) base, newNode);
			break;
		case XML_LAST_CHILD:
		default:
			xmlAddChild((xmlNodePtr) base, newNode);
			break;
		}
	}
	return (WsXmlNodeH) newNode;

}

int xml_parser_node_remove(WsXmlNodeH node)
{
	destroy_node_private_data(((xmlNodePtr) node)->_private);
	xmlUnlinkNode((xmlNodePtr) node);
	xmlFreeNode((xmlNodePtr) node);
	return 0;
}


WsXmlAttrH
xml_parser_attr_add(WsXmlNodeH node,
		const char *uri, const char *name, const char *value)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlNsPtr xmlNs =
		(xmlNsPtr) xml_parser_ns_find(node, uri, NULL, 1, 1);
	xmlAttrPtr xmlAttr =
		(xmlAttrPtr) ws_xml_find_node_attr(node, uri, name);

	if (xmlAttr != NULL)
		ws_xml_remove_node_attr((WsXmlAttrH) xmlAttr);

	if (xmlNs == NULL)
		xmlAttr =
			xmlNewProp(xmlNode, BAD_CAST name, BAD_CAST value);
	else
		xmlAttr =
			xmlNewNsProp(xmlNode, xmlNs, BAD_CAST name,
					BAD_CAST value);

	if (xmlAttr != NULL) {
		if (xmlNs == NULL)
			xmlAttr->_private =
				xmlGetProp(xmlNode, BAD_CAST name);
		else
			xmlAttr->_private =
				xmlGetNsProp(xmlNode, BAD_CAST name,
						xmlNs->href);
	}

	return (WsXmlAttrH) xmlAttr;
}



int xml_parser_attr_remove(WsXmlAttrH attr)
{
	xmlAttrPtr xmlAttr = (xmlAttrPtr) attr;
	xmlNodePtr xmlNode = (xmlNodePtr) xmlAttr->parent;
	xmlAttrPtr xmlAttrPrev =
		(xmlNode->properties == xmlAttr) ? NULL : xmlNode->properties;

	while (xmlAttrPrev != NULL && xmlAttrPrev->next != xmlAttr) {
		xmlAttrPrev = xmlAttrPrev->next;
	}
	if (xmlAttrPrev != NULL)
		xmlAttrPrev->next = xmlAttr->next;
	else
		xmlNode->properties = xmlAttr->next;

	xmlNode->parent = NULL;
	xmlNode->next = NULL;

	destroy_attr_private_data((xmlAttrPtr) attr);
	xmlFreeProp((xmlAttrPtr) attr);

	return 0;
}

char *xml_parser_attr_query(WsXmlAttrH attr, int what)
{
	char *ptr = NULL;
	xmlAttrPtr xmlAttr = (xmlAttrPtr) attr;
	switch (what) {
	case XML_LOCAL_NAME:
		ptr = (char *) xmlAttr->name;
		break;
	case XML_NS_URI:
		if (xmlAttr->ns != NULL)
			ptr = (char *) xmlAttr->ns->href;
		break;
	case XML_NS_PREFIX:
		if (xmlAttr->ns != NULL)
			ptr = (char *) xmlAttr->ns->prefix;
		break;
	case XML_TEXT_VALUE:
		if (xmlAttr->_private == NULL) {
			if (xmlAttr->ns == NULL)
				xmlAttr->_private =
					xmlGetProp(xmlAttr->parent,
							xmlAttr->name);
			else
				xmlAttr->_private =
					xmlGetNsProp(xmlAttr->parent,
							xmlAttr->name,
							xmlAttr->ns->href);
		}
		ptr = (char *) xmlAttr->_private;
		break;
	default:
		assert(what == XML_LOCAL_NAME);
		break;
	}
	return ptr;
}



WsXmlAttrH xml_parser_attr_get(WsXmlNodeH node, int which)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlAttrPtr xmlAttr = NULL;

	switch (which) {
	case XML_LAST_CHILD:
	default:
		if (which >= 0 || which == XML_LAST_CHILD) {
			int count = 0;
			xmlAttr = xmlNode->properties;

			while (xmlAttr) {
				if (which == XML_LAST_CHILD &&
						xmlAttr->next == NULL)
					break;

				if (which == count)
					break;

				count++;

				xmlAttr = xmlAttr->next;
			}
		} else {
			assert(which >= 0 || which == XML_LAST_CHILD);
		}
		break;
	}

	return (WsXmlAttrH) xmlAttr;
}



void xml_parser_element_dump(FILE * f, WsXmlDocH doc, WsXmlNodeH node)
{

	xmlNodePtr n = (xmlNodePtr) node;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	xmlElemDump(f, d, n);
}

void xml_parser_doc_dump(FILE * f, WsXmlDocH doc)
{

	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	xmlDocFormatDump(f, d, 1);
	return;
}

void xml_parser_doc_dump_memory(WsXmlDocH doc, char **buf, int *ptrSize)
{

	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	xmlDocDumpFormatMemory(d, (xmlChar **) buf, ptrSize, 1);
	return;
}

void xml_parser_doc_dump_memory_enc(WsXmlDocH doc, char **buf, int *ptrSize, const char *encoding)
{

	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
        xmlDocDumpFormatMemoryEnc(d, (xmlChar **) buf, ptrSize, encoding?encoding:"UTF-8", 1);
	return;
}

static void
register_namespaces(xmlXPathContextPtr ctxt, WsXmlDocH doc,
		WsXmlNodeH node)
{
	xmlNsPtr *nsList, *cur;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;


	nsList = xmlGetNsList(d, (xmlNodePtr) node);
	if (nsList == NULL) {
		return;
	}
	for (cur = nsList; *cur != NULL; cur++) {
		if (xmlXPathRegisterNs(ctxt, (*cur)->prefix, (*cur)->href)
				!= 0) {
			return;
		}
	}
	xmlFree(nsList);
}


int xml_parser_check_xpath(WsXmlDocH doc, const char *expression)
{
	xmlXPathObject *obj;
	xmlNodeSetPtr nodeset;
	xmlXPathContextPtr ctxt;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	int retval = 0;

	ctxt = xmlXPathNewContext(d);
	if (ctxt == NULL) {
		error("failed while creating xpath context");
		return 0;
	}
	register_namespaces(ctxt, doc, xml_parser_get_root(doc));
	obj = xmlXPathEvalExpression(BAD_CAST expression, ctxt);
	if (obj) {
		nodeset = obj->nodesetval;
		if (nodeset && nodeset->nodeNr > 0) {
			int size = nodeset->nodeNr;
			int i;
			xmlNodePtr cur;
			for(i = 0; i < size; ++i) {
				if(nodeset->nodeTab[i]->type == XML_ELEMENT_NODE) {
					cur = nodeset->nodeTab[i];
					if(cur->ns) {
						fprintf(stdout, "= element node \"%s:%s\"\n",
								cur->ns->href, cur->name);
					} else {
						fprintf(stdout, "= element node \"%s\"\n",
								cur->name);
					}
				}
			}

			retval = 1;
		}
		xmlXPathFreeObject(obj);
	}
	xmlXPathFreeContext(ctxt);

	return retval;
}



char *xml_parser_get_xpath_value(WsXmlDocH doc, const char *expression)
{
	//int i;
	char *result = NULL;
	xmlXPathObject *obj;
	xmlNodeSetPtr nodeset;
	xmlXPathContextPtr ctxt;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	WsXmlNodeH body;

	ctxt = xmlXPathNewContext(d);
	if (ctxt == NULL) {
		error("failed while creating xpath context");
		return NULL;
	}
	body = ws_xml_get_soap_body(doc);
	register_namespaces(ctxt, doc, xml_parser_get_root(doc));
	if (ws_xml_get_child(body, 0, NULL, NULL)) {
		register_namespaces(ctxt, doc,
				ws_xml_get_child(body, 0, NULL, NULL));
	}

	obj = xmlXPathEvalExpression(BAD_CAST expression, ctxt);
	if (obj) {
		nodeset = obj->nodesetval;
		if (nodeset && nodeset->nodeNr > 0)
			result = (char *) xmlNodeListGetString(d,
					nodeset->
					nodeTab[0]->
					xmlChildrenNode,
					1);

		xmlXPathFreeObject(obj);
	}
	xmlXPathFreeContext(ctxt);

	return result;
}



void xml_parser_unlink_node(WsXmlNodeH node)
{
	xmlUnlinkNode((xmlNodePtr) node);
	xmlFreeNode((xmlNodePtr) node);
	return;
}

void xml_parser_node_set_lang(WsXmlNodeH node,  const char *lang)
{
	xmlNodeSetLang((xmlNodePtr) node, BAD_CAST lang);
}


void xml_parser_set_ns(WsXmlNodeH r, WsXmlNsH ns, const char *prefix)
{
	xmlSetNs((xmlNodePtr) r, (xmlNsPtr) ns);
}

void xml_parser_copy_node(WsXmlNodeH src, WsXmlNodeH dst)
{
	if (src && dst) {
		xmlNodePtr x = xmlDocCopyNode((xmlNodePtr) src,
				   ((xmlDocPtr) src)->doc, 1);
		if (x)
			xmlAddChild((xmlNodePtr) dst, x);
	}
}
