about summary refs log tree commit diff
path: root/libnm/nm-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/nm-client.c')
-rw-r--r--libnm/nm-client.c8754
1 files changed, 0 insertions, 8754 deletions
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
deleted file mode 100644
index f1b25970..00000000
--- a/libnm/nm-client.c
+++ /dev/null
@@ -1,8754 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2018 Red Hat, Inc.
- */
-
-#include "libnm/nm-default-libnm.h"
-
-#include "nm-client.h"
-
-#include <libudev.h>
-
-#include "nm-std-aux/c-list-util.h"
-#include "nm-glib-aux/nm-c-list.h"
-#include "nm-glib-aux/nm-dbus-aux.h"
-#include "nm-libnm-core-intern/nm-common-macros.h"
-
-#include "nm-access-point.h"
-#include "nm-active-connection.h"
-#include "nm-checkpoint.h"
-#include "nm-core-internal.h"
-#include "nm-dbus-helpers.h"
-#include "nm-device-6lowpan.h"
-#include "nm-device-adsl.h"
-#include "nm-device-bond.h"
-#include "nm-device-bridge.h"
-#include "nm-device-bt.h"
-#include "nm-device-dummy.h"
-#include "nm-device-ethernet.h"
-#include "nm-device-generic.h"
-#include "nm-device-infiniband.h"
-#include "nm-device-ip-tunnel.h"
-#include "nm-device-macsec.h"
-#include "nm-device-macvlan.h"
-#include "nm-device-modem.h"
-#include "nm-device-olpc-mesh.h"
-#include "nm-device-ovs-bridge.h"
-#include "nm-device-ovs-interface.h"
-#include "nm-device-ovs-port.h"
-#include "nm-device-ppp.h"
-#include "nm-device-team.h"
-#include "nm-device-tun.h"
-#include "nm-device-vlan.h"
-#include "nm-device-vxlan.h"
-#include "nm-device-wifi-p2p.h"
-#include "nm-device-wifi.h"
-#include "nm-device-wireguard.h"
-#include "nm-device-wpan.h"
-#include "nm-dhcp-config.h"
-#include "nm-dhcp4-config.h"
-#include "nm-dhcp6-config.h"
-#include "nm-dns-manager.h"
-#include "nm-ip4-config.h"
-#include "nm-ip6-config.h"
-#include "nm-object-private.h"
-#include "nm-remote-connection.h"
-#include "nm-utils.h"
-#include "nm-vpn-connection.h"
-#include "nm-wifi-p2p-peer.h"
-
-/*****************************************************************************/
-
-NM_CACHED_QUARK_FCN("nm-context-busy-watcher", nm_context_busy_watcher_quark);
-
-static void
-_context_busy_watcher_attach_integration_source_cb(gpointer data, GObject *where_the_object_was)
-{
-    nm_g_source_destroy_and_unref(data);
-}
-
-void
-nm_context_busy_watcher_integrate_source(GMainContext *outer_context,
-                                         GMainContext *inner_context,
-                                         GObject *     context_busy_watcher)
-{
-    GSource *source;
-
-    nm_assert(outer_context);
-    nm_assert(inner_context);
-    nm_assert(outer_context != inner_context);
-    nm_assert(G_IS_OBJECT(context_busy_watcher));
-
-    source = nm_utils_g_main_context_create_integrate_source(inner_context);
-    g_source_attach(source, outer_context);
-
-    /* The problem is...
-     *
-     * NMClient is associated with a GMainContext, just like its underlying GDBusConnection
-     * also queues signals and callbacks on that main context. During operation, NMClient
-     * will schedule async operations which will return asynchronously on the GMainContext.
-     *
-     * Note that depending on whether NMClient got initialized synchronously or asynchronously,
-     * it has an internal priv->dbus_context that is different from the outer priv->main_context.
-     * However, the problem is in both cases.
-     *
-     * So, as long as there are pending D-Bus calls, the GMainContext is referenced and kept alive.
-     * When NMClient gets destroyed, the pending calls get cancelled, but the async callback are still
-     * scheduled to return.
-     * That means, the main context stays alive until it gets iterated long enough so that all pending
-     * operations are completed.
-     *
-     * Note that pending operations don't keep NMClient alive, so NMClient can already be gone by
-     * then, but the user still should iterate the main context long enough to process the (cancelled)
-     * callbacks... at least, if the user cares about whether the remaining memory and file descriptors
-     * of the GMainContext can be reclaimed.
-     *
-     * In hindsight, maybe pending references should kept NMClient alive. But then NMClient would
-     * need a special "shutdown()" API that the user must invoke, because unrefing would no longer
-     * be enough to ensure a shutdown (imagine a situation where NMClient receives a constant flow
-     * of "CheckPermissions" signals, which keeps retriggering an async request). Anyway, we cannot
-     * add such a shutdown API now, as it would break client's expectations that they can just unref
-     * the NMClient to destroy it.
-     *
-     * So, we allow NMClient to unref, but the user is advised to keep iterating the main context.
-     * But for how long? Here comes nm_client_get_context_busy_watcher() into play. The user may
-     * subscribe a weak pointer to that instance and should keep iterating as long as the object
-     * exists.
-     *
-     * Now, back to synchronous initialization. Here we have the internal priv->dbus_context context.
-     * We also cannot remove that context right away, instead we need to keep it integrated in the
-     * caller's priv->main_context as long as we have pending calls: that is, as long as the
-     * context-busy-watcher is alive.
-     */
-
-    g_object_weak_ref(context_busy_watcher,
-                      _context_busy_watcher_attach_integration_source_cb,
-                      source);
-}
-
-/*****************************************************************************/
-
-typedef struct {
-    /* It is quite wasteful to require 2 pointers per property (of an instance) only to track whether
-     * the property got changed. But it's convenient! */
-    CList changed_prop_lst;
-
-    GVariant *prop_data_value;
-} NMLDBusObjPropData;
-
-typedef struct {
-    CList iface_lst;
-    union {
-        const NMLDBusMetaIface *meta;
-        NMRefString *           name;
-    } dbus_iface;
-
-    CList changed_prop_lst_head;
-
-    /* We also keep track of non-well known interfaces. The presence of a D-Bus interface
-     * is what makes a D-Bus alive or not. As we should track all D-Bus objects, we also
-     * need to track whether there are any interfaces on it -- even if we otherwise don't
-     * care about the interface. */
-    bool dbus_iface_is_wellknown : 1;
-
-    /* if TRUE, the interface is about to be removed. */
-    bool iface_removed : 1;
-
-    bool nmobj_checked : 1;
-    bool nmobj_compatible : 1;
-
-    NMLDBusObjPropData prop_datas[];
-} NMLDBusObjIfaceData;
-
-/* The dbus_path must be the first element, so when we hash the object by the dbus_path,
- * we also can lookup the object by only having a NMRefString at hand
- * using nm_pdirect_hash()/nm_pdirect_equal(). */
-G_STATIC_ASSERT(G_STRUCT_OFFSET(NMLDBusObject, dbus_path) == 0);
-
-typedef void (*NMLDBusObjWatchNotifyFcn)(NMClient *client, gpointer obj_watcher);
-
-struct _NMLDBusObjWatcher {
-    NMLDBusObject *dbobj;
-    struct {
-        CList                    watcher_lst;
-        NMLDBusObjWatchNotifyFcn notify_fcn;
-    } _priv;
-};
-
-typedef struct {
-    NMLDBusObjWatcher parent;
-    gpointer          user_data;
-} NMLDBusObjWatcherWithPtr;
-
-/*****************************************************************************/
-
-NM_GOBJECT_PROPERTIES_DEFINE(NMClient,
-                             PROP_DBUS_CONNECTION,
-                             PROP_DBUS_NAME_OWNER,
-                             PROP_VERSION,
-                             PROP_INSTANCE_FLAGS,
-                             PROP_STATE,
-                             PROP_STARTUP,
-                             PROP_NM_RUNNING,
-                             PROP_NETWORKING_ENABLED,
-                             PROP_WIRELESS_ENABLED,
-                             PROP_WIRELESS_HARDWARE_ENABLED,
-                             PROP_WWAN_ENABLED,
-                             PROP_WWAN_HARDWARE_ENABLED,
-                             PROP_WIMAX_ENABLED,
-                             PROP_WIMAX_HARDWARE_ENABLED,
-                             PROP_ACTIVE_CONNECTIONS,
-                             PROP_CONNECTIVITY,
-                             PROP_CONNECTIVITY_CHECK_URI,
-                             PROP_CONNECTIVITY_CHECK_AVAILABLE,
-                             PROP_CONNECTIVITY_CHECK_ENABLED,
-                             PROP_PRIMARY_CONNECTION,
-                             PROP_ACTIVATING_CONNECTION,
-                             PROP_DEVICES,
-                             PROP_ALL_DEVICES,
-                             PROP_CONNECTIONS,
-                             PROP_HOSTNAME,
-                             PROP_CAN_MODIFY,
-                             PROP_METERED,
-                             PROP_DNS_MODE,
-                             PROP_DNS_RC_MANAGER,
-                             PROP_DNS_CONFIGURATION,
-                             PROP_CHECKPOINTS,
-                             PROP_CAPABILITIES,
-                             PROP_PERMISSIONS_STATE, );
-
-enum {
-    DEVICE_ADDED,
-    DEVICE_REMOVED,
-    ANY_DEVICE_ADDED,
-    ANY_DEVICE_REMOVED,
-    PERMISSION_CHANGED,
-    CONNECTION_ADDED,
-    CONNECTION_REMOVED,
-    ACTIVE_CONNECTION_ADDED,
-    ACTIVE_CONNECTION_REMOVED,
-
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-enum {
-    PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION = 0,
-    PROPERTY_O_IDX_NM_PRIMAY_CONNECTION,
-    _PROPERTY_O_IDX_NM_NUM,
-};
-
-enum {
-    PROPERTY_AO_IDX_DEVICES = 0,
-    PROPERTY_AO_IDX_ALL_DEVICES,
-    PROPERTY_AO_IDX_ACTIVE_CONNECTIONS,
-    PROPERTY_AO_IDX_CHECKPOINTS,
-    _PROPERTY_AO_IDX_NM_NUM,
-};
-
-typedef struct {
-    struct udev *    udev;
-    GMainContext *   main_context;
-    GMainContext *   dbus_context;
-    GObject *        context_busy_watcher;
-    GDBusConnection *dbus_connection;
-    NMLInitData *    init_data;
-    GHashTable *     dbus_objects;
-    CList            obj_changed_lst_head;
-    GCancellable *   name_owner_get_cancellable;
-    GCancellable *   get_managed_objects_cancellable;
-
-    CList queue_notify_lst_head;
-    CList notify_event_lst_head;
-
-    CList dbus_objects_lst_head_watched_only;
-    CList dbus_objects_lst_head_on_dbus;
-    CList dbus_objects_lst_head_with_nmobj_not_ready;
-    CList dbus_objects_lst_head_with_nmobj_ready;
-
-    NMLDBusObject *dbobj_nm;
-    NMLDBusObject *dbobj_settings;
-    NMLDBusObject *dbobj_dns_manager;
-
-    gsize log_call_counter;
-
-    guint8 *      permissions;
-    GCancellable *permissions_cancellable;
-
-    char *name_owner;
-    guint name_owner_changed_id;
-    guint dbsid_nm_object_manager;
-    guint dbsid_dbus_properties_properties_changed;
-    guint dbsid_nm_settings_connection_updated;
-    guint dbsid_nm_connection_active_state_changed;
-    guint dbsid_nm_vpn_connection_state_changed;
-    guint dbsid_nm_check_permissions;
-
-    NMClientInstanceFlags instance_flags : 3;
-
-    NMTernary permissions_state : 3;
-
-    bool instance_flags_constructed : 1;
-
-    bool udev_inited : 1;
-    bool notify_event_lst_changed : 1;
-    bool check_dbobj_visible_all : 1;
-    bool nm_running : 1;
-
-    struct {
-        NMLDBusPropertyO  property_o[_PROPERTY_O_IDX_NM_NUM];
-        NMLDBusPropertyAO property_ao[_PROPERTY_AO_IDX_NM_NUM];
-        char *            connectivity_check_uri;
-        char *            version;
-        guint32 *         capabilities_arr;
-        gsize             capabilities_len;
-        guint32           connectivity;
-        guint32           state;
-        guint32           metered;
-        bool              connectivity_check_available;
-        bool              connectivity_check_enabled;
-        bool              networking_enabled;
-        bool              startup;
-        bool              wireless_enabled;
-        bool              wireless_hardware_enabled;
-        bool              wwan_enabled;
-        bool              wwan_hardware_enabled;
-    } nm;
-
-    struct {
-        NMLDBusPropertyAO connections;
-        char *            hostname;
-        bool              can_modify;
-    } settings;
-
-    struct {
-        GPtrArray *configuration;
-        char *     mode;
-        char *     rc_manager;
-    } dns_manager;
-
-} NMClientPrivate;
-
-struct _NMClient {
-    union {
-        GObject      parent;
-        NMObjectBase obj_base;
-    };
-    NMClientPrivate _priv;
-};
-
-struct _NMClientClass {
-    union {
-        GObjectClass      parent;
-        NMObjectBaseClass obj_base;
-    };
-};
-
-static void nm_client_initable_iface_init(GInitableIface *iface);
-static void nm_client_async_initable_iface_init(GAsyncInitableIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE(NMClient,
-                        nm_client,
-                        G_TYPE_OBJECT,
-                        G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, nm_client_initable_iface_init);
-                        G_IMPLEMENT_INTERFACE(G_TYPE_ASYNC_INITABLE,
-                                              nm_client_async_initable_iface_init);)
-
-#define NM_CLIENT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMClient, NM_IS_CLIENT)
-
-/*****************************************************************************/
-
-static void _init_start_check_complete(NMClient *self);
-
-static void name_owner_changed_cb(GDBusConnection *connection,
-                                  const char *     sender_name,
-                                  const char *     object_path,
-                                  const char *     interface_name,
-                                  const char *     signal_name,
-                                  GVariant *       parameters,
-                                  gpointer         user_data);
-
-static void name_owner_get_call(NMClient *self);
-
-static void _set_nm_running(NMClient *self);
-
-/*****************************************************************************/
-
-static NMRefString *_dbus_path_nm          = NULL;
-static NMRefString *_dbus_path_settings    = NULL;
-static NMRefString *_dbus_path_dns_manager = NULL;
-
-/*****************************************************************************/
-
-static NM_UTILS_LOOKUP_STR_DEFINE(
-    nml_dbus_obj_state_to_string,
-    NMLDBusObjState,
-    NM_UTILS_LOOKUP_DEFAULT_WARN("???"),
-    NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_UNLINKED, "unlinked"),
-    NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_WATCHED_ONLY, "watched-only"),
-    NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_ON_DBUS, "on-dbus"),
-    NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, "not-ready"),
-    NM_UTILS_LOOKUP_ITEM(NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, "ready"), );
-
-/*****************************************************************************/
-
-/**
- * nm_client_error_quark:
- *
- * Registers an error quark for #NMClient if necessary.
- *
- * Returns: the error quark used for #NMClient errors.
- **/
-NM_CACHED_QUARK_FCN("nm-client-error-quark", nm_client_error_quark);
-
-/*****************************************************************************/
-
-NMLInitData *
-nml_init_data_new_sync(GCancellable *cancellable, GMainLoop *main_loop, GError **error_location)
-{
-    NMLInitData *init_data;
-
-    init_data  = g_slice_new(NMLInitData);
-    *init_data = (NMLInitData){
-        .cancellable = nm_g_object_ref(cancellable),
-        .is_sync     = TRUE,
-        .data.sync =
-            {
-                .main_loop      = main_loop,
-                .error_location = error_location,
-            },
-    };
-    return init_data;
-}
-
-NMLInitData *
-nml_init_data_new_async(GCancellable *cancellable, GTask *task_take)
-{
-    NMLInitData *init_data;
-
-    init_data  = g_slice_new(NMLInitData);
-    *init_data = (NMLInitData){
-        .cancellable = nm_g_object_ref(cancellable),
-        .is_sync     = FALSE,
-        .data.async =
-            {
-                .task = g_steal_pointer(&task_take),
-            },
-    };
-    return init_data;
-}
-
-void
-nml_init_data_return(NMLInitData *init_data, GError *error_take)
-{
-    nm_assert(init_data);
-
-    nm_clear_pointer(&init_data->cancel_on_idle_source, nm_g_source_destroy_and_unref);
-    nm_clear_g_signal_handler(init_data->cancellable, &init_data->cancelled_id);
-
-    if (init_data->is_sync) {
-        if (error_take)
-            g_propagate_error(init_data->data.sync.error_location, error_take);
-        g_main_loop_quit(init_data->data.sync.main_loop);
-    } else {
-        if (error_take)
-            g_task_return_error(init_data->data.async.task, error_take);
-        else
-            g_task_return_boolean(init_data->data.async.task, TRUE);
-        g_object_unref(init_data->data.async.task);
-    }
-    nm_g_object_unref(init_data->cancellable);
-    nm_g_slice_free(init_data);
-}
-
-/*****************************************************************************/
-
-GError *
-_nm_client_new_error_nm_not_running(void)
-{
-    return g_error_new_literal(NM_CLIENT_ERROR,
-                               NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
-                               "NetworkManager is not running");
-}
-
-GError *
-_nm_client_new_error_nm_not_cached(void)
-{
-    return g_error_new_literal(NM_CLIENT_ERROR,
-                               NM_CLIENT_ERROR_FAILED,
-                               "Object is no longer in the client cache");
-}
-
-static void
-_nm_client_dbus_call_simple_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    GAsyncReadyCallback callback;
-    gpointer            callback_user_data;
-    gs_unref_object GObject *context_busy_watcher = NULL;
-    gpointer                 obfuscated_self_ptr;
-    gpointer                 log_call_counter_ptr;
-
-    nm_utils_user_data_unpack(user_data,
-                              &callback,
-                              &callback_user_data,
-                              &context_busy_watcher,
-                              &obfuscated_self_ptr,
-                              &log_call_counter_ptr);
-
-    NML_DBUS_LOG(_NML_NMCLIENT_LOG_LEVEL_COERCE(NML_DBUS_LOG_LEVEL_TRACE),
-                 "nmclient[" NM_HASH_OBFUSCATE_PTR_FMT "]: call[%" G_GSIZE_FORMAT "] completed",
-                 (guint64) GPOINTER_TO_SIZE(obfuscated_self_ptr),
-                 GPOINTER_TO_SIZE(log_call_counter_ptr));
-
-    callback(source, result, callback_user_data);
-}
-
-void
-_nm_client_dbus_call_simple(NMClient *          self,
-                            GCancellable *      cancellable,
-                            const char *        object_path,
-                            const char *        interface_name,
-                            const char *        method_name,
-                            GVariant *          parameters,
-                            const GVariantType *reply_type,
-                            GDBusCallFlags      flags,
-                            int                 timeout_msec,
-                            GAsyncReadyCallback callback,
-                            gpointer            user_data)
-{
-    NMClientPrivate *        priv                       = NM_CLIENT_GET_PRIVATE(self);
-    nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
-    gs_free char *                         log_str      = NULL;
-    gsize                                  log_call_counter;
-
-    nm_assert(priv->name_owner);
-    nm_assert(!cancellable || G_IS_CANCELLABLE(cancellable));
-    nm_assert(callback);
-    nm_assert(object_path);
-    nm_assert(interface_name);
-    nm_assert(method_name);
-    nm_assert(parameters);
-    nm_assert(reply_type);
-
-    dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context);
-
-    log_call_counter = ++priv->log_call_counter;
-
-    NML_NMCLIENT_LOG_T(self,
-                       "call[%" G_GSIZE_FORMAT "] D-Bus method on %s: %s, %s.%s -> %s (%s)",
-                       log_call_counter,
-                       priv->name_owner,
-                       object_path,
-                       interface_name,
-                       method_name,
-                       (const char *) reply_type ?: "???",
-                       parameters ? (log_str = g_variant_print(parameters, TRUE)) : "NULL");
-
-    g_dbus_connection_call(priv->dbus_connection,
-                           priv->name_owner,
-                           object_path,
-                           interface_name,
-                           method_name,
-                           parameters,
-                           reply_type,
-                           flags,
-                           timeout_msec,
-                           cancellable,
-                           _nm_client_dbus_call_simple_cb,
-                           nm_utils_user_data_pack(callback,
-                                                   user_data,
-                                                   g_object_ref(priv->context_busy_watcher),
-                                                   GSIZE_TO_POINTER(NM_HASH_OBFUSCATE_PTR(self)),
-                                                   GSIZE_TO_POINTER(log_call_counter)));
-}
-
-void
-_nm_client_dbus_call(NMClient *          self,
-                     gpointer            source_obj,
-                     gpointer            source_tag,
-                     GCancellable *      cancellable,
-                     GAsyncReadyCallback user_callback,
-                     gpointer            user_callback_data,
-                     const char *        object_path,
-                     const char *        interface_name,
-                     const char *        method_name,
-                     GVariant *          parameters,
-                     const GVariantType *reply_type,
-                     GDBusCallFlags      flags,
-                     int                 timeout_msec,
-                     GAsyncReadyCallback internal_callback)
-{
-    NMClientPrivate *priv;
-    gs_unref_object GTask *task = NULL;
-
-    nm_assert(!source_obj || G_IS_OBJECT(source_obj));
-    nm_assert(source_tag);
-    nm_assert(!cancellable || G_IS_CANCELLABLE(cancellable));
-    nm_assert(internal_callback);
-    nm_assert(object_path);
-    nm_assert(interface_name);
-    nm_assert(method_name);
-    nm_assert(parameters);
-    nm_assert(reply_type);
-
-    task = nm_g_task_new(source_obj, cancellable, source_tag, user_callback, user_callback_data);
-
-    if (!self) {
-        nm_g_variant_unref_floating(parameters);
-        g_task_return_error(task, _nm_client_new_error_nm_not_cached());
-        return;
-    }
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-    if (!priv->name_owner) {
-        nm_g_variant_unref_floating(parameters);
-        g_task_return_error(task, _nm_client_new_error_nm_not_running());
-        return;
-    }
-
-    _nm_client_dbus_call_simple(self,
-                                cancellable,
-                                object_path,
-                                interface_name,
-                                method_name,
-                                parameters,
-                                reply_type,
-                                flags,
-                                timeout_msec,
-                                internal_callback,
-                                g_steal_pointer(&task));
-}
-
-GVariant *
-_nm_client_dbus_call_sync(NMClient *          self,
-                          GCancellable *      cancellable,
-                          const char *        object_path,
-                          const char *        interface_name,
-                          const char *        method_name,
-                          GVariant *          parameters,
-                          const GVariantType *reply_type,
-                          GDBusCallFlags      flags,
-                          int                 timeout_msec,
-                          gboolean            strip_dbus_error,
-                          GError **           error)
-{
-    NMClientPrivate *priv;
-    gs_unref_variant GVariant *ret = NULL;
-
-    nm_assert(!cancellable || G_IS_CANCELLABLE(cancellable));
-    nm_assert(!error || !*error);
-    nm_assert(object_path);
-    nm_assert(interface_name);
-    nm_assert(method_name);
-    nm_assert(parameters);
-    nm_assert(reply_type);
-
-    if (!self) {
-        nm_g_variant_unref_floating(parameters);
-        nm_g_set_error_take_lazy(error, _nm_client_new_error_nm_not_cached());
-        return NULL;
-    }
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-    if (!priv->name_owner) {
-        nm_g_variant_unref_floating(parameters);
-        nm_g_set_error_take_lazy(error, _nm_client_new_error_nm_not_running());
-        return NULL;
-    }
-
-    ret = g_dbus_connection_call_sync(priv->dbus_connection,
-                                      priv->name_owner,
-                                      object_path,
-                                      interface_name,
-                                      method_name,
-                                      parameters,
-                                      reply_type,
-                                      flags,
-                                      timeout_msec,
-                                      cancellable,
-                                      error);
-    if (!ret) {
-        if (error && strip_dbus_error)
-            g_dbus_error_strip_remote_error(*error);
-        return NULL;
-    }
-
-    return g_steal_pointer(&ret);
-}
-
-gboolean
-_nm_client_dbus_call_sync_void(NMClient *     self,
-                               GCancellable * cancellable,
-                               const char *   object_path,
-                               const char *   interface_name,
-                               const char *   method_name,
-                               GVariant *     parameters,
-                               GDBusCallFlags flags,
-                               int            timeout_msec,
-                               gboolean       strip_dbus_error,
-                               GError **      error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-
-    ret = _nm_client_dbus_call_sync(self,
-                                    cancellable,
-                                    object_path,
-                                    interface_name,
-                                    method_name,
-                                    parameters,
-                                    G_VARIANT_TYPE("()"),
-                                    flags,
-                                    timeout_msec,
-                                    strip_dbus_error,
-                                    error);
-    return !!ret;
-}
-
-void
-_nm_client_set_property_sync_legacy(NMClient *  self,
-                                    const char *object_path,
-                                    const char *interface_name,
-                                    const char *property_name,
-                                    const char *format_string,
-                                    ...)
-{
-    NMClientPrivate *priv;
-    GVariant *       val;
-    gs_unref_variant GVariant *ret = NULL;
-    va_list                    ap;
-
-    nm_assert(!self || NM_IS_CLIENT(self));
-    nm_assert(interface_name);
-    nm_assert(property_name);
-    nm_assert(format_string);
-
-    if (!self)
-        return;
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-    if (!priv->name_owner)
-        return;
-
-    va_start(ap, format_string);
-    val = g_variant_new_va(format_string, NULL, &ap);
-    va_end(ap);
-
-    nm_assert(val);
-
-    /* A synchronous D-Bus call that is not cancellable an ignores the return value.
-     * This function only exists for backward compatibility. */
-    ret = g_dbus_connection_call_sync(priv->dbus_connection,
-                                      priv->name_owner,
-                                      object_path,
-                                      DBUS_INTERFACE_PROPERTIES,
-                                      "Set",
-                                      g_variant_new("(ssv)", interface_name, property_name, val),
-                                      NULL,
-                                      G_DBUS_CALL_FLAGS_NONE,
-                                      2000,
-                                      NULL,
-                                      NULL);
-}
-
-/*****************************************************************************/
-
-#define _assert_main_context_is_current_source(self, x_context)               \
-    G_STMT_START                                                              \
-    {                                                                         \
-        if (NM_MORE_ASSERTS > 0) {                                            \
-            GSource *_source = g_main_current_source();                       \
-                                                                              \
-            if (_source) {                                                    \
-                NMClientPrivate *_priv = NM_CLIENT_GET_PRIVATE(self);         \
-                                                                              \
-                nm_assert(g_source_get_context(_source) == _priv->x_context); \
-                nm_assert(g_main_context_is_owner(_priv->x_context));         \
-            }                                                                 \
-        }                                                                     \
-    }                                                                         \
-    G_STMT_END
-
-#define _assert_main_context_is_current_thread_default(self, x_context)                 \
-    G_STMT_START                                                                        \
-    {                                                                                   \
-        if (NM_MORE_ASSERTS > 0) {                                                      \
-            NMClientPrivate *_priv = NM_CLIENT_GET_PRIVATE(self);                       \
-                                                                                        \
-            nm_assert((g_main_context_get_thread_default() ?: g_main_context_default()) \
-                      == _priv->x_context);                                             \
-            nm_assert(g_main_context_is_owner(_priv->x_context));                       \
-        }                                                                               \
-    }                                                                                   \
-    G_STMT_END
-
-/*****************************************************************************/
-
-void
-_nm_client_queue_notify_object(NMClient *self, gpointer nmobj, const GParamSpec *pspec)
-{
-    NMObjectBase *base;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NM_IS_OBJECT(nmobj) || NM_IS_CLIENT(nmobj));
-
-    base = (NMObjectBase *) nmobj;
-
-    if (base->is_disposing) {
-        /* Don't emit property changed signals once the NMClient
-         * instance is about to shut down. */
-        nm_assert(nmobj == self);
-        return;
-    }
-
-    if (c_list_is_empty(&base->queue_notify_lst)) {
-        c_list_link_tail(&NM_CLIENT_GET_PRIVATE(self)->queue_notify_lst_head,
-                         &base->queue_notify_lst);
-        g_object_ref(nmobj);
-        g_object_freeze_notify(nmobj);
-    }
-
-    if (pspec)
-        g_object_notify_by_pspec(nmobj, (GParamSpec *) pspec);
-}
-
-/*****************************************************************************/
-
-gpointer
-_nm_client_notify_event_queue(NMClient *            self,
-                              int                   priority,
-                              NMClientNotifyEventCb callback,
-                              gsize                 event_size)
-{
-    NMClientPrivate *    priv = NM_CLIENT_GET_PRIVATE(self);
-    NMClientNotifyEvent *notify_event;
-
-    nm_assert(callback);
-    nm_assert(event_size > sizeof(NMClientNotifyEvent));
-
-    notify_event           = g_malloc(event_size);
-    notify_event->priority = priority;
-    notify_event->callback = callback;
-    c_list_link_tail(&priv->notify_event_lst_head, &notify_event->lst);
-    priv->notify_event_lst_changed = TRUE;
-    return notify_event;
-}
-
-NMClientNotifyEventWithPtr *
-_nm_client_notify_event_queue_with_ptr(NMClient *                   self,
-                                       int                          priority,
-                                       NMClientNotifyEventWithPtrCb callback,
-                                       gpointer                     user_data)
-{
-    NMClientNotifyEventWithPtr *notify_event;
-
-    notify_event            = _nm_client_notify_event_queue(self,
-                                                 priority,
-                                                 (NMClientNotifyEventCb) callback,
-                                                 sizeof(NMClientNotifyEventWithPtr));
-    notify_event->user_data = user_data;
-    return notify_event;
-}
-
-/*****************************************************************************/
-
-typedef struct {
-    NMClientNotifyEvent parent;
-    GObject *           source;
-    NMObject *          obj;
-    guint               signal_id;
-} NMClientNotifyEventObjAddedRemove;
-
-static void
-_nm_client_notify_event_queue_emit_obj_signal_cb(NMClient *self, gpointer notify_event_base)
-{
-    NMClientNotifyEventObjAddedRemove *notify_event = notify_event_base;
-
-    NML_NMCLIENT_LOG_T(
-        self,
-        "[%s] emit \"%s\" signal for %s",
-        NM_IS_CLIENT(notify_event->source) ? "nmclient" : _nm_object_get_path(notify_event->source),
-        g_signal_name(notify_event->signal_id),
-        _nm_object_get_path(notify_event->obj));
-
-    nm_assert(NM_IS_OBJECT(notify_event->source) || NM_IS_CLIENT(notify_event->source));
-
-    g_signal_emit(notify_event->source, notify_event->signal_id, 0, notify_event->obj);
-
-    g_object_unref(notify_event->obj);
-    g_object_unref(notify_event->source);
-}
-
-void
-_nm_client_notify_event_queue_emit_obj_signal(NMClient *self,
-                                              GObject * source,
-                                              NMObject *nmobj,
-                                              gboolean  is_added /* or else removed */,
-                                              int       prio_offset,
-                                              guint     signal_id)
-{
-    NMClientNotifyEventObjAddedRemove *notify_event;
-
-    nm_assert(prio_offset >= 0);
-    nm_assert(prio_offset < 20);
-    nm_assert(NM_IS_OBJECT(source) || NM_IS_CLIENT(source));
-    nm_assert(NM_IS_OBJECT(nmobj));
-
-    if (((NMObjectBase *) source)->is_disposing) {
-        nm_assert(NM_IS_CLIENT(source));
-        return;
-    }
-
-    notify_event = _nm_client_notify_event_queue(
-        self,
-        is_added ? NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER - 20 + prio_offset
-                 : NM_CLIENT_NOTIFY_EVENT_PRIO_BEFORE + 20 - prio_offset,
-        _nm_client_notify_event_queue_emit_obj_signal_cb,
-        sizeof(NMClientNotifyEventObjAddedRemove));
-    notify_event->source    = g_object_ref(source);
-    notify_event->obj       = g_object_ref(nmobj);
-    notify_event->signal_id = signal_id;
-}
-
-/*****************************************************************************/
-
-static int
-_nm_client_notify_event_cmp(const CList *a, const CList *b, const void *user_data)
-{
-    NM_CMP_DIRECT(c_list_entry(a, NMClientNotifyEvent, lst)->priority,
-                  c_list_entry(b, NMClientNotifyEvent, lst)->priority);
-    return 0;
-}
-
-static void
-_nm_client_notify_event_emit_parts(NMClient *self, int max_priority /* included! */)
-{
-    NMClientPrivate *    priv = NM_CLIENT_GET_PRIVATE(self);
-    NMClientNotifyEvent *notify_event;
-
-    while (TRUE) {
-        if (priv->notify_event_lst_changed) {
-            priv->notify_event_lst_changed = FALSE;
-            c_list_sort(&priv->notify_event_lst_head, _nm_client_notify_event_cmp, NULL);
-        }
-        notify_event = c_list_first_entry(&priv->notify_event_lst_head, NMClientNotifyEvent, lst);
-        if (!notify_event)
-            return;
-        if (notify_event->priority > max_priority)
-            return;
-        c_list_unlink_stale(&notify_event->lst);
-        notify_event->callback(self, notify_event);
-        g_free(notify_event);
-    }
-}
-
-static void
-_nm_client_notify_event_emit(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    NMObjectBase *   base;
-
-    _nm_client_notify_event_emit_parts(self, NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP);
-
-    while (
-        (base = c_list_first_entry(&priv->queue_notify_lst_head, NMObjectBase, queue_notify_lst))) {
-        c_list_unlink(&base->queue_notify_lst);
-        g_object_thaw_notify(G_OBJECT(base));
-        g_object_unref(base);
-    }
-
-    _nm_client_notify_event_emit_parts(self, G_MAXINT);
-}
-
-/*****************************************************************************/
-
-GDBusConnection *
-_nm_client_get_dbus_connection(NMClient *self)
-{
-    return NM_CLIENT_GET_PRIVATE(self)->dbus_connection;
-}
-
-const char *
-_nm_client_get_dbus_name_owner(NMClient *self)
-{
-    return NM_CLIENT_GET_PRIVATE(self)->name_owner;
-}
-
-GMainContext *
-_nm_client_get_context_main(NMClient *self)
-{
-    return NM_CLIENT_GET_PRIVATE(self)->main_context;
-}
-
-GMainContext *
-_nm_client_get_context_dbus(NMClient *self)
-{
-    return NM_CLIENT_GET_PRIVATE(self)->dbus_context;
-}
-
-/**
- * nm_client_get_main_context:
- * @self: the #NMClient instance
- *
- * The #NMClient instance is permanently associated with the current
- * thread default #GMainContext, referenced the time when the instance
- * was created. To receive events, the user must iterate this context
- * and can use it to synchronize access to the client.
- *
- * Note that even after #NMClient instance got destroyed, there might
- * still be pending sources registered in the context. That means, to fully
- * clean up, the user must continue iterating the context as long as
- * the nm_client_get_context_busy_watcher() object is alive.
- *
- * Returns: (transfer none): the #GMainContext of the client.
- *
- * Since: 1.22
- */
-GMainContext *
-nm_client_get_main_context(NMClient *self)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(self), NULL);
-
-    return _nm_client_get_context_main(self);
-}
-
-/**
- * nm_client_get_context_busy_watcher:
- * @self: the NMClient instance.
- *
- * Returns: (transfer none): a GObject that stays alive as long as there are pending
- *   D-Bus operations.
- *
- * NMClient will schedule asynchronous D-Bus requests which will complete on
- * the GMainContext associated with the instance. When destroying the NMClient
- * instance, those requests are cancelled right away, however their pending requests are
- * still outstanding and queued in the GMainContext. These outstanding callbacks
- * keep the GMainContext alive. In order to fully release all resources,
- * the user must keep iterating the main context until all these callbacks
- * are handled. Of course, at this point no more actual callbacks will be invoked
- * for the user, those are all internally cancelled.
- *
- * This just leaves one problem: how long does the user need to keep the
- * GMainContext running to ensure everything is cleaned up? The answer is
- * this GObject. Subscribe a weak reference to the returned object and keep
- * iterating the main context until the object got unreferenced.
- *
- * Note that after the NMClient instance gets destroyed, the remaining callbacks
- * will be invoked right away. That means, the user won't have to iterate the
- * main context much longer.
- *
- * Since: 1.22
- */
-GObject *
-nm_client_get_context_busy_watcher(NMClient *self)
-{
-    GObject *w;
-
-    g_return_val_if_fail(NM_IS_CLIENT(self), NULL);
-
-    w = NM_CLIENT_GET_PRIVATE(self)->context_busy_watcher;
-    return g_object_get_qdata(w, nm_context_busy_watcher_quark()) ?: w;
-}
-
-struct udev *
-_nm_client_get_udev(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    if (G_UNLIKELY(!priv->udev_inited)) {
-        priv->udev_inited = TRUE;
-        /* for testing, we don't want to use udev in libnm. */
-        if (!nm_streq0(g_getenv("LIBNM_USE_NO_UDEV"), "1"))
-            priv->udev = udev_new();
-    }
-
-    return priv->udev;
-}
-
-/*****************************************************************************/
-
-static void
-_ASSERT_dbobj(NMLDBusObject *dbobj, NMClient *self)
-{
-#if NM_MORE_ASSERTS > 5
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NML_IS_DBUS_OBJECT(dbobj));
-    nm_assert(dbobj == g_hash_table_lookup(NM_CLIENT_GET_PRIVATE(self)->dbus_objects, dbobj));
-#endif
-}
-
-static NMLDBusObject *
-nml_dbus_object_new(NMRefString *dbus_path_take)
-{
-    NMLDBusObject *dbobj;
-
-    nm_assert(NM_IS_REF_STRING(dbus_path_take));
-
-    dbobj  = g_slice_new(NMLDBusObject);
-    *dbobj = (NMLDBusObject){
-        .dbus_path        = g_steal_pointer(&dbus_path_take),
-        .ref_count        = 1,
-        .dbus_objects_lst = C_LIST_INIT(dbobj->dbus_objects_lst),
-        .iface_lst_head   = C_LIST_INIT(dbobj->iface_lst_head),
-        .watcher_lst_head = C_LIST_INIT(dbobj->watcher_lst_head),
-        .obj_changed_lst  = C_LIST_INIT(dbobj->obj_changed_lst),
-        .obj_state        = NML_DBUS_OBJ_STATE_UNLINKED,
-    };
-    return dbobj;
-}
-
-NMLDBusObject *
-nml_dbus_object_ref(NMLDBusObject *dbobj)
-{
-    nm_assert(dbobj);
-    nm_assert(dbobj->ref_count > 0);
-
-    dbobj->ref_count++;
-    return dbobj;
-}
-
-void
-nml_dbus_object_unref(NMLDBusObject *dbobj)
-{
-    nm_assert(dbobj);
-    nm_assert(dbobj->ref_count > 0);
-
-    if (--dbobj->ref_count > 0)
-        return;
-
-    nm_assert(c_list_is_empty(&dbobj->obj_changed_lst));
-    nm_assert(c_list_is_empty(&dbobj->iface_lst_head));
-    nm_assert(c_list_is_empty(&dbobj->watcher_lst_head));
-    nm_assert(!dbobj->nmobj);
-
-    nm_ref_string_unref(dbobj->dbus_path);
-    nm_g_slice_free(dbobj);
-}
-
-static NMLDBusObjIfaceData *
-nml_dbus_object_iface_data_get(NMLDBusObject *dbobj,
-                               const char *   dbus_iface_name,
-                               gboolean       allow_create)
-{
-    const NMLDBusMetaIface *meta_iface;
-    NMLDBusObjIfaceData *   db_iface_data;
-    NMLDBusObjPropData *    db_prop_data;
-    guint                   count = 0;
-    guint                   i;
-
-    nm_assert(NML_IS_DBUS_OBJECT(dbobj));
-    nm_assert(dbus_iface_name);
-
-#if NM_MORE_ASSERTS > 10
-    {
-        gboolean expect_well_known = TRUE;
-
-        /* all well-known interfaces must come first in the list. */
-        c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
-            if (db_iface_data->dbus_iface_is_wellknown == expect_well_known)
-                continue;
-            nm_assert(expect_well_known);
-            expect_well_known = FALSE;
-        }
-    }
-#endif
-
-    meta_iface = nml_dbus_meta_iface_get(dbus_iface_name);
-    if (meta_iface) {
-        c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
-            if (!db_iface_data->dbus_iface_is_wellknown)
-                break;
-            if (db_iface_data->iface_removed)
-                continue;
-            if (db_iface_data->dbus_iface.meta == meta_iface)
-                return db_iface_data;
-            count++;
-        }
-    } else {
-        c_list_for_each_entry_prev (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
-            if (db_iface_data->dbus_iface_is_wellknown)
-                break;
-            if (db_iface_data->iface_removed)
-                continue;
-            if (nm_streq(db_iface_data->dbus_iface.name->str, dbus_iface_name))
-                return db_iface_data;
-            count++;
-        }
-    }
-
-    if (!allow_create)
-        return NULL;
-
-    if (count > 20) {
-        /* We track the list of interfaces that an object has in a linked list.
-         * That is efficient and convenient, if we assume that each object only has a small
-         * number of interfaces (which very much should be the case). Here, something is very
-         * odd, maybe there is a bug or the server side is misbehaving. Anyway, error out. */
-        return NULL;
-    }
-
-    db_iface_data = g_malloc(
-        G_STRUCT_OFFSET(NMLDBusObjIfaceData, prop_datas)
-        + (meta_iface ? (sizeof(NMLDBusObjPropData) * meta_iface->n_dbus_properties) : 0u));
-    if (meta_iface) {
-        *db_iface_data = (NMLDBusObjIfaceData){
-            .dbus_iface.meta         = meta_iface,
-            .dbus_iface_is_wellknown = TRUE,
-            .changed_prop_lst_head   = C_LIST_INIT(db_iface_data->changed_prop_lst_head),
-            .iface_removed           = FALSE,
-        };
-        db_prop_data = &db_iface_data->prop_datas[0];
-        for (i = 0; i < meta_iface->n_dbus_properties; i++, db_prop_data++) {
-            *db_prop_data = (NMLDBusObjPropData){
-                .prop_data_value  = NULL,
-                .changed_prop_lst = C_LIST_INIT(db_prop_data->changed_prop_lst),
-            };
-        }
-        c_list_link_front(&dbobj->iface_lst_head, &db_iface_data->iface_lst);
-    } else {
-        /* Intentionally don't initialize the other fields. We are not supposed
-         * to touch them, and a valgrind warning would be preferable. */
-        db_iface_data->dbus_iface.name         = nm_ref_string_new(dbus_iface_name);
-        db_iface_data->dbus_iface_is_wellknown = FALSE;
-        db_iface_data->iface_removed           = FALSE;
-        c_list_link_tail(&dbobj->iface_lst_head, &db_iface_data->iface_lst);
-    }
-
-    return db_iface_data;
-}
-
-static void
-nml_dbus_obj_iface_data_destroy(NMLDBusObjIfaceData *db_iface_data)
-{
-    guint i;
-
-    nm_assert(db_iface_data);
-    nm_assert(c_list_is_empty(&db_iface_data->iface_lst));
-
-    if (db_iface_data->dbus_iface_is_wellknown) {
-        for (i = 0; i < db_iface_data->dbus_iface.meta->n_dbus_properties; i++)
-            nm_g_variant_unref(db_iface_data->prop_datas[i].prop_data_value);
-    } else
-        nm_ref_string_unref(db_iface_data->dbus_iface.name);
-
-    g_free(db_iface_data);
-}
-
-gpointer
-nml_dbus_object_get_property_location(NMLDBusObject *            dbobj,
-                                      const NMLDBusMetaIface *   meta_iface,
-                                      const NMLDBusMetaProperty *meta_property)
-{
-    char *target_c;
-
-    target_c = (char *) dbobj->nmobj;
-    if (meta_iface->base_struct_offset > 0)
-        target_c = *((gpointer *) (&target_c[meta_iface->base_struct_offset]));
-    return &target_c[meta_property->prop_struct_offset];
-}
-
-static void
-nml_dbus_object_set_obj_state(NMLDBusObject *dbobj, NMLDBusObjState obj_state, NMClient *self)
-{
-    NMClientPrivate *priv;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NML_IS_DBUS_OBJECT(dbobj));
-
-#if NM_MORE_ASSERTS > 10
-    priv = NM_CLIENT_GET_PRIVATE(self);
-    switch (dbobj->obj_state) {
-    case NML_DBUS_OBJ_STATE_UNLINKED:
-        nm_assert(c_list_is_empty(&dbobj->dbus_objects_lst));
-        break;
-    case NML_DBUS_OBJ_STATE_WATCHED_ONLY:
-        nm_assert(
-            c_list_contains(&priv->dbus_objects_lst_head_watched_only, &dbobj->dbus_objects_lst));
-        break;
-    case NML_DBUS_OBJ_STATE_ON_DBUS:
-        nm_assert(c_list_contains(&priv->dbus_objects_lst_head_on_dbus, &dbobj->dbus_objects_lst));
-        break;
-    case NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY:
-        nm_assert(c_list_contains(&priv->dbus_objects_lst_head_with_nmobj_not_ready,
-                                  &dbobj->dbus_objects_lst));
-        break;
-    case NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY:
-        nm_assert(c_list_contains(&priv->dbus_objects_lst_head_with_nmobj_ready,
-                                  &dbobj->dbus_objects_lst));
-        break;
-    }
-#endif
-
-    if (dbobj->obj_state == obj_state)
-        return;
-
-    NML_NMCLIENT_LOG_T(self,
-                       "[%s]: set D-Bus object state %s",
-                       dbobj->dbus_path->str,
-                       nml_dbus_obj_state_to_string(obj_state));
-
-    priv             = NM_CLIENT_GET_PRIVATE(self);
-    dbobj->obj_state = obj_state;
-    switch (obj_state) {
-    case NML_DBUS_OBJ_STATE_UNLINKED:
-        c_list_unlink(&dbobj->dbus_objects_lst);
-        c_list_unlink(&dbobj->obj_changed_lst);
-        dbobj->obj_changed_type = NML_DBUS_OBJ_CHANGED_TYPE_NONE;
-        break;
-    case NML_DBUS_OBJ_STATE_WATCHED_ONLY:
-        nm_c_list_move_tail(&priv->dbus_objects_lst_head_watched_only, &dbobj->dbus_objects_lst);
-        break;
-    case NML_DBUS_OBJ_STATE_ON_DBUS:
-        nm_c_list_move_tail(&priv->dbus_objects_lst_head_on_dbus, &dbobj->dbus_objects_lst);
-        break;
-    case NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY:
-        nm_c_list_move_tail(&priv->dbus_objects_lst_head_with_nmobj_not_ready,
-                            &dbobj->dbus_objects_lst);
-        break;
-    case NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY:
-        nm_c_list_move_tail(&priv->dbus_objects_lst_head_with_nmobj_ready,
-                            &dbobj->dbus_objects_lst);
-        break;
-    default:
-        nm_assert_not_reached();
-    }
-}
-
-/*****************************************************************************/
-
-static void
-nml_dbus_object_obj_changed_link(NMClient *            self,
-                                 NMLDBusObject *       dbobj,
-                                 NMLDBusObjChangedType changed_type)
-{
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NML_IS_DBUS_OBJECT(dbobj));
-    nm_assert(changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE);
-
-    if (!NM_FLAGS_ALL((NMLDBusObjChangedType) dbobj->obj_changed_type, changed_type))
-        NML_NMCLIENT_LOG_T(self,
-                           "[%s]: changed-type 0x%02x linked",
-                           dbobj->dbus_path->str,
-                           (guint) changed_type);
-
-    if (dbobj->obj_changed_type == NML_DBUS_OBJ_CHANGED_TYPE_NONE) {
-        NMClientPrivate *priv;
-
-        /* We set the changed-type flag. Need to queue the object in the
-         * changed list. */
-        nm_assert(c_list_is_empty(&dbobj->obj_changed_lst));
-        priv = NM_CLIENT_GET_PRIVATE(self);
-        c_list_link_tail(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst);
-    } else {
-        /* The object has changes flags and must be linked already. Note that
-         * this may be priv->obj_changed_lst_head, or a temporary list on the
-         * stack.
-         *
-         * This dance with the temporary list is done to ensure we can enqueue
-         * objects while we process the changes. */
-        nm_assert(!c_list_is_empty(&dbobj->obj_changed_lst));
-    }
-
-    dbobj->obj_changed_type |= changed_type;
-
-    nm_assert(NM_FLAGS_ALL(dbobj->obj_changed_type, changed_type));
-}
-
-static NMLDBusObjChangedType
-nml_dbus_object_obj_changed_consume(NMClient *            self,
-                                    NMLDBusObject *       dbobj,
-                                    NMLDBusObjChangedType changed_type)
-{
-    NMClientPrivate *     priv;
-    NMLDBusObjChangedType changed_type_res;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NML_IS_DBUS_OBJECT(dbobj));
-    nm_assert(changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE);
-    nm_assert(dbobj->obj_changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE);
-    nm_assert(!c_list_is_empty(&dbobj->obj_changed_lst));
-
-    changed_type_res = dbobj->obj_changed_type & changed_type;
-
-    dbobj->obj_changed_type &= ~changed_type;
-
-    if (dbobj->obj_changed_type == NML_DBUS_OBJ_CHANGED_TYPE_NONE) {
-        c_list_unlink(&dbobj->obj_changed_lst);
-        nm_assert(changed_type_res != NML_DBUS_OBJ_CHANGED_TYPE_NONE);
-        NML_NMCLIENT_LOG_T(self,
-                           "[%s]: changed-type 0x%02x consumed",
-                           dbobj->dbus_path->str,
-                           (guint) changed_type_res);
-        return changed_type_res;
-    }
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    nm_assert(!c_list_contains(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst));
-    nm_c_list_move_tail(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst);
-    NML_NMCLIENT_LOG_T(self,
-                       "[%s]: changed-type 0x%02x consumed  (still has 0x%02x)",
-                       dbobj->dbus_path->str,
-                       (guint) changed_type_res,
-                       (guint) dbobj->obj_changed_type);
-    return changed_type_res;
-}
-
-static gboolean
-nml_dbus_object_obj_changed_any_linked(NMClient *self, NMLDBusObjChangedType changed_type)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    NMLDBusObject *  dbobj;
-
-    nm_assert(changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE);
-
-    c_list_for_each_entry (dbobj, &priv->obj_changed_lst_head, obj_changed_lst) {
-        nm_assert(dbobj->obj_changed_type != NML_DBUS_OBJ_CHANGED_TYPE_NONE);
-        if (NM_FLAGS_ANY(dbobj->obj_changed_type, changed_type))
-            return TRUE;
-    }
-    return FALSE;
-}
-
-/*****************************************************************************/
-
-static void
-_dbobjs_notify_watchers_for_dbobj(NMClient *self, NMLDBusObject *dbobj)
-{
-    NMLDBusObjWatcher *obj_watcher;
-    NMLDBusObjWatcher *obj_watcher_safe;
-
-    c_list_for_each_entry_safe (obj_watcher,
-                                obj_watcher_safe,
-                                &dbobj->watcher_lst_head,
-                                _priv.watcher_lst)
-        obj_watcher->_priv.notify_fcn(self, obj_watcher);
-}
-
-static gboolean
-_dbobjs_check_dbobj_ready(NMClient *self, NMLDBusObject *dbobj)
-{
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NML_IS_DBUS_OBJECT(dbobj));
-    nm_assert(G_IS_OBJECT(dbobj->nmobj));
-    nm_assert(NM_IS_OBJECT(dbobj->nmobj) || NM_IS_CLIENT(dbobj->nmobj));
-    nm_assert(NM_IN_SET((NMLDBusObjState) dbobj->obj_state,
-                        NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY,
-                        NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY));
-
-    if (G_LIKELY(dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY))
-        return TRUE;
-
-    if (!NM_OBJECT_GET_CLASS(dbobj->nmobj)->is_ready(NM_OBJECT(dbobj->nmobj)))
-        return FALSE;
-
-    nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, self);
-
-    nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-    _dbobjs_notify_watchers_for_dbobj(self, dbobj);
-
-    return TRUE;
-}
-
-void
-_nm_client_notify_object_changed(NMClient *self, NMLDBusObject *dbobj)
-{
-    nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-    _dbobjs_notify_watchers_for_dbobj(self, dbobj);
-}
-
-/*****************************************************************************/
-
-static NMLDBusObject *
-_dbobjs_dbobj_get_r(NMClient *self, NMRefString *dbus_path_r)
-{
-    nm_assert(NM_IS_REF_STRING(dbus_path_r));
-
-    return g_hash_table_lookup(NM_CLIENT_GET_PRIVATE(self)->dbus_objects, &dbus_path_r);
-}
-
-static NMLDBusObject *
-_dbobjs_dbobj_get_s(NMClient *self, const char *dbus_path)
-{
-    nm_auto_ref_string NMRefString *dbus_path_r = NULL;
-
-    nm_assert(dbus_path);
-    dbus_path_r = nm_ref_string_new(dbus_path);
-    return _dbobjs_dbobj_get_r(self, dbus_path_r);
-}
-
-static NMLDBusObject *
-_dbobjs_dbobj_create(NMClient *self, NMRefString *dbus_path_take)
-{
-    nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer(&dbus_path_take);
-    NMClientPrivate *               priv      = NM_CLIENT_GET_PRIVATE(self);
-    NMLDBusObject *                 dbobj;
-
-    nm_assert(!_dbobjs_dbobj_get_r(self, dbus_path));
-
-    dbobj = nml_dbus_object_new(g_steal_pointer(&dbus_path));
-    if (!g_hash_table_add(priv->dbus_objects, dbobj))
-        nm_assert_not_reached();
-    return dbobj;
-}
-
-static NMLDBusObject *
-_dbobjs_dbobj_get_or_create(NMClient *self, NMRefString *dbus_path_take)
-{
-    nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer(&dbus_path_take);
-    NMLDBusObject *                 dbobj;
-
-    dbobj = _dbobjs_dbobj_get_r(self, dbus_path);
-    if (dbobj)
-        return dbobj;
-    return _dbobjs_dbobj_create(self, g_steal_pointer(&dbus_path));
-}
-
-static NMLDBusObject *
-_dbobjs_get_nmobj(NMClient *self, const char *dbus_path, GType gtype)
-{
-    NMLDBusObject *dbobj;
-
-    nm_assert(gtype == G_TYPE_NONE || g_type_is_a(gtype, NM_TYPE_OBJECT));
-
-    dbobj = _dbobjs_dbobj_get_s(self, dbus_path);
-
-    if (!dbobj)
-        return NULL;
-    if (!dbobj->nmobj)
-        return NULL;
-
-    if (gtype != G_TYPE_NONE && !g_type_is_a(G_OBJECT_TYPE(dbobj->nmobj), gtype))
-        return NULL;
-
-    return dbobj;
-}
-
-static gpointer
-_dbobjs_get_nmobj_unpack_visible(NMClient *self, const char *dbus_path, GType gtype)
-{
-    NMLDBusObject *dbobj;
-
-    dbobj = _dbobjs_get_nmobj(self, dbus_path, gtype);
-    if (!dbobj)
-        return NULL;
-    if (dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY)
-        return NULL;
-    return dbobj->nmobj;
-}
-
-/*****************************************************************************/
-
-static gpointer
-_dbobjs_obj_watcher_register_o(NMClient *               self,
-                               NMLDBusObject *          dbobj,
-                               NMLDBusObjWatchNotifyFcn notify_fcn,
-                               gsize                    struct_size)
-{
-    NMLDBusObjWatcher *obj_watcher;
-
-    nm_assert(NM_IS_CLIENT(self));
-    _ASSERT_dbobj(dbobj, self);
-    nm_assert(notify_fcn);
-    nm_assert(struct_size > sizeof(NMLDBusObjWatcher));
-
-    obj_watcher                   = g_malloc(struct_size);
-    obj_watcher->dbobj            = dbobj;
-    obj_watcher->_priv.notify_fcn = notify_fcn;
-
-    /* we must enqueue the item in the front of the list. That is, because while
-     * invoking notify_fcn(), we iterate the watchers front-to-end. As we want to
-     * allow the callee to register new watches and unregister itself, this is
-     * the right way to do it. */
-    c_list_link_front(&dbobj->watcher_lst_head, &obj_watcher->_priv.watcher_lst);
-
-    return obj_watcher;
-}
-
-static gpointer
-_dbobjs_obj_watcher_register_r(NMClient *               self,
-                               NMRefString *            dbus_path_take,
-                               NMLDBusObjWatchNotifyFcn notify_fcn,
-                               gsize                    struct_size)
-{
-    nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer(&dbus_path_take);
-    NMLDBusObject *                 dbobj;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(notify_fcn);
-
-    dbobj = _dbobjs_dbobj_get_or_create(self, g_steal_pointer(&dbus_path));
-    if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED)
-        nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WATCHED_ONLY, self);
-    return _dbobjs_obj_watcher_register_o(self, dbobj, notify_fcn, struct_size);
-}
-
-static void
-_dbobjs_obj_watcher_unregister(NMClient *self, gpointer obj_watcher_base)
-{
-    NMLDBusObjWatcher *obj_watcher = obj_watcher_base;
-    NMLDBusObject *    dbobj;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(obj_watcher);
-    nm_assert(NML_IS_DBUS_OBJECT(obj_watcher->dbobj));
-    nm_assert(g_hash_table_lookup(NM_CLIENT_GET_PRIVATE(self)->dbus_objects, obj_watcher->dbobj)
-              == obj_watcher->dbobj);
-    nm_assert(
-        c_list_contains(&obj_watcher->dbobj->watcher_lst_head, &obj_watcher->_priv.watcher_lst));
-
-    c_list_unlink(&obj_watcher->_priv.watcher_lst);
-
-    dbobj = obj_watcher->dbobj;
-
-    g_free(obj_watcher);
-
-    if (c_list_is_empty(&dbobj->iface_lst_head) && c_list_is_empty(&dbobj->watcher_lst_head)) {
-        NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-        NML_NMCLIENT_LOG_T(self, "[%s]: drop D-Bus watcher", dbobj->dbus_path->str);
-        nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_UNLINKED, self);
-        if (!g_hash_table_steal(priv->dbus_objects, dbobj))
-            nm_assert_not_reached();
-        nml_dbus_object_unref(dbobj);
-    }
-}
-
-/*****************************************************************************/
-
-typedef struct {
-    NMLDBusObjWatcher parent;
-    NMLDBusPropertyO *pr_o;
-} PropertyOData;
-
-gpointer
-nml_dbus_property_o_get_obj(NMLDBusPropertyO *pr_o)
-{
-    nm_assert(!pr_o->nmobj || nml_dbus_property_o_is_ready(pr_o));
-    return pr_o->nmobj;
-}
-
-gboolean
-nml_dbus_property_o_is_ready(const NMLDBusPropertyO *pr_o)
-{
-    return pr_o->is_ready || !pr_o->owner_dbobj;
-}
-
-gboolean
-nml_dbus_property_o_is_ready_fully(const NMLDBusPropertyO *pr_o)
-{
-    return !pr_o->owner_dbobj || !pr_o->obj_watcher || pr_o->nmobj;
-}
-
-static void
-nml_dbus_property_o_notify_changed(NMLDBusPropertyO *pr_o, NMClient *self)
-{
-    const NMLDBusPropertVTableO *vtable;
-    GObject *                    nmobj    = NULL;
-    gboolean                     is_ready = TRUE;
-    gboolean                     changed_ready;
-    GType                        gtype;
-
-    nm_assert(pr_o);
-    nm_assert(NM_IS_CLIENT(self));
-
-    if (!pr_o->owner_dbobj)
-        return;
-
-    if (!pr_o->is_changed) {
-        if (pr_o->is_ready)
-            return;
-        goto done;
-    }
-
-    pr_o->is_changed = FALSE;
-
-    if (!pr_o->obj_watcher)
-        goto done;
-
-    if (!pr_o->obj_watcher->dbobj->nmobj) {
-        if (pr_o->obj_watcher->dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS) {
-            NML_NMCLIENT_LOG_W(
-                self,
-                "[%s]: property %s references %s but object is not created",
-                pr_o->owner_dbobj->dbus_path->str,
-                pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name,
-                pr_o->obj_watcher->dbobj->dbus_path->str);
-        } else {
-            NML_NMCLIENT_LOG_E(
-                self,
-                "[%s]: property %s references %s but object is not present on D-Bus",
-                pr_o->owner_dbobj->dbus_path->str,
-                pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name,
-                pr_o->obj_watcher->dbobj->dbus_path->str);
-        }
-        goto done;
-    }
-
-    vtable = pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].extra.property_vtable_o;
-
-    gtype = vtable->get_o_type_fcn();
-    if (!g_type_is_a(G_OBJECT_TYPE(pr_o->obj_watcher->dbobj->nmobj), gtype)) {
-        NML_NMCLIENT_LOG_E(
-            self,
-            "[%s]: property %s references %s with unexpected GObject type %s instead of %s",
-            pr_o->owner_dbobj->dbus_path->str,
-            pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name,
-            pr_o->obj_watcher->dbobj->dbus_path->str,
-            G_OBJECT_TYPE_NAME(pr_o->obj_watcher->dbobj->nmobj),
-            g_type_name(gtype));
-        goto done;
-    }
-
-    if (pr_o->obj_watcher->dbobj == pr_o->owner_dbobj) {
-        NML_NMCLIENT_LOG_W(
-            self,
-            "[%s]: property %s references itself",
-            pr_o->owner_dbobj->dbus_path->str,
-            pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name);
-        nmobj = pr_o->owner_dbobj->nmobj;
-        goto done;
-    }
-
-    pr_o->block_is_changed = TRUE;
-    is_ready               = _dbobjs_check_dbobj_ready(self, pr_o->obj_watcher->dbobj);
-    pr_o->block_is_changed = FALSE;
-
-    if (!is_ready) {
-        is_ready = vtable->is_always_ready;
-        goto done;
-    }
-
-    nmobj = pr_o->obj_watcher->dbobj->nmobj;
-
-done:
-    changed_ready = FALSE;
-    if (!pr_o->is_ready && is_ready) {
-        pr_o->is_ready = TRUE;
-        changed_ready  = TRUE;
-    }
-    if (pr_o->nmobj != nmobj) {
-        pr_o->nmobj = nmobj;
-        _nm_client_queue_notify_object(
-            self,
-            pr_o->owner_dbobj->nmobj,
-            pr_o->meta_iface->obj_properties
-                [pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].obj_properties_idx]);
-    }
-    if (changed_ready && pr_o->owner_dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY)
-        nml_dbus_object_obj_changed_link(self, pr_o->owner_dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-}
-
-void
-nml_dbus_property_o_notify_changed_many(NMLDBusPropertyO *ptr, guint len, NMClient *self)
-{
-    while (len-- > 0)
-        nml_dbus_property_o_notify_changed(ptr++, self);
-}
-
-static void
-nml_dbus_property_o_notify_watch_cb(NMClient *self, gpointer obj_watcher)
-{
-    PropertyOData *   pr_o_data = obj_watcher;
-    NMLDBusPropertyO *pr_o      = pr_o_data->pr_o;
-
-    nm_assert(pr_o->obj_watcher == obj_watcher);
-
-    if (!pr_o->block_is_changed && !pr_o->is_changed) {
-        pr_o->is_changed = TRUE;
-        nml_dbus_object_obj_changed_link(self, pr_o->owner_dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-    }
-}
-
-static NMLDBusNotifyUpdatePropFlags
-nml_dbus_property_o_notify(NMClient *              self,
-                           NMLDBusPropertyO *      pr_o,
-                           NMLDBusObject *         dbobj,
-                           const NMLDBusMetaIface *meta_iface,
-                           guint                   dbus_property_idx,
-                           GVariant *              value)
-{
-    const char *dbus_path = NULL;
-    gboolean    changed   = FALSE;
-
-    if (!pr_o->owner_dbobj) {
-        nm_assert(!pr_o->meta_iface);
-        nm_assert(pr_o->dbus_property_idx == 0);
-        nm_assert(!pr_o->is_ready);
-        pr_o->owner_dbobj       = dbobj;
-        pr_o->meta_iface        = meta_iface;
-        pr_o->dbus_property_idx = dbus_property_idx;
-    } else {
-        nm_assert(pr_o->owner_dbobj == dbobj);
-        nm_assert(pr_o->meta_iface == meta_iface);
-        nm_assert(pr_o->dbus_property_idx == dbus_property_idx);
-    }
-
-    if (value)
-        dbus_path = nm_dbus_path_not_empty(g_variant_get_string(value, NULL));
-
-    if (pr_o->obj_watcher
-        && (!dbus_path || !nm_streq(dbus_path, pr_o->obj_watcher->dbobj->dbus_path->str))) {
-        _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&pr_o->obj_watcher));
-        changed = TRUE;
-    }
-    if (!pr_o->obj_watcher && dbus_path) {
-        pr_o->obj_watcher                           = _dbobjs_obj_watcher_register_r(self,
-                                                           nm_ref_string_new(dbus_path),
-                                                           nml_dbus_property_o_notify_watch_cb,
-                                                           sizeof(PropertyOData));
-        ((PropertyOData *) pr_o->obj_watcher)->pr_o = pr_o;
-        changed                                     = TRUE;
-    }
-
-    if (changed && !pr_o->is_changed) {
-        pr_o->is_changed = TRUE;
-        nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-    }
-
-    return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
-}
-
-void
-nml_dbus_property_o_clear(NMLDBusPropertyO *pr_o, NMClient *self)
-{
-    if (pr_o->obj_watcher) {
-        nm_assert(NM_IS_CLIENT(self));
-        _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&pr_o->obj_watcher));
-    }
-    if (pr_o->nmobj && pr_o->owner_dbobj && pr_o->owner_dbobj->nmobj) {
-        _nm_client_queue_notify_object(
-            self,
-            pr_o->owner_dbobj->nmobj,
-            pr_o->meta_iface->obj_properties
-                [pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].obj_properties_idx]);
-    }
-    pr_o->owner_dbobj       = NULL;
-    pr_o->meta_iface        = NULL;
-    pr_o->dbus_property_idx = 0;
-    pr_o->is_ready          = FALSE;
-}
-
-void
-nml_dbus_property_o_clear_many(NMLDBusPropertyO *pr_o, guint len, NMClient *self)
-{
-    while (len-- > 0)
-        nml_dbus_property_o_clear(pr_o++, self);
-}
-
-/*****************************************************************************/
-
-typedef struct _NMLDBusPropertyAOData {
-    NMLDBusObjWatcher              obj_watcher;
-    NMLDBusPropertyAO *            parent;
-    CList                          data_lst;
-    GObject *                      nmobj;
-    struct _NMLDBusPropertyAOData *changed_next;
-    bool                           is_ready : 1;
-    bool                           is_notified : 1;
-    bool                           is_changed : 1;
-    bool                           block_is_changed : 1;
-} PropertyAOData;
-
-static void
-_ASSERT_pr_ao(NMLDBusPropertyAO *pr_ao)
-{
-    nm_assert(pr_ao);
-
-#if NM_MORE_ASSERTS > 10
-    if (pr_ao->owner_dbobj) {
-        guint           n_not_ready  = 0;
-        guint           n_is_changed = 0;
-        guint           n_is_changed_2;
-        PropertyAOData *pr_ao_data;
-
-        c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) {
-            if (pr_ao_data->is_changed)
-                n_is_changed++;
-            if (!pr_ao_data->is_ready)
-                n_not_ready++;
-        }
-        nm_assert(n_not_ready == pr_ao->n_not_ready);
-
-        n_is_changed_2 = 0;
-        pr_ao_data     = pr_ao->changed_head;
-        while (pr_ao_data) {
-            nm_assert(pr_ao_data->is_changed);
-            n_is_changed_2++;
-            pr_ao_data = pr_ao_data->changed_next;
-        }
-        nm_assert(n_is_changed == n_is_changed_2);
-    }
-#endif
-}
-
-static gboolean
-nml_dbus_property_ao_notify_changed_ao(PropertyAOData *pr_ao_data,
-                                       NMClient *      self,
-                                       gboolean        is_added /* or else removed */)
-{
-    NMLDBusPropertyAO *           pr_ao;
-    const NMLDBusPropertVTableAO *vtable;
-
-    if (!pr_ao_data->nmobj)
-        return FALSE;
-
-    nm_assert(pr_ao_data->is_ready);
-
-    if (is_added) {
-        if (pr_ao_data->is_notified)
-            return FALSE;
-        pr_ao_data->is_notified = TRUE;
-    } else {
-        if (!pr_ao_data->is_notified)
-            return FALSE;
-        pr_ao_data->is_notified = FALSE;
-    }
-
-    pr_ao = pr_ao_data->parent;
-
-    vtable = pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].extra.property_vtable_ao;
-
-    if (vtable->notify_changed_ao)
-        vtable->notify_changed_ao(pr_ao, self, NM_OBJECT(pr_ao_data->nmobj), is_added);
-    return TRUE;
-}
-
-const GPtrArray *
-nml_dbus_property_ao_get_objs_as_ptrarray(NMLDBusPropertyAO *pr_ao)
-{
-    if (!pr_ao->arr) {
-        PropertyAOData *pr_ao_data;
-        gsize           n;
-
-        n = 0;
-        if (pr_ao->owner_dbobj) {
-            c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) {
-                if (pr_ao_data->nmobj)
-                    n++;
-            }
-        }
-
-        pr_ao->arr = g_ptr_array_new_full(n, g_object_unref);
-        if (pr_ao->owner_dbobj) {
-            c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) {
-                if (pr_ao_data->nmobj)
-                    g_ptr_array_add(pr_ao->arr, g_object_ref(pr_ao_data->nmobj));
-            }
-        }
-    }
-    return pr_ao->arr;
-}
-
-gboolean
-nml_dbus_property_ao_is_ready(const NMLDBusPropertyAO *pr_ao)
-{
-    return pr_ao->n_not_ready == 0;
-}
-
-static void
-nml_dbus_property_ao_notify_changed(NMLDBusPropertyAO *pr_ao, NMClient *self)
-{
-    gboolean        changed_prop  = FALSE;
-    gboolean        changed_ready = FALSE;
-    PropertyAOData *pr_ao_data;
-
-    nm_assert(NM_IS_CLIENT(self));
-    _ASSERT_pr_ao(pr_ao);
-
-    if (!pr_ao->owner_dbobj)
-        return;
-
-    if (!pr_ao->is_changed) {
-        if (pr_ao->n_not_ready == 0)
-            return;
-        goto done;
-    }
-
-    pr_ao->is_changed = FALSE;
-
-    while (pr_ao->changed_head) {
-        const NMLDBusPropertVTableAO *vtable;
-        GObject *                     nmobj    = NULL;
-        gboolean                      is_ready = TRUE;
-        GType                         gtype;
-
-        pr_ao_data = g_steal_pointer(&pr_ao->changed_head);
-        nm_assert(pr_ao_data->is_changed);
-
-        pr_ao->changed_head    = pr_ao_data->changed_next;
-        pr_ao_data->is_changed = FALSE;
-
-        if (!pr_ao_data->obj_watcher.dbobj->nmobj) {
-            if (pr_ao_data->obj_watcher.dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS) {
-                NML_NMCLIENT_LOG_W(
-                    self,
-                    "[%s]: property %s references %s but object is not created",
-                    pr_ao->owner_dbobj->dbus_path->str,
-                    pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name,
-                    pr_ao_data->obj_watcher.dbobj->dbus_path->str);
-            } else {
-                NML_NMCLIENT_LOG_E(
-                    self,
-                    "[%s]: property %s references %s but object is not present on D-Bus",
-                    pr_ao->owner_dbobj->dbus_path->str,
-                    pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name,
-                    pr_ao_data->obj_watcher.dbobj->dbus_path->str);
-            }
-            goto done_pr_ao_data;
-        }
-
-        vtable =
-            pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].extra.property_vtable_ao;
-
-        gtype = vtable->get_o_type_fcn();
-        if (!g_type_is_a(G_OBJECT_TYPE(pr_ao_data->obj_watcher.dbobj->nmobj), gtype)) {
-            NML_NMCLIENT_LOG_E(
-                self,
-                "[%s]: property %s references %s with unexpected GObject type %s instead of %s",
-                pr_ao->owner_dbobj->dbus_path->str,
-                pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name,
-                pr_ao_data->obj_watcher.dbobj->dbus_path->str,
-                G_OBJECT_TYPE_NAME(pr_ao_data->obj_watcher.dbobj->nmobj),
-                g_type_name(gtype));
-            goto done_pr_ao_data;
-        }
-
-        if (pr_ao_data->obj_watcher.dbobj == pr_ao->owner_dbobj) {
-            NML_NMCLIENT_LOG_W(
-                self,
-                "[%s]: property %s references itself",
-                pr_ao->owner_dbobj->dbus_path->str,
-                pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name);
-            nmobj = pr_ao->owner_dbobj->nmobj;
-            goto done_pr_ao_data;
-        }
-
-        pr_ao_data->block_is_changed = TRUE;
-        is_ready = _dbobjs_check_dbobj_ready(self, pr_ao_data->obj_watcher.dbobj);
-        pr_ao_data->block_is_changed = FALSE;
-
-        if (!is_ready) {
-            is_ready = vtable->is_always_ready;
-            goto done_pr_ao_data;
-        }
-
-        if (vtable->check_nmobj_visible_fcn
-            && !vtable->check_nmobj_visible_fcn(pr_ao_data->obj_watcher.dbobj->nmobj)) {
-            is_ready = TRUE;
-            goto done_pr_ao_data;
-        }
-
-        nmobj = pr_ao_data->obj_watcher.dbobj->nmobj;
-
-done_pr_ao_data:
-
-        if (!pr_ao_data->is_ready && is_ready) {
-            nm_assert(pr_ao->n_not_ready > 0);
-            pr_ao->n_not_ready--;
-            pr_ao_data->is_ready = TRUE;
-            changed_ready        = TRUE;
-        }
-
-        if (pr_ao_data->nmobj != nmobj) {
-            if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, FALSE))
-                changed_prop = TRUE;
-            pr_ao_data->nmobj = nmobj;
-        }
-
-        if (!pr_ao_data->is_notified) {
-            if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, TRUE))
-                changed_prop = TRUE;
-        }
-    }
-
-    _ASSERT_pr_ao(pr_ao);
-
-done:
-    if (changed_prop) {
-        nm_clear_pointer(&pr_ao->arr, g_ptr_array_unref);
-        _nm_client_queue_notify_object(
-            self,
-            pr_ao->owner_dbobj->nmobj,
-            pr_ao->meta_iface->obj_properties
-                [pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].obj_properties_idx]);
-    }
-    if (changed_ready && pr_ao->n_not_ready == 0
-        && pr_ao->owner_dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY)
-        nml_dbus_object_obj_changed_link(self, pr_ao->owner_dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-}
-
-void
-nml_dbus_property_ao_notify_changed_many(NMLDBusPropertyAO *ptr, guint len, NMClient *self)
-{
-    while (len-- > 0)
-        nml_dbus_property_ao_notify_changed(ptr++, self);
-}
-
-static void
-nml_dbus_property_ao_notify_watch_cb(NMClient *self, gpointer obj_watcher)
-{
-    PropertyAOData *   pr_ao_data = obj_watcher;
-    NMLDBusPropertyAO *pr_ao      = pr_ao_data->parent;
-
-    nm_assert(g_hash_table_lookup(pr_ao->hash, pr_ao_data) == pr_ao_data);
-
-    if (!pr_ao_data->block_is_changed && !pr_ao_data->is_changed) {
-        pr_ao_data->is_changed   = TRUE;
-        pr_ao_data->changed_next = pr_ao->changed_head;
-        pr_ao->changed_head      = pr_ao_data;
-        if (!pr_ao->is_changed) {
-            pr_ao->is_changed = TRUE;
-            nml_dbus_object_obj_changed_link(self,
-                                             pr_ao->owner_dbobj,
-                                             NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-        }
-    }
-
-    _ASSERT_pr_ao(pr_ao);
-}
-
-static NMLDBusNotifyUpdatePropFlags
-nml_dbus_property_ao_notify(NMClient *              self,
-                            NMLDBusPropertyAO *     pr_ao,
-                            NMLDBusObject *         dbobj,
-                            const NMLDBusMetaIface *meta_iface,
-                            guint                   dbus_property_idx,
-                            GVariant *              value)
-{
-    CList           stale_lst_head = C_LIST_INIT(stale_lst_head);
-    PropertyAOData *pr_ao_data;
-    gboolean        changed_prop = FALSE;
-    gboolean        changed_obj  = FALSE;
-
-    if (!pr_ao->owner_dbobj) {
-        nm_assert(!pr_ao->data_lst_head.next);
-        nm_assert(!pr_ao->data_lst_head.prev);
-        nm_assert(!pr_ao->hash);
-        nm_assert(!pr_ao->meta_iface);
-        nm_assert(pr_ao->dbus_property_idx == 0);
-        nm_assert(pr_ao->n_not_ready == 0);
-        nm_assert(!pr_ao->changed_head);
-        nm_assert(!pr_ao->is_changed);
-
-        c_list_init(&pr_ao->data_lst_head);
-        pr_ao->hash              = g_hash_table_new(nm_ppdirect_hash, nm_ppdirect_equal);
-        pr_ao->owner_dbobj       = dbobj;
-        pr_ao->meta_iface        = meta_iface;
-        pr_ao->dbus_property_idx = dbus_property_idx;
-    } else {
-        nm_assert(pr_ao->data_lst_head.next);
-        nm_assert(pr_ao->data_lst_head.prev);
-        nm_assert(pr_ao->hash);
-        nm_assert(pr_ao->meta_iface == meta_iface);
-        nm_assert(pr_ao->dbus_property_idx == dbus_property_idx);
-    }
-
-    c_list_splice(&stale_lst_head, &pr_ao->data_lst_head);
-
-    if (value) {
-        GVariantIter iter;
-        const char * path;
-
-        g_variant_iter_init(&iter, value);
-        while (g_variant_iter_next(&iter, "&o", &path)) {
-            nm_auto_ref_string NMRefString *dbus_path_r = NULL;
-            gpointer                        p_dbus_path_1;
-
-            G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(PropertyAOData, obj_watcher) == 0);
-            G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMLDBusObjWatcher, dbobj) == 0);
-            G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMLDBusObject, dbus_path) == 0);
-
-            if (!nm_dbus_path_not_empty(path)) {
-                /* should not happen. Anyway, silently skip empty paths. */
-                continue;
-            }
-
-            dbus_path_r   = nm_ref_string_new(path);
-            p_dbus_path_1 = &dbus_path_r;
-            pr_ao_data    = g_hash_table_lookup(pr_ao->hash, &p_dbus_path_1);
-
-            if (pr_ao_data) {
-                /* With this implementation we cannot track the same path multiple times.
-                 * Of course, for none of the properties where we use this, the server
-                 * should expose the same path more than once, so this limitation is fine
-                 * (maybe even preferable to drop duplicates form NMClient's API). */
-                nm_assert(pr_ao_data->obj_watcher.dbobj->dbus_path == dbus_path_r);
-                if (!changed_prop && pr_ao_data->is_notified) {
-                    /* The order of a notified entry changed. That means, we need to signal
-                     * a change of the property. This detection of a change is not always
-                     * correct, in particular we might detect some changes when there were
-                     * none. That's not a serious problem, and fixing it would be expensive
-                     * to implement. */
-                    changed_prop = (c_list_first(&stale_lst_head) != &pr_ao_data->data_lst);
-                }
-                nm_c_list_move_tail(&pr_ao->data_lst_head, &pr_ao_data->data_lst);
-            } else {
-                pr_ao_data                   = _dbobjs_obj_watcher_register_r(self,
-                                                            g_steal_pointer(&dbus_path_r),
-                                                            nml_dbus_property_ao_notify_watch_cb,
-                                                            sizeof(PropertyAOData)),
-                pr_ao_data->parent           = pr_ao;
-                pr_ao_data->nmobj            = NULL;
-                pr_ao_data->changed_next     = NULL;
-                pr_ao_data->is_changed       = TRUE;
-                pr_ao_data->block_is_changed = FALSE;
-                pr_ao_data->is_ready         = FALSE;
-                pr_ao_data->is_notified      = FALSE;
-                c_list_link_tail(&pr_ao->data_lst_head, &pr_ao_data->data_lst);
-                if (!g_hash_table_add(pr_ao->hash, pr_ao_data))
-                    nm_assert_not_reached();
-                nm_assert(pr_ao->n_not_ready < G_MAXUINT);
-                pr_ao->n_not_ready++;
-            }
-
-#if NM_MORE_ASSERTS > 10
-            {
-                nm_auto_ref_string NMRefString *p  = nm_ref_string_new(path);
-                gpointer                        pp = &p;
-
-                nm_assert(g_hash_table_lookup(pr_ao->hash, &pp) == pr_ao_data);
-            }
-#endif
-        }
-    }
-
-    pr_ao->changed_head = NULL;
-    c_list_for_each_entry (pr_ao_data, &pr_ao->data_lst_head, data_lst) {
-        if (pr_ao_data->is_changed) {
-            pr_ao_data->changed_next = pr_ao->changed_head;
-            pr_ao->changed_head      = pr_ao_data;
-            changed_obj              = TRUE;
-        }
-    }
-
-    while ((pr_ao_data = c_list_first_entry(&stale_lst_head, PropertyAOData, data_lst))) {
-        changed_obj = TRUE;
-        c_list_unlink(&pr_ao_data->data_lst);
-        if (!g_hash_table_remove(pr_ao->hash, pr_ao_data))
-            nm_assert_not_reached();
-        if (!pr_ao_data->is_ready) {
-            nm_assert(pr_ao->n_not_ready > 0);
-            pr_ao->n_not_ready--;
-        } else {
-            if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, FALSE))
-                changed_prop = TRUE;
-        }
-        _dbobjs_obj_watcher_unregister(self, pr_ao_data);
-    }
-
-    _ASSERT_pr_ao(pr_ao);
-
-    if (changed_obj) {
-        pr_ao->is_changed = TRUE;
-        nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-    }
-
-    if (changed_prop) {
-        nm_clear_pointer(&pr_ao->arr, g_ptr_array_unref);
-        _nm_client_queue_notify_object(
-            self,
-            pr_ao->owner_dbobj->nmobj,
-            pr_ao->meta_iface->obj_properties
-                [pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].obj_properties_idx]);
-    }
-
-    return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
-}
-
-void
-nml_dbus_property_ao_clear(NMLDBusPropertyAO *pr_ao, NMClient *self)
-{
-    _ASSERT_pr_ao(pr_ao);
-
-    if (!pr_ao->owner_dbobj) {
-        nm_assert(pr_ao->n_not_ready == 0);
-        nm_assert((!pr_ao->data_lst_head.next && !pr_ao->data_lst_head.prev)
-                  || (pr_ao->data_lst_head.next == pr_ao->data_lst_head.prev));
-        nm_assert(!pr_ao->hash);
-        nm_assert(!pr_ao->meta_iface);
-        nm_assert(pr_ao->dbus_property_idx == 0);
-        nm_assert(!pr_ao->is_changed);
-    } else {
-        PropertyAOData *pr_ao_data;
-        gboolean        changed_prop = FALSE;
-
-        nm_assert(NM_IS_CLIENT(self));
-        nm_assert(pr_ao->data_lst_head.next);
-        nm_assert(pr_ao->data_lst_head.prev);
-        nm_assert(pr_ao->hash);
-        nm_assert(pr_ao->meta_iface);
-
-        while ((pr_ao_data = c_list_first_entry(&pr_ao->data_lst_head, PropertyAOData, data_lst))) {
-            if (!pr_ao_data->is_ready) {
-                nm_assert(pr_ao->n_not_ready > 0);
-                pr_ao->n_not_ready--;
-            } else {
-                if (nml_dbus_property_ao_notify_changed_ao(pr_ao_data, self, FALSE))
-                    changed_prop = TRUE;
-            }
-            c_list_unlink(&pr_ao_data->data_lst);
-            if (!g_hash_table_remove(pr_ao->hash, pr_ao_data))
-                nm_assert_not_reached();
-            _dbobjs_obj_watcher_unregister(self, pr_ao_data);
-        }
-
-        nm_assert(c_list_is_empty(&pr_ao->data_lst_head));
-        nm_assert(pr_ao->n_not_ready == 0);
-        nm_assert(g_hash_table_size(pr_ao->hash) == 0);
-
-        if (changed_prop && pr_ao->owner_dbobj->nmobj) {
-            _nm_client_queue_notify_object(
-                self,
-                pr_ao->owner_dbobj->nmobj,
-                pr_ao->meta_iface
-                    ->obj_properties[pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx]
-                                         .obj_properties_idx]);
-        }
-
-        nm_assert(c_list_is_empty(&pr_ao->data_lst_head));
-        nm_assert(pr_ao->n_not_ready == 0);
-        nm_assert(g_hash_table_size(pr_ao->hash) == 0);
-        nm_clear_pointer(&pr_ao->hash, g_hash_table_unref);
-        pr_ao->owner_dbobj        = NULL;
-        pr_ao->meta_iface         = NULL;
-        pr_ao->dbus_property_idx  = 0;
-        pr_ao->data_lst_head.next = NULL;
-        pr_ao->data_lst_head.prev = NULL;
-        pr_ao->is_changed         = FALSE;
-    }
-
-    nm_clear_pointer(&pr_ao->arr, g_ptr_array_unref);
-}
-
-void
-nml_dbus_property_ao_clear_many(NMLDBusPropertyAO *pr_ao, guint len, NMClient *self)
-{
-    while (len-- > 0)
-        nml_dbus_property_ao_clear(pr_ao++, self);
-}
-
-/*****************************************************************************/
-
-NMLDBusNotifyUpdatePropFlags
-_nml_dbus_notify_update_prop_ignore(NMClient *              self,
-                                    NMLDBusObject *         dbobj,
-                                    const NMLDBusMetaIface *meta_iface,
-                                    guint                   dbus_property_idx,
-                                    GVariant *              value)
-{
-    return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
-}
-
-NMLDBusNotifyUpdatePropFlags
-_nml_dbus_notify_update_prop_o(NMClient *              self,
-                               NMLDBusObject *         dbobj,
-                               const NMLDBusMetaIface *meta_iface,
-                               guint                   dbus_property_idx,
-                               GVariant *              value)
-{
-    const char *  path = NULL;
-    NMRefString **p_property;
-
-    if (value)
-        path = g_variant_get_string(value, NULL);
-
-    p_property =
-        nml_dbus_object_get_property_location(dbobj,
-                                              meta_iface,
-                                              &meta_iface->dbus_properties[dbus_property_idx]);
-
-    if (!nm_streq0(nm_ref_string_get_str(*p_property), path)) {
-        nm_ref_string_unref(*p_property);
-        *p_property = nm_ref_string_new(path);
-    }
-    return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
-}
-
-/*****************************************************************************/
-
-static void
-_obj_handle_dbus_prop_changes(NMClient *           self,
-                              NMLDBusObject *      dbobj,
-                              NMLDBusObjIfaceData *db_iface_data,
-                              guint                dbus_property_idx,
-                              GVariant *           value)
-{
-    const NMLDBusMetaIface *     meta_iface    = db_iface_data->dbus_iface.meta;
-    const NMLDBusMetaProperty *  meta_property = &meta_iface->dbus_properties[dbus_property_idx];
-    gpointer                     p_property;
-    const char *                 dbus_type_s;
-    const GParamSpec *           param_spec;
-    NMLDBusNotifyUpdatePropFlags notify_update_prop_flags;
-
-    nm_assert(G_IS_OBJECT(dbobj->nmobj));
-
-    if (value && !g_variant_is_of_type(value, meta_property->dbus_type)) {
-        NML_NMCLIENT_LOG_E(self,
-                           "[%s] property %s.%s expected of type \"%s\" but is \"%s\". Ignore",
-                           dbobj->dbus_path->str,
-                           meta_iface->dbus_iface_name,
-                           meta_property->dbus_property_name,
-                           (const char *) meta_property->dbus_type,
-                           (const char *) g_variant_get_type(value));
-        value = NULL;
-    }
-
-    if (meta_property->use_notify_update_prop) {
-        notify_update_prop_flags =
-            meta_property->notify_update_prop(self, dbobj, meta_iface, dbus_property_idx, value);
-        if (notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE)
-            return;
-
-        nm_assert(notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY);
-        nm_assert(G_IS_OBJECT(dbobj->nmobj));
-        nm_assert(meta_iface->obj_properties);
-        nm_assert(meta_property->obj_properties_idx > 0);
-        param_spec = meta_iface->obj_properties[meta_property->obj_properties_idx];
-        goto notify;
-    }
-
-    p_property = nml_dbus_object_get_property_location(dbobj, meta_iface, meta_property);
-
-    dbus_type_s = (const char *) meta_property->dbus_type;
-
-    nm_assert(G_IS_OBJECT(dbobj->nmobj));
-    nm_assert(meta_iface->obj_properties);
-    nm_assert(meta_property->obj_properties_idx > 0);
-    param_spec = meta_iface->obj_properties[meta_property->obj_properties_idx];
-
-    notify_update_prop_flags = NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
-
-    switch (dbus_type_s[0]) {
-    case 'b':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((bool *) p_property) = g_variant_get_boolean(value);
-        else if (param_spec->value_type == G_TYPE_BOOLEAN)
-            *((bool *) p_property) = ((GParamSpecBoolean *) param_spec)->default_value;
-        else {
-            nm_assert_not_reached();
-            *((bool *) p_property) = FALSE;
-        }
-        break;
-    case 'y':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((guint8 *) p_property) = g_variant_get_byte(value);
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((guint8 *) p_property) = 0;
-        }
-        break;
-    case 'q':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((guint16 *) p_property) = g_variant_get_uint16(value);
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((guint16 *) p_property) = 0;
-        }
-        break;
-    case 'i':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((gint32 *) p_property) = g_variant_get_int32(value);
-        else if (param_spec->value_type == G_TYPE_INT)
-            *((gint32 *) p_property) = ((GParamSpecInt *) param_spec)->default_value;
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((gint32 *) p_property) = 0;
-        }
-        break;
-    case 'u':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((guint32 *) p_property) = g_variant_get_uint32(value);
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((guint32 *) p_property) = 0;
-        }
-        break;
-    case 'x':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((gint64 *) p_property) = g_variant_get_int64(value);
-        else if (param_spec->value_type == G_TYPE_INT64)
-            *((gint64 *) p_property) = ((GParamSpecInt64 *) param_spec)->default_value;
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((gint64 *) p_property) = 0;
-        }
-        break;
-    case 't':
-        nm_assert(dbus_type_s[1] == '\0');
-        if (value)
-            *((guint64 *) p_property) = g_variant_get_uint64(value);
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((guint64 *) p_property) = 0;
-        }
-        break;
-    case 's':
-        nm_assert(dbus_type_s[1] == '\0');
-        nm_clear_g_free((char **) p_property);
-        if (value)
-            *((char **) p_property) = g_variant_dup_string(value, NULL);
-        else {
-            nm_assert(nm_utils_g_param_spec_is_default(param_spec));
-            *((char **) p_property) = NULL;
-        }
-        break;
-    case 'o':
-        nm_assert(dbus_type_s[1] == '\0');
-        notify_update_prop_flags = nml_dbus_property_o_notify(self,
-                                                              p_property,
-                                                              dbobj,
-                                                              meta_iface,
-                                                              dbus_property_idx,
-                                                              value);
-        break;
-    case 'a':
-        switch (dbus_type_s[1]) {
-        case 'y':
-            nm_assert(dbus_type_s[2] == '\0');
-            {
-                gconstpointer v;
-                gsize         l;
-                GBytes *      b = NULL;
-
-                if (value) {
-                    v = g_variant_get_fixed_array(value, &l, 1);
-
-                    if (l > 0) {
-                        /* empty arrays are coerced to NULL. */
-                        b = g_bytes_new(v, l);
-                    }
-                }
-
-                nm_clear_pointer((GBytes **) p_property, g_bytes_unref);
-                *((GBytes **) p_property) = b;
-            }
-            break;
-        case 's':
-            nm_assert(dbus_type_s[2] == '\0');
-            nm_assert(param_spec->value_type == G_TYPE_STRV);
-
-            g_strfreev(*((char ***) p_property));
-            if (value)
-                *((char ***) p_property) = g_variant_dup_strv(value, NULL);
-            else
-                *((char ***) p_property) = NULL;
-            break;
-        case 'o':
-            nm_assert(dbus_type_s[2] == '\0');
-            notify_update_prop_flags = nml_dbus_property_ao_notify(self,
-                                                                   p_property,
-                                                                   dbobj,
-                                                                   meta_iface,
-                                                                   dbus_property_idx,
-                                                                   value);
-            break;
-        default:
-            nm_assert_not_reached();
-        }
-        break;
-    default:
-        nm_assert_not_reached();
-    }
-
-notify:
-    if (NM_FLAGS_HAS(notify_update_prop_flags, NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY))
-        g_object_notify_by_pspec(dbobj->nmobj, (GParamSpec *) param_spec);
-}
-
-static void
-_obj_handle_dbus_iface_changes(NMClient *           self,
-                               NMLDBusObject *      dbobj,
-                               NMLDBusObjIfaceData *db_iface_data)
-{
-    NMLDBusObjPropData *db_prop_data;
-    gboolean            is_self = (G_OBJECT(self) == dbobj->nmobj);
-    gboolean            is_removed;
-    gboolean            type_compatible;
-    guint8              i_prop;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(is_self || NM_IS_OBJECT(dbobj->nmobj));
-
-    if (G_UNLIKELY(!db_iface_data->nmobj_checked)) {
-        db_iface_data->nmobj_checked = TRUE;
-        type_compatible              = db_iface_data->dbus_iface.meta->get_type_fcn
-                          && g_type_is_a(G_OBJECT_TYPE(dbobj->nmobj),
-                                         db_iface_data->dbus_iface.meta->get_type_fcn());
-        db_iface_data->nmobj_compatible = type_compatible;
-    } else
-        type_compatible = db_iface_data->nmobj_compatible;
-
-    if (!type_compatible) {
-        /* on D-Bus, we have this interface associate with the object, but apparently
-         * it is not compatible. This is either a bug, or NetworkManager exposed an
-         * unexpected interface on D-Bus object for which we create a certain NMObject
-         * type. */
-        return;
-    }
-
-    is_removed = c_list_is_empty(&db_iface_data->iface_lst);
-
-    nm_assert(is_removed || !c_list_is_empty(&db_iface_data->changed_prop_lst_head));
-
-    _nm_client_queue_notify_object(self, dbobj->nmobj, NULL);
-
-    if (is_removed) {
-        for (i_prop = 0; i_prop < db_iface_data->dbus_iface.meta->n_dbus_properties; i_prop++) {
-            _obj_handle_dbus_prop_changes(self, dbobj, db_iface_data, i_prop, NULL);
-        }
-    } else {
-        while ((db_prop_data = c_list_first_entry(&db_iface_data->changed_prop_lst_head,
-                                                  NMLDBusObjPropData,
-                                                  changed_prop_lst))) {
-            gs_unref_variant GVariant *prop_data_value = NULL;
-
-            c_list_unlink(&db_prop_data->changed_prop_lst);
-
-            nm_assert(db_prop_data >= db_iface_data->prop_datas);
-            nm_assert(
-                db_prop_data
-                < &db_iface_data->prop_datas[db_iface_data->dbus_iface.meta->n_dbus_properties]);
-            nm_assert(db_prop_data->prop_data_value);
-
-            /* Currently, NMLDBusObject forgets about the variant. Theoretically, it could cache
-             * it, but there is no need because we update the property in nmobj (which extracts and
-             * keeps the property value itself).
-             *
-             * Note that we only consume the variant here when we process it.
-             * That implies that we already created a NMObject for the dbobj
-             * instance. Unless that happens, we cache the last seen property values. */
-            prop_data_value = g_steal_pointer(&db_prop_data->prop_data_value);
-
-            i_prop = (db_prop_data - &db_iface_data->prop_datas[0]);
-            _obj_handle_dbus_prop_changes(self, dbobj, db_iface_data, i_prop, prop_data_value);
-        }
-    }
-}
-
-static void
-_obj_handle_dbus_changes(NMClient *self, NMLDBusObject *dbobj)
-{
-    NMClientPrivate *    priv = NM_CLIENT_GET_PRIVATE(self);
-    NMLDBusObjIfaceData *db_iface_data;
-    NMLDBusObjIfaceData *db_iface_data_safe;
-    gs_unref_object GObject *nmobj_unregistering = NULL;
-
-    _ASSERT_dbobj(dbobj, self);
-
-    /* In a first step we only remember all the changes that a D-Bus message brings
-     * and queue the object to process them.
-     *
-     * Here (in step 2) we look at what changed on D-Bus and propagate those changes
-     * to the NMObject instance.
-     *
-     * Note that here we still must not emit any GObject signals. That follows later,
-     * and again if the object changes, we will just queue that we handle the changes
-     * later. */
-
-    c_list_for_each_entry_safe (db_iface_data,
-                                db_iface_data_safe,
-                                &dbobj->iface_lst_head,
-                                iface_lst) {
-        if (!db_iface_data->iface_removed)
-            continue;
-        c_list_unlink(&db_iface_data->iface_lst);
-        if (db_iface_data->dbus_iface_is_wellknown && dbobj->nmobj)
-            _obj_handle_dbus_iface_changes(self, dbobj, db_iface_data);
-        nml_dbus_obj_iface_data_destroy(db_iface_data);
-    }
-
-    if (G_UNLIKELY(!dbobj->nmobj) && !c_list_is_empty(&dbobj->iface_lst_head)) {
-        /* Try to create a NMObject for this D-Bus object. Note that we detect the type
-         * based on the interfaces that it has, and if we make a choice once, we don't
-         * change. That means, one D-Bus object can only be of one type. */
-
-        if (NM_IN_SET(dbobj->dbus_path,
-                      _dbus_path_nm,
-                      _dbus_path_settings,
-                      _dbus_path_dns_manager)) {
-            /* For the main types, we don't detect them based on the interfaces present,
-             * but on the path names. Of course, both should correspond anyway. */
-            NML_NMCLIENT_LOG_T(self,
-                               "[%s]: register NMClient for D-Bus object",
-                               dbobj->dbus_path->str);
-            dbobj->nmobj = G_OBJECT(self);
-            if (dbobj->dbus_path == _dbus_path_nm) {
-                nm_assert(!priv->dbobj_nm);
-                priv->dbobj_nm = dbobj;
-            } else if (dbobj->dbus_path == _dbus_path_settings) {
-                nm_assert(!priv->dbobj_settings);
-                priv->dbobj_settings = dbobj;
-            } else {
-                nm_assert(dbobj->dbus_path == _dbus_path_dns_manager);
-                nm_assert(!priv->dbobj_dns_manager);
-                priv->dbobj_dns_manager = dbobj;
-            }
-            nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY, self);
-        } else {
-            GType                   gtype     = G_TYPE_NONE;
-            NMLDBusMetaInteracePrio curr_prio = NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_10 - 1;
-
-            c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
-                nm_assert(!db_iface_data->iface_removed);
-                if (!db_iface_data->dbus_iface_is_wellknown)
-                    break;
-                if (db_iface_data->dbus_iface.meta->interface_prio <= curr_prio)
-                    continue;
-                curr_prio = db_iface_data->dbus_iface.meta->interface_prio;
-                gtype     = db_iface_data->dbus_iface.meta->get_type_fcn();
-            }
-            if (gtype != G_TYPE_NONE) {
-                dbobj->nmobj = g_object_new(gtype, NULL);
-
-                NML_NMCLIENT_LOG_T(self,
-                                   "[%s]: register new NMObject " NM_HASH_OBFUSCATE_PTR_FMT
-                                   " of type %s",
-                                   dbobj->dbus_path->str,
-                                   NM_HASH_OBFUSCATE_PTR(dbobj->nmobj),
-                                   g_type_name(gtype));
-
-                nm_assert(NM_IS_OBJECT(dbobj->nmobj));
-                NM_OBJECT_GET_CLASS(dbobj->nmobj)
-                    ->register_client(NM_OBJECT(dbobj->nmobj), self, dbobj);
-                nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, self);
-            }
-        }
-    }
-
-    c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
-        nm_assert(!db_iface_data->iface_removed);
-        if (!db_iface_data->dbus_iface_is_wellknown)
-            break;
-        if (c_list_is_empty(&db_iface_data->changed_prop_lst_head))
-            continue;
-        if (dbobj->nmobj)
-            _obj_handle_dbus_iface_changes(self, dbobj, db_iface_data);
-    }
-
-    if (c_list_is_empty(&dbobj->iface_lst_head) && dbobj->nmobj) {
-        if (dbobj->nmobj == G_OBJECT(self)) {
-            dbobj->nmobj = NULL;
-            NML_NMCLIENT_LOG_T(self,
-                               "[%s]: unregister NMClient from D-Bus object",
-                               dbobj->dbus_path->str);
-            if (dbobj->dbus_path == _dbus_path_nm) {
-                nm_assert(priv->dbobj_nm == dbobj);
-                priv->dbobj_nm = NULL;
-                nml_dbus_property_o_clear_many(priv->nm.property_o,
-                                               G_N_ELEMENTS(priv->nm.property_o),
-                                               self);
-                nml_dbus_property_ao_clear_many(priv->nm.property_ao,
-                                                G_N_ELEMENTS(priv->nm.property_ao),
-                                                self);
-            } else if (dbobj->dbus_path == _dbus_path_settings) {
-                nm_assert(priv->dbobj_settings == dbobj);
-                priv->dbobj_settings = NULL;
-                nml_dbus_property_ao_clear(&priv->settings.connections, self);
-            } else {
-                nm_assert(dbobj->dbus_path == _dbus_path_dns_manager);
-                nm_assert(priv->dbobj_dns_manager == dbobj);
-                priv->dbobj_dns_manager = NULL;
-            }
-        } else {
-            nmobj_unregistering = g_steal_pointer(&dbobj->nmobj);
-            nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_WATCHED_ONLY, self);
-            NML_NMCLIENT_LOG_T(self,
-                               "[%s]: unregister NMObject " NM_HASH_OBFUSCATE_PTR_FMT " of type %s",
-                               dbobj->dbus_path->str,
-                               NM_HASH_OBFUSCATE_PTR(nmobj_unregistering),
-                               g_type_name(G_OBJECT_TYPE(nmobj_unregistering)));
-            NM_OBJECT_GET_CLASS(nmobj_unregistering)
-                ->unregister_client(NM_OBJECT(nmobj_unregistering), self, dbobj);
-        }
-    }
-
-    nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ);
-}
-
-/*****************************************************************************/
-
-static void
-_dbus_handle_obj_changed_nmobj(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    NMLDBusObject *  dbobj;
-    CList            obj_changed_tmp_lst_head = C_LIST_INIT(obj_changed_tmp_lst_head);
-
-    nm_assert(!nml_dbus_object_obj_changed_any_linked(self, ~NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ));
-
-    /* First we notify all watchers that these objects changed. Note that we only do that
-     * here for the list before processing the changes below in a loop. That is, because
-     * processing changes can again enqueue changed objects, and we only want to want to
-     * notify watchers for the events that happened earlier (not repeatedly notify them). */
-    c_list_splice(&obj_changed_tmp_lst_head, &priv->obj_changed_lst_head);
-    while (
-        (dbobj = c_list_first_entry(&obj_changed_tmp_lst_head, NMLDBusObject, obj_changed_lst))) {
-        nm_c_list_move_tail(&priv->obj_changed_lst_head, &dbobj->obj_changed_lst);
-        _dbobjs_notify_watchers_for_dbobj(self, dbobj);
-    }
-
-again:
-
-    nm_assert(!nml_dbus_object_obj_changed_any_linked(self, ~NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ));
-
-    c_list_splice(&obj_changed_tmp_lst_head, &priv->obj_changed_lst_head);
-
-    while (
-        (dbobj = c_list_first_entry(&obj_changed_tmp_lst_head, NMLDBusObject, obj_changed_lst))) {
-        if (!nml_dbus_object_obj_changed_consume(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ)) {
-            nm_assert_not_reached();
-            continue;
-        }
-
-        if (!dbobj->nmobj)
-            continue;
-
-        if (dbobj->nmobj == G_OBJECT(self)) {
-            if (dbobj == priv->dbobj_nm) {
-                nml_dbus_property_o_notify_changed_many(priv->nm.property_o,
-                                                        G_N_ELEMENTS(priv->nm.property_o),
-                                                        self);
-                nml_dbus_property_ao_notify_changed_many(priv->nm.property_ao,
-                                                         G_N_ELEMENTS(priv->nm.property_ao),
-                                                         self);
-            } else if (dbobj == priv->dbobj_settings)
-                nml_dbus_property_ao_notify_changed(&priv->settings.connections, self);
-            else
-                nm_assert(dbobj == priv->dbobj_dns_manager);
-        } else
-            NM_OBJECT_GET_CLASS(dbobj->nmobj)->obj_changed_notify(NM_OBJECT(dbobj->nmobj));
-
-        _dbobjs_check_dbobj_ready(self, dbobj);
-    }
-
-    if (!c_list_is_empty(&priv->obj_changed_lst_head)) {
-        nm_assert(nml_dbus_object_obj_changed_any_linked(self, NML_DBUS_OBJ_CHANGED_TYPE_NMOBJ));
-        /* we got new changes enqueued. Need to check again. */
-        goto again;
-    }
-}
-
-static void
-_dbus_handle_obj_changed_dbus(NMClient *self, const char *log_context)
-{
-    NMClientPrivate *priv;
-    NMLDBusObject *  dbobj;
-    CList            obj_changed_tmp_lst_head = C_LIST_INIT(obj_changed_tmp_lst_head);
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    /* We move the changed list onto a temporary list and consume that.
-     * Note that nml_dbus_object_obj_changed_consume() will move the object
-     * back to the original list if there are changes of another type.
-     *
-     * This is done so that we can enqueue more changes while processing the
-     * change list. */
-    c_list_splice(&obj_changed_tmp_lst_head, &priv->obj_changed_lst_head);
-
-    while (
-        (dbobj = c_list_first_entry(&obj_changed_tmp_lst_head, NMLDBusObject, obj_changed_lst))) {
-        nm_auto_unref_nml_dbusobj NMLDBusObject *dbobj_unref = NULL;
-
-        if (!nml_dbus_object_obj_changed_consume(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS))
-            continue;
-
-        nm_assert(dbobj->obj_state >= NML_DBUS_OBJ_STATE_ON_DBUS);
-
-        dbobj_unref = nml_dbus_object_ref(dbobj);
-
-        _obj_handle_dbus_changes(self, dbobj);
-
-        if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED)
-            continue;
-
-        if (c_list_is_empty(&dbobj->iface_lst_head) && c_list_is_empty(&dbobj->watcher_lst_head)) {
-            NML_NMCLIENT_LOG_T(self, "[%s]: drop D-Bus instance", dbobj->dbus_path->str);
-            nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_UNLINKED, self);
-            if (!g_hash_table_steal(priv->dbus_objects, dbobj))
-                nm_assert_not_reached();
-            nml_dbus_object_unref(dbobj);
-        }
-    }
-
-    /* D-Bus changes can only be enqueued in an earlier stage. We don't expect
-     * anymore changes of type D-Bus at this point. */
-    nm_assert(!nml_dbus_object_obj_changed_any_linked(self, NML_DBUS_OBJ_CHANGED_TYPE_DBUS));
-}
-
-static void
-_dbus_handle_changes_commit(NMClient *self, gboolean allow_init_start_check_complete)
-{
-    NMClientPrivate *        priv                       = NM_CLIENT_GET_PRIVATE(self);
-    nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
-
-    _dbus_handle_obj_changed_nmobj(self);
-
-    dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context);
-
-    _nm_client_notify_event_emit(self);
-
-    _set_nm_running(self);
-
-    if (allow_init_start_check_complete)
-        _init_start_check_complete(self);
-}
-
-static void
-_dbus_handle_changes(NMClient *  self,
-                     const char *log_context,
-                     gboolean    allow_init_start_check_complete)
-{
-    _dbus_handle_obj_changed_dbus(self, log_context);
-    _dbus_handle_changes_commit(self, allow_init_start_check_complete);
-}
-
-static gboolean
-_dbus_handle_properties_changed(NMClient *      self,
-                                const char *    log_context,
-                                const char *    object_path,
-                                const char *    interface_name,
-                                gboolean        allow_add_iface,
-                                GVariant *      changed_properties,
-                                NMLDBusObject **inout_dbobj)
-{
-    NMLDBusObject *      dbobj                = NULL;
-    NMLDBusObjIfaceData *db_iface_data        = NULL;
-    nm_auto_ref_string NMRefString *dbus_path = NULL;
-
-    nm_assert(!changed_properties
-              || g_variant_is_of_type(changed_properties, G_VARIANT_TYPE("a{sv}")));
-
-    {
-        gs_free char *ss = NULL;
-
-        NML_NMCLIENT_LOG_T(self,
-                           "[%s]: %s: properties changed for interface %s %s%s%s",
-                           object_path,
-                           log_context,
-                           interface_name,
-                           NM_PRINT_FMT_QUOTED(changed_properties,
-                                               "{ ",
-                                               (ss = g_variant_print(changed_properties, TRUE)),
-                                               " }",
-                                               "(no changed properties)"));
-    }
-
-    if (inout_dbobj) {
-        dbobj = *inout_dbobj;
-        nm_assert(!dbobj || nm_streq(object_path, dbobj->dbus_path->str));
-    }
-    if (!dbobj) {
-        dbus_path = nm_ref_string_new(object_path);
-        dbobj     = _dbobjs_dbobj_get_r(self, dbus_path);
-    }
-
-    if (dbobj) {
-        nm_assert(dbobj->obj_state >= NML_DBUS_OBJ_STATE_WATCHED_ONLY);
-        db_iface_data = nml_dbus_object_iface_data_get(dbobj, interface_name, allow_add_iface);
-        if (db_iface_data && dbobj->obj_state == NML_DBUS_OBJ_STATE_WATCHED_ONLY)
-            nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_ON_DBUS, self);
-    } else if (allow_add_iface) {
-        dbobj = _dbobjs_dbobj_create(self, g_steal_pointer(&dbus_path));
-        nml_dbus_object_set_obj_state(dbobj, NML_DBUS_OBJ_STATE_ON_DBUS, self);
-        db_iface_data = nml_dbus_object_iface_data_get(dbobj, interface_name, TRUE);
-        nm_assert(db_iface_data);
-    }
-
-    NM_SET_OUT(inout_dbobj, dbobj);
-
-    if (!db_iface_data) {
-        if (allow_add_iface)
-            NML_NMCLIENT_LOG_E(self,
-                               "%s: [%s] too many interfaces on object. Something is very wrong",
-                               log_context,
-                               object_path);
-        else
-            NML_NMCLIENT_LOG_E(self,
-                               "%s: [%s] property changed signal for non existing interface %s",
-                               log_context,
-                               object_path,
-                               interface_name);
-        nm_assert(!dbobj || dbobj->obj_state != NML_DBUS_OBJ_STATE_UNLINKED);
-        return FALSE;
-    }
-
-    if (!db_iface_data->dbus_iface_is_wellknown)
-        NML_NMCLIENT_LOG_W(self,
-                           "%s: [%s] ignore unknown interface %s",
-                           log_context,
-                           object_path,
-                           interface_name);
-    else if (changed_properties) {
-        GVariantIter iter_prop;
-        const char * property_name;
-        GVariant *   property_value_tmp;
-
-        g_variant_iter_init(&iter_prop, changed_properties);
-        while (g_variant_iter_next(&iter_prop, "{&sv}", &property_name, &property_value_tmp)) {
-            _nm_unused gs_unref_variant GVariant *property_value = property_value_tmp;
-            const NMLDBusMetaProperty *           meta_property;
-            NMLDBusObjPropData *                  db_propdata;
-            guint                                 property_idx;
-
-            meta_property = nml_dbus_meta_property_get(db_iface_data->dbus_iface.meta,
-                                                       property_name,
-                                                       &property_idx);
-            if (!meta_property) {
-                NML_NMCLIENT_LOG_W(self,
-                                   "%s: [%s]: ignore unknown property %s.%s",
-                                   log_context,
-                                   object_path,
-                                   interface_name,
-                                   property_name);
-                continue;
-            }
-
-            db_propdata = &db_iface_data->prop_datas[property_idx];
-
-            NML_NMCLIENT_LOG_T(self,
-                               "[%s]: %s: %s property %s.%s",
-                               object_path,
-                               log_context,
-                               db_propdata->prop_data_value ? "update" : "set",
-                               interface_name,
-                               property_name);
-
-            nm_g_variant_unref(db_propdata->prop_data_value);
-            db_propdata->prop_data_value = g_steal_pointer(&property_value);
-            nm_c_list_move_tail(&db_iface_data->changed_prop_lst_head,
-                                &db_propdata->changed_prop_lst);
-        }
-    }
-
-    nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS);
-    return TRUE;
-}
-
-static gboolean
-_dbus_handle_interface_added(NMClient *  self,
-                             const char *log_context,
-                             const char *object_path,
-                             GVariant *  ifaces)
-{
-    gboolean       changed = FALSE;
-    const char *   interface_name;
-    GVariant *     changed_properties;
-    GVariantIter   iter_ifaces;
-    NMLDBusObject *dbobj = NULL;
-
-    nm_assert(g_variant_is_of_type(ifaces, G_VARIANT_TYPE("a{sa{sv}}")));
-
-    g_variant_iter_init(&iter_ifaces, ifaces);
-    while (g_variant_iter_next(&iter_ifaces, "{&s@a{sv}}", &interface_name, &changed_properties)) {
-        _nm_unused gs_unref_variant GVariant *changed_properties_free = changed_properties;
-
-        if (_dbus_handle_properties_changed(self,
-                                            log_context,
-                                            object_path,
-                                            interface_name,
-                                            TRUE,
-                                            changed_properties,
-                                            &dbobj))
-            changed = TRUE;
-    }
-
-    return changed;
-}
-
-static gboolean
-_dbus_handle_interface_removed(NMClient *         self,
-                               const char *       log_context,
-                               const char *       object_path,
-                               NMLDBusObject **   inout_dbobj,
-                               const char *const *removed_interfaces)
-{
-    gboolean       changed = FALSE;
-    NMLDBusObject *dbobj;
-    gsize          i;
-
-    if (inout_dbobj && *inout_dbobj) {
-        dbobj = *inout_dbobj;
-        nm_assert(dbobj == _dbobjs_dbobj_get_s(self, object_path));
-    } else {
-        dbobj = _dbobjs_dbobj_get_s(self, object_path);
-        if (!dbobj) {
-            NML_NMCLIENT_LOG_E(self,
-                               "%s: [%s]: receive interface removed event for non existing object",
-                               log_context,
-                               object_path);
-            return FALSE;
-        }
-        NM_SET_OUT(inout_dbobj, dbobj);
-    }
-
-    for (i = 0; removed_interfaces[i]; i++) {
-        NMLDBusObjIfaceData *db_iface_data;
-        const char *         interface_name = removed_interfaces[i];
-
-        db_iface_data = nml_dbus_object_iface_data_get(dbobj, interface_name, FALSE);
-        if (!db_iface_data) {
-            NML_NMCLIENT_LOG_E(
-                self,
-                "%s: [%s] receive interface remove event for unexpected interface %s",
-                log_context,
-                object_path,
-                interface_name);
-            continue;
-        }
-
-        NML_NMCLIENT_LOG_T(self,
-                           "%s: [%s] receive interface remove event for interface %s",
-                           log_context,
-                           object_path,
-                           interface_name);
-        db_iface_data->iface_removed = TRUE;
-        changed                      = TRUE;
-    }
-
-    if (changed)
-        nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS);
-
-    return changed;
-}
-
-static void
-_dbus_managed_objects_changed_cb(GDBusConnection *connection,
-                                 const char *     sender_name,
-                                 const char *     arg_object_path,
-                                 const char *     interface_name,
-                                 const char *     signal_name,
-                                 GVariant *       parameters,
-                                 gpointer         user_data)
-{
-    NMClient *       self = user_data;
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    const char *     log_context;
-    gboolean         changed;
-
-    nm_assert(nm_streq0(interface_name, DBUS_INTERFACE_OBJECT_MANAGER));
-
-    if (priv->get_managed_objects_cancellable) {
-        /* we still wait for the initial GetManagedObjects(). Ignore the event. */
-        return;
-    }
-
-    if (nm_streq(signal_name, "InterfacesAdded")) {
-        gs_unref_variant GVariant *interfaces_and_properties = NULL;
-        const char *               object_path;
-
-        if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(oa{sa{sv}})")))
-            return;
-
-        g_variant_get(parameters, "(&o@a{sa{sv}})", &object_path, &interfaces_and_properties);
-
-        log_context = "interfaces-added";
-        changed =
-            _dbus_handle_interface_added(self, log_context, object_path, interfaces_and_properties);
-        goto out;
-    }
-
-    if (nm_streq(signal_name, "InterfacesRemoved")) {
-        gs_free const char **interfaces = NULL;
-        const char *         object_path;
-
-        if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(oas)")))
-            return;
-
-        g_variant_get(parameters, "(&o^a&s)", &object_path, &interfaces);
-
-        log_context = "interfaces-removed";
-        changed = _dbus_handle_interface_removed(self, log_context, object_path, NULL, interfaces);
-        goto out;
-    }
-
-    return;
-
-out:
-    if (changed)
-        _dbus_handle_changes(self, log_context, TRUE);
-}
-
-static void
-_dbus_properties_changed_cb(GDBusConnection *connection,
-                            const char *     sender_name,
-                            const char *     object_path,
-                            const char *     signal_interface_name,
-                            const char *     signal_name,
-                            GVariant *       parameters,
-                            gpointer         user_data)
-{
-    NMClient *       self = user_data;
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    const char *     interface_name;
-    gs_unref_variant GVariant *changed_properties     = NULL;
-    gs_free const char **      invalidated_properties = NULL;
-    const char *               log_context            = "properties-changed";
-
-    if (priv->get_managed_objects_cancellable) {
-        /* we still wait for the initial GetManagedObjects(). Ignore the event. */
-        return;
-    }
-
-    if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv}as)")))
-        return;
-
-    g_variant_get(parameters,
-                  "(&s@a{sv}^a&s)",
-                  &interface_name,
-                  &changed_properties,
-                  &invalidated_properties);
-
-    if (invalidated_properties && invalidated_properties[0]) {
-        NML_NMCLIENT_LOG_W(self,
-                           "%s: [%s] ignore invalidated properties on interface %s",
-                           log_context,
-                           object_path,
-                           interface_name);
-    }
-
-    if (_dbus_handle_properties_changed(self,
-                                        log_context,
-                                        object_path,
-                                        interface_name,
-                                        FALSE,
-                                        changed_properties,
-                                        NULL))
-        _dbus_handle_changes(self, log_context, TRUE);
-}
-
-static void
-_dbus_get_managed_objects_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMClient *       self;
-    NMClientPrivate *priv;
-    gs_unref_variant GVariant *ret                = NULL;
-    gs_unref_variant GVariant *managed_objects    = NULL;
-    gs_free_error GError *error                   = NULL;
-    gs_unref_object GObject *context_busy_watcher = NULL;
-
-    nm_utils_user_data_unpack(user_data, &self, &context_busy_watcher);
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
-
-    nm_assert((!!ret) != (!!error));
-
-    if (!ret && nm_utils_error_is_cancelled(error))
-        return;
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    if (ret) {
-        nm_assert(g_variant_is_of_type(ret, G_VARIANT_TYPE("(a{oa{sa{sv}}})")));
-        managed_objects = g_variant_get_child_value(ret, 0);
-    }
-
-    g_clear_object(&priv->get_managed_objects_cancellable);
-
-    if (!managed_objects) {
-        NML_NMCLIENT_LOG_D(self, "GetManagedObjects() call failed: %s", error->message);
-        /* hm, now that's odd. Maybe NetworkManager just quit and we are about to get
-         * a name-owner changed signal soon. Treat this as if we got no managed objects at all. */
-    } else
-        NML_NMCLIENT_LOG_D(self, "GetManagedObjects() completed");
-
-    if (managed_objects) {
-        GVariantIter iter;
-        const char * object_path;
-        GVariant *   ifaces_tmp;
-
-        g_variant_iter_init(&iter, managed_objects);
-        while (g_variant_iter_next(&iter, "{&o@a{sa{sv}}}", &object_path, &ifaces_tmp)) {
-            gs_unref_variant GVariant *ifaces = ifaces_tmp;
-
-            _dbus_handle_interface_added(self, "get-managed-objects", object_path, ifaces);
-        }
-    }
-
-    /* always call _dbus_handle_changes(), even if nothing changed. We need this to complete
-     * initialization. */
-    _dbus_handle_changes(self, "get-managed-objects", TRUE);
-}
-
-/*****************************************************************************/
-
-static void
-_nm_client_get_settings_call_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMRemoteConnection *remote_connection;
-    NMClient *          self;
-    gs_unref_variant GVariant *ret      = NULL;
-    gs_free_error GError *error         = NULL;
-    gs_unref_variant GVariant *settings = NULL;
-    NMLDBusObject *            dbobj;
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
-    if (!ret && nm_utils_error_is_cancelled(error))
-        return;
-
-    remote_connection = user_data;
-
-    self = _nm_object_get_client(remote_connection);
-
-    dbobj = _nm_object_get_dbobj(remote_connection);
-
-    _ASSERT_dbobj(dbobj, self);
-
-    if (!ret) {
-        NML_NMCLIENT_LOG_T(self,
-                           "[%s] GetSettings() completed with error: %s",
-                           dbobj->dbus_path->str,
-                           error->message);
-    } else {
-        NML_NMCLIENT_LOG_T(self,
-                           "[%s] GetSettings() completed with success",
-                           dbobj->dbus_path->str);
-        g_variant_get(ret, "(@a{sa{sv}})", &settings);
-    }
-
-    _nm_remote_settings_get_settings_commit(remote_connection, settings);
-
-    _dbus_handle_changes_commit(self, TRUE);
-}
-
-void
-_nm_client_get_settings_call(NMClient *self, NMLDBusObject *dbobj)
-{
-    GCancellable *cancellable;
-
-    cancellable = _nm_remote_settings_get_settings_prepare(NM_REMOTE_CONNECTION(dbobj->nmobj));
-
-    _nm_client_dbus_call_simple(self,
-                                cancellable,
-                                dbobj->dbus_path->str,
-                                NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
-                                "GetSettings",
-                                g_variant_new("()"),
-                                G_VARIANT_TYPE("(a{sa{sv}})"),
-                                G_DBUS_CALL_FLAGS_NONE,
-                                NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                _nm_client_get_settings_call_cb,
-                                dbobj->nmobj);
-}
-
-static void
-_dbus_settings_updated_cb(GDBusConnection *connection,
-                          const char *     sender_name,
-                          const char *     object_path,
-                          const char *     signal_interface_name,
-                          const char *     signal_name,
-                          GVariant *       parameters,
-                          gpointer         user_data)
-{
-    NMClient *       self        = user_data;
-    NMClientPrivate *priv        = NM_CLIENT_GET_PRIVATE(self);
-    const char *     log_context = "settings-updated";
-    NMLDBusObject *  dbobj;
-
-    if (priv->get_managed_objects_cancellable) {
-        /* we still wait for the initial GetManagedObjects(). Ignore the event. */
-        return;
-    }
-
-    if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("()")))
-        return;
-
-    dbobj = _dbobjs_dbobj_get_s(self, object_path);
-
-    if (!dbobj || !NM_IS_REMOTE_CONNECTION(dbobj->nmobj)) {
-        NML_NMCLIENT_LOG_W(self,
-                           "%s: [%s] ignore Updated signal for non-existing setting",
-                           log_context,
-                           object_path);
-        return;
-    }
-
-    NML_NMCLIENT_LOG_T(self, "%s: [%s] Updated signal received", log_context, object_path);
-
-    _nm_client_get_settings_call(self, dbobj);
-}
-
-/*****************************************************************************/
-
-static void
-_dbus_nm_connection_active_state_changed_cb(GDBusConnection *connection,
-                                            const char *     sender_name,
-                                            const char *     object_path,
-                                            const char *     signal_interface_name,
-                                            const char *     signal_name,
-                                            GVariant *       parameters,
-                                            gpointer         user_data)
-{
-    NMClient *       self        = user_data;
-    NMClientPrivate *priv        = NM_CLIENT_GET_PRIVATE(self);
-    const char *     log_context = "active-connection-state-changed";
-    NMLDBusObject *  dbobj;
-    guint32          state;
-    guint32          reason;
-
-    if (priv->get_managed_objects_cancellable) {
-        /* we still wait for the initial GetManagedObjects(). Ignore the event. */
-        return;
-    }
-
-    if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(uu)"))) {
-        NML_NMCLIENT_LOG_E(self,
-                           "%s: [%s] ignore StateChanged signal with unexpected signature",
-                           log_context,
-                           object_path);
-        return;
-    }
-
-    dbobj = _dbobjs_dbobj_get_s(self, object_path);
-
-    if (!dbobj || !NM_IS_ACTIVE_CONNECTION(dbobj->nmobj)) {
-        NML_NMCLIENT_LOG_E(self,
-                           "%s: [%s] ignore StateChanged signal for non-existing active connection",
-                           log_context,
-                           object_path);
-        return;
-    }
-
-    g_variant_get(parameters, "(uu)", &state, &reason);
-
-    NML_NMCLIENT_LOG_T(self, "%s: [%s] StateChanged signal received", log_context, object_path);
-
-    _nm_active_connection_state_changed_commit(NM_ACTIVE_CONNECTION(dbobj->nmobj), state, reason);
-
-    _dbus_handle_changes_commit(self, TRUE);
-}
-
-/*****************************************************************************/
-
-static void
-_dbus_nm_vpn_connection_state_changed_cb(GDBusConnection *connection,
-                                         const char *     sender_name,
-                                         const char *     object_path,
-                                         const char *     signal_interface_name,
-                                         const char *     signal_name,
-                                         GVariant *       parameters,
-                                         gpointer         user_data)
-{
-    NMClient *       self        = user_data;
-    NMClientPrivate *priv        = NM_CLIENT_GET_PRIVATE(self);
-    const char *     log_context = "vpn-connection-state-changed";
-    NMLDBusObject *  dbobj;
-    guint32          state;
-    guint32          reason;
-
-    if (priv->get_managed_objects_cancellable) {
-        /* we still wait for the initial GetManagedObjects(). Ignore the event. */
-        return;
-    }
-
-    if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(uu)"))) {
-        NML_NMCLIENT_LOG_E(self,
-                           "%s: [%s] ignore VpnStateChanged signal with unexpected signature",
-                           log_context,
-                           object_path);
-        return;
-    }
-
-    dbobj = _dbobjs_dbobj_get_s(self, object_path);
-
-    if (!dbobj || !NM_IS_VPN_CONNECTION(dbobj->nmobj)) {
-        NML_NMCLIENT_LOG_E(self,
-                           "%s: [%s] ignore VpnStateChanged signal for non-existing vpn connection",
-                           log_context,
-                           object_path);
-        return;
-    }
-
-    g_variant_get(parameters, "(uu)", &state, &reason);
-
-    NML_NMCLIENT_LOG_T(self, "%s: [%s] VpnStateChanged signal received", log_context, object_path);
-
-    _nm_vpn_connection_state_changed_commit(NM_VPN_CONNECTION(dbobj->nmobj), state, reason);
-
-    _dbus_handle_changes_commit(self, TRUE);
-}
-
-/*****************************************************************************/
-
-static void
-_emit_permissions_changed(NMClient *self, const guint8 *old_permissions, const guint8 *permissions)
-{
-    int i;
-
-    if (self->obj_base.is_disposing)
-        return;
-
-    if (old_permissions == permissions)
-        return;
-
-    for (i = 0; i < (int) G_N_ELEMENTS(nm_auth_permission_sorted); i++) {
-        NMClientPermission       perm            = nm_auth_permission_sorted[i];
-        NMClientPermissionResult perm_result     = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
-        NMClientPermissionResult perm_result_old = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
-
-        if (permissions)
-            perm_result = permissions[perm - 1];
-        if (old_permissions)
-            perm_result_old = old_permissions[perm - 1];
-
-        if (perm_result == perm_result_old)
-            continue;
-
-        g_signal_emit(self, signals[PERMISSION_CHANGED], 0, (guint) perm, (guint) perm_result);
-    }
-}
-
-static void
-_dbus_check_permissions_start_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
-    NMClient *                             self;
-    NMClientPrivate *                      priv;
-    gs_unref_variant GVariant *ret                        = NULL;
-    nm_auto_free_variant_iter GVariantIter *v_permissions = NULL;
-    gs_free guint8 *old_permissions                       = NULL;
-    gs_free_error GError *error                           = NULL;
-    const char *          pkey;
-    const char *          pvalue;
-    int                   i;
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
-    if (!ret && nm_utils_error_is_cancelled(error))
-        return;
-
-    self = user_data;
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    g_clear_object(&priv->permissions_cancellable);
-
-    old_permissions = g_steal_pointer(&priv->permissions);
-
-    if (!ret) {
-        /* when the call completes, we always pretend success. Even a failure means
-         * that we fetched the permissions, however they are all unknown. */
-        NML_NMCLIENT_LOG_T(self, "GetPermissions call failed: %s", error->message);
-        goto out;
-    }
-
-    NML_NMCLIENT_LOG_T(self, "GetPermissions call finished with success");
-
-    g_variant_get(ret, "(a{ss})", &v_permissions);
-    while (g_variant_iter_next(v_permissions, "{&s&s}", &pkey, &pvalue)) {
-        NMClientPermission       perm;
-        NMClientPermissionResult perm_result;
-
-        perm = nm_auth_permission_from_string(pkey);
-        if (perm == NM_CLIENT_PERMISSION_NONE)
-            continue;
-
-        perm_result = nm_client_permission_result_from_string(pvalue);
-
-        if (!priv->permissions) {
-            if (perm_result == NM_CLIENT_PERMISSION_RESULT_UNKNOWN)
-                continue;
-            priv->permissions = g_new(guint8, G_N_ELEMENTS(nm_auth_permission_sorted));
-            for (i = 0; i < (int) G_N_ELEMENTS(nm_auth_permission_sorted); i++)
-                priv->permissions[i] = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
-        }
-        priv->permissions[perm - 1] = perm_result;
-    }
-
-out:
-    priv->permissions_state = NM_TERNARY_TRUE;
-
-    dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context);
-    _emit_permissions_changed(self, old_permissions, priv->permissions);
-    _notify(self, PROP_PERMISSIONS_STATE);
-}
-
-static void
-_dbus_check_permissions_start(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    gboolean         fetch;
-
-    fetch = !NM_FLAGS_HAS((NMClientInstanceFlags) priv->instance_flags,
-                          NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS);
-
-    nm_clear_g_cancellable(&priv->permissions_cancellable);
-
-    if (fetch) {
-        NML_NMCLIENT_LOG_T(self, "GetPermissions() call started...");
-
-        priv->permissions_cancellable = g_cancellable_new();
-        _nm_client_dbus_call_simple(self,
-                                    priv->permissions_cancellable,
-                                    NM_DBUS_PATH,
-                                    NM_DBUS_INTERFACE,
-                                    "GetPermissions",
-                                    g_variant_new("()"),
-                                    G_VARIANT_TYPE("(a{ss})"),
-                                    G_DBUS_CALL_FLAGS_NONE,
-                                    NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                    _dbus_check_permissions_start_cb,
-                                    self);
-    }
-}
-
-static void
-_dbus_nm_check_permissions_cb(GDBusConnection *connection,
-                              const char *     sender_name,
-                              const char *     object_path,
-                              const char *     signal_interface_name,
-                              const char *     signal_name,
-                              GVariant *       parameters,
-                              gpointer         user_data)
-{
-    NMClient *       self = user_data;
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("()"))) {
-        NML_NMCLIENT_LOG_E(self,
-                           "ignore CheckPermissions signal with unexpected signature %s",
-                           g_variant_get_type_string(parameters));
-        return;
-    }
-
-    _dbus_check_permissions_start(self);
-
-    if (priv->permissions_state == NM_TERNARY_TRUE)
-        priv->permissions_state = NM_TERNARY_FALSE;
-    _notify(self, PROP_PERMISSIONS_STATE);
-}
-
-/*****************************************************************************/
-
-static void
-_property_ao_notify_changed_connections_cb(NMLDBusPropertyAO *pr_ao,
-                                           NMClient *         self,
-                                           NMObject *         nmobj,
-                                           gboolean           is_added /* or else removed */)
-{
-    _nm_client_notify_event_queue_emit_obj_signal(self,
-                                                  G_OBJECT(self),
-                                                  nmobj,
-                                                  is_added,
-                                                  5,
-                                                  is_added ? signals[CONNECTION_ADDED]
-                                                           : signals[CONNECTION_REMOVED]);
-}
-
-static void
-_property_ao_notify_changed_all_devices_cb(NMLDBusPropertyAO *pr_ao,
-                                           NMClient *         self,
-                                           NMObject *         nmobj,
-                                           gboolean           is_added /* or else removed */)
-{
-    _nm_client_notify_event_queue_emit_obj_signal(self,
-                                                  G_OBJECT(self),
-                                                  nmobj,
-                                                  is_added,
-                                                  6,
-                                                  is_added ? signals[ANY_DEVICE_ADDED]
-                                                           : signals[ANY_DEVICE_REMOVED]);
-}
-
-static void
-_property_ao_notify_changed_devices_cb(NMLDBusPropertyAO *pr_ao,
-                                       NMClient *         self,
-                                       NMObject *         nmobj,
-                                       gboolean           is_added /* or else removed */)
-{
-    _nm_client_notify_event_queue_emit_obj_signal(self,
-                                                  G_OBJECT(self),
-                                                  nmobj,
-                                                  is_added,
-                                                  7,
-                                                  is_added ? signals[DEVICE_ADDED]
-                                                           : signals[DEVICE_REMOVED]);
-}
-
-static void
-_property_ao_notify_changed_active_connections_cb(NMLDBusPropertyAO *pr_ao,
-                                                  NMClient *         self,
-                                                  NMObject *         nmobj,
-                                                  gboolean           is_added /* or else removed */)
-{
-    _nm_client_notify_event_queue_emit_obj_signal(self,
-                                                  G_OBJECT(self),
-                                                  nmobj,
-                                                  is_added,
-                                                  8,
-                                                  is_added ? signals[ACTIVE_CONNECTION_ADDED]
-                                                           : signals[ACTIVE_CONNECTION_REMOVED]);
-}
-
-/*****************************************************************************/
-
-typedef struct {
-    NMLDBusObjWatcherWithPtr *obj_watcher;
-    const char *              op_name;
-    NMLDBusObject *           dbobj;
-    GTask *                   task;
-    GVariant *                extra_results;
-    gpointer                  result;
-    GType                     gtype;
-    gulong                    cancellable_id;
-} RequestWaitData;
-
-static void
-_request_wait_data_free(RequestWaitData *request_data)
-{
-    nm_assert(!request_data->obj_watcher);
-    nm_assert(request_data->cancellable_id == 0);
-    nm_assert(!request_data->task || G_IS_TASK(request_data->task));
-
-    nm_g_object_unref(request_data->task);
-    nm_g_object_unref(request_data->result);
-    nm_g_variant_unref(request_data->extra_results);
-    if (request_data->dbobj)
-        nml_dbus_object_unref(request_data->dbobj);
-    nm_g_slice_free(request_data);
-}
-
-static void
-_request_wait_task_return(RequestWaitData *request_data)
-{
-    gs_unref_object GTask *task = NULL;
-
-    nm_assert(request_data);
-    nm_assert(G_IS_TASK(request_data->task));
-    nm_assert(request_data->dbobj);
-    nm_assert(NM_IS_OBJECT(request_data->dbobj->nmobj));
-    nm_assert(!request_data->result);
-
-    task = g_steal_pointer(&request_data->task);
-
-    request_data->result = g_object_ref(request_data->dbobj->nmobj);
-    nm_clear_g_signal_handler(g_task_get_cancellable(task), &request_data->cancellable_id);
-    nm_clear_pointer(&request_data->dbobj, nml_dbus_object_unref);
-    g_task_return_pointer(task, request_data, (GDestroyNotify) _request_wait_data_free);
-}
-
-static gboolean
-_request_wait_complete(NMClient *self, RequestWaitData *request_data, gboolean force_complete)
-{
-    NMLDBusObject *dbobj;
-
-    nm_assert(request_data);
-    nm_assert(!request_data->result);
-    nm_assert(!request_data->obj_watcher);
-    nm_assert(request_data->dbobj);
-
-    dbobj = request_data->dbobj;
-
-    if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY) {
-        NML_NMCLIENT_LOG_D(self,
-                           "%s() succeeded with %s",
-                           request_data->op_name,
-                           dbobj->dbus_path->str);
-        nm_assert(G_TYPE_CHECK_INSTANCE_TYPE(dbobj->nmobj, request_data->gtype));
-        _request_wait_task_return(request_data);
-        return TRUE;
-    }
-
-    if (force_complete || dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) {
-        if (force_complete)
-            NML_NMCLIENT_LOG_D(self,
-                               "%s() succeeded with %s but object is in an unsuitable state",
-                               request_data->op_name,
-                               dbobj->dbus_path->str);
-        else
-            NML_NMCLIENT_LOG_W(self,
-                               "%s() succeeded with %s but object is in an unsuitable state",
-                               request_data->op_name,
-                               dbobj->dbus_path->str);
-
-        g_task_return_error(
-            request_data->task,
-            g_error_new(NM_CLIENT_ERROR,
-                        NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
-                        _("request succeeded with %s but object is in an unsuitable state"),
-                        dbobj->dbus_path->str));
-        _request_wait_data_free(request_data);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-static void
-_request_wait_complete_cb(NMClient *self, NMClientNotifyEventWithPtr *notify_event)
-{
-    _request_wait_complete(self, notify_event->user_data, TRUE);
-}
-
-static void
-_request_wait_obj_watcher_cb(NMClient *self, gpointer obj_watcher_base)
-{
-    NMLDBusObjWatcherWithPtr *obj_watcher  = obj_watcher_base;
-    RequestWaitData *         request_data = obj_watcher->user_data;
-    NMLDBusObject *           dbobj;
-
-    dbobj = request_data->dbobj;
-
-    if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY)
-        return;
-
-    nm_assert(NM_IN_SET((NMLDBusObjState) dbobj->obj_state,
-                        NML_DBUS_OBJ_STATE_WATCHED_ONLY,
-                        NML_DBUS_OBJ_STATE_ON_DBUS,
-                        NML_DBUS_OBJ_STATE_WITH_NMOBJ_READY));
-
-    _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&request_data->obj_watcher));
-
-    nm_clear_g_signal_handler(g_task_get_cancellable(request_data->task),
-                              &request_data->cancellable_id);
-
-    _nm_client_notify_event_queue_with_ptr(self,
-                                           NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER + 30,
-                                           _request_wait_complete_cb,
-                                           request_data);
-}
-
-static void
-_request_wait_cancelled_cb(GCancellable *cancellable, gpointer user_data)
-{
-    RequestWaitData *request_data = user_data;
-    NMClient *       self;
-    GError *         error = NULL;
-
-    nm_assert(cancellable == g_task_get_cancellable(request_data->task));
-
-    nm_utils_error_set_cancelled(&error, FALSE, NULL);
-
-    self = g_task_get_source_object(request_data->task);
-
-    nm_clear_g_signal_handler(cancellable, &request_data->cancellable_id);
-
-    _dbobjs_obj_watcher_unregister(self, g_steal_pointer(&request_data->obj_watcher));
-
-    g_task_return_error(request_data->task, error);
-
-    _request_wait_data_free(request_data);
-}
-
-static void
-_request_wait_start(GTask *     task_take,
-                    const char *op_name,
-                    GType       gtype,
-                    const char *dbus_path,
-                    GVariant *  extra_results_take)
-{
-    NMClient *      self;
-    gs_unref_object GTask *task = g_steal_pointer(&task_take);
-    RequestWaitData *      request_data;
-    GCancellable *         cancellable;
-    NMLDBusObject *        dbobj;
-
-    nm_assert(G_IS_TASK(task));
-
-    self = g_task_get_source_object(task);
-
-    dbobj = _dbobjs_get_nmobj(self, dbus_path, gtype);
-
-    if (!dbobj) {
-        NML_NMCLIENT_LOG_E(self,
-                           "%s() succeeded with %s but object does not exist",
-                           op_name,
-                           dbus_path);
-        g_task_return_error(task,
-                            g_error_new(NM_CLIENT_ERROR,
-                                        NM_CLIENT_ERROR_FAILED,
-                                        _("operation succeeded but object %s does not exist"),
-                                        dbus_path));
-        return;
-    }
-
-    request_data  = g_slice_new(RequestWaitData);
-    *request_data = (RequestWaitData){
-        .task           = g_steal_pointer(&task),
-        .op_name        = op_name,
-        .gtype          = gtype,
-        .dbobj          = nml_dbus_object_ref(dbobj),
-        .obj_watcher    = NULL,
-        .extra_results  = g_steal_pointer(&extra_results_take),
-        .result         = NULL,
-        .cancellable_id = 0,
-    };
-
-    if (_request_wait_complete(self, request_data, FALSE))
-        return;
-
-    NML_NMCLIENT_LOG_T(self,
-                       "%s() succeeded with %s. Wait for object to become ready",
-                       op_name,
-                       dbobj->dbus_path->str);
-
-    request_data->obj_watcher            = _dbobjs_obj_watcher_register_o(self,
-                                                               dbobj,
-                                                               _request_wait_obj_watcher_cb,
-                                                               sizeof(NMLDBusObjWatcherWithPtr));
-    request_data->obj_watcher->user_data = request_data;
-
-    cancellable = g_task_get_cancellable(request_data->task);
-    if (cancellable) {
-        gulong id;
-
-        id = g_cancellable_connect(cancellable,
-                                   G_CALLBACK(_request_wait_cancelled_cb),
-                                   request_data,
-                                   NULL);
-        if (id == 0) {
-            /* the callback was invoked synchronously, which destroyed @request_data.
-             * We must not touch @info anymore. */
-        } else
-            request_data->cancellable_id = id;
-    }
-}
-
-static gpointer
-_request_wait_finish(NMClient *    client,
-                     GAsyncResult *result,
-                     gpointer      source_tag,
-                     GVariant **   out_result,
-                     GError **     error)
-{
-    RequestWaitData *request_data = NULL;
-    gpointer         r;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, source_tag), NULL);
-
-    request_data = g_task_propagate_pointer(G_TASK(result), error);
-    if (!request_data) {
-        NM_SET_OUT(out_result, NULL);
-        return NULL;
-    }
-
-    nm_assert(NM_IS_OBJECT(request_data->result));
-
-    NM_SET_OUT(out_result, g_steal_pointer(&request_data->extra_results));
-    r = g_steal_pointer(&request_data->result);
-
-    nm_assert(NM_IS_OBJECT(r));
-
-    _request_wait_data_free(request_data);
-    return r;
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_get_instance_flags:
- * @self: the #NMClient instance.
- *
- * Returns: the #NMClientInstanceFlags flags.
- *
- * Since: 1.24
- */
-NMClientInstanceFlags
-nm_client_get_instance_flags(NMClient *self)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(self), NM_CLIENT_INSTANCE_FLAGS_NONE);
-
-    return NM_CLIENT_GET_PRIVATE(self)->instance_flags;
-}
-
-/**
- * nm_client_get_dbus_connection:
- * @client: a #NMClient
- *
- * Gets the %GDBusConnection of the instance. This can be either passed when
- * constructing the instance (as "dbus-connection" property), or it will be
- * automatically initialized during async/sync init.
- *
- * Returns: (transfer none): the D-Bus connection of the client, or %NULL if none is set.
- *
- * Since: 1.22
- **/
-GDBusConnection *
-nm_client_get_dbus_connection(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->dbus_connection;
-}
-
-/**
- * nm_client_get_dbus_name_owner:
- * @client: a #NMClient
- *
- * Returns: (transfer none): the current name owner of the D-Bus service of NetworkManager.
- *
- * Since: 1.22
- **/
-const char *
-nm_client_get_dbus_name_owner(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->name_owner;
-}
-
-/**
- * nm_client_get_version:
- * @client: a #NMClient
- *
- * Gets NetworkManager version.
- *
- * Returns: string with the version (or %NULL if NetworkManager is not running)
- **/
-const char *
-nm_client_get_version(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.version;
-}
-
-/**
- * nm_client_get_state:
- * @client: a #NMClient
- *
- * Gets the current daemon state.
- *
- * Returns: the current %NMState
- **/
-NMState
-nm_client_get_state(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NM_STATE_UNKNOWN);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.state;
-}
-
-/**
- * nm_client_get_startup:
- * @client: a #NMClient
- *
- * Tests whether the daemon is still in the process of activating
- * connections at startup.
- *
- * Returns: whether the daemon is still starting up
- **/
-gboolean
-nm_client_get_startup(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.startup;
-}
-
-static void
-_set_nm_running(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    gboolean         nm_running;
-
-    nm_running = priv->name_owner && !priv->get_managed_objects_cancellable;
-    if (priv->nm_running != nm_running) {
-        priv->nm_running = nm_running;
-        _notify(self, PROP_NM_RUNNING);
-    }
-}
-
-/**
- * nm_client_get_nm_running:
- * @client: a #NMClient
- *
- * Determines whether the daemon is running.
- *
- * Returns: %TRUE if the daemon is running
- **/
-gboolean
-nm_client_get_nm_running(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm_running;
-}
-
-/**
- * nm_client_get_object_by_path:
- * @client: the #NMClient instance
- * @dbus_path: the D-Bus path of the object to look up
- *
- * Returns: (transfer none): the #NMObject instance that is
- *   cached under @dbus_path, or %NULL if no such object exists.
- *
- * Since: 1.24
- */
-NMObject *
-nm_client_get_object_by_path(NMClient *client, const char *dbus_path)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(dbus_path, NULL);
-
-    return _dbobjs_get_nmobj_unpack_visible(client, dbus_path, G_TYPE_NONE);
-}
-
-/**
- * nm_client_get_metered:
- * @client: a #NMClient
- *
- * Returns: whether the default route is metered.
- *
- * Since: 1.22
- */
-NMMetered
-nm_client_get_metered(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NM_METERED_UNKNOWN);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.metered;
-}
-
-/**
- * nm_client_networking_get_enabled:
- * @client: a #NMClient
- *
- * Whether networking is enabled or disabled.
- *
- * Returns: %TRUE if networking is enabled, %FALSE if networking is disabled
- **/
-gboolean
-nm_client_networking_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.networking_enabled;
-}
-
-/**
- * nm_client_networking_set_enabled:
- * @client: a #NMClient
- * @enabled: %TRUE to set networking enabled, %FALSE to set networking disabled
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Enables or disables networking.  When networking is disabled, all controlled
- * interfaces are disconnected and deactivated.  When networking is enabled,
- * all controlled interfaces are available for activation.
- *
- * Returns: %TRUE on success, %FALSE otherwise
- *
- * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH,
- * %NM_DBUS_INTERFACE to call "Enable" with "(b)" arguments and no return value.
- **/
-gboolean
-nm_client_networking_set_enabled(NMClient *client, gboolean enable, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return _nm_client_dbus_call_sync_void(client,
-                                          NULL,
-                                          NM_DBUS_PATH,
-                                          NM_DBUS_INTERFACE,
-                                          "Enable",
-                                          g_variant_new("(b)", enable),
-                                          G_DBUS_CALL_FLAGS_NONE,
-                                          NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                          TRUE,
-                                          error);
-}
-
-/**
- * nm_client_wireless_get_enabled:
- * @client: a #NMClient
- *
- * Determines whether the wireless is enabled.
- *
- * Returns: %TRUE if wireless is enabled
- **/
-gboolean
-nm_client_wireless_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.wireless_enabled;
-}
-
-/**
- * nm_client_wireless_set_enabled:
- * @client: a #NMClient
- * @enabled: %TRUE to enable wireless
- *
- * Enables or disables wireless devices.
- *
- * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH,
- * %NM_DBUS_INTERFACE to set "WirelessEnabled" property to a "(b)" value.
- */
-void
-nm_client_wireless_set_enabled(NMClient *client, gboolean enabled)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    _nm_client_set_property_sync_legacy(client,
-                                        NM_DBUS_PATH,
-                                        NM_DBUS_INTERFACE,
-                                        "WirelessEnabled",
-                                        "b",
-                                        enabled);
-}
-
-/**
- * nm_client_wireless_hardware_get_enabled:
- * @client: a #NMClient
- *
- * Determines whether the wireless hardware is enabled.
- *
- * Returns: %TRUE if the wireless hardware is enabled
- **/
-gboolean
-nm_client_wireless_hardware_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.wireless_hardware_enabled;
-}
-
-/**
- * nm_client_wwan_get_enabled:
- * @client: a #NMClient
- *
- * Determines whether WWAN is enabled.
- *
- * Returns: %TRUE if WWAN is enabled
- **/
-gboolean
-nm_client_wwan_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.wwan_enabled;
-}
-
-/**
- * nm_client_wwan_set_enabled:
- * @client: a #NMClient
- * @enabled: %TRUE to enable WWAN
- *
- * Enables or disables WWAN devices.
- *
- * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH,
- * %NM_DBUS_INTERFACE to set "WwanEnabled" property to a "(b)" value.
- **/
-void
-nm_client_wwan_set_enabled(NMClient *client, gboolean enabled)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    _nm_client_set_property_sync_legacy(client,
-                                        NM_DBUS_PATH,
-                                        NM_DBUS_INTERFACE,
-                                        "WwanEnabled",
-                                        "b",
-                                        enabled);
-}
-
-/**
- * nm_client_wwan_hardware_get_enabled:
- * @client: a #NMClient
- *
- * Determines whether the WWAN hardware is enabled.
- *
- * Returns: %TRUE if the WWAN hardware is enabled
- **/
-gboolean
-nm_client_wwan_hardware_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.wwan_hardware_enabled;
-}
-
-/**
- * nm_client_wimax_get_enabled:
- * @client: a #NMClient
- *
- * Determines whether WiMAX is enabled.
- *
- * Returns: %TRUE if WiMAX is enabled
- *
- * Deprecated: 1.22: This function always returns FALSE because WiMax is no longer supported.
- **/
-gboolean
-nm_client_wimax_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return FALSE;
-}
-
-/**
- * nm_client_wimax_set_enabled:
- * @client: a #NMClient
- * @enabled: %TRUE to enable WiMAX
- *
- * Enables or disables WiMAX devices.
- *
- * Deprecated: 1.22: This function does nothing because WiMax is no longer supported.
- **/
-void
-nm_client_wimax_set_enabled(NMClient *client, gboolean enabled)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-}
-
-/**
- * nm_client_wimax_hardware_get_enabled:
- * @client: a #NMClient
- *
- * Determines whether the WiMAX hardware is enabled.
- *
- * Returns: %TRUE if the WiMAX hardware is enabled
- *
- * Deprecated: 1.22: This function always returns FALSE because WiMax is no longer supported.
- **/
-gboolean
-nm_client_wimax_hardware_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return FALSE;
-}
-
-/**
- * nm_client_connectivity_check_get_available:
- * @client: a #NMClient
- *
- * Determine whether connectivity checking is available.  This
- * requires that the URI of a connectivity service has been set in the
- * configuration file.
- *
- * Returns: %TRUE if connectivity checking is available.
- *
- * Since: 1.10
- */
-gboolean
-nm_client_connectivity_check_get_available(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_available;
-}
-
-/**
- * nm_client_connectivity_check_get_enabled:
- * @client: a #NMClient
- *
- * Determine whether connectivity checking is enabled.
- *
- * Returns: %TRUE if connectivity checking is enabled.
- *
- * Since: 1.10
- */
-gboolean
-nm_client_connectivity_check_get_enabled(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_enabled;
-}
-
-/**
- * nm_client_connectivity_check_set_enabled:
- * @client: a #NMClient
- * @enabled: %TRUE to enable connectivity checking
- *
- * Enable or disable connectivity checking.  Note that if a
- * connectivity checking URI has not been configured, this will not
- * have any effect.
- *
- * Since: 1.10
- *
- * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH,
- * %NM_DBUS_INTERFACE to set "ConnectivityCheckEnabled" property to a "(b)" value.
- */
-void
-nm_client_connectivity_check_set_enabled(NMClient *client, gboolean enabled)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    _nm_client_set_property_sync_legacy(client,
-                                        NM_DBUS_PATH,
-                                        NM_DBUS_INTERFACE,
-                                        "ConnectivityCheckEnabled",
-                                        "b",
-                                        enabled);
-}
-
-/**
- * nm_client_connectivity_check_get_uri:
- * @client: a #NMClient
- *
- * Get the URI that will be queried to determine if there is internet
- * connectivity.
- *
- * Returns: (transfer none): the connectivity URI in use
- *
- * Since: 1.20
- */
-const char *
-nm_client_connectivity_check_get_uri(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_uri;
-}
-
-/**
- * nm_client_get_logging:
- * @client: a #NMClient
- * @level: (allow-none): return location for logging level string
- * @domains: (allow-none): return location for log domains string. The string is
- *   a list of domains separated by ","
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Gets NetworkManager current logging level and domains.
- *
- * Returns: %TRUE on success, %FALSE otherwise
- *
- * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH,
- * %NM_DBUS_INTERFACE to call "GetLogging" with no arguments to get "(ss)" for level
- * and domains.
- **/
-gboolean
-nm_client_get_logging(NMClient *client, char **level, char **domains, GError **error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(level == NULL || *level == NULL, FALSE);
-    g_return_val_if_fail(domains == NULL || *domains == NULL, FALSE);
-    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
-
-    ret = _nm_client_dbus_call_sync(client,
-                                    NULL,
-                                    NM_DBUS_PATH,
-                                    NM_DBUS_INTERFACE,
-                                    "GetLogging",
-                                    g_variant_new("()"),
-                                    G_VARIANT_TYPE("(ss)"),
-                                    G_DBUS_CALL_FLAGS_NONE,
-                                    NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                    TRUE,
-                                    error);
-    if (!ret)
-        return FALSE;
-
-    g_variant_get(ret, "(ss)", level, domains);
-    return TRUE;
-}
-
-/**
- * nm_client_set_logging:
- * @client: a #NMClient
- * @level: (allow-none): logging level to set (%NULL or an empty string for no change)
- * @domains: (allow-none): logging domains to set. The string should be a list of log
- *   domains separated by ",". (%NULL or an empty string for no change)
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Sets NetworkManager logging level and/or domains.
- *
- * Returns: %TRUE on success, %FALSE otherwise
- *
- * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH,
- * %NM_DBUS_INTERFACE to call "SetLogging" with "(ss)" arguments for level and domains.
- **/
-gboolean
-nm_client_set_logging(NMClient *client, const char *level, const char *domains, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
-
-    return _nm_client_dbus_call_sync_void(client,
-                                          NULL,
-                                          NM_DBUS_PATH,
-                                          NM_DBUS_INTERFACE,
-                                          "SetLogging",
-                                          g_variant_new("(ss)", level ?: "", domains ?: ""),
-                                          G_DBUS_CALL_FLAGS_NONE,
-                                          NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                          TRUE,
-                                          error);
-}
-
-/**
- * nm_client_get_permission_result:
- * @client: a #NMClient
- * @permission: the permission for which to return the result, one of #NMClientPermission
- *
- * Requests the result of a specific permission, which indicates whether the
- * client can or cannot perform the action the permission represents
- *
- * Returns: the permission's result, one of #NMClientPermissionResult
- **/
-NMClientPermissionResult
-nm_client_get_permission_result(NMClient *client, NMClientPermission permission)
-{
-    NMClientPrivate *        priv;
-    NMClientPermissionResult result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
-
-    if (permission > NM_CLIENT_PERMISSION_NONE && permission <= NM_CLIENT_PERMISSION_LAST) {
-        priv = NM_CLIENT_GET_PRIVATE(client);
-        if (priv->permissions)
-            result = priv->permissions[permission - 1];
-    }
-
-    return result;
-}
-
-/**
- * nm_client_get_permissions_state:
- * @self: the #NMClient instance
- *
- * Returns: the state of the cached permissions. %NM_TERNARY_DEFAULT
- *   means that no permissions result was yet received. All permissions
- *   are unknown. %NM_TERNARY_TRUE means that the permissions got received
- *   and are cached. %%NM_TERNARY_FALSE means that permissions are cached,
- *   but they are invalided as "CheckPermissions" signal was received
- *   in the meantime.
- *
- * Since: 1.24
- */
-NMTernary
-nm_client_get_permissions_state(NMClient *self)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(self), NM_TERNARY_DEFAULT);
-
-    return NM_CLIENT_GET_PRIVATE(self)->permissions_state;
-}
-
-/**
- * nm_client_get_connectivity:
- * @client: an #NMClient
- *
- * Gets the current network connectivity state. Contrast
- * nm_client_check_connectivity() and
- * nm_client_check_connectivity_async(), which re-check the
- * connectivity state first before returning any information.
- *
- * Returns: the current connectivity state
- */
-NMConnectivityState
-nm_client_get_connectivity(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NM_CONNECTIVITY_UNKNOWN);
-
-    return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity;
-}
-
-/**
- * nm_client_check_connectivity:
- * @client: an #NMClient
- * @cancellable: a #GCancellable
- * @error: return location for a #GError
- *
- * Updates the network connectivity state and returns the (new)
- * current state. Contrast nm_client_get_connectivity(), which returns
- * the most recent known state without re-checking.
- *
- * This is a blocking call; use nm_client_check_connectivity_async()
- * if you do not want to block.
- *
- * Returns: the (new) current connectivity state
- *
- * Deprecated: 1.22: Use nm_client_check_connectivity_async() or GDBusConnection.
- */
-NMConnectivityState
-nm_client_check_connectivity(NMClient *client, GCancellable *cancellable, GError **error)
-{
-    NMClientPrivate *priv;
-    gs_unref_variant GVariant *ret = NULL;
-    guint32                    connectivity;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NM_CONNECTIVITY_UNKNOWN);
-
-    ret = _nm_client_dbus_call_sync(client,
-                                    cancellable,
-                                    NM_DBUS_PATH,
-                                    NM_DBUS_INTERFACE,
-                                    "CheckConnectivity",
-                                    g_variant_new("()"),
-                                    G_VARIANT_TYPE("(u)"),
-                                    G_DBUS_CALL_FLAGS_NONE,
-                                    NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                    TRUE,
-                                    error);
-    if (!ret)
-        return NM_CONNECTIVITY_UNKNOWN;
-
-    g_variant_get(ret, "(u)", &connectivity);
-
-    /* upon receiving the synchronous response, we hack the NMClient state
-     * and update the property outside the ordered D-Bus messages (like
-     * "PropertiesChanged" signals).
-     *
-     * This is really ugly, we shouldn't do this. */
-
-    priv = NM_CLIENT_GET_PRIVATE(client);
-
-    if (priv->nm.connectivity != connectivity) {
-        priv->nm.connectivity = connectivity;
-        _notify(client, PROP_CONNECTIVITY);
-    }
-
-    return connectivity;
-}
-
-/**
- * nm_client_check_connectivity_async:
- * @client: an #NMClient
- * @cancellable: a #GCancellable
- * @callback: callback to call with the result
- * @user_data: data for @callback.
- *
- * Asynchronously updates the network connectivity state and invokes
- * @callback when complete. Contrast nm_client_get_connectivity(),
- * which (immediately) returns the most recent known state without
- * re-checking, and nm_client_check_connectivity(), which blocks.
- */
-void
-nm_client_check_connectivity_async(NMClient *          client,
-                                   GCancellable *      cancellable,
-                                   GAsyncReadyCallback callback,
-                                   gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_check_connectivity_async,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH,
-                         NM_DBUS_INTERFACE,
-                         "CheckConnectivity",
-                         g_variant_new("()"),
-                         G_VARIANT_TYPE("(u)"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_check_connectivity_finish:
- * @client: an #NMClient
- * @result: the #GAsyncResult
- * @error: return location for a #GError
- *
- * Retrieves the result of an nm_client_check_connectivity_async()
- * call.
- *
- * Returns: the (new) current connectivity state
- */
-NMConnectivityState
-nm_client_check_connectivity_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-    guint32                    connectivity;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NM_CONNECTIVITY_UNKNOWN);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_check_connectivity_async),
-                         NM_CONNECTIVITY_UNKNOWN);
-
-    ret = g_task_propagate_pointer(G_TASK(result), error);
-    if (!ret)
-        return NM_CONNECTIVITY_UNKNOWN;
-
-    g_variant_get(ret, "(u)", &connectivity);
-    return connectivity;
-}
-
-/**
- * nm_client_save_hostname:
- * @client: the %NMClient
- * @hostname: (allow-none): the new persistent hostname to set, or %NULL to
- *   clear any existing persistent hostname
- * @cancellable: a #GCancellable, or %NULL
- * @error: return location for #GError
- *
- * Requests that the machine's persistent hostname be set to the specified value
- * or cleared.
- *
- * Returns: %TRUE if the request was successful, %FALSE if it failed
- *
- * Deprecated: 1.22: Use nm_client_save_hostname_async() or GDBusConnection.
- **/
-gboolean
-nm_client_save_hostname(NMClient *    client,
-                        const char *  hostname,
-                        GCancellable *cancellable,
-                        GError **     error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE);
-
-    return _nm_client_dbus_call_sync_void(client,
-                                          cancellable,
-                                          NM_DBUS_PATH_SETTINGS,
-                                          NM_DBUS_INTERFACE_SETTINGS,
-                                          "SaveHostname",
-                                          g_variant_new("(s)", hostname ?: ""),
-                                          G_DBUS_CALL_FLAGS_NONE,
-                                          NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                          TRUE,
-                                          error);
-}
-
-/**
- * nm_client_save_hostname_async:
- * @client: the %NMClient
- * @hostname: (allow-none): the new persistent hostname to set, or %NULL to
- *   clear any existing persistent hostname
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Requests that the machine's persistent hostname be set to the specified value
- * or cleared.
- **/
-void
-nm_client_save_hostname_async(NMClient *          client,
-                              const char *        hostname,
-                              GCancellable *      cancellable,
-                              GAsyncReadyCallback callback,
-                              gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_save_hostname_async,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH_SETTINGS,
-                         NM_DBUS_INTERFACE_SETTINGS,
-                         "SaveHostname",
-                         g_variant_new("(s)", hostname ?: ""),
-                         G_VARIANT_TYPE("()"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_save_hostname_finish:
- * @client: the %NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: return location for #GError
- *
- * Gets the result of an nm_client_save_hostname_async() call.
- *
- * Returns: %TRUE if the request was successful, %FALSE if it failed
- **/
-gboolean
-nm_client_save_hostname_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_save_hostname_async), FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/*****************************************************************************/
-/* Devices                                                                   */
-/*****************************************************************************/
-
-/**
- * nm_client_get_devices:
- * @client: a #NMClient
- *
- * Gets all the known network devices.  Use nm_device_get_type() or the
- * <literal>NM_IS_DEVICE_XXXX</literal> functions to determine what kind of
- * device member of the returned array is, and then you may use device-specific
- * methods such as nm_device_ethernet_get_hw_address().
- *
- * Returns: (transfer none) (element-type NMDevice): a #GPtrArray
- * containing all the #NMDevices.  The returned array is owned by the
- * #NMClient object and should not be modified.
- **/
-const GPtrArray *
-nm_client_get_devices(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_ao_get_objs_as_ptrarray(
-        &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_DEVICES]);
-}
-
-/**
- * nm_client_get_all_devices:
- * @client: a #NMClient
- *
- * Gets both real devices and device placeholders (eg, software devices which
- * do not currently exist, but could be created automatically by NetworkManager
- * if one of their NMDevice::ActivatableConnections was activated).  Use
- * nm_device_is_real() to determine whether each device is a real device or
- * a placeholder.
- *
- * Use nm_device_get_type() or the NM_IS_DEVICE_XXXX() functions to determine
- * what kind of device each member of the returned array is, and then you may
- * use device-specific methods such as nm_device_ethernet_get_hw_address().
- *
- * Returns: (transfer none) (element-type NMDevice): a #GPtrArray
- * containing all the #NMDevices.  The returned array is owned by the
- * #NMClient object and should not be modified.
- *
- * Since: 1.2
- **/
-const GPtrArray *
-nm_client_get_all_devices(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_ao_get_objs_as_ptrarray(
-        &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_ALL_DEVICES]);
-}
-
-/**
- * nm_client_get_device_by_path:
- * @client: a #NMClient
- * @object_path: the object path to search for
- *
- * Gets a #NMDevice from a #NMClient.
- *
- * Returns: (transfer none): the #NMDevice for the given @object_path or %NULL if none is found.
- **/
-NMDevice *
-nm_client_get_device_by_path(NMClient *client, const char *object_path)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(object_path, NULL);
-
-    return _dbobjs_get_nmobj_unpack_visible(client, object_path, NM_TYPE_DEVICE);
-}
-
-/**
- * nm_client_get_device_by_iface:
- * @client: a #NMClient
- * @iface: the interface name to search for
- *
- * Gets a #NMDevice from a #NMClient.
- *
- * Returns: (transfer none): the #NMDevice for the given @iface or %NULL if none is found.
- **/
-NMDevice *
-nm_client_get_device_by_iface(NMClient *client, const char *iface)
-{
-    const GPtrArray *devices;
-    guint            i;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(iface, NULL);
-
-    devices = nm_client_get_devices(client);
-    for (i = 0; i < devices->len; i++) {
-        NMDevice *candidate = g_ptr_array_index(devices, i);
-
-        if (nm_streq0(nm_device_get_iface(candidate), iface))
-            return candidate;
-    }
-
-    return NULL;
-}
-
-/*****************************************************************************/
-/* Active Connections                                           */
-/*****************************************************************************/
-
-/**
- * nm_client_get_active_connections:
- * @client: a #NMClient
- *
- * Gets the active connections.
- *
- * Returns: (transfer none) (element-type NMActiveConnection): a #GPtrArray
- *  containing all the active #NMActiveConnections.
- * The returned array is owned by the client and should not be modified.
- **/
-const GPtrArray *
-nm_client_get_active_connections(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_ao_get_objs_as_ptrarray(
-        &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_ACTIVE_CONNECTIONS]);
-}
-
-/**
- * nm_client_get_primary_connection:
- * @client: an #NMClient
- *
- * Gets the #NMActiveConnection corresponding to the primary active
- * network device.
- *
- * In particular, when there is no VPN active, or the VPN does not
- * have the default route, this returns the active connection that has
- * the default route. If there is a VPN active with the default route,
- * then this function returns the active connection that contains the
- * route to the VPN endpoint.
- *
- * If there is no default route, or the default route is over a
- * non-NetworkManager-recognized device, this will return %NULL.
- *
- * Returns: (transfer none): the appropriate #NMActiveConnection, if
- * any
- */
-NMActiveConnection *
-nm_client_get_primary_connection(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_o_get_obj(
-        &NM_CLIENT_GET_PRIVATE(client)->nm.property_o[PROPERTY_O_IDX_NM_PRIMAY_CONNECTION]);
-}
-
-/**
- * nm_client_get_activating_connection:
- * @client: an #NMClient
- *
- * Gets the #NMActiveConnection corresponding to a
- * currently-activating connection that is expected to become the new
- * #NMClient:primary-connection upon successful activation.
- *
- * Returns: (transfer none): the appropriate #NMActiveConnection, if
- * any.
- */
-NMActiveConnection *
-nm_client_get_activating_connection(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_o_get_obj(
-        &NM_CLIENT_GET_PRIVATE(client)->nm.property_o[PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION]);
-}
-
-/*****************************************************************************/
-
-static void
-activate_connection_cb(GObject *object, GAsyncResult *result, gpointer user_data)
-{
-    gs_unref_object GTask *task    = user_data;
-    gs_unref_variant GVariant *ret = NULL;
-    const char *               v_active_connection;
-    GError *                   error = NULL;
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), result, &error);
-    if (!ret) {
-        if (!nm_utils_error_is_cancelled(error))
-            g_dbus_error_strip_remote_error(error);
-        g_task_return_error(task, error);
-        return;
-    }
-
-    g_variant_get(ret, "(&o)", &v_active_connection);
-
-    _request_wait_start(g_steal_pointer(&task),
-                        "ActivateConnection",
-                        NM_TYPE_ACTIVE_CONNECTION,
-                        v_active_connection,
-                        NULL);
-}
-
-/**
- * nm_client_activate_connection_async:
- * @client: a #NMClient
- * @connection: (allow-none): an #NMConnection
- * @device: (allow-none): the #NMDevice
- * @specific_object: (allow-none): the object path of a connection-type-specific
- *   object this activation should use. This parameter is currently ignored for
- *   wired and mobile broadband connections, and the value of %NULL should be used
- *   (ie, no specific object).  For Wi-Fi or WiMAX connections, pass the object
- *   path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can
- *   get using nm_object_get_path(), and which will be used to complete the
- *   details of the newly added connection.
- * @cancellable: a #GCancellable, or %NULL
- * @callback: callback to be called when the activation has started
- * @user_data: caller-specific data passed to @callback
- *
- * Asynchronously starts a connection to a particular network using the
- * configuration settings from @connection and the network device @device.
- * Certain connection types also take a "specific object" which is the object
- * path of a connection- specific object, like an #NMAccessPoint for Wi-Fi
- * connections, or an #NMWimaxNsp for WiMAX connections, to which you wish to
- * connect.  If the specific object is not given, NetworkManager can, in some
- * cases, automatically determine which network to connect to given the settings
- * in @connection.
- *
- * If @connection is not given for a device-based activation, NetworkManager
- * picks the best available connection for the device and activates it.
- *
- * Note that the callback is invoked when NetworkManager has started activating
- * the new connection, not when it finishes. You can use the returned
- * #NMActiveConnection object (in particular, #NMActiveConnection:state) to
- * track the activation to its completion.
- **/
-void
-nm_client_activate_connection_async(NMClient *          client,
-                                    NMConnection *      connection,
-                                    NMDevice *          device,
-                                    const char *        specific_object,
-                                    GCancellable *      cancellable,
-                                    GAsyncReadyCallback callback,
-                                    gpointer            user_data)
-{
-    const char *arg_connection = NULL;
-    const char *arg_device     = NULL;
-
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    if (connection) {
-        g_return_if_fail(NM_IS_CONNECTION(connection));
-        arg_connection = nm_connection_get_path(connection);
-        g_return_if_fail(arg_connection);
-    }
-
-    if (device) {
-        g_return_if_fail(NM_IS_DEVICE(device));
-        arg_device = nm_object_get_path(NM_OBJECT(device));
-        g_return_if_fail(arg_device);
-    }
-
-    NML_NMCLIENT_LOG_T(
-        client,
-        "ActivateConnection() for connection \"%s\", device \"%s\", specific_object \"%s",
-        arg_connection ?: "/",
-        arg_device ?: "/",
-        specific_object ?: "/");
-
-    _nm_client_dbus_call(
-        client,
-        client,
-        nm_client_activate_connection_async,
-        cancellable,
-        callback,
-        user_data,
-        NM_DBUS_PATH,
-        NM_DBUS_INTERFACE,
-        "ActivateConnection",
-        g_variant_new("(ooo)", arg_connection ?: "/", arg_device ?: "/", specific_object ?: "/"),
-        G_VARIANT_TYPE("(o)"),
-        G_DBUS_CALL_FLAGS_NONE,
-        NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-        activate_connection_cb);
-}
-
-/**
- * nm_client_activate_connection_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_activate_connection_async().
- *
- * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on
- *   failure, in which case @error will be set.
- **/
-NMActiveConnection *
-nm_client_activate_connection_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    return NM_ACTIVE_CONNECTION(
-        _request_wait_finish(client, result, nm_client_activate_connection_async, NULL, error));
-}
-
-/*****************************************************************************/
-
-static void
-_add_and_activate_connection_done(GObject *     object,
-                                  GAsyncResult *result,
-                                  gboolean      use_add_and_activate_v2,
-                                  GTask *       task_take)
-{
-    _nm_unused gs_unref_object GTask *task = task_take;
-    gs_unref_variant GVariant *ret         = NULL;
-    GError *                   error       = NULL;
-    gs_unref_variant GVariant *v_result    = NULL;
-    const char *               v_active_connection;
-    const char *               v_path;
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), result, &error);
-    if (!ret) {
-        if (!nm_utils_error_is_cancelled(error))
-            g_dbus_error_strip_remote_error(error);
-        g_task_return_error(task, error);
-        return;
-    }
-
-    if (use_add_and_activate_v2) {
-        g_variant_get(ret, "(&o&o@a{sv})", &v_path, &v_active_connection, &v_result);
-    } else {
-        g_variant_get(ret, "(&o&o)", &v_path, &v_active_connection);
-    }
-
-    _request_wait_start(g_steal_pointer(&task),
-                        "AddAndActivateConnection",
-                        NM_TYPE_ACTIVE_CONNECTION,
-                        v_active_connection,
-                        g_steal_pointer(&v_result));
-}
-
-static void
-_add_and_activate_connection_v1_cb(GObject *object, GAsyncResult *result, gpointer user_data)
-{
-    _add_and_activate_connection_done(object, result, FALSE, user_data);
-}
-
-static void
-_add_and_activate_connection_v2_cb(GObject *object, GAsyncResult *result, gpointer user_data)
-{
-    _add_and_activate_connection_done(object, result, TRUE, user_data);
-}
-
-static void
-_add_and_activate_connection(NMClient *          self,
-                             gboolean            is_v2,
-                             NMConnection *      partial,
-                             NMDevice *          device,
-                             const char *        specific_object,
-                             GVariant *          options,
-                             GCancellable *      cancellable,
-                             GAsyncReadyCallback callback,
-                             gpointer            user_data)
-{
-    GVariant *  arg_connection          = NULL;
-    gboolean    use_add_and_activate_v2 = FALSE;
-    const char *arg_device              = NULL;
-    gpointer    source_tag;
-
-    g_return_if_fail(NM_IS_CLIENT(self));
-    g_return_if_fail(!partial || NM_IS_CONNECTION(partial));
-
-    if (device) {
-        g_return_if_fail(NM_IS_DEVICE(device));
-        arg_device = nm_object_get_path(NM_OBJECT(device));
-        g_return_if_fail(arg_device);
-    }
-
-    if (partial)
-        arg_connection = nm_connection_to_dbus(partial, NM_CONNECTION_SERIALIZE_ALL);
-    if (!arg_connection)
-        arg_connection = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0);
-
-    if (is_v2) {
-        if (!options)
-            options = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0);
-        use_add_and_activate_v2 = TRUE;
-        source_tag              = nm_client_add_and_activate_connection2;
-    } else {
-        if (options) {
-            if (g_variant_n_children(options) > 0)
-                use_add_and_activate_v2 = TRUE;
-            else
-                nm_clear_pointer(&options, nm_g_variant_unref_floating);
-        }
-        source_tag = nm_client_add_and_activate_connection_async;
-    }
-
-    NML_NMCLIENT_LOG_D(self, "AddAndActivateConnection() started...");
-
-    if (use_add_and_activate_v2) {
-        _nm_client_dbus_call(self,
-                             self,
-                             source_tag,
-                             cancellable,
-                             callback,
-                             user_data,
-                             NM_DBUS_PATH,
-                             NM_DBUS_INTERFACE,
-                             "AddAndActivateConnection2",
-                             g_variant_new("(@a{sa{sv}}oo@a{sv})",
-                                           arg_connection,
-                                           arg_device ?: "/",
-                                           specific_object ?: "/",
-                                           options),
-                             G_VARIANT_TYPE("(ooa{sv})"),
-                             G_DBUS_CALL_FLAGS_NONE,
-                             NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                             _add_and_activate_connection_v2_cb);
-    } else {
-        _nm_client_dbus_call(self,
-                             self,
-                             source_tag,
-                             cancellable,
-                             callback,
-                             user_data,
-                             NM_DBUS_PATH,
-                             NM_DBUS_INTERFACE,
-                             "AddAndActivateConnection",
-                             g_variant_new("(@a{sa{sv}}oo)",
-                                           arg_connection,
-                                           arg_device ?: "/",
-                                           specific_object ?: "/"),
-                             G_VARIANT_TYPE("(oo)"),
-                             G_DBUS_CALL_FLAGS_NONE,
-                             NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                             _add_and_activate_connection_v1_cb);
-    }
-}
-
-/**
- * nm_client_add_and_activate_connection_async:
- * @client: a #NMClient
- * @partial: (allow-none): an #NMConnection to add; the connection may be
- *   partially filled (or even %NULL) and will be completed by NetworkManager
- *   using the given @device and @specific_object before being added
- * @device: the #NMDevice
- * @specific_object: (allow-none): the object path of a connection-type-specific
- *   object this activation should use. This parameter is currently ignored for
- *   wired and mobile broadband connections, and the value of %NULL should be used
- *   (ie, no specific object).  For Wi-Fi or WiMAX connections, pass the object
- *   path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can
- *   get using nm_object_get_path(), and which will be used to complete the
- *   details of the newly added connection.
- *   If the variant is floating, it will be consumed.
- * @cancellable: a #GCancellable, or %NULL
- * @callback: callback to be called when the activation has started
- * @user_data: caller-specific data passed to @callback
- *
- * Adds a new connection using the given details (if any) as a template,
- * automatically filling in missing settings with the capabilities of the given
- * device and specific object.  The new connection is then asynchronously
- * activated as with nm_client_activate_connection_async(). Cannot be used for
- * VPN connections at this time.
- *
- * Note that the callback is invoked when NetworkManager has started activating
- * the new connection, not when it finishes. You can used the returned
- * #NMActiveConnection object (in particular, #NMActiveConnection:state) to
- * track the activation to its completion.
- **/
-void
-nm_client_add_and_activate_connection_async(NMClient *          client,
-                                            NMConnection *      partial,
-                                            NMDevice *          device,
-                                            const char *        specific_object,
-                                            GCancellable *      cancellable,
-                                            GAsyncReadyCallback callback,
-                                            gpointer            user_data)
-{
-    _add_and_activate_connection(client,
-                                 FALSE,
-                                 partial,
-                                 device,
-                                 specific_object,
-                                 NULL,
-                                 cancellable,
-                                 callback,
-                                 user_data);
-}
-
-/**
- * nm_client_add_and_activate_connection_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_add_and_activate_connection_async().
- *
- * You can call nm_active_connection_get_connection() on the returned
- * #NMActiveConnection to find the path of the created #NMConnection.
- *
- * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on
- *   failure, in which case @error will be set.
- **/
-NMActiveConnection *
-nm_client_add_and_activate_connection_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    return NM_ACTIVE_CONNECTION(_request_wait_finish(client,
-                                                     result,
-                                                     nm_client_add_and_activate_connection_async,
-                                                     NULL,
-                                                     error));
-}
-
-/**
- * nm_client_add_and_activate_connection2:
- * @client: a #NMClient
- * @partial: (allow-none): an #NMConnection to add; the connection may be
- *   partially filled (or even %NULL) and will be completed by NetworkManager
- *   using the given @device and @specific_object before being added
- * @device: the #NMDevice
- * @specific_object: (allow-none): the object path of a connection-type-specific
- *   object this activation should use. This parameter is currently ignored for
- *   wired and mobile broadband connections, and the value of %NULL should be used
- *   (i.e., no specific object).  For Wi-Fi or WiMAX connections, pass the object
- *   path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can
- *   get using nm_object_get_path(), and which will be used to complete the
- *   details of the newly added connection.
- * @options: a #GVariant containing a dictionary with options, or %NULL
- * @cancellable: a #GCancellable, or %NULL
- * @callback: callback to be called when the activation has started
- * @user_data: caller-specific data passed to @callback
- *
- * Adds a new connection using the given details (if any) as a template,
- * automatically filling in missing settings with the capabilities of the given
- * device and specific object.  The new connection is then asynchronously
- * activated as with nm_client_activate_connection_async(). Cannot be used for
- * VPN connections at this time.
- *
- * Note that the callback is invoked when NetworkManager has started activating
- * the new connection, not when it finishes. You can used the returned
- * #NMActiveConnection object (in particular, #NMActiveConnection:state) to
- * track the activation to its completion.
- *
- * This is identical to nm_client_add_and_activate_connection_async() but takes
- * a further @options parameter. Currently, the following options are supported
- * by the daemon:
- *  * "persist": A string describing how the connection should be stored.
- *               The default is "disk", but it can be modified to "memory" (until
- *               the daemon quits) or "volatile" (will be deleted on disconnect).
- *  * "bind-activation": Bind the connection lifetime to something. The default is "none",
- *            meaning an explicit disconnect is needed. The value "dbus-client"
- *            means the connection will automatically be deactivated when the calling
- *            D-Bus client disappears from the system bus.
- *
- * Since: 1.16
- **/
-void
-nm_client_add_and_activate_connection2(NMClient *          client,
-                                       NMConnection *      partial,
-                                       NMDevice *          device,
-                                       const char *        specific_object,
-                                       GVariant *          options,
-                                       GCancellable *      cancellable,
-                                       GAsyncReadyCallback callback,
-                                       gpointer            user_data)
-{
-    _add_and_activate_connection(client,
-                                 TRUE,
-                                 partial,
-                                 device,
-                                 specific_object,
-                                 options,
-                                 cancellable,
-                                 callback,
-                                 user_data);
-}
-
-/**
- * nm_client_add_and_activate_connection2_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- * @out_result: (allow-none) (transfer full): the output result
- *   of type "a{sv}" returned by D-Bus' AddAndActivate2 call. Currently, no
- *   output is implemented yet.
- *
- * Gets the result of a call to nm_client_add_and_activate_connection2().
- *
- * You can call nm_active_connection_get_connection() on the returned
- * #NMActiveConnection to find the path of the created #NMConnection.
- *
- * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on
- *   failure, in which case @error will be set.
- **/
-NMActiveConnection *
-nm_client_add_and_activate_connection2_finish(NMClient *    client,
-                                              GAsyncResult *result,
-                                              GVariant **   out_result,
-                                              GError **     error)
-{
-    return NM_ACTIVE_CONNECTION(_request_wait_finish(client,
-                                                     result,
-                                                     nm_client_add_and_activate_connection2,
-                                                     out_result,
-                                                     error));
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_deactivate_connection:
- * @client: a #NMClient
- * @active: the #NMActiveConnection to deactivate
- * @cancellable: a #GCancellable, or %NULL
- * @error: location for a #GError, or %NULL
- *
- * Deactivates an active #NMActiveConnection.
- *
- * Returns: success or failure
- *
- * Deprecated: 1.22: Use nm_client_deactivate_connection_async() or GDBusConnection.
- **/
-gboolean
-nm_client_deactivate_connection(NMClient *          client,
-                                NMActiveConnection *active,
-                                GCancellable *      cancellable,
-                                GError **           error)
-{
-    const char *active_path;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(NM_IS_ACTIVE_CONNECTION(active), FALSE);
-
-    active_path = nm_object_get_path(NM_OBJECT(active));
-    g_return_val_if_fail(active_path, FALSE);
-
-    return _nm_client_dbus_call_sync_void(client,
-                                          cancellable,
-                                          NM_DBUS_PATH,
-                                          NM_DBUS_INTERFACE,
-                                          "DeactivateConnection",
-                                          g_variant_new("(o)", active_path),
-                                          G_DBUS_CALL_FLAGS_NONE,
-                                          NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                          TRUE,
-                                          error);
-}
-
-/**
- * nm_client_deactivate_connection_async:
- * @client: a #NMClient
- * @active: the #NMActiveConnection to deactivate
- * @cancellable: a #GCancellable, or %NULL
- * @callback: callback to be called when the deactivation has completed
- * @user_data: caller-specific data passed to @callback
- *
- * Asynchronously deactivates an active #NMActiveConnection.
- **/
-void
-nm_client_deactivate_connection_async(NMClient *          client,
-                                      NMActiveConnection *active,
-                                      GCancellable *      cancellable,
-                                      GAsyncReadyCallback callback,
-                                      gpointer            user_data)
-{
-    const char *active_path;
-
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(NM_IS_ACTIVE_CONNECTION(active));
-
-    active_path = nm_object_get_path(NM_OBJECT(active));
-    g_return_if_fail(active_path);
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_deactivate_connection_async,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH,
-                         NM_DBUS_INTERFACE,
-                         "DeactivateConnection",
-                         g_variant_new("(o)", active_path),
-                         G_VARIANT_TYPE("()"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_deactivate_connection_finish:
- * @client: a #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_deactivate_connection_async().
- *
- * Returns: success or failure
- **/
-gboolean
-nm_client_deactivate_connection_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_deactivate_connection_async),
-                         FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/*****************************************************************************/
-/* Connections                                                  */
-/*****************************************************************************/
-
-/**
- * nm_client_get_connections:
- * @client: the %NMClient
- *
- * Returns: (transfer none) (element-type NMRemoteConnection): an array
- * containing all connections provided by the remote settings service.  The
- * returned array is owned by the #NMClient object and should not be modified.
- *
- * The connections are as received from D-Bus and might not validate according
- * to nm_connection_verify().
- **/
-const GPtrArray *
-nm_client_get_connections(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_ao_get_objs_as_ptrarray(
-        &NM_CLIENT_GET_PRIVATE(client)->settings.connections);
-}
-
-/**
- * nm_client_get_connection_by_id:
- * @client: the %NMClient
- * @id: the id of the remote connection
- *
- * Returns the first matching %NMRemoteConnection matching a given @id.
- *
- * Returns: (transfer none): the remote connection object on success, or %NULL if no
- *  matching object was found.
- *
- * The connection is as received from D-Bus and might not validate according
- * to nm_connection_verify().
- **/
-NMRemoteConnection *
-nm_client_get_connection_by_id(NMClient *client, const char *id)
-{
-    const GPtrArray *arr;
-    guint            i;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(id, NULL);
-
-    arr = nm_client_get_connections(client);
-    for (i = 0; i < arr->len; i++) {
-        NMRemoteConnection *c = NM_REMOTE_CONNECTION(arr->pdata[i]);
-
-        if (nm_streq0(id, nm_connection_get_id(NM_CONNECTION(c))))
-            return c;
-    }
-    return NULL;
-}
-
-/**
- * nm_client_get_connection_by_path:
- * @client: the %NMClient
- * @path: the D-Bus object path of the remote connection
- *
- * Returns the %NMRemoteConnection representing the connection at @path.
- *
- * Returns: (transfer none): the remote connection object on success, or %NULL if the object was
- *  not known
- *
- * The connection is as received from D-Bus and might not validate according
- * to nm_connection_verify().
- **/
-NMRemoteConnection *
-nm_client_get_connection_by_path(NMClient *client, const char *path)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(path != NULL, NULL);
-
-    return _dbobjs_get_nmobj_unpack_visible(client, path, NM_TYPE_REMOTE_CONNECTION);
-}
-
-/**
- * nm_client_get_connection_by_uuid:
- * @client: the %NMClient
- * @uuid: the UUID of the remote connection
- *
- * Returns the %NMRemoteConnection identified by @uuid.
- *
- * Returns: (transfer none): the remote connection object on success, or %NULL if the object was
- *  not known
- *
- * The connection is as received from D-Bus and might not validate according
- * to nm_connection_verify().
- **/
-NMRemoteConnection *
-nm_client_get_connection_by_uuid(NMClient *client, const char *uuid)
-{
-    const GPtrArray *arr;
-    guint            i;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(uuid, NULL);
-
-    arr = nm_client_get_connections(client);
-    for (i = 0; i < arr->len; i++) {
-        NMRemoteConnection *c = NM_REMOTE_CONNECTION(arr->pdata[i]);
-
-        if (nm_streq0(uuid, nm_connection_get_uuid(NM_CONNECTION(c))))
-            return c;
-    }
-    return NULL;
-}
-
-/*****************************************************************************/
-
-static void
-_add_connection_cb(GObject *     source,
-                   GAsyncResult *result,
-                   gboolean      with_extra_arg,
-                   gpointer      user_data)
-{
-    gs_unref_variant GVariant *ret      = NULL;
-    gs_unref_object GTask *task         = user_data;
-    gs_unref_variant GVariant *v_result = NULL;
-    const char *               v_path;
-    GError *                   error = NULL;
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
-    if (!ret) {
-        if (!nm_utils_error_is_cancelled(error))
-            g_dbus_error_strip_remote_error(error);
-        g_task_return_error(task, error);
-        return;
-    }
-
-    if (with_extra_arg) {
-        g_variant_get(ret, "(&o@a{sv})", &v_path, &v_result);
-    } else {
-        g_variant_get(ret, "(&o)", &v_path);
-    }
-
-    _request_wait_start(g_steal_pointer(&task),
-                        "AddConnection",
-                        NM_TYPE_REMOTE_CONNECTION,
-                        v_path,
-                        g_steal_pointer(&v_result));
-}
-
-static void
-_add_connection_cb_without_extra_result(GObject *object, GAsyncResult *result, gpointer user_data)
-{
-    _add_connection_cb(object, result, FALSE, user_data);
-}
-
-static void
-_add_connection_cb_with_extra_result(GObject *object, GAsyncResult *result, gpointer user_data)
-{
-    _add_connection_cb(object, result, TRUE, user_data);
-}
-
-static void
-_add_connection_call(NMClient *                    self,
-                     gpointer                      source_tag,
-                     gboolean                      ignore_out_result,
-                     GVariant *                    settings,
-                     NMSettingsAddConnection2Flags flags,
-                     GVariant *                    args,
-                     GCancellable *                cancellable,
-                     GAsyncReadyCallback           callback,
-                     gpointer                      user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(self));
-    g_return_if_fail(!settings || g_variant_is_of_type(settings, G_VARIANT_TYPE("a{sa{sv}}")));
-    g_return_if_fail(!args || g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}")));
-
-    NML_NMCLIENT_LOG_D(self, "AddConnection() started...");
-
-    if (!settings)
-        settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0);
-
-    /* Although AddConnection2() being capable to handle also AddConnection() and
-     * AddConnectionUnsaved() variants, we prefer to use the old D-Bus methods when
-     * they are sufficient. The reason is that libnm should avoid hard dependencies
-     * on 1.20 API whenever possible. */
-    if (ignore_out_result && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
-        _nm_client_dbus_call(self,
-                             self,
-                             source_tag,
-                             cancellable,
-                             callback,
-                             user_data,
-                             NM_DBUS_PATH_SETTINGS,
-                             NM_DBUS_INTERFACE_SETTINGS,
-                             "AddConnection",
-                             g_variant_new("(@a{sa{sv}})", settings),
-                             G_VARIANT_TYPE("(o)"),
-                             G_DBUS_CALL_FLAGS_NONE,
-                             NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                             _add_connection_cb_without_extra_result);
-    } else if (ignore_out_result && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
-        _nm_client_dbus_call(self,
-                             self,
-                             source_tag,
-                             cancellable,
-                             callback,
-                             user_data,
-                             NM_DBUS_PATH_SETTINGS,
-                             NM_DBUS_INTERFACE_SETTINGS,
-                             "AddConnectionUnsaved",
-                             g_variant_new("(@a{sa{sv}})", settings),
-                             G_VARIANT_TYPE("(o)"),
-                             G_DBUS_CALL_FLAGS_NONE,
-                             NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                             _add_connection_cb_without_extra_result);
-    } else {
-        _nm_client_dbus_call(
-            self,
-            self,
-            source_tag,
-            cancellable,
-            callback,
-            user_data,
-            NM_DBUS_PATH_SETTINGS,
-            NM_DBUS_INTERFACE_SETTINGS,
-            "AddConnection2",
-            g_variant_new("(@a{sa{sv}}u@a{sv})",
-                          settings,
-                          (guint32) flags,
-                          args ?: g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0)),
-            G_VARIANT_TYPE("(oa{sv})"),
-            G_DBUS_CALL_FLAGS_NONE,
-            NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-            _add_connection_cb_with_extra_result);
-    }
-}
-
-/**
- * nm_client_add_connection_async:
- * @client: the %NMClient
- * @connection: the connection to add. Note that this object's settings will be
- *   added, not the object itself
- * @save_to_disk: whether to immediately save the connection to disk
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Requests that the remote settings service add the given settings to a new
- * connection.  If @save_to_disk is %TRUE, the connection is immediately written
- * to disk; otherwise it is initially only stored in memory, but may be saved
- * later by calling the connection's nm_remote_connection_commit_changes()
- * method.
- *
- * @connection is untouched by this function and only serves as a template of
- * the settings to add.  The #NMRemoteConnection object that represents what
- * NetworkManager actually added is returned to @callback when the addition
- * operation is complete.
- *
- * Note that the #NMRemoteConnection returned in @callback may not contain
- * identical settings to @connection as NetworkManager may perform automatic
- * completion and/or normalization of connection properties.
- **/
-void
-nm_client_add_connection_async(NMClient *          client,
-                               NMConnection *      connection,
-                               gboolean            save_to_disk,
-                               GCancellable *      cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CONNECTION(connection));
-
-    _add_connection_call(client,
-                         nm_client_add_connection_async,
-                         TRUE,
-                         nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL),
-                         save_to_disk ? NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
-                                      : NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY,
-                         NULL,
-                         cancellable,
-                         callback,
-                         user_data);
-}
-
-/**
- * nm_client_add_connection_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_add_connection_async().
- *
- * Returns: (transfer full): the new #NMRemoteConnection on success, %NULL on
- *   failure, in which case @error will be set.
- **/
-NMRemoteConnection *
-nm_client_add_connection_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    return NM_REMOTE_CONNECTION(
-        _request_wait_finish(client, result, nm_client_add_connection_async, NULL, error));
-}
-
-/**
- * nm_client_add_connection2:
- * @client: the %NMClient
- * @settings: the "a{sa{sv}}" #GVariant with the content of the setting.
- * @flags: the %NMSettingsAddConnection2Flags argument.
- * @args: (allow-none): the "a{sv}" #GVariant with extra argument or %NULL
- *   for no extra arguments.
- * @ignore_out_result: this function wraps AddConnection2(), which has an
- *   additional result "a{sv}" output parameter. By setting this to %TRUE,
- *   you signal that you are not interested in that output parameter.
- *   This allows the function to fall back to AddConnection() and AddConnectionUnsaved(),
- *   which is interesting if you run against an older server version that does
- *   not yet provide AddConnection2(). By setting this to %FALSE, the function
- *   under the hood always calls AddConnection2().
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Call AddConnection2() D-Bus API asynchronously.
- *
- * Since: 1.20
- **/
-void
-nm_client_add_connection2(NMClient *                    client,
-                          GVariant *                    settings,
-                          NMSettingsAddConnection2Flags flags,
-                          GVariant *                    args,
-                          gboolean                      ignore_out_result,
-                          GCancellable *                cancellable,
-                          GAsyncReadyCallback           callback,
-                          gpointer                      user_data)
-{
-    _add_connection_call(client,
-                         nm_client_add_connection2,
-                         ignore_out_result,
-                         settings,
-                         flags,
-                         args,
-                         cancellable,
-                         callback,
-                         user_data);
-}
-
-/**
- * nm_client_add_connection2_finish:
- * @client: the #NMClient
- * @result: the #GAsyncResult
- * @out_result: (allow-none) (transfer full) (out): the output #GVariant
- *   from AddConnection2().
- *   If you care about the output result, then the "ignore_out_result"
- *   parameter of nm_client_add_connection2() must not be set to %TRUE.
- * @error: (allow-none): the error argument.
- *
- * Returns: (transfer full): on success, a pointer to the added
- *   #NMRemoteConnection.
- *
- * Since: 1.20
- */
-NMRemoteConnection *
-nm_client_add_connection2_finish(NMClient *    client,
-                                 GAsyncResult *result,
-                                 GVariant **   out_result,
-                                 GError **     error)
-{
-    return NM_REMOTE_CONNECTION(
-        _request_wait_finish(client, result, nm_client_add_connection2, out_result, error));
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_load_connections:
- * @client: the %NMClient
- * @filenames: (array zero-terminated=1): %NULL-terminated array of filenames to load
- * @failures: (out) (transfer full): on return, a %NULL-terminated array of
- *   filenames that failed to load
- * @cancellable: a #GCancellable, or %NULL
- * @error: return location for #GError
- *
- * Requests that the remote settings service load or reload the given files,
- * adding or updating the connections described within.
- *
- * The changes to the indicated files will not yet be reflected in
- * @client's connections array when the function returns.
- *
- * If all of the indicated files were successfully loaded, the
- * function will return %TRUE, and @failures will be set to %NULL. If
- * NetworkManager tried to load the files, but some (or all) failed,
- * then @failures will be set to a %NULL-terminated array of the
- * filenames that failed to load.
- *
- * Returns: %TRUE on success.
- *
- * Warning: before libnm 1.22, the boolean return value was inconsistent.
- *   That is made worse, because when running against certain server versions
- *   before 1.20, the server would return wrong values for success/failure.
- *   This means, if you use this function in libnm before 1.22, you are advised
- *   to ignore the boolean return value and only look at @failures and @error.
- *   With libnm >= 1.22, the boolean return value corresponds to whether @error was
- *   set. Note that even in the success case, you might have individual @failures.
- *   With 1.22, the return value is consistent with nm_client_load_connections_finish().
- *
- * Deprecated: 1.22: Use nm_client_load_connections_async() or GDBusConnection.
- **/
-gboolean
-nm_client_load_connections(NMClient *    client,
-                           char **       filenames,
-                           char ***      failures,
-                           GCancellable *cancellable,
-                           GError **     error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE);
-
-    ret = _nm_client_dbus_call_sync(client,
-                                    cancellable,
-                                    NM_DBUS_PATH_SETTINGS,
-                                    NM_DBUS_INTERFACE_SETTINGS,
-                                    "LoadConnections",
-                                    g_variant_new("(^as)", filenames ?: NM_PTRARRAY_EMPTY(char *)),
-                                    G_VARIANT_TYPE("(bas)"),
-                                    G_DBUS_CALL_FLAGS_NONE,
-                                    NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                    TRUE,
-                                    error);
-    if (!ret) {
-        *failures = NULL;
-        return FALSE;
-    }
-
-    g_variant_get(ret, "(b^as)", NULL, &failures);
-
-    return TRUE;
-}
-
-/**
- * nm_client_load_connections_async:
- * @client: the %NMClient
- * @filenames: (array zero-terminated=1): %NULL-terminated array of filenames to load
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Requests that the remote settings service asynchronously load or reload the
- * given files, adding or updating the connections described within.
- *
- * See nm_client_load_connections() for more details.
- **/
-void
-nm_client_load_connections_async(NMClient *          client,
-                                 char **             filenames,
-                                 GCancellable *      cancellable,
-                                 GAsyncReadyCallback callback,
-                                 gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_load_connections_async,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH_SETTINGS,
-                         NM_DBUS_INTERFACE_SETTINGS,
-                         "LoadConnections",
-                         g_variant_new("(^as)", filenames ?: NM_PTRARRAY_EMPTY(char *)),
-                         G_VARIANT_TYPE("(bas)"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_load_connections_finish:
- * @client: the %NMClient
- * @failures: (out) (transfer full) (array zero-terminated=1): on return, a
- *    %NULL-terminated array of filenames that failed to load
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of an nm_client_load_connections_async() call.
-
- * See nm_client_load_connections() for more details.
- *
- * Returns: %TRUE on success.
- *   Note that even in the success case, you might have individual @failures.
- **/
-gboolean
-nm_client_load_connections_finish(NMClient *    client,
-                                  char ***      failures,
-                                  GAsyncResult *result,
-                                  GError **     error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_load_connections_async),
-                         FALSE);
-
-    ret = g_task_propagate_pointer(G_TASK(result), error);
-    if (!ret) {
-        *failures = NULL;
-        return FALSE;
-    }
-
-    g_variant_get(ret, "(b^as)", NULL, &failures);
-
-    return TRUE;
-}
-
-/**
- * nm_client_reload_connections:
- * @client: the #NMClient
- * @cancellable: a #GCancellable, or %NULL
- * @error: return location for #GError
- *
- * Requests that the remote settings service reload all connection
- * files from disk, adding, updating, and removing connections until
- * the in-memory state matches the on-disk state.
- *
- * Return value: %TRUE on success, %FALSE on failure
- *
- * Deprecated: 1.22: Use nm_client_reload_connections_async() or GDBusConnection.
- **/
-gboolean
-nm_client_reload_connections(NMClient *client, GCancellable *cancellable, GError **error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE);
-
-    ret = _nm_client_dbus_call_sync(client,
-                                    cancellable,
-                                    NM_DBUS_PATH_SETTINGS,
-                                    NM_DBUS_INTERFACE_SETTINGS,
-                                    "ReloadConnections",
-                                    g_variant_new("()"),
-                                    G_VARIANT_TYPE("(b)"),
-                                    G_DBUS_CALL_FLAGS_NONE,
-                                    NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                                    TRUE,
-                                    error);
-    if (!ret)
-        return FALSE;
-
-    return TRUE;
-}
-
-/**
- * nm_client_reload_connections_async:
- * @client: the #NMClient
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the reload operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Requests that the remote settings service begin reloading all connection
- * files from disk, adding, updating, and removing connections until the
- * in-memory state matches the on-disk state.
- **/
-void
-nm_client_reload_connections_async(NMClient *          client,
-                                   GCancellable *      cancellable,
-                                   GAsyncReadyCallback callback,
-                                   gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_reload_connections_async,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH_SETTINGS,
-                         NM_DBUS_INTERFACE_SETTINGS,
-                         "ReloadConnections",
-                         g_variant_new("()"),
-                         G_VARIANT_TYPE("(b)"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_reload_connections_finish:
- * @client: the #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: return location for #GError
- *
- * Gets the result of an nm_client_reload_connections_async() call.
- *
- * Return value: %TRUE on success, %FALSE on failure
- **/
-gboolean
-nm_client_reload_connections_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    gs_unref_variant GVariant *ret = NULL;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_reload_connections_async),
-                         FALSE);
-
-    ret = g_task_propagate_pointer(G_TASK(result), error);
-    if (!ret)
-        return FALSE;
-
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_get_dns_mode:
- * @client: the #NMClient
- *
- * Gets the current DNS processing mode.
- *
- * Return value: the DNS processing mode, or %NULL in case the
- *   value is not available.
- *
- * Since: 1.6
- **/
-const char *
-nm_client_get_dns_mode(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->dns_manager.mode;
-}
-
-/**
- * nm_client_get_dns_rc_manager:
- * @client: the #NMClient
- *
- * Gets the current DNS resolv.conf manager.
- *
- * Return value: the resolv.conf manager or %NULL in case the
- *   value is not available.
- *
- * Since: 1.6
- **/
-const char *
-nm_client_get_dns_rc_manager(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->dns_manager.rc_manager;
-}
-
-/**
- * nm_client_get_dns_configuration:
- * @client: a #NMClient
- *
- * Gets the current DNS configuration
- *
- * Returns: (transfer none) (element-type NMDnsEntry): a #GPtrArray
- * containing #NMDnsEntry elements or %NULL in case the value is not
- * available.  The returned array is owned by the #NMClient object
- * and should not be modified.
- *
- * Since: 1.6
- **/
-const GPtrArray *
-nm_client_get_dns_configuration(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return NM_CLIENT_GET_PRIVATE(client)->dns_manager.configuration;
-}
-
-static NMLDBusNotifyUpdatePropFlags
-_notify_update_prop_dns_manager_configuration(NMClient *              self,
-                                              NMLDBusObject *         dbobj,
-                                              const NMLDBusMetaIface *meta_iface,
-                                              guint                   dbus_property_idx,
-                                              GVariant *              value)
-{
-    NMClientPrivate * priv                         = NM_CLIENT_GET_PRIVATE(self);
-    gs_unref_ptrarray GPtrArray *configuration_old = NULL;
-    gs_unref_ptrarray GPtrArray *configuration_new = NULL;
-
-    nm_assert(G_OBJECT(self) == dbobj->nmobj);
-
-    if (value) {
-        GVariant *   entry_var_tmp;
-        GVariantIter iter;
-        GPtrArray *  array;
-
-        configuration_new = g_ptr_array_new_with_free_func((GDestroyNotify) nm_dns_entry_unref);
-
-        g_variant_iter_init(&iter, value);
-        while (g_variant_iter_next(&iter, "@a{sv}", &entry_var_tmp)) {
-            gs_unref_variant GVariant *entry_var                      = entry_var_tmp;
-            nm_auto_free_variant_iter GVariantIter *iterp_nameservers = NULL;
-            nm_auto_free_variant_iter GVariantIter *iterp_domains     = NULL;
-            gs_free char **                         nameservers       = NULL;
-            gs_free char **                         domains           = NULL;
-            gboolean                                vpn               = FALSE;
-            NMDnsEntry *                            entry;
-            char *                                  interface = NULL;
-            char *                                  str;
-            gint32                                  priority = 0;
-
-            if (!g_variant_lookup(entry_var, "nameservers", "as", &iterp_nameservers)
-                || !g_variant_lookup(entry_var, "priority", "i", &priority)) {
-                g_warning("Ignoring invalid DNS configuration");
-                continue;
-            }
-
-            array = g_ptr_array_new();
-            while (g_variant_iter_next(iterp_nameservers, "&s", &str))
-                g_ptr_array_add(array, str);
-            g_ptr_array_add(array, NULL);
-            nameservers = (char **) g_ptr_array_free(array, FALSE);
-
-            if (g_variant_lookup(entry_var, "domains", "as", &iterp_domains)) {
-                array = g_ptr_array_new();
-                while (g_variant_iter_next(iterp_domains, "&s", &str))
-                    g_ptr_array_add(array, str);
-                g_ptr_array_add(array, NULL);
-                domains = (char **) g_ptr_array_free(array, FALSE);
-            }
-
-            g_variant_lookup(entry_var, "interface", "&s", &interface);
-            g_variant_lookup(entry_var, "vpn", "b", &vpn);
-
-            entry = nm_dns_entry_new(interface,
-                                     (const char *const *) nameservers,
-                                     (const char *const *) domains,
-                                     priority,
-                                     vpn);
-            if (!entry) {
-                g_warning("Ignoring invalid DNS entry");
-                continue;
-            }
-
-            g_ptr_array_add(configuration_new, entry);
-        }
-    }
-
-    configuration_old               = priv->dns_manager.configuration;
-    priv->dns_manager.configuration = g_steal_pointer(&configuration_new);
-
-    return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
-}
-
-/**
- * nm_client_get_capabilities:
- * @client: the #NMClient instance
- * @length: (out) (allow-none): the number of returned capabilities.
- *
- * Returns: (transfer none) (array length=length): the
- *   list of capabilities reported by the server or %NULL
- *   if the capabilities are unknown.
- *   The numeric values correspond to #NMCapability enum.
- *   The array is terminated by a numeric zero sentinel
- *   at position @length.
- *
- * Since: 1.24
- */
-const guint32 *
-nm_client_get_capabilities(NMClient *client, gsize *length)
-{
-    NMClientPrivate *priv;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(length, NULL);
-
-    priv = NM_CLIENT_GET_PRIVATE(client);
-
-    NM_SET_OUT(length, priv->nm.capabilities_len);
-    return priv->nm.capabilities_arr;
-}
-
-static NMLDBusNotifyUpdatePropFlags
-_notify_update_prop_nm_capabilities(NMClient *              self,
-                                    NMLDBusObject *         dbobj,
-                                    const NMLDBusMetaIface *meta_iface,
-                                    guint                   dbus_property_idx,
-                                    GVariant *              value)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    nm_assert(G_OBJECT(self) == dbobj->nmobj);
-
-    nm_clear_g_free(&priv->nm.capabilities_arr);
-    priv->nm.capabilities_len = 0;
-
-    if (value) {
-        const guint32 *arr;
-        gsize          len;
-
-        arr                       = g_variant_get_fixed_array(value, &len, sizeof(guint32));
-        priv->nm.capabilities_len = len;
-        priv->nm.capabilities_arr = g_new(guint32, len + 1);
-        if (len > 0)
-            memcpy(priv->nm.capabilities_arr, arr, len * sizeof(guint32));
-        priv->nm.capabilities_arr[len] = 0;
-    }
-
-    return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_get_checkpoints:
- * @client: a #NMClient
- *
- * Gets all the active checkpoints.
- *
- * Returns: (transfer none) (element-type NMCheckpoint): a #GPtrArray
- * containing all the #NMCheckpoint.  The returned array is owned by the
- * #NMClient object and should not be modified.
- *
- * Since: 1.12
- **/
-const GPtrArray *
-nm_client_get_checkpoints(NMClient *client)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-
-    return nml_dbus_property_ao_get_objs_as_ptrarray(
-        &NM_CLIENT_GET_PRIVATE(client)->nm.property_ao[PROPERTY_AO_IDX_CHECKPOINTS]);
-}
-
-static void
-checkpoint_create_cb(GObject *object, GAsyncResult *result, gpointer user_data)
-{
-    gs_unref_object GTask *task    = user_data;
-    gs_unref_variant GVariant *ret = NULL;
-    const char *               v_checkpoint_path;
-    GError *                   error = NULL;
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), result, &error);
-    if (!ret) {
-        if (!nm_utils_error_is_cancelled(error))
-            g_dbus_error_strip_remote_error(error);
-        g_task_return_error(task, error);
-        return;
-    }
-
-    g_variant_get(ret, "(&o)", &v_checkpoint_path);
-
-    _request_wait_start(g_steal_pointer(&task),
-                        "CheckpointCreate",
-                        NM_TYPE_CHECKPOINT,
-                        v_checkpoint_path,
-                        NULL);
-}
-
-/**
- * nm_client_checkpoint_create:
- * @client: the %NMClient
- * @devices: (element-type NMDevice): a list of devices for which a
- *   checkpoint should be created.
- * @rollback_timeout: the rollback timeout in seconds
- * @flags: creation flags
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Creates a checkpoint of the current networking configuration
- * for given interfaces. An empty @devices argument means all
- * devices. If @rollback_timeout is not zero, a rollback is
- * automatically performed after the given timeout.
- *
- * Since: 1.12
- **/
-void
-nm_client_checkpoint_create(NMClient *              client,
-                            const GPtrArray *       devices,
-                            guint32                 rollback_timeout,
-                            NMCheckpointCreateFlags flags,
-                            GCancellable *          cancellable,
-                            GAsyncReadyCallback     callback,
-                            gpointer                user_data)
-{
-    gs_free const char **paths = NULL;
-    guint                i;
-
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    if (devices && devices->len > 0) {
-        paths = g_new(const char *, devices->len + 1);
-        for (i = 0; i < devices->len; i++)
-            paths[i] = nm_object_get_path(NM_OBJECT(devices->pdata[i]));
-        paths[i] = NULL;
-    }
-
-    _nm_client_dbus_call(
-        client,
-        client,
-        nm_client_checkpoint_create,
-        cancellable,
-        callback,
-        user_data,
-        NM_DBUS_PATH,
-        NM_DBUS_INTERFACE,
-        "CheckpointCreate",
-        g_variant_new("(^aouu)", paths ?: NM_PTRARRAY_EMPTY(const char *), rollback_timeout, flags),
-        G_VARIANT_TYPE("(o)"),
-        G_DBUS_CALL_FLAGS_NONE,
-        NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-        checkpoint_create_cb);
-}
-
-/**
- * nm_client_checkpoint_create_finish:
- * @client: the #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_checkpoint_create().
- *
- * Returns: (transfer full): the new #NMCheckpoint on success, %NULL on
- *   failure, in which case @error will be set.
- *
- * Since: 1.12
- **/
-NMCheckpoint *
-nm_client_checkpoint_create_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    return NM_CHECKPOINT(
-        _request_wait_finish(client, result, nm_client_checkpoint_create, NULL, error));
-}
-
-/**
- * nm_client_checkpoint_destroy:
- * @client: the %NMClient
- * @checkpoint_path: the D-Bus path for the checkpoint
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Destroys an existing checkpoint without performing a rollback.
- *
- * Since: 1.12
- **/
-void
-nm_client_checkpoint_destroy(NMClient *          client,
-                             const char *        checkpoint_path,
-                             GCancellable *      cancellable,
-                             GAsyncReadyCallback callback,
-                             gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(checkpoint_path && checkpoint_path[0] == '/');
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_checkpoint_destroy,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH,
-                         NM_DBUS_INTERFACE,
-                         "CheckpointDestroy",
-                         g_variant_new("(o)", checkpoint_path),
-                         G_VARIANT_TYPE("()"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_checkpoint_destroy_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_checkpoint_destroy().
- *
- * Returns: %TRUE on success or %FALSE on failure, in which case
- *   @error will be set.
- *
- * Since: 1.12
- **/
-gboolean
-nm_client_checkpoint_destroy_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_checkpoint_destroy), FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/**
- * nm_client_checkpoint_rollback:
- * @client: the %NMClient
- * @checkpoint_path: the D-Bus path to the checkpoint
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Performs the rollback of a checkpoint before the timeout is reached.
- *
- * Since: 1.12
- **/
-void
-nm_client_checkpoint_rollback(NMClient *          client,
-                              const char *        checkpoint_path,
-                              GCancellable *      cancellable,
-                              GAsyncReadyCallback callback,
-                              gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(checkpoint_path && checkpoint_path[0] == '/');
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_checkpoint_rollback,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH,
-                         NM_DBUS_INTERFACE,
-                         "CheckpointRollback",
-                         g_variant_new("(o)", checkpoint_path),
-                         G_VARIANT_TYPE("(a{su})"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_checkpoint_rollback_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_checkpoint_rollback().
- *
- * Returns: (transfer full) (element-type utf8 guint32): an hash table of
- *   devices and results. Devices are represented by their original
- *   D-Bus path; each result is a #NMRollbackResult.
- *
- * Since: 1.12
- **/
-GHashTable *
-nm_client_checkpoint_rollback_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    gs_unref_variant GVariant *ret      = NULL;
-    gs_unref_variant GVariant *v_result = NULL;
-    GVariantIter               iter;
-    GHashTable *               hash;
-    const char *               path;
-    guint32                    r;
-
-    g_return_val_if_fail(NM_IS_CLIENT(client), NULL);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_checkpoint_rollback), NULL);
-
-    ret = g_task_propagate_pointer(G_TASK(result), error);
-    if (!ret)
-        return NULL;
-
-    g_variant_get(ret, "(@a{su})", &v_result);
-
-    hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, NULL);
-
-    g_variant_iter_init(&iter, v_result);
-    while (g_variant_iter_next(&iter, "{&su}", &path, &r))
-        g_hash_table_insert(hash, g_strdup(path), GUINT_TO_POINTER(r));
-
-    return hash;
-}
-
-/**
- * nm_client_checkpoint_adjust_rollback_timeout:
- * @client: the %NMClient
- * @checkpoint_path: a D-Bus path to a checkpoint
- * @add_timeout: the timeout in seconds counting from now.
- *   Set to zero, to disable the timeout.
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Resets the timeout for the checkpoint with path @checkpoint_path
- * to @timeout_add.
- *
- * Since: 1.12
- **/
-void
-nm_client_checkpoint_adjust_rollback_timeout(NMClient *          client,
-                                             const char *        checkpoint_path,
-                                             guint32             add_timeout,
-                                             GCancellable *      cancellable,
-                                             GAsyncReadyCallback callback,
-                                             gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(checkpoint_path && checkpoint_path[0] == '/');
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_checkpoint_adjust_rollback_timeout,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH,
-                         NM_DBUS_INTERFACE,
-                         "CheckpointAdjustRollbackTimeout",
-                         g_variant_new("(ou)", checkpoint_path, add_timeout),
-                         G_VARIANT_TYPE("()"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_checkpoint_adjust_rollback_timeout_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_checkpoint_adjust_rollback_timeout().
- *
- * Returns: %TRUE on success or %FALSE on failure.
- *
- * Since: 1.12
- **/
-gboolean
-nm_client_checkpoint_adjust_rollback_timeout_finish(NMClient *    client,
-                                                    GAsyncResult *result,
-                                                    GError **     error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(
-        nm_g_task_is_valid(result, client, nm_client_checkpoint_adjust_rollback_timeout),
-        FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/**
- * nm_client_reload:
- * @client: the %NMClient
- * @flags: flags indicating what to reload.
- * @cancellable: a #GCancellable, or %NULL
- * @callback: (scope async): callback to be called when the add operation completes
- * @user_data: (closure): caller-specific data passed to @callback
- *
- * Reload NetworkManager's configuration and perform certain updates, like
- * flushing caches or rewriting external state to disk. This is similar to
- * sending SIGHUP to NetworkManager but it allows for more fine-grained control
- * over what to reload (see @flags). It also allows non-root access via
- * PolicyKit and contrary to signals it is synchronous.
- *
- * Since: 1.22
- **/
-void
-nm_client_reload(NMClient *           client,
-                 NMManagerReloadFlags flags,
-                 GCancellable *       cancellable,
-                 GAsyncReadyCallback  callback,
-                 gpointer             user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_reload,
-                         cancellable,
-                         callback,
-                         user_data,
-                         NM_DBUS_PATH,
-                         NM_DBUS_INTERFACE,
-                         "Reload",
-                         g_variant_new("(u)", (guint32) flags),
-                         G_VARIANT_TYPE("()"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                         nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
-}
-
-/**
- * nm_client_reload_finish:
- * @client: an #NMClient
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_reload().
- *
- * Returns: %TRUE on success or %FALSE on failure.
- *
- * Since: 1.22
- **/
-gboolean
-nm_client_reload_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_reload), FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_dbus_call:
- * @client: the #NMClient
- * @object_path: path of remote object
- * @interface_name: D-Bus interface to invoke method on
- * @method_name: the name of the method to invoke
- * @parameters: (nullable): a #GVariant tuple with parameters for the method
- *     or %NULL if not passing parameters
- * @reply_type: (nullable): the expected type of the reply (which will be a
- *     tuple), or %NULL
- * @timeout_msec: the timeout in milliseconds, -1 to use the default
- *     timeout or %G_MAXINT for no timeout
- * @cancellable: (nullable): a #GCancellable or %NULL
- * @callback: (nullable): a #GAsyncReadyCallback to call when the request
- *     is satisfied or %NULL if you don't care about the result of the
- *     method invocation
- * @user_data: the data to pass to @callback
- *
- * Call g_dbus_connection_call() on the current name owner with the specified
- * arguments. Most importantly, this invokes g_dbus_connection_call() with the
- * client's #GMainContext, so that the response is always in order with other
- * events D-Bus events. Of course, the call uses #GTask and will invoke the
- * callback on the current g_main_context_get_thread_default().
- *
- * This API is merely a convenient wrapper for g_dbus_connection_call(). You can
- * also use g_dbus_connection_call() directly, with the same effect.
- *
- * Since: 1.24
- **/
-void
-nm_client_dbus_call(NMClient *          client,
-                    const char *        object_path,
-                    const char *        interface_name,
-                    const char *        method_name,
-                    GVariant *          parameters,
-                    const GVariantType *reply_type,
-                    int                 timeout_msec,
-                    GCancellable *      cancellable,
-                    GAsyncReadyCallback callback,
-                    gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_dbus_call,
-                         cancellable,
-                         callback,
-                         user_data,
-                         object_path,
-                         interface_name,
-                         method_name,
-                         parameters,
-                         reply_type,
-                         G_DBUS_CALL_FLAGS_NONE,
-                         timeout_msec == -1 ? NM_DBUS_DEFAULT_TIMEOUT_MSEC : timeout_msec,
-                         nm_dbus_connection_call_finish_variant_cb);
-}
-
-/**
- * nm_client_dbus_call_finish:
- * @client: the #NMClient instance
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_dbus_call().
- *
- * Returns: (transfer full): the result #GVariant or %NULL on error.
- *
- * Since: 1.24
- **/
-GVariant *
-nm_client_dbus_call_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_dbus_call), FALSE);
-
-    return g_task_propagate_pointer(G_TASK(result), error);
-}
-
-/*****************************************************************************/
-
-/**
- * nm_client_dbus_set_property:
- * @client: the #NMClient
- * @object_path: path of remote object
- * @interface_name: D-Bus interface for the property to set.
- * @property_name: the name of the property to set
- * @value: a #GVariant with the value to set.
- * @timeout_msec: the timeout in milliseconds, -1 to use the default
- *     timeout or %G_MAXINT for no timeout
- * @cancellable: (nullable): a #GCancellable or %NULL
- * @callback: (nullable): a #GAsyncReadyCallback to call when the request
- *     is satisfied or %NULL if you don't care about the result of the
- *     method invocation
- * @user_data: the data to pass to @callback
- *
- * Like nm_client_dbus_call() but calls "Set" on the standard "org.freedesktop.DBus.Properties"
- * D-Bus interface.
- *
- * Since: 1.24
- **/
-void
-nm_client_dbus_set_property(NMClient *          client,
-                            const char *        object_path,
-                            const char *        interface_name,
-                            const char *        property_name,
-                            GVariant *          value,
-                            int                 timeout_msec,
-                            GCancellable *      cancellable,
-                            GAsyncReadyCallback callback,
-                            gpointer            user_data)
-{
-    g_return_if_fail(NM_IS_CLIENT(client));
-    g_return_if_fail(interface_name);
-    g_return_if_fail(property_name);
-    g_return_if_fail(value);
-
-    _nm_client_dbus_call(client,
-                         client,
-                         nm_client_dbus_set_property,
-                         cancellable,
-                         callback,
-                         user_data,
-                         object_path,
-                         DBUS_INTERFACE_PROPERTIES,
-                         "Set",
-                         g_variant_new("(ssv)", interface_name, property_name, value),
-                         G_VARIANT_TYPE("()"),
-                         G_DBUS_CALL_FLAGS_NONE,
-                         timeout_msec == -1 ? NM_DBUS_DEFAULT_TIMEOUT_MSEC : timeout_msec,
-                         nm_dbus_connection_call_finish_void_cb);
-}
-
-/**
- * nm_client_dbus_set_property_finish:
- * @client: the #NMClient instance
- * @result: the result passed to the #GAsyncReadyCallback
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of a call to nm_client_dbus_set_property().
- *
- * Returns: %TRUE on success or %FALSE on failure.
- *
- * Since: 1.24
- **/
-gboolean
-nm_client_dbus_set_property_finish(NMClient *client, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(client), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, client, nm_client_dbus_set_property), FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/*****************************************************************************/
-
-static void
-_init_fetch_all(NMClient *self)
-{
-    NMClientPrivate *        priv                       = NM_CLIENT_GET_PRIVATE(self);
-    nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
-
-    dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context);
-
-    NML_NMCLIENT_LOG_D(self, "fetch all");
-
-    nm_assert(!priv->get_managed_objects_cancellable);
-
-    priv->get_managed_objects_cancellable = g_cancellable_new();
-
-    priv->dbsid_nm_object_manager =
-        nm_dbus_connection_signal_subscribe_object_manager(priv->dbus_connection,
-                                                           priv->name_owner,
-                                                           "/org/freedesktop",
-                                                           NULL,
-                                                           _dbus_managed_objects_changed_cb,
-                                                           self,
-                                                           NULL);
-
-    priv->dbsid_dbus_properties_properties_changed =
-        nm_dbus_connection_signal_subscribe_properties_changed(priv->dbus_connection,
-                                                               priv->name_owner,
-                                                               NULL,
-                                                               NULL,
-                                                               _dbus_properties_changed_cb,
-                                                               self,
-                                                               NULL);
-
-    priv->dbsid_nm_settings_connection_updated =
-        g_dbus_connection_signal_subscribe(priv->dbus_connection,
-                                           priv->name_owner,
-                                           NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
-                                           "Updated",
-                                           NULL,
-                                           NULL,
-                                           G_DBUS_SIGNAL_FLAGS_NONE,
-                                           _dbus_settings_updated_cb,
-                                           self,
-                                           NULL);
-
-    priv->dbsid_nm_connection_active_state_changed =
-        g_dbus_connection_signal_subscribe(priv->dbus_connection,
-                                           priv->name_owner,
-                                           NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
-                                           "StateChanged",
-                                           NULL,
-                                           NULL,
-                                           G_DBUS_SIGNAL_FLAGS_NONE,
-                                           _dbus_nm_connection_active_state_changed_cb,
-                                           self,
-                                           NULL);
-
-    priv->dbsid_nm_vpn_connection_state_changed =
-        g_dbus_connection_signal_subscribe(priv->dbus_connection,
-                                           priv->name_owner,
-                                           NM_DBUS_INTERFACE_VPN_CONNECTION,
-                                           "VpnStateChanged",
-                                           NULL,
-                                           NULL,
-                                           G_DBUS_SIGNAL_FLAGS_NONE,
-                                           _dbus_nm_vpn_connection_state_changed_cb,
-                                           self,
-                                           NULL);
-
-    priv->dbsid_nm_check_permissions =
-        g_dbus_connection_signal_subscribe(priv->dbus_connection,
-                                           priv->name_owner,
-                                           NM_DBUS_INTERFACE,
-                                           "CheckPermissions",
-                                           NULL,
-                                           NULL,
-                                           G_DBUS_SIGNAL_FLAGS_NONE,
-                                           _dbus_nm_check_permissions_cb,
-                                           self,
-                                           NULL);
-
-    g_dbus_connection_call(priv->dbus_connection,
-                           priv->name_owner,
-                           "/org/freedesktop",
-                           DBUS_INTERFACE_OBJECT_MANAGER,
-                           "GetManagedObjects",
-                           NULL,
-                           G_VARIANT_TYPE("(a{oa{sa{sv}}})"),
-                           G_DBUS_CALL_FLAGS_NO_AUTO_START,
-                           NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                           priv->get_managed_objects_cancellable,
-                           _dbus_get_managed_objects_cb,
-                           nm_utils_user_data_pack(self, g_object_ref(priv->context_busy_watcher)));
-
-    _dbus_check_permissions_start(self);
-}
-
-static void
-_init_release_all(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    CList **         dbus_objects_lst_heads;
-    NMLDBusObject *  dbobj;
-    int              i;
-    gboolean         permissions_state_changed = FALSE;
-
-    NML_NMCLIENT_LOG_D(self, "release all");
-
-    nm_clear_g_cancellable(&priv->permissions_cancellable);
-    nm_clear_g_cancellable(&priv->get_managed_objects_cancellable);
-
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->dbsid_nm_object_manager);
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection,
-                                      &priv->dbsid_dbus_properties_properties_changed);
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection,
-                                      &priv->dbsid_nm_settings_connection_updated);
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection,
-                                      &priv->dbsid_nm_connection_active_state_changed);
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection,
-                                      &priv->dbsid_nm_vpn_connection_state_changed);
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->dbsid_nm_check_permissions);
-
-    if (priv->permissions_state != NM_TERNARY_DEFAULT) {
-        priv->permissions_state   = NM_TERNARY_DEFAULT;
-        permissions_state_changed = TRUE;
-    }
-
-    if (priv->permissions) {
-        gs_free guint8 *old_permissions = g_steal_pointer(&priv->permissions);
-
-        _emit_permissions_changed(self, old_permissions, NULL);
-    }
-
-    if (permissions_state_changed)
-        _notify(self, PROP_PERMISSIONS_STATE);
-
-    nm_assert(c_list_is_empty(&priv->obj_changed_lst_head));
-
-    dbus_objects_lst_heads = ((CList *[]){
-        &priv->dbus_objects_lst_head_on_dbus,
-        &priv->dbus_objects_lst_head_with_nmobj_not_ready,
-        &priv->dbus_objects_lst_head_with_nmobj_ready,
-        NULL,
-    });
-    for (i = 0; dbus_objects_lst_heads[i]; i++) {
-        c_list_for_each_entry (dbobj, dbus_objects_lst_heads[i], dbus_objects_lst) {
-            NMLDBusObjIfaceData *db_iface_data;
-
-            nm_assert(c_list_is_empty(&dbobj->obj_changed_lst));
-            c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst)
-                db_iface_data->iface_removed = TRUE;
-            nml_dbus_object_obj_changed_link(self, dbobj, NML_DBUS_OBJ_CHANGED_TYPE_DBUS);
-        }
-    }
-
-    _dbus_handle_changes(self, "release-all", FALSE);
-
-    /* We require that when we remove all D-Bus interfaces, that all object will go
-     * away. Note that a NMLDBusObject can be alive due to a NMLDBusObjWatcher, but
-     * even those should be all cleaned up. */
-    nm_assert(c_list_is_empty(&priv->obj_changed_lst_head));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_watched_only));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_on_dbus));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_not_ready));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_ready));
-    nm_assert(nm_g_hash_table_size(priv->dbus_objects) == 0);
-}
-
-/*****************************************************************************/
-
-static void
-name_owner_changed(NMClient *self, const char *name_owner)
-{
-    NMClientPrivate *        priv = NM_CLIENT_GET_PRIVATE(self);
-    gboolean                 changed;
-    gs_free char *           old_name_owner_free = NULL;
-    const char *             old_name_owner;
-    nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
-
-    name_owner = nm_str_not_empty(name_owner);
-
-    changed = !nm_streq0(priv->name_owner, name_owner);
-
-    if (!name_owner && priv->main_context != priv->dbus_context) {
-        gs_unref_object GObject *old_context_busy_watcher = NULL;
-
-        NML_NMCLIENT_LOG_D(self, "resync main context as we have no name owner");
-
-        nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id);
-
-        /* Our instance was initialized synchronously. Usually we must henceforth
-         * stick to a internal main context. But now we have no name-owner...
-         * at this point, we anyway are going to do a full resync. Swap the main
-         * contexts again. */
-
-        old_context_busy_watcher   = g_steal_pointer(&priv->context_busy_watcher);
-        priv->context_busy_watcher = g_object_ref(
-            g_object_get_qdata(old_context_busy_watcher, nm_context_busy_watcher_quark()));
-
-        g_main_context_ref(priv->main_context);
-        g_main_context_unref(priv->dbus_context);
-        priv->dbus_context = priv->main_context;
-
-        dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context);
-
-        /* we need to sync again... */
-
-        _assert_main_context_is_current_thread_default(self, dbus_context);
-
-        priv->name_owner_changed_id =
-            nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection,
-                                                                   NM_DBUS_SERVICE,
-                                                                   name_owner_changed_cb,
-                                                                   self,
-                                                                   NULL);
-        name_owner_get_call(self);
-    } else
-        dbus_context = nm_g_main_context_push_thread_default_if_necessary(priv->dbus_context);
-
-    if (changed) {
-        NML_NMCLIENT_LOG_D(self,
-                           "name owner changed: %s%s%s -> %s%s%s",
-                           NM_PRINT_FMT_QUOTE_STRING(priv->name_owner),
-                           NM_PRINT_FMT_QUOTE_STRING(name_owner));
-        old_name_owner_free = priv->name_owner;
-        priv->name_owner    = g_strdup(name_owner);
-        old_name_owner      = old_name_owner_free;
-    } else
-        old_name_owner = priv->name_owner;
-
-    if (changed)
-        _notify(self, PROP_DBUS_NAME_OWNER);
-
-    if (changed && old_name_owner)
-        _init_release_all(self);
-
-    if (changed && priv->name_owner)
-        _init_fetch_all(self);
-
-    _set_nm_running(self);
-
-    if (priv->init_data) {
-        nm_auto_pop_gmaincontext GMainContext *main_context = NULL;
-
-        if (priv->main_context != priv->dbus_context)
-            main_context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context);
-        _init_start_check_complete(self);
-    }
-}
-
-static void
-name_owner_changed_cb(GDBusConnection *connection,
-                      const char *     sender_name,
-                      const char *     object_path,
-                      const char *     interface_name,
-                      const char *     signal_name,
-                      GVariant *       parameters,
-                      gpointer         user_data)
-{
-    NMClient *       self = user_data;
-    NMClientPrivate *priv;
-    const char *     new_owner;
-
-    if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)")))
-        return;
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-    if (priv->name_owner_get_cancellable)
-        return;
-
-    g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner);
-
-    name_owner_changed(self, new_owner);
-}
-
-static void
-name_owner_get_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMClient *       self;
-    NMClientPrivate *priv;
-    gs_unref_object GObject *context_busy_watcher = NULL;
-    gs_unref_variant GVariant *ret                = NULL;
-    gs_free_error GError *error                   = NULL;
-    const char *          name_owner              = NULL;
-
-    nm_utils_user_data_unpack(user_data, &self, &context_busy_watcher);
-
-    ret = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
-
-    if (!ret && nm_utils_error_is_cancelled(error))
-        return;
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    g_clear_object(&priv->name_owner_get_cancellable);
-
-    if (ret)
-        g_variant_get(ret, "(&s)", &name_owner);
-
-    name_owner_changed(self, name_owner);
-}
-
-static void
-name_owner_get_call(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    nm_assert(!priv->name_owner_get_cancellable);
-    priv->name_owner_get_cancellable = g_cancellable_new();
-
-    g_dbus_connection_call(priv->dbus_connection,
-                           DBUS_SERVICE_DBUS,
-                           DBUS_PATH_DBUS,
-                           DBUS_INTERFACE_DBUS,
-                           "GetNameOwner",
-                           g_variant_new("(s)", NM_DBUS_SERVICE),
-                           G_VARIANT_TYPE("(s)"),
-                           G_DBUS_CALL_FLAGS_NONE,
-                           NM_DBUS_DEFAULT_TIMEOUT_MSEC,
-                           priv->name_owner_get_cancellable,
-                           name_owner_get_cb,
-                           nm_utils_user_data_pack(self, g_object_ref(priv->context_busy_watcher)));
-}
-
-/*****************************************************************************/
-
-static inline gboolean
-_nml_cleanup_context_busy_watcher_on_idle_cb(gpointer user_data)
-{
-    nm_auto_unref_gmaincontext GMainContext *context = NULL;
-    gs_unref_object GObject *context_busy_watcher    = NULL;
-
-    nm_utils_user_data_unpack(user_data, &context, &context_busy_watcher);
-
-    nm_assert(context);
-    nm_assert(G_IS_OBJECT(context_busy_watcher));
-    return G_SOURCE_REMOVE;
-}
-
-void
-nml_cleanup_context_busy_watcher_on_idle(GObject *context_busy_watcher_take, GMainContext *context)
-{
-    gs_unref_object GObject *context_busy_watcher = g_steal_pointer(&context_busy_watcher_take);
-    GSource *                cleanup_source;
-
-    nm_assert(G_IS_OBJECT(context_busy_watcher));
-    nm_assert(context);
-
-    /* Technically, we cancelled all pending actions (and these actions
-     * (GTask) keep the context_busy_watcher object alive). Also, we passed
-     * no destroy notify to g_dbus_connection_signal_subscribe().
-     * That means, there should be no other unaccounted GSource'es left.
-     *
-     * However, we really need to be sure that the context_busy_watcher's
-     * lifetime matches the time that the context is busy. That is especially
-     * important with synchronous initialization, where the context-busy-watcher
-     * keeps the inner GMainContext integrated in the caller's.
-     * We must not g_source_destroy() that integration too early.
-     *
-     * So to be really sure all this is given, always schedule one last
-     * cleanup idle action with low priority. This should be the last
-     * thing related to this instance that keeps the context busy.
-     *
-     * Note that we could also *not* take a reference on @context
-     * and unref @context_busy_watcher via the GDestroyNotify. That would
-     * allow for the context to be wrapped up early, and when the last user
-     * gives up the reference to the context, the destroy notify could complete
-     * without even invoke the idle handler. However, that destroy notify may
-     * not be called in the right thread. So, we want to be sure that we unref
-     * the context-busy-watcher in the right context. Hence, we always take an
-     * additional reference and always cleanup in the idle handler. This means:
-     * the user *MUST* always keep iterating the context after NMClient got destroyed.
-     * But that is not a severe limitation, because the user anyway must be prepared
-     * to do that. That is because in many cases it is necessary anyway (and the user
-     * wouldn't know a priory when not). This way, it is just always necessary. */
-
-    cleanup_source =
-        nm_g_idle_source_new(G_PRIORITY_LOW + 10,
-                             _nml_cleanup_context_busy_watcher_on_idle_cb,
-                             nm_utils_user_data_pack(g_main_context_ref(context),
-                                                     g_steal_pointer(&context_busy_watcher)),
-                             NULL);
-    g_source_attach(cleanup_source, context);
-    g_source_unref(cleanup_source);
-}
-
-/*****************************************************************************/
-
-static void
-_init_start_complete(NMClient *self, GError *error_take)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    NML_NMCLIENT_LOG_D(
-        self,
-        "%s init complete with %s%s%s",
-        priv->init_data->is_sync ? "sync" : "async",
-        NM_PRINT_FMT_QUOTED(error_take, "error: ", error_take->message, "", "success"));
-
-    nml_init_data_return(g_steal_pointer(&priv->init_data), error_take);
-}
-
-static void
-_init_start_check_complete(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    _assert_main_context_is_current_thread_default(self, main_context);
-
-    if (!priv->init_data)
-        return;
-
-    if (priv->get_managed_objects_cancellable) {
-        /* still initializing. Wait. */
-        return;
-    }
-
-#if NM_MORE_ASSERTS > 10
-    {
-        NMLDBusObject *dbobj;
-
-        c_list_for_each_entry (dbobj,
-                               &priv->dbus_objects_lst_head_with_nmobj_not_ready,
-                               dbus_objects_lst) {
-            NML_NMCLIENT_LOG_T(self, "init-start waiting for %s", dbobj->dbus_path->str);
-            break;
-        }
-    }
-#endif
-
-    if (!c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_not_ready))
-        return;
-
-    _init_start_complete(self, NULL);
-}
-
-static void
-_init_start_cancelled_cb(GCancellable *cancellable, gpointer user_data)
-{
-    NMClient *self = user_data;
-    GError *  error;
-
-    nm_assert(NM_IS_CLIENT(self));
-    nm_assert(NM_CLIENT_GET_PRIVATE(self)->init_data);
-    nm_assert(NM_CLIENT_GET_PRIVATE(self)->init_data->cancellable == cancellable);
-
-    nm_utils_error_set_cancelled(&error, FALSE, NULL);
-    _init_start_complete(self, error);
-}
-
-static gboolean
-_init_start_cancel_on_idle_cb(gpointer user_data)
-{
-    NMClient *self = user_data;
-    GError *  error;
-
-    nm_utils_error_set_cancelled(&error, FALSE, NULL);
-    _init_start_complete(self, error);
-    return G_SOURCE_CONTINUE;
-}
-
-static void
-_init_start_with_bus(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    if (priv->init_data->cancellable) {
-        priv->init_data->cancelled_id = g_signal_connect(priv->init_data->cancellable,
-                                                         "cancelled",
-                                                         G_CALLBACK(_init_start_cancelled_cb),
-                                                         self);
-        if (g_cancellable_is_cancelled(priv->init_data->cancellable)) {
-            priv->init_data->cancel_on_idle_source = g_idle_source_new();
-            g_source_set_callback(priv->init_data->cancel_on_idle_source,
-                                  _init_start_cancel_on_idle_cb,
-                                  self,
-                                  NULL);
-            g_source_attach(priv->init_data->cancel_on_idle_source, priv->main_context);
-            return;
-        }
-    }
-
-    _assert_main_context_is_current_thread_default(self, dbus_context);
-
-    priv->name_owner_changed_id =
-        nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection,
-                                                               NM_DBUS_SERVICE,
-                                                               name_owner_changed_cb,
-                                                               self,
-                                                               NULL);
-    name_owner_get_call(self);
-}
-
-static void
-_init_start_bus_get_cb(GObject *source, GAsyncResult *result, gpointer user_data)
-{
-    NMClient *       self = user_data;
-    NMClientPrivate *priv;
-    GDBusConnection *dbus_connection;
-    GError *         error = NULL;
-
-    nm_assert(NM_IS_CLIENT(self));
-
-    dbus_connection = g_bus_get_finish(result, &error);
-
-    if (!dbus_connection) {
-        _init_start_complete(self, error);
-        return;
-    }
-
-    priv                  = NM_CLIENT_GET_PRIVATE(self);
-    priv->dbus_connection = dbus_connection;
-
-    _init_start_with_bus(self);
-
-    _notify(self, PROP_DBUS_CONNECTION);
-}
-
-static void
-_init_start(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    NML_NMCLIENT_LOG_D(self,
-                       "starting %s initialization...",
-                       priv->init_data->is_sync ? "sync" : "async");
-
-    if (!priv->dbus_connection) {
-        g_bus_get(_nm_dbus_bus_type(), priv->init_data->cancellable, _init_start_bus_get_cb, self);
-        return;
-    }
-
-    _init_start_with_bus(self);
-}
-
-/*****************************************************************************/
-
-static void
-get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
-    NMClient *       self = NM_CLIENT(object);
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(object);
-
-    switch (prop_id) {
-    case PROP_INSTANCE_FLAGS:
-        g_value_set_uint(value, priv->instance_flags);
-        break;
-    case PROP_DBUS_CONNECTION:
-        g_value_set_object(value, priv->dbus_connection);
-        break;
-    case PROP_DBUS_NAME_OWNER:
-        g_value_set_string(value, nm_client_get_dbus_name_owner(self));
-        break;
-    case PROP_NM_RUNNING:
-        g_value_set_boolean(value, nm_client_get_nm_running(self));
-        break;
-
-    /* Manager properties. */
-    case PROP_VERSION:
-        g_value_set_string(value, nm_client_get_version(self));
-        break;
-    case PROP_STATE:
-        g_value_set_enum(value, nm_client_get_state(self));
-        break;
-    case PROP_STARTUP:
-        g_value_set_boolean(value, nm_client_get_startup(self));
-        break;
-    case PROP_NETWORKING_ENABLED:
-        g_value_set_boolean(value, nm_client_networking_get_enabled(self));
-        break;
-    case PROP_WIRELESS_ENABLED:
-        g_value_set_boolean(value, nm_client_wireless_get_enabled(self));
-        break;
-    case PROP_WIRELESS_HARDWARE_ENABLED:
-        g_value_set_boolean(value, nm_client_wireless_hardware_get_enabled(self));
-        break;
-    case PROP_WWAN_ENABLED:
-        g_value_set_boolean(value, nm_client_wwan_get_enabled(self));
-        break;
-    case PROP_WWAN_HARDWARE_ENABLED:
-        g_value_set_boolean(value, nm_client_wwan_hardware_get_enabled(self));
-        break;
-    case PROP_WIMAX_ENABLED:
-        g_value_set_boolean(value, FALSE);
-        break;
-    case PROP_WIMAX_HARDWARE_ENABLED:
-        g_value_set_boolean(value, FALSE);
-        break;
-    case PROP_ACTIVE_CONNECTIONS:
-        g_value_take_boxed(value,
-                           _nm_utils_copy_object_array(nm_client_get_active_connections(self)));
-        break;
-    case PROP_CONNECTIVITY:
-        g_value_set_enum(value, nm_client_get_connectivity(self));
-        break;
-    case PROP_CONNECTIVITY_CHECK_AVAILABLE:
-        g_value_set_boolean(value, nm_client_connectivity_check_get_available(self));
-        break;
-    case PROP_CONNECTIVITY_CHECK_ENABLED:
-        g_value_set_boolean(value, nm_client_connectivity_check_get_enabled(self));
-        break;
-    case PROP_CONNECTIVITY_CHECK_URI:
-        g_value_set_string(value, nm_client_connectivity_check_get_uri(self));
-        break;
-    case PROP_PRIMARY_CONNECTION:
-        g_value_set_object(value, nm_client_get_primary_connection(self));
-        break;
-    case PROP_ACTIVATING_CONNECTION:
-        g_value_set_object(value, nm_client_get_activating_connection(self));
-        break;
-    case PROP_DEVICES:
-        g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_devices(self)));
-        break;
-    case PROP_METERED:
-        g_value_set_uint(value, nm_client_get_metered(self));
-        break;
-    case PROP_ALL_DEVICES:
-        g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_all_devices(self)));
-        break;
-    case PROP_CHECKPOINTS:
-        g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_checkpoints(self)));
-        break;
-    case PROP_CAPABILITIES:
-    {
-        const guint32 *arr;
-        GArray *       out;
-        gsize          len;
-
-        arr = nm_client_get_capabilities(self, &len);
-        if (arr) {
-            out = g_array_new(TRUE, FALSE, sizeof(guint32));
-            g_array_append_vals(out, arr, len);
-        } else
-            out = NULL;
-        g_value_take_boxed(value, out);
-    } break;
-    case PROP_PERMISSIONS_STATE:
-        g_value_set_enum(value, priv->permissions_state);
-        break;
-
-    /* Settings properties. */
-    case PROP_CONNECTIONS:
-        g_value_take_boxed(value, _nm_utils_copy_object_array(nm_client_get_connections(self)));
-        break;
-    case PROP_HOSTNAME:
-        g_value_set_string(value, priv->settings.hostname);
-        break;
-    case PROP_CAN_MODIFY:
-        g_value_set_boolean(value, priv->settings.can_modify);
-        break;
-
-    /* DNS properties */
-    case PROP_DNS_MODE:
-        g_value_set_string(value, nm_client_get_dns_mode(self));
-        break;
-    case PROP_DNS_RC_MANAGER:
-        g_value_set_string(value, nm_client_get_dns_rc_manager(self));
-        break;
-    case PROP_DNS_CONFIGURATION:
-        g_value_take_boxed(value,
-                           _nm_utils_copy_array(nm_client_get_dns_configuration(self),
-                                                (NMUtilsCopyFunc) nm_dns_entry_dup,
-                                                (GDestroyNotify) nm_dns_entry_unref));
-        break;
-
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
-    NMClient *       self = NM_CLIENT(object);
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-    gboolean         b;
-    guint            v_uint;
-
-    switch (prop_id) {
-    case PROP_INSTANCE_FLAGS:
-        /* construct */
-
-        v_uint = g_value_get_uint(value);
-        g_return_if_fail(!NM_FLAGS_ANY(v_uint, ~((guint) NM_CLIENT_INSTANCE_FLAGS_ALL)));
-        v_uint &= ((guint) NM_CLIENT_INSTANCE_FLAGS_ALL);
-
-        if (!priv->instance_flags_constructed) {
-            priv->instance_flags_constructed = TRUE;
-            priv->instance_flags             = v_uint;
-            nm_assert((guint) priv->instance_flags == v_uint);
-        } else {
-            NMClientInstanceFlags flags = v_uint;
-
-            /* After object construction, we only allow to toggle certain flags and
-             * ignore all other flags. */
-
-            if ((priv->instance_flags ^ flags)
-                & NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS) {
-                if (NM_FLAGS_HAS(flags, NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS))
-                    priv->instance_flags |= NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS;
-                else
-                    priv->instance_flags &= ~NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS;
-                if (priv->dbsid_nm_check_permissions != 0)
-                    _dbus_check_permissions_start(self);
-            }
-        }
-        break;
-
-    case PROP_DBUS_CONNECTION:
-        /* construct-only */
-        priv->dbus_connection = g_value_dup_object(value);
-        break;
-
-    case PROP_NETWORKING_ENABLED:
-        b = g_value_get_boolean(value);
-        if (priv->nm.networking_enabled != b) {
-            nm_client_networking_set_enabled(self, b, NULL);
-            /* Let the property value flip when we get the change signal from NM */
-        }
-        break;
-    case PROP_WIRELESS_ENABLED:
-        b = g_value_get_boolean(value);
-        if (priv->nm.wireless_enabled != b) {
-            nm_client_wireless_set_enabled(self, b);
-            /* Let the property value flip when we get the change signal from NM */
-        }
-        break;
-    case PROP_WWAN_ENABLED:
-        b = g_value_get_boolean(value);
-        if (priv->nm.wwan_enabled != b) {
-            nm_client_wwan_set_enabled(self, b);
-            /* Let the property value flip when we get the change signal from NM */
-        }
-        break;
-    case PROP_CONNECTIVITY_CHECK_ENABLED:
-        b = g_value_get_boolean(value);
-        if (priv->nm.connectivity_check_enabled != b) {
-            nm_client_connectivity_check_set_enabled(self, b);
-            /* Let the property value flip when we get the change signal from NM */
-        }
-        break;
-    case PROP_WIMAX_ENABLED:
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-/*****************************************************************************/
-
-static gboolean
-init_sync(GInitable *initable, GCancellable *cancellable, GError **error)
-{
-    gs_unref_object NMClient *self = NULL;
-    NMClientPrivate *         priv;
-    GMainContext *            dbus_context;
-    GError *                  local_error = NULL;
-    GMainLoop *               main_loop;
-    GObject *                 parent_context_busy_watcher;
-
-    g_return_val_if_fail(NM_IS_CLIENT(initable), FALSE);
-
-    self = g_object_ref(NM_CLIENT(initable)); /* keep instance alive. */
-
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    g_return_val_if_fail(!priv->dbus_context, FALSE);
-
-    /* when using init_sync(), we use a separate internal GMainContext for
-     * all D-Bus operations and use our regular async-init code. That means,
-     * also in sync-init, we don't actually block waiting for our D-Bus requests,
-     * instead, we only block (g_main_loop_run()) for the overall result.
-     *
-     * Doing this has a performance overhead. Also, we cannot ever fall back
-     * to the regular main-context (not unless we lose the main-owner and
-     * need to re-initialize). The reason is that we receive events on our
-     * dbus_context, and this cannot be brought in sync -- short of full
-     * reinitalizing. Therefor, using sync init not only is slower during
-     * construction of the object, but NMClient will stick to the dual GMainContext
-     * mode.
-     *
-     * Aside from this downside, the solution is good:
-     *
-     * - we don't duplicate the implementation of async-init.
-     * - we don't iterate the main-context of the caller while waiting for
-     *   initialization to happen
-     * - we still invoke all changes under the main_context of the caller.
-     * - all D-Bus events strictly go through dbus_context and are in order.
-     */
-
-    dbus_context       = g_main_context_new();
-    priv->dbus_context = g_main_context_ref(dbus_context);
-
-    /* We have an inner context. Note that if we loose the name owner, we have a chance
-     * to resync and drop the inner context. That means, requests made against the inner
-     * context have a different lifetime. Hence, we create a separate tracking
-     * object. This "wraps" the outer context-busy-watcher and references it, so
-     * that the work together. Grep for nm_context_busy_watcher_quark() to
-     * see how this works. */
-    parent_context_busy_watcher = g_steal_pointer(&priv->context_busy_watcher);
-    priv->context_busy_watcher  = g_object_new(G_TYPE_OBJECT, NULL);
-    g_object_set_qdata_full(priv->context_busy_watcher,
-                            nm_context_busy_watcher_quark(),
-                            parent_context_busy_watcher,
-                            g_object_unref);
-
-    g_main_context_push_thread_default(dbus_context);
-
-    main_loop = g_main_loop_new(dbus_context, FALSE);
-
-    priv->init_data = nml_init_data_new_sync(cancellable, main_loop, &local_error);
-
-    _init_start(self);
-
-    g_main_loop_run(main_loop);
-
-    g_main_loop_unref(main_loop);
-
-    g_main_context_pop_thread_default(dbus_context);
-
-    if (priv->main_context != priv->dbus_context) {
-        nm_context_busy_watcher_integrate_source(priv->main_context,
-                                                 priv->dbus_context,
-                                                 priv->context_busy_watcher);
-    }
-
-    g_main_context_unref(dbus_context);
-
-    if (local_error) {
-        g_propagate_error(error, local_error);
-        return FALSE;
-    }
-    return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-init_async(GAsyncInitable *    initable,
-           int                 io_priority,
-           GCancellable *      cancellable,
-           GAsyncReadyCallback callback,
-           gpointer            user_data)
-{
-    NMClientPrivate *        priv;
-    NMClient *               self;
-    nm_auto_pop_gmaincontext GMainContext *context = NULL;
-    GTask *                                task;
-
-    g_return_if_fail(NM_IS_CLIENT(initable));
-
-    self = NM_CLIENT(initable);
-    priv = NM_CLIENT_GET_PRIVATE(self);
-
-    g_return_if_fail(!priv->dbus_context);
-
-    priv->dbus_context = g_main_context_ref(priv->main_context);
-
-    context = nm_g_main_context_push_thread_default_if_necessary(priv->main_context);
-
-    task = nm_g_task_new(self, cancellable, init_async, callback, user_data);
-    g_task_set_priority(task, io_priority);
-
-    priv->init_data = nml_init_data_new_async(cancellable, g_steal_pointer(&task));
-
-    _init_start(self);
-}
-
-static gboolean
-init_finish(GAsyncInitable *initable, GAsyncResult *result, GError **error)
-{
-    g_return_val_if_fail(NM_IS_CLIENT(initable), FALSE);
-    g_return_val_if_fail(nm_g_task_is_valid(result, initable, init_async), FALSE);
-
-    return g_task_propagate_boolean(G_TASK(result), error);
-}
-
-/*****************************************************************************/
-
-static void
-nm_client_init(NMClient *self)
-{
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    priv->permissions_state = NM_TERNARY_DEFAULT;
-
-    priv->context_busy_watcher = g_object_new(G_TYPE_OBJECT, NULL);
-
-    c_list_init(&self->obj_base.queue_notify_lst);
-    c_list_init(&priv->queue_notify_lst_head);
-    c_list_init(&priv->notify_event_lst_head);
-
-    priv->dbus_objects = g_hash_table_new(nm_pdirect_hash, nm_pdirect_equal);
-    c_list_init(&priv->dbus_objects_lst_head_watched_only);
-    c_list_init(&priv->dbus_objects_lst_head_on_dbus);
-    c_list_init(&priv->dbus_objects_lst_head_with_nmobj_not_ready);
-    c_list_init(&priv->dbus_objects_lst_head_with_nmobj_ready);
-    c_list_init(&priv->obj_changed_lst_head);
-}
-
-/**
- * nm_client_new:
- * @cancellable: a #GCancellable, or %NULL
- * @error: location for a #GError, or %NULL
- *
- * Creates a new #NMClient.
- *
- * Note that this will do blocking D-Bus calls to initialize the
- * client. You can use nm_client_new_async() if you want to avoid
- * that.
- *
- * Returns: a new #NMClient or NULL on an error
- **/
-NMClient *
-nm_client_new(GCancellable *cancellable, GError **error)
-{
-    return g_initable_new(NM_TYPE_CLIENT, cancellable, error, NULL);
-}
-
-/**
- * nm_client_new_async:
- * @cancellable: a #GCancellable, or %NULL
- * @callback: callback to call when the client is created
- * @user_data: data for @callback
- *
- * Creates a new #NMClient and begins asynchronously initializing it.
- * @callback will be called when it is done; use
- * nm_client_new_finish() to get the result. Note that on an error,
- * the callback can be invoked with two first parameters as NULL.
- **/
-void
-nm_client_new_async(GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
-{
-    g_async_initable_new_async(NM_TYPE_CLIENT,
-                               G_PRIORITY_DEFAULT,
-                               cancellable,
-                               callback,
-                               user_data,
-                               NULL);
-}
-
-/**
- * nm_client_new_finish:
- * @result: a #GAsyncResult
- * @error: location for a #GError, or %NULL
- *
- * Gets the result of an nm_client_new_async() call.
- *
- * Returns: a new #NMClient, or %NULL on error
- **/
-NMClient *
-nm_client_new_finish(GAsyncResult *result, GError **error)
-{
-    gs_unref_object GObject *source_object = NULL;
-    GObject *                object;
-
-    source_object = g_async_result_get_source_object(result);
-    g_return_val_if_fail(source_object, NULL);
-
-    object = g_async_initable_new_finish(G_ASYNC_INITABLE(source_object), result, error);
-    g_return_val_if_fail(!object || NM_IS_CLIENT(object), FALSE);
-
-    return NM_CLIENT(object);
-}
-
-static void
-constructed(GObject *object)
-{
-    NMClient *       self = NM_CLIENT(object);
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    priv->main_context = g_main_context_ref_thread_default();
-
-    G_OBJECT_CLASS(nm_client_parent_class)->constructed(object);
-
-    NML_NMCLIENT_LOG_D(self, "new NMClient instance");
-}
-
-static void
-dispose(GObject *object)
-{
-    NMClient *       self = NM_CLIENT(object);
-    NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self);
-
-    nm_assert(!priv->init_data);
-
-    self->obj_base.is_disposing = TRUE;
-
-    nm_clear_g_cancellable(&priv->name_owner_get_cancellable);
-
-    nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id);
-
-    nm_clear_g_free(&priv->name_owner);
-
-    _init_release_all(self);
-
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_watched_only));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_on_dbus));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_not_ready));
-    nm_assert(c_list_is_empty(&priv->dbus_objects_lst_head_with_nmobj_ready));
-
-    nm_assert(c_list_is_empty(&priv->queue_notify_lst_head));
-    nm_assert(c_list_is_empty(&priv->notify_event_lst_head));
-    nm_assert(c_list_is_empty(&self->obj_base.queue_notify_lst));
-    nm_assert(nm_g_hash_table_size(priv->dbus_objects) == 0);
-
-    nml_dbus_property_o_clear_many(priv->nm.property_o, G_N_ELEMENTS(priv->nm.property_o), NULL);
-    nml_dbus_property_ao_clear_many(priv->nm.property_ao, G_N_ELEMENTS(priv->nm.property_ao), NULL);
-
-    nm_clear_g_free(&priv->nm.connectivity_check_uri);
-    nm_clear_g_free(&priv->nm.version);
-
-    nml_dbus_property_ao_clear(&priv->settings.connections, NULL);
-    nm_clear_g_free(&priv->settings.hostname);
-
-    nm_clear_pointer(&priv->dns_manager.configuration, g_ptr_array_unref);
-    nm_clear_g_free(&priv->dns_manager.mode);
-    nm_clear_g_free(&priv->dns_manager.rc_manager);
-
-    nm_clear_pointer(&priv->dbus_objects, g_hash_table_destroy);
-
-    G_OBJECT_CLASS(nm_client_parent_class)->dispose(object);
-
-    nm_clear_pointer(&priv->udev, udev_unref);
-
-    if (priv->context_busy_watcher && priv->dbus_context) {
-        nml_cleanup_context_busy_watcher_on_idle(g_steal_pointer(&priv->context_busy_watcher),
-                                                 priv->dbus_context);
-    }
-
-    nm_clear_pointer(&priv->dbus_context, g_main_context_unref);
-    nm_clear_pointer(&priv->main_context, g_main_context_unref);
-
-    nm_clear_g_free(&priv->permissions);
-
-    g_clear_object(&priv->dbus_connection);
-
-    g_clear_object(&priv->context_busy_watcher);
-
-    nm_clear_g_free(&priv->name_owner);
-
-    priv->nm.capabilities_len = 0;
-    nm_clear_g_free(&priv->nm.capabilities_arr);
-
-    NML_NMCLIENT_LOG_D(self, "disposed");
-}
-
-const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager =
-    NML_DBUS_META_IFACE_INIT(NM_DBUS_INTERFACE_AGENT_MANAGER,
-                             NULL,
-                             NML_DBUS_META_INTERFACE_PRIO_NONE, );
-
-const NMLDBusMetaIface _nml_dbus_meta_iface_nm = NML_DBUS_META_IFACE_INIT_PROP(
-    NM_DBUS_INTERFACE,
-    nm_client_get_type,
-    NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
-    NML_DBUS_META_IFACE_DBUS_PROPERTIES(
-        NML_DBUS_META_PROPERTY_INIT_O_PROP(
-            "ActivatingConnection",
-            PROP_ACTIVATING_CONNECTION,
-            NMClient,
-            _priv.nm.property_o[PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION],
-            nm_active_connection_get_type),
-        NML_DBUS_META_PROPERTY_INIT_AO_PROP(
-            "ActiveConnections",
-            PROP_ACTIVE_CONNECTIONS,
-            NMClient,
-            _priv.nm.property_ao[PROPERTY_AO_IDX_ACTIVE_CONNECTIONS],
-            nm_active_connection_get_type,
-            .notify_changed_ao = _property_ao_notify_changed_active_connections_cb),
-        NML_DBUS_META_PROPERTY_INIT_AO_PROP("AllDevices",
-                                            PROP_ALL_DEVICES,
-                                            NMClient,
-                                            _priv.nm.property_ao[PROPERTY_AO_IDX_ALL_DEVICES],
-                                            nm_device_get_type,
-                                            .notify_changed_ao =
-                                                _property_ao_notify_changed_all_devices_cb),
-        NML_DBUS_META_PROPERTY_INIT_FCN("Capabilities",
-                                        PROP_CAPABILITIES,
-                                        "au",
-                                        _notify_update_prop_nm_capabilities, ),
-        NML_DBUS_META_PROPERTY_INIT_AO_PROP("Checkpoints",
-                                            PROP_CHECKPOINTS,
-                                            NMClient,
-                                            _priv.nm.property_ao[PROPERTY_AO_IDX_CHECKPOINTS],
-                                            nm_checkpoint_get_type),
-        NML_DBUS_META_PROPERTY_INIT_U("Connectivity",
-                                      PROP_CONNECTIVITY,
-                                      NMClient,
-                                      _priv.nm.connectivity),
-        NML_DBUS_META_PROPERTY_INIT_B("ConnectivityCheckAvailable",
-                                      PROP_CONNECTIVITY_CHECK_AVAILABLE,
-                                      NMClient,
-                                      _priv.nm.connectivity_check_available),
-        NML_DBUS_META_PROPERTY_INIT_B("ConnectivityCheckEnabled",
-                                      PROP_CONNECTIVITY_CHECK_ENABLED,
-                                      NMClient,
-                                      _priv.nm.connectivity_check_enabled),
-        NML_DBUS_META_PROPERTY_INIT_S("ConnectivityCheckUri",
-                                      PROP_CONNECTIVITY_CHECK_URI,
-                                      NMClient,
-                                      _priv.nm.connectivity_check_uri),
-        NML_DBUS_META_PROPERTY_INIT_AO_PROP("Devices",
-                                            PROP_DEVICES,
-                                            NMClient,
-                                            _priv.nm.property_ao[PROPERTY_AO_IDX_DEVICES],
-                                            nm_device_get_type,
-                                            .notify_changed_ao =
-                                                _property_ao_notify_changed_devices_cb),
-        NML_DBUS_META_PROPERTY_INIT_IGNORE("GlobalDnsConfiguration", "a{sv}"),
-        NML_DBUS_META_PROPERTY_INIT_U("Metered", PROP_METERED, NMClient, _priv.nm.metered),
-        NML_DBUS_META_PROPERTY_INIT_B("NetworkingEnabled",
-                                      PROP_NETWORKING_ENABLED,
-                                      NMClient,
-                                      _priv.nm.networking_enabled),
-        NML_DBUS_META_PROPERTY_INIT_O_PROP("PrimaryConnection",
-                                           PROP_PRIMARY_CONNECTION,
-                                           NMClient,
-                                           _priv.nm.property_o[PROPERTY_O_IDX_NM_PRIMAY_CONNECTION],
-                                           nm_active_connection_get_type),
-        NML_DBUS_META_PROPERTY_INIT_IGNORE("PrimaryConnectionType", "s"),
-        NML_DBUS_META_PROPERTY_INIT_B("Startup", PROP_STARTUP, NMClient, _priv.nm.startup),
-        NML_DBUS_META_PROPERTY_INIT_U("State", PROP_STATE, NMClient, _priv.nm.state),
-        NML_DBUS_META_PROPERTY_INIT_S("Version", PROP_VERSION, NMClient, _priv.nm.version),
-        NML_DBUS_META_PROPERTY_INIT_IGNORE("WimaxEnabled", "b"),
-        NML_DBUS_META_PROPERTY_INIT_IGNORE("WimaxHardwareEnabled", "b"),
-        NML_DBUS_META_PROPERTY_INIT_B("WirelessEnabled",
-                                      PROP_WIRELESS_ENABLED,
-                                      NMClient,
-                                      _priv.nm.wireless_enabled),
-        NML_DBUS_META_PROPERTY_INIT_B("WirelessHardwareEnabled",
-                                      PROP_WIRELESS_HARDWARE_ENABLED,
-                                      NMClient,
-                                      _priv.nm.wireless_hardware_enabled),
-        NML_DBUS_META_PROPERTY_INIT_B("WwanEnabled",
-                                      PROP_WWAN_ENABLED,
-                                      NMClient,
-                                      _priv.nm.wwan_enabled),
-        NML_DBUS_META_PROPERTY_INIT_B("WwanHardwareEnabled",
-                                      PROP_WWAN_HARDWARE_ENABLED,
-                                      NMClient,
-                                      _priv.nm.wwan_hardware_enabled), ), );
-
-const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings = NML_DBUS_META_IFACE_INIT_PROP(
-    NM_DBUS_INTERFACE_SETTINGS,
-    nm_client_get_type,
-    NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
-    NML_DBUS_META_IFACE_DBUS_PROPERTIES(
-        NML_DBUS_META_PROPERTY_INIT_B("CanModify",
-                                      PROP_CAN_MODIFY,
-                                      NMClient,
-                                      _priv.settings.can_modify),
-        NML_DBUS_META_PROPERTY_INIT_AO_PROP(
-            "Connections",
-            PROP_CONNECTIONS,
-            NMClient,
-            _priv.settings.connections,
-            nm_remote_connection_get_type,
-            .notify_changed_ao       = _property_ao_notify_changed_connections_cb,
-            .check_nmobj_visible_fcn = (gboolean(*)(GObject *)) nm_remote_connection_get_visible),
-        NML_DBUS_META_PROPERTY_INIT_S("Hostname",
-                                      PROP_HOSTNAME,
-                                      NMClient,
-                                      _priv.settings.hostname), ), );
-
-const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dnsmanager = NML_DBUS_META_IFACE_INIT_PROP(
-    NM_DBUS_INTERFACE_DNS_MANAGER,
-    nm_client_get_type,
-    NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
-    NML_DBUS_META_IFACE_DBUS_PROPERTIES(
-        NML_DBUS_META_PROPERTY_INIT_FCN("Configuration",
-                                        PROP_DNS_CONFIGURATION,
-                                        "aa{sv}",
-                                        _notify_update_prop_dns_manager_configuration),
-        NML_DBUS_META_PROPERTY_INIT_S("Mode", PROP_DNS_MODE, NMClient, _priv.dns_manager.mode),
-        NML_DBUS_META_PROPERTY_INIT_S("RcManager",
-                                      PROP_DNS_RC_MANAGER,
-                                      NMClient,
-                                      _priv.dns_manager.rc_manager), ), );
-
-static void
-nm_client_class_init(NMClientClass *client_class)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(client_class);
-
-    _dbus_path_nm          = nm_ref_string_new(NM_DBUS_PATH);
-    _dbus_path_settings    = nm_ref_string_new(NM_DBUS_PATH_SETTINGS);
-    _dbus_path_dns_manager = nm_ref_string_new(NM_DBUS_PATH_DNS_MANAGER);
-
-    object_class->get_property = get_property;
-    object_class->set_property = set_property;
-    object_class->constructed  = constructed;
-    object_class->dispose      = dispose;
-
-    /**
-     * NMClient:dbus-connection:
-     *
-     * The #GDBusConnection to use.
-     *
-     * If this is not set during object construction, the D-Bus connection will
-     * automatically be chosen during async/sync initalization via g_bus_get().
-     *
-     * Since: 1.22
-     */
-    obj_properties[PROP_DBUS_CONNECTION] = g_param_spec_object(
-        NM_CLIENT_DBUS_CONNECTION,
-        "",
-        "",
-        G_TYPE_DBUS_CONNECTION,
-        G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:instance-flags:
-     *
-     * #NMClientInstanceFlags for the instance. These affect behavior of #NMClient.
-     * This is a construct property and you may only set most flags only during
-     * construction.
-     *
-     * The flag %NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS can be toggled any time,
-     * even after constructing the instance. Note that you may want to watch NMClient:permissions-state
-     * property to know whether permissions are ready. Note that permissions are only fetched
-     * when NMClient has a D-Bus name owner.
-     *
-     * Since: 1.24
-     */
-    obj_properties[PROP_INSTANCE_FLAGS] = g_param_spec_uint(
-        NM_CLIENT_INSTANCE_FLAGS,
-        "",
-        "",
-        0,
-        G_MAXUINT32,
-        0,
-        G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:dbus-name-owner:
-     *
-     * The name owner of the NetworkManager D-Bus service.
-     *
-     * Since: 1.22
-     **/
-    obj_properties[PROP_DBUS_NAME_OWNER] =
-        g_param_spec_string(NM_CLIENT_DBUS_NAME_OWNER,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:version:
-     *
-     * The NetworkManager version.
-     **/
-    obj_properties[PROP_VERSION] = g_param_spec_string(NM_CLIENT_VERSION,
-                                                       "",
-                                                       "",
-                                                       NULL,
-                                                       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:state:
-     *
-     * The current daemon state.
-     **/
-    obj_properties[PROP_STATE] = g_param_spec_enum(NM_CLIENT_STATE,
-                                                   "",
-                                                   "",
-                                                   NM_TYPE_STATE,
-                                                   NM_STATE_UNKNOWN,
-                                                   G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:startup:
-     *
-     * Whether the daemon is still starting up.
-     **/
-    obj_properties[PROP_STARTUP] = g_param_spec_boolean(NM_CLIENT_STARTUP,
-                                                        "",
-                                                        "",
-                                                        FALSE,
-                                                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:nm-running:
-     *
-     * Whether the daemon is running.
-     **/
-    obj_properties[PROP_NM_RUNNING] =
-        g_param_spec_boolean(NM_CLIENT_NM_RUNNING,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:networking-enabled:
-     *
-     * Whether networking is enabled.
-     *
-     * The property setter is a synchronous D-Bus call. This is deprecated since 1.22.
-     */
-    obj_properties[PROP_NETWORKING_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_NETWORKING_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:wireless-enabled:
-     *
-     * Whether wireless is enabled.
-     *
-     * The property setter is a synchronous D-Bus call. This is deprecated since 1.22.
-     **/
-    obj_properties[PROP_WIRELESS_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_WIRELESS_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:wireless-hardware-enabled:
-     *
-     * Whether the wireless hardware is enabled.
-     **/
-    obj_properties[PROP_WIRELESS_HARDWARE_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_WIRELESS_HARDWARE_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:wwan-enabled:
-     *
-     * Whether WWAN functionality is enabled.
-     *
-     * The property setter is a synchronous D-Bus call. This is deprecated since 1.22.
-     */
-    obj_properties[PROP_WWAN_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_WWAN_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:wwan-hardware-enabled:
-     *
-     * Whether the WWAN hardware is enabled.
-     **/
-    obj_properties[PROP_WWAN_HARDWARE_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_WWAN_HARDWARE_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:wimax-enabled:
-     *
-     * Whether WiMAX functionality is enabled.
-     *
-     * Deprecated: 1.22: WiMAX is no longer supported and this always returns FALSE. The setter has no effect.
-     */
-    obj_properties[PROP_WIMAX_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_WIMAX_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:wimax-hardware-enabled:
-     *
-     * Whether the WiMAX hardware is enabled.
-     *
-     * Deprecated: 1.22: WiMAX is no longer supported and this always returns FALSE.
-     **/
-    obj_properties[PROP_WIMAX_HARDWARE_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_WIMAX_HARDWARE_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:active-connections: (type GPtrArray(NMActiveConnection))
-     *
-     * The active connections.
-     **/
-    obj_properties[PROP_ACTIVE_CONNECTIONS] =
-        g_param_spec_boxed(NM_CLIENT_ACTIVE_CONNECTIONS,
-                           "",
-                           "",
-                           G_TYPE_PTR_ARRAY,
-                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:connectivity:
-     *
-     * The network connectivity state.
-     */
-    obj_properties[PROP_CONNECTIVITY] =
-        g_param_spec_enum(NM_CLIENT_CONNECTIVITY,
-                          "",
-                          "",
-                          NM_TYPE_CONNECTIVITY_STATE,
-                          NM_CONNECTIVITY_UNKNOWN,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient::connectivity-check-available
-     *
-     * Whether a connectivity checking service has been configured.
-     *
-     * Since: 1.10
-     */
-    obj_properties[PROP_CONNECTIVITY_CHECK_AVAILABLE] =
-        g_param_spec_boolean(NM_CLIENT_CONNECTIVITY_CHECK_AVAILABLE,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient::connectivity-check-enabled
-     *
-     * Whether a connectivity checking service has been enabled.
-     *
-     * Since: 1.10
-     *
-     * The property setter is a synchronous D-Bus call. This is deprecated since 1.22.
-     */
-    obj_properties[PROP_CONNECTIVITY_CHECK_ENABLED] =
-        g_param_spec_boolean(NM_CLIENT_CONNECTIVITY_CHECK_ENABLED,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:connectivity-check-uri:
-     *
-     * The used URI for connectivity checking.
-     *
-     * Since: 1.22
-     **/
-    obj_properties[PROP_CONNECTIVITY_CHECK_URI] =
-        g_param_spec_string(NM_CLIENT_CONNECTIVITY_CHECK_URI,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:primary-connection:
-     *
-     * The #NMActiveConnection of the device with the default route;
-     * see nm_client_get_primary_connection() for more details.
-     **/
-    obj_properties[PROP_PRIMARY_CONNECTION] =
-        g_param_spec_object(NM_CLIENT_PRIMARY_CONNECTION,
-                            "",
-                            "",
-                            NM_TYPE_ACTIVE_CONNECTION,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:activating-connection:
-     *
-     * The #NMActiveConnection of the activating connection that is
-     * likely to become the new #NMClient:primary-connection.
-     **/
-    obj_properties[PROP_ACTIVATING_CONNECTION] =
-        g_param_spec_object(NM_CLIENT_ACTIVATING_CONNECTION,
-                            "",
-                            "",
-                            NM_TYPE_ACTIVE_CONNECTION,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:devices: (type GPtrArray(NMDevice))
-     *
-     * List of real network devices.  Does not include placeholder devices.
-     **/
-    obj_properties[PROP_DEVICES] = g_param_spec_boxed(NM_CLIENT_DEVICES,
-                                                      "",
-                                                      "",
-                                                      G_TYPE_PTR_ARRAY,
-                                                      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:all-devices: (type GPtrArray(NMDevice))
-     *
-     * List of both real devices and device placeholders.
-     * Since: 1.2
-     **/
-    obj_properties[PROP_ALL_DEVICES] =
-        g_param_spec_boxed(NM_CLIENT_ALL_DEVICES,
-                           "",
-                           "",
-                           G_TYPE_PTR_ARRAY,
-                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:connections: (type GPtrArray(NMRemoteConnection))
-     *
-     * The list of configured connections that are available to the user. (Note
-     * that this differs from the underlying D-Bus property, which may also
-     * contain the object paths of connections that the user does not have
-     * permission to read the details of.)
-     */
-    obj_properties[PROP_CONNECTIONS] =
-        g_param_spec_boxed(NM_CLIENT_CONNECTIONS,
-                           "",
-                           "",
-                           G_TYPE_PTR_ARRAY,
-                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:hostname:
-     *
-     * The machine hostname stored in persistent configuration. This can be
-     * modified by calling nm_client_save_hostname().
-     */
-    obj_properties[PROP_HOSTNAME] = g_param_spec_string(NM_CLIENT_HOSTNAME,
-                                                        "",
-                                                        "",
-                                                        NULL,
-                                                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:can-modify:
-     *
-     * If %TRUE, adding and modifying connections is supported.
-     */
-    obj_properties[PROP_CAN_MODIFY] =
-        g_param_spec_boolean(NM_CLIENT_CAN_MODIFY,
-                             "",
-                             "",
-                             FALSE,
-                             G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:metered:
-     *
-     * Whether the connectivity is metered.
-     *
-     * Since: 1.2
-     **/
-    obj_properties[PROP_METERED] = g_param_spec_uint(NM_CLIENT_METERED,
-                                                     "",
-                                                     "",
-                                                     0,
-                                                     G_MAXUINT32,
-                                                     NM_METERED_UNKNOWN,
-                                                     G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:dns-mode:
-     *
-     * The current DNS processing mode.
-     *
-     * Since: 1.6
-     **/
-    obj_properties[PROP_DNS_MODE] = g_param_spec_string(NM_CLIENT_DNS_MODE,
-                                                        "",
-                                                        "",
-                                                        NULL,
-                                                        G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:dns-rc-manager:
-     *
-     * The current resolv.conf management mode.
-     *
-     * Since: 1.6
-     **/
-    obj_properties[PROP_DNS_RC_MANAGER] =
-        g_param_spec_string(NM_CLIENT_DNS_RC_MANAGER,
-                            "",
-                            "",
-                            NULL,
-                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:dns-configuration: (type GPtrArray(NMDnsEntry))
-     *
-     * The current DNS configuration, represented as an array
-     * of #NMDnsEntry objects.
-     *
-     * Since: 1.6
-     **/
-    obj_properties[PROP_DNS_CONFIGURATION] =
-        g_param_spec_boxed(NM_CLIENT_DNS_CONFIGURATION,
-                           "",
-                           "",
-                           G_TYPE_PTR_ARRAY,
-                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:checkpoints: (type GPtrArray(NMCheckpoint))
-     *
-     * The list of active checkpoints.
-     *
-     * Since: 1.12
-     */
-    obj_properties[PROP_CHECKPOINTS] =
-        g_param_spec_boxed(NM_CLIENT_CHECKPOINTS,
-                           "",
-                           "",
-                           G_TYPE_PTR_ARRAY,
-                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:capabilities: (type GArray(guint32))
-     *
-     * The list of capabilities numbers as guint32 or %NULL if
-     * there are no capabilities. The numeric value correspond
-     * to %NMCapability enum.
-     *
-     * Since: 1.24
-     */
-    obj_properties[PROP_CAPABILITIES] =
-        g_param_spec_boxed(NM_CLIENT_CAPABILITIES,
-                           "",
-                           "",
-                           G_TYPE_ARRAY,
-                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    /**
-     * NMClient:permissions-state:
-     *
-     * The state of the cached permissions. The value %NM_TERNARY_DEFAULT
-     * means that no permissions are yet received (or not yet requested).
-     * %NM_TERNARY_TRUE means that permissions are received, cached and up
-     * to date. %NM_TERNARY_FALSE means that permissions were received and are
-     * cached, but in the meantime a "CheckPermissions" signal was received
-     * that invalidated the cached permissions.
-     * Note that NMClient will always emit a notify::permissions-state signal
-     * when a "CheckPermissions" signal got received or after new permissions
-     * got received (that is regardless whether the value of the permission state
-     * actually changed). With this you can watch the permissions-state property
-     * to know whether the permissions are ready. Note that while NMClient has
-     * no D-Bus name owner, no permissions are fetched (and this property won't
-     * change).
-     *
-     * Since: 1.24
-     */
-    obj_properties[PROP_PERMISSIONS_STATE] =
-        g_param_spec_enum(NM_CLIENT_PERMISSIONS_STATE,
-                          "",
-                          "",
-                          NM_TYPE_TERNARY,
-                          NM_TERNARY_DEFAULT,
-                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-    _nml_dbus_meta_class_init_with_properties(object_class,
-                                              &_nml_dbus_meta_iface_nm,
-                                              &_nml_dbus_meta_iface_nm_settings,
-                                              &_nml_dbus_meta_iface_nm_dnsmanager);
-
-    /**
-     * NMClient::device-added:
-     * @client: the client that received the signal
-     * @device: (type NMDevice): the new device
-     *
-     * Notifies that a #NMDevice is added.  This signal is not emitted for
-     * placeholder devices.
-     **/
-    signals[DEVICE_ADDED] = g_signal_new(NM_CLIENT_DEVICE_ADDED,
-                                         G_OBJECT_CLASS_TYPE(object_class),
-                                         G_SIGNAL_RUN_FIRST,
-                                         0,
-                                         NULL,
-                                         NULL,
-                                         NULL,
-                                         G_TYPE_NONE,
-                                         1,
-                                         G_TYPE_OBJECT);
-
-    /**
-     * NMClient::device-removed:
-     * @client: the client that received the signal
-     * @device: (type NMDevice): the removed device
-     *
-     * Notifies that a #NMDevice is removed.  This signal is not emitted for
-     * placeholder devices.
-     **/
-    signals[DEVICE_REMOVED] = g_signal_new(NM_CLIENT_DEVICE_REMOVED,
-                                           G_OBJECT_CLASS_TYPE(object_class),
-                                           G_SIGNAL_RUN_FIRST,
-                                           0,
-                                           NULL,
-                                           NULL,
-                                           NULL,
-                                           G_TYPE_NONE,
-                                           1,
-                                           G_TYPE_OBJECT);
-
-    /**
-     * NMClient::any-device-added:
-     * @client: the client that received the signal
-     * @device: (type NMDevice): the new device
-     *
-     * Notifies that a #NMDevice is added.  This signal is emitted for both
-     * regular devices and placeholder devices.
-     **/
-    signals[ANY_DEVICE_ADDED] = g_signal_new(NM_CLIENT_ANY_DEVICE_ADDED,
-                                             G_OBJECT_CLASS_TYPE(object_class),
-                                             G_SIGNAL_RUN_FIRST,
-                                             0,
-                                             NULL,
-                                             NULL,
-                                             NULL,
-                                             G_TYPE_NONE,
-                                             1,
-                                             G_TYPE_OBJECT);
-
-    /**
-     * NMClient::any-device-removed:
-     * @client: the client that received the signal
-     * @device: (type NMDevice): the removed device
-     *
-     * Notifies that a #NMDevice is removed.  This signal is emitted for both
-     * regular devices and placeholder devices.
-     **/
-    signals[ANY_DEVICE_REMOVED] = g_signal_new(NM_CLIENT_ANY_DEVICE_REMOVED,
-                                               G_OBJECT_CLASS_TYPE(object_class),
-                                               G_SIGNAL_RUN_FIRST,
-                                               0,
-                                               NULL,
-                                               NULL,
-                                               NULL,
-                                               G_TYPE_NONE,
-                                               1,
-                                               G_TYPE_OBJECT);
-
-    /**
-     * NMClient::permission-changed:
-     * @client: the client that received the signal
-     * @permission: a permission from #NMClientPermission
-     * @result: the permission's result, one of #NMClientPermissionResult
-     *
-     * Notifies that a permission has changed
-     **/
-    signals[PERMISSION_CHANGED] = g_signal_new(NM_CLIENT_PERMISSION_CHANGED,
-                                               G_OBJECT_CLASS_TYPE(object_class),
-                                               G_SIGNAL_RUN_FIRST,
-                                               0,
-                                               NULL,
-                                               NULL,
-                                               NULL,
-                                               G_TYPE_NONE,
-                                               2,
-                                               G_TYPE_UINT,
-                                               G_TYPE_UINT);
-    /**
-     * NMClient::connection-added:
-     * @client: the settings object that received the signal
-     * @connection: the new connection
-     *
-     * Notifies that a #NMConnection has been added.
-     **/
-    signals[CONNECTION_ADDED] = g_signal_new(NM_CLIENT_CONNECTION_ADDED,
-                                             G_OBJECT_CLASS_TYPE(object_class),
-                                             G_SIGNAL_RUN_FIRST,
-                                             0,
-                                             NULL,
-                                             NULL,
-                                             NULL,
-                                             G_TYPE_NONE,
-                                             1,
-                                             NM_TYPE_REMOTE_CONNECTION);
-
-    /**
-     * NMClient::connection-removed:
-     * @client: the settings object that received the signal
-     * @connection: the removed connection
-     *
-     * Notifies that a #NMConnection has been removed.
-     **/
-    signals[CONNECTION_REMOVED] = g_signal_new(NM_CLIENT_CONNECTION_REMOVED,
-                                               G_OBJECT_CLASS_TYPE(object_class),
-                                               G_SIGNAL_RUN_FIRST,
-                                               0,
-                                               NULL,
-                                               NULL,
-                                               NULL,
-                                               G_TYPE_NONE,
-                                               1,
-                                               NM_TYPE_REMOTE_CONNECTION);
-
-    /**
-     * NMClient::active-connection-added:
-     * @client: the settings object that received the signal
-     * @active_connection: the new active connection
-     *
-     * Notifies that a #NMActiveConnection has been added.
-     **/
-    signals[ACTIVE_CONNECTION_ADDED] = g_signal_new(NM_CLIENT_ACTIVE_CONNECTION_ADDED,
-                                                    G_OBJECT_CLASS_TYPE(object_class),
-                                                    G_SIGNAL_RUN_FIRST,
-                                                    0,
-                                                    NULL,
-                                                    NULL,
-                                                    NULL,
-                                                    G_TYPE_NONE,
-                                                    1,
-                                                    NM_TYPE_ACTIVE_CONNECTION);
-
-    /**
-     * NMClient::active-connection-removed:
-     * @client: the settings object that received the signal
-     * @active_connection: the removed active connection
-     *
-     * Notifies that a #NMActiveConnection has been removed.
-     **/
-    signals[ACTIVE_CONNECTION_REMOVED] = g_signal_new(NM_CLIENT_ACTIVE_CONNECTION_REMOVED,
-                                                      G_OBJECT_CLASS_TYPE(object_class),
-                                                      G_SIGNAL_RUN_FIRST,
-                                                      0,
-                                                      NULL,
-                                                      NULL,
-                                                      NULL,
-                                                      G_TYPE_NONE,
-                                                      1,
-                                                      NM_TYPE_ACTIVE_CONNECTION);
-}
-
-static void
-nm_client_initable_iface_init(GInitableIface *iface)
-{
-    iface->init = init_sync;
-}
-
-static void
-nm_client_async_initable_iface_init(GAsyncInitableIface *iface)
-{
-    iface->init_async  = init_async;
-    iface->init_finish = init_finish;
-}
-
-/*****************************************************************************
- * Backported symbols. Usually, new API is only added in new major versions
- * of NetworkManager (that is, on "master" branch). Sometimes however, we might
- * have to backport some API to an older stable branch. In that case, we backport
- * the symbols with a different version corresponding to the minor API.
- *
- * To allow upgrading from such a extended minor-release, "master" contains these
- * backported symbols too.
- *
- * For example, 1.2.0 added nm_setting_connection_autoconnect_slaves_get_type.
- * This was backported for 1.0.4 as nm_setting_connection_autoconnect_slaves_get_type@libnm_1_0_4
- * To allow an application that was linked against 1.0.4 to seamlessly upgrade to
- * a newer major version, the same symbols is also exposed on "master". Note, that
- * a user can only seamlessly upgrade to a newer major version, that is released
- * *after* 1.0.4 is out. In this example, 1.2.0 was released after 1.4.0, and thus
- * a 1.0.4 user can upgrade to 1.2.0 ABI.
- *****************************************************************************/
-
-NM_BACKPORT_SYMBOL(libnm_1_0_4,
-                   NMSettingConnectionAutoconnectSlaves,
-                   nm_setting_connection_get_autoconnect_slaves,
-                   (NMSettingConnection * setting),
-                   (setting));
-
-NM_BACKPORT_SYMBOL(libnm_1_0_4,
-                   GType,
-                   nm_setting_connection_autoconnect_slaves_get_type,
-                   (void),
-                   ());
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6,
-                   NMMetered,
-                   nm_setting_connection_get_metered,
-                   (NMSettingConnection * setting),
-                   (setting));
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6, GType, nm_metered_get_type, (void), ());
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6,
-                   NMSettingWiredWakeOnLan,
-                   nm_setting_wired_get_wake_on_lan,
-                   (NMSettingWired * setting),
-                   (setting));
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6,
-                   const char *,
-                   nm_setting_wired_get_wake_on_lan_password,
-                   (NMSettingWired * setting),
-                   (setting));
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6, GType, nm_setting_wired_wake_on_lan_get_type, (void), ());
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6, const guint *, nm_utils_wifi_2ghz_freqs, (void), ());
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6, const guint *, nm_utils_wifi_5ghz_freqs, (void), ());
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6,
-                   char *,
-                   nm_utils_enum_to_str,
-                   (GType type, int value),
-                   (type, value));
-
-NM_BACKPORT_SYMBOL(libnm_1_0_6,
-                   gboolean,
-                   nm_utils_enum_from_str,
-                   (GType type, const char *str, int *out_value, char **err_token),
-                   (type, str, out_value, err_token));
-
-NM_BACKPORT_SYMBOL(libnm_1_2_4,
-                   int,
-                   nm_setting_ip_config_get_dns_priority,
-                   (NMSettingIPConfig * setting),
-                   (setting));
-
-NM_BACKPORT_SYMBOL(libnm_1_10_14,
-                   NMSettingConnectionMdns,
-                   nm_setting_connection_get_mdns,
-                   (NMSettingConnection * setting),
-                   (setting));
-NM_BACKPORT_SYMBOL(libnm_1_10_14, GType, nm_setting_connection_mdns_get_type, (void), ());