static DBusMessage*
service_method_create_collection (GkdSecretService *self, DBusMessage *message)
{
	DBusMessageIter iter, array;
	GckAttributes *attrs;
	GkdSecretCreate *create;
	DBusMessage *reply;
	const gchar *path;
	const gchar *alias;
	const char *caller;
	const gchar *coll;

	/* Parse the incoming message */
	if (!dbus_message_has_signature (message, "a{sv}s"))
		return NULL;
	if (!dbus_message_iter_init (message, &iter))
		g_return_val_if_reached (NULL);
	attrs = gck_attributes_new ();
	dbus_message_iter_recurse (&iter, &array);
	if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, attrs)) {
		gck_attributes_unref (attrs);
		return dbus_message_new_error_printf (message, DBUS_ERROR_INVALID_ARGS,
		                                      "Invalid properties");
	}
	if (!dbus_message_iter_next (&iter))
		g_return_val_if_reached (NULL);
	dbus_message_iter_get_basic (&iter, &alias);

	/* Empty alias is no alias */
	if (alias) {
		if (!alias[0]) {
			alias = NULL;
		} else if (!g_str_equal (alias, "default")) {
			gck_attributes_unref (attrs);
			return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED,
			                               "Only the 'default' alias is supported");
		}
	}

	gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);

	/* Create the prompt object, for the password */
	caller = dbus_message_get_sender (message);
	create = gkd_secret_create_new (self, caller, attrs, alias);
	gck_attributes_unref (attrs);

	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create));
	gkd_secret_service_publish_dispatch (self, caller,
	                                     GKD_SECRET_DISPATCH (create));

	coll = "/";
	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply,
	                          DBUS_TYPE_OBJECT_PATH, &coll,
	                          DBUS_TYPE_OBJECT_PATH, &path,
	                          DBUS_TYPE_INVALID);

	g_object_unref (create);
	return reply;
}
static gboolean
service_method_create_collection (GkdExportedService *skeleton,
				  GDBusMethodInvocation *invocation,
				  GVariant *properties,
				  gchar *alias,
				  GkdSecretService *self)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckAttributes *attrs;
	GkdSecretCreate *create;
	const gchar *path;
	const char *caller;

	if (!gkd_secret_property_parse_all (properties, SECRET_COLLECTION_INTERFACE, &builder)) {
		gck_builder_clear (&builder);
		g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_INVALID_ARGS,
							       "Invalid properties");
		return TRUE;
	}

	/* Empty alias is no alias */
	if (alias) {
		if (!alias[0]) {
			alias = NULL;
		} else if (!g_str_equal (alias, "default")) {
			gck_builder_clear (&builder);
			g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
								       G_DBUS_ERROR_NOT_SUPPORTED,
								       "Only the 'default' alias is supported");
			return TRUE;
		}
	}

	gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));

	/* Create the prompt object, for the password */
	caller = g_dbus_method_invocation_get_sender (invocation);
	create = gkd_secret_create_new (self, caller, attrs, alias);
	gck_attributes_unref (attrs);

	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create));
	gkd_secret_service_publish_dispatch (self, caller,
					     GKD_SECRET_DISPATCH (create));

	gkd_exported_service_complete_create_collection (skeleton, invocation,
							 "/", path);
	return TRUE;
}
static DBusMessage*
service_method_create_collection (GkdSecretService *self, DBusMessage *message)
{
	DBusMessageIter iter, array;
	GP11Attributes *attrs;
	GkdSecretCreate *create;
	ServiceClient *client;
	DBusMessage *reply;
	const gchar *path;
	const char *caller;
	const gchar *coll;

	/* Parse the incoming message */
	if (!dbus_message_has_signature (message, "a{sv}"))
		return NULL;
	if (!dbus_message_iter_init (message, &iter))
		g_return_val_if_reached (NULL);
	attrs = gp11_attributes_new ();
	dbus_message_iter_recurse (&iter, &array);
	if (!gkd_secret_property_parse_all (&array, attrs)) {
		gp11_attributes_unref (attrs);
		return dbus_message_new_error_printf (message, DBUS_ERROR_INVALID_ARGS,
		                                      "Invalid properties");
	}

	gp11_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);

	/* Create the prompt object, for the password */
	caller = dbus_message_get_sender (message);
	create = gkd_secret_create_new (self, caller, attrs);
	gp11_attributes_unref (attrs);

	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create));
	client = g_hash_table_lookup (self->clients, caller);
	g_return_val_if_fail (client, NULL);
	g_hash_table_replace (client->prompts, (gpointer)path, create);

	coll = "/";
	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply,
	                          DBUS_TYPE_OBJECT_PATH, &coll,
	                          DBUS_TYPE_OBJECT_PATH, &path,
	                          DBUS_TYPE_INVALID);

	return reply;
}