/*******************************************************************************
 * 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,cl
 *    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 NEGLIGclE 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 <stdbool.h>

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

#include "wsman-xml.h"
#include "wsman-xml-serialize.h"
#include "wsman-filter.h"
#include "wsman-client-transport.h"
#include "wsman-faults.h"
#include "wsman-client.h"

void
wsmc_set_dumpfile( WsManClient *cl, FILE *f )
{
    if (f)
		cl->dumpfile = f;
    return;
}


FILE *
wsmc_get_dumpfile(WsManClient *cl)
{
    return cl->dumpfile;
}


#ifndef _WIN32
void
wsmc_set_conffile(WsManClient *cl, char *f )
{
        u_free(cl->client_config_file);
        cl->client_config_file = (f != NULL) ? u_strdup(f): NULL;
}

char *
wsmc_get_conffile(WsManClient *cl)
{
        return cl->client_config_file;
}
#endif


static char*
wsman_make_action(const char *uri, const char *op_name)
{
	if (uri && op_name) {
		size_t len = strlen(uri) + strlen(op_name) + 2;
		char *ptr = (char *)u_malloc(len);
		if (ptr) {
			int ret = snprintf(ptr, len, "%s/%s", uri, op_name);
			if (ret < 0 || ret >= len) {
				error("Error: formating action");
				u_free(ptr);
				return NULL;
			}
			return ptr;
		}
	}
	return NULL;
}


/*
 * find key in property list
 * callback for list_find()
 */
static int
_list_key_compare(const void *node1, const void *key)
{
  const char *key1 = ((key_value_t *)node1)->key;
  const char *key2 = (const char *)key;
  return strcmp(key1, key2);
}


static WsXmlDocH
wsmc_build_envelope(WsSerializerContextH serctx,
		const char *action,
		const char *reply_to_uri,
		const char *resource_uri,
		const char *to_uri,
		client_opt_t *options)
{
	WsXmlNodeH      node;
	char            uuidBuf[100];
	WsXmlNodeH      header;
	WsXmlDocH       doc = ws_xml_create_envelope();
	if (!doc) {
		error("Error while creating envelope");
		return NULL;
	}

	header = ws_xml_get_soap_header(doc);
	if (header == NULL) {
		return NULL;
	}
	generate_uuid(uuidBuf, sizeof(uuidBuf), 0);

	if (reply_to_uri == NULL) {
		reply_to_uri = WSA_TO_ANONYMOUS;
	}
	if (to_uri == NULL) {
		to_uri = WSA_TO_ANONYMOUS;
	}
	if (action != NULL) {
		ws_serialize_str(serctx, header,
			(char *)action, XML_NS_ADDRESSING, WSA_ACTION, 1);
	}

	if (to_uri) {
		ws_serialize_str(serctx, header, (char *)to_uri,
			XML_NS_ADDRESSING, WSA_TO, 1);
	}
	if (resource_uri) {
		ws_serialize_str(serctx, header, (char *)resource_uri,
				XML_NS_WS_MAN, WSM_RESOURCE_URI, 1);
	}
	if (uuidBuf[0] != 0) {
		ws_serialize_str(serctx, header, uuidBuf,
			XML_NS_ADDRESSING, WSA_MESSAGE_ID, 1);
	}
	if (options->timeout) {
	  /* FIXME: see wsman-xml-serialize.c */
		char buf[20];
		int ret;
		ret = snprintf(buf, sizeof(buf), "PT%u.%uS",
				(unsigned int) options->timeout / 1000,
				(unsigned int) options->timeout % 1000);
		if (ret < 0 || ret >= sizeof(buf)) {
			error("Error: formating time");
			return NULL;
		}
		ws_serialize_str(serctx, header, buf,
			XML_NS_WS_MAN, WSM_OPERATION_TIMEOUT, 0);
	}
	if (options->max_envelope_size) {
		ws_serialize_uint32(serctx, header, options->max_envelope_size,
				XML_NS_WS_MAN, WSM_MAX_ENVELOPE_SIZE,
				options->flags & FLAG_MUND_MAX_ESIZE);
	}
	if (options->fragment) {
          /* FIXME: mu set but unused
		int mu = 0;
		if ((options->flags & FLAG_MUND_FRAGMENT) ==
				FLAG_MUND_FRAGMENT)
			mu = 1;
           */
		ws_serialize_str(serctx, header, options->fragment,
				XML_NS_WS_MAN, WSM_FRAGMENT_TRANSFER,
				1);
	}
	if (options->locale) {
          node = ws_xml_add_child(header, XML_NS_WS_MAN, WSM_LOCALE, NULL);
          ws_xml_set_node_lang(node, options->locale);
          ws_xml_add_node_attr(node, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND, "false");
	}

	node = ws_xml_add_child(header, XML_NS_ADDRESSING, WSA_REPLY_TO, NULL);
	if (node == NULL) {
		return NULL;
	}
	ws_xml_add_child(node, XML_NS_ADDRESSING, WSA_ADDRESS, (char *)reply_to_uri);

  	/* Do not add the selectors to the header for reference instances */
	if ((options->flags & FLAG_CIM_REFERENCES) != FLAG_CIM_REFERENCES) {
		wsmc_add_selector_from_options(doc, options);

		if (options->cim_ns) {
                  /* don't add CIM_NAMESPACE_SELECTOR twice */
                  if (options->selectors && list_count(options->selectors) > 0) {
                    if (!list_find(options->selectors, CIM_NAMESPACE_SELECTOR, _list_key_compare)) {
                      wsman_add_selector(header, CIM_NAMESPACE_SELECTOR, options->cim_ns);
                    }
                  }
                  else {
                    wsman_add_selector(header, CIM_NAMESPACE_SELECTOR, options->cim_ns);
                  }
                }
	}
	return doc;
}



// Access to client elements
WS_LASTERR_Code
wsmc_get_last_error(WsManClient * cl)
{
	return cl->last_error;
}


long
wsmc_get_response_code(WsManClient * cl)
{
	return cl->response_code;
}

char*
wsmc_get_fault_string(WsManClient * cl)
{
	return cl->fault_string;
}

WsSerializerContextH
wsmc_get_serialization_context(WsManClient * cl)
{
	return cl->serctx;
}


char *
wsmc_get_hostname(WsManClient * cl)
{
	return cl->data.hostname? u_strdup (cl->data.hostname) : NULL;
}


unsigned int
wsmc_get_port(WsManClient * cl)
{
	return cl->data.port;
}

char *
wsmc_get_scheme(WsManClient * cl)
{
	return cl->data.scheme ?  u_strdup ( cl->data.scheme) : NULL;
}


char *
wsmc_get_path(WsManClient * cl)
{
	return cl->data.path ?  u_strdup( cl->data.path ) : NULL;
}


char *
wsmc_get_user(WsManClient * cl)
{
	return  cl->data.user ? u_strdup( cl->data.user ) : NULL;
}


char *
wsmc_get_encoding(WsManClient *cl)
{
	return cl->content_encoding;
}


char *
wsmc_get_password(WsManClient * cl)
{
	return   cl->data.pwd ? u_strdup( cl->data.pwd ) : NULL;
}


char *
wsmc_get_endpoint(WsManClient * cl)
{
	return cl->data.endpoint ? cl->data.endpoint : NULL;
}




WsXmlDocH
wsmc_read_file( const char *filename,
		const char *encoding, unsigned long options)
{
	return ws_xml_read_file( filename, encoding, options);
}

WsXmlDocH
wsmc_read_memory( char *buf,
		size_t size, const char *encoding, unsigned long options)
{
	return ws_xml_read_memory( buf, size, encoding, options);
}

client_opt_t *
wsmc_options_init(void)
{
	client_opt_t *op = u_malloc(sizeof(client_opt_t));
	if (op)
		memset(op, 0, sizeof(client_opt_t));
	else
		return NULL;
	return op;
}

/*
 * Destroy list of key_value_t
 *
 */
static void
_wsmc_kvl_destroy(list_t *kvl)
{
  if (!kvl)
    return;
  while (!list_isempty(kvl)) {
    lnode_t *node;
    key_value_t *kv;

    node = list_del_last(kvl);
    if (!node)
      break;
    kv = (key_value_t *)node->list_data;
    lnode_destroy(node);
    key_value_destroy(kv, 0);
  }
  list_destroy(kvl);
}

void
wsmc_options_destroy(client_opt_t * op)
{
	if (op->options) {
		hash_free(op->options);
	}
        _wsmc_kvl_destroy(op->selectors);
        _wsmc_kvl_destroy(op->properties);
	u_free(op->fragment);
	u_free(op->cim_ns);
	u_free(op->delivery_uri);
	u_free(op->reference);
	u_free(op);
	return;
}

void
wsmc_set_action_option(client_opt_t * options, unsigned long flag)
{
	options->flags |= flag;
	return;
}


unsigned long
wsmc_get_action_option(client_opt_t * options)
{
	return options->flags;
}


void
wsmc_clear_action_option(client_opt_t * options, unsigned long flag)
{
	options->flags &= ~flag;
	return;
}


/*
 * (static function)
 * Add key/value to list_t (e.g. options->properties or ->selectors)
 * either as char* (string set, epr == NULL)
 * or as epr_t (string == NULL, epr set)
 * if (useArray == true) then value will be added without duplicate key checking
 */

static void
_wsmc_add_key_value(list_t **list_ptr,
		const char *key,
		const char *string,
		const epr_t *epr,
                bool useArray)
{
  key_value_t *kv;
  list_t *list = *list_ptr;
  lnode_t *lnode;
  if ((string != NULL) && (epr != NULL)) {
    error("Ambiguous call to add_key_value");
    return;
  }
  if (key == NULL) {
    error("Can't add_key_value with NULL key");
    return;
  }
  if (list == NULL) {
    list = list_create(LISTCOUNT_T_MAX);
    if (list == NULL) {
      error("list_create returned NULL");
      return;
    }
    *list_ptr = list;
  }
  if (!useArray && list_find(list, key, _list_key_compare)) {
    error("duplicate key not added to list");
    return;
  }
  kv = key_value_create(key, string, epr, NULL);
  if (!kv) {
    error("No memory for key/value pair");
    return;
  }
  lnode = lnode_create(kv);
  if (!lnode) {
    error("No memory for key/value node");
    return;
  }
  list_append(list, lnode);
}

/*
 * add a char* as an array type property (an array item)
 *
 */

void
wsmc_add_property_array_item(client_opt_t * options,
		const char *key,
		const char *value)
{
  _wsmc_add_key_value(&(options->properties), key, value, NULL, true);
}

/*
 * add a char* as property
 *
 */

void
wsmc_add_property(client_opt_t * options,
		const char *key,
		const char *value)
{
  _wsmc_add_key_value(&(options->properties), key, value, NULL, false);
}


/*
 * add an EndpointReference as property
 *
 */

void
wsmc_add_property_epr(client_opt_t * options,
		const char *key,
		const epr_t *value)
{
  _wsmc_add_key_value(&(options->properties), key, NULL, value, false);
}

/*
 * add key/value pair to WSM_OPTION_SET
 *
 */
void
wsmc_add_option(client_opt_t * options,
		const char *key,
		const char *value)
{
	if (options->options == NULL) {
		options->options = hash_create3(HASHCOUNT_T_MAX, 0, 0);
		if (options->options == NULL) {
			error("hash_create3 failed");
			return;
		}
	}
	if (!hash_lookup(options->options, key)) {
          char *k = u_strdup(key);
          char *v = u_strdup(value);
		if (!hash_alloc_insert(options->options, k, v)) {
			error( "hash_alloc_insert failed");
                  u_free(v);
                  u_free(k);
		}
	} else {
		error( "duplicate not added to hash");
	}
}

void
wsmc_add_selector(client_opt_t *options,
		const char *key,
		const char *value)
{
  _wsmc_add_key_value(&(options->selectors), key, value, NULL, false);
}

void
wsmc_add_selector_epr(client_opt_t *options,
		const char *key,
		const epr_t *value)
{
  _wsmc_add_key_value(&(options->selectors), key, NULL, value, false);
}

static void
_wsmc_add_uri_to_list(list_t **list_ptr, const char *query_string)
{
  hash_t *query;
  if (!query_string || !list_ptr)
    return;
  
  query = u_parse_query(query_string);
  if (query) {
    /* convert query hash to property list */
    hscan_t hs;
    hnode_t *hn;
    list_t *list = *list_ptr;
    _wsmc_kvl_destroy(list);
    *list_ptr = NULL;
    hash_scan_begin(&hs, query);
    while ((hn = hash_scan_next(&hs))) {
      _wsmc_add_key_value(list_ptr,
                          (char *)hnode_getkey(hn),
                          (char *)hnode_get(hn),
                          NULL, false);
    }
    hash_free(query);
  }
}

void
wsmc_add_selectors_from_str(client_opt_t * options,
		const char *query_string)
{
  _wsmc_add_uri_to_list(&(options->selectors), query_string);
}

void
wsmc_add_prop_from_str(client_opt_t * options,
		const char *query_string)
{
  _wsmc_add_uri_to_list(&(options->properties), query_string);
}

void
wsmc_add_selector_from_options(WsXmlDocH doc, client_opt_t *options)
{
	WsXmlNodeH      header;
	lnode_t        *node;
	if (!options->selectors || list_count(options->selectors) == 0)
		return;
	header = ws_xml_get_soap_header(doc);
	if (header == NULL) {
		return;
	}
        node = list_first(options->selectors);
  	while (node) {
          key_value_t *kv;
          kv = (key_value_t *)node->list_data;
          if (kv->type == 0) {
            wsman_add_selector(header, kv->key, kv->v.text);
          }
          else {
            wsman_add_selector_epr(header, kv->key, kv->v.epr);
          }
          node = list_next(options->selectors, node);
	}
}

void
wsmc_set_selectors_from_uri(const char *resource_uri, client_opt_t * options)
{
  if (options->selectors) {
    list_destroy_nodes(options->selectors);
    list_destroy(options->selectors);
    options->selectors = NULL;
  }
  u_uri_t *uri = u_malloc(sizeof(u_uri_t));
  u_uri_parse(resource_uri, &uri);
  wsmc_add_selectors_from_str(options, uri->query);
  u_uri_free(uri);
}

/* Err: should be wsmc_set_selectors_from_uri() */
void
wsmc_set_options_from_uri(const char *resource_uri, client_opt_t * options)
{
  error("Call to deprecated 'wsmc_set_options_from_uri', use 'wsmc_set_selectors_from_uri' instead");
  wsmc_set_selectors_from_uri(resource_uri, options);
}

void
wsmc_set_delivery_uri(const char *delivery_uri, client_opt_t * options)
{
  u_free(options->delivery_uri);
  options->delivery_uri = delivery_uri ? u_strdup(delivery_uri) : NULL;
}

void
wsmc_set_cim_ns(const char *ns, client_opt_t * options)
{
  u_free(options->cim_ns);
  options->cim_ns = ns ? u_strdup(ns) : NULL;
}

void
wsmc_set_fragment(const char *fragment, client_opt_t * options)
{
  u_free(options->fragment);
  options->fragment = fragment ? u_strdup(fragment) : NULL;
}

void
wsmc_set_reference(const char *reference, client_opt_t * options)
{
  u_free(options->reference);
  options->reference = reference ? u_strdup(reference) : NULL;
}

void
wsmc_set_sub_expiry(int event_subscription_expire, client_opt_t * options)
{
	options->expires = event_subscription_expire;
}

void
wsmc_set_heartbeat_interval(int heartbeat_interval, client_opt_t * options)
{
	options->heartbeat_interval = heartbeat_interval;
}

void
wsmc_set_delivery_mode(WsmanDeliveryMode delivery_mode, client_opt_t * options)
{
	options->delivery_mode = delivery_mode;
}

void
wsmc_set_delivery_security_mode(WsManDeliverySecurityMode delivery_sec_mode, client_opt_t * options)
{
        options->delivery_sec_mode = delivery_sec_mode;
}

void
wsmc_set_locale(client_opt_t * options, const char *locale)
{
  u_free(options->locale);
  options->locale = locale ? u_strdup(locale) : NULL;
}

char *
wsmc_get_locale(client_opt_t * options)
{
  return options->locale;
}

void
wsmc_add_selector_from_uri(WsXmlDocH doc,
		const char *resource_uri)
{
	u_uri_t        *uri = NULL;
	WsXmlNodeH      header = ws_xml_get_soap_header(doc);
	hash_t         *query;
	hnode_t        *hn;
	hscan_t         hs;

	if (header == NULL) {
		return;
	}
	if (resource_uri == NULL) {
		return;
	}
	if (u_uri_parse((const char *) resource_uri, &uri) != 0) {
		return;
	} else if (!uri->query) {
		goto cleanup;
	}

	query = u_parse_query(uri->query);
	if (query == NULL) {
		goto cleanup;
	}
	hash_scan_begin(&hs, query);
	while ((hn = hash_scan_next(&hs))) {
		wsman_add_selector(header,
				(char *) hnode_getkey(hn),
				(char *) hnode_get(hn));
		debug("key=%s value=%s", (char *) hnode_getkey(hn),
				(char *) hnode_get(hn));
	}
	hash_free_nodes(query);
	hash_destroy(query);
cleanup:
	if (uri) {
		u_uri_free(uri);
	}
}


static char*
wsmc_create_action_str(WsmanAction action)
{
	char           *action_str = NULL;

	switch (action) {
	case WSMAN_ACTION_ASSOCIATORS:
	case WSMAN_ACTION_REFERENCES:
	case WSMAN_ACTION_ENUMERATION:
		action_str = wsman_make_action(XML_NS_ENUMERATION, WSENUM_ENUMERATE);
		break;
	case WSMAN_ACTION_PULL:
		action_str = wsman_make_action(XML_NS_ENUMERATION, WSENUM_PULL);
		break;
	case WSMAN_ACTION_RELEASE:
		action_str = wsman_make_action(XML_NS_ENUMERATION, WSENUM_RELEASE);
		break;
	case WSMAN_ACTION_TRANSFER_CREATE:
		action_str = wsman_make_action(XML_NS_TRANSFER, TRANSFER_CREATE);
		break;
	case WSMAN_ACTION_TRANSFER_DELETE:
		action_str = wsman_make_action(XML_NS_TRANSFER, TRANSFER_DELETE);
		break;
	case WSMAN_ACTION_TRANSFER_GET:
		action_str = wsman_make_action(XML_NS_TRANSFER, TRANSFER_GET);
		break;
	case WSMAN_ACTION_TRANSFER_PUT:
		action_str = wsman_make_action(XML_NS_TRANSFER, TRANSFER_PUT);
		break;
	case WSMAN_ACTION_SUBSCRIBE:
		action_str = wsman_make_action(XML_NS_EVENTING, WSEVENT_SUBSCRIBE);
		break;
	case WSMAN_ACTION_UNSUBSCRIBE:
		action_str = wsman_make_action(XML_NS_EVENTING, WSEVENT_UNSUBSCRIBE);
		break;
	case WSMAN_ACTION_RENEW:
		action_str = wsman_make_action(XML_NS_EVENTING, WSEVENT_RENEW);
		break;
	case WSMAN_ACTION_NONE:
	case WSMAN_ACTION_IDENTIFY:
	case WSMAN_ACTION_ANON_IDENTIFY:
	case WSMAN_ACTION_TEST:
	case WSMAN_ACTION_CUSTOM:
		break;
	}
	return action_str;
}

static char *
wsmc_create_delivery_mode_str(WsmanDeliveryMode mode)
{
	char * str = NULL;
	switch(mode) {
		case WSMAN_DELIVERY_PUSH:
			str = u_strdup(WSEVENT_DELIVERY_MODE_PUSH);
			break;
		case WSMAN_DELIVERY_PUSHWITHACK:
			str = u_strdup(WSEVENT_DELIVERY_MODE_PUSHWITHACK);
			break;
		case WSMAN_DELIVERY_EVENTS:
			str = u_strdup(WSEVENT_DELIVERY_MODE_EVENTS);
			break;
		case WSMAN_DELIVERY_PULL:
			str = u_strdup(WSEVENT_DELIVERY_MODE_PULL);
	}
	return str;
}

static char *
wsmc_create_delivery_sec_mode_str(WsManDeliverySecurityMode mode)
{
	char * str = NULL;
	switch(mode) {
		case WSMAN_DELIVERY_SEC_HTTP_BASIC:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTP_BASIC);
			break;
		case WSMAN_DELIVERY_SEC_HTTP_DIGEST:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTP_DIGEST);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_BASIC:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_BASIC);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_DIGEST:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_DIGEST);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_MUTUAL:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_MUTUAL_BASIC:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_BASIC);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_MUTUAL_DIGEST:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_DIGEST);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_SPNEGO_KERBEROS:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_SPNEGO_KERBEROS);
			break;
		case WSMAN_DELIVERY_SEC_HTTPS_MUTUAL_SPNEGO_KERBEROS:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTPS_MUTUAL_SPNEGO_KERBEROS);
			break;
		case WSMAN_DELIVERY_SEC_HTTP_SPNEGO_KERBEROS:
			str = u_strdup(WSMAN_SECURITY_PROFILE_HTTP_SPNEGO_KERBEROS);
			break;
		default:
			break;
	}
	return str;
}

static void
wsman_set_enumeration_options(WsManClient * cl, WsXmlNodeH body, const char* resource_uri,
			client_opt_t *options, filter_t *filter)
{
	WsXmlNodeH node = ws_xml_get_child(body, 0, NULL, NULL);
	if (node == NULL) {
		return;
	}
	if ((options->flags & FLAG_ENUMERATION_OPTIMIZATION) ==
			FLAG_ENUMERATION_OPTIMIZATION) {
		ws_xml_add_child(node, XML_NS_WS_MAN, WSM_OPTIMIZE_ENUM, NULL);
	}

	if ((options->flags & FLAG_ENUMERATION_ENUM_EPR) ==
			FLAG_ENUMERATION_ENUM_EPR) {
		ws_xml_add_child(node, XML_NS_WS_MAN, WSM_ENUM_MODE, WSM_ENUM_EPR);
	} else if ((options->flags & FLAG_ENUMERATION_ENUM_OBJ_AND_EPR) ==
			FLAG_ENUMERATION_ENUM_OBJ_AND_EPR) {
		ws_xml_add_child(node, XML_NS_WS_MAN, WSM_ENUM_MODE,
				WSM_ENUM_OBJ_AND_EPR);
	}

	// Polymorphism
	if ((options->flags & FLAG_IncludeSubClassProperties)
			== FLAG_IncludeSubClassProperties) {
		ws_xml_add_child(node, XML_NS_CIM_BINDING,
				WSMB_POLYMORPHISM_MODE, WSMB_INCLUDE_SUBCLASS_PROP);
	} else if ((options->flags & FLAG_ExcludeSubClassProperties) ==
			FLAG_ExcludeSubClassProperties) {
		ws_xml_add_child(node, XML_NS_CIM_BINDING,
				WSMB_POLYMORPHISM_MODE, WSMB_EXCLUDE_SUBCLASS_PROP);
	} else if ((options->flags & FLAG_POLYMORPHISM_NONE)
			== FLAG_POLYMORPHISM_NONE) {
		ws_xml_add_child(node, XML_NS_CIM_BINDING,
				WSMB_POLYMORPHISM_MODE, "None");
	}

	if (filter != NULL) {
		filter_serialize(node, filter, XML_NS_WS_MAN);
	}
	return;
}

static void
wsman_set_subscribe_options(WsManClient * cl,
			WsXmlDocH request,
			const char* resource_uri,
			client_opt_t *options,
			filter_t *filter)
{
	WsXmlNodeH body = ws_xml_get_soap_body(request);
	WsXmlNodeH header = ws_xml_get_soap_header(request);
	WsXmlNodeH node = NULL, temp = NULL, node2 = NULL, node3 = NULL;
	char buf[32];

	if (header == NULL || body == NULL) {
		return;
	}
	if(options->delivery_certificatethumbprint ||options->delivery_password ||
		options->delivery_password) {
		node = ws_xml_add_child(header, XML_NS_TRUST, WST_ISSUEDTOKENS, NULL);
		if (node == NULL) {
			return;
		}
		ws_xml_add_node_attr(node, XML_NS_SOAP_1_2, SOAP_MUST_UNDERSTAND, "true");
		if(options->delivery_certificatethumbprint) {
			if (node == NULL) {
				return;
			}
			node2 = ws_xml_add_child(node, XML_NS_TRUST, WST_REQUESTSECURITYTOKENRESPONSE, NULL);
			if (node2 == NULL) {
				return;
			}
			ws_xml_add_child(node2, XML_NS_TRUST, WST_TOKENTYPE,WST_CERTIFICATETHUMBPRINT );
			node3 = ws_xml_add_child(node2, XML_NS_TRUST, WST_REQUESTEDSECURITYTOKEN, NULL);
			if (node3 == NULL) {
				return;
			}
			ws_xml_add_child(node3, XML_NS_WS_MAN, WSM_CERTIFICATETHUMBPRINT,
				options->delivery_certificatethumbprint);
			node3 = ws_xml_add_child(node2, XML_NS_POLICY, WSP_APPLIESTO, NULL);
			if (node3 == NULL) {
				return;
			}
			node3 = ws_xml_add_child(node3, XML_NS_ADDRESSING, WSA_EPR, NULL);
			if (node3 == NULL) {
				return;
			}
			ws_xml_add_child(node3, XML_NS_ADDRESSING, WSA_ADDRESS, options->delivery_uri);
		}
		if(options->delivery_username || options->delivery_password) {
			node2 = ws_xml_add_child(node, XML_NS_TRUST, WST_REQUESTSECURITYTOKENRESPONSE, NULL);
			if (node2 == NULL) {
				return;
			}
			ws_xml_add_child(node2, XML_NS_TRUST, WST_TOKENTYPE,WST_USERNAMETOKEN);
			node3 = ws_xml_add_child(node2, XML_NS_TRUST, WST_REQUESTEDSECURITYTOKEN, NULL);
			if (node3 == NULL) {
				return;
			}
			node3 = ws_xml_add_child(node3, XML_NS_SE, WSSE_USERNAMETOKEN, NULL);
			if (options->delivery_username) {
				if (node3 == NULL) {
					return;
				}
				ws_xml_add_child(node3, XML_NS_SE, WSSE_USERNAME, options->delivery_username);
			}
			if (options->delivery_password) {
				if (node3 == NULL) {
					return;
				}
				ws_xml_add_child(node3, XML_NS_SE, WSSE_PASSWORD, options->delivery_password);
			}
			node3 = ws_xml_add_child(node2, XML_NS_POLICY, WSP_APPLIESTO, NULL);
			if (node3 == NULL) {
				return;
			}
			node3 = ws_xml_add_child(node3, XML_NS_ADDRESSING, WSA_EPR, NULL);
			if (node3 == NULL) {
				return;
			}
			ws_xml_add_child(node3, XML_NS_ADDRESSING, WSA_ADDRESS, options->delivery_uri);
		}
	}
	node = ws_xml_add_child(body,
				XML_NS_EVENTING, WSEVENT_SUBSCRIBE,NULL);
	if (node == NULL) {
		return;
	}
	temp = ws_xml_add_child(node, XML_NS_EVENTING, WSEVENT_DELIVERY, NULL);
	if(temp) {
		char *mode = wsmc_create_delivery_mode_str(options->delivery_mode);
		ws_xml_add_node_attr(temp, NULL, WSEVENT_DELIVERY_MODE, mode);
		u_free(mode);
		if(options->delivery_uri) {
			node2 = ws_xml_add_child(temp, XML_NS_EVENTING, WSEVENT_NOTIFY_TO, NULL);
			if (node2 == NULL) {
				return;
			}
			ws_xml_add_child(node2, XML_NS_ADDRESSING, WSA_ADDRESS, options->delivery_uri);
		}
		if(options->delivery_sec_mode) {
			temp = ws_xml_add_child(temp, XML_NS_WS_MAN, WSM_AUTH, NULL);
			if (temp == NULL) {
				return;
			}
			char *mode = wsmc_create_delivery_sec_mode_str(options->delivery_sec_mode);
			ws_xml_add_node_attr(temp, NULL, WSM_PROFILE, mode);
			u_free(mode);
		}
		if(options->heartbeat_interval) {
			snprintf(buf, 32, "PT%fS", options->heartbeat_interval);
			ws_xml_add_child(temp, XML_NS_WS_MAN, WSM_HEARTBEATS, buf);
		}
		if(options->reference) {
			WsXmlDocH doc = ws_xml_read_memory( options->reference, strlen(options->reference), "UTF-8", 0);
			node3 = ws_xml_get_doc_root(doc);
			temp = ws_xml_add_child(node2, XML_NS_ADDRESSING, WSA_REFERENCE_PROPERTIES, NULL);
			if(temp)
				ws_xml_duplicate_tree(temp, node3);
		}
	}
	if (options->expires) {
		snprintf(buf, 32, "PT%fS", options->expires);
		ws_xml_add_child(node, XML_NS_EVENTING, WSEVENT_EXPIRES, buf);
	}
	if (filter) {
		filter_serialize(node, filter, XML_NS_WS_MAN);
	}
	if (options->flags & FLAG_EVENT_SENDBOOKMARK) {
		ws_xml_add_child(node, XML_NS_WS_MAN, WSM_SENDBOOKMARKS, NULL);
	}
}

static void
wsmc_set_put_prop(WsXmlDocH get_response,
		WsXmlDocH put_request,
		client_opt_t *options)
{
	WsXmlNodeH      resource_node;
	char           *ns_uri;
	WsXmlNodeH      get_body = ws_xml_get_soap_body(get_response);
	WsXmlNodeH      put_body = ws_xml_get_soap_body(put_request);

	ws_xml_copy_node(ws_xml_get_child(get_body, 0, NULL, NULL), put_body);
	resource_node = ws_xml_get_child(put_body, 0, NULL, NULL);
	ns_uri = ws_xml_get_node_name_ns_uri(resource_node);

	if (!list_isempty(options->properties)) {
		lnode_t *node = list_first(options->properties);
		while (node) {
			key_value_t *property = (key_value_t *)node->list_data;
			WsXmlNodeH n = ws_xml_get_child(resource_node, 0, ns_uri, property->key);
			if (n != NULL) {
				if (property->type == 0) {
					ws_xml_set_node_text(n, property->v.text);
				}
				else {
					epr_serialize(n, ns_uri, property->key, property->v.epr, 1);
				}
			}
			node = list_next(options->properties, node);
		}
	}
}


void
wsmc_node_to_buf(WsXmlNodeH node, char **buf) {
	int   len;
	WsXmlDocH doc = ws_xml_create_doc_by_import( node);
	ws_xml_dump_memory_enc(doc, buf, &len, "UTF-8");
	ws_xml_destroy_doc(doc);
	return;
}


char*
wsmc_node_to_formatbuf(WsXmlNodeH node) {
	char *buf;
	int   len;
	WsXmlDocH doc = ws_xml_create_doc_by_import( node);
	ws_xml_dump_memory_node_tree(ws_xml_get_doc_root(doc), &buf, &len);
	ws_xml_destroy_doc(doc);
	return buf;
}


static void
add_subscription_context(WsXmlNodeH node, char *context)
{
	WsXmlNodeH subsnode;
	WsXmlDocH doc = ws_xml_read_memory(context, strlen(context), "UTF-8", 0);
	if(doc == NULL) return;
	subsnode = ws_xml_get_doc_root(doc);
	ws_xml_duplicate_children(node, subsnode);
}

WsXmlDocH
wsmc_create_request(WsManClient * cl, const char *resource_uri,
		client_opt_t *options, filter_t *filter,
		WsmanAction action, char *method, void *data)
{
	WsXmlDocH       request;
	WsXmlNodeH      body;
	WsXmlNodeH      header;
	WsXmlNodeH      node;
	char           *_action = NULL;
	if (action == WSMAN_ACTION_IDENTIFY) {
		request = ws_xml_create_envelope();
	} else {
		if (method) {
		        /* WSA_ACTION is a URI */
			if (strchr(method, '/'))
				_action = u_strdup(method);
			else /* 'invoke' action */
				_action = wsman_make_action((char *)resource_uri, method);
		} else {
			_action = wsmc_create_action_str(action);
		}
		if (options && _action) {
			request = wsmc_build_envelope(cl->serctx, _action,
					WSA_TO_ANONYMOUS, (char *)resource_uri,
					cl->data.endpoint, options);
		} else {
			u_free(_action);
			return NULL;
		}
		u_free(_action);
	}

	body = ws_xml_get_soap_body(request);
	header = ws_xml_get_soap_header(request);
	if (!body  || !header )
		return NULL;
	/*
	 * flags to be passed as <w:OptionSet ...> <w:Option Name="..." ...> >
	 */
	if (options) {
	  WsXmlNodeH opset = NULL;
	  if (options->flags & (FLAG_CIM_EXTENSIONS|FLAG_EXCLUDE_NIL_PROPS)) {
	    /* need WSM_OPTION_SET */
		opset = ws_xml_add_child(header,
				XML_NS_WS_MAN, WSM_OPTION_SET, NULL);
		if (opset == NULL) {
		  return NULL;
		}
		if ((options->flags & FLAG_CIM_EXTENSIONS) == FLAG_CIM_EXTENSIONS) {
			WsXmlNodeH op = ws_xml_add_child(opset,
				XML_NS_WS_MAN, WSM_OPTION, NULL);
			ws_xml_add_node_attr(op, NULL, WSM_NAME, WSMB_SHOW_EXTENSION);
		}
		if ((options->flags & FLAG_EXCLUDE_NIL_PROPS) == FLAG_EXCLUDE_NIL_PROPS) {
			/* ExcludeNilProperties is non-standard, so put it under an openwsman namespace */
			WsXmlNodeH op = ws_xml_add_child(opset,
				XML_NS_OPENWSMAN, WSM_OPTION, NULL);
			ws_xml_add_node_attr(op, NULL, WSM_NAME, WSMB_EXCLUDE_NIL_PROPS);
		}
	  }
	  if (options->options && hash_count(options->options) > 0) {
	    hnode_t *hn;
	    hscan_t hs;
	    hash_scan_begin(&hs, options->options);
	    if (!opset) {
	      opset = ws_xml_add_child(header,
				       XML_NS_WS_MAN, WSM_OPTION_SET, NULL);
	    }
	    while ((hn = hash_scan_next(&hs))) {
		  if (opset == NULL) {
			  return NULL;
		  }
	      WsXmlNodeH op = ws_xml_add_child(opset,
					       XML_NS_WS_MAN, WSM_OPTION, NULL);
	      ws_xml_add_node_attr(op, NULL, WSM_NAME, (char *) hnode_getkey(hn));
	      ws_xml_set_node_text(op, (char *) hnode_get(hn));
	    }
	  }
	}


	switch (action) {
	case WSMAN_ACTION_IDENTIFY:
	case WSMAN_ACTION_ANON_IDENTIFY:
		ws_xml_add_child(body,
				XML_NS_WSMAN_ID, WSMID_IDENTIFY, NULL);
		break;
	case WSMAN_ACTION_CUSTOM:
		break;
	case WSMAN_ACTION_ENUMERATION:
	case WSMAN_ACTION_ASSOCIATORS:
	case WSMAN_ACTION_REFERENCES:
		node = ws_xml_add_child(body,
				XML_NS_ENUMERATION, WSENUM_ENUMERATE, NULL);
		if (options) {
			wsman_set_enumeration_options(cl, body, resource_uri, options, filter);
		}
		break;
	case WSMAN_ACTION_PULL:
		node = ws_xml_add_child(body,
				XML_NS_ENUMERATION, WSENUM_PULL, NULL);
		if (node == NULL) {
		  return NULL;
		}
		if (data) {
			ws_xml_add_child(node, XML_NS_ENUMERATION,
					WSENUM_ENUMERATION_CONTEXT, (char *) data);
		}
		break;
	case WSMAN_ACTION_RELEASE:
		node = ws_xml_add_child(body,
				XML_NS_ENUMERATION, WSENUM_RELEASE, NULL);
		if (node == NULL) {
		  return NULL;
		}
		if (data) {
			ws_xml_add_child(node, XML_NS_ENUMERATION,
					WSENUM_ENUMERATION_CONTEXT, (char *) data);
		}
		break;
	case WSMAN_ACTION_SUBSCRIBE:
		if (options) {
			wsman_set_subscribe_options(cl, request, resource_uri, options, filter);
		}
		break;
	case WSMAN_ACTION_UNSUBSCRIBE:
		node = ws_xml_add_child(body,
				XML_NS_EVENTING, WSEVENT_UNSUBSCRIBE,NULL);
		if(data) {
			if(((char *)data)[0] != 0)
				add_subscription_context(ws_xml_get_soap_header(request), (char *)data);
		}
		break;
	case WSMAN_ACTION_RENEW:
          {
                char buf[20];
		node = ws_xml_add_child(body,
				XML_NS_EVENTING, WSEVENT_RENEW, NULL);
		if (node == NULL) {
			return NULL;
		}
                /* %f default precision is 6 -> [-]ddd.ddd */
		snprintf(buf, 20, "PT%fS", (options) ? options->expires : 0);
		ws_xml_add_child(node, XML_NS_EVENTING, WSEVENT_EXPIRES, buf);
		if(data) {
			if(((char *)data)[0] != 0)
				add_subscription_context(ws_xml_get_soap_header(request), (char *)data);
		}
          }
		break;
	case WSMAN_ACTION_NONE:
	case WSMAN_ACTION_TRANSFER_CREATE:
	case WSMAN_ACTION_TEST:
	case WSMAN_ACTION_TRANSFER_GET:
	case WSMAN_ACTION_TRANSFER_PUT:
	case WSMAN_ACTION_TRANSFER_DELETE:
		break;
	}

	if (action == WSMAN_ACTION_PULL || action == WSMAN_ACTION_ENUMERATION) {
		if (options && options->max_elements > 0 ) {
			node = ws_xml_get_child(body, 0, NULL, NULL);
			if (action == WSMAN_ACTION_ENUMERATION) {
				if ((options->flags & FLAG_ENUMERATION_OPTIMIZATION) ==
					FLAG_ENUMERATION_OPTIMIZATION ) {
						if (node == NULL) {
							return NULL;
						}
						/* wsman:MaxElements is for Enumerate */
						ws_xml_add_child_format(node, XML_NS_WS_MAN,
									WSENUM_MAX_ELEMENTS, "%d", options->max_elements);
				}
		         } else {
				if (node == NULL) {
					return NULL;
				}
				/* wsen:MaxElements is for Pull */
				ws_xml_add_child_format(node, XML_NS_ENUMERATION,
						WSENUM_MAX_ELEMENTS, "%d", options->max_elements);
			}
		}
		if (options && (options->flags & FLAG_ENUMERATION_COUNT_ESTIMATION) ==
				FLAG_ENUMERATION_COUNT_ESTIMATION) {
			ws_xml_add_child(header, XML_NS_WS_MAN, WSM_REQUEST_TOTAL, NULL);
		}
	}
	if (action != WSMAN_ACTION_TRANSFER_CREATE &&
			action != WSMAN_ACTION_TRANSFER_PUT &&
			action != WSMAN_ACTION_CUSTOM) {
		if (options && (options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) {
			ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request));
		}
	}
	return request;
}



static void
handle_resource_request(WsManClient * cl, WsXmlDocH request,
		void *data,
		void *typeInfo,
		char *resource_uri)
{
	if (data && typeInfo) {
		char           *class = u_strdup(strrchr(resource_uri, '/') + 1);
		ws_serialize(cl->serctx, ws_xml_get_soap_body(request),
				data, (XmlSerializerInfo *) typeInfo,
				class, resource_uri, NULL, 1);
		ws_serializer_free_mem(cl->serctx, data,
				(XmlSerializerInfo *) typeInfo);
		u_free(class);
	} else if (data != NULL) {
		if (wsman_is_valid_xml_envelope((WsXmlDocH) data)) {
			WsXmlNodeH      body = ws_xml_get_soap_body((WsXmlDocH) data);
			ws_xml_duplicate_tree(ws_xml_get_soap_body(request),
					ws_xml_get_child(body, 0, NULL, NULL));
		} else {
			ws_xml_duplicate_tree(ws_xml_get_soap_body(request),
					ws_xml_get_doc_root((WsXmlDocH) data));
		}
	}
}


static          WsXmlDocH
_wsmc_action_create(WsManClient * cl,
		char *resource_uri,
		void *data,
		void *typeInfo,
		client_opt_t *options)
{
	WsXmlDocH response;
	WsXmlDocH request = wsmc_create_request(cl, (char *)resource_uri, options, NULL,
			WSMAN_ACTION_TRANSFER_CREATE, NULL, NULL);
	if (!request)
		return NULL;

	handle_resource_request(cl, request, data, typeInfo, (char *)resource_uri);

	if ((options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) {
		ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request));
	}
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}

WsXmlDocH
wsmc_action_create(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		WsXmlDocH source_doc)
{

	return _wsmc_action_create(cl, (char *)resource_uri,
			source_doc, NULL, options);
}


WsXmlDocH
wsmc_action_create_fromtext(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		const char *data, size_t size, const char *encoding)
{
	WsXmlDocH source_doc = wsmc_read_memory( (char *)data, size,
			(char *)encoding, 0);
	WsXmlDocH response;
	if (source_doc == NULL) {
		error("could not convert XML text to doc");
		return NULL;
	}

	response = _wsmc_action_create(cl, (char *)resource_uri,
			source_doc, NULL, options);
	ws_xml_destroy_doc(source_doc);
	return response;
}

WsXmlDocH
wsmc_action_create_serialized(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		void *data,
		void *typeInfo)
{
	return _wsmc_action_create(cl, (char *)resource_uri, data, typeInfo, options);
}


static WsXmlDocH
_wsmc_action_put(WsManClient * cl,
		char *resource_uri,
		void *data,
		void *typeInfo,
		client_opt_t *options)
{
	WsXmlDocH response;
	WsXmlDocH request = wsmc_create_request(cl, resource_uri, options, NULL,
			WSMAN_ACTION_TRANSFER_PUT, NULL, NULL);
	if (!request)
		return NULL;

	handle_resource_request(cl, request, data, typeInfo, resource_uri);
	if ((options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) {
		ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request));
	}
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}

WsXmlDocH
wsmc_action_put(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		WsXmlDocH source_doc)
{
	return _wsmc_action_put(cl, (char *)resource_uri, source_doc, NULL, options);
}


WsXmlDocH
wsmc_action_put_fromtext(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		const char *data, size_t size, const char *encoding)
{
	WsXmlDocH source_doc = wsmc_read_memory( (char *)data, size,
			(char *)encoding, 0);
	WsXmlDocH response;
	if (source_doc == NULL) {
		error("could not convert XML text to doc");
		return NULL;
	}
	response =  _wsmc_action_put(cl, (char *)resource_uri, source_doc, NULL, options);
	ws_xml_destroy_doc(source_doc);
	return response;
}


WsXmlDocH
wsmc_action_put_serialized(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		void *data,
		void *typeInfo)
{
	return _wsmc_action_put(cl, (char *)resource_uri, data, typeInfo, options);
}

WsXmlDocH
wsmc_action_delete(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options)
{

	WsXmlDocH response;
	WsXmlDocH request = wsmc_create_request(cl, resource_uri, options, NULL,
				WSMAN_ACTION_TRANSFER_DELETE, NULL, NULL);
	if (!request)
		return NULL;

	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}

static int add_selectors_from_epr(void *options, const key_value_t *kv)
{
	client_opt_t *op = (client_opt_t *)options;
        if (kv->type == 0)
	  wsmc_add_selector(op, kv->key, kv->v.text);
        else
	  wsmc_add_selector_epr(op, kv->key, kv->v.epr);
	return 0;
}

WsXmlDocH
wsmc_action_delete_from_epr(WsManClient *cl, epr_t *epr,
		client_opt_t *options)
{
	char *resource_uri = epr_get_resource_uri(epr);
	wsman_epr_selector_cb(epr, add_selectors_from_epr, options);
	return wsmc_action_delete(cl, resource_uri, options);
}

WsXmlDocH
wsmc_action_get_from_epr(WsManClient *cl, epr_t *epr,
		client_opt_t *options)
{
	char *resource_uri = epr_get_resource_uri(epr);
	wsman_epr_selector_cb(epr, add_selectors_from_epr, options);
	return wsmc_action_get(cl, resource_uri, options);
}

WsXmlDocH
wsmc_action_get(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options)
{
	WsXmlDocH       response;
	WsXmlDocH       request = wsmc_create_request(cl, resource_uri, options, NULL,
			WSMAN_ACTION_TRANSFER_GET, NULL, NULL);
	if (!request)
		return NULL;
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}


WsXmlDocH
wsmc_action_get_and_put(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options)
{
	WsXmlDocH       put_request;
	WsXmlDocH       put_response;
	WsXmlDocH       get_response = wsmc_action_get(cl, resource_uri, options);

	if (!get_response) {
		error("wsmc_action_get returned NULL doc");
		return NULL;
	}
	if (wsman_is_fault_envelope(get_response)) {
		return get_response;
	}
	put_request = wsmc_create_request(cl, resource_uri, options, NULL,
			WSMAN_ACTION_TRANSFER_PUT, NULL, (void *) get_response);
	if (!put_request)
		return NULL;

	wsmc_set_put_prop(get_response, put_request, options);
	//ws_xml_destroy_doc(get_response);
	if (wsman_send_request(cl, put_request)) {
		ws_xml_destroy_doc(put_request);
		return NULL;
	}
	put_response = wsmc_build_envelope_from_response(cl);

	//ws_xml_destroy_doc(put_request);
	return put_response;
}




WsXmlDocH
wsmc_action_invoke(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		const char *method,
		WsXmlDocH data)
{
	WsXmlDocH       response;
	WsXmlNodeH body = NULL;
        WsXmlDocH       request = wsmc_create_request(cl, resource_uri, options, NULL,
                WSMAN_ACTION_CUSTOM, (char *)method, NULL);
	if (!request)
		return NULL;

	body = ws_xml_get_soap_body(request);
	if (body == NULL) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	if (list_isempty(options->properties) &&
                data != NULL) {

		WsXmlNodeH n = ws_xml_get_doc_root(data);
		ws_xml_duplicate_tree(ws_xml_get_soap_body(request), n);
        } else if (!list_isempty(options->properties)) {
            if (method) {
              WsXmlNodeH xnode = ws_xml_add_empty_child_format(body,
                                  (char *)resource_uri, "%s_INPUT", method);
              if (xnode == NULL) {
                  return NULL;
              }
              lnode_t *lnode = list_first(options->properties);
              while (lnode) {
                key_value_t *property = (key_value_t *)lnode->list_data;
                if (property->type == 0) {
                  ws_xml_add_child(xnode, (char *)resource_uri, (char *)property->key, (char *)property->v.text);
                }
                else {
                  epr_serialize(xnode, (char *)resource_uri, property->key, property->v.epr, 1);
                }
                lnode = list_next(options->properties, lnode);
              }
            }
        } else if (!strchr(method, '/')) { /* non-custom method without parameters */
            ws_xml_add_empty_child_format(body,
                    (char *)resource_uri, "%s_INPUT", method);
        } else {
	  /* empty body */
	}
	if ((options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) {
		ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request));
	}

	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}


WsXmlDocH
wsmc_action_invoke_fromtext(WsManClient * cl,
		const char *resourceUri,
		client_opt_t *options,
		const char *method,
		const char *data,
                size_t size,
                const char *encoding)
{
	WsXmlDocH       response;
        WsXmlDocH request = wsmc_create_request(cl, resourceUri, options, NULL,
						  WSMAN_ACTION_CUSTOM,
						  (char *)method, NULL);
	if (request == NULL) {
		error("could not create request");
		return NULL;
	}
	if ( data != NULL) {
		WsXmlDocH doc = wsmc_read_memory(
				(char *)data, size, (char *)encoding, 0);
		WsXmlNodeH n;
		if (doc == NULL) {
			error("could not wsmc_read_memory");
			ws_xml_destroy_doc(request);
			return NULL;
		}
		n = ws_xml_get_doc_root(doc);
		ws_xml_duplicate_tree(ws_xml_get_soap_body(request), n);
		ws_xml_destroy_doc(doc);
	} else {
            warning("No XML provided");
        }
	if ((options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) {
		ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request));
	}


	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}



WsXmlDocH
wsmc_action_invoke_serialized(WsManClient * cl,
		const char *resourceUri,
		client_opt_t *options,
		const char *method,
		void *typeInfo, void *data)
{
	WsXmlDocH       response;
	WsXmlDocH       request = wsmc_create_request(cl, resourceUri, options, NULL,
			WSMAN_ACTION_CUSTOM, (char *)method, NULL);
	if (request == NULL) {
		error("could not create request");
		return NULL;
	}
	if (data != NULL) {
		handle_resource_request(cl, request, data, typeInfo, (char *)resourceUri);
	}
	if ((options->flags & FLAG_DUMP_REQUEST) == FLAG_DUMP_REQUEST) {
		ws_xml_dump_node_tree(cl->dumpfile, ws_xml_get_doc_root(request));
	}


	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}


WsXmlDocH
wsmc_action_identify(WsManClient * cl,
		client_opt_t *options)
{
	WsXmlDocH       response;
	WsXmlDocH       request = wsmc_create_request(cl, NULL, options, NULL,
			WSMAN_ACTION_IDENTIFY, NULL, NULL);
	if (!request)
		return NULL;
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}


int
wsmc_action_enumerate_and_pull(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		filter_t *filter,
		SoapResponseCallback callback,
		void *callback_data)
{
	WsXmlDocH doc;
	char *enumContext = NULL;
	WsXmlDocH enum_response = wsmc_action_enumerate(cl,
			resource_uri, options, filter);

	if (enum_response) {
		long rc = wsmc_get_response_code(cl);
		if (rc == 200 || rc == 400 || rc == 500) {
			callback(cl, enum_response, callback_data);
		} else {
			return 0;
		}
		enumContext = wsmc_get_enum_context(enum_response);
		ws_xml_destroy_doc(enum_response);
	} else {
		return 0;
	}

	while (enumContext != NULL && enumContext[0] != 0) {
		long rc = wsmc_get_response_code(cl);
		doc = wsmc_action_pull(cl, resource_uri, options, filter, enumContext);

		if (rc != 200 && rc != 400 && rc != 500) {
			wsmc_free_enum_context(enumContext);
			return 0;
		}
		callback(cl, doc, callback_data);
		wsmc_free_enum_context(enumContext);
		enumContext = wsmc_get_enum_context(doc);
		if (doc) {
			ws_xml_destroy_doc(doc);
		}
	}
	wsmc_free_enum_context(enumContext);
	return 1;
}




WsXmlDocH
wsmc_action_enumerate(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		filter_t *filter)
{
	WsXmlDocH response;
	WsXmlDocH request = wsmc_create_request(cl,
					resource_uri, options, filter,
					WSMAN_ACTION_ENUMERATION, NULL, NULL);
	if (!request)
		return NULL;
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}


WsXmlDocH
wsmc_action_pull(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		filter_t *filter,
		const char *enumContext)
{
	WsXmlDocH       response;
	WsXmlNodeH      node;

	if (enumContext || (enumContext && enumContext[0] == 0)) {
		WsXmlDocH request = wsmc_create_request(cl, resource_uri, options, filter,
				WSMAN_ACTION_PULL,	NULL, (char *)enumContext);
		if (wsman_send_request(cl, request)) {
			ws_xml_destroy_doc(request);
			return NULL;
		}

		response = wsmc_build_envelope_from_response(cl);
		ws_xml_destroy_doc(request);
	} else {
		error("No enumeration context ???");
		return NULL;
	}

	node = ws_xml_get_child(ws_xml_get_soap_body(response),
			0, NULL, NULL);

	if (node == NULL ||
			(strcmp(ws_xml_get_node_local_name(node), WSENUM_PULL_RESP)) != 0) {
		error("no Pull response");
	}
	return response;
}



WsXmlDocH
wsmc_action_release(WsManClient * cl,
		const char *resource_uri,
		client_opt_t *options,
		const char *enumContext)
{
	WsXmlDocH       response;

	if (enumContext || (enumContext && enumContext[0] == 0)) {
		WsXmlDocH request = wsmc_create_request(cl, resource_uri, options, NULL,
				WSMAN_ACTION_RELEASE,
				NULL, (char *)enumContext);
		if (!request)
			return NULL;
		if (wsman_send_request(cl, request)) {
			ws_xml_destroy_doc(request);
			return NULL;
		}
		response = wsmc_build_envelope_from_response(cl);
		ws_xml_destroy_doc(request);
	} else {
		return NULL;
	}
	return response;
}

WsXmlDocH wsmc_action_subscribe(WsManClient * cl, const char *resource_uri,
				 client_opt_t * options, filter_t *filter)
{
	WsXmlDocH response;
	WsXmlDocH request = wsmc_create_request(cl, resource_uri, options, filter,
			WSMAN_ACTION_SUBSCRIBE, NULL, NULL);
	if (!request)
		return NULL;
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}

WsXmlDocH wsmc_action_unsubscribe(WsManClient * cl, const char *resource_uri,
				 client_opt_t * options,
				 const char *subsContext)
{
	WsXmlDocH       response;
	WsXmlDocH       request = wsmc_create_request(cl, resource_uri, options, NULL,
			WSMAN_ACTION_UNSUBSCRIBE, NULL, (void *)subsContext);
	if (!request)
		return NULL;
	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}

WsXmlDocH wsmc_action_renew(WsManClient * cl, const char *resource_uri,
				 client_opt_t * options,
				 const char *subsContext)
{
	WsXmlDocH       response;
	WsXmlDocH       request = wsmc_create_request(cl, resource_uri, options, NULL,
			WSMAN_ACTION_RENEW, NULL, (void *)subsContext);
	if (!request)
		return NULL;

	if (wsman_send_request(cl, request)) {
		ws_xml_destroy_doc(request);
		return NULL;
	}
	response = wsmc_build_envelope_from_response(cl);
	ws_xml_destroy_doc(request);
	return response;
}

char*
wsmc_get_enum_context(WsXmlDocH doc)
{
	char           *enumContext = NULL;
	char           *text = NULL;
	WsXmlNodeH      enumStartNode = ws_xml_get_child(ws_xml_get_soap_body(doc),
			0, NULL, NULL);

	if (enumStartNode) {
		WsXmlNodeH      cntxNode = ws_xml_get_child(enumStartNode, 0,
				XML_NS_ENUMERATION,
				WSENUM_ENUMERATION_CONTEXT);
		if (!cntxNode) {
			return NULL;
		}
		text = ws_xml_get_node_text(cntxNode);
		if (text) {
			enumContext = u_strdup(text);
		}
	}
	return enumContext;
}

char *
wsmc_get_event_enum_context(WsXmlDocH doc)
{
	char           *enumContext = NULL;
	char           *text = NULL;
	WsXmlNodeH      node = ws_xml_get_child(ws_xml_get_soap_body(doc),
			0, XML_NS_EVENTING, WSEVENT_SUBSCRIBE_RESP);

	if (node) {
		node = ws_xml_get_child(node, 0,
				XML_NS_ENUMERATION,
				WSENUM_ENUMERATION_CONTEXT);
		if (!node)
			return NULL;
		text = ws_xml_get_node_text(node);
		if (text) {
			enumContext = u_strdup(text);
		}
	}
	return enumContext;
}

void
wsmc_free_enum_context(char *enumcontext)
{
	u_free(enumcontext);
}


/**
 * Buid Inbound Envelope from Response
 * @param cl Client Handler
 * @return XML document with Envelope
 */

WsXmlDocH
wsmc_build_envelope_from_response(WsManClient * cl)
{
	WsXmlDocH       doc = NULL;
	u_buf_t        *buffer = cl->connection->response;

	if (!buffer || !u_buf_ptr(buffer)) {
		error("NULL response");
		return NULL;
	}
	doc = ws_xml_read_memory( u_buf_ptr(buffer), u_buf_len(buffer), cl->content_encoding, 0);
	if (doc == NULL) {
		error("could not create xmldoc from response");
	}
	return doc;
}


static void
wsmc_release_conn(WsManConnection * conn)
{
	if (conn == NULL) {
		return;
	}
	if (conn->request) {
		u_buf_free(conn->request);
		conn->request = NULL;
	}
	if (conn->response) {
		u_buf_free(conn->response);
		conn->response = NULL;
	}
	u_free(conn);
}



void
wsmc_reinit_conn(WsManClient * cl)
{
	u_buf_clear(cl->connection->response);
	u_buf_clear(cl->connection->request);
	cl->response_code = 0;
	cl->last_error = 0;
	if (cl->fault_string) {
		u_free(cl->fault_string);
		cl->fault_string = NULL;
	}
}


static void
init_client_connection(WsManClient * cl)
{
	WsManConnection *conn = (WsManConnection *) u_zalloc(sizeof(WsManConnection));
	u_buf_create(&conn->response);
	u_buf_create(&conn->request);
	cl->response_code = 0;
	cl->connection = conn;
}


WsManClient*
wsmc_create_from_uri(const char* endpoint)
{
	u_uri_t *uri = NULL;
	WsManClient* cl;
	if (!endpoint) {
		return NULL;
	}
	if (u_uri_parse((const char *) endpoint, &uri) != 0 ) {
		return NULL;
	}
	if (!uri) {
		return NULL;
	}
	cl = wsmc_create( uri->host,
			uri->port,
			uri->path,
			uri->scheme,
			uri->user,
			uri->pwd);
	u_uri_free(uri);
	return cl;
}

int
wsmc_set_encoding(WsManClient *cl, const char *encoding)
{
	u_free(cl->content_encoding);
	cl->content_encoding = encoding ? u_strdup(encoding) : NULL;
	return 0;
}

int
wsmc_set_namespace(WsManClient *cl, const char *ns)
{
	u_free(cl->cim_ns);
	cl->cim_ns = ns ? u_strdup(ns) : NULL;
	return 0;
}

char *wsmc_get_namespace(WsManClient *cl)
{
	return cl->cim_ns;
}

int
wsmc_check_for_fault(WsXmlDocH doc )
{
	return wsman_is_fault_envelope(doc);
}


WsManFault *
wsmc_fault_new(void)
{
	WsManFault     *fault =
		(WsManFault *) u_zalloc(sizeof(WsManFault));

	if (fault)
		return fault;
	else
		return NULL;
}

void wsmc_fault_destroy(WsManFault *fault)
{
	/*
	if (fault->code)
		u_free(fault->code);
	if (fault->subcode)
		u_free(fault->subcode);
	if (fault->reason)
		u_free(fault->reason);
	if (fault->fault_detail)
		u_free(fault->fault_detail);
		*/
	u_free(fault);
	return;
}



void
wsmc_get_fault_data(WsXmlDocH doc,
		WsManFault *fault)
{
	WsXmlNodeH body;
	WsXmlNodeH fault_node;
	WsXmlNodeH code;
	WsXmlNodeH reason;
	WsXmlNodeH detail;
	if (wsmc_check_for_fault(doc) == 0 || !fault )
		return;

	body = ws_xml_get_soap_body(doc);
	fault_node = ws_xml_get_child(body, 0, XML_NS_SOAP_1_2, SOAP_FAULT);
	if (!fault_node)
		return;

	code = ws_xml_get_child(fault_node, 0, XML_NS_SOAP_1_2, SOAP_CODE);
	if (code) {
		WsXmlNodeH code_v = ws_xml_get_child(code, 0 , XML_NS_SOAP_1_2, SOAP_VALUE);
		WsXmlNodeH subcode = ws_xml_get_child(code, 0 , XML_NS_SOAP_1_2, SOAP_SUBCODE);
		WsXmlNodeH subcode_v = ws_xml_get_child(subcode, 0 , XML_NS_SOAP_1_2, SOAP_VALUE);
		fault->code = ws_xml_get_node_text(code_v);
		fault->subcode = ws_xml_get_node_text(subcode_v);
	}
	reason = ws_xml_get_child(fault_node, 0, XML_NS_SOAP_1_2, SOAP_REASON);
	if (reason) {
		WsXmlNodeH reason_text = ws_xml_get_child(reason, 0 , XML_NS_SOAP_1_2, SOAP_TEXT);
		fault->reason = ws_xml_get_node_text(reason_text);
	}
	detail = ws_xml_get_child(fault_node, 0, XML_NS_SOAP_1_2, SOAP_DETAIL);
	if (detail) {
		// FIXME
		// WsXmlNodeH fault_detail = ws_xml_get_child(detail, 0 , XML_NS_WS_MAN, SOAP_FAULT_DETAIL);
		// fault->fault_detail = ws_xml_get_node_text(fault_detail);
		fault->fault_detail = ws_xml_get_node_text(detail);
	}
	return;
}



WsManClient*
wsmc_create(const char *hostname,
		const int port,
		const char *path,
		const char *scheme,
		const char *username,
		const char *password)
{
#ifndef _WIN32
        dictionary *ini;
#endif
	WsManClient *wsc = (WsManClient *) calloc(1, sizeof(WsManClient));
        if (wsc == NULL) {
          error("Can't alloc WsManClient");
          return NULL;
        }
	wsc->hdl = &wsc->data;

	if (pthread_mutex_init(&wsc->mutex, NULL)) {
		u_free(wsc);
		return NULL;
	}
#ifndef _WIN32
	wsmc_set_conffile(wsc, DEFAULT_CLIENT_CONFIG_FILE);
        ini = iniparser_new(wsmc_get_conffile(wsc));
        if (ini) {
          char *user_agent = iniparser_getstr(ini, "client:agent");
          if (user_agent) {
            wsman_transport_set_agent(wsc, user_agent);
          }
          iniparser_free(ini);
        }
#endif
	wsc->serctx = ws_serializer_init();
	wsc->dumpfile = stdout;
	wsc->data.scheme = u_strdup(scheme ? scheme : "http");
	wsc->data.hostname = hostname ? u_strdup(hostname) : u_strdup("localhost");
	wsc->data.port = port;
	wsc->data.path = u_strdup(path ? path : "/wsman");
	wsc->data.user = username ? u_strdup(username) : NULL;
	wsc->data.pwd = password ? u_strdup(password) : NULL;
	wsc->data.auth_set = 0;
	wsc->initialized = 0;
	wsc->transport_timeout = 0;
	wsc->content_encoding = u_strdup("UTF-8");
#ifdef _WIN32
	wsc->session_handle = 0;
#endif
	wsc->data.endpoint = u_strdup_printf("%s://%s:%d%s%s",
                                             wsc->data.scheme, wsc->data.hostname,
                                             wsc->data.port,
                                             (*wsc->data.path == '/') ? "" : "/",
                                             wsc->data.path);
	debug("Endpoint: %s", wsc->data.endpoint);
	wsc->authentication.verify_host = 1; //verify CN in server certicates by default
	wsc->authentication.verify_peer = 1; //validate server certificates by default
#ifndef _WIN32
	wsc->authentication.crl_check = 0;   // No CRL check by default
	wsc->authentication.crl_file = NULL;
#endif

	init_client_connection(wsc);

	return wsc;
}



void
wsmc_release(WsManClient * cl)
{
#ifndef _WIN32
	if (cl->client_config_file) {
		u_free(cl->client_config_file);
		cl->client_config_file = NULL;
	}
#endif
	if (cl->data.scheme) {
		u_free(cl->data.scheme);
		cl->data.scheme = NULL;
	}
	if (cl->data.hostname) {
		u_free(cl->data.hostname);
		cl->data.hostname = NULL;
	}
	if (cl->data.path) {
		u_free(cl->data.path);
		cl->data.path = NULL;
	}
	if (cl->data.user) {
		u_free(cl->data.user);
		cl->data.user = NULL;
	}

	if (cl->data.pwd) {
		u_free(cl->data.pwd);
		cl->data.pwd = NULL;
	}

	if (cl->data.endpoint) {
		u_free(cl->data.endpoint);
		cl->data.endpoint = NULL;
	}
	if (cl->fault_string) {
		u_free(cl->fault_string);
		cl->fault_string = NULL;
	}
	if (cl->connection) {
		wsmc_release_conn(cl->connection);
		cl->connection = NULL;
	}
	if (cl->serctx) {
		ws_serializer_cleanup(cl->serctx);
		cl->serctx = NULL;
	}
	if (cl->content_encoding) {
		u_free(cl->content_encoding);
		cl->content_encoding = NULL;
	}
	if (cl->cim_ns) {
		u_free(cl->cim_ns);
		cl->cim_ns = NULL;
	}
	if (cl->authentication.crl_file != NULL) {
		u_free(cl->authentication.crl_file);
		cl->authentication.crl_file = NULL;
	}
	if (cl->authentication.method != NULL) {
		u_free(cl->authentication.method);
		cl->authentication.method = NULL;
	}
        if (cl->authentication.cainfo != NULL) {	 
          u_free(cl->authentication.cainfo);
          cl->authentication.cainfo = NULL;
        }
        if (cl->authentication.caoid != NULL) {
          u_free(cl->authentication.caoid);
          cl->authentication.caoid = NULL;
        }
        if (cl->proxy_data.proxy_username != NULL) {
          u_free(cl->proxy_data.proxy_username);
          cl->proxy_data.proxy_username = NULL;
        }
        if (cl->proxy_data.proxy_password != NULL) {
          u_free(cl->proxy_data.proxy_password);
          cl->proxy_data.proxy_password = NULL;
        }
        pthread_mutex_destroy(&cl->mutex);

	wsman_transport_close_transport(cl);

	u_free(cl);
}

int
wsmc_lock(WsManClient * cl)
{
	if (pthread_mutex_lock(&cl->mutex))
		return 1;

	if (cl->flags & WSMAN_CLIENT_BUSY) {
		pthread_mutex_unlock(&cl->mutex);
		return 1;
	}
	cl->flags |= WSMAN_CLIENT_BUSY;
	pthread_mutex_unlock(&cl->mutex);
	return 0;
}


void
wsmc_unlock(WsManClient * cl)
{
	if (pthread_mutex_lock(&cl->mutex))
		return;

	cl->flags &= ~WSMAN_CLIENT_BUSY;
	pthread_mutex_unlock(&cl->mutex);
}


void
wsmc_remove_query_string(const char *s, char **result)
{
	char           *r = 0;
	const char     *q;
	char           *buf = 0;

	buf = u_strndup(s, strlen(s));
	if (!buf) {
		*result = NULL;
		return;
	}
	if ((q = strchr(buf, '?')) != NULL) {
		r = u_strndup(s, q - buf);
		*result = r;
	} else {
		*result = (char *)s;
	}

	u_free(buf);
}
