index_replacev (p11_index *index,
                CK_OBJECT_HANDLE *handles,
                CK_ATTRIBUTE_TYPE key,
                CK_ATTRIBUTE **replace,
                CK_ULONG replacen)
{
	index_object *obj;
	CK_ATTRIBUTE *attrs;
	CK_ATTRIBUTE *attr;
	bool handled = false;
	CK_RV rv;
	int i, j;

	for (i = 0; handles && handles[i] != 0; i++) {
		obj = p11_dict_get (index->objects, handles + i);
		if (obj == NULL)
			continue;

		handled = false;
		attr = p11_attrs_find (obj->attrs, key);

		/* The match doesn't have the key, so remove it */
		if (attr != NULL) {
			for (j = 0; j < replacen; j++) {
				if (!replace[j])
					continue;
				if (p11_attrs_matchn (replace[j], attr, 1)) {
					attrs = NULL;
					rv = index_build (index, obj->handle, &attrs, replace[j]);
					if (rv != CKR_OK)
						return rv;
					p11_attrs_free (obj->attrs);
					obj->attrs = attrs;
					replace[j] = NULL;
					handled = true;
					index_hash (index, obj);
					index_notify (index, obj->handle, NULL);
					break;
				}
			}
		}

		if (!handled) {
			rv = p11_index_remove (index, handles[i]);
			if (rv != CKR_OK)
				return rv;
		}
	}

	for (j = 0; j < replacen; j++) {
		if (!replace[j])
			continue;
		attrs = replace[j];
		replace[j] = NULL;
		rv = p11_index_take (index, attrs, NULL);
		if (rv != CKR_OK)
			return rv;
	}

	return CKR_OK;
}
index_replacev (p11_index *index,
                CK_OBJECT_HANDLE *handles,
                CK_ATTRIBUTE_TYPE key,
                CK_ATTRIBUTE **replace,
                CK_ULONG replacen)
{
	index_object *obj;
	CK_ATTRIBUTE *attrs;
	CK_ATTRIBUTE *attr;
	bool handled = false;
	CK_RV rv;
	int i, j;

	for (i = 0; handles && handles[i] != 0; i++) {
		obj = p11_dict_get (index->objects, handles + i);
		if (obj == NULL)
			continue;

		handled = false;
		attr = p11_attrs_find (obj->attrs, key);

		 
		if (attr != NULL) {
			for (j = 0; j < replacen; j++) {
				if (!replace[j])
					continue;
				if (p11_attrs_matchn (replace[j], attr, 1)) {
					attrs = NULL;
					rv = index_build (index, obj->handle, &attrs, replace[j]);
					if (rv != CKR_OK)
						return rv;
					p11_attrs_free (obj->attrs);
					obj->attrs = attrs;
					replace[j] = NULL;
					handled = true;
					index_hash (index, obj);
					index_notify (index, obj->handle, NULL);
					break;
				}
			}
		}

		if (!handled) {
			rv = p11_index_remove (index, handles[i]);
			if (rv != CKR_OK)
				return rv;
		}
	}

	for (j = 0; j < replacen; j++) {
		if (!replace[j])
			continue;
		attrs = replace[j];
		replace[j] = NULL;
		rv = p11_index_take (index, attrs, NULL);
		if (rv != CKR_OK)
			return rv;
	}

	return CKR_OK;
}