static DBusMessage*
service_message_handler (GkdSecretService *self, DBusMessage *message)
{
	g_return_val_if_fail (message, NULL);
	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);

	/* org.freedesktop.Secret.Service.OpenSession() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "OpenSession"))
		return service_method_open_session (self, message);

	/* org.freedesktop.Secret.Service.CreateCollection() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "CreateCollection"))
		return service_method_create_collection (self, message);

	/* org.freedesktop.Secret.Service.LockService() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "LockService"))
		return service_method_lock_service (self, message);

	/* org.freedesktop.Secret.Service.SearchItems() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "SearchItems"))
		return gkd_secret_objects_handle_search_items (self->objects, message, NULL);

	/* org.freedesktop.Secret.Service.GetSecrets() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "GetSecrets"))
		return gkd_secret_objects_handle_get_secrets (self->objects, message);

	/* org.freedesktop.Secret.Service.Unlock() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "Unlock"))
		return service_method_unlock (self, message);

	/* org.freedesktop.Secret.Service.Lock() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "Lock"))
		return service_method_lock (self, message);

	/* org.mate.keyring.Service.ChangeLock() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "ChangeLock"))
		return service_method_change_lock (self, message);

	/* org.freedesktop.Secret.Service.ReadAlias() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "ReadAlias"))
		return service_method_read_alias (self, message);

	/* org.freedesktop.Secret.Service.SetAlias() */
	if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "SetAlias"))
		return service_method_set_alias (self, message);

	/* org.mate.keyring.InternalUnsupportedGuiltRiddenInterface.CreateWithMasterPassword */
	if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "CreateWithMasterPassword"))
		return service_method_create_with_master_password (self, message);

	/* org.mate.keyring.InternalUnsupportedGuiltRiddenInterface.ChangeWithMasterPassword() */
	if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "ChangeWithMasterPassword"))
		return service_method_change_with_master_password (self, message);

	/* org.mate.keyring.InternalUnsupportedGuiltRiddenInterface.UnlockWithMasterPassword() */
	if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "UnlockWithMasterPassword"))
		return service_method_unlock_with_master_password (self, message);

	/* org.freedesktop.DBus.Properties.Get() */
	if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Get"))
		return service_property_get (self, message);

	/* org.freedesktop.DBus.Properties.Set() */
	else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Set"))
		return service_property_set (self, message);

	/* org.freedesktop.DBus.Properties.GetAll() */
	else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "GetAll"))
		return service_property_getall (self, message);

	else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
		return gkd_dbus_introspect_handle (message, gkd_secret_introspect_service);

	return NULL;
}
static DBusMessage *
service_introspect (GkdSecretService *self,
                    DBusMessage *message)
{
	GPtrArray *names;
	DBusMessage *reply;
	ServiceClient *client;
	const gchar *caller;
	const gchar *path;
	GHashTableIter iter;

	names = g_ptr_array_new_with_free_func (g_free);
	gkd_secret_objects_foreach_collection (self->objects, message,
	                                       on_each_path_append_to_array,
	                                       names);

	/* Lookup all sessions and prompts for this client */
	caller = dbus_message_get_sender (message);
	if (caller != NULL) {
		client = g_hash_table_lookup (self->clients, caller);
		if (client != NULL) {
			g_hash_table_iter_init (&iter, client->dispatch);
			while (g_hash_table_iter_next (&iter, (gpointer *)&path, NULL))
				g_ptr_array_add (names, g_strdup (path));
		}
	}

	g_ptr_array_add (names, NULL);

	reply = gkd_dbus_introspect_handle (message, gkd_secret_introspect_service,
	                                    (const gchar **)names->pdata);

	g_ptr_array_unref (names);
	return reply;
}
static gboolean
root_dispatch_message (GkdSecretService *self,
                       DBusMessage *message)
{
	DBusMessage *reply = NULL;

	if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
		reply = gkd_dbus_introspect_handle (message, gkd_secret_introspect_root, NULL);

	if (reply != NULL) {
		dbus_connection_send (self->connection, reply, NULL);
		dbus_message_unref (reply);
		return TRUE;
	}

	return FALSE;
}