/*******************************************************************************
 * 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 Liang Hou
 * @author Sumeet Kukreja, Dell Inc.
 */
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <CimClientLib/cmci.h>
#include <CimClientLib/native.h>
#include "u/libu.h"


#include "wsman-xml.h"
#include "wsman-xml-binding.h"
#include "wsman-client-api.h"
#include "wsman-soap.h"
#include "wsman-soap-envelope.h"
#include "wsman-epr.h"

#include "sfcc-interface.h"
#include "cim-interface.h"
#include "cim_data.h"

#define SYSTEMCREATIONCLASSNAME "CIM_ComputerSystem"
#define SYSTEMNAME "localhost.localdomain"

extern char *get_server_port(void);

typedef struct _sfcc_enumcontext {
	CimClientInfo *ecClient;
	CMPIEnumeration *ecEnumeration;
} sfcc_enumcontext;

static int cim_getEprObjAt(CimClientInfo * client, WsEnumerateInfo * enumInfo,
		    WsXmlNodeH itemsNode);

static int cim_getEprAt(CimClientInfo * client, WsEnumerateInfo * enumInfo,
		 WsXmlNodeH itemsNode);

static int cim_getElementAt(CimClientInfo * client, WsEnumerateInfo * enumInfo,
		     WsXmlNodeH itemsNode);



static char *
cim_find_namespace_for_class(CimClientInfo * client,
		WsEnumerateInfo * enumInfo,
		char *classname)
{
	char *ns = NULL;
	char *sub, *target_class = NULL;
	hscan_t hs;
	hnode_t *hn;
	if (strcmp(client->requested_class, "*")  &&
			enumInfo && (enumInfo->flags & WSMAN_ENUMINFO_POLY_EXCLUDE)) {
		if ( (enumInfo->flags & WSMAN_ENUMINFO_EPR ) &&
				!(enumInfo->flags & WSMAN_ENUMINFO_OBJEPR))  {
			target_class = classname;
		} else {
			target_class = client->requested_class;
		}
	} else {
		target_class = classname;
	}

	//debug("target class:%s", target_class);
	if (strstr(client->resource_uri, XML_NS_CIM_CLASS) != NULL &&
			(strcmp(client->method, TRANSFER_GET) == 0 ||
			 strcmp(client->method, TRANSFER_DELETE) == 0 ||
			 strcmp(client->method, TRANSFER_PUT) == 0)) {
		ns = u_strdup(client->resource_uri);
		return ns;
	}
	if (target_class && client->namespaces) {
		hash_scan_begin(&hs, client->namespaces);
		while ((hn = hash_scan_next(&hs))) {
			//debug("namespace=%s", (char *) hnode_get(hn));
			if ((sub =  strstr(target_class, (char *) hnode_getkey(hn)))) {
				ns = u_strdup_printf("%s/%s",(char *) hnode_get(hn), target_class);
				//debug("vendor namespace match...");
				break;
			}
		}
	}
	if (!ns)
		ns = u_strdup_printf("%s/%s", XML_NS_CIM_CLASS,
				target_class);
	return ns;
}


static char *
cmpitype2string (CMPIType type)
{
   type &= ~CMPI_ARRAY;
   switch (type) {
      case CMPI_instance:
	return "instance";
      case CMPI_ref:
	return "reference";
      case CMPI_args:
	return "args";
      case CMPI_filter:
	return "filter";
      case CMPI_string:
	return "string";
      case CMPI_numericString:
	return "numericstring";
      case CMPI_booleanString:
	return "booleanstring";
      case CMPI_dateTimeString:
	return "datetimestring";
      case CMPI_classNameString:  /* identical with CMPI_chars */
	return "classnamestring";
      case CMPI_dateTime:
	return "datetime";
      case CMPI_boolean:
	return "boolean";
      case CMPI_char16:
	return "char16";
      case CMPI_uint8:
	return "uint8";
      case CMPI_sint8:
	return "sint8";
      case CMPI_uint16:
	return "uint16";
      case CMPI_sint16:
	return "sint16";
      case CMPI_uint32:
	return "uint32";
      case CMPI_sint32:
	return "sint32";
      case CMPI_uint64:
	return "uint64";
      case CMPI_sint64:
	return "sint64";
      case CMPI_real32:
	return "real32";
      case CMPI_real64:
	return "real64";
   }
   return "***Unknown***";
}



void
path2xml(CimClientInfo * client,
		WsXmlNodeH node, char *resource_uri, CMPIValue * val)
{
	int i = 0, numkeys = 0;
	char *_path_res_uri = NULL, *cv = NULL;
	WsXmlNodeH cimns, wsman_selector_set, refparam;

	CMPIObjectPath *objectpath = val->ref;
	CMPIString *namespace = objectpath->ft->getNameSpace(objectpath, NULL);
#if 0
	CMPIString *opstr = CMObjectPathToString(objectpath, NULL);
	debug("objectpath: %s", (char *) CMGetCharPtr(opstr));
	debug("namespace: %s", (char *) CMGetCharPtr(namespace));
#endif
	CMPIString *classname =  objectpath->ft->getClassName(objectpath, NULL);
	numkeys = objectpath->ft->getKeyCount(objectpath, NULL);

	ws_xml_add_child(node, XML_NS_ADDRESSING, WSA_ADDRESS,
			WSA_TO_ANONYMOUS);
	refparam = ws_xml_add_child(node, XML_NS_ADDRESSING,
			WSA_REFERENCE_PARAMETERS,
			NULL);
	_path_res_uri = cim_find_namespace_for_class(client, NULL, CMGetCharPtr(classname));
	ws_xml_add_child_format(refparam, XML_NS_WS_MAN, WSM_RESOURCE_URI,
			"%s", _path_res_uri);
	u_free(_path_res_uri);

	wsman_selector_set = ws_xml_add_child(refparam,
			XML_NS_WS_MAN,
			WSM_SELECTOR_SET,
			NULL);

	for (i = 0; i < numkeys; i++) {
		CMPIString *keyname;
		WsXmlNodeH s = NULL;
		CMPIData data = objectpath->ft->getKeyAt(objectpath, i,
				&keyname, NULL);
		cv = (char *) value2Chars(data.  type, &data.value);
		s = ws_xml_add_child(wsman_selector_set, XML_NS_WS_MAN,
				WSM_SELECTOR, cv );
		ws_xml_add_node_attr(s, NULL, "Name", CMGetCharPtr(keyname));
		if (cv)
			u_free(cv);
		if (keyname)
			CMRelease(keyname);
	}
	if (CMGetCharPtr(namespace) != NULL) {
		cimns = ws_xml_add_child(wsman_selector_set,
				XML_NS_WS_MAN, WSM_SELECTOR,
				CMGetCharPtr(namespace));
		ws_xml_add_node_attr(cimns, NULL, "Name",
				CIM_NAMESPACE_SELECTOR);
	}

	if (classname) {
		CMRelease(classname);
	}
	if (namespace) {
		CMRelease(namespace);
	}
}


/*
 * convert xml (string) value to CMPIData honoring type
 * I: data.type = expected type
 * I: value = pointer to string representation
 * O: data.value = type-correct value
 */
static void
xml2data(CMPIData *data, char *value, char *name, 
   WsXmlNodeH resource, const char *resource_uri)
{
	CMPIType type = data->type;

	if (type & CMPI_ARRAY) {
		WsXmlNodeH child;
		CMPIData adata;
		int count, ii;

		adata.type = (type ^ CMPI_ARRAY);
		count = ws_xml_get_child_count_by_qname(resource, resource_uri, name);
		data->value.array = newCMPIArray(count, adata.type, NULL);
		for (ii = 0; ii < count; ii++) {
			child = ws_xml_get_child(resource, ii, resource_uri, name);
			if (child) {
				if ((value = ws_xml_get_node_text(child))) {
					xml2data(&adata, value, name, resource, resource_uri);
					CMSetArrayElementAt(data->value.array, ii, &(adata.value), adata.type);
				}
			}
		}
	} else {
		switch (type) {
		case CMPI_instance:
		        data->value.inst = NULL;
			break;
		case CMPI_ref:
		        data->value.ref = NULL;
			break;
		case CMPI_args:
		        data->value.args = NULL;
			break;
#if CMPI_VER_200		  
		case CMPI_filter:
		        data->value.filter = NULL;
			break;
#endif		  
		case CMPI_string:
		case CMPI_numericString:
		case CMPI_booleanString:
		case CMPI_dateTimeString:
		case CMPI_classNameString: /* identical to CMPI_chars */
		        data->value.string = newCMPIString(value, NULL);
			break;
		case CMPI_dateTime:
		        data->value.dateTime = NULL;
			break;
		case CMPI_boolean: {
		      	int yes = 0;
			if (strcmp(value, "true") == 0)
				yes = 1;
		        data->value.boolean = yes;
			break;
		}
		case CMPI_uint8:
		        data->value.uint8 = strtoul(value, NULL, 10);
			break;
		case CMPI_sint8:
		        data->value.sint8 = atoi(value);
			break;
		case CMPI_uint16:
			data->value.uint16 = strtoul(value, NULL, 10);
			break;
		case CMPI_sint16:
			data->value.sint16 = atoi(value);
			break;
		case CMPI_uint32:
			data->value.uint32 = strtoul(value, NULL, 10);
			break;
		case CMPI_sint32:
			data->value.sint32 = atol(value);
			break;
		case CMPI_uint64:
			data->value.uint64 = strtoull(value, NULL, 10);
			break;
		case CMPI_sint64:
			data->value.sint64 = atoll(value);
			break;
		case CMPI_real32:
		        data->value.real32 = atof(value);
			break;
		case CMPI_real64:
		        data->value.real64 = atof(value);
			break;
		default:
		        debug("*** xml2data: type %x unsupported", type);
		}
	}
}



void
xml2objectpath(CMPIObjectPath * objectpath,
	         CMPIData *data, char *name, char *value)
{
  debug("xml2objectpath([0x%04x]%s:%s)", data->type, name, value);
        xml2data(data, value, NULL, NULL, NULL);
        CMAddKey(objectpath, name, &(data->value), data->type);
}


void
xml2property(CMPIInstance * instance,
		CMPIData *data, char *name, char *value, 
      WsXmlNodeH resource, const char *resource_uri)
{
  debug("xml2property([0x%04x]%s:%s)", data->type, name, value);
        xml2data(data, value, name, resource, resource_uri);
        CMSetProperty(instance, name, &(data->value), data->type);
}


void
type2xml(CimClientInfo * client, WsXmlNodeH node, char *resource_uri, CMPIType type)
{
        const char *typestr = cmpitype2string(type);
        if (type & CMPI_ARRAY) {
                WsXmlNodeH typenode = ws_xml_add_child(node, resource_uri, "type", NULL);
                ws_xml_add_child(typenode, resource_uri, "array", typestr);
	}
        else {
	        ws_xml_add_child(node, resource_uri, "type", typestr);
        }
}


void
property2xml(CimClientInfo * client, CMPIData *data,
		const char *name, WsXmlNodeH node, char *resource_uri,
		int frag_type, int is_key)
{

	char *valuestr = NULL;

	int xmlescape = strcasecmp("SfcbLocal", get_cim_client_frontend())==0 ? 1 : 0;

	if (CMIsArray((*data))) {
		WsXmlNodeH nilnode;
		if (( client->flags & FLAG_CIM_SCHEMA_OPT ) == FLAG_CIM_SCHEMA_OPT
				&& data->state == CMPI_nullValue) {
			return;
		} else if (data->type == CMPI_null && data->state == CMPI_nullValue) {
			nilnode = ws_xml_add_child_sort(node, resource_uri, name, NULL, xmlescape);
			ws_xml_add_node_attr(nilnode, XML_NS_SCHEMA_INSTANCE, "nil", "true");
			return;
		}
		CMPIArray *arr = data->value.array;
		CMPIType eletyp = data->type & ~CMPI_ARRAY;
		int j, n;
		if (arr != NULL) {
			n = CMGetArrayCount(arr, NULL);
			for (j = 0; j < n; ++j) {
				CMPIData ele = CMGetArrayElementAt(arr, j, NULL);
				valuestr = value2Chars(eletyp, &ele.value);
				ws_xml_add_child_sort(node, resource_uri, name, valuestr, xmlescape);
				free(valuestr);
			}
		}
	} else {
		if (( client->flags & FLAG_CIM_SCHEMA_OPT ) == FLAG_CIM_SCHEMA_OPT
				&&  data->state == CMPI_nullValue) {
			return;
		} else if (data->type != CMPI_null && data->state != CMPI_nullValue) {
			WsXmlNodeH refpoint = NULL;
			WsXmlNodeH propnode;

			if (data->type == CMPI_ref) {
				refpoint = ws_xml_add_child_sort(node, resource_uri, name, NULL, xmlescape);
				path2xml(client, refpoint, resource_uri, &(data->value));
			} else {
				valuestr = value2Chars(data->type, &(data->value));
				if(frag_type == 2)
					ws_xml_set_node_text(node, valuestr);
				else if(frag_type == 1) {
					ws_xml_add_child(node, NULL, name, valuestr);
				}
				else {
					propnode = ws_xml_add_child_sort(node, resource_uri, name, valuestr, xmlescape);
					if (is_key == 0 &&
							(client->flags & WSMAN_ENUMINFO_EXT )) {
						ws_xml_add_node_attr(propnode, XML_NS_CIM_SCHEMA, "Key",
								"true");
					}
				}
				if (valuestr)
					u_free(valuestr);
			}
		} else {
			WsXmlNodeH nilnode = ws_xml_add_child_sort(node, resource_uri, name,
					NULL, xmlescape);
			ws_xml_add_node_attr(nilnode, XML_NS_SCHEMA_INSTANCE, "nil", "true");
		}
	}
}


WsXmlNodeH
datatype2xml(CimClientInfo * client, WsXmlNodeH parent, char *resource_uri, const char *nodename, const char *name, CMPIData *data)
{
       WsXmlNodeH node = ws_xml_add_child(parent, resource_uri, nodename, NULL);
       ws_xml_add_child(node, resource_uri, "name", name);
       type2xml(client, node, resource_uri, data->type);
       property2xml(client, data, "value", node, resource_uri, 0, 0);
       return node;
}


/*
 * Convert class or property qualifiers to xml
 * client: client
 * _class: class
 * property_name: NULL for class qualifiers
 */

void
qualifiers2xml(CimClientInfo *client, WsXmlNodeH node, CMPIConstClass *_class, const char *property_name)
{
        unsigned int count;
        CMPIStatus rc;
        if (property_name)
		count = _class->ft->getPropertyQualifierCount(_class, property_name, &rc);
        else
 		count = _class->ft->getQualifierCount(_class, &rc);

        if (count > 0) {
	        unsigned int i = 0;
		WsXmlNodeH qualifiers = ws_xml_add_child(node, client->resource_uri, "qualifiers", NULL);
		while (i < count) {
			CMPIString *qualifier_name;
			CMPIData data;
		        if (property_name)
				data = _class->ft->getPropertyQualifierAt(_class,
					property_name, i++, &qualifier_name, &rc);
		        else
		                data = _class->ft->getQualifierAt(_class, i++, &qualifier_name, &rc);
		        if (rc.rc)
				return;
			datatype2xml(client, qualifiers, client->resource_uri, "qualifier", CMGetCharPtr(qualifier_name), &data);

		        CMRelease(qualifier_name);
		}
	}
}


/*
 * Get value of hash node "__cimnamespace"
 * 
 */

char *
cim_get_namespace_selector(hash_t * keys)
{
	char *cim_namespace = NULL;
	selector_entry *sentry = NULL;
	hnode_t *hn = hash_lookup(keys, (char *) CIM_NAMESPACE_SELECTOR);
	if (hn) {
		sentry = (selector_entry *) hnode_get(hn);
		if(sentry->type == 1) return NULL;
		cim_namespace = sentry->entry.text;
		hash_delete(keys, hn);
		hnode_destroy(hn);
		u_free(sentry);
		debug("CIM Namespace: %s", cim_namespace);
	}
	return cim_namespace;
}


static int
cim_add_keys_from_filter_cb(void *objectpath, const char* key,
		const char *value)
{
	CMPIObjectPath *op = (CMPIObjectPath *)objectpath;
	debug("adding selector %s=%s", key, value );
	if(strcmp(key, CIM_NAMESPACE_SELECTOR) == 0) //it is __cimnamespace
		CMSetNameSpace(op, value);
	else
		CMAddKey(op, key, value, CMPI_chars);
	return 0;
}


static CMPIObjectPath *
cim_epr_to_objectpath(CimClientInfo * client, epr_t *epr)
{
	CMPIObjectPath * objectpath = NULL;
	char *class = NULL;
	if (epr && epr->refparams.uri) {
		debug("uri: %s", epr->refparams.uri);
		class = strrchr(epr->refparams.uri, '/');
	}
	if (class) {
		class++;
		if ((NULL != client) && (NULL != client->cim_namespace))
			objectpath = newCMPIObjectPath(client->cim_namespace, class, NULL);
		else
			objectpath = newCMPIObjectPath(CIM_NAMESPACE, class, NULL);
		wsman_epr_selector_cb(epr, cim_add_keys_from_filter_cb, objectpath);
		debug( "ObjectPath: %s",
			CMGetCharPtr(CMObjectPathToString(objectpath, NULL)));
	}
	return objectpath;
}


static int
comparef(const void *key1, const void *key2)
{
	methodarglist_t * d1 = (methodarglist_t*)key1;
	methodarglist_t * d2 = (methodarglist_t*)key2;
	return strcmp(d1->key, d2->key);
}


static int
cim_add_args(CimClientInfo * client, CMPIObjectPath *op,
		CMPIArgs * argsin)
{
	hscan_t hs;
	hnode_t *hn;
	hash_scan_begin(&hs, client->method_args);
	list_t *arglist = NULL;
	int res = 0;

	debug("cim_add_args:");
	while ((hn = hash_scan_next(&hs))) {
		if (strcmp(METHOD_ARGS_KEY, (char *)hnode_getkey(hn)) == 0)
			arglist = (list_t *)hnode_get(hn);
	}
	if (NULL != arglist) {
		lnode_t *argnode;
		methodarglist_t *arraynode = NULL;
		methodarglist_t *node_val;
		int ii, jj, listcount = list_count(arglist);

		// sort the list first then tag arrays
		debug("cim_add_args: list count: %u", listcount);
		if (0 >= listcount) {
			return res; // nothing to do so return
		}
		list_sort(arglist, comparef);
		argnode = list_first(arglist);
		arraynode = (methodarglist_t *)argnode->list_data;
		argnode = list_next(arglist, argnode);
		while (argnode) {
			node_val = (methodarglist_t *)argnode->list_data;
			if (strcmp(arraynode->key, node_val->key) == 0) {
				arraynode->arraycount++;
			} else {
				arraynode = node_val;
			}
			argnode = list_next(arglist, argnode);
		}

		// reiterate the list and add args
		argnode = list_first(arglist);
		for (ii = 0; ii < listcount; ii++) {
			CMPIValue value;
			selector_entry *sentry;
			node_val = (methodarglist_t *)argnode->list_data;
			sentry = (selector_entry *)node_val->data;
			if (0 < node_val->arraycount) {
				CMPIArray *arraydata = NULL;
				lnode_t *t_anode = argnode;
				int arraytype = sentry->type, kk;
				node_val->arraycount++; // since value of 0 is singleton and value of 1 is actually 2 count in an array
				debug("cim_add_args: array key: %s type: %u count: %u", node_val->key, arraytype, node_val->arraycount);

				// first verify if array type is the same for all elements in the array.
				for (kk = 1; kk < node_val->arraycount; kk++) {
					t_anode = list_next(arglist, t_anode);
					if (NULL != t_anode) {
						selector_entry *t_sentry = (selector_entry *)((methodarglist_t *)t_anode->list_data)->data;
						char *key = ((methodarglist_t *)t_anode->list_data)->key;
						debug(" %s[0] = %d, %s[%d] = %d", key, sentry->type, key, kk, t_sentry->type);	
						if (sentry->type != t_sentry->type) {
							res = 1;
							goto error;
						}
					}
				}

				if (0 != arraytype)
					arraydata = native_new_CMPIArray(node_val->arraycount, CMPI_ref, NULL);
				else
					arraydata = native_new_CMPIArray(node_val->arraycount, CMPI_string, NULL);
				for (jj = 0; jj < node_val->arraycount; jj++) {
					debug("cim_add_args: array %u object: %p", jj, sentry);
					if (0 != arraytype) {
						value.ref = cim_epr_to_objectpath(client, sentry->entry.eprp);
						if (value.ref == NULL) {
						        res = 1;
							goto error;
						}
						CMSetArrayElementAt(arraydata, jj, &value, CMPI_ref);
					} else {
						value.string = native_new_CMPIString((char *)sentry->entry.text, NULL);
						CMSetArrayElementAt(arraydata, jj, &value, CMPI_string);
					}
					argnode = list_next(arglist, argnode);
					if (NULL != argnode)
						sentry = (selector_entry *)((methodarglist_t *)argnode->list_data)->data;
				}
				value.array = arraydata;
				if (0 != arraytype)
					CMAddArg(argsin, node_val->key, (char *)&value, CMPI_refA);
				else
					CMAddArg(argsin, node_val->key, (char *)&value, CMPI_stringA);
				ii += (jj - 1);
			} else {
				debug("cim_add_args: single key: %s type: %u", node_val->key, sentry->type);
				if (0 != sentry->type) {
					epr_t *eprp = sentry->entry.eprp;
					if (eprp == NULL) {
						res = 1;
						break;
					}
					debug("epr_t: selectorcount: %u", eprp->refparams.selectorset.count);
					value.ref = cim_epr_to_objectpath(client, sentry->entry.eprp);
					CMAddArg(argsin, node_val->key, &value, CMPI_ref);
				} else {
					debug("text: %s", sentry->entry.text);
					CMAddArg(argsin, node_val->key, sentry->entry.text, CMPI_chars);
				}
				argnode = list_next(arglist, argnode);
			}
		}
	} else {
		debug("cim_add_args: did not find any argument list");
	}

error:
	return res;
}


static void
cim_add_keys(CMPIObjectPath * objectpath, hash_t * keys)
{
	hscan_t hs;
	hnode_t *hn;
	selector_entry *sentry;
	if (keys == NULL) {
		return;
	}
	hash_scan_begin(&hs, keys);
	while ((hn = hash_scan_next(&hs))) {
		sentry = (selector_entry *)hnode_get(hn);
		debug("in cim_add_keys: key: %s, text: %s", hnode_getkey(hn), sentry->entry.text);
		if(sentry->type == 0)
			CMAddKey(objectpath, (char *) hnode_getkey(hn),
					sentry->entry.text, CMPI_chars);
		else {
			CMPIValue value;
			value.ref = cim_epr_to_objectpath(NULL, sentry->entry.eprp);;
			if (NULL != value.ref) {
				CMAddKey(objectpath, (char *) hnode_getkey(hn),
					&value, CMPI_ref);
			}
		}

	}
}

static int
cim_verify_class_keys(CMPIConstClass * class,
		hash_t * keys, WsmanStatus * statusP)
{
	CMPIStatus rc;
	int count, ccount = 0;
	int numproperties, i;
	debug("verify class selectors");

	if (!keys) {
		count = 0;
	} else {
		count = (int) hash_count(keys);
	}
	numproperties = class->ft->getPropertyCount(class, NULL);
	debug("number of prop in class: %d", numproperties);
	for (i = 0; i < numproperties; i++) {
		CMPIString *propertyname;
		CMPIData data;
		class->ft->getPropertyAt(class, i, &propertyname, NULL);
		data = class->ft->getPropertyQualifier(class,
				CMGetCharPtr(propertyname), "Key", &rc);
		if ((data.state != CMPI_nullValue) && (data.value.boolean)) {
			ccount++;
		}
		CMRelease(propertyname);
	}

	debug("selector count from user: %d, in class definition: %d",
			count, ccount);
	if (ccount > count) {
		statusP->fault_code = WSMAN_INVALID_SELECTORS;
		statusP->fault_detail_code =
			WSMAN_DETAIL_INSUFFICIENT_SELECTORS;
		debug("insuffcient selectors");
		goto cleanup;
	} else if (ccount < hash_count(keys)) {
		statusP->fault_code = WSMAN_INVALID_SELECTORS;
		statusP->fault_detail_code =
			WSMAN_DETAIL_UNEXPECTED_SELECTORS;
		debug("invalid selectors");
		goto cleanup;
	}
cleanup:
	return statusP->fault_code;
}

static int
cim_opcmp(CMPIObjectPath * op1, CMPIObjectPath * op2) {
	CMPIStatus rc;
	unsigned int i = 0;
	unsigned int count = CMGetKeyCount(op2, &rc);
	debug("count = %d", count);
	char *cv1,*cv2;
	int match = 0;
	while (i < count) {
		CMPIString *name1 = NULL;
		CMPIData value1 = CMGetKeyAt(op2, i, &name1, &rc);
		if(rc.rc) goto DONE;
		i++;
		char *p1 = CMGetCharsPtr(name1, &rc);
		if(rc.rc)
			goto DONE;
		CMPIData value2 = CMGetKey(op1, p1, &rc);
		if(rc.rc) goto DONE;
		cv1 = value2Chars(value1.type, &value1.value);
		cv2 = value2Chars(value2.type, &value2.value);
		match = strcmp(cv1,cv2);
		u_free(cv1);
		u_free(cv2);
		if(match == 0)
			continue;
		else
			goto DONE;
	}
DONE:
	CMRelease(op1);
	CMRelease(op2);
	if(rc.rc || match)
		return 1;
	else
		return 0;
}

static int
cim_verify_keys(CMPIObjectPath * objectpath, hash_t * keys,
		WsmanStatus * statusP)
{
	CMPIStatus rc;
	hscan_t hs;
	hnode_t *hn;
	int count, opcount;
	char *cv = NULL;

	debug("verify selectors");

	if (!keys) {
		count = 0;
	} else {
		count = (int) hash_count(keys);
	}
	opcount = CMGetKeyCount(objectpath, &rc);

	debug("selector count from user: %d, in object path: %d", count,
			opcount);
	if (opcount > count) {
		statusP->fault_code = WSMAN_INVALID_SELECTORS;
		statusP->fault_detail_code = WSMAN_DETAIL_INSUFFICIENT_SELECTORS;
		debug("insuffcient selectors");
		goto cleanup;
	} else if (opcount < hash_count(keys)) {
		statusP->fault_code = WSMAN_INVALID_SELECTORS;
		debug("invalid selectors");
		goto cleanup;
	}

	hash_scan_begin(&hs, keys);

	while ((hn = hash_scan_next(&hs))) {
		CMPIData data = CMGetKey(objectpath, (char *) hnode_getkey(hn), &rc);
		if (rc.rc != 0) {	// key not found
			statusP->fault_code = WSMAN_INVALID_SELECTORS;
			statusP->fault_detail_code = WSMAN_DETAIL_UNEXPECTED_SELECTORS;
			debug("unexpected selectors");
			break;
		}
		selector_entry *sentry = (selector_entry*)hnode_get(hn);
		if(sentry->type == 0) {
			cv = value2Chars(data.type, &data.value);
			if(cv != NULL && strcmp(cv, sentry->entry.text) == 0) {
				statusP->fault_code = WSMAN_RC_OK;
				statusP->fault_detail_code = WSMAN_DETAIL_OK;
				u_free(cv);
			}
			else {
				statusP->fault_code = WSA_DESTINATION_UNREACHABLE;
				statusP->fault_detail_code = WSMAN_DETAIL_INVALID_RESOURCEURI;
				debug("selector '%s', value: [ %s ] not matched", hnode_getkey(hn), sentry->entry.text);
			        debug("data.type 0x%04x, cv '%s'", data.type, cv?cv:"<NULL>");
				u_free(cv);
				break;
			}
		}
		else {
			CMPIObjectPath *objectpath_epr = cim_epr_to_objectpath(NULL, sentry->entry.eprp);
			CMPIObjectPath *objectpath_epr2 = CMClone(data.value.ref, NULL);
			if (cim_opcmp(objectpath_epr2, objectpath_epr) == 0) {
				statusP->fault_code = WSMAN_RC_OK;
				statusP->fault_detail_code = WSMAN_DETAIL_OK;
				u_free(cv);
			} else {
				statusP->fault_code = WSA_DESTINATION_UNREACHABLE;
				statusP->fault_detail_code =
					WSMAN_DETAIL_INVALID_RESOURCEURI;
				debug("invalid resource_uri %s != %s", cv,
						(char *)CMGetCharPtr(CMObjectPathToString(objectpath, NULL)));
				u_free(cv);
				break;
			}
		}
	}
cleanup:
	debug("getKey rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	return statusP->fault_code;
}



static CMPIConstClass *
cim_get_class(CimClientInfo * client,
		const char *class,
		CMPIFlags flags, WsmanStatus * status)
{
	CMPIObjectPath *op;
	CMPIConstClass *_class;
	CMPIStatus rc;

	CMCIClient *cc = (CMCIClient *) client->cc;
	op = newCMPIObjectPath(client->cim_namespace, class, NULL);
	_class = cc->ft->getClass(cc, op, flags, NULL, &rc);

	debug("getClass() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : "<NULL>");
	cim_to_wsman_status(rc, status);
	if (op)
		CMRelease(op);
	return _class;
}

static int
filter_instance(CMPIInstance * instance, WsEnumerateInfo * enumInfo)
{
	filter_t *filter = enumInfo->filter;
	int i;
	int matches = 0;
	Selector *ss = filter->selectorset.selectors;
	if (ss == NULL) {
		debug("epr->refparams.selectors == NULL");
		return 0;
	}
	for (i = 0; i < filter->selectorset.count; i++) {
		Selector *s;
		s = ss + i;
		CMPIData data = instance->ft->getProperty(instance, s->name, NULL);
		char *valuestr = value2Chars(data.type, &data.value);
		if (valuestr && strcmp(s->value, valuestr) == 0 ) {
			matches++;
		}
		u_free(valuestr);
	}
	if (matches == filter->selectorset.count)
		return 1;

	return 0;
}

static void
instance2xml(CimClientInfo * client,
		CMPIInstance * instance, char *fragstr,
		WsXmlNodeH body, WsEnumerateInfo * enumInfo)
{
	int i = 0;
	char *class_namespace = NULL;
	CMPIObjectPath *objectpath;
	CMPIString *classname;
	CMPIConstClass *_class = NULL;
	char *final_class = NULL;
	int numproperties = 0;
	int frag_type = 0;
	int index;
	char *propertystr = NULL;
	WsXmlNodeH xmlr = NULL;

	objectpath = instance->ft->getObjectPath(instance, NULL);
	classname = objectpath->ft->getClassName(objectpath, NULL);
	class_namespace = cim_find_namespace_for_class(client, enumInfo,
			CMGetCharPtr(classname));

	final_class = u_strdup(strrchr(class_namespace, '/') + 1);

	if(fragstr) {
		xmlr = body;
	}
	else {
		xmlr = ws_xml_add_child(body, class_namespace, final_class, NULL);
	}

	wsman_get_fragment_type(fragstr, &frag_type, &propertystr, &index);

	if (strcmp(client->requested_class, "*")  && enumInfo &&
			(enumInfo->flags & WSMAN_ENUMINFO_POLY_EXCLUDE )) {
		_class = cim_get_class(client, client->requested_class, 0, NULL);
		if (_class)
			numproperties = _class->ft->getPropertyCount(_class, NULL);
	} else {
		numproperties = instance->ft->getPropertyCount(instance, NULL);
	}


	for (i = 0; i < numproperties; i++) {
		CMPIString *propertyname;
		CMPIData data;
		CMPIStatus is_key;
		if (strcmp(client->requested_class, "*")
				&& enumInfo && (enumInfo->flags & WSMAN_ENUMINFO_POLY_EXCLUDE)) {
			_class->ft->getPropertyAt(_class, i, &propertyname,
					NULL);
			data = instance->ft->getProperty(instance, CMGetCharPtr(propertyname),
					NULL);
		} else {
			data = instance->ft->getPropertyAt(instance, i,
					&propertyname,
					NULL);
		}
		if(propertystr && strcmp(propertystr, CMGetCharPtr(propertyname))) {
			CMRelease(propertyname);
			continue;
		}
		objectpath->ft->getKey(objectpath, CMGetCharPtr(propertyname), &is_key);
		property2xml(client, &data, CMGetCharPtr(propertyname), xmlr,
				class_namespace, frag_type, is_key.rc);
		CMRelease(propertyname);
	}
	//ws_xml_dump_node_tree(stdout, r );
	struct timeval tv0, tv1;
	long long t0, t1;
	long long ttime = 0;
	gettimeofday(&tv0, NULL);

	gettimeofday(&tv1, NULL);
	t0 = tv0.tv_sec * 10000000 + tv0.tv_usec;
	t1 = tv1.tv_sec * 10000000 + tv1.tv_usec;
	ttime += t1 -t0;

	if (enumInfo && (enumInfo->flags &  WSMAN_ENUMINFO_POLY_EXCLUDE ) ) {
		if (_class) {
			CMRelease(_class);
		}
	}
	if(propertystr)
		u_free(propertystr);
	if (classname)
		CMRelease(classname);
	if (objectpath)
		CMRelease(objectpath);
	if (final_class)
		u_free(final_class);
	if (class_namespace)
		u_free(class_namespace);
}



/*
 * An operation (for a concrete instance) is given only the abstract base class
 * 
 * Enumerate through all instances of the base class, comparing keys to identify
 * the matching instance
 *
 */

static CMPIObjectPath *
cim_get_op_from_enum(CimClientInfo * client,
		WsmanStatus * statusP)
{
	CMPIStatus rc;
	int match = 0;
	CMPIEnumeration *enumeration;
	CMPIObjectPath *result_op = NULL;
	CMPIArray *enumArr = NULL;

	if (client->requested_class)
		debug("class available");

	CMPIObjectPath *objectpath =
		newCMPIObjectPath(client->cim_namespace,
				client->requested_class, NULL);
	enumeration =
		((CMCIClient *) client->cc)->ft->enumInstanceNames(client->cc,
			objectpath,
			&rc);
	debug("enumInstanceNames rc=%d, msg=%s", rc.rc,
			(rc.msg) ? CMGetCharPtr(rc.msg) : NULL);

	if (rc.rc != 0) {
		cim_to_wsman_status(rc, statusP);
		//statusP->fault_detail_code = WSMAN_DETAIL_INVALID_RESOURCEURI;
		if (rc.msg)
			CMRelease(rc.msg);
		goto cleanup;
	}

	enumArr = enumeration->ft->toArray(enumeration, NULL);
	int n = CMGetArrayCount(enumArr, NULL);
	if (n > 0) {
		while (enumeration->ft->hasNext(enumeration, NULL)) {
			CMPIData data = enumeration->ft->getNext(enumeration,
					NULL);
			CMPIObjectPath *op = CMClone(data.value.ref, NULL);
			CMPIString *opstr = CMObjectPathToString(op, NULL);
			debug("objectpath: %s", CMGetCharPtr(opstr));
			if (cim_verify_keys(op, client->selectors, statusP) != 0) {
				if (opstr)
					CMRelease(opstr);
				if (op)
					CMRelease(op);
				continue;
			} else {
				result_op = CMClone(data.value.ref, NULL);
				CMSetNameSpace(result_op,
						client->cim_namespace);
				match = 1;
				if (opstr)
					CMRelease(opstr);
				if (op)
					CMRelease(op);
				break;
			}
			if (opstr)
				CMRelease(opstr);
			if (op)
				CMRelease(op);
		}
	} else {
		statusP->fault_code = WSA_DESTINATION_UNREACHABLE;
		statusP->fault_detail_code =
			WSMAN_DETAIL_INVALID_RESOURCEURI;
	}
	debug("fault: %d %d", statusP->fault_code, statusP->fault_detail_code);

cleanup:

	if (objectpath)
		CMRelease(objectpath);
	if (enumeration)
		CMRelease(enumeration);
	if (match)
		return result_op;
	else
		return NULL;
}



void
cim_enum_instances(CimClientInfo * client,
		WsEnumerateInfo * enumInfo,
		WsmanStatus * status)
{
	CMPIObjectPath *objectpath = NULL;
	CMPIEnumeration *enumeration = NULL;
	CMPIStatus rc;
	CMCIClient *cc = (CMCIClient *) client->cc;
	sfcc_enumcontext *enumcontext;
	filter_t *filter = NULL;
	filter = enumInfo->filter;

	if( (enumInfo->flags & WSMAN_ENUMINFO_REF) ||
			(enumInfo->flags & WSMAN_ENUMINFO_ASSOC )) {
		char *class = NULL;
		epr_t *epr;
		if (filter) {
			epr = (epr_t *)filter->epr;
			class = strrchr(epr->refparams.uri, '/') + 1;
			objectpath = newCMPIObjectPath(client->cim_namespace,
					class, NULL);
			wsman_epr_selector_cb(filter->epr,
					cim_add_keys_from_filter_cb, objectpath);
			debug( "ObjectPath: %s",
					CMGetCharPtr(CMObjectPathToString(objectpath, &rc)));
		} else {
			status->fault_code = WXF_INVALID_REPRESENTATION;
			status->fault_detail_code = WSMAN_DETAIL_OK;
			goto cleanup;
		}
		/*
	} else if(enumInfo->flags & WSMAN_ENUMINFO_SELECTOR) {
		char *cim_namespace;
		cim_namespace = get_cimnamespace_from_selectorset(&filter->selectorset);
		if(cim_namespace == NULL)
			cim_namespace = client->cim_namespace;
		objectpath = newCMPIObjectPath(cim_namespace, client->requested_class, NULL);
		wsman_selectorset_cb(&filter->selectorset,
				cim_add_keys_from_filter_cb, objectpath);
		debug( "ObjectPath: %s",
				CMGetCharPtr(CMObjectPathToString(objectpath, &rc)));
		 */
	} else {
		objectpath = newCMPIObjectPath(client->cim_namespace,
				client->requested_class, NULL);
	}

	if (enumInfo->flags & WSMAN_ENUMINFO_REF) {
		enumeration = cc->ft->references(cc, objectpath, filter->resultClass,
				filter->role, 0, NULL, &rc);
	} else if (enumInfo->flags & WSMAN_ENUMINFO_ASSOC) {
		enumeration = cc->ft->associators(cc, objectpath, filter->assocClass,
				filter->resultClass,
				filter->role,
				filter->resultRole, 0, NULL, &rc);
	} else if (( enumInfo->flags & WSMAN_ENUMINFO_WQL )) {
		enumeration = cc->ft->execQuery(cc, objectpath, filter->query, "WQL", &rc);
	} else if (( enumInfo->flags & WSMAN_ENUMINFO_CQL )) {
		enumeration = cc->ft->execQuery(cc, objectpath, filter->query, "CQL", &rc);
	} else if (( enumInfo->flags & WSMAN_ENUMINFO_XPATH )) { /* XPath unsupported in Sfcc */
                status->fault_code = WSEN_CANNOT_PROCESS_FILTER;
                status->fault_detail_code = WSMAN_DETAIL_NOT_SUPPORTED;
                goto cleanup;
	} else {
		enumeration = cc->ft->enumInstances(cc, objectpath,
				CMPI_FLAG_DeepInheritance,
				NULL, &rc);
	}

	debug("enumInstances() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);

	if (rc.rc) {
		debug("*** CMCIClient enumInstances() failed");
		cim_to_wsman_status(rc, status);
		if (rc.msg)
			CMRelease(rc.msg);
		if (objectpath)
			CMRelease(objectpath);
		goto cleanup;
	}
	CMPIArray *enumArr = enumeration->ft->toArray(enumeration, NULL);
	CMPIArray *fenumArr = NULL;
	if (enumInfo->flags & WSMAN_ENUMINFO_SELECTOR) {
		CMPIType t = enumArr->ft->getSimpleType(enumArr, NULL);
		fenumArr = newCMPIArray(0, t , NULL);
		int idx = 0;
		int fidx = 0;
		for (idx = 0; idx<enumArr->ft->getSize(enumArr, NULL); idx++) {
			CMPIData d = enumArr->ft->getElementAt(enumArr, idx, NULL);
			if (filter_instance(d.value.inst, enumInfo)) {
				fenumArr->ft->setElementAt(fenumArr, fidx, &d.value, d.type);
				fidx++;
			}
		}
	} else {
		fenumArr = enumArr;
	}

	cim_to_wsman_status(rc, status);
	if (rc.msg)
		CMRelease(rc.msg);
	if (!enumArr) {
		goto cleanup;
	}

	enumInfo->totalItems = cim_enum_totalItems(fenumArr);
	debug("Total items: %d", enumInfo->totalItems);
	enumcontext = u_zalloc(sizeof(sfcc_enumcontext));
	enumcontext->ecClient = client;
	enumcontext->ecEnumeration = enumeration;
	enumInfo->enumResults = fenumArr;
	enumInfo->appEnumContext = enumcontext;

	if (objectpath)
		CMRelease(objectpath);
cleanup:
	return;
}


/*
 * Get enumeration item as element at enumInfo->index and append it to itemsNode
 * return 1 on success
 */

static int
cim_getElementAt(CimClientInfo * client,
		WsEnumerateInfo * enumInfo, WsXmlNodeH itemsNode)
{
	int retval = 1;
	char *fragstr = NULL;

	CMPIArray *results = (CMPIArray *) enumInfo->enumResults;
	CMPIData data = results->ft->getElementAt(results,
			enumInfo->index, NULL);

	CMPIInstance *instance = data.value.inst;
	CMPIObjectPath *objectpath = instance->ft->getObjectPath(instance, NULL);
	CMPIString *classname = objectpath->ft->getClassName(objectpath, NULL);

	if ((enumInfo->flags & WSMAN_ENUMINFO_POLY_NONE ) &&
			(strcmp(CMGetCharPtr(classname), client->requested_class) != 0)) {
		retval = 0;
	}

	fragstr = wsman_get_fragment_string(client->cntx, client->cntx->indoc);
	if(fragstr) {
		itemsNode = ws_xml_add_child(itemsNode, XML_NS_WS_MAN, WSM_XML_FRAGMENT,
				NULL);
	}
	if (retval)
		instance2xml(client, instance, fragstr, itemsNode, enumInfo);
	if (classname)
		CMRelease(classname);
	if (objectpath)
		CMRelease(objectpath);
	return retval;
}


/*
 * Get enumeration item as WS end point reference at enumInfo->index and append it to itemsNode
 * return 1 on success
 * 
 */

static int
cim_getEprAt(CimClientInfo * client,
		WsEnumerateInfo * enumInfo, WsXmlNodeH itemsNode)
{
	int retval = 1;
	char *uri = NULL;
	CMPIArray *results = (CMPIArray *) enumInfo->enumResults;
	CMPIData data = results->ft->getElementAt(results,
			enumInfo->index, NULL);

	CMPIInstance *instance = data.value.inst;
	CMPIObjectPath *objectpath = instance->ft->getObjectPath(instance, NULL);
	CMPIString *classname = objectpath->ft->getClassName(objectpath, NULL);

	if ((enumInfo->flags & WSMAN_ENUMINFO_POLY_NONE)
			&& (strcmp(CMGetCharPtr(classname), client->requested_class) != 0)) {
		retval = 0;
	}
	uri = cim_find_namespace_for_class(client, enumInfo, CMGetCharPtr(classname));
	if (retval) {
		cim_add_epr(client, itemsNode, uri, objectpath);
	}

	u_free(uri);
	if (classname)
		CMRelease(classname);
	if (objectpath)
		CMRelease(objectpath);
	return retval;
}


/*
 * Get enumeration item as WS end point reference object at enumInfo->index and append it to itemsNode
 * return 1 on success
 * 
 */

static int
cim_getEprObjAt(CimClientInfo * client,
		WsEnumerateInfo * enumInfo, WsXmlNodeH itemsNode)
{
	int retval = 1;
	char *uri = NULL;
	CMPIArray *results = (CMPIArray *) enumInfo->enumResults;
	CMPIData data =
		results->ft->getElementAt(results, enumInfo->index, NULL);

	CMPIInstance *instance = data.value.inst;
	CMPIObjectPath *objectpath =
		instance->ft->getObjectPath(instance, NULL);
	CMPIString *classname =
		objectpath->ft->getClassName(objectpath, NULL);

	if ((enumInfo->flags & WSMAN_ENUMINFO_POLY_NONE) &&
			(strcmp(CMGetCharPtr(classname), client->requested_class) != 0)) {
		retval = 0;
	}
	uri = cim_find_namespace_for_class(client, enumInfo, CMGetCharPtr(classname));

	if (retval) {
		WsXmlNodeH item =
                        ws_xml_add_child(itemsNode, XML_NS_WS_MAN, WSM_ITEM,
                                        NULL);
		instance2xml(client, instance, NULL, item, enumInfo);
		cim_add_epr(client, item, uri, objectpath);
	}
	u_free(uri);
	if (classname)
		CMRelease(classname);
	if (objectpath)
		CMRelease(objectpath);
	return retval;
}


void
create_instance_from_xml(CMPIInstance * instance,
		CMPIConstClass * class,
		WsXmlNodeH resource, char *fragstr,
		char *resource_uri, WsmanStatus * status)
{
	int i;
	int fragment_flag;
	char *element;
	int index;
	WsXmlNodeH child = NULL;
	char *value = NULL;
	CMPIData data;

	CMPIObjectPath *objectpath =
		instance->ft->getObjectPath(instance, NULL);
	CMPIString *classname =
		objectpath->ft->getClassName(objectpath, NULL);
	int numproperties = 0;
	numproperties = class->ft->getPropertyCount(class, NULL);
	wsman_get_fragment_type(fragstr, &fragment_flag, &element, &index);

	for (i = 0; i < numproperties; i++) {
		CMPIString *propertyname;
		data = class->ft->getPropertyAt(class,
				i, &propertyname,
				NULL);
		debug("working on property: %s", CMGetCharPtr(propertyname) );
		if(fragment_flag == 0) {
			child = ws_xml_get_child(resource, 0, resource_uri,
					CMGetCharPtr(propertyname));
			if (child) {
				value = ws_xml_get_node_text(child);
				WsXmlAttrH attr =
					ws_xml_find_node_attr(child,
							XML_NS_SCHEMA_INSTANCE,
							XML_NS_SCHEMA_INSTANCE_NIL);
				char *attr_val = ws_xml_get_attr_value(attr);
				if (attr && attr_val && (strcmp(attr_val, "true") == 0)) {
					continue;
				}
				debug("prop value: %s", value );
				if (value) {
					xml2property(instance, &data,
							CMGetCharPtr(propertyname),
							value, resource, resource_uri);
				}
			} else if (data.type != CMPI_null
					&& data.state != CMPI_nullValue) {
				status->fault_code = WXF_INVALID_REPRESENTATION;
				status->fault_detail_code =
					WSMAN_DETAIL_MISSING_VALUES;
				CMRelease(propertyname);
				break;
			} else {
				warning("cannot handle property");
			}
		}
		else {
			if(strcmp(element, CMGetCharPtr(propertyname) ) == 0) {
			  debug("release %s", element);
				CMRelease(propertyname);
				break;
			}
		}
		CMRelease(propertyname);
	}

	if(fragment_flag) {
		child = ws_xml_get_child(resource, 0, XML_NS_WS_MAN, WSM_XML_FRAGMENT);
		if(i == numproperties) {
			status->fault_code = WSMAN_INVALID_SELECTORS;
			status->fault_detail_code = WSMAN_DETAIL_UNEXPECTED_SELECTORS;
		}
		else {
			if(fragment_flag == 1) {
				child = ws_xml_get_child(resource, 0, NULL, element);
				if(child == NULL) {
					status->fault_code = WSMAN_INVALID_SELECTORS;
					status->fault_detail_code = WSMAN_DETAIL_UNEXPECTED_SELECTORS;
					goto cleanup;
				}
				value = ws_xml_get_node_text(child);
			}
			else
				value = ws_xml_get_node_text(resource);
			debug("prop value: %s", value );
			if (value) {
				xml2property(instance, &data,
						element, value, resource, NULL);
			}
		}
	}
cleanup:
	if (classname)
		CMRelease(classname);
	if (objectpath)
		CMRelease(objectpath);
	if (element)
		u_free(element);

	return;
}



void
xml2instance(CMPIInstance * instance, WsXmlNodeH body, char *resourceUri)
{
	int i, numproperties;
	CMPIString *namespace, *classname;
	CMPIObjectPath *objectpath = NULL;
	WsXmlNodeH r;

	objectpath = instance->ft->getObjectPath(instance, NULL);
	namespace = objectpath->ft->getNameSpace(objectpath, NULL);
	classname =objectpath->ft->getClassName(objectpath, NULL);

	numproperties = instance->ft->getPropertyCount(instance, NULL);
	r = ws_xml_get_child(body, 0, resourceUri, CMGetCharPtr(classname));

	if (numproperties) {
		for (i = 0; i < numproperties; i++) {
			CMPIString *propertyname;
			CMPIData data = instance->ft->getPropertyAt(instance,
					i, &propertyname,
					NULL);
			WsXmlNodeH child = ws_xml_get_child(r, 0,
					resourceUri,
					(char *)
					propertyname->
					hdl);

			char *value = ws_xml_get_node_text(child);
			if (value) {
				xml2property(instance, &data,
						CMGetCharPtr(propertyname),
						value, body, resourceUri);
			}
			CMRelease(propertyname);
		}
	}

	if (classname)
		CMRelease(classname);
	if (namespace)
		CMRelease(namespace);
	if (objectpath)
		CMRelease(objectpath);
}





void
cim_add_epr_details(CimClientInfo * client,
		WsXmlNodeH resource,
		char *resource_uri, CMPIObjectPath * objectpath)
{
	int numkeys = 0, i = 0;
	char *cv = NULL;

	ws_xml_add_child(resource, XML_NS_ADDRESSING, WSA_ADDRESS,
			WSA_TO_ANONYMOUS);
	numkeys = objectpath->ft->getKeyCount(objectpath, NULL);

	WsXmlNodeH refparam = ws_xml_add_child(resource,
			XML_NS_ADDRESSING,
			WSA_REFERENCE_PARAMETERS,
			NULL);
	ws_xml_add_child_format(refparam, XML_NS_WS_MAN, WSM_RESOURCE_URI,
			"%s", resource_uri);
	WsXmlNodeH wsman_selector_set = ws_xml_add_child(refparam,
			XML_NS_WS_MAN,
			WSM_SELECTOR_SET,
			NULL);

	if (0 < numkeys) {
		CMPIString * cim_namespace = objectpath->ft->getNameSpace(objectpath, NULL);
		char *str_namespace = client->cim_namespace;
		if (NULL != cim_namespace && NULL != CMGetCharPtr(cim_namespace)) {
			str_namespace = CMGetCharPtr(cim_namespace);
		}
		if (str_namespace != NULL) {
			WsXmlNodeH cimns = ws_xml_add_child(wsman_selector_set,
				XML_NS_WS_MAN, WSM_SELECTOR,
				(char *) str_namespace);
			ws_xml_add_node_attr(cimns, NULL, "Name",
				CIM_NAMESPACE_SELECTOR);
		}
	}

	for (i = 0; i < numkeys; i++) {
		CMPIString *keyname;
		CMPIData data =
			objectpath->ft->getKeyAt(objectpath, i, &keyname,
					NULL);
		WsXmlNodeH s = NULL;
		if (data.type == CMPI_ref) {
			s = ws_xml_add_child(wsman_selector_set,
					XML_NS_WS_MAN, WSM_SELECTOR,
					NULL);
			WsXmlNodeH epr = ws_xml_add_child(s,
					XML_NS_ADDRESSING,
					WSA_EPR, NULL);
			path2xml(client, epr, resource_uri, &data.value);
		} else {
			char *valuestr =
				value2Chars(data.type, &data.value);
			s = ws_xml_add_child(wsman_selector_set,
					XML_NS_WS_MAN, WSM_SELECTOR,
					valuestr);
			if (valuestr)
				free(valuestr);
		}
		ws_xml_add_node_attr(s, NULL, WSM_NAME, CMGetCharPtr(keyname));


		if (cv)
			free(cv);
		if (keyname)
			CMRelease(keyname);
	}
	return;
}

void
cim_add_epr(CimClientInfo * client,
		WsXmlNodeH resource,
		char *resource_uri, CMPIObjectPath * objectpath)
{
	WsXmlNodeH epr = ws_xml_add_child(resource,
			XML_NS_ADDRESSING, WSA_EPR,
			NULL);
	cim_add_epr_details(client, epr, resource_uri, objectpath);
	return;
}

CMCIClient *
cim_connect_to_cimom(char *cim_host,
		char *cim_port,
		char *cim_host_userid,
		char *cim_host_passwd,
		char *frontend,
		WsmanStatus * status)
{
	CMPIStatus rc;
        memset(&rc, 0, sizeof(CMPIStatus)); /* workaround for sfcb bug #2844812 */
	if (strcmp(frontend, "SfcbLocal") != 0) {
          if (get_cim_ssl())
            frontend = "https";
          else
            frontend = "http";
        }

	CMCIClient *cimclient = cmciConnect2(cim_host, frontend, cim_port,
			cim_host_userid,
			cim_host_passwd,
                        get_cim_verify(),
                        get_cim_trust_store(),
                        NULL, /* certFile */
                        NULL, /* keyFile */
                        &rc);

	if (cimclient == NULL) {
	        debug( "*** Connection to CIMOM %s://%s:%s failed with %d:%s", frontend, cim_host, cim_port, rc.rc, rc.msg ? CMGetCharPtr(rc.msg) : "?");
	} else {
		debug("new cimclient: 0x%8x", cimclient);
		debug("new cimclient: %d", cimclient->ft->ftVersion);
	}
	cim_to_wsman_status(rc, status);
	return cimclient;
}

void
cim_release_client(CimClientInfo * cimclient)
{
	if (cimclient->cc) {
		CMRelease((CMCIClient *) cimclient->cc);
	}
}

void
release_cmpi_data(CMPIData data)
{
        if (data.state == CMPI_nullValue)
                return;
        debug("release_cmpi_data, type = 0x%04x", data.type);
        switch(data.type)
        {
                case CMPI_string:
                        debug("release String");
                        CMRelease(data.value.string);
                        break;
                case CMPI_chars:
                        debug("free chars");
                        free (data.value.chars);
                        break;
                case CMPI_instance:
                        debug("release instance");
                        CMRelease(data.value.inst);
                        break;
                case CMPI_ref:
                        debug("release ref");
                        CMRelease(data.value.ref);
                        break;
                case CMPI_dateTime:
                        debug("release datetime");
                        CMRelease(data.value.dateTime);
                        break;
                default:
                        break;
        }
}


/*
 * Invoke 'EnumerateClassNames' intrinsic method
 *
 */

void
invoke_enumerate_class_names(CimClientInfo *client, WsXmlNodeH body, CMPIStatus *rc)
{
	CMPIObjectPath *op = newCMPIObjectPath(client->cim_namespace, "", NULL);
	CMCIClient *cc = (CMCIClient *)client->cc;
        unsigned long flags = client->flags;
        if (client->selectors && hash_lookup(client->selectors, (char *) "DeepInheritance"))
                flags |= CMPI_FLAG_DeepInheritance;
	CMPIEnumeration *classnames = cc->ft->enumClassNames(cc, op, flags, rc);

        debug("invoke_enumerate_class_names");
  
	if (classnames) {
		WsXmlNodeH node = ws_xml_add_child(body, client->resource_uri, client->method, NULL);
		while (classnames->ft->hasNext(classnames, NULL)) {
			CMPIData next = classnames->ft->getNext(classnames, NULL);
			char *name = CMGetCharPtr(CMObjectPathToString(next.value.ref, NULL));
			ws_xml_add_child(node, client->resource_uri, "name", name);
		}
	        CMRelease(classnames);
	}
	if (op)
		CMRelease(op);
}


/*
 * Invoke 'GetClass' intrinsic method
 *
 */

void
invoke_get_class(CimClientInfo *client, WsXmlNodeH body, CMPIStatus *rc)
{
	CMPIObjectPath *op = newCMPIObjectPath(client->cim_namespace, client->requested_class, NULL);
	CMCIClient *cc = (CMCIClient *)client->cc;
	CMPIConstClass *_class = cc->ft->getClass(cc, op,
		client->flags | (CMPI_FLAG_LocalOnly|CMPI_FLAG_IncludeQualifiers|CMPI_FLAG_IncludeClassOrigin),
		NULL, rc);

        debug("invoke_get_class");
  
	if (_class) {
		char *classname = CMGetCharPtr(_class->ft->getClassName(_class, rc));
		unsigned int property_count = _class->ft->getPropertyCount(_class, rc);

		/* <body><GetClass>...</GetClass> */
		WsXmlNodeH node = ws_xml_add_child(body, client->resource_uri, client->method, NULL);

		/* <GetClass><name>name</name> */
		ws_xml_add_child(node, client->resource_uri, "name", classname);
    
		debug("getClass: %s", classname);

	        qualifiers2xml(client, node, _class, NULL);

	        if (property_count > 0) {
		        unsigned int i = 0;
	      
		        /* <GetClass><properties>...</properties> */
		        WsXmlNodeH properties = ws_xml_add_child(node, client->resource_uri, "properties", NULL);			      
		        while (i < property_count) {
			        CMPIString *property_name;
			        CMPIData data = _class->ft->getPropertyAt(_class, i++, &property_name, rc);
			        if (rc->rc)
				        return;
			        WsXmlNodeH property = datatype2xml(client, properties, client->resource_uri, "property", CMGetCharPtr(property_name), &data);
			        qualifiers2xml(client, property, _class, CMGetCharPtr(property_name));
			}
		  
		}
    
		CMRelease(_class);			      
	}

	if (op)
		CMRelease(op);
}


void
cim_invoke_method(CimClientInfo * client,
		WsContextH cntx, WsXmlNodeH body, WsmanStatus * status)
{
	CMPIObjectPath *objectpath;
	CMCIClient *cc = (CMCIClient *) client->cc;
	WsXmlNodeH method_node = NULL;

	if (client->resource_uri
	    && strstr(client->resource_uri, XML_NS_CIM_CLASS) != NULL) {
	        /* Generic CIM uri given (pointing to abstract CIM_xxx class
		 * enumerate through all instances of this class to
		 * get the correct instance matching the selectors
		 */
		objectpath = cim_get_op_from_enum(client, status);
	} else {
		objectpath = newCMPIObjectPath(client->cim_namespace,
				client->requested_class, NULL);
		if (objectpath != NULL)
			cim_add_keys(objectpath, client->selectors);
	}

	if (objectpath != NULL) {
		CMPIStatus rc;
		CMPIArgs *argsin = NULL, *argsout = NULL;

	        memset(&rc, 0, sizeof(CMPIStatus));
		argsin = newCMPIArgs(NULL);

		u_free(status->fault_msg);
	        wsman_status_init(status);

		if (client->method_args && hash_count(client->method_args) > 0) {
			debug("adding method arguments");
			if (0 != cim_add_args(client, objectpath, argsin)) {
				status->fault_code = WSMAN_INVALID_PARAMETER;
				status->fault_detail_code = WSMAN_DETAIL_INVALID_VALUE;
				goto cleanup;
			}
		}

	        if (strstr(client->resource_uri, XML_NS_CIM_INTRINSIC) != NULL) {
			debug("Instrinsic op ?: %s", client->method);

			if (!strcmp(client->method, CIM_ACTION_ENUMERATE_CLASS_NAMES))
				invoke_enumerate_class_names(client, body, &rc);
			else if (!strcmp(client->method, CIM_ACTION_GET_CLASS))
				invoke_get_class(client, body, &rc);

		} else  {

			argsout = newCMPIArgs(NULL);
			CMPIData data = cc->ft->invokeMethod(cc, objectpath,
				client->method,
				argsin, argsout, &rc);
	  
			debug("invokeMethod(%s) rc=%d, msg=%s",
				client->method, rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : "<NULL>");

			method_node = ws_xml_add_empty_child_format(body,
				client->resource_uri,
				"%s_OUTPUT",
				client->method);

			if (rc.rc == 0) {
				property2xml(client, &data, "ReturnValue",
					method_node, client->resource_uri, 0, 1);
			}

		        release_cmpi_data(data);

			if (argsout) {
				int count = CMGetArgCount(argsout, NULL);
				int i = 0;
				for (i = 0; i < count; i++) {
					CMPIString *argname;
					data = CMGetArgAt(argsout, i, &argname, NULL);
					property2xml(client, &data,
							CMGetCharPtr(argname),
							method_node, client->resource_uri, 0, 0);
					CMRelease(argname);
				}
			}
	        }

		cim_to_wsman_status(rc, status);
		if (rc.msg)
			CMRelease(rc.msg);
cleanup:
		if (argsin)
			CMRelease(argsin);
		if (argsout)
			CMRelease(argsout);
	}

	if (objectpath)
		CMRelease(objectpath);

	return;
}





void
cim_delete_instance_from_enum(CimClientInfo * client, WsmanStatus * status)
{
	CMPIObjectPath *objectpath = NULL;
	CMPIStatus rc;
	CMCIClient *cc = (CMCIClient *) client->cc;

	if (!cc) {
		goto cleanup;
	}

	if ((objectpath = cim_get_op_from_enum(client, status)) != NULL) {
        u_free(status->fault_msg);
        wsman_status_init(status);
		rc = cc->ft->deleteInstance(cc, objectpath);
		if (rc.rc != 0) {
			cim_to_wsman_status(rc, status);
		}
		debug("deleteInstance rc=%d, msg=%s", rc.rc,
				(rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	}

	debug("fault: %d %d", status->fault_code,
			status->fault_detail_code);

cleanup:
	if (objectpath)
		CMRelease(objectpath);
	return;
}



void
cim_get_instance_from_enum(CimClientInfo * client,
		WsContextH cntx,
		WsXmlNodeH body, char *fragstr, WsmanStatus * status)
{
	CMPIInstance *instance;
	CMPIObjectPath *objectpath;
	CMPIStatus rc;
	CMCIClient *cc = (CMCIClient *) client->cc;

	if (!cc) {
		goto cleanup;
	}

	if ((objectpath = cim_get_op_from_enum(client, status)) != NULL) {
	        u_free(status->fault_msg);
	        wsman_status_init(status);
		instance = cc->ft->getInstance(cc, objectpath,
				CMPI_FLAG_IncludeClassOrigin,
				NULL, &rc);
		if (rc.rc == 0) {
			if (instance) {
				instance2xml(client, instance, fragstr, body, NULL);
			}
		} else {
			cim_to_wsman_status(rc, status);
		}
		debug("getInstance rc=%d, msg=%s", rc.rc,
				(rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
		if (instance)
			CMRelease(instance);
	}

	debug("fault: %d %d", status->fault_code,
			status->fault_detail_code);

	if (objectpath)
		CMRelease(objectpath);
cleanup:
	return;
}


void
cim_put_instance(CimClientInfo * client,
		WsContextH cntx,
		WsXmlNodeH in_body, WsXmlNodeH body, char *fragstr, WsmanStatus * status)
{
	CMPIInstance *instance = NULL;
	CMPIObjectPath *objectpath;
	CMPIStatus rc;
	WsXmlNodeH resource = NULL;
	CMCIClient *cc = (CMCIClient *) client->cc;
	CMPIConstClass *class = NULL;

	objectpath = newCMPIObjectPath(client->cim_namespace,
			client->requested_class, NULL);
        if (!objectpath) {
		status->fault_code = WXF_INVALID_REPRESENTATION;
		status->fault_detail_code = WSMAN_DETAIL_INVALID_NAMESPACE;
	        goto cleanup;
	}
	if (fragstr == NULL) {
		resource = ws_xml_get_child(in_body, 0, client->resource_uri,
				client->requested_class);
	}
	else {
		resource = ws_xml_get_child(in_body, 0, XML_NS_WS_MAN, WSM_XML_FRAGMENT);
	}
	if (!resource) {
		status->fault_code = WXF_INVALID_REPRESENTATION;
		status->fault_detail_code = WSMAN_DETAIL_INVALID_NAMESPACE;
		goto cleanup;
	}

	cim_add_keys(objectpath, client->selectors);

	instance = newCMPIInstance(objectpath, NULL);
	if (!instance) {
		status->fault_code = WXF_INVALID_REPRESENTATION;
		status->fault_detail_code = WSMAN_DETAIL_INVALID_NAMESPACE;
		goto cleanup;
	}

	class = cim_get_class(client, client->requested_class,
			CMPI_FLAG_IncludeQualifiers,
			status);
	if (class) {
		create_instance_from_xml(instance, class, resource,
				fragstr, client->resource_uri, status);
		CMRelease(class);
	}
	if (status->fault_code == 0 && instance ) {
		CMPIString *opstr = CMObjectPathToString(objectpath, NULL);
		debug("objectpath: %s", CMGetCharPtr(opstr) );
		rc = cc->ft->setInstance(cc, objectpath, instance, 0, NULL);
		debug("modifyInstance() rc=%d, msg=%s", rc.rc,
				(rc.msg) ? (char *) CMGetCharPtr(rc.msg) : NULL);
		cim_to_wsman_status(rc, status);
		if (rc.rc == CMPI_RC_OK) {
			// return the current representation of the resource
			instance = cc->ft->getInstance(cc, objectpath,
					CMPI_FLAG_IncludeClassOrigin,
					NULL, &rc);
			instance2xml(client, instance, fragstr, body, NULL);
		}

		if (rc.msg)
			CMRelease(rc.msg);
	}
cleanup:
	if (objectpath)
		CMRelease(objectpath);
	if (instance)
		CMRelease(instance);
	return;
}


void
cim_create_instance(CimClientInfo * client,
		WsContextH cntx,
		WsXmlNodeH in_body,
		WsXmlNodeH body, char *fragstr, WsmanStatus * status)
{

	CMPIInstance *instance = NULL;
	CMPIObjectPath *objectpath, *objectpath_r;
	CMPIStatus rc;
	CMPIConstClass *class;
	int fragment_flag;
	char *element = NULL;
	int index;
	WsXmlNodeH resource;
	char *resource_xsd = NULL;
	WsXmlNodeH child = NULL;
	int numproperties = 0, i;

	CMCIClient *cc = (CMCIClient *) client->cc;
	objectpath = newCMPIObjectPath(client->cim_namespace,
			client->requested_class, NULL);
        /* now ask the CIMOM for the class definition */
	class = cim_get_class(client, client->requested_class,
			CMPI_FLAG_IncludeQualifiers, status);
	if (!class) {
	        /* couldn't connect to CIMOM */
		status->fault_code = WSA_ENDPOINT_UNAVAILABLE;
	        status->fault_detail_code = OWSMAN_DETAIL_ENDPOINT_ERROR;
		goto cleanup;
	}
        numproperties = class->ft->getPropertyCount(class, NULL);
	debug("cim_create_instance: class %s, %d properties", client->requested_class, numproperties);
	if(fragstr == NULL) {
		resource = ws_xml_get_child(in_body, 0, client->resource_uri,
				client->requested_class);
	        if(!resource) {
		        /* cim_data_stubs allows .xsd suffix for the namespace
			 * follow this convention here.
			 */
			resource_xsd = u_strdup_printf("%s.xsd", client->resource_uri);
		        resource = ws_xml_get_child(in_body, 0, resource_xsd,
				client->requested_class);
		}
	}
	else {
		resource = ws_xml_get_child(in_body, 0, XML_NS_WS_MAN, WSM_XML_FRAGMENT);
	}
	if (!resource) {
		status->fault_code = WXF_INVALID_REPRESENTATION;
		status->fault_detail_code = WSMAN_DETAIL_INVALID_NAMESPACE;
		goto cleanup;
	}
	wsman_get_fragment_type(fragstr, &fragment_flag, &element, &index);

	/*
	 * Add keys (according to class definition)
	 */
	for (i = 0; i < numproperties; i++) {
		CMPIString *propertyname;
                /* retrieve property type (in data) and name (in propertyname) */
	        CMPIData data = class->ft->getPropertyAt(class, i, &propertyname, NULL);
		class->ft->getPropertyQualifier(class, CMGetCharPtr(propertyname), "KEY", &rc);

		if (rc.rc == 0
		    && fragstr == NULL
		    && !ws_xml_get_child(resource, 0,
					resource_xsd ? resource_xsd : client->resource_uri,
					CMGetCharPtr(propertyname))) {
			debug("WXF_INVALID_REPRESENTATION");
			debug("No <%s:%s>", resource_xsd ? resource_xsd : client->resource_uri, CMGetCharPtr(propertyname));
			status->fault_code = WXF_INVALID_REPRESENTATION;
			status->fault_detail_code = WSMAN_DETAIL_MISSING_VALUES;
			break;
		} else if (rc.rc == 0) {
			if(fragstr == NULL) {
				child = ws_xml_get_child(resource, 0,
							 resource_xsd ? resource_xsd : client->resource_uri, CMGetCharPtr(propertyname));
			}
			else {
				if(strcmp(element, CMGetCharPtr(propertyname))) {
					CMRelease(propertyname);
					continue;
				}
				if(fragment_flag == 1 || fragment_flag == 3)
					child = ws_xml_get_child(resource, 0, NULL, element);
			}

			/* assemble objectpath, passing value with correct type */
		        xml2objectpath(objectpath, &data, CMGetCharPtr(propertyname), ws_xml_get_node_text(child));

			if(fragstr && strcmp(element, CMGetCharPtr(propertyname)) == 0) {
			  debug("fragstr, early break");
				CMRelease(propertyname);
				break;
			}
		}
		CMRelease(propertyname);
	}

	if(fragstr && i == numproperties) {
		status->fault_code = WSMAN_INVALID_SELECTORS;
		status->fault_detail_code = WSMAN_DETAIL_UNEXPECTED_SELECTORS;
		goto cleanup;
	}
      
        /* create a new (empty) instance */
	instance = newCMPIInstance(objectpath, NULL);
	debug("newCMPIInstance(%s) = %p", CMGetCharPtr(CMObjectPathToString(objectpath, NULL)), instance);
	if (!instance) {
                debug("newCMPIInstance failed");
		goto cleanup;
	}

        /* write properties to the instance */
	create_instance_from_xml(instance, class,
			resource, fragstr, client->resource_uri, status);
	if (status->fault_code == 0) {
		objectpath_r = cc->ft->createInstance(cc, objectpath, instance, &rc);
		debug("createInstance() rc=%d, msg=%s", rc.rc,
				(rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
		if (objectpath_r) {
			WsXmlNodeH epr = ws_xml_add_child(body, XML_NS_TRANSFER,
					WXF_RESOURCE_CREATED,
					NULL);
			cim_add_epr_details(client, epr, client->resource_uri,
					objectpath_r);
		}
		if (rc.rc == CMPI_RC_ERR_FAILED) {
			status->fault_code = WSA_ACTION_NOT_SUPPORTED;
		} else {
			cim_to_wsman_status(rc, status);
		}
		if (rc.msg)
			CMRelease(rc.msg);
	}
cleanup:
	if (resource_xsd)
		u_free(resource_xsd);	
	if (class)
		CMRelease(class);
	if (instance)
		CMRelease(instance);
	if (objectpath)
		CMRelease(objectpath);
	if (element)
		u_free(element);
	return;
}

void
cim_delete_instance(CimClientInfo * client, WsmanStatus * status)
{
	CMPIObjectPath *objectpath;
	CMPIStatus rc;

	CMCIClient *cc = (CMCIClient *) client->cc;
	CMPIConstClass *class =
		cim_get_class(client, client->requested_class,
				CMPI_FLAG_IncludeQualifiers,
				status);
	if (!class)
		goto cleanup;

	cim_verify_class_keys(class, client->selectors, status);
	if (status->fault_code != 0)
		goto cleanup;
	objectpath = newCMPIObjectPath(client->cim_namespace,
			client->requested_class, NULL);

	cim_add_keys(objectpath, client->selectors);
	rc = cc->ft->deleteInstance(cc, objectpath);
	/* Print the results */
	debug("deleteInstance() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	cim_to_wsman_status(rc, status);
	if (rc.msg)
		CMRelease(rc.msg);
	if (objectpath)
		CMRelease(objectpath);
cleanup:
	return;

}


CMPIInstance *
cim_get_instance_from_selectors(CimClientInfo * client,
		WsContextH cntx, WsmanStatus * status)
{
	CMPIInstance *instance = NULL;
	CMPIObjectPath *objectpath = NULL;
	CMPIStatus rc;

	CMCIClient *cc = (CMCIClient *) client->cc;

	CMPIConstClass *class = cim_get_class(client,
			client->requested_class,
			CMPI_FLAG_IncludeQualifiers,
			status);
	if (!class)
		goto cleanup;

	cim_verify_class_keys(class, client->selectors, status);
	if (status->fault_code != 0)
		goto cleanup;

	objectpath = newCMPIObjectPath(client->cim_namespace,
			client->requested_class, NULL);

	cim_add_keys(objectpath, client->selectors);
	instance = cc->ft->getInstance(cc, objectpath,
			CMPI_FLAG_DeepInheritance, NULL,
			&rc);
	/* Print the results */
	debug("getInstance() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	cim_to_wsman_status(rc, status);
	if (rc.msg)
		CMRelease(rc.msg);
cleanup:
	if (objectpath)
		CMRelease(objectpath);
	if (class)
		CMRelease(class);
	return instance;

}

CMPIObjectPath *
cim_get_indicationfilter_objectpath_from_selectors(CimClientInfo * client,
        WsContextH cntx, WsmanStatus * status)
{
    CMPIObjectPath *objectpath = NULL;

    CMPIConstClass *class = NULL;

    objectpath = newCMPIObjectPath(
            get_indication_profile_implementation_ns(),
            client->requested_class, NULL);

    if(objectpath) {
        CMPIStatus rc;
        CMCIClient *cc = (CMCIClient *)client->cc;
        class = cc->ft->getClass(cc,
                                 objectpath,
                                 CMPI_FLAG_IncludeQualifiers,
                                 NULL,
                                 &rc);
        if (!class){
            CMRelease(objectpath);
            goto cleanup;
        }

        cim_verify_class_keys(class, client->selectors, status);
        if (status->fault_code != 0){
            CMRelease(objectpath);
            goto cleanup;
        }

        cim_add_keys(objectpath, client->selectors);
    }
cleanup:
    if (class)
        CMRelease(class);
    return objectpath;

}

CMPIObjectPath *
cim_get_objectpath_from_selectors(CimClientInfo * client,
		WsContextH cntx, WsmanStatus * status)
{
	CMPIObjectPath *objectpath = NULL;
	CMPIConstClass *class = cim_get_class(client,
			client->requested_class,
			CMPI_FLAG_IncludeQualifiers,
			status);
	if (!class)
		goto cleanup;

	cim_verify_class_keys(class, client->selectors, status);
	if (status->fault_code != 0)
		goto cleanup;

	objectpath = newCMPIObjectPath(client->cim_namespace,
			client->requested_class, NULL);

	cim_add_keys(objectpath, client->selectors);
cleanup:
	if (class)
		CMRelease(class);
	return objectpath;

}

void
cim_get_instance(CimClientInfo * client,
		WsContextH cntx, WsXmlNodeH body, char *fragstr, WsmanStatus * status)
{
	CMPIInstance *instance = cim_get_instance_from_selectors(client, cntx, status);
	if(instance) {
		instance2xml(client, instance, fragstr, body, NULL);
		CMRelease(instance);
	}
}

static CMPIObjectPath *
cim_indication_filter_objectpath(CimClientInfo *client,
		WsSubscribeInfo *subsInfo, CMPIStatus *rc)
{
	CMPIObjectPath *objectpath_filter = newCMPIObjectPath(
            get_indication_profile_implementation_ns(),
			"CIM_IndicationFilter", rc);
	CMAddKey(objectpath_filter, "SystemCreationClassName",
			SYSTEMCREATIONCLASSNAME, CMPI_chars);
	CMAddKey(objectpath_filter, "SystemName",
			SYSTEMNAME, CMPI_chars);
	CMAddKey(objectpath_filter, "CreationClassName",
			"CIM_IndicationFilter", CMPI_chars);
	CMAddKey(objectpath_filter, "Name",
			subsInfo->subsId, CMPI_chars);
	return objectpath_filter;
}

static CMPIObjectPath
*cim_indication_handler_objectpath(CimClientInfo *client, WsSubscribeInfo *subsInfo, CMPIStatus *rc)
{
	CMPIObjectPath *objectpath_handler = newCMPIObjectPath(
            get_indication_profile_implementation_ns(),
			"CIM_IndicationHandlerCIMXML", rc);
	CMAddKey(objectpath_handler, "SystemCreationClassName",
			SYSTEMCREATIONCLASSNAME, CMPI_chars);
	CMAddKey(objectpath_handler, "SystemName",
			SYSTEMNAME, CMPI_chars);
	CMAddKey(objectpath_handler, "CreationClassName",
			"CIM_IndicationHandlerCIMXML", CMPI_chars);
	CMAddKey(objectpath_handler, "Name",
			subsInfo->subsId, CMPI_chars);
	return objectpath_handler;
}

CMPIObjectPath *
cim_create_indication_filter(CimClientInfo *client, WsSubscribeInfo *subsInfo, WsmanStatus *status)
{
	CMPIInstance *instance = NULL;
	CMPIObjectPath *objectpath = NULL;
	CMPIObjectPath *objectpath_r = NULL;
	CMPIObjectPath *filter_op = NULL;
	CMPIStatus rc;

	CMCIClient *cc = (CMCIClient *) client->cc;

	objectpath = cim_indication_filter_objectpath(client, subsInfo, &rc);
	if(rc.rc)
		goto cleanup;
	filter_op = CMClone(objectpath, &rc);
	CMAddKey(objectpath, "Query",
			subsInfo->filter->query, CMPI_chars);
	if(subsInfo->flags & WSMAN_SUBSCRIPTION_WQL)
		CMAddKey(objectpath, "QueryLanguage",
				"WQL",CMPI_chars);
	else if(subsInfo->flags & WSMAN_SUBSCRIPTION_CQL)
		CMAddKey(objectpath, "QueryLanguage",
				"CQL",CMPI_chars);
	char *indicationns = subsInfo->cim_namespace;
	if(indicationns)
		CMAddKey(objectpath, "SourceNamespace",
				indicationns, CMPI_chars);
	instance = newCMPIInstance(objectpath, NULL);
	objectpath_r = cc->ft->createInstance(cc, objectpath, instance, &rc);
cleanup:
	/* Print the results */
	debug("create CIM_IndicationFilter() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	if (rc.rc == CMPI_RC_ERR_FAILED) {
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
	} else if(rc.rc != 11){ // an object already exists. We take this erros as success
		cim_to_wsman_status(rc, status);
	}
	if (rc.msg)
		CMRelease(rc.msg);
	if (objectpath_r)
		CMRelease(objectpath_r);
	if (objectpath)
		CMRelease(objectpath);
	if (instance)
		CMRelease(instance);
	return filter_op;
}
static char *
create_cimxml_listener_path(char *uuid)
{
	char path[128];
	snprintf(path, 128, "/cimindicationlistener/%s", uuid);
	return u_strdup(path);
}


CMPIObjectPath *
cim_create_indication_handler(CimClientInfo *client, WsSubscribeInfo *subsInfo, WsmanStatus *status)
{
	CMPIInstance *instance = NULL;
	CMPIObjectPath *objectpath = NULL;
	CMPIObjectPath *objectpath_r = NULL;
	CMPIObjectPath *handler_op = NULL;
	CMPIStatus rc;

	CMCIClient *cc = (CMCIClient *) client->cc;

	objectpath = cim_indication_handler_objectpath(client, subsInfo, &rc);
	if(rc.rc)
		goto cleanup;
	handler_op = CMClone(objectpath, &rc);

	instance = newCMPIInstance(objectpath, NULL);

	char *servicepath = create_cimxml_listener_path(subsInfo->subsId);
	char serverpath[128];
#if 0
  /* might be a security risk */
	snprintf(serverpath, 128, "http://%s:%s@localhost:%s%s", client->username, client->password,
			get_server_port(), servicepath);
#else
	snprintf(serverpath, 128, "http://localhost:%s%s", get_server_port(), servicepath);
#endif
	u_free(servicepath);
	CMPIValue value;
	value.uint16 = 2;
	CMSetProperty(instance, "Destination",
			serverpath, CMPI_chars);
	CMSetProperty(instance, "PersistenceType",
			&value, CMPI_uint16);


	objectpath_r = cc->ft->createInstance(cc, objectpath, instance, &rc);
cleanup:
	/* Print the results */
	debug("create CIM_IndicationHandlerCIMXML() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	if (rc.rc == CMPI_RC_ERR_FAILED) {
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
	} else if(rc.rc != 11){ // an object already exists. We take this erros as success
		cim_to_wsman_status(rc, status);
	}
	if (rc.msg)
		CMRelease(rc.msg);
	if (objectpath_r)
		CMRelease(objectpath_r);
	if (objectpath)
		CMRelease(objectpath);
	if (instance)
		CMRelease(instance);
	return handler_op;
}

void
cim_create_indication_subscription(CimClientInfo * client, WsSubscribeInfo *subsInfo, CMPIObjectPath *filter, CMPIObjectPath *handler, WsmanStatus *status)
{
	CMPIInstance *instance = NULL;
	CMPIObjectPath *instance_r = NULL;
	CMPIObjectPath *objectpath = NULL;
	CMPIStatus rc;

	CMCIClient *cc = (CMCIClient *) client->cc;
	//	CMPIObjectPath *objectpath_filter = cim_indication_filter_objectpath(client, subsInfo, &rc);
	//	if(rc.rc) goto cleanup;
	//	objectpath_handler = cim_indication_handler_objectpath(client, subsInfo, &rc);
	//	if(rc.rc) goto cleanup;

	objectpath = newCMPIObjectPath(
            get_indication_profile_implementation_ns(),
			"CIM_IndicationSubscription", NULL);
	CMPIValue value;
	value.ref = filter;
	CMAddKey(objectpath, "Filter",
			&value, CMPI_ref);
	value.ref = handler;
	CMAddKey(objectpath, "Handler",
			&value, CMPI_ref);
        instance = newCMPIInstance(objectpath, NULL);
	//set OnFatalErrorPolicy to "Ignore"
	value.uint16 = 2;
        CMSetProperty(instance, "OnFatalErrorPolicy",
			&value, CMPI_uint16);
	//enable subscription
	value.uint16 = 2;
        CMSetProperty(instance, "SubscriptionState",
			&value, CMPI_uint16);
	if(subsInfo->expires) {
		struct timeval  tv;
		gettimeofday(&tv, NULL);
		value.uint64 = subsInfo->expires - tv.tv_sec;
                CMSetProperty(instance, "SubscriptionDuration",
				&value, CMPI_uint64);
	}
	//set RepeatNotificationPolicy to None
	value.uint16 = 2;
        CMSetProperty(instance, "RepeatNotificationPolicy",
			&value, CMPI_uint16);
	instance_r = cc->ft->createInstance(cc, objectpath, instance, &rc);

	/* Print the results */
	debug("create CIM_IndicationSubscription() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	if (rc.rc == CMPI_RC_ERR_FAILED) {
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
	} else if (rc.rc != 11){ // an object already exists. We take this erros as success
		cim_to_wsman_status(rc, status);
	}
	if (rc.msg)
		CMRelease(rc.msg);
	if (objectpath)
		CMRelease(objectpath);
	if (instance)
		CMRelease(instance);
	if (instance_r)
		CMRelease(instance_r);
	return;
}

void
cim_update_indication_subscription(CimClientInfo *client, WsSubscribeInfo *subsInfo, WsmanStatus *status)
{
	CMPIObjectPath *objectpath = NULL;
	CMPIInstance *instance = NULL;
	CMPIStatus rc;
	CMPIObjectPath *objectpath_handler = NULL;
	CMCIClient *cc = (CMCIClient *) client->cc;

	CMPIObjectPath *objectpath_filter = NULL;
	if(subsInfo->flags & WSMAN_SUBSCRIPTION_SELECTORSET)
		objectpath_filter = subsInfo->existingfilterOP;
	else {
		objectpath_filter = cim_indication_filter_objectpath(client, subsInfo, &rc);
		if(rc.rc)
			goto cleanup;
	}
	objectpath_handler = cim_indication_handler_objectpath(client, subsInfo, &rc);
	if(rc.rc)
		goto cleanup;
	objectpath = newCMPIObjectPath(
            get_indication_profile_implementation_ns(),
			"CIM_IndicationSubscription", NULL);
	CMPIValue value;
	value.ref = objectpath_filter;
	CMAddKey(objectpath, "Filter",
			&value, CMPI_ref);
	value.ref = objectpath_handler;
	CMAddKey(objectpath, "Handler",
			&value, CMPI_ref);
	struct timeval  tv;
	gettimeofday(&tv, NULL);
	value.uint64 = subsInfo->expires - tv.tv_sec;
	instance = newCMPIInstance(objectpath, NULL);
	CMSetProperty(instance, "subscriptionDuration", &value, CMPI_uint64);
	char *properties[] = {"subscriptionDuration",NULL};
	cc->ft->setInstance(cc, objectpath, instance, 0, properties);
cleanup:
	if (rc.rc == CMPI_RC_ERR_FAILED) {
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
	} else {
		cim_to_wsman_status(rc, status);
	}
	debug("cim_update_indication_subscription() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	if (rc.msg)
		CMRelease(rc.msg);
	if (!(subsInfo->flags & WSMAN_SUBSCRIPTION_SELECTORSET) && objectpath_filter)
		CMRelease(objectpath_filter);
	if (objectpath_handler)
		CMRelease(objectpath_handler);
	if (instance)
		CMRelease(instance);
	if (objectpath)
		CMRelease(objectpath);
	return;
}

void
cim_delete_indication_subscription(CimClientInfo *client, WsSubscribeInfo *subsInfo, WsmanStatus *status)
{
	CMPIStatus rc;
	CMPIObjectPath *objectpath_subscription = NULL;
	CMCIClient *cc = (CMCIClient *) client->cc;
	CMPIObjectPath *objectpath_handler = NULL;
	CMPIObjectPath *objectpath_filter = NULL;
	if(subsInfo->flags & WSMAN_SUBSCRIPTION_SELECTORSET) {
		objectpath_filter = subsInfo->existingfilterOP;
	}
	else{
		objectpath_filter = cim_indication_filter_objectpath(client, subsInfo, &rc);
		if(rc.rc)
			goto cleanup;
	}
	objectpath_handler = cim_indication_handler_objectpath(client, subsInfo, &rc);
	if(rc.rc)
		goto cleanup;
	objectpath_subscription = newCMPIObjectPath(
            get_indication_profile_implementation_ns(),
			"CIM_IndicationSubscription", &rc);
	if(rc.rc)
		goto cleanup;
	CMPIValue value;
	value.ref = objectpath_filter;
	CMAddKey(objectpath_subscription, "Filter",
			&value, CMPI_ref);
	value.ref = objectpath_handler;
	CMAddKey(objectpath_subscription, "Handler",
			&value, CMPI_ref);
	rc = cc->ft->deleteInstance(cc, objectpath_subscription);
	if(rc.rc)
		goto cleanup;
	if(!(subsInfo->flags & WSMAN_SUBSCRIPTION_SELECTORSET)) {
		rc = cc->ft->deleteInstance(cc, objectpath_filter);
		if(rc.rc)
			goto cleanup;
	}
	rc = cc->ft->deleteInstance(cc, objectpath_handler);

cleanup:
	if (rc.rc == CMPI_RC_ERR_FAILED) {
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
	} else {
		cim_to_wsman_status(rc, status);
	}
	debug("cim_delete_indication_subscription() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);
	if (rc.msg)
		CMRelease(rc.msg);
	if (objectpath_filter)
		CMRelease(objectpath_filter);
	if (objectpath_handler)
		CMRelease(objectpath_handler);
	if (objectpath_subscription)
		CMRelease(objectpath_subscription);
	return;
}

void
cim_to_wsman_status(CMPIStatus rc, WsmanStatus * status)
{
	if (!status) {
		return;
	}
	switch (rc.rc) {
	case CMPI_RC_OK:
		status->fault_code = WSMAN_RC_OK;
		break;
	case CMPI_RC_ERR_INVALID_CLASS:
		status->fault_code = WSA_DESTINATION_UNREACHABLE;
		status->fault_detail_code =
			WSMAN_DETAIL_INVALID_RESOURCEURI;
		break;
	case CMPI_RC_ERR_FAILED:
		if (rc.msg && strcmp(CMGetCharPtr(rc.msg), "CURL error: 7") == 0)
			status->fault_code = WSA_DESTINATION_UNREACHABLE;
		else
			status->fault_code = WSMAN_INTERNAL_ERROR;
		break;
	case CMPI_RC_ERR_METHOD_NOT_AVAILABLE:
	case CMPI_RC_ERR_METHOD_NOT_FOUND:
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
		break;
	case CMPI_RC_ERR_INVALID_NAMESPACE:
	case CMPI_RC_ERR_NOT_FOUND:
		status->fault_code = WSA_DESTINATION_UNREACHABLE;
		break;
	case CMPI_RC_ERR_ACCESS_DENIED:
		status->fault_code = WSMAN_ACCESS_DENIED;
		break;
	case CMPI_RC_ERR_INVALID_PARAMETER:
		status->fault_code = WSMAN_INVALID_PARAMETER;
		status->fault_detail_code = WSMAN_DETAIL_MISSING_VALUES;
		break;
	case CMPI_RC_ERR_NOT_SUPPORTED:
		status->fault_code = WSA_ACTION_NOT_SUPPORTED;
		break;
	case CMPI_RC_ERR_CLASS_HAS_CHILDREN:
	case CMPI_RC_ERR_CLASS_HAS_INSTANCES:
	case CMPI_RC_ERR_INVALID_SUPERCLASS:
	case CMPI_RC_ERR_ALREADY_EXISTS:
		status->fault_code = WSMAN_ALREADY_EXISTS;
		break;
	case CMPI_RC_ERR_INVALID_QUERY:
		status->fault_code = WSEN_CANNOT_PROCESS_FILTER;
		break;
	case CMPI_RC_ERR_NO_SUCH_PROPERTY:
	case CMPI_RC_ERR_TYPE_MISMATCH:
	case CMPI_RC_ERR_QUERY_LANGUAGE_NOT_SUPPORTED:
	case CMPI_RC_DO_NOT_UNLOAD:
	case CMPI_RC_NEVER_UNLOAD:
	case CMPI_RC_ERROR_SYSTEM:
	case CMPI_RC_ERROR:
	default:
		status->fault_code = WSMAN_UNKNOWN;
	}
        if (rc.msg) {
	   status->fault_msg = u_strdup(CMGetCharPtr(rc.msg));
	}
}


void
cim_release_enum_context(WsEnumerateInfo * enumInfo)
{
	if (!(enumInfo && enumInfo->appEnumContext))
		return;

	debug("releasing enumInfo->appEnumContext");
	sfcc_enumcontext *enumcontext = enumInfo->appEnumContext;
	CMPIEnumeration *enumeration;
	CimClientInfo *client;

	enumeration = enumcontext->ecEnumeration;
	client = enumcontext->ecClient;

	if (enumeration) {
		debug("released enumeration");
		CMRelease(enumeration);
	}
	u_free(enumcontext);
}

CimClientInfo *
cim_getclient_from_enum_context(WsEnumerateInfo * enumInfo)
{
	CimClientInfo *cimclient = NULL;
	if (enumInfo && enumInfo->appEnumContext) {
		sfcc_enumcontext *enumcontext =
			(sfcc_enumcontext *) enumInfo->appEnumContext;
		cimclient = enumcontext->ecClient;
	}
	return cimclient;
}

CMPIArray *
cim_enum_instancenames(CimClientInfo * client,
		char *class_name, WsmanStatus * status)
{
	CMPIStatus rc;
	CMPIObjectPath *objectpath;
	CMPIEnumeration *enumeration;

	CMCIClient *cc = (CMCIClient *) client->cc;

	objectpath =
		newCMPIObjectPath(client->cim_namespace, class_name, NULL);

	enumeration = cc->ft->enumInstanceNames(cc, objectpath, &rc);
	debug("enumInstanceNames() rc=%d, msg=%s",
			rc.rc, (rc.msg) ? CMGetCharPtr(rc.msg) : NULL);

	if (rc.rc) {
		debug("*** CMCIClient enumInstanceNames() failed");
		cim_to_wsman_status(rc, status);
		return NULL;
	}
	CMPIArray *enumArr = enumeration->ft->toArray(enumeration, NULL);
	debug("Total enumeration items: %d",
			enumArr->ft->getSize(enumArr, NULL));
	cim_to_wsman_status(rc, status);
	return enumArr;
}


CMPICount
cim_enum_totalItems(CMPIArray * enumArr)
{
	return enumArr->ft->getSize(enumArr, NULL);
}


char *
cim_get_property(CMPIInstance * instance, char *property)
{
	CMPIStatus rc;
	CMPIData data = instance->ft->getProperty(instance, property, &rc);
	char *valuestr = NULL;
	if (CMIsArray(data)) {
		return NULL;
	} else {
		if (data.type != CMPI_null && data.state != CMPI_nullValue) {

			if (data.type != CMPI_ref) {
				valuestr =
					value2Chars(data.type, &data.value);
			}
		}
	}
	return valuestr;
}

char *
cim_get_keyvalue(CMPIObjectPath * objpath, char *keyname)
{
	CMPIStatus status;
	char *valuestr;
	debug("Get key property from objpath");

	if (!objpath) {
		debug("objpath is NULL");
		return "";
	}

	CMPIData data = objpath->ft->getKey(objpath, keyname, &status);
	if (status.rc || CMIsArray(data)) {
		return "";
	} else {
		valuestr = value2Chars(data.type, &data.value);
		return valuestr;
	}
}

void
cim_get_enum_items(CimClientInfo * client,
		WsContextH cntx,
		WsXmlNodeH node,
		WsEnumerateInfo * enumInfo,
		char *namespace,
		int maxelements,
		unsigned long maxsize)
{
	WsXmlNodeH itemsNode;
	WsXmlDocH outdoc = NULL;
        int c;
        int count = 0;
	if (node == NULL)
		return;

	itemsNode = ws_xml_add_child(node, namespace, WSENUM_ITEMS, NULL);
	debug("Total items: %d", enumInfo->totalItems);
	debug("enum flags: %lu", enumInfo->flags );

	outdoc = ws_xml_get_node_doc(node);
	if (enumInfo->totalItems > 0) {
                if (maxelements <= 0) {
                        maxelements = -1; /* don't check maxelements */
                }
		while (enumInfo->index >= 0 &&
				enumInfo->index < enumInfo->totalItems) {
			if (enumInfo->flags & WSMAN_ENUMINFO_EPR ) {
				c = cim_getEprAt(client, enumInfo, itemsNode);
			} else if (enumInfo->flags & WSMAN_ENUMINFO_OBJEPR) {
				c = cim_getEprObjAt(client, enumInfo, itemsNode);
			} else {
				c = cim_getElementAt(client, enumInfo, itemsNode);
			}
                        if (!c) {
                                /* cim_getE... failed */
                                break;
                        }
			if (check_envelope_size(outdoc, maxsize, enumInfo->encoding)) {
                                /* last item added to itemsNode exceeded the envelope size */
                                if (count > 0) {
                                        /* if there's already a partial result,
                                         * remove last child from itemsNode
                                         * and return partial result */
                                        WsXmlNodeH item = xml_parser_node_get(itemsNode, XML_LAST_CHILD);
                                        xml_parser_node_remove(item);
                                }
                                /* if the first item already exceeds the envelope size, leave it
                                 * and let the SOAP report an EncodingLimit fault.
                                 */
				break;
			}
			enumInfo->index++;
                        count++;
			maxelements--;
                        if (maxelements == 0) {
                                break;
                        }
		}
		enumInfo->index--; /* callee (wsman-soap.c) increments it again */
	}
	enumInfo->pullResultPtr = outdoc;
}
