/*******************************************************************************
 * 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
 * @author Eugene Yarmosh
 * @author Liang Hou
 */

#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#define _GNU_SOURCE

#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"
#include "wsman-dispatcher.h"
#include "wsman-xml-serializer.h"
#include "wsman-xml-serialize.h"
#include "wsman-soap-envelope.h"
#include "wsman-faults.h"
#include "wsman-soap-message.h"

#include "wsman-client-api.h"
#include "wsman-client-transport.h"

/*    ENUMERATION  */
#define ENUM_EXPIRED(enuminfo, mytime) \
	((enumInfo->expires > 0) &&        \
	(enumInfo->expires > mytime))



/**
 * Calculate needed space for interface array with Endpoints
 * @param interfaces List of interfaces
 * @return Needed size of WsManDispatcherInfo
 */
static int
calculate_map_count(list_t * interfaces)
{
	int             count = 0;
	int             j;

	lnode_t        *node = list_first(interfaces);
	while (node) {
		WsDispatchInterfaceInfo *ifc =
			(WsDispatchInterfaceInfo *) node->list_data;
		for (j = 0; ifc->endPoints[j].serviceEndPoint != NULL; j++)
			count++;
		node = list_next(interfaces, node);
	}

	return (list_count(interfaces) * sizeof(WsManDispatcherInfo))
		+ (count * sizeof(DispatchToEpMap));
}

/**
 * Register Dispatcher
 * @param cntx Context
 * @param proc Dispatcher Callback
 * @param data Callback data
 */
static void
ws_register_dispatcher(WsContextH cntx, DispatcherCallback proc, void *data)
{
	SoapH soap = ws_context_get_runtime(cntx);
	if (soap) {
		soap->dispatcherProc = proc;
		soap->dispatcherData = data;
	}
	return;
}

static int
set_context_val(WsContextH cntx,
		char *name,
		void *val,
		int size,
		int no_dup,
		unsigned long type)
{
	int retVal = 1;
	debug("Setting context value: %s", name);
	if (cntx && name) {
		void *ptr = val;

		if (!no_dup) {
			if (val && (ptr = u_malloc(size))) {
				memcpy(ptr, val, size);
			}
		}
		if (ptr || val == NULL) {
			u_lock(cntx->soap);
			ws_remove_context_val(cntx, name);
			if (create_context_entry(cntx->entries, name, ptr)) {
				retVal = 0;
			}
			u_unlock(cntx->soap);
		}
	} else {
		error("error setting context value.");
	}
	return retVal;
}


static void
free_hentry_func(hnode_t * n, void *arg)
{
	u_free((void*)hnode_getkey(n));
	u_free(n);
}


static void
remove_locked_enuminfo(WsContextH cntx,
                       WsEnumerateInfo * enumInfo)
{
	u_lock(cntx->soap);
	if (!(enumInfo->flags & WSMAN_ENUMINFO_INWORK_FLAG)) {
		error("locked enuminfo unlocked");
		u_unlock(cntx->soap);
		return;
	}
	hash_delete_free(cntx->enuminfos,
		hash_lookup(cntx->enuminfos, enumInfo->enumId));
	u_unlock(cntx->soap);
}

#ifdef ENABLE_EVENTING_SUPPORT
static void wsman_expiretime2xmldatetime(unsigned long expire, char *str)
{
	time_t t = expire;
	struct tm tm;
	localtime_r(&t, &tm);
	snprintf(str, 30, "%u-%u%u-%u%uT%u%u:%u%u:%u%u+%u%u:%u%u",
			tm.tm_year + 1900, (tm.tm_mon + 1)/10, (tm.tm_mon + 1)%10,
			tm.tm_mday/10, tm.tm_mday%10, tm.tm_hour/10, tm.tm_hour%10,
			tm.tm_min/10, tm.tm_min%10, tm.tm_sec/10, tm.tm_sec%10,
			0, 0, 0,0);

}

static void delete_notification_info(WsNotificationInfoH notificationInfo) {
	if(notificationInfo) {
		ws_xml_destroy_doc(notificationInfo->EventContent);
		ws_xml_destroy_doc(notificationInfo->headerOpaqueData);
		u_free(notificationInfo->EventAction);
		u_free(notificationInfo);
	}
}
#endif


static WsSubscribeInfo*
search_pull_subs_info(SoapH soap, WsXmlDocH indoc)
{
	WsSubscribeInfo *subsInfo = NULL;
	char *uuid = NULL;
	lnode_t *lnode;
	WsContextH soapCntx = ws_get_soap_context(soap);
	WsXmlNodeH node = ws_xml_get_soap_body(indoc);

	node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_PULL);
	if(node) {
		node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT);
		uuid = ws_xml_get_node_text(node);
	}
	if(uuid == NULL) return subsInfo;
	if (pthread_mutex_lock(&soap->lockSubs))
	{
		error("Error: Can't lock soap->lockSubs");
		return NULL;
	}
	lnode = list_first(soapCntx->subscriptionMemList);
	while(lnode) {
		subsInfo = (WsSubscribeInfo *)lnode->list_data;
		if(!strcmp(subsInfo->subsId, uuid+5)) break;
		lnode = list_next(soapCntx->subscriptionMemList, lnode);
	}
	if (pthread_mutex_unlock(&soap->lockSubs))
	{
		error("Error: Can't unlock soap->lockSubs");
		return NULL;
	}
	if(lnode == NULL) return NULL;
	return subsInfo;
}


static WsXmlDocH
create_enum_info(SoapOpH op,
		 WsContextH epcntx,
              	 WsXmlDocH indoc,
		 WsEnumerateInfo **eInfo)
{
	WsXmlNodeH node = ws_xml_get_soap_body(indoc);
	WsXmlNodeH header = ws_xml_get_soap_header(indoc);
	WsXmlDocH outdoc = NULL;
	WsXmlNodeH enumnode = NULL;
	WsEnumerateInfo *enumInfo;
	WsmanMessage *msg = wsman_get_msg_from_op(op);
	WsmanFaultCodeType fault_code = WSMAN_RC_OK;
	WsmanFaultDetailType fault_detail_code = WSMAN_DETAIL_OK;
	char *uri, *to;

	enumInfo = (WsEnumerateInfo *)u_zalloc(sizeof (WsEnumerateInfo));
	if (enumInfo == NULL) {
		error("No memory");
		fault_code = WSMAN_INTERNAL_ERROR;
		goto DONE;
	}
	enumInfo->encoding = u_strdup(msg->charset);
	enumInfo->maxsize = wsman_get_maxsize_from_op(op);
	if(enumInfo->maxsize == 0) {
		enumnode = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATE);
		enumInfo->maxsize = ws_deserialize_uint32(NULL, enumnode,
					     0, XML_NS_ENUMERATION,
					     WSENUM_MAX_CHARACTERS);
	}
	enumInfo->releaseproc = wsman_get_release_endpoint(epcntx, indoc);
	to = ws_xml_get_node_text(
			ws_xml_get_child(header, 0, XML_NS_ADDRESSING, WSA_TO));
	if (to == NULL) {
		error("No to node");
		fault_code = WSMAN_INTERNAL_ERROR;
		goto DONE;
	}
	uri =  ws_xml_get_node_text(
			ws_xml_get_child(header, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI));
	if (uri == NULL) {
		error("No uri node");
		fault_code = WSMAN_INTERNAL_ERROR;
		goto DONE;
	}

	enumInfo->epr_to = u_strdup(to);
	enumInfo->epr_uri = u_strdup(uri);
	node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ENUMERATE);
	node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_EXPIRES);
	if (node == NULL) {
		debug("No wsen:Expires");
		enumInfo->expires = 0;
	} else {
		wsman_set_expiretime(node, &(enumInfo->expires), &fault_code);
		if (fault_code != WSMAN_RC_OK) {
			fault_detail_code = WSMAN_DETAIL_EXPIRATION_TIME;
			goto DONE;
		}
	}

	if (msg->auth_data.username != NULL) {
		enumInfo->auth_data.username =
				u_strdup(msg->auth_data.username);
		enumInfo->auth_data.password =
				u_strdup(msg->auth_data.password);
	} else {
		enumInfo->auth_data.username = NULL;
		enumInfo->auth_data.password = NULL;
	}
	generate_uuid(enumInfo->enumId, EUIDLEN, 1);

DONE:
	if (fault_code != WSMAN_RC_OK) {
		outdoc = wsman_generate_fault(indoc, fault_code, fault_detail_code, NULL);
		u_free(enumInfo);
                *eInfo = NULL;
	} else {
		*eInfo = enumInfo;
	}
	return outdoc;
}

static void
destroy_enuminfo(WsEnumerateInfo * enumInfo)
{
	debug("destroy enuminfo");
	u_free(enumInfo->auth_data.username);
	u_free(enumInfo->auth_data.password);
	u_free(enumInfo->epr_to);
	u_free(enumInfo->epr_uri);
	u_free(enumInfo->encoding);
	if (enumInfo->filter)
		filter_destroy(enumInfo->filter);
	u_free(enumInfo);
}

static int
wsman_verify_enum_info(SoapOpH op,
		       WsEnumerateInfo * enumInfo,
		       WsXmlDocH doc,
		       WsmanStatus * status)
{

	WsmanMessage *msg = wsman_get_msg_from_op(op);
	WsXmlNodeH header = ws_xml_get_soap_header(doc);

	char *to = ws_xml_get_node_text(ws_xml_get_child(header, 0,
			XML_NS_ADDRESSING, WSA_TO));
	char *uri= ws_xml_get_node_text(ws_xml_get_child(header, 0,
			XML_NS_WS_MAN, WSM_RESOURCE_URI));
	if (to == NULL || uri == NULL) {
		error("No to or uri node");
		status->fault_code = WSMAN_INTERNAL_ERROR;
		status->fault_detail_code = 0;
		return 0;
	}

	if (strcmp(enumInfo->epr_to, to) != 0 ||
			strcmp(enumInfo->epr_uri, uri) != 0 ) {
		status->fault_code = WSA_MESSAGE_INFORMATION_HEADER_REQUIRED;
		status->fault_detail_code = 0;
		debug("verifying enumeration context: ACTUAL  uri: %s, to: %s", uri, to);
		debug("verifying enumeration context: SHOULD uri: %s, to: %s",
				enumInfo->epr_uri, enumInfo->epr_to);
		return 0;
	}

	if (msg->auth_data.username && msg->auth_data.password) {
		if (strcmp(msg->auth_data.username,
				enumInfo->auth_data.username) != 0 &&
				strcmp(msg->auth_data.password,
				enumInfo->auth_data.password) != 0) {
			status->fault_code = WSMAN_ACCESS_DENIED;
			status->fault_detail_code = 0;
			return 0;
		}
	}
	return 1;
}



static int
insert_enum_info(WsContextH cntx,
		WsEnumerateInfo *enumInfo)
{
	struct timeval tv;
	int retVal = 1;

	u_lock(cntx->soap);
	gettimeofday(&tv, NULL);
	enumInfo->timeStamp = tv.tv_sec;
	if (create_context_entry(cntx->enuminfos, enumInfo->enumId, enumInfo)) {
		retVal = 0;
	}
	u_unlock(cntx->soap);
	return retVal;
}



static WsEnumerateInfo *
get_locked_enuminfo(WsContextH cntx,
                    WsXmlDocH doc,
                    SoapOpH op,
                    char *action,
                    WsmanStatus *status)
{
	hnode_t *hn;
	WsEnumerateInfo *eInfo = NULL;
	char *enumId = NULL;
	WsXmlNodeH node = ws_xml_get_soap_body(doc);

	if (node && (node = ws_xml_get_child(node,
			0, XML_NS_ENUMERATION, action))) {
		node = ws_xml_get_child(node, 0,
			XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT);
		if (node) {
			enumId = ws_xml_get_node_text(node);
		}
	}
	debug("enum context: %s", enumId);

	if (enumId == NULL) {
		status->fault_code = WSEN_INVALID_ENUMERATION_CONTEXT;
		return NULL;
	}
	u_lock(cntx->soap);
	hn = hash_lookup(cntx->enuminfos, enumId);
	if (hn) {
		eInfo = (WsEnumerateInfo *)hnode_get(hn);
		if (strcmp(eInfo->enumId, enumId)) {
			error("enum context mismatch: %s == %s",
			     eInfo->enumId, enumId);
			status->fault_code = WSMAN_INTERNAL_ERROR;
		} else if (wsman_verify_enum_info(op, eInfo, doc,status)) {
			if (eInfo->flags & WSMAN_ENUMINFO_INWORK_FLAG) {
				status->fault_code = WSMAN_CONCURRENCY;
			} else {
				eInfo->flags |= WSMAN_ENUMINFO_INWORK_FLAG;
			}
		}
	} else {
		status->fault_code = WSEN_INVALID_ENUMERATION_CONTEXT;
	}

	if (status->fault_code != WSMAN_RC_OK) {
		eInfo = NULL;
	}
	u_unlock(cntx->soap);
	return eInfo;
}

static void
unlock_enuminfo(WsContextH cntx, WsEnumerateInfo *enumInfo)
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	u_lock(cntx->soap);
	if (!(enumInfo->flags & WSMAN_ENUMINFO_INWORK_FLAG)) {
		error("locked enuminfo unlocked");
		u_unlock(cntx->soap);
		return;
	}
	enumInfo->flags &= ~WSMAN_ENUMINFO_INWORK_FLAG;
	enumInfo->timeStamp = tv.tv_sec;
	u_unlock(cntx->soap);
}

static void
ws_clear_context_entries(WsContextH hCntx)
{
	hash_t *h;
	if (!hCntx) {
		return;
	}
	h = hCntx->entries;
	hash_free(h);
}

static void
ws_clear_context_enuminfos(WsContextH hCntx)
{
	hash_t *h;
	if (!hCntx) {
		return;
	}
	h = hCntx->enuminfos;
	hash_free(h);
}

callback_t *
make_callback_entry(SoapServiceCallback proc,
		    void *data,
		    list_t * list_to_add)
{
	callback_t *entry = (callback_t *) u_malloc(sizeof(callback_t));
	debug("make new callback entry");
	if (entry) {
		lnode_init(&entry->node, data);
		entry->proc = proc;
		if (list_to_add || (list_to_add = list_create(LISTCOUNT_T_MAX))) {
			list_append(list_to_add, &entry->node);
		} else {
			u_free(entry);
			return NULL;
		}
	} else {
		return NULL;
	}
	return entry;
}



void
ws_initialize_context(WsContextH cntx, SoapH soap)
{
	cntx->entries = hash_create(HASHCOUNT_T_MAX, NULL, NULL);
	if (cntx->entries) {
		hash_set_allocator(cntx->entries, NULL, free_hentry_func, NULL);
	}

	cntx->enuminfos = hash_create(HASHCOUNT_T_MAX, NULL, NULL);
	cntx->subscriptionMemList = list_create(LISTCOUNT_T_MAX);
	if (cntx->enuminfos) {
		hash_set_allocator(cntx->enuminfos, NULL, free_hentry_func, NULL);
	}
	cntx->owner = 1;
	cntx->soap = soap;
	cntx->serializercntx = ws_serializer_init();
}

WsContextH
ws_create_context(SoapH soap)
{
	WsContextH cntx = (WsContextH) u_zalloc(sizeof (*cntx));
	if (cntx) {
		ws_initialize_context(cntx, soap);
	}
	return cntx;
}

SoapH
ws_soap_initialize()
{
	SoapH soap = (SoapH) u_zalloc(sizeof(*soap));

	if (soap == NULL) {
		error("Could not alloc memory");
		return NULL;
	}
	soap->cntx = ws_create_context(soap);

	soap->inboundFilterList = NULL;
	soap->outboundFilterList = NULL;
	soap->dispatchList = NULL;
	soap->processedMsgIdList = NULL;

	u_init_lock(soap);
	u_init_lock(&soap->lockSubs);
	ws_xml_parser_initialize();

	soap_add_filter(soap, outbound_addressing_filter, NULL, 0);
	soap_add_filter(soap, outbound_control_header_filter, NULL, 0);
	return soap;
}

void
ws_set_context_enumIdleTimeout(WsContextH cntx,
                               unsigned long timeout)
{
	cntx->enumIdleTimeout = timeout;
}



WsContextH
ws_create_runtime(list_t * interfaces)
{
	SoapH soap = ws_soap_initialize();
	WsManDispatcherInfo *dispInfo;
	int size;
	lnode_t *node;
	if (soap == NULL) {
		error("Could not initialize soap");
		return NULL;
	}

	if (interfaces == NULL) {
		return soap->cntx;
	}

	size = calculate_map_count(interfaces);
	dispInfo = (WsManDispatcherInfo *) u_zalloc(size);
	if (dispInfo == NULL) {
		error("Could not allocate memory");
		soap_destroy(soap);
		return NULL;
	}
	debug("Registering %d plugins", (int) list_count(interfaces));
	dispInfo->interfaceCount = list_count(interfaces);
	dispInfo->interfaces = interfaces;
	node = list_first(interfaces);
	while (node != NULL) {
	        WsDispatchInterfaceInfo *wdii = (WsDispatchInterfaceInfo *) node->list_data;
		if (wsman_register_interface(soap->cntx, wdii, dispInfo) != 0) {
			error("Interface registration failed for %s", wdii->displayName);
			u_free(dispInfo);
			soap_destroy(soap);
			return NULL;
		}
		node = list_next(interfaces, node);
	}
	ws_register_dispatcher(soap->cntx, wsman_dispatcher, dispInfo);
	return soap->cntx;
}




/**
 * Register Dispatcher Interfaces
 * @param cntx WS-Man Context
 * @param wsInterface Interface
 * @param dispinfo Dispatcher
 */
int
wsman_register_interface(WsContextH cntx,
			 WsDispatchInterfaceInfo * wsInterface,
			 WsManDispatcherInfo * dispInfo)
{
	int i, retVal = 0;
	WsDispatchEndPointInfo *ep = wsInterface->endPoints;

	for (i = 0; ep[i].serviceEndPoint != NULL; i++) {
		if ((retVal = wsman_register_endpoint(cntx, wsInterface,
						  &ep[i], dispInfo)) != 0) {
			break;
		}
	}
	return retVal;
}


/*
 * Register Endpoint
 * @param cntx Context
 * @param wsInterface Interface
 * @param ep Endpoint
 * @param dispInfo Dispatcher information
 */
int
wsman_register_endpoint(WsContextH cntx,
			WsDispatchInterfaceInfo *wsInterface,
			WsDispatchEndPointInfo *ep,
			WsManDispatcherInfo *dispInfo)
{
	SoapDispatchH   disp = NULL;
	unsigned long   flags = SOAP_CUSTOM_DISPATCHER;
	SoapServiceCallback callbackProc = NULL;
	SoapH soap = ws_context_get_runtime(cntx);
	char *action = NULL;

	debug("Registering Endpoint: %s", ep->inAction ? ep->inAction : "<null>");
	switch (ep->flags & WS_DISP_TYPE_MASK) {
	case WS_DISP_TYPE_IDENTIFY:
		debug("Registering endpoint for Identify");
		action = ep->inAction;
		callbackProc = wsman_identify_stub;
		break;
	case WS_DISP_TYPE_ENUMERATE:
		debug("Registering endpoint for Enumerate");
		action = ep->inAction;
		callbackProc = wsenum_enumerate_stub;
		break;
	case WS_DISP_TYPE_RELEASE:
		debug("Registering endpoint for Release");
		action = ep->inAction;
		callbackProc = wsenum_release_stub;
		break;
	case WS_DISP_TYPE_DELETE:
		debug("Registering endpoint for Delete");
		action = ep->inAction;
		callbackProc = ws_transfer_delete_stub;
		break;
	case WS_DISP_TYPE_PULL:
		debug("Registering endpoint for Pull");
		action = ep->inAction;
		callbackProc = wsenum_pull_stub;
		break;
	case WS_DISP_TYPE_DIRECT_PULL:
		debug("Registering endpoint for direct Pull");
		action = ep->inAction;
		callbackProc = wsenum_pull_direct_stub;
		break;
	case WS_DISP_TYPE_GET:
		debug("Registering endpoint for Get");
		action = ep->inAction;
		callbackProc = ws_transfer_get_stub;
		break;
	case WS_DISP_TYPE_DIRECT_GET:
		debug("Registering endpoint for direct Get");
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;
	case WS_DISP_TYPE_DIRECT_DELETE:
		debug("Registering endpoint for Delete");
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;
	case WS_DISP_TYPE_DIRECT_PUT:
		debug("Registering endpoint for direct Put");
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;
	case WS_DISP_TYPE_DIRECT_CREATE:
		debug("Registering endpoint for direct Create");
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;
	case WS_DISP_TYPE_PUT:
		debug("Registering endpoint for Put");
		action = ep->inAction;
		callbackProc = ws_transfer_put_stub;
		break;
#ifdef ENABLE_EVENTING_SUPPORT
	case WS_DISP_TYPE_SUBSCRIBE:
		debug("Registering endpoint for Subscribe");
		action = ep->inAction;
		callbackProc = wse_subscribe_stub;
		break;
	case WS_DISP_TYPE_UNSUBSCRIBE:
		debug("Registering endpoint for Unsubscribe");
		action = ep->inAction;
		callbackProc = wse_unsubscribe_stub;
		break;
	case WS_DISP_TYPE_RENEW:
		action = ep->inAction;
		callbackProc = wse_renew_stub;
		break;
#endif
	case WS_DISP_TYPE_RAW_DOC:
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;
	case WS_DISP_TYPE_CUSTOM_METHOD:
		debug("Registering endpoint for custom method");
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;

	case WS_DISP_TYPE_PRIVATE:
		debug("Registering endpoint for private EndPoint");
		action = ep->inAction;
		callbackProc = (SoapServiceCallback) ep->serviceEndPoint;
		break;

	default:
		debug("unknown dispatch type %lu",
			ep->flags & WS_DISP_TYPE_MASK);
		break;
	}

	if (callbackProc != NULL &&
			(disp = wsman_dispatch_create(soap, action, NULL, NULL, callbackProc, ep, flags))) {
		dispInfo->map[dispInfo->mapCount].ep = ep;
		dispInfo->map[dispInfo->mapCount].disp = disp;
		dispInfo->mapCount++;
		wsman_dispatch_start(disp);
	}
	if (action && action != ep->inAction) {
		u_free(action);
	}
	return (disp == NULL);
}

/*  ENDPOINTS STUBS */

int
wsman_identify_stub(SoapOpH op,
		    void *appData,
			void *opaqueData)
{
	void           *data;
	WsXmlDocH       doc = NULL;
	WsContextH      cntx;
	WsDispatchEndPointInfo *info;
	XmlSerializerInfo *typeInfo;
	WsmanStatus    *status;
	SoapH           soap;
	WsEndPointGet   endPoint;

	soap = soap_get_op_soap(op);
	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	status = u_zalloc(sizeof(WsmanStatus *));
	cntx = ws_create_ep_context(soap, soap_get_op_doc(op, 1));
	if (cntx == NULL) {
		error("ws_create_ep_context failed");
		u_free(status);
		return -1;
	}
	info = (WsDispatchEndPointInfo *) appData;
	typeInfo = info->serializationInfo;
	endPoint = (WsEndPointGet) info->serviceEndPoint;
	debug("Identify called");

	if ((data = endPoint(cntx, status, opaqueData)) == NULL) {
		error("Identify Fault");
		doc = wsman_generate_fault(soap_get_op_doc(op, 1), WSMAN_INTERNAL_ERROR, 0, NULL);
	} else {
		doc = wsman_create_response_envelope(soap_get_op_doc(op, 1), NULL);
		ws_serialize(cntx->serializercntx, ws_xml_get_soap_body(doc), data, typeInfo,
			WSMID_IDENTIFY_RESPONSE, (char *) info->data, NULL, 1);
		ws_serializer_free_mem(cntx->serializercntx, data, typeInfo);
                u_free(data);
	}

	if (doc) {
		soap_set_op_doc(op, doc, 0);
	} else {
		error("Response doc invalid");
	}

	ws_destroy_context(cntx);
	u_free(status);

	return 0;
}




int
ws_transfer_put_stub(SoapOpH op,
		     void *appData,
			void *opaqueData)
{
	int             retVal = 0;
	WsXmlDocH       doc = NULL;
	void           *outData = NULL;
	WsmanStatus     status;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH   cntx = ws_create_ep_context(soap, soap_get_op_doc(op, 1));
	if (cntx == NULL) {
		error("ws_create_ep_context");
		return -1;
	}
	WsDispatchEndPointInfo *info = (WsDispatchEndPointInfo *) appData;
	XmlSerializerInfo *typeInfo = info->serializationInfo;
	WsEndPointPut   endPoint = (WsEndPointPut) info->serviceEndPoint;

	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	WsXmlNodeH      _body = ws_xml_get_soap_body(_doc);
	WsXmlNodeH      _r = ws_xml_get_child(_body, 0, NULL, NULL);

	void  *data = ws_deserialize(cntx->serializercntx, _body, typeInfo,
					ws_xml_get_node_local_name(_r),
			    	(char *) info->data, NULL, 0, 0);

	if ((retVal = endPoint(cntx, data, &outData, &status, opaqueData))) {
		doc = wsman_generate_fault( _doc, status.fault_code,
					   status.fault_detail_code, NULL);
	} else {
		doc = wsman_create_response_envelope(_doc, NULL);
		if (outData) {
			ws_serialize(cntx->serializercntx, ws_xml_get_soap_body(doc), outData,
				     typeInfo, TRANSFER_PUT_RESP,
                     (char *) info->data, NULL, 1);
			ws_serializer_free_mem(cntx->serializercntx, outData, typeInfo);
		}
	}

	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	ws_serializer_free_all(cntx->serializercntx);
	ws_serializer_cleanup(cntx->serializercntx);
	return retVal;
}




int
ws_transfer_delete_stub(SoapOpH op,
		     void *appData,
			void *opaqueData)
{
	WsmanStatus     status;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH      cntx = ws_create_ep_context(soap,
					soap_get_op_doc(op, 1));

	WsDispatchEndPointInfo *info = (WsDispatchEndPointInfo *) appData;
	WsEndPointGet   endPoint = (WsEndPointGet) info->serviceEndPoint;

	void           *data;
	WsXmlDocH       doc = NULL;

	wsman_status_init(&status);
	if ((data = endPoint(cntx, &status, opaqueData)) == NULL) {
		warning("Transfer Delete fault");
		doc = wsman_generate_fault(soap_get_op_doc(op, 1),
					 WSMAN_INVALID_SELECTORS, 0, NULL);
	} else {
		debug("Creating Response doc");
		doc = wsman_create_response_envelope(soap_get_op_doc(op, 1), NULL);
	}

	if (doc) {
		soap_set_op_doc(op, doc, 0);
	} else {
		error("Response doc invalid");
	}
	ws_destroy_context(cntx);
	return 0;
}




int
ws_transfer_get_stub(SoapOpH op,
		     void *appData,
			void *opaqueData)
{
	WsmanStatus     status;


	SoapH       soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH  cntx = ws_create_ep_context(soap, soap_get_op_doc(op, 1));
	if (cntx == NULL) {
		error("ws_create_ep_context failed");
		return -1;
	}
	WsDispatchEndPointInfo *info = (WsDispatchEndPointInfo *) appData;
	XmlSerializerInfo *typeInfo = info->serializationInfo;
	WsEndPointGet   endPoint = (WsEndPointGet) info->serviceEndPoint;

	void           *data;
	WsXmlDocH       doc = NULL;

	wsman_status_init(&status);
	if ((data = endPoint(cntx, &status, opaqueData)) == NULL) {
		warning("Transfer Get fault");
		doc = wsman_generate_fault( soap_get_op_doc(op, 1),
					 WSMAN_INVALID_SELECTORS, 0, NULL);
	} else {
		debug("Creating Response doc");
		doc = wsman_create_response_envelope(soap_get_op_doc(op, 1), NULL);

		ws_serialize(cntx->serializercntx, ws_xml_get_soap_body(doc), data, typeInfo,
			 TRANSFER_GET_RESP, (char *) info->data, NULL, 1);
		ws_serializer_free_mem(cntx->serializercntx, data, typeInfo);
	}

	if (doc) {
		debug("Setting operation document");
		soap_set_op_doc(op, doc, 0);
	} else {
		warning("Response doc invalid");
	}

	ws_destroy_context(cntx);
	return 0;
}



WsmanMessage *wsman_get_msg_from_op(SoapOpH op)
{
	op_t *_op = (op_t *)op;
	WsmanMessage *msg = (WsmanMessage *)_op->data;
	return msg;
}

unsigned long wsman_get_maxsize_from_op(SoapOpH op)
{
	op_t *_op = (op_t *)op;
	return _op->maxsize;
}

static
unsigned long get_total_enum_context(WsContextH cntx){
        hscan_t hs;
        u_lock(cntx->soap);
        hash_scan_begin(&hs, cntx->enuminfos);
        unsigned long total = hash_count(hs.hash_table);
        u_unlock(cntx->soap);
        return total;
}

/**
 * The following extern methods are defined in wsmand-daemon.c,
 * which is compiled into openwsmand binary, which in turn links
 * to libwsman.la. So when a call is made to the following methods
 * from the openwsmand binary, they should be present.
 *
 * However, if they are dlopened from somewhere other than 
 * openwsmand library or linked to some other
 * binary or shared object, then these methods may or may not be
 * preset, hence marking them as weak symbols and testing to see
 * if they are resolved before using them.
 */
#pragma weak wsmand_options_get_max_threads
extern int wsmand_options_get_max_threads(void);
#pragma weak wsmand_options_get_max_connections_per_thread
extern int wsmand_options_get_max_connections_per_thread(void);

/**
 * Enumeration Stub for processing enumeration requests
 * @param op SOAP pperation handler
 * @param appData Application data
 * @return status
 */
int
wsenum_enumerate_stub(SoapOpH op,
		      void *appData,
			void *opaqueData)
{
	WsXmlDocH       doc = NULL;
	int             retVal = 0;
	WsEnumerateInfo *enumInfo = NULL;
	WsmanStatus     status;
	WsXmlNodeH      resp_node, body;
	WsContextH      soapCntx;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
	WsEndPointEnumerate endPoint =
			(WsEndPointEnumerate)ep->serviceEndPoint;

	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	WsContextH      epcntx;

        int max_threads = 0;
        int max_connections_per_thread = 0;
        int(* fptr)(void);
        if((fptr = wsmand_options_get_max_threads) != 0){
                max_threads = (* fptr)();
                if((fptr = wsmand_options_get_max_connections_per_thread) != 0){
                        max_connections_per_thread = (* fptr)();
                }
                else{
                        debug("Could not resolve wsmand_options_get_max_connections_per_thread");
                        max_threads=0;
                }
        }
        else{
                debug("Could not resolve wsman_options_get_max_threads");
        }

        if(max_threads){
                if(get_total_enum_context(ws_get_soap_context(soap)) >= (max_threads * max_connections_per_thread)){
                        debug("enum context queue is full, we wait till some expire or are cleared");
                        doc = wsman_generate_fault(_doc, WSMAN_QUOTA_LIMIT, OWSMAN_NO_DETAILS,
                                    "The service is busy servicing other requests. Try later.");
                        if(doc){
                                soap_set_op_doc(op, doc, 0);
                        }
                        return 1;
                }
        }

	wsman_status_init(&status);

	epcntx = ws_create_ep_context(soap, _doc);
	if (epcntx == NULL) {
		goto DONE;
	}
	doc = create_enum_info(op, epcntx, _doc, &enumInfo);
	if (doc != NULL) {
		/* wrong enum elements met. Fault message generated */
		goto DONE;
	}

	if (endPoint && (retVal = endPoint(epcntx, enumInfo, &status, opaqueData))) {
                debug("enumeration fault");
		doc = wsman_generate_fault( _doc, status.fault_code,
				status.fault_detail_code, status.fault_msg);
		goto DONE;
	}
	if (enumInfo->pullResultPtr) {
		doc = enumInfo->pullResultPtr;
		enumInfo->index++;
	} else {
		doc = wsman_create_response_envelope( _doc, NULL);
	}

	if (!doc)
		goto DONE;

	wsman_set_estimated_total(_doc, doc, enumInfo);
	body = ws_xml_get_soap_body(doc);
	if (!body) {
		goto DONE;
	}

	if (enumInfo->pullResultPtr == NULL) {
		resp_node = ws_xml_add_child(body, XML_NS_ENUMERATION,
					     WSENUM_ENUMERATE_RESP, NULL);
	} else {
		resp_node = ws_xml_get_child(body, 0,
				 XML_NS_ENUMERATION, WSENUM_ENUMERATE_RESP);
	}
	if (!resp_node) {
		goto DONE;
	}

	soapCntx = ws_get_soap_context(soap);
	if (( enumInfo->flags & WSMAN_ENUMINFO_OPT ) == WSMAN_ENUMINFO_OPT  &&
		(enumInfo->totalItems == 0 || enumInfo->index == enumInfo->totalItems)) {
		ws_serialize_str(epcntx->serializercntx, resp_node, NULL,
			    XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, 0);
		ws_serialize_str(epcntx->serializercntx, resp_node,
			       NULL, XML_NS_WS_MAN, WSENUM_END_OF_SEQUENCE, 0);
	} else {
		ws_serialize_str(epcntx->serializercntx, resp_node, enumInfo->enumId,
			    XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, 0);
		insert_enum_info(soapCntx, enumInfo);
		enumInfo = NULL;
	}

DONE:
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	ws_destroy_context(epcntx);
	u_free(status.fault_msg);
	if (enumInfo) {
		destroy_enuminfo(enumInfo);
	}
	return retVal;
}



int
wsenum_release_stub(SoapOpH op,
		    void *appData,
			void *opaqueData)
{
	int             retVal = 0;
	WsXmlDocH       doc = NULL;
	WsmanStatus     status;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH      soapCntx = ws_get_soap_context(soap);
	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
	WsEndPointRelease endPoint = (WsEndPointRelease) ep->serviceEndPoint;
	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	WsEnumerateInfo *enumInfo;

	wsman_status_init(&status);
	enumInfo = get_locked_enuminfo(soapCntx, _doc,
		op, WSENUM_RELEASE, &status);

        ws_set_context_xml_doc_val(soapCntx, WSFW_INDOC, _doc);

	if (enumInfo == NULL) {
		doc = wsman_generate_fault( _doc,
			status.fault_code, status.fault_detail_code, NULL);

	} else {
		if (endPoint && (retVal = endPoint(soapCntx,
						enumInfo, &status, opaqueData))) {
			error("endPoint error");
			doc = wsman_generate_fault( _doc,
				WSMAN_INTERNAL_ERROR,
				OWSMAN_DETAIL_ENDPOINT_ERROR, NULL);
			unlock_enuminfo(soapCntx, enumInfo);
		} else {
			doc = wsman_create_response_envelope( _doc, NULL);
			debug("Releasing context: %s", enumInfo->enumId);
			remove_locked_enuminfo(soapCntx, enumInfo);
			destroy_enuminfo(enumInfo);
		}
	}
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	return retVal;
}





int
wsenum_pull_stub(SoapOpH op, void *appData,
			void *opaqueData)
{
	WsXmlNodeH      node;
	WsmanStatus     status;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH      soapCntx = ws_get_soap_context(soap);

	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
	XmlSerializerInfo *typeInfo = ep->serializationInfo;
	WsEndPointPull  endPoint = (WsEndPointPull) ep->serviceEndPoint;

	int retVal = 0, locked = 0;
	WsXmlDocH doc = NULL;
	char *enumId = NULL;

	WsXmlDocH _doc = soap_get_op_doc(op, 1);
	WsEnumerateInfo *enumInfo;
	WsXmlNodeH body;

	wsman_status_init(&status);
	enumInfo = get_locked_enuminfo(soapCntx, _doc,
		op, WSENUM_PULL, &status);

	if (enumInfo == NULL) {
		doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, NULL);
		goto DONE;
	}
	locked = 1;
	if ((retVal = endPoint(ws_create_ep_context(soap, _doc),
						enumInfo, &status, opaqueData))) {
		doc = wsman_generate_fault(_doc, status.fault_code, status.fault_detail_code, NULL);
		goto DONE;
	}
	enumInfo->index++;
	doc = wsman_create_response_envelope( _doc, NULL);

	if (!doc) {
		goto DONE;
	}

	wsman_set_estimated_total(_doc, doc, enumInfo);
	body = ws_xml_get_soap_body(doc);
	if (!body) {
		goto DONE;
	}

	node = ws_xml_add_child(body, XML_NS_ENUMERATION, WSENUM_PULL_RESP, NULL);
	if (node == NULL) {
		goto DONE;
	}
	if (enumInfo->pullResultPtr) {
		if (enumId) {
			ws_serialize_str(soapCntx->serializercntx, node, enumId,
			    XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, 0);
		}
		WsXmlNodeH itemsNode = ws_xml_add_child(node,
				    XML_NS_ENUMERATION, WSENUM_ITEMS, NULL);
		ws_serialize(soapCntx->serializercntx, itemsNode, enumInfo->pullResultPtr,
			 typeInfo, ep->respName, (char *) ep->data, NULL, 1);
		ws_serializer_free_mem(soapCntx->serializercntx,
			enumInfo->pullResultPtr, typeInfo);
	} else {
		/*
		ws_serialize_str(soapCntx, node, NULL,
			    XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, 0);
			    */
		ws_serialize_str(soapCntx->serializercntx,
		    node, NULL, XML_NS_ENUMERATION, WSENUM_END_OF_SEQUENCE, 0);
		remove_locked_enuminfo(soapCntx, enumInfo);
		locked = 0;
		destroy_enuminfo(enumInfo);
	}

DONE:
	if (locked) {
		unlock_enuminfo(soapCntx, enumInfo);
	}
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	return retVal;
}


int
wsenum_pull_direct_stub(SoapOpH op,
		     void *appData,
			void *opaqueData)
{
	WsmanStatus     status;
	WsXmlDocH       doc = NULL;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH      soapCntx = ws_get_soap_context(soap);
	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
#ifdef ENABLE_EVENTING_SUPPORT
	WsNotificationInfoH notificationInfo = NULL;
#endif

	WsEndPointPull  endPoint = (WsEndPointPull) ep->serviceEndPoint;
	int             retVal = 0;
	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	int locked = 0;
	WsEnumerateInfo *enumInfo;
	WsSubscribeInfo *subsInfo = NULL;
	wsman_status_init(&status);
	enumInfo = get_locked_enuminfo(soapCntx,
	                               _doc, op, WSENUM_PULL, &status);

	if (enumInfo == NULL) {
		subsInfo = search_pull_subs_info(soap, _doc);
		if(subsInfo == NULL) {
			error("Invalid enumeration context...");
			doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, NULL);
			goto cleanup;
		}
	}
	if (enumInfo) { //pull things from "enumerate" results
		locked = 1;

		if ((retVal = endPoint(ws_create_ep_context(soap, _doc),
						enumInfo, &status, opaqueData))) {
			doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, NULL);
//			ws_remove_context_val(soapCntx, cntxName);
			goto cleanup;
		}

		enumInfo->index++;
		if (enumInfo->pullResultPtr) {
			WsXmlNodeH      body;
			WsXmlNodeH      response, items;
			doc = enumInfo->pullResultPtr;
			wsman_set_estimated_total(_doc, doc, enumInfo);

			body = ws_xml_get_soap_body(doc);
			response = ws_xml_get_child(body, 0,
					XML_NS_ENUMERATION, WSENUM_PULL_RESP);
			items = ws_xml_get_child(response, 0,
                                        XML_NS_ENUMERATION, WSENUM_ITEMS);
			if (items == NULL) {
				error("Invalid enumeration items...");
				doc = wsman_generate_fault( _doc, WSMAN_INTERNAL_ERROR, WSMAN_DETAIL_INVALID, NULL);
				goto cleanup;
			}
			if (enumInfo->totalItems == 0 || enumInfo->index == enumInfo->totalItems) {
				/*
				   ws_serialize_str(soapCntx, response, NULL,
				   XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT, 0);
				   */
				ws_serialize_str(soapCntx->serializercntx, response, NULL,
						XML_NS_ENUMERATION, WSENUM_END_OF_SEQUENCE, 0);
				remove_locked_enuminfo(soapCntx, enumInfo);
				locked = 0;
				destroy_enuminfo(enumInfo);
			} else  {
			        /* add Context before Items to comply to WS-Enumeration xsd */
				ws_xml_add_prev_sibling(items, XML_NS_ENUMERATION,
							WSENUM_ENUMERATION_CONTEXT, enumInfo->enumId);
			}
		}
	}
#ifdef ENABLE_EVENTING_SUPPORT
	else { //pull things from notifications
		ws_xml_destroy_doc(doc);
		pthread_mutex_lock(&subsInfo->notificationlock);
		int count = soap->eventpoolOpSet->count(subsInfo->subsId);
		int max_elements = 1;
		if(count > 0) {
			doc = ws_xml_create_envelope();
			WsXmlNodeH docnode = ws_xml_get_soap_body(doc);
			WsXmlNodeH docheader = ws_xml_get_soap_header(doc);
			docnode = ws_xml_add_child(docnode, XML_NS_ENUMERATION, WSENUM_PULL_RESP, NULL);
			if(docnode) {
				ws_xml_add_child_format(docnode, XML_NS_ENUMERATION, WSENUM_ENUMERATION_CONTEXT,
					"uuid:%s", subsInfo->subsId);
			}
			WsXmlDocH notidoc = NULL;
			WsXmlNodeH header = ws_xml_get_soap_header(_doc);
			if (ws_xml_get_child(header, 0,XML_NS_WS_MAN, WSM_REQUEST_TOTAL) != NULL) {
				WsXmlNodeH response_header =ws_xml_get_soap_header(doc);
				response_header = ws_xml_add_child(response_header, XML_NS_WS_MAN,
					WSM_TOTAL_ESTIMATE, NULL);
				if(response_header)
					ws_xml_add_node_attr(response_header, XML_NS_SCHEMA_INSTANCE, XML_SCHEMA_NIL, "true");
			}
			header = ws_xml_get_child(header, 0, XML_NS_ENUMERATION, WSENUM_MAX_ELEMENTS);
			if(header)
				max_elements = atoi(ws_xml_get_node_text(header));
			if(max_elements > 1 && count > 1) {
				docnode = ws_xml_add_child(docnode, XML_NS_ENUMERATION, WSENUM_ITEMS, NULL);
			}
			while(max_elements > 0) {
				if(soap->eventpoolOpSet->remove(subsInfo->subsId, &notificationInfo))
					break;
				ws_xml_add_child(docheader, XML_NS_ADDRESSING, WSA_ACTION, notificationInfo->EventAction);
				notidoc = notificationInfo->EventContent;
				WsXmlNodeH tempnode = ws_xml_get_doc_root(notidoc);
				ws_xml_duplicate_tree(docnode, tempnode);
				delete_notification_info(notificationInfo);
				max_elements--;
			}
		}
		else {
			status.fault_code = WSMAN_TIMED_OUT;
			doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, NULL);
		}
		pthread_mutex_unlock(&subsInfo->notificationlock);
	}
#endif
cleanup:
	if (locked) {
		unlock_enuminfo(soapCntx, enumInfo);
	}
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	} else {
		error("doc is null");
	}

	return retVal;
}

static list_t *
wsman_get_expired_enuminfos(WsContextH cntx)
{
	list_t *list = NULL;
	hnode_t        *hn;
	hscan_t         hs;
	WsEnumerateInfo *enumInfo;
	struct timeval tv;
	unsigned long mytime;
	unsigned long aeit = cntx->enumIdleTimeout;

	if (aeit == 0) {
		return NULL;
	}
	gettimeofday(&tv, NULL);
	mytime = tv.tv_sec;
	u_lock(cntx->soap);
	if (hash_isempty(cntx->enuminfos)) {
		u_unlock(cntx->soap);
		return NULL;
	}
	hash_scan_begin(&hs, cntx->enuminfos);
	while ((hn = hash_scan_next(&hs))) {
		enumInfo = (WsEnumerateInfo *)hnode_get(hn);
		if (enumInfo->flags & WSMAN_ENUMINFO_INWORK_FLAG) {
			debug("Enum in work: %s", enumInfo->enumId);
			continue;
		}
		if ((enumInfo->timeStamp + aeit > mytime) &&
				((enumInfo->expires == 0) ||
				(enumInfo->expires > mytime))) {
			continue;
		}
		if (list == NULL) {
			list = list_create(LISTCOUNT_T_MAX);
		}
		if (list == NULL) {
			u_unlock(cntx->soap);
			error("could not create list");
			return NULL;
		}
		hash_scan_delfree(cntx->enuminfos, hn);
		list_append(list, lnode_create(enumInfo));
		debug("Enum expired list appended: %s", enumInfo->enumId);
	}
	u_unlock(cntx->soap);
	return list;
}

void
wsman_timeouts_manager(WsContextH cntx, void *opaqueData)
{
	list_t *list = wsman_get_expired_enuminfos(cntx);
	lnode_t *node;
	WsEnumerateInfo *enumInfo;
	WsmanStatus status;

	if (list == NULL) {
		return;
	}
	while ((node = list_del_first(list))) {
		enumInfo = (WsEnumerateInfo *)lnode_get(node);
		debug("EnumContext expired : %s", enumInfo->enumId);
		lnode_destroy(node);
		if (enumInfo->releaseproc) {
			if (enumInfo->releaseproc(cntx, enumInfo, &status, opaqueData)) {
				debug("released with failure: %s",
						enumInfo->enumId);
			} else {
				debug("released: %s", enumInfo->enumId);
			}
		} else {
			debug("no release endpoint: %s", enumInfo->enumId);
		}
		destroy_enuminfo(enumInfo);
		if (list_isempty(list)) {
			list_destroy(list);
			break;
		}
	}
	return;
}


#ifdef ENABLE_EVENTING_SUPPORT
static int destination_reachable(char *url)
{
	int valid = 0;
	u_uri_t *uri = NULL;
	if(strstr(url, "http") == NULL)
		return valid;
	if (u_uri_parse((const char *)url, &uri) == 0) {
		valid = 1;
	}
	u_uri_free(uri);
	return valid;
}

WsEventThreadContextH
ws_create_event_context(SoapH soap, WsSubscribeInfo *subsInfo, WsXmlDocH doc)
{
	WsEventThreadContextH eventcntx = u_malloc(sizeof(*eventcntx));
	eventcntx->soap = soap;
	eventcntx->subsInfo = subsInfo;
	eventcntx->outdoc = doc;
	return eventcntx;
}

static void
destroy_subsinfo(WsSubscribeInfo * subsInfo)
{
	if(subsInfo == NULL) return;
	u_free(subsInfo->uri);
	u_free(subsInfo->auth_data.username);
	u_free(subsInfo->auth_data.password);
	u_free(subsInfo->epr_notifyto);
	u_free(subsInfo->locale);
	u_free(subsInfo->soapNs);
	u_free(subsInfo->contentEncoding);
	u_free(subsInfo->cim_namespace);
	u_free(subsInfo->username);
	u_free(subsInfo->password);
	u_free(subsInfo->certificate_thumbprint);
	if (subsInfo->filter) {
		filter_destroy(subsInfo->filter);
	}
	ws_xml_destroy_doc(subsInfo->bookmarkDoc);
	ws_xml_destroy_doc(subsInfo->templateDoc);
	ws_xml_destroy_doc(subsInfo->heartbeatDoc);
	u_free(subsInfo);
}


static void
create_notification_template(WsXmlDocH indoc, WsSubscribeInfo *subsInfo)
{
	WsXmlDocH notificationDoc = ws_xml_create_envelope();
	WsXmlNodeH temp = NULL;
	WsXmlNodeH node = NULL;
	WsXmlNodeH header = NULL;
	header = ws_xml_get_soap_header(notificationDoc);
	ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_TO, subsInfo->epr_notifyto);
	if(subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_EVENTS ||
		subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_PUSHWITHACK) {
		ws_xml_add_child(header, XML_NS_WS_MAN, WSM_ACKREQUESTED, NULL);
	}
	node = ws_xml_get_soap_body(indoc);
	node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
	node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_DELIVERY);
	node = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_NOTIFY_TO);
	temp = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PROPERTIES);
	if(temp == NULL)
		node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS);
	if(node ) {
		ws_xml_duplicate_children(header, node);
	}
	subsInfo->templateDoc = ws_xml_duplicate_doc(notificationDoc);
	subsInfo->heartbeatDoc = ws_xml_duplicate_doc( notificationDoc);
	temp = ws_xml_get_soap_header(subsInfo->heartbeatDoc);
	temp = ws_xml_add_child(temp, XML_NS_ADDRESSING, WSA_ACTION, WSMAN_ACTION_HEARTBEAT);
	ws_xml_add_node_attr(temp, XML_NS_XML_SCHEMA, SOAP_MUST_UNDERSTAND, "true");
	ws_xml_destroy_doc(notificationDoc);
}


static WsXmlDocH
create_subs_info(SoapOpH op,
		 		WsContextH epcntx,
              	WsXmlDocH indoc,
              	WsSubscribeInfo**sInfo)
{
	WsXmlNodeH  node = ws_xml_get_soap_body(indoc);
	WsXmlNodeH	subNode = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
	WsXmlNodeH	temp;
	WsXmlDocH outdoc = NULL;
	WsSubscribeInfo *subsInfo;
	WsXmlAttrH attr = NULL;
	op_t *_op = (op_t *) op;
	WsmanMessage   *msg = (WsmanMessage *) _op->data;
	WsmanFaultCodeType fault_code = WSMAN_RC_OK;
	WsmanFaultDetailType fault_detail_code = WSMAN_DETAIL_OK;
	char *str = NULL;
	time_t timeout;
	int r;
	char *soapNs = NULL, *ntext = NULL;


	*sInfo = NULL;
	subsInfo = (WsSubscribeInfo *)u_zalloc(sizeof (WsSubscribeInfo));
	if (subsInfo == NULL) {
		error("No memory");
		fault_code = WSMAN_INTERNAL_ERROR;
		goto DONE;
	}
	if((r = pthread_mutex_init(&subsInfo->notificationlock, NULL)) != 0) {
		fault_code = WSMAN_INTERNAL_ERROR;
		goto DONE;
	}
	subsInfo->uri = u_strdup(wsman_get_resource_uri(epcntx, indoc));
	if(!subNode) {
		message("No subsribe body");
		fault_code = WSE_INVALID_MESSAGE;
		goto DONE;
	}
	soapNs = ws_xml_get_node_name_ns(ws_xml_get_doc_root(indoc));
	subsInfo->soapNs = u_strdup(soapNs);
	node = ws_xml_get_child(subNode, 0, XML_NS_WS_MAN, WSM_SENDBOOKMARKS);
	if(node) {
		subsInfo->bookmarksFlag = 1;
	}
	node = ws_xml_get_child(subNode, 0, XML_NS_WS_MAN, WSM_BOOKMARK);
	if(node) {
		if(ws_xml_get_node_text(node) &&
			!strcmp(ws_xml_get_node_text(node), WSM_DEFAULTBOOKMARK)){
			subsInfo->flags |= WSMAN_SUBSCRIBEINFO_BOOKMARK_DEFAULT;
		}
		else {
			subsInfo->bookmarkDoc = ws_xml_create_doc(XML_NS_WS_MAN, WSM_BOOKMARK);
			temp = ws_xml_get_doc_root(subsInfo->bookmarkDoc);
			ws_xml_duplicate_children(temp, node);
		}
	}
	node = ws_xml_get_child(subNode, 0, XML_NS_EVENTING, WSEVENT_EXPIRES);
	if (node == NULL) {
		debug("No wsen:Expires");
		subsInfo->expires = 0;
	}
	else {
		wsman_set_expiretime(node, &subsInfo->expires, &fault_code);
		if (fault_code != WSMAN_RC_OK) {
			debug("Invalid expiration time!");
			goto DONE;
		}
		if(time_expired(subsInfo->expires)) {
			fault_code = WSE_INVALID_EXPIRATION_TIME;
			debug("Invalid expiration time!");
			goto DONE;
		}
	}
	node = ws_xml_get_child(subNode, 0, XML_NS_EVENTING, WSEVENT_DELIVERY);
	attr = ws_xml_find_node_attr(node, NULL,WSEVENT_DELIVERY_MODE);
	if(attr) {
		str = ws_xml_get_attr_value(attr);
		if (!strcasecmp(str, WSEVENT_DELIVERY_MODE_PUSH)) {
			subsInfo->deliveryMode = WS_EVENT_DELIVERY_MODE_PUSH;
		}
		else if (!strcasecmp(str, WSEVENT_DELIVERY_MODE_PUSHWITHACK)) {
			subsInfo->deliveryMode = WS_EVENT_DELIVERY_MODE_PUSHWITHACK;
		}
		else if (!strcasecmp(str, WSEVENT_DELIVERY_MODE_EVENTS))  {
			subsInfo->deliveryMode = WS_EVENT_DELIVERY_MODE_EVENTS;
		}
		else {
			subsInfo->deliveryMode = WS_EVENT_DELIVERY_MODE_PULL;
		}
	}
	else {
		//"push" is the default delivery mode
		subsInfo->deliveryMode = WS_EVENT_DELIVERY_MODE_PUSH;
	}
	temp = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_CONTENTCODING);
	if(temp){
		str = ws_xml_get_node_text(temp);
		subsInfo->contentEncoding = u_strdup(str);
	}
	temp = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_LOCALE);
	if(temp) {
		attr = ws_xml_find_node_attr(temp, XML_NS_WS_MAN, WSM_LOCALE);
		if(attr)
			subsInfo->locale = u_strdup(ws_xml_get_attr_value(attr));
	}
	temp = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_HEARTBEATS);
	if(temp) {
		str = ws_xml_get_node_text(temp);
		debug("[heartbeat interval = %s]",str);
		if(str[0]=='P') {
			//  xml duration
			if (ws_deserialize_duration(str, &timeout)) {
				fault_code = WSEN_INVALID_EXPIRATION_TIME;
				goto DONE;
			}
			debug("timeout = %d", timeout);
			subsInfo->heartbeatInterval = timeout * 1000;
			subsInfo->heartbeatCountdown = subsInfo->heartbeatInterval;
		}
	}
	if(subsInfo->deliveryMode != WS_EVENT_DELIVERY_MODE_PULL) {
		temp = ws_xml_get_child(node, 0, XML_NS_EVENTING, WSEVENT_NOTIFY_TO);
		if(temp == NULL) {
			message("No notification destination");
			fault_code = WSE_INVALID_MESSAGE;
			goto DONE;
		}
		str = ws_xml_get_node_text(ws_xml_get_child(temp, 0, XML_NS_ADDRESSING, WSA_ADDRESS));
		debug("event sink: %s", str);
		if(str && strcmp(str, "")) {
			subsInfo->epr_notifyto = u_strdup(str);
			if(destination_reachable(str) == 0) {
				fault_code = WSMAN_EVENT_DELIVER_TO_UNUSABLE;
				goto DONE;
			}
		}
		else {
			fault_code = WSE_INVALID_MESSAGE;
			goto DONE;
		}
		temp = ws_xml_get_child(node, 0, XML_NS_WS_MAN, WSM_AUTH);
		if(temp) {
			attr = ws_xml_find_node_attr(temp, NULL, WSM_PROFILE);
			if(attr) {
				str = ws_xml_get_attr_value(attr);
				if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTP_BASIC))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTP_BASIC_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTP_DIGEST))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTP_DIGEST_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_BASIC))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_BASIC_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_DIGEST))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_DIGEST_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_BASIC))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_BASIC_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_DIGEST))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_DIGEST_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_SPNEGO_KERBEROS))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_SPNEGO_KERBEROS_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_SPNEGO_KERBEROS))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_SPNEGO_KERBEROS_TYPE;
				else if(!strcasecmp(str, WSMAN_SECURITY_PROFILE_HTTP_SPNEGO_KERBEROS))
					subsInfo->deliveryAuthType = WSMAN_SECURITY_PROFILE_HTTP_SPNEGO_KERBEROS_TYPE;
				else {
					fault_code = WSMAN_INVALID_OPTIONS;
					fault_detail_code = WSMAN_DETAIL_AUTHERIZATION_MODE;
					goto DONE;
				}
				debug("auth profile type = %d", subsInfo->deliveryAuthType);

			}
		}
	}
	if(wsman_parse_credentials(indoc, subsInfo, &fault_code, &fault_detail_code)) {
		goto DONE;
	}
	if(wsman_parse_event_request(indoc, subsInfo, &fault_code, &fault_detail_code)) {
		goto DONE;
	}
	if (msg->auth_data.username != NULL) {
		subsInfo->auth_data.username =
				u_strdup(msg->auth_data.username);
		subsInfo->auth_data.password =
				u_strdup(msg->auth_data.password);
	} else {
		subsInfo->auth_data.username = NULL;
		subsInfo->auth_data.password = NULL;
	}
	temp = ws_xml_get_soap_header(indoc);
	temp = ws_xml_get_child(temp, 0, XML_NS_OPENWSMAN, "FormerUID");
	ntext = ws_xml_get_node_text(temp);
	if(temp && ntext) { //it is a request from the saved reqeust. So we recover the former UUID
		strncpy(subsInfo->subsId, ntext, EUIDLEN);
		debug("Recover to uuid:%s",subsInfo->subsId);
	}
	else
		generate_uuid(subsInfo->subsId, EUIDLEN, 1);
	if(subsInfo->deliveryMode != WS_EVENT_DELIVERY_MODE_PULL)
		create_notification_template(indoc, subsInfo);
DONE:
	if (fault_code != WSMAN_RC_OK) {
		outdoc = wsman_generate_fault(indoc, fault_code, fault_detail_code, NULL);
		destroy_subsinfo(subsInfo);
	} else {
		*sInfo = subsInfo;
	}
	return outdoc;
}


/**
 * Subscribe Stub for processing subscription requests
 * @param op SOAP pperation handler
 * @param appData Application data
 * @return status
 */
int
wse_subscribe_stub(SoapOpH op, void *appData, void *opaqueData)
{
	WsXmlDocH       doc = NULL;
	int             retVal = 0;
	WsSubscribeInfo *subsInfo = NULL;
	WsmanStatus     status;
	WsXmlNodeH      inNode, body, header, temp;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH soapCntx = ws_get_soap_context(soap);
	int i;
	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
	WsEndPointSubscribe endPoint =
			(WsEndPointSubscribe)ep->serviceEndPoint;

	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	WsContextH      epcntx;
	char *buf = NULL;
	char *expiresstr = NULL;
	int len;
	epcntx = ws_create_ep_context(soap, _doc);
	wsman_status_init(&status);
	doc = create_subs_info(op, epcntx, _doc, &subsInfo);
	if (doc != NULL) {
		goto DONE;
	}
	if (endPoint && (retVal = endPoint(epcntx, subsInfo, &status, opaqueData))) {
                debug("Subscribe fault");
		doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, status.fault_msg);
		destroy_subsinfo(subsInfo);
		goto DONE;
	}
	doc = wsman_create_response_envelope(_doc, NULL);
	if (!doc)
		goto DONE;

	char str[30];
	wsman_expiretime2xmldatetime(subsInfo->expires, str);
	if(soap->subscriptionOpSet) {
		temp = ws_xml_get_child(ws_xml_get_soap_body(_doc), 0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
		temp = ws_xml_get_child(temp, 0, XML_NS_EVENTING, WSEVENT_EXPIRES);
		if(temp) {
			expiresstr = strdup(ws_xml_get_node_text(temp));
			ws_xml_set_node_text(temp, str);
		}
		temp = ws_xml_get_soap_header(_doc);
		inNode = ws_xml_get_child(temp, 0, XML_NS_OPENWSMAN, "FormerUID");
		if(inNode == NULL)
			ws_xml_add_child(temp, XML_NS_OPENWSMAN, "FormerUID", subsInfo->subsId);
		ws_xml_dump_memory_enc(_doc, &buf, &len, "UTF-8");
		if(buf) {
			soap->subscriptionOpSet->save_subscritption(soap->uri_subsRepository, subsInfo->subsId, (unsigned char*)buf);
			u_free(buf);
		}
	}
	lnode_t * sinfo = lnode_create(subsInfo);
	pthread_mutex_lock(&soap->lockSubs);
	list_append(soapCntx->subscriptionMemList, sinfo);
	pthread_mutex_unlock(&soap->lockSubs);
	debug("subscription uuid:%s kept in the memory", subsInfo->subsId);
	header = ws_xml_get_soap_header(doc);
	inNode = ws_xml_get_soap_header(_doc);
	inNode = ws_xml_get_child(inNode, 0, XML_NS_ADDRESSING, WSA_REPLY_TO);
	inNode = ws_xml_get_child(inNode, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PROPERTIES);
	if(inNode == NULL)
		inNode = ws_xml_get_child(inNode, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS);
	if(inNode) {
		for (i = 0;
		     (temp =
		      ws_xml_get_child(inNode, i, NULL, NULL)) != NULL;
		     i++) {
			ws_xml_duplicate_tree(header, temp);
		}
	}
	body = ws_xml_get_soap_body(doc);
	inNode = ws_xml_add_child(body, XML_NS_EVENTING, WSEVENT_SUBSCRIBE_RESP, NULL);
	temp = ws_xml_add_child(inNode, XML_NS_EVENTING, WSEVENT_SUBSCRIPTION_MANAGER, NULL);
	if(subsInfo->expires)
		ws_xml_add_child(inNode, XML_NS_EVENTING, WSEVENT_EXPIRES, expiresstr);
	if(subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_PULL)
		ws_xml_add_child_format(inNode, XML_NS_ENUMERATION,
		WSENUM_ENUMERATION_CONTEXT, "uuid:%s", subsInfo->subsId);
	inNode = temp;
	if(inNode){
		temp = ws_xml_get_soap_header(_doc);
		temp = ws_xml_get_child(temp, 0, XML_NS_ADDRESSING, WSA_TO);
		ws_xml_add_child(inNode,XML_NS_ADDRESSING,WSA_ADDRESS,ws_xml_get_node_text(temp));
	}
	temp = ws_xml_add_child(inNode, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS, NULL);
	if(temp)
		ws_xml_add_child_format(temp, XML_NS_EVENTING, WSEVENT_IDENTIFIER, "uuid:%s", subsInfo->subsId);
DONE:
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	u_free(expiresstr);
	ws_serializer_free_all(epcntx->serializercntx);
	ws_destroy_context(epcntx);
	u_free(status.fault_msg);
	return retVal;
}




/**
 * Unsubscribe Stub for processing unsubscription requests
 * @param op SOAP pperation handler
 * @param appData Application data
 * @return status
 */
int
wse_unsubscribe_stub(SoapOpH op, void *appData, void *opaqueData)
{
	WsXmlDocH       doc = NULL;
	int             retVal = 0;
	WsSubscribeInfo *subsInfo = NULL;
	WsmanStatus     status;
	WsXmlNodeH      inNode;
	WsXmlNodeH      header;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH soapCntx = ws_get_soap_context(soap);
	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
	WsEndPointSubscribe endPoint =
			(WsEndPointSubscribe)ep->serviceEndPoint;

	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	WsContextH      epcntx;

	epcntx = ws_create_ep_context(soap, _doc);
	wsman_status_init(&status);
	header = ws_xml_get_soap_header(_doc);
	inNode = ws_xml_get_child(header, 0, XML_NS_EVENTING, WSEVENT_IDENTIFIER);
	if(inNode == NULL) {
		status.fault_code = WSE_INVALID_MESSAGE;
		status.fault_detail_code = WSMAN_DETAIL_INVALID_VALUE;
		goto DONE;
	}
	char *uuid = ws_xml_get_node_text(inNode);
	lnode_t *t = NULL;
	pthread_mutex_lock(&soap->lockSubs);
	if(!list_isempty(soapCntx->subscriptionMemList)) {
		t = list_first(soapCntx->subscriptionMemList);
		subsInfo = (WsSubscribeInfo *)t->list_data;
		while(t && strcasecmp(subsInfo->subsId, uuid+5)) {
			t = list_next(soapCntx->subscriptionMemList, t);
			if(t)
				subsInfo = (WsSubscribeInfo *)t->list_data;
		}
	}
	if(t == NULL) {
		status.fault_code = WSMAN_INVALID_PARAMETER;
		status.fault_detail_code = WSMAN_DETAIL_INVALID_VALUE;
		doc = wsman_generate_fault( _doc,
		 	status.fault_code, status.fault_detail_code, NULL);
		pthread_mutex_unlock(&soap->lockSubs);
		goto DONE;
	}
	pthread_mutex_unlock(&soap->lockSubs);
	if (endPoint && (retVal = endPoint(epcntx, subsInfo, &status, opaqueData))) {
               debug("UnSubscribe fault");
		doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, status.fault_msg);
		goto DONE;
	}
	pthread_mutex_lock(&subsInfo->notificationlock);
	subsInfo->flags |= WSMAN_SUBSCRIBEINFO_UNSUBSCRIBE;
	pthread_mutex_unlock(&subsInfo->notificationlock);
	debug("subscription %s unsubscribed", uuid);
	doc = wsman_create_response_envelope( _doc, NULL);
	if (!doc)
		goto DONE;
DONE:
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	ws_serializer_free_all(epcntx->serializercntx);
	ws_destroy_context(epcntx);
	u_free(status.fault_msg);
	return retVal;
}


/**
 * Renew Stub for processing renew requests
 * @param op SOAP pperation handler
 * @param appData Application data
 * @return status
 */
int
wse_renew_stub(SoapOpH op, void *appData, void *opaqueData)
{
	WsXmlDocH       doc = NULL;
	int             retVal = 0;
	WsSubscribeInfo *subsInfo;
	WsmanStatus     status;
	WsXmlNodeH      inNode;
	WsXmlNodeH      body;
	WsXmlNodeH      header;
	SoapH           soap = soap_get_op_soap(op);

	if (soap == NULL) {
		error("soap_get_op_soap failed");
		return -1;
	}

	WsContextH soapCntx = ws_get_soap_context(soap);
	char * expirestr = NULL;

	WsDispatchEndPointInfo *ep = (WsDispatchEndPointInfo *) appData;
	WsEndPointSubscribe endPoint =
			(WsEndPointSubscribe)ep->serviceEndPoint;

	WsXmlDocH       _doc = soap_get_op_doc(op, 1);
	WsContextH      epcntx;
	epcntx = ws_create_ep_context(soap, _doc);
	wsman_status_init(&status);
	body = ws_xml_get_soap_body(_doc);
	header = ws_xml_get_soap_header(_doc);
	inNode = ws_xml_get_child(header, 0, XML_NS_EVENTING, WSEVENT_IDENTIFIER);
	char *uuid = ws_xml_get_node_text(inNode);
	if(uuid == NULL) {
		status.fault_code = WSE_INVALID_MESSAGE;
		status.fault_detail_code = WSMAN_DETAIL_MISSING_VALUES;
		doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, NULL);
		goto DONE;
	}
	pthread_mutex_lock(&soap->lockSubs);
	lnode_t *t = NULL;
	if(!list_isempty(soapCntx->subscriptionMemList)) {
		t = list_first(soapCntx->subscriptionMemList);
		subsInfo = (WsSubscribeInfo *)t->list_data;
		while(t && strcasecmp(subsInfo->subsId, uuid+5)) {
			t = list_next(soapCntx->subscriptionMemList, t);
			if(t)
				subsInfo = (WsSubscribeInfo *)t->list_data;
		}
	}
	if(t == NULL) {
		status.fault_code = WSE_UNABLE_TO_RENEW;
		doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, NULL);
		pthread_mutex_unlock(&soap->lockSubs);
		goto DONE;
	}
	pthread_mutex_unlock(&soap->lockSubs);
	inNode = ws_xml_get_child(body, 0, XML_NS_EVENTING, WSEVENT_RENEW);
	inNode = ws_xml_get_child(inNode, 0, XML_NS_EVENTING ,WSEVENT_EXPIRES);
	pthread_mutex_lock(&subsInfo->notificationlock);
	wsman_set_expiretime(inNode, &subsInfo->expires, &status.fault_code);
	expirestr = ws_xml_get_node_text(inNode);
	pthread_mutex_unlock(&subsInfo->notificationlock);
	if (status.fault_code != WSMAN_RC_OK) {
		status.fault_detail_code = WSMAN_DETAIL_EXPIRATION_TIME;
		pthread_mutex_unlock(&subsInfo->notificationlock);
		goto DONE;
	}
	char str[30];
	wsman_expiretime2xmldatetime(subsInfo->expires, str);
	if(soap->subscriptionOpSet) {
		soap->subscriptionOpSet->update_subscription(soap->uri_subsRepository, uuid+5,
			str);
		debug("subscription %s updated!", uuid);
	}

	if (endPoint && (retVal = endPoint(epcntx, subsInfo, &status, opaqueData))) {
                debug("renew fault in plug-in");
		doc = wsman_generate_fault( _doc, status.fault_code, status.fault_detail_code, status.fault_msg);
		pthread_mutex_unlock(&subsInfo->notificationlock);
		goto DONE;
	}
	doc = wsman_create_response_envelope( _doc, NULL);
	if (!doc)
		goto DONE;
	body = ws_xml_get_soap_body(doc);
	body = ws_xml_add_child(body, XML_NS_EVENTING, WSEVENT_RENEW_RESP, NULL);
	ws_xml_add_child(body, XML_NS_EVENTING, WSEVENT_EXPIRES, expirestr);
DONE:
	if (doc) {
		soap_set_op_doc(op, doc, 0);
	}
	ws_serializer_free_all(epcntx->serializercntx);
	ws_destroy_context(epcntx);
	u_free(status.fault_msg);
	return retVal;
}


void
wsman_heartbeat_generator(WsContextH cntx, void *opaqueData)
{
	SoapH soap = cntx->soap;
	WsSubscribeInfo *subsInfo = NULL;
	WsEventThreadContextH threadcntx = NULL;
	WsContextH soapCntx = ws_get_soap_context(soap);
	pthread_t eventsender;
	pthread_attr_t pattrs;
	int r;
	if ((r = pthread_attr_init(&pattrs)) != 0) {
		debug("pthread_attr_init failed = %d", r);
		return;
	}
	if ((r = pthread_attr_setdetachstate(&pattrs,
					     PTHREAD_CREATE_DETACHED)) !=0) {
		debug("pthread_attr_setdetachstate = %d", r);
		return;
	}
	pthread_mutex_lock(&soap->lockSubs);
	lnode_t *node = list_first(soapCntx->subscriptionMemList);
	while(node) {
		subsInfo = (WsSubscribeInfo *)node->list_data;
		pthread_mutex_lock(&subsInfo->notificationlock);
#if 0
		debug("subscription %s : event sent last time = %d, heartbeat= %ld, heartbeatcountdown = %ld, pending events = %d",
			subsInfo->subsId, 	subsInfo->eventSentLastTime, subsInfo->heartbeatInterval, subsInfo->heartbeatCountdown, subsInfo->flags & WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING);
#endif
		if(subsInfo->flags & WSMAN_SUBSCRIBEINFO_UNSUBSCRIBE) {
			goto LOOP;
		}
		if(time_expired(subsInfo->expires)) {

			goto LOOP;

		}
		if(subsInfo->heartbeatInterval == 0 || subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_PULL) {
			goto LOOP;
		}
		subsInfo->heartbeatCountdown -= 1000;
		if(subsInfo->heartbeatCountdown > 0) {
			goto LOOP;
		}
		if(subsInfo->eventSentLastTime) {
			subsInfo->eventSentLastTime = 0;
		}
		else {
			debug("one heartbeat document created for %s", subsInfo->subsId);
			if((subsInfo->flags & WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING) == 0) {
				threadcntx = ws_create_event_context(soap, subsInfo, NULL);
				if(pthread_create(&eventsender, &pattrs, wse_heartbeat_sender, threadcntx) == 0)
					subsInfo->flags |= WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING;
			}
		}
		subsInfo->heartbeatCountdown = subsInfo->heartbeatInterval;
LOOP:
		pthread_mutex_unlock(&subsInfo->notificationlock);
		node = list_next(soapCntx->subscriptionMemList, node);
	}
	pthread_mutex_unlock(&soap->lockSubs);
}

static int wse_send_notification(WsEventThreadContextH cntx, WsXmlDocH outdoc, WsSubscribeInfo *subsInfo, unsigned char acked)
{
	int retVal = 0;
	WsManClient *notificationSender = wsmc_create_from_uri(subsInfo->epr_notifyto);
	if(subsInfo->contentEncoding)
		wsmc_set_encoding(notificationSender, subsInfo->contentEncoding);
	if(subsInfo->username)
		wsman_transport_set_userName(notificationSender, subsInfo->username);
	if(subsInfo->password)
		wsman_transport_set_password(notificationSender, subsInfo->password);
	if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTP_BASIC_TYPE) {
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTP_DIGEST_TYPE) {
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_BASIC_TYPE) {
		wsman_transport_set_verify_peer(notificationSender, 0);
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_DIGEST_TYPE) {
		wsman_transport_set_verify_peer(notificationSender, 0);
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_TYPE) {
		wsman_transport_set_verify_peer(notificationSender, 1);
		wsman_transport_set_certhumbprint(notificationSender, subsInfo->certificate_thumbprint);
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_BASIC_TYPE) {
		wsman_transport_set_verify_peer(notificationSender, 1);
		wsman_transport_set_certhumbprint(notificationSender, subsInfo->certificate_thumbprint);
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_DIGEST_TYPE) {
		wsman_transport_set_verify_peer(notificationSender, 1);
		wsman_transport_set_certhumbprint(notificationSender, subsInfo->certificate_thumbprint);
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_SPNEGO_KERBEROS_TYPE) {
	}
	else if(subsInfo->deliveryAuthType ==
		WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_SPNEGO_KERBEROS_TYPE) {
	}
	else { //WSMAN_SECURITY_PROFILE_HTTP_SPNEGO_KERBEROS_TYPE
	}
	wsmc_transport_init(notificationSender, NULL);
	if (wsman_send_request(notificationSender, outdoc)) {
                warning("wse_send_notification: wsman_send_request fails for endpoint %s", subsInfo->epr_notifyto);
                /* FIXME: retVal */
        }
	if(acked) {
		retVal = WSE_NOTIFICATION_NOACK;
		WsXmlDocH ackdoc = wsmc_build_envelope_from_response(notificationSender);
		if(ackdoc) {
			WsXmlNodeH node = ws_xml_get_soap_header(ackdoc);
			WsXmlNodeH srcnode = ws_xml_get_soap_header(outdoc);
			WsXmlNodeH temp = NULL;
			srcnode = ws_xml_get_child(srcnode, 0, XML_NS_ADDRESSING, WSA_MESSAGE_ID);
			if(node) {
				temp = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_RELATES_TO);
				if(temp) {
					if(!strcasecmp(ws_xml_get_node_text(srcnode),
						ws_xml_get_node_text(temp))) {
						node = ws_xml_get_child(node, 0, XML_NS_ADDRESSING, WSA_ACTION);
						if(!strcasecmp(ws_xml_get_node_text(node), WSMAN_ACTION_ACK))
							retVal = 0;
					}

				}
			}
			ws_xml_destroy_doc(ackdoc);
		}
	}
	wsmc_release(notificationSender);
	return retVal;
}


static void * wse_event_sender(void * thrdcntx, unsigned char flag)
{
	char uuidBuf[50];
	WsXmlNodeH header;
	if(thrdcntx == NULL) return NULL;
	WsEventThreadContextH threadcntx = (WsEventThreadContextH)thrdcntx;
	WsSubscribeInfo * subsInfo = threadcntx->subsInfo;
	if(flag == 1)
		debug("wse_notification_sender for %s started", subsInfo->subsId);
	else
		debug("wse_heartbeat_sender for %s started", subsInfo->subsId);
	WsXmlDocH notificationDoc = NULL;
	pthread_mutex_lock(&subsInfo->notificationlock);
	if(flag == 1)
		subsInfo->eventSentLastTime = 1;
	if(!(subsInfo->flags & WSMAN_SUBSCRIBEINFO_UNSUBSCRIBE) &&
		!time_expired(subsInfo->expires)) {
		if(flag) {
			notificationDoc = threadcntx->outdoc;
		}
		else {
	 		notificationDoc = ws_xml_duplicate_doc(subsInfo->heartbeatDoc);
			header = ws_xml_get_soap_header(notificationDoc);
			generate_uuid(uuidBuf, sizeof(uuidBuf), 0);
			ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_MESSAGE_ID,uuidBuf);
		}
		if (subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_EVENTS  ||
			subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_PUSHWITHACK){
			if(wse_send_notification(threadcntx, notificationDoc, subsInfo, 1) == WSE_NOTIFICATION_NOACK)
				subsInfo->flags |= WSMAN_SUBSCRIPTION_CANCELLED;
		}
		else
			wse_send_notification(threadcntx, notificationDoc, subsInfo, 0);
	}
	ws_xml_destroy_doc(notificationDoc);
	subsInfo->flags &= ~WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING;
	debug("[ wse_notification_sender thread for %s quit! ]",subsInfo->subsId);
	pthread_mutex_unlock(&subsInfo->notificationlock);
	u_free(thrdcntx);
	return NULL;
}

void * wse_heartbeat_sender(void *thrdcntx)
{
	return wse_event_sender(thrdcntx, 0);
}

void *wse_notification_sender(void *thrdcntx)
{
	return wse_event_sender(thrdcntx, 1);
}

void wse_notification_manager(void * cntx)
{
	int retVal;
	WsSubscribeInfo * subsInfo = NULL;
	WsXmlDocH notificationDoc =NULL;
	WsXmlNodeH header = NULL;
	WsXmlNodeH body = NULL;
	WsXmlNodeH node = NULL;
	WsXmlNodeH eventnode = NULL;
	WsXmlNodeH temp = NULL;
	lnode_t *subsnode = NULL;
	WsEventThreadContextH threadcntx = NULL;
	WsContextH contex = (WsContextH)cntx;
	SoapH soap = contex->soap;
	WsContextH soapCntx = ws_get_soap_context(soap);
	pthread_t eventsender;
	pthread_attr_t pattrs;
	char uuidBuf[50];
	int r;
	if ((r = pthread_attr_init(&pattrs)) != 0) {
		debug("pthread_attr_init failed = %d", r);
		return;
	}
	if ((r = pthread_attr_setdetachstate(&pattrs,
					     PTHREAD_CREATE_DETACHED)) !=0) {
		debug("pthread_attr_setdetachstate = %d", r);
		return;
	}
	pthread_mutex_lock(&soap->lockSubs);
	subsnode = list_first(soapCntx->subscriptionMemList);
	while(subsnode) {
		subsInfo = (WsSubscribeInfo *)subsnode->list_data;
		pthread_mutex_lock(&subsInfo->notificationlock);
		threadcntx = ws_create_event_context(soap, subsInfo, NULL);
		if(((subsInfo->flags & WSMAN_SUBSCRIBEINFO_UNSUBSCRIBE) ||
			subsInfo->flags & WSMAN_SUBSCRIPTION_CANCELLED ||
			time_expired(subsInfo->expires)) &&
			((subsInfo->flags & WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING ) == 0)) {
			lnode_t *nodetemp = list_delete2(soapCntx->subscriptionMemList, subsnode);
			soap->subscriptionOpSet->delete_subscription(soap->uri_subsRepository, subsInfo->subsId);
			soap->eventpoolOpSet->clear(subsInfo->subsId, delete_notification_info);
			if(!(subsInfo->flags & WSMAN_SUBSCRIBEINFO_UNSUBSCRIBE) && subsInfo->cancel)
				subsInfo->cancel(threadcntx);
			if(subsInfo->flags & WSMAN_SUBSCRIBEINFO_UNSUBSCRIBE)
				debug("Unsubscribed!uuid:%s deleted", subsInfo->subsId);
			else if(subsInfo->flags & WSMAN_SUBSCRIPTION_CANCELLED)
				debug("Cancelled! uuid:%s deleted", subsInfo->subsId);
			else
				debug("Expired! uuid:%s deleted", subsInfo->subsId);
			destroy_subsinfo(subsInfo);
			lnode_destroy(subsnode);
			u_free(threadcntx);
			subsnode = nodetemp;
			continue;
		}
		if(subsInfo->eventpoll) { //poll the events
			retVal = subsInfo->eventpoll(threadcntx);
			if(retVal == WSE_NOTIFICATION_EVENTS_PENDING) {
				goto LOOP;
			}
		}
		if(subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_PULL)
			goto LOOP;
		WsNotificationInfoH notificationInfo = NULL;
		if(soap->eventpoolOpSet->remove(subsInfo->subsId, &notificationInfo) ) // to get the event and delete it from the event source
			goto LOOP;
		if(subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_PULL) goto LOOP;
		notificationDoc = ws_xml_duplicate_doc(subsInfo->templateDoc);
		header = ws_xml_get_soap_header(notificationDoc);
		body = ws_xml_get_soap_body(notificationDoc);
		if(notificationInfo->headerOpaqueData) {
			temp = ws_xml_get_doc_root(notificationInfo->headerOpaqueData);
			ws_xml_duplicate_tree(header, temp);
		}
		if(subsInfo->deliveryMode == WS_EVENT_DELIVERY_MODE_EVENTS) {
			ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_ACTION, WSEVENT_DELIVERY_MODE_EVENTS);
			generate_uuid(uuidBuf, sizeof(uuidBuf), 0);
			ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_MESSAGE_ID,uuidBuf);
			eventnode = ws_xml_add_child(body, XML_NS_WS_MAN, WSM_EVENTS, NULL);
			while(notificationInfo) {
				temp = ws_xml_add_child(eventnode, XML_NS_WS_MAN, WSM_EVENT, NULL);
				if(notificationInfo->EventAction)  {
					ws_xml_add_node_attr(temp, XML_NS_WS_MAN, WSM_ACTION, notificationInfo->EventAction);
				}
				else {
					ws_xml_add_node_attr(temp, XML_NS_WS_MAN, WSM_ACTION, WSMAN_ACTION_EVENT);
				}
				if(temp) {
					node = ws_xml_get_doc_root(notificationInfo->EventContent);
					ws_xml_duplicate_children(temp, node);
				}
				delete_notification_info(notificationInfo);
				soap->eventpoolOpSet->remove(subsInfo->subsId, &notificationInfo);
			}
		}
		else{
			generate_uuid(uuidBuf, sizeof(uuidBuf), 0);
			ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_MESSAGE_ID,uuidBuf);
			if(notificationInfo->EventAction)
				ws_xml_add_child(header, XML_NS_WS_MAN, WSM_ACTION, notificationInfo->EventAction);
			else
				ws_xml_add_child(header, XML_NS_WS_MAN, WSM_ACTION, WSMAN_ACTION_EVENT);
			node = ws_xml_get_doc_root(notificationInfo->EventContent);
			ws_xml_duplicate_children(body, node);
			delete_notification_info(notificationInfo);
		}
		if(subsInfo->deliveryMode != WS_EVENT_DELIVERY_MODE_PULL) {
			if((subsInfo->flags & WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING) == 0) {
				WsEventThreadContextH threadcntx2 = ws_create_event_context(soap, subsInfo, notificationDoc);
				if(pthread_create(&eventsender, &pattrs, wse_notification_sender, threadcntx2) == 0) {
					subsInfo->flags |= WSMAN_SUBSCRIPTION_NOTIFICAITON_PENDING;
				}
				else {
					debug("thread created for %s failed![ %s ]", subsInfo->subsId, strerror(errno));
				}
			}
		}

LOOP:
		if(threadcntx)
			u_free(threadcntx);
		pthread_mutex_unlock(&subsInfo->notificationlock);
		subsnode = list_next(soapCntx->subscriptionMemList, subsnode);
	}
	pthread_mutex_unlock(&soap->lockSubs);
}



#endif


WsContextH
ws_get_soap_context(SoapH soap)
{
	return soap->cntx;
}


int
ws_remove_context_val(WsContextH cntx, char *name)
{
	int retVal = 1;
	if (cntx && name) {
		hnode_t        *hn;
		u_lock(cntx->soap);
		hn = hash_lookup(cntx->entries, name);
		if (hn) {
			debug("Found context entry: %s", name);
			hash_delete_free(cntx->entries, hn);
			retVal = 0;
		}
		u_unlock(cntx->soap);
	}
	return retVal;
}

int
ws_set_context_ulong_val(WsContextH cntx,
			 char *name,
			 unsigned long val)
{
	int retVal = set_context_val(cntx, name, &val, sizeof(unsigned long),
			0, WS_CONTEXT_TYPE_ULONG);
	return retVal;
}


int
ws_set_context_xml_doc_val(WsContextH cntx,
			   char *name,
			   WsXmlDocH val)
{
	cntx->indoc = val;
	return 0;
}

WsContextH
ws_create_ep_context(SoapH soap,
		     WsXmlDocH doc)
{
	WsContextH      cntx = ws_create_context(soap);
	if (cntx)
		ws_set_context_xml_doc_val(cntx, WSFW_INDOC, doc);
	return cntx;
}


int
ws_destroy_context(WsContextH cntx)
{
	int             retVal = 1;
	if (cntx && cntx->owner) {
		ws_clear_context_entries(cntx);
		ws_clear_context_enuminfos(cntx);
		ws_serializer_cleanup(cntx->serializercntx);
		if(cntx->subscriptionMemList) {
			list_destroy_nodes(cntx->subscriptionMemList);
			list_destroy(cntx->subscriptionMemList);
		}
		u_free(cntx);
		retVal = 0;
	}
	return retVal;
}


hnode_t*
create_context_entry(hash_t * h,
		     char *name,
		     void *val)
{
	char           *key = u_strdup(name);
	hnode_t        *hn = hnode_create(val);
	if (!key || !hn) {
		u_free(key);
		u_free(hn);
		return NULL;
	}
	hash_insert(h, hn, (void *) key);
	return hn;
}

SoapH
ws_context_get_runtime(WsContextH cntx)
{
	SoapH soap = NULL;
	if (cntx)
		soap = cntx->soap;
	return soap;
}


const void *
get_context_val(WsContextH cntx, const char *name)
{
	const char *val = NULL;
	if (cntx && name) {
		u_lock(cntx->soap);
		if (cntx->entries) {
			hnode_t *hn = hash_lookup(cntx->entries, name);
			if (hn)
				val = hnode_get(hn);
		}
		u_unlock(cntx->soap);
	}
	return val;
}


const void *
ws_get_context_val(WsContextH cntx, const char *name, int *size)
{
	return get_context_val(cntx, name);
}


unsigned long
ws_get_context_ulong_val(WsContextH cntx, char *name)
{
	const void *ptr = get_context_val(cntx, name);
	if (ptr != NULL)
		return *((unsigned long *) ptr);
	return 0;
}


SoapOpH
soap_create_op(SoapH soap,
	       char *inboundAction,
	       char *outboundAction, //optional
	       char *role,
	       SoapServiceCallback callbackProc,
	       void *callbackData,
	       unsigned long flags)
{
	SoapDispatchH  disp = NULL;
	op_t           *entry = NULL;

	if ((disp = wsman_dispatch_create(soap, inboundAction, outboundAction,
			      NULL, //reserved, must be NULL
			      callbackProc, callbackData, flags)) != NULL) {
		entry = create_op_entry(soap, disp, NULL);
	}
	return (SoapOpH) entry;
}



/**
 * Get Operation Document
 * @param op Operation Handle
 * @param inbound Direction flag
 * @return XML Document
 */
WsXmlDocH
soap_get_op_doc(SoapOpH op,
		int inbound)
{
	WsXmlDocH       doc = NULL;
	if (op) {
		op_t           *e = (op_t *) op;
		doc = (!inbound) ? e->out_doc : e->in_doc;
	}
	return doc;
}

WsXmlDocH
soap_detach_op_doc(SoapOpH op,
		   int inbound)
{
	WsXmlDocH       doc = NULL;
	if (op) {
		op_t           *e = (op_t *) op;
		if (!inbound) {
			doc = e->out_doc;
			e->out_doc = NULL;
		} else {
			doc = e->in_doc;
			e->in_doc = NULL;
		}
	}
	return doc;
}

int
soap_set_op_doc(SoapOpH op,
		WsXmlDocH doc,
		int inbound)
{
	int             retVal = 1;
	if (op) {
		op_t           *e = (op_t *) op;
		if (!inbound)
			e->out_doc = doc;
		else
			e->in_doc = doc;
		retVal = 0;
	}
	return retVal;
}


SoapH
soap_get_op_soap(SoapOpH op)
{
	if (op)
		return (SoapH) ((op_t *) op)->dispatch->soap;

	return NULL;
}

void
soap_destroy_op(SoapOpH op)
{
	destroy_op_entry((op_t *) op);
}


op_t *
create_op_entry(SoapH soap,
		SoapDispatchH dispatch,
		WsmanMessage * data)
{
	op_t *entry = (op_t *) u_zalloc(sizeof(op_t));
	if (entry) {
		entry->dispatch = dispatch;
		entry->cntx = ws_create_context(soap);
		entry->data = data;
		// entry->processed_headers = list_create(LISTCOUNT_T_MAX);
	}
	return entry;
}


void
destroy_op_entry(op_t * entry)
{
	SoapH           soap;
	debug("destroy op");
	if (!entry) {
		debug("nothing to destroy...");
		return;
	}
	soap = entry->dispatch->soap;
	if (soap == NULL) {
		goto NULL_SOAP;
	}
	u_lock(soap);
	if (soap->dispatchList && list_contains(soap->dispatchList, &entry->dispatch->node)) {
		list_delete(soap->dispatchList, &entry->dispatch->node);
	}
	u_unlock(soap);

NULL_SOAP:
	destroy_dispatch_entry(entry->dispatch);
	ws_destroy_context(entry->cntx);
#if 0
	list_destroy_nodes(entry->processed_headers);
	list_destroy(entry->processed_headers);
#endif
	u_free(entry);
}

void
destroy_dispatch_entry(SoapDispatchH entry)
{
	int usageCount;
	list_t *dlist;
	if (!entry) {
		return;
	}

	u_lock(entry->soap);
	entry->usageCount--;
	usageCount = entry->usageCount;
	dlist = entry->soap->dispatchList;
	if (!usageCount && dlist != NULL &&
			list_contains(dlist, &entry->node)) {
		lnode_t *n = list_delete(dlist, &entry->node);
		lnode_destroy(n);
	}
	u_unlock(entry->soap);

	if (!usageCount) {
		if (entry->inboundFilterList) {
			list_destroy_nodes(entry->inboundFilterList);
			list_destroy(entry->inboundFilterList);
		}
		if (entry->outboundFilterList) {
			list_destroy_nodes(entry->outboundFilterList);
			list_destroy(entry->outboundFilterList);
		}

		u_free(entry->inboundAction);
		u_free(entry->outboundAction);

		u_free(entry);
	}
}


void
soap_destroy(SoapH soap)
{
	if (soap == NULL )
		return;

	if (soap->dispatcherProc)
		soap->dispatcherProc(soap->cntx, soap->dispatcherData, NULL);

	if (soap->dispatchList) {
		while (!list_isempty(soap->dispatchList)) {
			destroy_dispatch_entry(
				(SoapDispatchH)list_first(soap->dispatchList));
		}
		list_destroy(soap->dispatchList);
	}

	if (soap->processedMsgIdList) {
		while (!list_isempty(soap->processedMsgIdList)) {
			lnode_t *node = list_del_first(soap->processedMsgIdList);
			u_free(node->list_data);
			lnode_destroy(node);
		}
		list_destroy(soap->processedMsgIdList);
	}


	if (soap->inboundFilterList) {
		list_destroy_nodes(soap->inboundFilterList);
		list_destroy(soap->inboundFilterList);
	}

	if (soap->outboundFilterList) {
		list_destroy_nodes(soap->outboundFilterList);
		list_destroy(soap->outboundFilterList);
	}
	ws_xml_parser_destroy();

	ws_destroy_context(soap->cntx);
	u_free(soap);

	return;
}


void
wsman_status_init(WsmanStatus * status)
{
	status->fault_code = 0;
	status->fault_detail_code = 0;
	status->fault_msg = NULL;
}

int
wsman_check_status(WsmanStatus * status)
{
	return status->fault_code;
}
