static int xacml_resource_unmarshal(xacml_resource_t ** res, const hessian_object_t * h_resource) {
    const char * map_type;
    xacml_resource_t * resource;
    size_t map_l;
    int i, j;
    if (hessian_gettype(h_resource) != HESSIAN_MAP) {
        log_error("xacml_resource_unmarshal: wrong Hessian type: %d (%s).", hessian_gettype(h_resource), hessian_getclassname(h_resource));
        return PEP_IO_ERROR;
    }
    map_type= hessian_map_gettype(h_resource);
    if (map_type == NULL) {
        log_error("xacml_resource_unmarshal: NULL Hessian map type.");
        return PEP_IO_ERROR;
    }
    if (strcmp(XACML_HESSIAN_RESOURCE_CLASSNAME,map_type) != 0) {
        log_error("xacml_resource_unmarshal: wrong Hessian map type: %s.",map_type);
        return PEP_IO_ERROR;
    }

    resource= xacml_resource_create();
    if (resource == NULL) {
        log_error("xacml_resource_unmarshal: can't create XACML resource.");
        return PEP_IO_ERROR;
    }

    /* parse all map pair<key>s */
    map_l= hessian_map_length(h_resource);
    for(i= 0; i<map_l; i++) {
        hessian_object_t * h_map_key= hessian_map_getkey(h_resource,i);
        const char * key;
        if (hessian_gettype(h_map_key) != HESSIAN_STRING) {
            log_error("xacml_resource_unmarshal: Hessian map<key> is not an Hessian string at: %d.",i);
            xacml_resource_delete(resource);
            return PEP_IO_ERROR;
        }
        key= hessian_string_getstring(h_map_key);
        if (key == NULL) {
            log_error("xacml_resource_unmarshal: Hessian map<key>: NULL string at: %d.",i);
            xacml_resource_delete(resource);
            return PEP_IO_ERROR;
        }
        /* content (can be null) */
        if (strcmp(XACML_HESSIAN_RESOURCE_CONTENT,key) == 0) {
            hessian_object_t * h_string= hessian_map_getvalue(h_resource,i);
            hessian_t h_string_type= hessian_gettype(h_string);
            const char * content;
            if ( h_string_type != HESSIAN_STRING && h_string_type != HESSIAN_NULL) {
                log_error("xacml_resource_unmarshal: Hessian map<'%s',value> is not a Hessian string or null at: %d.",key,i);
                xacml_resource_delete(resource);
                return PEP_IO_ERROR;
            }
            content= NULL;
            if (h_string_type == HESSIAN_STRING) {
                content= hessian_string_getstring(h_string);
            }
            if (xacml_resource_setcontent(resource,content) != PEP_XACML_OK) {
                log_error("xacml_resource_unmarshal: can't set content: %s to XACML resource.",content);
                xacml_resource_delete(resource);
                return PEP_IO_ERROR;
            }
        }
        /* attributes list */
        else if (strcmp(XACML_HESSIAN_RESOURCE_ATTRIBUTES,key) == 0) {
            hessian_object_t * h_attributes= hessian_map_getvalue(h_resource,i);
            size_t h_attributes_l;
            if (hessian_gettype(h_attributes) != HESSIAN_LIST) {
                log_error("xacml_resource_unmarshal: Hessian map<'%s',value> is not a Hessian list at: %d.",key, i);
                xacml_resource_delete(resource);
                return PEP_IO_ERROR;
            }
            h_attributes_l= hessian_list_length(h_attributes);
            for(j= 0; j<h_attributes_l; j++) {
                hessian_object_t * h_attr= hessian_list_get(h_attributes,j);
                xacml_attribute_t * attribute= NULL;
                if (xacml_attribute_unmarshal(&attribute,h_attr) != PEP_IO_OK) {
                    log_error("xacml_resource_unmarshal: can't unmarshal XACML attribute at: %d.",j);
                    xacml_resource_delete(resource);
                    return PEP_IO_ERROR;
                }
                if (xacml_resource_addattribute(resource,attribute) != PEP_XACML_OK) {
                    log_error("xacml_resource_unmarshal: can't add XACML attribute to XACML resource at: %d",j);
                    xacml_resource_delete(resource);
                    xacml_attribute_delete(attribute);
                    return PEP_IO_ERROR;
                }
            }
        }
        else {
            /* unkown key ??? */
            log_warn("xacml_resource_unmarshal: unknown Hessian map<key>: %s at: %d.",key,i);
        }
    }
    *res= resource;
    return PEP_IO_OK;
}
/*
 * Creates a XACML Request containing a XACML Subject with the given subjectid, a XACML Resource
 * with the given resourceid and a XACML Action with the given actionid.
 * 
 * @param [in/out] request address of the pointer to the XACML request object
 * @param [in] subjectid, a X.509 DN, attribute value of the XACML Request/Subject element 
 * @param [in] resourceid  attribute value of the XACML Request/Resource element
 * @param [in] actionid  attribute value of the XACML Request/Action element
 * @return 0 on success or error code on failure.
 */
static int create_xacml_request(xacml_request_t ** request,const char * subjectid, const char * resourceid, const char * actionid)
{
    xacml_subject_t * subject;
    xacml_attribute_t * subject_attr_id;
    xacml_resource_t * resource;
    xacml_attribute_t * resource_attr_id;
    xacml_action_t * action;
    xacml_attribute_t * action_attr_id;
    
    /* XACML Subject with subjectid Attribute value */
    subject= xacml_subject_create();
    if (subject == NULL) {
        fprintf(stderr,"can not create XACML Subject\n");
        return 1;
    }
    subject_attr_id= xacml_attribute_create(XACML_SUBJECT_ID);
    if (subject_attr_id == NULL) {
        fprintf(stderr,"can not create XACML Subject/Attribute:%s\n",XACML_SUBJECT_ID);
        xacml_subject_delete(subject);
        return 1;
    }
    // set X.509 DN value
    xacml_attribute_addvalue(subject_attr_id,subjectid);
    // set attribute datatype for X.509 DN
    xacml_attribute_setdatatype(subject_attr_id,XACML_DATATYPE_X500NAME); 
    xacml_subject_addattribute(subject,subject_attr_id);

    /* XACML Resource with resourceid Attribute value */
    resource= xacml_resource_create();
    if (resource == NULL) {
        fprintf(stderr,"can not create XACML Resource\n");
        xacml_subject_delete(subject);
        return 2;
    }
    resource_attr_id= xacml_attribute_create(XACML_RESOURCE_ID);
    if (resource_attr_id == NULL) {
        fprintf(stderr,"can not create XACML Resource/Attribute:%s\n",XACML_RESOURCE_ID);
        xacml_subject_delete(subject);
        xacml_resource_delete(resource);
        return 2;
    }
    xacml_attribute_addvalue(resource_attr_id,resourceid);
    xacml_resource_addattribute(resource,resource_attr_id);

    /* XACML Action with actionid Attribute value */
    action= xacml_action_create();
    if (action == NULL) {
        fprintf(stderr,"can not create XACML Action\n");
        xacml_subject_delete(subject);
        xacml_resource_delete(resource);
        return 3;
    }
    action_attr_id= xacml_attribute_create(XACML_ACTION_ID);
    if (action_attr_id == NULL) {
        fprintf(stderr,"can not create XACML Action/Attribute:%s\n",XACML_ACTION_ID);
        xacml_subject_delete(subject);
        xacml_resource_delete(resource);
        xacml_action_delete(action);
        return 3;
    }
    xacml_attribute_addvalue(action_attr_id,actionid);
    xacml_action_addattribute(action,action_attr_id);

    /* XACML Request with all elements */
    *request= xacml_request_create();
    if (*request == NULL) {
        fprintf(stderr,"can not create XACML Request\n");
        xacml_subject_delete(subject);
        xacml_resource_delete(resource);
        xacml_action_delete(action);
        return 4;
    }
    xacml_request_addsubject(*request,subject);
    xacml_request_addresource(*request,resource);
    xacml_request_setaction(*request,action);
    
    return 0;
}