summary refs log tree commit diff
path: root/libnm-glib
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-01-20 16:26:51 +0100
committerMichael Biebl <biebl@debian.org>2016-01-20 16:26:51 +0100
commit494f296a3baab08522617b24b1f126d8f9a17502 (patch)
treec8ef32fb0dd1c4ff35a0b38e787abb58692de0cd /libnm-glib
parent54f6333410ffd570e62717d9e77c5c987175e397 (diff)
Imported Upstream version 1.1.90 upstream/1.1.90
Diffstat (limited to 'libnm-glib')
-rw-r--r--libnm-glib/Makefile.am5
-rw-r--r--libnm-glib/Makefile.in23
-rw-r--r--libnm-glib/libnm-glib-test.c15
-rw-r--r--libnm-glib/libnm-glib.ver3
-rw-r--r--libnm-glib/libnm_glib.c6
-rw-r--r--libnm-glib/nm-access-point.c11
-rw-r--r--libnm-glib/nm-access-point.h4
-rw-r--r--libnm-glib/nm-active-connection.c6
-rw-r--r--libnm-glib/nm-client.c220
-rw-r--r--libnm-glib/nm-client.h3
-rw-r--r--libnm-glib/nm-dbus-helpers-private.h5
-rw-r--r--libnm-glib/nm-dbus-helpers.c55
-rw-r--r--libnm-glib/nm-device-bond.c3
-rw-r--r--libnm-glib/nm-device-bridge.c3
-rw-r--r--libnm-glib/nm-device-bt.c3
-rw-r--r--libnm-glib/nm-device-ethernet.c3
-rw-r--r--libnm-glib/nm-device-generic.c30
-rw-r--r--libnm-glib/nm-device-infiniband.c3
-rw-r--r--libnm-glib/nm-device-modem.c3
-rw-r--r--libnm-glib/nm-device-olpc-mesh.c3
-rw-r--r--libnm-glib/nm-device-private.h1
-rw-r--r--libnm-glib/nm-device-team.c3
-rw-r--r--libnm-glib/nm-device-vlan.c3
-rw-r--r--libnm-glib/nm-device-wifi.c3
-rw-r--r--libnm-glib/nm-device-wimax.c44
-rw-r--r--libnm-glib/nm-device-wimax.h12
-rw-r--r--libnm-glib/nm-device.c124
-rw-r--r--libnm-glib/nm-device.h5
-rw-r--r--libnm-glib/nm-glib-enum-types.c2
-rw-r--r--libnm-glib/nm-object-cache.c2
-rw-r--r--libnm-glib/nm-object-cache.h3
-rw-r--r--libnm-glib/nm-object-private.h4
-rw-r--r--libnm-glib/nm-object.c294
-rw-r--r--libnm-glib/nm-remote-connection.c11
-rw-r--r--libnm-glib/nm-remote-settings.c93
-rw-r--r--libnm-glib/nm-secret-agent.c58
-rw-r--r--libnm-glib/nm-types.c2
-rw-r--r--libnm-glib/nm-vpn-enum-types.c2
-rw-r--r--libnm-glib/nm-vpn-plugin-ui-interface.h46
-rw-r--r--libnm-glib/nm-vpn-plugin.c8
-rw-r--r--libnm-glib/nm-wimax-nsp.c3
-rw-r--r--libnm-glib/tests/Makefile.am13
-rw-r--r--libnm-glib/tests/Makefile.in60
-rw-r--r--libnm-glib/tests/common.c121
-rw-r--r--libnm-glib/tests/common.h31
-rw-r--r--libnm-glib/tests/test-nm-client.c366
-rw-r--r--libnm-glib/tests/test-remote-settings-client.c35
47 files changed, 1118 insertions, 638 deletions
diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am
index f131c467..676b0671 100644
--- a/libnm-glib/Makefile.am
+++ b/libnm-glib/Makefile.am
@@ -3,11 +3,12 @@ include $(GLIB_MAKEFILE)
 SUBDIRS = . tests
 
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_builddir)/libnm-util \
 	-DG_LOG_DOMAIN=\""libnm-glib"\" \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS)
diff --git a/libnm-glib/Makefile.in b/libnm-glib/Makefile.in
index 26e9f4ee..25a9f7c0 100644
--- a/libnm-glib/Makefile.in
+++ b/libnm-glib/Makefile.in
@@ -345,7 +345,6 @@ BLUEZ5_LIBS = @BLUEZ5_LIBS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
-CKDB_PATH = @CKDB_PATH@
 CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
 CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
 CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
@@ -357,8 +356,6 @@ CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DBUS_CFLAGS = @DBUS_CFLAGS@
-DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
-DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
 DBUS_LIBS = @DBUS_LIBS@
 DBUS_SYS_DIR = @DBUS_SYS_DIR@
 DEFS = @DEFS@
@@ -368,6 +365,7 @@ DHCPCD_PATH = @DHCPCD_PATH@
 DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
 DLLTOOL = @DLLTOOL@
 DNSMASQ_PATH = @DNSMASQ_PATH@
+DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -422,16 +420,13 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
 INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
 INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
 IPTABLES_PATH = @IPTABLES_PATH@
-IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
-IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
 KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
 LCOV = @LCOV@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@
+LIBAUDIT_LIBS = @LIBAUDIT_LIBS@
 LIBDL = @LIBDL@
-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
@@ -468,6 +463,8 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
+NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
 NM_MICRO_VERSION = @NM_MICRO_VERSION@
 NM_MINOR_VERSION = @NM_MINOR_VERSION@
@@ -496,7 +493,6 @@ POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PATH = @PPPD_PATH@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
-PPPOE_PATH = @PPPOE_PATH@
 QT_CFLAGS = @QT_CFLAGS@
 QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
@@ -511,6 +507,8 @@ SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@
 SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@
 SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@
 SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
+SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@
+SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@
 SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
 SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
@@ -571,6 +569,7 @@ mkdir_p = @mkdir_p@
 nmbinary = @nmbinary@
 nmconfdir = @nmconfdir@
 nmdatadir = @nmdatadir@
+nmlibdir = @nmlibdir@
 nmrundir = @nmrundir@
 nmstatedir = @nmstatedir@
 oldincludedir = @oldincludedir@
@@ -578,6 +577,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -595,11 +595,12 @@ with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
 SUBDIRS = . tests
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_builddir)/libnm-util \
 	-DG_LOG_DOMAIN=\""libnm-glib"\" \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
 	$(DBUS_CFLAGS) \
 	$(GLIB_CFLAGS)
diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c
index 7dc6823e..9c8085d3 100644
--- a/libnm-glib/libnm-glib-test.c
+++ b/libnm-glib/libnm-glib-test.c
@@ -30,10 +30,13 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
+
+#include "nm-default.h"
 #include "nm-client.h"
 #include "nm-device.h"
 #include "nm-device-ethernet.h"
 #include "nm-device-wifi.h"
+#include "nm-device-generic.h"
 #include "nm-utils.h"
 #include "nm-active-connection.h"
 #include "nm-vpn-connection.h"
@@ -210,6 +213,12 @@ dump_wireless (NMDeviceWifi *device)
 }
 
 static void
+dump_generic (NMDeviceGeneric *device)
+{
+	g_print ("HW address: %s\n", nm_device_generic_get_hw_address (device));
+}
+
+static void
 dump_wired (NMDeviceEthernet *device)
 {
 	const char *str;
@@ -251,6 +260,8 @@ dump_device (NMDevice *device)
 		dump_wired (NM_DEVICE_ETHERNET (device));
 	else if (NM_IS_DEVICE_WIFI (device))
 		dump_wireless (NM_DEVICE_WIFI (device));
+	else if (NM_IS_DEVICE_GENERIC (device))
+		dump_generic (NM_DEVICE_GENERIC (device));
 
 	dump_dhcp4_config (nm_device_get_dhcp4_config (device));
 }
@@ -392,9 +403,7 @@ main (int argc, char *argv[])
 {
 	NMClient *client;
 
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
+	nm_g_type_init ();
 
 	client = nm_client_new ();
 	if (!client) {
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
index dc982e56..bce31b0b 100644
--- a/libnm-glib/libnm-glib.ver
+++ b/libnm-glib/libnm-glib.ver
@@ -47,6 +47,7 @@ global:
 	nm_client_error_quark;
 	nm_client_get_activating_connection;
 	nm_client_get_active_connections;
+	nm_client_get_all_devices;
 	nm_client_get_connectivity;
 	nm_client_get_device_by_iface;
 	nm_client_get_device_by_path;
@@ -158,6 +159,7 @@ global:
 	nm_device_infiniband_get_hw_address;
 	nm_device_infiniband_get_type;
 	nm_device_infiniband_new;
+	nm_device_is_real;
 	nm_device_is_software;
 	nm_device_modem_error_get_type;
 	nm_device_modem_error_quark;
@@ -173,6 +175,7 @@ global:
 	nm_device_olpc_mesh_get_type;
 	nm_device_olpc_mesh_new;
 	nm_device_set_autoconnect;
+	nm_device_set_managed;
 	nm_device_team_error_get_type;
 	nm_device_team_error_quark;
 	nm_device_team_get_carrier;
diff --git a/libnm-glib/libnm_glib.c b/libnm-glib/libnm_glib.c
index fed80160..09d9bea9 100644
--- a/libnm-glib/libnm_glib.c
+++ b/libnm-glib/libnm_glib.c
@@ -26,9 +26,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <glib.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
+#include "nm-default.h"
 #include "NetworkManager.h"
 #include "libnm_glib.h"
 
@@ -495,9 +495,7 @@ libnm_glib_init (void)
 {
 	libnm_glib_ctx	*ctx = NULL;
 
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
+	nm_g_type_init ();
 
 	if (!g_thread_supported ())
 		g_thread_init (NULL);
diff --git a/libnm-glib/nm-access-point.c b/libnm-glib/nm-access-point.c
index b980943a..3a420ea1 100644
--- a/libnm-glib/nm-access-point.c
+++ b/libnm-glib/nm-access-point.c
@@ -24,14 +24,13 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-connection.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-wireless.h>
 #include <nm-setting-wireless-security.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-access-point.h"
 #include "NetworkManager.h"
 #include "nm-types-private.h"
@@ -53,7 +52,7 @@ typedef struct {
 	NM80211Mode mode;
 	guint32 max_bitrate;
 	guint8 strength;
-	gint32 last_seen;
+	gint last_seen;
 } NMAccessPointPrivate;
 
 enum {
@@ -277,9 +276,9 @@ nm_access_point_get_strength (NMAccessPoint *ap)
  *
  * Returns: the last seen time in seconds
  *
- * Since: 1.0.6
+ * Since: 1.2
  **/
-gint32
+gint
 nm_access_point_get_last_seen (NMAccessPoint *ap)
 {
 	g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), -1);
@@ -707,7 +706,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class)
 	 * access point was found in scan results.  A value of -1 means the
 	 * access point has not been found in a scan.
 	 *
-	 * Since: 1.0.6
+	 * Since: 1.2
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_LAST_SEEN,
diff --git a/libnm-glib/nm-access-point.h b/libnm-glib/nm-access-point.h
index 57bd6ed1..7ea8f812 100644
--- a/libnm-glib/nm-access-point.h
+++ b/libnm-glib/nm-access-point.h
@@ -81,8 +81,8 @@ guint32                nm_access_point_get_frequency    (NMAccessPoint *ap);
 NM80211Mode            nm_access_point_get_mode         (NMAccessPoint *ap);
 guint32                nm_access_point_get_max_bitrate  (NMAccessPoint *ap);
 guint8                 nm_access_point_get_strength     (NMAccessPoint *ap);
-NM_AVAILABLE_IN_1_0_6
-gint32                 nm_access_point_get_last_seen    (NMAccessPoint *ap);
+NM_AVAILABLE_IN_1_2
+gint                   nm_access_point_get_last_seen    (NMAccessPoint *ap);
 
 GSList *               nm_access_point_filter_connections (NMAccessPoint *ap,
                                                            const GSList *connections);
diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c
index 7067a110..539eb75f 100644
--- a/libnm-glib/nm-active-connection.c
+++ b/libnm-glib/nm-active-connection.c
@@ -23,6 +23,7 @@
 
 #include <string.h>
 
+#include "nm-default.h"
 #include "NetworkManager.h"
 #include "nm-active-connection.h"
 #include "nm-object-private.h"
@@ -31,7 +32,6 @@
 #include "nm-device-private.h"
 #include "nm-connection.h"
 #include "nm-vpn-connection.h"
-#include "nm-glib-compat.h"
 #include "nm-dbus-helpers-private.h"
 
 static GType _nm_active_connection_type_for_path (DBusGConnection *connection,
@@ -120,7 +120,7 @@ _nm_active_connection_type_for_path (DBusGConnection *connection,
 	GValue value = G_VALUE_INIT;
 	GType type;
 
-	proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties");
+	proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
 	if (!proxy) {
 		g_warning ("%s: couldn't create D-Bus object proxy.", __func__);
 		return G_TYPE_INVALID;
@@ -197,7 +197,7 @@ _nm_active_connection_type_for_path_async (DBusGConnection *connection,
 	async_data->callback = callback;
 	async_data->user_data = user_data;
 
-	proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties");
+	proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
 	dbus_g_proxy_begin_call (proxy, "Get",
 	                         async_got_type, async_data, NULL,
 	                         G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c
index 40add09c..248b9d97 100644
--- a/libnm-glib/nm-client.c
+++ b/libnm-glib/nm-client.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-client.h"
 #include "nm-device-ethernet.h"
 #include "nm-device-wifi.h"
@@ -35,7 +36,6 @@
 #include "nm-vpn-connection.h"
 #include "nm-object-cache.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-glib-compat.h"
 
 void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
 
@@ -59,6 +59,7 @@ typedef struct {
 	NMState state;
 	gboolean startup;
 	GPtrArray *devices;
+	GPtrArray *all_devices;
 	GPtrArray *active_connections;
 	NMConnectivityState connectivity;
 	NMActiveConnection *primary_connection;
@@ -101,6 +102,7 @@ enum {
 	PROP_PRIMARY_CONNECTION,
 	PROP_ACTIVATING_CONNECTION,
 	PROP_DEVICES,
+	PROP_ALL_DEVICES,
 
 	LAST_PROP
 };
@@ -108,6 +110,8 @@ enum {
 enum {
 	DEVICE_ADDED,
 	DEVICE_REMOVED,
+	ANY_DEVICE_ADDED,
+	ANY_DEVICE_REMOVED,
 	PERMISSION_CHANGED,
 
 	LAST_SIGNAL
@@ -160,8 +164,8 @@ poke_wireless_devices_with_rf_status (NMClient *client)
 	NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
 	int i;
 
-	for (i = 0; priv->devices && (i < priv->devices->len); i++) {
-		NMDevice *device = g_ptr_array_index (priv->devices, i);
+	for (i = 0; priv->all_devices && (i < priv->all_devices->len); i++) {
+		NMDevice *device = g_ptr_array_index (priv->all_devices, i);
 
 		if (NM_IS_DEVICE_WIFI (device))
 			_nm_device_wifi_set_wireless_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled);
@@ -194,6 +198,7 @@ register_properties (NMClient *client)
 		{ NM_CLIENT_PRIMARY_CONNECTION,        &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
 		{ NM_CLIENT_ACTIVATING_CONNECTION,     &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
 		{ NM_CLIENT_DEVICES,                   &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
+		{ NM_CLIENT_ALL_DEVICES,               &priv->all_devices, NULL, NM_TYPE_DEVICE, "any-device" },
 		{ NULL },
 	};
 
@@ -379,6 +384,34 @@ nm_client_get_devices (NMClient *client)
 }
 
 /**
+ * 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 NM_CLIENT_GET_PRIVATE (client)->all_devices;
+}
+
+/**
  * nm_client_get_device_by_path:
  * @client: a #NMClient
  * @object_path: the object path to search for
@@ -1291,25 +1324,55 @@ nm_client_get_activating_connection (NMClient *client)
 /****************************************************************/
 
 static void
-free_devices (NMClient *client, gboolean emit_signals)
+free_devices (NMClient *client, gboolean in_dispose)
 {
 	NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
-	GPtrArray *devices;
-	NMDevice *device;
-	int i;
+	gs_unref_ptrarray GPtrArray *real_devices = NULL;
+	gs_unref_ptrarray GPtrArray *all_devices = NULL;
+	GPtrArray *devices = NULL;
+	guint i, j;
 
-	if (!priv->devices)
-		return;
+	real_devices = priv->devices;
+	all_devices = priv->all_devices;
 
-	devices = priv->devices;
-	priv->devices = NULL;
-	for (i = 0; i < devices->len; i++) {
-		device = devices->pdata[i];
-		if (emit_signals)
-			g_signal_emit (client, signals[DEVICE_REMOVED], 0, device);
-		g_object_unref (device);
+	if (in_dispose) {
+		priv->devices = NULL;
+		priv->all_devices = NULL;
+	} else {
+		priv->devices = g_ptr_array_new ();
+		priv->all_devices = g_ptr_array_new ();
+	}
+
+	if (all_devices && all_devices->len > 0)
+		devices = all_devices;
+	else if (devices && devices->len > 0)
+		devices = real_devices;
+
+	if (real_devices && devices != real_devices) {
+		for (i = 0; i < real_devices->len; i++) {
+			NMDevice *d = real_devices->pdata[i];
+
+			if (all_devices) {
+				for (j = 0; j < all_devices->len; j++) {
+					if (d == all_devices->pdata[j])
+						goto next;
+				}
+			}
+			if (!in_dispose)
+				g_signal_emit (client, signals[DEVICE_REMOVED], 0, d);
+next:
+			g_object_unref (d);
+		}
+	}
+	if (devices) {
+		for (i = 0; i < devices->len; i++) {
+			NMDevice *d = devices->pdata[i];
+
+			if (!in_dispose)
+				g_signal_emit (client, signals[DEVICE_REMOVED], 0, d);
+			g_object_unref (d);
+		}
 	}
-	g_ptr_array_free (devices, TRUE);
 }
 
 static void
@@ -1382,7 +1445,7 @@ proxy_name_owner_changed (DBusGProxy *proxy,
 		_nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_MANAGER_RUNNING);
 		_nm_object_suppress_property_updates (NM_OBJECT (client), TRUE);
 		poke_wireless_devices_with_rf_status (client);
-		free_devices (client, TRUE);
+		free_devices (client, FALSE);
 		free_active_connections (client, TRUE);
 		update_permissions (client, NULL);
 		priv->wireless_enabled = FALSE;
@@ -1798,23 +1861,19 @@ constructed (GObject *object)
 	                             object,
 	                             NULL);
 
-	if (_nm_object_is_connection_private (NM_OBJECT (object)))
-		priv->manager_running = TRUE;
-	else {
-		priv->bus_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
-		                                             DBUS_SERVICE_DBUS,
-		                                             DBUS_PATH_DBUS,
-		                                             DBUS_INTERFACE_DBUS);
-		g_assert (priv->bus_proxy);
-
-		dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
-		                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-		                         G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal (priv->bus_proxy,
-		                             "NameOwnerChanged",
-		                             G_CALLBACK (proxy_name_owner_changed),
-		                             object, NULL);
-	}
+	priv->bus_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
+	                                             DBUS_SERVICE_DBUS,
+	                                             DBUS_PATH_DBUS,
+	                                             DBUS_INTERFACE_DBUS);
+	g_assert (priv->bus_proxy);
+
+	dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
+	                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+	                         G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (priv->bus_proxy,
+	                             "NameOwnerChanged",
+	                             G_CALLBACK (proxy_name_owner_changed),
+	                             object, NULL);
 
 	g_signal_connect (object, "notify::" NM_CLIENT_WIRELESS_ENABLED,
 	                  G_CALLBACK (wireless_enabled_cb), NULL);
@@ -1835,15 +1894,13 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
 	if (!nm_client_parent_initable_iface->init (initable, cancellable, error))
 		return FALSE;
 
-	if (!_nm_object_is_connection_private (NM_OBJECT (client))) {
-		if (!dbus_g_proxy_call (priv->bus_proxy,
-		                        "NameHasOwner", error,
-		                        G_TYPE_STRING, NM_DBUS_SERVICE,
-		                        G_TYPE_INVALID,
-		                        G_TYPE_BOOLEAN, &priv->manager_running,
-		                        G_TYPE_INVALID))
-			return FALSE;
-	}
+	if (!dbus_g_proxy_call (priv->bus_proxy,
+	                        "NameHasOwner", error,
+	                        G_TYPE_STRING, NM_DBUS_SERVICE,
+	                        G_TYPE_INVALID,
+	                        G_TYPE_BOOLEAN, &priv->manager_running,
+	                        G_TYPE_INVALID))
+		return FALSE;
 
 	if (priv->manager_running && !get_permissions_sync (client, error))
 		return FALSE;
@@ -1953,16 +2010,12 @@ init_async (GAsyncInitable *initable, int io_priority,
 	                                               user_data, init_async);
 	g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
 
-	if (_nm_object_is_connection_private (NM_OBJECT (init_data->client)))
-		finish_init (init_data);
-	else {
-		/* Check if NM is running */
-		dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
-		                         init_async_got_manager_running,
-		                         init_data, NULL,
-		                         G_TYPE_STRING, NM_DBUS_SERVICE,
-		                         G_TYPE_INVALID);
-	}
+	/* Check if NM is running */
+	dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
+	                         init_async_got_manager_running,
+	                         init_data, NULL,
+	                         G_TYPE_STRING, NM_DBUS_SERVICE,
+	                         G_TYPE_INVALID);
 }
 
 static gboolean
@@ -1990,7 +2043,7 @@ dispose (GObject *object)
 	g_clear_object (&priv->client_proxy);
 	g_clear_object (&priv->bus_proxy);
 
-	free_devices (client, FALSE);
+	free_devices (client, TRUE);
 	free_active_connections (client, FALSE);
 	g_clear_object (&priv->primary_connection);
 	g_clear_object (&priv->activating_connection);
@@ -2116,6 +2169,9 @@ get_property (GObject *object,
 	case PROP_DEVICES:
 		g_value_set_boxed (value, nm_client_get_devices (self));
 		break;
+	case PROP_ALL_DEVICES:
+		g_value_set_boxed (value, nm_client_get_all_devices (self));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -2333,7 +2389,7 @@ nm_client_class_init (NMClientClass *client_class)
 	/**
 	 * NMClient:devices:
 	 *
-	 * List of known network devices.
+	 * List of real network devices.  Does not include placeholder devices.
 	 *
 	 * Since: 0.9.10
 	 **/
@@ -2344,6 +2400,20 @@ nm_client_class_init (NMClientClass *client_class)
 		                     G_PARAM_READABLE |
 		                     G_PARAM_STATIC_STRINGS));
 
+	/**
+	 * NMClient:all-devices:
+	 *
+	 * List of both real devices and device placeholders.
+	 *
+	 * Since: 1.2
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_ALL_DEVICES,
+		 g_param_spec_boxed (NM_CLIENT_ALL_DEVICES, "", "",
+		                     NM_TYPE_OBJECT_ARRAY,
+		                     G_PARAM_READABLE |
+		                     G_PARAM_STATIC_STRINGS));
+
 	/* signals */
 
 	/**
@@ -2351,7 +2421,8 @@ nm_client_class_init (NMClientClass *client_class)
 	 * @client: the client that received the signal
 	 * @device: (type NMDevice): the new device
 	 *
-	 * Notifies that a #NMDevice is added.
+	 * Notifies that a #NMDevice is added.  This signal is not emitted for
+	 * placeholder devices.
 	 **/
 	signals[DEVICE_ADDED] =
 		g_signal_new ("device-added",
@@ -2367,7 +2438,8 @@ nm_client_class_init (NMClientClass *client_class)
 	 * @client: the client that received the signal
 	 * @device: (type NMDevice): the removed device
 	 *
-	 * Notifies that a #NMDevice is removed.
+	 * Notifies that a #NMDevice is removed.  This signal is not emitted for
+	 * placeholder devices.
 	 **/
 	signals[DEVICE_REMOVED] =
 		g_signal_new ("device-removed",
@@ -2379,6 +2451,38 @@ nm_client_class_init (NMClientClass *client_class)
 		              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 ("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 ("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
diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h
index ffe513cb..39af321e 100644
--- a/libnm-glib/nm-client.h
+++ b/libnm-glib/nm-client.h
@@ -57,6 +57,7 @@ G_BEGIN_DECLS
 #define NM_CLIENT_PRIMARY_CONNECTION "primary-connection"
 #define NM_CLIENT_ACTIVATING_CONNECTION "activating-connection"
 #define NM_CLIENT_DEVICES "devices"
+#define NM_CLIENT_ALL_DEVICES "all-devices"
 
 /**
  * NMClientPermission:
@@ -175,6 +176,8 @@ NMClient *nm_client_new_finish (GAsyncResult         *result,
                                 GError              **error);
 
 const GPtrArray *nm_client_get_devices    (NMClient *client);
+NM_AVAILABLE_IN_1_2
+const GPtrArray *nm_client_get_all_devices(NMClient *client);
 NMDevice *nm_client_get_device_by_path    (NMClient *client, const char *object_path);
 NMDevice *nm_client_get_device_by_iface   (NMClient *client, const char *iface);
 
diff --git a/libnm-glib/nm-dbus-helpers-private.h b/libnm-glib/nm-dbus-helpers-private.h
index 8a350e78..c78bf1da 100644
--- a/libnm-glib/nm-dbus-helpers-private.h
+++ b/libnm-glib/nm-dbus-helpers-private.h
@@ -21,13 +21,12 @@
 #ifndef NM_DBUS_HELPERS_PRIVATE_H
 #define NM_DBUS_HELPERS_PRIVATE_H
 
-#include <gio/gio.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
-DBusGConnection *_nm_dbus_new_connection (GError **error);
+#include "nm-default.h"
 
-gboolean         _nm_dbus_is_connection_private (DBusGConnection *connection);
+DBusGConnection *_nm_dbus_new_connection (GError **error);
 
 DBusGProxy *     _nm_dbus_new_proxy_for_connection (DBusGConnection *connection,
                                                     const char *path,
diff --git a/libnm-glib/nm-dbus-helpers.c b/libnm-glib/nm-dbus-helpers.c
index 00e04ab4..db75eb24 100644
--- a/libnm-glib/nm-dbus-helpers.c
+++ b/libnm-glib/nm-dbus-helpers.c
@@ -21,80 +21,27 @@
 #include "config.h"
 
 #include <string.h>
-#include <gio/gio.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
+#include "nm-default.h"
 #include "nm-dbus-helpers-private.h"
 #include "NetworkManager.h"
 
-static dbus_int32_t priv_slot = -1;
-
-static gboolean
-_ensure_dbus_data_slot (void)
-{
-	static gsize init_value = 0;
-	gboolean success = TRUE;
-
-	if (g_once_init_enter (&init_value)) {
-		success = dbus_connection_allocate_data_slot (&priv_slot);
-		g_once_init_leave (&init_value, 1);
-	}
-	return success;
-}
-
 DBusGConnection *
 _nm_dbus_new_connection (GError **error)
 {
 	DBusGConnection *connection = NULL;
 
-	if (!_ensure_dbus_data_slot ()) {
-		g_set_error (error, DBUS_GERROR, DBUS_GERROR_FAILED, "failed to allocated data slot");
-		return NULL;
-	}
-
-#if HAVE_DBUS_GLIB_100
-	/* If running as root try the private bus first */
-	if (0 == geteuid ()) {
-		connection = dbus_g_connection_open ("unix:path=" NMRUNDIR "/private", error);
-		if (connection) {
-			DBusConnection *dbus_connection = dbus_g_connection_get_connection (connection);
-
-			/* Mark this connection as private */
-			dbus_connection_set_data (dbus_connection, priv_slot, GUINT_TO_POINTER (TRUE), NULL);
-			dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
-			return connection;
-		}
-		/* Fall back to a bus if for some reason private socket isn't available */
-		g_clear_error (error);
-	}
-#endif
-
 	if (connection == NULL)
 		connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, error);
 
 	return connection;
 }
 
-gboolean
-_nm_dbus_is_connection_private (DBusGConnection *connection)
-{
-	if (!_ensure_dbus_data_slot ())
-		return FALSE;
-	return !!dbus_connection_get_data (dbus_g_connection_get_connection (connection), priv_slot);
-}
-
 DBusGProxy *
 _nm_dbus_new_proxy_for_connection (DBusGConnection *connection,
                                    const char *path,
                                    const char *interface)
 {
-	/* Private connections can't use dbus_g_proxy_new_for_name() or
-	 * dbus_g_proxy_new_for_name_owner() because peer-to-peer connections don't
-	 * have either a bus daemon or name owners, both of which those functions
-	 * require.
-	 */
-	if (_nm_dbus_is_connection_private (connection))
-		return dbus_g_proxy_new_for_peer (connection, path, interface);
-
 	return dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, interface);
 }
diff --git a/libnm-glib/nm-device-bond.c b/libnm-glib/nm-device-bond.c
index 786d4f16..12df490f 100644
--- a/libnm-glib/nm-device-bond.c
+++ b/libnm-glib/nm-device-bond.c
@@ -23,12 +23,11 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-bond.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-device-bond.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-bridge.c b/libnm-glib/nm-device-bridge.c
index ef69fb26..d08104d1 100644
--- a/libnm-glib/nm-device-bridge.c
+++ b/libnm-glib/nm-device-bridge.c
@@ -23,12 +23,11 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-bridge.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-device-bridge.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-bt.c b/libnm-glib/nm-device-bt.c
index 58d48344..3d7d183b 100644
--- a/libnm-glib/nm-device-bt.c
+++ b/libnm-glib/nm-device-bt.c
@@ -24,11 +24,10 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-bluetooth.h>
 
+#include "nm-default.h"
 #include "nm-device-bt.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-ethernet.c b/libnm-glib/nm-device-ethernet.c
index d27a980f..b5914616 100644
--- a/libnm-glib/nm-device-ethernet.c
+++ b/libnm-glib/nm-device-ethernet.c
@@ -24,12 +24,11 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-wired.h>
 #include <nm-setting-pppoe.h>
 
+#include "nm-default.h"
 #include "nm-device-ethernet.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-generic.c b/libnm-glib/nm-device-generic.c
index a17a6735..a7b2fa04 100644
--- a/libnm-glib/nm-device-generic.c
+++ b/libnm-glib/nm-device-generic.c
@@ -184,15 +184,41 @@ register_properties (NMDeviceGeneric *device)
 	                                property_info);
 }
 
+static const char *
+_device_type_to_interface (NMDeviceType type)
+{
+	switch (type) {
+	case NM_DEVICE_TYPE_GENERIC:
+		return NM_DBUS_INTERFACE_DEVICE_GENERIC;
+	case NM_DEVICE_TYPE_TUN:
+		return NM_DBUS_INTERFACE_DEVICE_TUN;
+	default:
+		return NULL;
+	}
+}
+
 static void
 constructed (GObject *object)
 {
 	NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object);
+	NMDeviceType type;
+	DBusGConnection *connection;
+	const char *path, *interface;
 
 	G_OBJECT_CLASS (nm_device_generic_parent_class)->constructed (object);
 
-	priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_GENERIC);
-	register_properties (NM_DEVICE_GENERIC (object));
+	g_object_get (object,
+	              NM_OBJECT_DBUS_CONNECTION, &connection,
+	              NM_OBJECT_DBUS_PATH, &path,
+	              NULL);
+
+	type = _nm_device_type_for_path (connection, path);
+	interface = _device_type_to_interface (type);
+
+	if (interface) {
+		priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, interface);
+		register_properties (NM_DEVICE_GENERIC (object));
+	}
 }
 
 static void
diff --git a/libnm-glib/nm-device-infiniband.c b/libnm-glib/nm-device-infiniband.c
index 663b3651..b9af8879 100644
--- a/libnm-glib/nm-device-infiniband.c
+++ b/libnm-glib/nm-device-infiniband.c
@@ -24,12 +24,11 @@
 #include <linux/if_infiniband.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-infiniband.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-device-infiniband.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-modem.c b/libnm-glib/nm-device-modem.c
index 524d86ce..88c15dd7 100644
--- a/libnm-glib/nm-device-modem.c
+++ b/libnm-glib/nm-device-modem.c
@@ -23,12 +23,11 @@
 
 #include <string.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-gsm.h>
 #include <nm-setting-cdma.h>
 
+#include "nm-default.h"
 #include "nm-device-modem.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-olpc-mesh.c b/libnm-glib/nm-device-olpc-mesh.c
index e68fda62..69acce45 100644
--- a/libnm-glib/nm-device-olpc-mesh.c
+++ b/libnm-glib/nm-device-olpc-mesh.c
@@ -22,11 +22,10 @@
 
 #include <string.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-olpc-mesh.h>
 
+#include "nm-default.h"
 #include "nm-device-olpc-mesh.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-private.h b/libnm-glib/nm-device-private.h
index 82d676f9..1a29c97d 100644
--- a/libnm-glib/nm-device-private.h
+++ b/libnm-glib/nm-device-private.h
@@ -22,5 +22,6 @@
 #define NM_DEVICE_PRIVATE_H
 
 void _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype);
+NMDeviceType _nm_device_type_for_path (DBusGConnection *connection, const char *path);
 
 #endif /* NM_DEVICE_PRIVATE_H */
diff --git a/libnm-glib/nm-device-team.c b/libnm-glib/nm-device-team.c
index d9a5fce0..e7622962 100644
--- a/libnm-glib/nm-device-team.c
+++ b/libnm-glib/nm-device-team.c
@@ -23,12 +23,11 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-team.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-device-team.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-vlan.c b/libnm-glib/nm-device-vlan.c
index 26c234bd..fe3db03a 100644
--- a/libnm-glib/nm-device-vlan.c
+++ b/libnm-glib/nm-device-vlan.c
@@ -23,12 +23,11 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-vlan.h>
 #include <nm-utils.h>
 
+#include "nm-default.h"
 #include "nm-device-vlan.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-wifi.c b/libnm-glib/nm-device-wifi.c
index 28609c79..05b47b4d 100644
--- a/libnm-glib/nm-device-wifi.c
+++ b/libnm-glib/nm-device-wifi.c
@@ -24,12 +24,11 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-wireless.h>
 #include <nm-setting-wireless-security.h>
 
+#include "nm-default.h"
 #include "nm-device-wifi.h"
 #include "nm-device-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c
index f0187fdc..70c8b14e 100644
--- a/libnm-glib/nm-device-wimax.c
+++ b/libnm-glib/nm-device-wimax.c
@@ -24,11 +24,10 @@
 #include <string.h>
 #include <netinet/ether.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-setting-connection.h>
 #include <nm-setting-wimax.h>
 
+#include "nm-default.h"
 #include "nm-device-wimax.h"
 #include "nm-object-private.h"
 #include "nm-object-cache.h"
@@ -84,6 +83,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
  * Registers an error quark for #NMDeviceWimax if necessary.
  *
  * Returns: the error quark used for #NMDeviceWimax errors.
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 GQuark
 nm_device_wimax_error_quark (void)
@@ -103,6 +104,8 @@ nm_device_wimax_error_quark (void)
  * Creates a new #NMDeviceWimax.
  *
  * Returns: (transfer full): a new WiMAX device
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 GObject *
 nm_device_wimax_new (DBusGConnection *connection, const char *path)
@@ -128,6 +131,8 @@ nm_device_wimax_new (DBusGConnection *connection, const char *path)
  *
  * Returns: the hardware address. This is the internal string used by the
  *          device, and must not be modified.
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 const char *
 nm_device_wimax_get_hw_address (NMDeviceWimax *wimax)
@@ -145,6 +150,8 @@ nm_device_wimax_get_hw_address (NMDeviceWimax *wimax)
  * Gets the active #NMWimaxNsp.
  *
  * Returns: (transfer full): the access point or %NULL if none is active
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 NMWimaxNsp *
 nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax)
@@ -182,6 +189,8 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax)
  * Returns: (element-type NMWimaxNsp): a #GPtrArray containing
  *          all the scanned #NMWimaxNsps.
  * The returned array is owned by the client and should not be modified.
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 const GPtrArray *
 nm_device_wimax_get_nsps (NMDeviceWimax *wimax)
@@ -200,6 +209,8 @@ nm_device_wimax_get_nsps (NMDeviceWimax *wimax)
  * Gets a #NMWimaxNsp by path.
  *
  * Returns: (transfer none): the access point or %NULL if none is found.
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 NMWimaxNsp *
 nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax,
@@ -264,6 +275,8 @@ clean_up_nsps (NMDeviceWimax *self, gboolean notify)
  * device is not connected.
  *
  * Returns: the center frequency in KHz, or 0
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 guint
 nm_device_wimax_get_center_frequency (NMDeviceWimax *self)
@@ -284,6 +297,8 @@ nm_device_wimax_get_center_frequency (NMDeviceWimax *self)
  * device is not connected.
  *
  * Returns: the RSSI in dBm, or 0
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 gint
 nm_device_wimax_get_rssi (NMDeviceWimax *self)
@@ -303,6 +318,8 @@ nm_device_wimax_get_rssi (NMDeviceWimax *self)
  * meaning when the device is not connected.
  *
  * Returns: the CINR in dB, or 0
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 gint
 nm_device_wimax_get_cinr (NMDeviceWimax *self)
@@ -322,6 +339,8 @@ nm_device_wimax_get_cinr (NMDeviceWimax *self)
  * -5.5 dBm.  Has no meaning when the device is not connected.
  *
  * Returns: the TX power in dBm, or 0
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 gint
 nm_device_wimax_get_tx_power (NMDeviceWimax *self)
@@ -339,6 +358,8 @@ nm_device_wimax_get_tx_power (NMDeviceWimax *self)
  * Gets the ID of the serving Base Station when the device is connected.
  *
  * Returns: the ID of the serving Base Station, or %NULL
+ *
+ * Deprecated: 1.2: WiMAX is no longer supported.
  **/
 const char *
 nm_device_wimax_get_bsid (NMDeviceWimax *self)
@@ -614,6 +635,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * NMDeviceWimax:hw-address:
 	 *
 	 * The hardware (MAC) address of the device.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_HW_ADDRESS,
@@ -626,6 +649,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * NMDeviceWimax:active-nsp:
 	 *
 	 * The active #NMWimaxNsp of the device.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_ACTIVE_NSP,
@@ -640,6 +665,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * The center frequency (in KHz) of the radio channel the device is using to
 	 * communicate with the network when connected.  Has no meaning when the
 	 * device is not connected.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_CENTER_FREQ,
@@ -655,6 +682,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * the raw received RF signal from the base station is, but does not
 	 * indicate the overall quality of the radio link.  Has no meaning when the
 	 * device is not connected.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_RSSI,
@@ -669,6 +698,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * CINR (Carrier to Interference + Noise Ratio) of the current radio link
 	 * in dB.  CINR is a more accurate measure of radio link quality.  Has no
 	 * meaning when the device is not connected.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_CINR,
@@ -683,6 +714,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * Average power of the last burst transmitted by the device, in units of
 	 * 0.5 dBm.  i.e. a TxPower of -11 represents an actual device TX power of
 	 * -5.5 dBm.  Has no meaning when the device is not connected.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_TX_POWER,
@@ -696,6 +729,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 *
 	 * The ID of the serving base station as received from the network.  Has
 	 * no meaning when the device is not connected.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_BSID,
@@ -710,6 +745,7 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * List of all WiMAX Network Service Providers the device can see.
 	 *
 	 * Since: 0.9.10
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_NSPS,
@@ -726,6 +762,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * @nsp: the new NSP
 	 *
 	 * Notifies that a #NMWimaxNsp is added to the wimax device.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	signals[NSP_ADDED] =
 		g_signal_new ("nsp-added",
@@ -743,6 +781,8 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
 	 * @nsp: the removed NSP
 	 *
 	 * Notifies that a #NMWimaxNsp is removed from the wimax device.
+	 *
+	 * Deprecated: 1.2: WiMAX is no longer supported.
 	 **/
 	signals[NSP_REMOVED] =
 		g_signal_new ("nsp-removed",
diff --git a/libnm-glib/nm-device-wimax.h b/libnm-glib/nm-device-wimax.h
index 1b889d95..24e46348 100644
--- a/libnm-glib/nm-device-wimax.h
+++ b/libnm-glib/nm-device-wimax.h
@@ -51,6 +51,7 @@ typedef enum {
 } NMDeviceWimaxError;
 
 #define NM_DEVICE_WIMAX_ERROR nm_device_wimax_error_quark ()
+NM_DEPRECATED_IN_1_2
 GQuark nm_device_wimax_error_quark (void);
 
 #define NM_DEVICE_WIMAX_HW_ADDRESS       "hw-address"
@@ -74,22 +75,33 @@ typedef struct {
 	void (*nsp_removed) (NMDeviceWimax *self, NMWimaxNsp *nsp);
 } NMDeviceWimaxClass;
 
+NM_DEPRECATED_IN_1_2
 GType nm_device_wimax_get_type (void);
 
+NM_DEPRECATED_IN_1_2
 GObject         *nm_device_wimax_new             (DBusGConnection *connection,
                                                   const char *path);
 
+NM_DEPRECATED_IN_1_2
 const char      *nm_device_wimax_get_hw_address  (NMDeviceWimax *wimax);
+NM_DEPRECATED_IN_1_2
 NMWimaxNsp      *nm_device_wimax_get_active_nsp  (NMDeviceWimax *wimax);
+NM_DEPRECATED_IN_1_2
 NMWimaxNsp      *nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax,
                                                   const char *path);
 
+NM_DEPRECATED_IN_1_2
 const GPtrArray *nm_device_wimax_get_nsps        (NMDeviceWimax *wimax);
 
+NM_DEPRECATED_IN_1_2
 guint            nm_device_wimax_get_center_frequency (NMDeviceWimax *self);
+NM_DEPRECATED_IN_1_2
 gint             nm_device_wimax_get_rssi        (NMDeviceWimax *self);
+NM_DEPRECATED_IN_1_2
 gint             nm_device_wimax_get_cinr        (NMDeviceWimax *self);
+NM_DEPRECATED_IN_1_2
 gint             nm_device_wimax_get_tx_power    (NMDeviceWimax *self);
+NM_DEPRECATED_IN_1_2
 const char *     nm_device_wimax_get_bsid        (NMDeviceWimax *self);
 
 G_END_DECLS
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
index bd5d1637..b1f8cfb2 100644
--- a/libnm-glib/nm-device.c
+++ b/libnm-glib/nm-device.c
@@ -23,9 +23,9 @@
 
 #include <string.h>
 
-#include <glib/gi18n-lib.h>
 #include <gudev/gudev.h>
 
+#include "nm-default.h"
 #include "NetworkManager.h"
 #include "nm-device-ethernet.h"
 #include "nm-device-adsl.h"
@@ -47,21 +47,20 @@
 #include "nm-remote-connection.h"
 #include "nm-types.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-glib-compat.h"
 #include "nm-utils.h"
 #include "nm-dbus-helpers-private.h"
 
-static GType _nm_device_type_for_path (DBusGConnection *connection,
-                                       const char *path);
-static void _nm_device_type_for_path_async (DBusGConnection *connection,
-                                            const char *path,
-                                            NMObjectTypeCallbackFunc callback,
-                                            gpointer user_data);
+static GType _nm_device_gtype_for_path (DBusGConnection *connection,
+                                        const char *path);
+static void _nm_device_gtype_for_path_async (DBusGConnection *connection,
+                                             const char *path,
+                                             NMObjectTypeCallbackFunc callback,
+                                             gpointer user_data);
 gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error);
 
 G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT,
-                         _nm_object_register_type_func (g_define_type_id, _nm_device_type_for_path,
-                                                        _nm_device_type_for_path_async);
+                         _nm_object_register_type_func (g_define_type_id, _nm_device_gtype_for_path,
+                                                        _nm_device_gtype_for_path_async);
                          )
 
 #define DBUS_G_TYPE_UINT_STRUCT (dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID))
@@ -80,6 +79,7 @@ typedef struct {
 	char *firmware_version;
 	char *type_description;
 	NMDeviceCapabilities capabilities;
+	gboolean real;
 	gboolean managed;
 	gboolean firmware_missing;
 	gboolean autoconnect;
@@ -111,6 +111,7 @@ enum {
 	PROP_DRIVER_VERSION,
 	PROP_FIRMWARE_VERSION,
 	PROP_CAPABILITIES,
+	PROP_REAL,
 	PROP_MANAGED,
 	PROP_AUTOCONNECT,
 	PROP_FIRMWARE_MISSING,
@@ -197,6 +198,7 @@ register_properties (NMDevice *device)
 		{ NM_DEVICE_DRIVER_VERSION,    &priv->driver_version },
 		{ NM_DEVICE_FIRMWARE_VERSION,  &priv->firmware_version },
 		{ NM_DEVICE_CAPABILITIES,      &priv->capabilities },
+		{ NM_DEVICE_REAL,              &priv->real },
 		{ NM_DEVICE_MANAGED,           &priv->managed },
 		{ NM_DEVICE_AUTOCONNECT,       &priv->autoconnect },
 		{ NM_DEVICE_FIRMWARE_MISSING,  &priv->firmware_missing },
@@ -321,10 +323,12 @@ _nm_device_gtype_from_dtype (NMDeviceType dtype)
 	case NM_DEVICE_TYPE_VLAN:
 		return NM_TYPE_DEVICE_VLAN;
 	case NM_DEVICE_TYPE_GENERIC:
+	case NM_DEVICE_TYPE_TUN:
+	case NM_DEVICE_TYPE_IP_TUNNEL:
 		return NM_TYPE_DEVICE_GENERIC;
 	default:
-		g_warning ("Unknown device type %d", dtype);
-		return G_TYPE_INVALID;
+		/* Fall back to NMDeviceGeneric for unknown devices */
+		return NM_TYPE_DEVICE_GENERIC;
 	}
 }
 
@@ -445,6 +449,9 @@ get_property (GObject *object,
 	case PROP_CAPABILITIES:
 		g_value_set_uint (value, nm_device_get_capabilities (device));
 		break;
+	case PROP_REAL:
+		g_value_set_boolean (value, nm_device_is_real (device));
+		break;
 	case PROP_MANAGED:
 		g_value_set_boolean (value, nm_device_get_managed (device));
 		break;
@@ -516,6 +523,11 @@ set_property (GObject *object,
 		/* Construct only */
 		priv->device_type = g_value_get_uint (value);
 		break;
+	case PROP_MANAGED:
+		b = g_value_get_boolean (value);
+		if (priv->managed != b)
+			nm_device_set_managed (NM_DEVICE (object), b);
+		break;
 	case PROP_AUTOCONNECT:
 		b = g_value_get_boolean (value);
 		if (priv->autoconnect != b)
@@ -647,6 +659,22 @@ nm_device_class_init (NMDeviceClass *device_class)
 		                    G_PARAM_STATIC_STRINGS));
 
 	/**
+	 * NMDevice:real:
+	 *
+	 * Whether the device is real or is a placeholder device that could
+	 * be created automatically by NetworkManager if one of its
+	 * #NMDevice:available-connections was activated.
+	 *
+	 * Since: 1.2
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_REAL,
+		 g_param_spec_boolean (NM_DEVICE_REAL, "", "",
+		                       FALSE,
+		                       G_PARAM_READABLE |
+		                       G_PARAM_STATIC_STRINGS));
+
+	/**
 	 * NMDevice:managed:
 	 *
 	 * Whether the device is managed by NetworkManager.
@@ -878,16 +906,14 @@ _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype)
 		g_warn_if_fail (dtype == priv->device_type);
 }
 
-static GType
-_nm_device_type_for_path (DBusGConnection *connection,
-                          const char *path)
+NMDeviceType
+_nm_device_type_for_path (DBusGConnection *connection, const char *path)
 {
 	DBusGProxy *proxy;
 	GError *err = NULL;
 	GValue value = G_VALUE_INIT;
-	NMDeviceType nm_dtype;
 
-	proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties");
+	proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
 	if (!proxy) {
 		g_warning ("%s: couldn't create D-Bus object proxy.", __func__);
 		return G_TYPE_INVALID;
@@ -906,8 +932,14 @@ _nm_device_type_for_path (DBusGConnection *connection,
 	}
 	g_object_unref (proxy);
 
-	nm_dtype = g_value_get_uint (&value);
-	return _nm_device_gtype_from_dtype (nm_dtype);
+	return g_value_get_uint (&value);
+}
+
+static GType
+_nm_device_gtype_for_path (DBusGConnection *connection,
+                           const char *path)
+{
+	return _nm_device_gtype_from_dtype (_nm_device_type_for_path (connection, path));
 }
 
 /**
@@ -928,7 +960,7 @@ nm_device_new (DBusGConnection *connection, const char *path)
 	g_return_val_if_fail (connection != NULL, NULL);
 	g_return_val_if_fail (path != NULL, NULL);
 
-	dtype = _nm_device_type_for_path (connection, path);
+	dtype = _nm_device_gtype_for_path (connection, path);
 	if (dtype == G_TYPE_INVALID)
 		return NULL;
 
@@ -974,7 +1006,7 @@ async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
 }
 
 static void
-_nm_device_type_for_path_async (DBusGConnection *connection,
+_nm_device_gtype_for_path_async (DBusGConnection *connection,
                                 const char *path,
                                 NMObjectTypeCallbackFunc callback,
                                 gpointer user_data)
@@ -987,7 +1019,7 @@ _nm_device_type_for_path_async (DBusGConnection *connection,
 	async_data->callback = callback;
 	async_data->user_data = user_data;
 
-	proxy = _nm_dbus_new_proxy_for_connection (connection, path, "org.freedesktop.DBus.Properties");
+	proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
 	dbus_g_proxy_begin_call (proxy, "Get",
 	                         async_got_type, async_data, NULL,
 	                         G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE,
@@ -1215,6 +1247,35 @@ nm_device_get_managed (NMDevice *device)
 }
 
 /**
+ * nm_device_set_managed:
+ * @device: a #NMDevice
+ * @managed: %TRUE to make the device managed by NetworkManager.
+ *
+ * Enables or disables management of  #NMDevice by NetworkManager.
+ *
+ * Since: 1.2
+ **/
+void
+nm_device_set_managed (NMDevice *device, gboolean managed)
+{
+	GValue value = G_VALUE_INIT;
+
+	g_return_if_fail (NM_IS_DEVICE (device));
+
+	managed = !!managed;
+
+	g_value_init (&value, G_TYPE_BOOLEAN);
+	g_value_set_boolean (&value, managed);
+
+	NM_DEVICE_GET_PRIVATE (device)->managed = managed;
+
+	_nm_object_set_property (NM_OBJECT (device),
+	                         NM_DBUS_INTERFACE_DEVICE,
+	                         "Managed",
+	                         &value);
+}
+
+/**
  * nm_device_get_autoconnect:
  * @device: a #NMDevice
  *
@@ -2067,6 +2128,25 @@ nm_device_get_mtu (NMDevice *device)
 }
 
 /**
+ * nm_device_is_real:
+ * @device: a #NMDevice
+ *
+ * Returns: %TRUE if the device exists, or %FALSE if it is a placeholder device
+ * that could be automatically created by NetworkManager if one of its
+ * #NMDevice:available-connections was activated.
+ *
+ * Since: 1.2
+ **/
+gboolean
+nm_device_is_real (NMDevice *device)
+{
+	g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
+
+	_nm_object_ensure_inited (NM_OBJECT (device));
+	return NM_DEVICE_GET_PRIVATE (device)->real;
+}
+
+/**
  * nm_device_is_software:
  * @device: a #NMDevice
  *
diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h
index 707fddf8..d2d154dc 100644
--- a/libnm-glib/nm-device.h
+++ b/libnm-glib/nm-device.h
@@ -66,6 +66,7 @@ GQuark nm_device_error_quark (void);
 #define NM_DEVICE_DRIVER_VERSION "driver-version"
 #define NM_DEVICE_FIRMWARE_VERSION "firmware-version"
 #define NM_DEVICE_CAPABILITIES "capabilities"
+#define NM_DEVICE_REAL "real"
 #define NM_DEVICE_MANAGED "managed"
 #define NM_DEVICE_AUTOCONNECT "autoconnect"
 #define NM_DEVICE_FIRMWARE_MISSING "firmware-missing"
@@ -127,6 +128,8 @@ NM_AVAILABLE_IN_0_9_10
 const char *         nm_device_get_hw_address       (NMDevice *device);
 NMDeviceCapabilities nm_device_get_capabilities     (NMDevice *device);
 gboolean             nm_device_get_managed          (NMDevice *device);
+NM_AVAILABLE_IN_1_2
+void                 nm_device_set_managed          (NMDevice *device, gboolean managed);
 gboolean             nm_device_get_autoconnect      (NMDevice *device);
 void                 nm_device_set_autoconnect      (NMDevice *device, gboolean autoconnect);
 gboolean             nm_device_get_firmware_missing (NMDevice *device);
@@ -144,6 +147,8 @@ NM_AVAILABLE_IN_0_9_10
 guint32              nm_device_get_mtu              (NMDevice *device);
 NM_AVAILABLE_IN_1_0
 gboolean             nm_device_is_software          (NMDevice *device);
+NM_AVAILABLE_IN_1_2
+gboolean             nm_device_is_real              (NMDevice *device);
 
 const char *         nm_device_get_product           (NMDevice  *device);
 const char *         nm_device_get_vendor            (NMDevice  *device);
diff --git a/libnm-glib/nm-glib-enum-types.c b/libnm-glib/nm-glib-enum-types.c
index 8e8b0ff9..f3030aa5 100644
--- a/libnm-glib/nm-glib-enum-types.c
+++ b/libnm-glib/nm-glib-enum-types.c
@@ -3,6 +3,8 @@
 
 /* Generated by glib-mkenums. Do not edit */
 
+#include "config.h"
+
 #include "nm-glib-enum-types.h"
 
 #include "nm-object.h" 
diff --git a/libnm-glib/nm-object-cache.c b/libnm-glib/nm-object-cache.c
index 752c606a..82af1140 100644
--- a/libnm-glib/nm-object-cache.c
+++ b/libnm-glib/nm-object-cache.c
@@ -21,7 +21,7 @@
 #include "config.h"
 
 #include <string.h>
-#include <glib.h>
+#include "nm-default.h"
 #include "nm-object-cache.h"
 #include "nm-object.h"
 
diff --git a/libnm-glib/nm-object-cache.h b/libnm-glib/nm-object-cache.h
index 7aca3b4f..30b62f08 100644
--- a/libnm-glib/nm-object-cache.h
+++ b/libnm-glib/nm-object-cache.h
@@ -21,8 +21,7 @@
 #ifndef NM_OBJECT_CACHE_H
 #define NM_OBJECT_CACHE_H
 
-#include <glib.h>
-#include <glib-object.h>
+#include "nm-default.h"
 #include "nm-object.h"
 
 G_BEGIN_DECLS
diff --git a/libnm-glib/nm-object-private.h b/libnm-glib/nm-object-private.h
index 75e63b2e..8878354f 100644
--- a/libnm-glib/nm-object-private.h
+++ b/libnm-glib/nm-object-private.h
@@ -21,7 +21,7 @@
 #ifndef NM_OBJECT_PRIVATE_H
 #define NM_OBJECT_PRIVATE_H
 
-#include <gio/gio.h>
+#include "nm-default.h"
 #include "nm-object.h"
 
 void _nm_object_ensure_inited (NMObject *object);
@@ -42,8 +42,6 @@ DBusGProxy *_nm_object_new_proxy (NMObject *self,
                                   const char *path,
                                   const char *interface);
 
-gboolean _nm_object_is_connection_private (NMObject *self);
-
 void _nm_object_register_properties (NMObject *object,
                                      DBusGProxy *proxy,
                                      const NMPropertiesInfo *info);
diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c
index fb25c1ac..f2f46e01 100644
--- a/libnm-glib/nm-object.c
+++ b/libnm-glib/nm-object.c
@@ -22,16 +22,15 @@
 #include "config.h"
 
 #include <string.h>
-#include <gio/gio.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <nm-utils.h>
+#include "nm-default.h"
 #include "NetworkManager.h"
 #include "nm-object.h"
 #include "nm-object-cache.h"
 #include "nm-object-private.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-glib-compat.h"
 #include "nm-types.h"
 #include "nm-dbus-helpers-private.h"
 
@@ -59,7 +58,7 @@ typedef struct {
 	const char *signal_prefix;
 } PropertyInfo;
 
-static void reload_complete (NMObject *object);
+static void reload_complete (NMObject *object, gboolean emit_now);
 
 typedef struct {
 	DBusGConnection *connection;
@@ -73,7 +72,7 @@ typedef struct {
 	NMObject *parent;
 	gboolean suppress_property_updates;
 
-	GSList *notify_props;
+	GSList *notify_items;
 	guint32 notify_id;
 	gboolean inited;
 
@@ -115,6 +114,27 @@ nm_object_error_quark (void)
 	return quark;
 }
 
+typedef enum {
+	NOTIFY_SIGNAL_PENDING_NONE,
+	NOTIFY_SIGNAL_PENDING_ADDED,
+	NOTIFY_SIGNAL_PENDING_REMOVED,
+	NOTIFY_SIGNAL_PENDING_ADDED_REMOVED,
+} NotifySignalPending;
+
+typedef struct {
+	const char *property;
+	const char *signal_prefix;
+	NotifySignalPending pending;
+	NMObject *changed;
+} NotifyItem;
+
+static void
+notify_item_free (NotifyItem *item)
+{
+	g_clear_object (&item->changed);
+	g_slice_free (NotifyItem, item);
+}
+
 static void
 proxy_name_owner_changed (DBusGProxy *proxy,
                           const char *name,
@@ -173,25 +193,21 @@ constructed (GObject *object)
 	if (G_OBJECT_CLASS (nm_object_parent_class)->constructed)
 		G_OBJECT_CLASS (nm_object_parent_class)->constructed (object);
 
-	priv->properties_proxy = _nm_object_new_proxy (self, NULL, "org.freedesktop.DBus.Properties");
-
-	if (_nm_object_is_connection_private (self))
-		priv->nm_running = TRUE;
-	else {
-		priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
-		                                             DBUS_SERVICE_DBUS,
-		                                             DBUS_PATH_DBUS,
-		                                             DBUS_INTERFACE_DBUS);
-		g_assert (priv->bus_proxy);
-
-		dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
-		                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-		                         G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal (priv->bus_proxy,
-		                             "NameOwnerChanged",
-		                             G_CALLBACK (proxy_name_owner_changed),
-		                             object, NULL);
-	}
+	priv->properties_proxy = _nm_object_new_proxy (self, NULL, DBUS_INTERFACE_PROPERTIES);
+
+	priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
+	                                             DBUS_SERVICE_DBUS,
+	                                             DBUS_PATH_DBUS,
+	                                             DBUS_INTERFACE_DBUS);
+	g_assert (priv->bus_proxy);
+
+	dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
+	                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+	                         G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (priv->bus_proxy,
+	                             "NameOwnerChanged",
+	                             G_CALLBACK (proxy_name_owner_changed),
+	                             object, NULL);
 }
 
 static gboolean
@@ -273,16 +289,12 @@ init_async (GAsyncInitable *initable, int io_priority,
 
 	simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async);
 
-	if (_nm_object_is_connection_private (NM_OBJECT (initable)))
-		_nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple);
-	else {
-		/* Check if NM is running */
-		dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
-		                         init_async_got_manager_running,
-		                         simple, NULL,
-		                         G_TYPE_STRING, NM_DBUS_SERVICE,
-		                         G_TYPE_INVALID);
-	}
+	/* Check if NM is running */
+	dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
+	                         init_async_got_manager_running,
+	                         simple, NULL,
+	                         G_TYPE_STRING, NM_DBUS_SERVICE,
+	                         G_TYPE_INVALID);
 }
 
 static gboolean
@@ -306,8 +318,8 @@ dispose (GObject *object)
 		priv->notify_id = 0;
 	}
 
-	g_slist_free_full (priv->notify_props, g_free);
-	priv->notify_props = NULL;
+	g_slist_free_full (priv->notify_items, (GDestroyNotify) notify_item_free);
+	priv->notify_items = NULL;
 
 	g_slist_free_full (priv->property_interfaces, g_free);
 	priv->property_interfaces = NULL;
@@ -493,52 +505,155 @@ deferred_notify_cb (gpointer data)
 {
 	NMObject *object = NM_OBJECT (data);
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
+	NMObjectClass *object_class = NM_OBJECT_GET_CLASS (object);
 	GSList *props, *iter;
 
 	priv->notify_id = 0;
 
-	/* Clear priv->notify_props early so that an NMObject subclass that
+	/* Wait until all reloads are done before notifying */
+	if (priv->reload_remaining)
+		return G_SOURCE_REMOVE;
+
+	/* Clear priv->notify_items early so that an NMObject subclass that
 	 * listens to property changes can queue up other property changes
 	 * during the g_object_notify() call separately from the property
 	 * list we're iterating.
 	 */
-	props = g_slist_reverse (priv->notify_props);
-	priv->notify_props = NULL;
+	props = g_slist_reverse (priv->notify_items);
+	priv->notify_items = NULL;
 
 	g_object_ref (object);
+
+	/* Emit property change notifications first */
 	for (iter = props; iter; iter = g_slist_next (iter)) {
-		g_object_notify (G_OBJECT (object), (const char *) iter->data);
-		g_free (iter->data);
+		NotifyItem *item = iter->data;
+
+		if (item->property)
+			g_object_notify (G_OBJECT (object), item->property);
+	}
+
+	/* And added/removed signals second */
+	for (iter = props; iter; iter = g_slist_next (iter)) {
+		NotifyItem *item = iter->data;
+		char buf[50];
+		gint ret = 0;
+
+		switch (item->pending) {
+		case NOTIFY_SIGNAL_PENDING_ADDED:
+			ret = g_snprintf (buf, sizeof (buf), "%s-added", item->signal_prefix);
+			break;
+		case NOTIFY_SIGNAL_PENDING_REMOVED:
+			ret = g_snprintf (buf, sizeof (buf), "%s-removed", item->signal_prefix);
+			break;
+		case NOTIFY_SIGNAL_PENDING_ADDED_REMOVED:
+			// XXX
+			if (object_class->object_creation_failed)
+				object_class->object_creation_failed (object, NULL, g_strdup (nm_object_get_path (item->changed)));
+			break;
+		case NOTIFY_SIGNAL_PENDING_NONE:
+		default:
+			break;
+		}
+		if (ret > 0) {
+			g_assert (ret < sizeof (buf));
+			g_signal_emit_by_name (object, buf, item->changed);
+		}
 	}
 	g_object_unref (object);
 
-	g_slist_free (props);
-	return FALSE;
+	g_slist_free_full (props, (GDestroyNotify) notify_item_free);
+	return G_SOURCE_REMOVE;
 }
 
-void
-_nm_object_queue_notify (NMObject *object, const char *property)
+static void
+_nm_object_defer_notify (NMObject *object)
+{
+	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
+
+	if (!priv->notify_id)
+		priv->notify_id = g_idle_add_full (G_PRIORITY_LOW, deferred_notify_cb, object, NULL);
+}
+
+static void
+_nm_object_queue_notify_full (NMObject *object,
+                              const char *property,
+                              const char *signal_prefix,
+                              gboolean added,
+                              NMObject *changed)
 {
 	NMObjectPrivate *priv;
-	gboolean found = FALSE;
+	NotifyItem *item;
 	GSList *iter;
 
 	g_return_if_fail (NM_IS_OBJECT (object));
-	g_return_if_fail (property != NULL);
+	g_return_if_fail (!signal_prefix != !property);
+	g_return_if_fail (!signal_prefix == !changed);
 
 	priv = NM_OBJECT_GET_PRIVATE (object);
-	if (!priv->notify_id)
-		priv->notify_id = g_idle_add_full (G_PRIORITY_LOW, deferred_notify_cb, object, NULL);
-
-	for (iter = priv->notify_props; iter; iter = g_slist_next (iter)) {
-		if (!strcmp ((char *) iter->data, property)) {
-			found = TRUE;
-			break;
+	_nm_object_defer_notify (object);
+
+	property = g_intern_string (property);
+	signal_prefix = g_intern_string (signal_prefix);
+	for (iter = priv->notify_items; iter; iter = g_slist_next (iter)) {
+		item = iter->data;
+
+		if (property && (property == item->property))
+			return;
+
+		/* Collapse signals for the same object (such as "added->removed") to
+		 * ensure we don't emit signals when their sum should have no effect.
+		 * The "added->removed->removed" sequence requires special handling,
+		 * hence the addition of the ADDED_REMOVED state to ensure that no
+		 * signal is emitted in this case:
+		 *
+		 * Without the ADDED_REMOVED state:
+		 *     NONE          + added   -> ADDED
+		 *     ADDED         + removed -> NONE
+		 *     NONE          + removed -> REMOVED (would emit 'removed' signal)
+		 *
+		 * With the ADDED_REMOVED state:
+		 *     NONE | ADDED_REMOVED  + added   -> ADDED
+		 *     ADDED                 + removed -> ADDED_REMOVED
+		 *     ADDED_REMOVED         + removed -> ADDED_REMOVED (emits no signal)
+		 */
+		if (signal_prefix && (changed == item->changed) && (item->signal_prefix == signal_prefix)) {
+			switch (item->pending) {
+			case NOTIFY_SIGNAL_PENDING_ADDED:
+				if (!added)
+					item->pending = NOTIFY_SIGNAL_PENDING_ADDED_REMOVED;
+				break;
+			case NOTIFY_SIGNAL_PENDING_REMOVED:
+				if (added)
+					item->pending = NOTIFY_SIGNAL_PENDING_NONE;
+				break;
+			case NOTIFY_SIGNAL_PENDING_ADDED_REMOVED:
+				if (added)
+					item->pending = NOTIFY_SIGNAL_PENDING_ADDED;
+				break;
+			case NOTIFY_SIGNAL_PENDING_NONE:
+				item->pending = added ? NOTIFY_SIGNAL_PENDING_ADDED : NOTIFY_SIGNAL_PENDING_REMOVED;
+				break;
+			default:
+				g_assert_not_reached ();
+			}
+			return;
 		}
 	}
 
-	if (!found)
-		priv->notify_props = g_slist_prepend (priv->notify_props, g_strdup (property));
+	item = g_slice_new0 (NotifyItem);
+	item->property = property;
+	if (signal_prefix) {
+		item->signal_prefix = signal_prefix;
+		item->pending = added ? NOTIFY_SIGNAL_PENDING_ADDED : NOTIFY_SIGNAL_PENDING_REMOVED;
+		item->changed = changed ? g_object_ref (changed) : NULL;
+	}
+	priv->notify_items = g_slist_prepend (priv->notify_items, item);
+}
+
+void
+_nm_object_queue_notify (NMObject *object, const char *property)
+{
+	_nm_object_queue_notify_full (object, property, NULL, FALSE, NULL);
 }
 
 void
@@ -768,17 +883,12 @@ array_diff (GPtrArray *needles, GPtrArray *haystack, GPtrArray *diff)
 }
 
 static void
-emit_added_removed_signal (NMObject *self,
-                           const char *signal_prefix,
-                           NMObject *changed,
-                           gboolean added)
+queue_added_removed_signal (NMObject *self,
+                            const char *signal_prefix,
+                            NMObject *changed,
+                            gboolean added)
 {
-	char buf[50];
-	int ret;
-
-	ret = g_snprintf (buf, sizeof (buf), "%s-%s", signal_prefix, added ? "added" : "removed");
-	g_assert (ret < sizeof (buf));
-	g_signal_emit_by_name (self, buf, changed);
+	_nm_object_queue_notify_full (self, NULL, signal_prefix, added, changed);
 }
 
 static void
@@ -818,17 +928,17 @@ object_property_complete (ObjectCreatedData *odata)
 
 			/* Emit added & removed */
 			for (i = 0; i < removed->len; i++) {
-				emit_added_removed_signal (self,
-				                           pi->signal_prefix,
-				                           g_ptr_array_index (removed, i),
-				                           FALSE);
+				queue_added_removed_signal (self,
+				                            pi->signal_prefix,
+				                            g_ptr_array_index (removed, i),
+				                            FALSE);
 			}
 
 			for (i = 0; i < added->len; i++) {
-				emit_added_removed_signal (self,
-				                           pi->signal_prefix,
-				                           g_ptr_array_index (added, i),
-				                           TRUE);
+				queue_added_removed_signal (self,
+				                            pi->signal_prefix,
+				                            g_ptr_array_index (added, i),
+				                            TRUE);
 			}
 
 			different = removed->len || added->len;
@@ -859,8 +969,8 @@ object_property_complete (ObjectCreatedData *odata)
 	if (different && odata->property_name)
 		_nm_object_queue_notify (self, odata->property_name);
 
-	if (priv->reload_results && --priv->reload_remaining == 0)
-		reload_complete (self);
+	if (--priv->reload_remaining == 0)
+		reload_complete (self, FALSE);
 
 	g_object_unref (self);
 	g_free (odata->objects);
@@ -907,8 +1017,7 @@ handle_object_property (NMObject *self, const char *property_name, GValue *value
 	odata->array = FALSE;
 	odata->property_name = property_name;
 
-	if (priv->reload_results)
-		priv->reload_remaining++;
+	priv->reload_remaining++;
 
 	path = g_value_get_boxed (value);
 
@@ -955,8 +1064,7 @@ handle_object_array_property (NMObject *self, const char *property_name, GValue
 	odata->array = TRUE;
 	odata->property_name = property_name;
 
-	if (priv->reload_results)
-		priv->reload_remaining++;
+	priv->reload_remaining++;
 
 	if (paths->len == 0) {
 		object_property_complete (odata);
@@ -1137,8 +1245,8 @@ demarshal_generic (NMObject *object,
 	HANDLE_TYPE(DOUBLE, double, double)
 	HANDLE_TYPE(INT, int, int)
 	HANDLE_TYPE(UINT, uint, uint)
-	HANDLE_TYPE(INT64, int, int)
-	HANDLE_TYPE(UINT64, uint, uint)
+	HANDLE_TYPE(INT64, int64, int64)
+	HANDLE_TYPE(UINT64, uint64, uint64)
 	HANDLE_TYPE(LONG, long, long)
 	HANDLE_TYPE(ULONG, ulong, ulong)
 	} else {
@@ -1223,6 +1331,8 @@ _nm_object_reload_properties (NMObject *object, GError **error)
 	if (!priv->property_interfaces || !priv->nm_running)
 		return TRUE;
 
+	priv->reload_remaining++;
+
 	for (p = priv->property_interfaces; p; p = p->next) {
 		if (!dbus_g_proxy_call (priv->properties_proxy, "GetAll", error,
 		                        G_TYPE_STRING, p->data,
@@ -1235,6 +1345,9 @@ _nm_object_reload_properties (NMObject *object, GError **error)
 		g_hash_table_destroy (props);
 	}
 
+	if (--priv->reload_remaining == 0)
+		reload_complete (object, TRUE);
+
 	return TRUE;
 }
 
@@ -1331,13 +1444,22 @@ _nm_object_set_property (NMObject *object,
 }
 
 static void
-reload_complete (NMObject *object)
+reload_complete (NMObject *object, gboolean emit_now)
 {
 	NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
 	GSimpleAsyncResult *simple;
 	GSList *results, *iter;
 	GError *error;
 
+	if (emit_now) {
+		if (priv->notify_id) {
+			g_source_remove (priv->notify_id);
+			priv->notify_id = 0;
+		}
+		deferred_notify_cb (object);
+	} else
+		_nm_object_defer_notify (object);
+
 	results = priv->reload_results;
 	priv->reload_results = NULL;
 	error = priv->reload_error;
@@ -1380,7 +1502,7 @@ reload_got_properties (DBusGProxy *proxy, DBusGProxyCall *call,
 	}
 
 	if (--priv->reload_remaining == 0)
-		reload_complete (object);
+		reload_complete (object, FALSE);
 }
 
 void
@@ -1439,9 +1561,3 @@ _nm_object_new_proxy (NMObject *self, const char *path, const char *interface)
 
 	return _nm_dbus_new_proxy_for_connection (priv->connection, path ? path : priv->path, interface);
 }
-
-gboolean
-_nm_object_is_connection_private (NMObject *self)
-{
-	return _nm_dbus_is_connection_private (NM_OBJECT_GET_PRIVATE (self)->connection);
-}
diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c
index 3a70e81e..4298129b 100644
--- a/libnm-glib/nm-remote-connection.c
+++ b/libnm-glib/nm-remote-connection.c
@@ -22,17 +22,15 @@
 #include "config.h"
 
 #include <string.h>
-#include <gio/gio.h>
-#include <glib/gi18n-lib.h>
 
 #include <NetworkManager.h>
 #include <nm-utils.h>
 #include <nm-setting-connection.h>
+#include "nm-default.h"
 #include "nm-remote-connection.h"
 #include "nm-remote-connection-private.h"
 #include "nm-object-private.h"
 #include "nm-dbus-glib-types.h"
-#include "nm-glib-compat.h"
 #include "nm-dbus-helpers-private.h"
 
 #define NM_REMOTE_CONNECTION_BUS "bus"
@@ -498,6 +496,9 @@ updated_get_settings_cb (DBusGProxy *proxy,
 		priv->visible = FALSE;
 		g_signal_emit (self, signals[VISIBLE], 0, FALSE);
 	} else {
+		gs_unref_object NMConnection *self_alive = NULL;
+
+		self_alive = g_object_ref (self);
 		replace_settings (self, new_settings);
 		g_hash_table_destroy (new_settings);
 
@@ -620,6 +621,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
 {
 	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable);
 	GHashTable *hash;
+	gs_unref_object NMConnection *self_alive = NULL;
 
 	if (!dbus_g_proxy_call (priv->proxy, "GetSettings", error,
 	                        G_TYPE_INVALID,
@@ -627,6 +629,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
 	                        G_TYPE_INVALID))
 		return FALSE;
 	priv->visible = TRUE;
+	self_alive = g_object_ref (initable);
 	replace_settings (NM_REMOTE_CONNECTION (initable), hash);
 	g_hash_table_destroy (hash);
 
@@ -690,6 +693,7 @@ init_get_settings_cb (DBusGProxy *proxy,
 	NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection);
 	GHashTable *settings;
 	GError *error = NULL;
+	gs_unref_object NMConnection *self_alive = NULL;
 
 	dbus_g_proxy_end_call (proxy, call, &error,
 	                       DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings,
@@ -700,6 +704,7 @@ init_get_settings_cb (DBusGProxy *proxy,
 	}
 
 	priv->visible = TRUE;
+	self_alive = g_object_ref (init_data->connection);
 	replace_settings (init_data->connection, settings);
 	g_hash_table_destroy (settings);
 
diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c
index 80a274f5..421f7030 100644
--- a/libnm-glib/nm-remote-settings.c
+++ b/libnm-glib/nm-remote-settings.c
@@ -25,12 +25,12 @@
 #include <NetworkManager.h>
 #include <nm-connection.h>
 
+#include "nm-default.h"
 #include "nm-dbus-glib-types.h"
 #include "nm-remote-settings.h"
 #include "nm-remote-connection-private.h"
 #include "nm-object-private.h"
 #include "nm-dbus-helpers-private.h"
-#include "nm-glib-compat.h"
 #include "nm-object-private.h"
 
 /**
@@ -132,7 +132,6 @@ G_DEFINE_TYPE_WITH_CODE (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT,
 
 typedef struct {
 	DBusGConnection *bus;
-	gboolean private_bus;
 	gboolean inited;
 
 	DBusGProxy *proxy;
@@ -1177,26 +1176,24 @@ constructed (GObject *object)
 
 	priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
 
-	if (priv->private_bus == FALSE) {
-		/* D-Bus proxy for clearing connections on NameOwnerChanged */
-		priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
-		                                              DBUS_SERVICE_DBUS,
-		                                              DBUS_PATH_DBUS,
-		                                              DBUS_INTERFACE_DBUS);
-		g_assert (priv->dbus_proxy);
-
-		dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
-		                                   G_TYPE_NONE,
-		                                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-		                                   G_TYPE_INVALID);
-		dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
-		                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-		                         G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal (priv->dbus_proxy,
-		                             "NameOwnerChanged",
-		                             G_CALLBACK (name_owner_changed),
-		                             object, NULL);
-	}
+	/* D-Bus proxy for clearing connections on NameOwnerChanged */
+	priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+	                                              DBUS_SERVICE_DBUS,
+	                                              DBUS_PATH_DBUS,
+	                                              DBUS_INTERFACE_DBUS);
+	g_assert (priv->dbus_proxy);
+
+	dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
+	                                   G_TYPE_NONE,
+	                                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+	                                   G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
+	                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+	                         G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (priv->dbus_proxy,
+	                             "NameOwnerChanged",
+	                             G_CALLBACK (name_owner_changed),
+	                             object, NULL);
 
 	priv->proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
 	                                                 NM_DBUS_PATH_SETTINGS,
@@ -1215,7 +1212,7 @@ constructed (GObject *object)
 	/* D-Bus properties proxy */
 	priv->props_proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
 	                                                       NM_DBUS_PATH_SETTINGS,
-	                                                       "org.freedesktop.DBus.Properties");
+	                                                       DBUS_INTERFACE_PROPERTIES);
 	g_assert (priv->props_proxy);
 
 	/* Monitor properties */
@@ -1239,23 +1236,20 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
 	NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
 	GHashTable *props;
 
-	if (priv->private_bus == FALSE) {
-		if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", error,
-		                        G_TYPE_STRING, NM_DBUS_SERVICE,
-		                        G_TYPE_INVALID,
-		                        G_TYPE_BOOLEAN, &priv->service_running,
-		                        G_TYPE_INVALID)) {
-			priv->service_running = FALSE;
-			return FALSE;
-		}
+	if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", error,
+	                        G_TYPE_STRING, NM_DBUS_SERVICE,
+	                        G_TYPE_INVALID,
+	                        G_TYPE_BOOLEAN, &priv->service_running,
+	                        G_TYPE_INVALID)) {
+		priv->service_running = FALSE;
+		return FALSE;
+	}
 
-		/* If NM isn't running we'll grab properties from name_owner_changed()
-		 * when it starts.
-		 */
-		if (!priv->service_running)
-			return TRUE;
-	} else
-		priv->service_running = TRUE;
+	/* If NM isn't running we'll grab properties from name_owner_changed()
+	 * when it starts.
+	 */
+	if (!priv->service_running)
+		return TRUE;
 
 	priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections",
 	                                              fetch_connections_done, NM_REMOTE_SETTINGS (initable), NULL,
@@ -1376,17 +1370,12 @@ init_async (GAsyncInitable *initable, int io_priority,
 	init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
 	                                               user_data, init_async);
 
-	if (priv->private_bus) {
-		priv->service_running = TRUE;
-		init_get_properties (init_data);
-	} else {
-		/* Check if NM is running */
-		dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner",
-		                         init_async_got_manager_running,
-		                         init_data, NULL,
-		                         G_TYPE_STRING, NM_DBUS_SERVICE,
-		                         G_TYPE_INVALID);
-	}
+	/* Check if NM is running */
+	dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner",
+	                         init_async_got_manager_running,
+	                         init_data, NULL,
+	                         G_TYPE_STRING, NM_DBUS_SERVICE,
+	                         G_TYPE_INVALID);
 }
 
 static gboolean
@@ -1444,10 +1433,8 @@ set_property (GObject *object, guint prop_id,
 	case PROP_BUS:
 		/* Construct only */
 		priv->bus = g_value_dup_boxed (value);
-		if (!priv->bus) {
+		if (!priv->bus)
 			priv->bus = _nm_dbus_new_connection (NULL);
-			priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
-		}
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c
index 04f8dd8b..99871ad2 100644
--- a/libnm-glib/nm-secret-agent.c
+++ b/libnm-glib/nm-secret-agent.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
-#include "nm-glib-compat.h"
+#include "nm-default.h"
 #include "NetworkManager.h"
 #include "nm-secret-agent.h"
 #include "nm-glib-enum-types.h"
@@ -65,7 +65,6 @@ typedef struct {
 	NMSecretAgentCapabilities capabilities;
 
 	DBusGConnection *bus;
-	gboolean private_bus;
 	DBusGProxy *dbus_proxy;
 	DBusGProxy *manager_proxy;
 	DBusGProxyCall *reg_call;
@@ -227,12 +226,6 @@ verify_sender (NMSecretAgent *self,
 
 	g_return_val_if_fail (context != NULL, FALSE);
 
-	/* Private bus connection is always to NetworkManager, which is always
-	 * UID 0.
-	 */
-	if (priv->private_bus)
-		return TRUE;
-
 	/* Verify the sender's UID is 0, and that the sender is the same as
 	 * NetworkManager's bus name owner.
 	 */
@@ -626,7 +619,7 @@ nm_secret_agent_register (NMSecretAgent *self)
 	g_return_val_if_fail (class->save_secrets != NULL, FALSE);
 	g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
 
-	if (!priv->nm_owner && !priv->private_bus)
+	if (!priv->nm_owner)
 		return FALSE;
 
 	priv->suppress_auto = FALSE;
@@ -671,7 +664,7 @@ nm_secret_agent_unregister (NMSecretAgent *self)
 	g_return_val_if_fail (priv->bus != NULL, FALSE);
 	g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
 
-	if (!priv->nm_owner && !priv->private_bus)
+	if (!priv->nm_owner)
 		return FALSE;
 
 	dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID);
@@ -853,29 +846,26 @@ nm_secret_agent_init (NMSecretAgent *self)
 		g_error_free (error);
 		return;
 	}
-	priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
-
-	if (priv->private_bus == FALSE) {
-		priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
-		                                              DBUS_SERVICE_DBUS,
-		                                              DBUS_PATH_DBUS,
-		                                              DBUS_INTERFACE_DBUS);
-		g_assert (priv->dbus_proxy);
-
-		dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
-		                                   G_TYPE_NONE,
-		                                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-		                                   G_TYPE_INVALID);
-		dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
-		                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-		                         G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal (priv->dbus_proxy,
-		                             "NameOwnerChanged",
-		                             G_CALLBACK (name_owner_changed),
-		                             self, NULL);
-
-		get_nm_owner (self);
-	}
+
+	priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+	                                              DBUS_SERVICE_DBUS,
+	                                              DBUS_PATH_DBUS,
+	                                              DBUS_INTERFACE_DBUS);
+	g_assert (priv->dbus_proxy);
+
+	dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
+	                                   G_TYPE_NONE,
+	                                   G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+	                                   G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
+	                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+	                         G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (priv->dbus_proxy,
+	                             "NameOwnerChanged",
+	                             G_CALLBACK (name_owner_changed),
+	                             self, NULL);
+
+	get_nm_owner (self);
 
 	priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
 	                                                         NM_DBUS_PATH_AGENT_MANAGER,
@@ -885,7 +875,7 @@ nm_secret_agent_init (NMSecretAgent *self)
 		return;
 	}
 
-	if (priv->nm_owner || priv->private_bus)
+	if (priv->nm_owner)
 		priv->auto_register_id = g_idle_add (auto_register_cb, self);
 }
 
diff --git a/libnm-glib/nm-types.c b/libnm-glib/nm-types.c
index 5b434aa9..30936f4e 100644
--- a/libnm-glib/nm-types.c
+++ b/libnm-glib/nm-types.c
@@ -20,9 +20,9 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <dbus/dbus-glib.h>
 #include <string.h>
+#include "nm-default.h"
 #include "nm-types.h"
 #include "nm-types-private.h"
 #include "nm-object-private.h"
diff --git a/libnm-glib/nm-vpn-enum-types.c b/libnm-glib/nm-vpn-enum-types.c
index 45418518..e47f38da 100644
--- a/libnm-glib/nm-vpn-enum-types.c
+++ b/libnm-glib/nm-vpn-enum-types.c
@@ -3,6 +3,8 @@
 
 /* Generated by glib-mkenums. Do not edit */
 
+#include "config.h"
+
 #include "nm-vpn-enum-types.h"
 
 #include "nm-vpn-plugin.h" 
diff --git a/libnm-glib/nm-vpn-plugin-ui-interface.h b/libnm-glib/nm-vpn-plugin-ui-interface.h
index 9c6e49eb..e671e6cf 100644
--- a/libnm-glib/nm-vpn-plugin-ui-interface.h
+++ b/libnm-glib/nm-vpn-plugin-ui-interface.h
@@ -224,6 +224,52 @@ gboolean nm_vpn_plugin_ui_widget_interface_save_secrets (NMVpnPluginUiWidgetInte
                                                          NMConnection *connection,
                                                          GError **error);
 
+
+#ifdef NM_VPN_LIBNM_COMPAT
+#define nm_vpn_editor_plugin_factory nm_vpn_plugin_ui_factory
+
+#define NM_TYPE_VPN_EDITOR_PLUGIN               NM_TYPE_VPN_PLUGIN_UI_INTERFACE
+#define NM_VPN_EDITOR_PLUGIN(obj)               NM_VPN_PLUGIN_UI_INTERFACE(obj)
+#define NM_IS_VPN_EDITOR_PLUGIN(obj)            NM_IS_VPN_PLUGIN_UI_INTERFACE(obj)
+#define NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(obj) NM_VPN_PLUGIN_UI_INTERFACE_GET_INTERFACE(obj)
+
+#define NMVpnEditorPluginCapability NMVpnPluginUiCapability
+#define NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE   NM_VPN_PLUGIN_UI_CAPABILITY_NONE
+#define NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT NM_VPN_PLUGIN_UI_CAPABILITY_IMPORT
+#define NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT NM_VPN_PLUGIN_UI_CAPABILITY_EXPORT
+#define NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6   NM_VPN_PLUGIN_UI_CAPABILITY_IPV6
+
+#define NM_VPN_EDITOR_PLUGIN_NAME        NM_VPN_PLUGIN_UI_INTERFACE_NAME
+#define NM_VPN_EDITOR_PLUGIN_DESCRIPTION NM_VPN_PLUGIN_UI_INTERFACE_DESC
+#define NM_VPN_EDITOR_PLUGIN_SERVICE     NM_VPN_PLUGIN_UI_INTERFACE_SERVICE
+
+#define NMVpnEditorPlugin NMVpnPluginUiInterface
+#define NMVpnEditorPluginInterface NMVpnPluginUiInterface
+
+#define get_editor             ui_factory
+#define get_suggested_filename get_suggested_name
+
+#define nm_vpn_editor_plugin_get_type nm_vpn_plugin_ui_interface_get_type
+#define nm_vpn_editor_plugin_get_editor nm_vpn_plugin_ui_interface_ui_factory
+#define nm_vpn_editor_plugin_get_capabilities nm_vpn_plugin_ui_interface_get_capabilities
+#define nm_vpn_editor_plugin_import nm_vpn_plugin_ui_interface_import
+#define nm_vpn_editor_plugin_export nm_vpn_plugin_ui_interface_export
+#define nm_vpn_editor_plugin_get_suggested_filename nm_vpn_plugin_ui_interface_get_suggested_name
+
+#define NM_TYPE_VPN_EDITOR               NM_TYPE_VPN_PLUGIN_UI_WIDGET_INTERFACE
+#define NM_VPN_EDITOR(obj)               NM_VPN_PLUGIN_UI_WIDGET_INTERFACE (obj)
+#define NM_IS_VPN_EDITOR(obj)            NM_IS_VPN_PLUGIN_UI_WIDGET_INTERFACE (obj)
+#define NM_VPN_EDITOR_GET_INTERFACE(obj) NM_VPN_PLUGIN_UI_WIDGET_INTERFACE_GET_INTERFACE (obj)
+
+#define NMVpnEditor NMVpnPluginUiWidgetInterface
+#define NMVpnEditorInterface NMVpnPluginUiWidgetInterface
+
+#define nm_vpn_editor_get_type nm_vpn_plugin_ui_widget_interface_get_type
+#define nm_vpn_editor_get_widget nm_vpn_plugin_ui_widget_interface_get_widget
+#define nm_vpn_editor_update_connection nm_vpn_plugin_ui_widget_interface_update_connection
+
+#endif /* NM_VPN_LIBNM_COMPAT */
+
 G_END_DECLS
 
 #endif	/* NM_VPN_PLUGIN_UI_INTERFACE_H */
diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c
index 4350e600..d180ec44 100644
--- a/libnm-glib/nm-vpn-plugin.c
+++ b/libnm-glib/nm-vpn-plugin.c
@@ -22,7 +22,7 @@
 #include "config.h"
 
 #include <signal.h>
-#include "nm-glib-compat.h"
+#include "nm-default.h"
 #include "nm-vpn-plugin.h"
 #include "nm-vpn-enum-types.h"
 #include "nm-utils.h"
@@ -769,9 +769,9 @@ constructor (GType type,
 		goto err;
 
 	proxy = dbus_g_proxy_new_for_name (connection,
-	                                   "org.freedesktop.DBus",
-	                                   "/org/freedesktop/DBus",
-	                                   "org.freedesktop.DBus");
+	                                   DBUS_SERVICE_DBUS,
+	                                   DBUS_PATH_DBUS,
+	                                   DBUS_INTERFACE_DBUS);
 
 	if (!dbus_g_proxy_call (proxy, "RequestName", &err,
 	                        G_TYPE_STRING, priv->dbus_service_name,
diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c
index 1735ab3e..1c40a217 100644
--- a/libnm-glib/nm-wimax-nsp.c
+++ b/libnm-glib/nm-wimax-nsp.c
@@ -22,12 +22,11 @@
 
 #include <string.h>
 
-#include "nm-glib-compat.h"
-
 #include <nm-connection.h>
 #include <nm-setting-connection.h>
 #include <nm-setting-wimax.h>
 
+#include "nm-default.h"
 #include "nm-wimax-nsp.h"
 #include "NetworkManager.h"
 #include "nm-types-private.h"
diff --git a/libnm-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am
index aeaaa6b6..a1b25f62 100644
--- a/libnm-glib/tests/Makefile.am
+++ b/libnm-glib/tests/Makefile.am
@@ -1,11 +1,12 @@
 if ENABLE_TESTS
 
 AM_CPPFLAGS = \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir)/include \
+	-I$(top_srcdir)/shared \
+	-I$(top_builddir)/shared \
 	-I$(top_srcdir)/libnm-util \
 	-I$(top_builddir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
+	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
 	-DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \
 	$(GLIB_CFLAGS) \
@@ -23,8 +24,8 @@ TESTS = test-nm-client test-remote-settings-client
 ####### NMClient and non-settings tests #######
 
 test_nm_client_SOURCES = \
-	common.c \
-	common.h \
+	$(top_builddir)/shared/nm-test-utils-impl.c \
+	$(top_builddir)/shared/nm-test-libnm-utils.h \
 	test-nm-client.c
 
 test_nm_client_LDADD = \
@@ -36,8 +37,8 @@ test_nm_client_LDADD = \
 ####### remote settings client test #######
 
 test_remote_settings_client_SOURCES = \
-	common.c \
-	common.h \
+	$(top_builddir)/shared/nm-test-utils-impl.c \
+	$(top_builddir)/shared/nm-test-libnm-utils.h \
 	test-remote-settings-client.c
 
 test_remote_settings_client_LDADD = \
diff --git a/libnm-glib/tests/Makefile.in b/libnm-glib/tests/Makefile.in
index ab088a30..8d7e6dea 100644
--- a/libnm-glib/tests/Makefile.in
+++ b/libnm-glib/tests/Makefile.in
@@ -116,8 +116,11 @@ CONFIG_CLEAN_VPATH_FILES =
 @ENABLE_TESTS_TRUE@am__EXEEXT_1 = test-nm-client$(EXEEXT) \
 @ENABLE_TESTS_TRUE@	test-remote-settings-client$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
-am__test_nm_client_SOURCES_DIST = common.c common.h test-nm-client.c
-@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS = common.$(OBJEXT) \
+am__test_nm_client_SOURCES_DIST =  \
+	$(top_builddir)/shared/nm-test-utils-impl.c \
+	$(top_builddir)/shared/nm-test-libnm-utils.h test-nm-client.c
+@ENABLE_TESTS_TRUE@am_test_nm_client_OBJECTS =  \
+@ENABLE_TESTS_TRUE@	nm-test-utils-impl.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	test-nm-client.$(OBJEXT)
 test_nm_client_OBJECTS = $(am_test_nm_client_OBJECTS)
 am__DEPENDENCIES_1 =
@@ -129,10 +132,12 @@ AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-am__test_remote_settings_client_SOURCES_DIST = common.c common.h \
+am__test_remote_settings_client_SOURCES_DIST =  \
+	$(top_builddir)/shared/nm-test-utils-impl.c \
+	$(top_builddir)/shared/nm-test-libnm-utils.h \
 	test-remote-settings-client.c
 @ENABLE_TESTS_TRUE@am_test_remote_settings_client_OBJECTS =  \
-@ENABLE_TESTS_TRUE@	common.$(OBJEXT) \
+@ENABLE_TESTS_TRUE@	nm-test-utils-impl.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	test-remote-settings-client.$(OBJEXT)
 test_remote_settings_client_OBJECTS =  \
 	$(am_test_remote_settings_client_OBJECTS)
@@ -424,7 +429,6 @@ BLUEZ5_LIBS = @BLUEZ5_LIBS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
-CKDB_PATH = @CKDB_PATH@
 CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
 CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
 CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
@@ -436,8 +440,6 @@ CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DBUS_CFLAGS = @DBUS_CFLAGS@
-DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@
-DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@
 DBUS_LIBS = @DBUS_LIBS@
 DBUS_SYS_DIR = @DBUS_SYS_DIR@
 DEFS = @DEFS@
@@ -447,6 +449,7 @@ DHCPCD_PATH = @DHCPCD_PATH@
 DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@
 DLLTOOL = @DLLTOOL@
 DNSMASQ_PATH = @DNSMASQ_PATH@
+DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
 ECHO_C = @ECHO_C@
@@ -501,16 +504,13 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
 INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
 INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
 IPTABLES_PATH = @IPTABLES_PATH@
-IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
-IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
 KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
 LCOV = @LCOV@
 LD = @LD@
 LDFLAGS = @LDFLAGS@
+LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@
+LIBAUDIT_LIBS = @LIBAUDIT_LIBS@
 LIBDL = @LIBDL@
-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
@@ -547,6 +547,8 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
+NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
 NM_MICRO_VERSION = @NM_MICRO_VERSION@
 NM_MINOR_VERSION = @NM_MINOR_VERSION@
@@ -575,7 +577,6 @@ POLKIT_LIBS = @POLKIT_LIBS@
 POSUB = @POSUB@
 PPPD_PATH = @PPPD_PATH@
 PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
-PPPOE_PATH = @PPPOE_PATH@
 QT_CFLAGS = @QT_CFLAGS@
 QT_LIBS = @QT_LIBS@
 RANLIB = @RANLIB@
@@ -590,6 +591,8 @@ SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@
 SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@
 SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@
 SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
+SYSTEMD_JOURNAL_CFLAGS = @SYSTEMD_JOURNAL_CFLAGS@
+SYSTEMD_JOURNAL_LIBS = @SYSTEMD_JOURNAL_LIBS@
 SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
 SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
@@ -650,6 +653,7 @@ mkdir_p = @mkdir_p@
 nmbinary = @nmbinary@
 nmconfdir = @nmconfdir@
 nmdatadir = @nmdatadir@
+nmlibdir = @nmlibdir@
 nmrundir = @nmrundir@
 nmstatedir = @nmstatedir@
 oldincludedir = @oldincludedir@
@@ -657,6 +661,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -673,11 +678,12 @@ with_netconfig = @with_netconfig@
 with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
 @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \
-@ENABLE_TESTS_TRUE@	-I$(top_srcdir)/include \
-@ENABLE_TESTS_TRUE@	-I$(top_builddir)/include \
+@ENABLE_TESTS_TRUE@	-I$(top_srcdir)/shared \
+@ENABLE_TESTS_TRUE@	-I$(top_builddir)/shared \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/libnm-util \
 @ENABLE_TESTS_TRUE@	-I$(top_builddir)/libnm-util \
 @ENABLE_TESTS_TRUE@	-I$(top_srcdir)/libnm-glib \
+@ENABLE_TESTS_TRUE@	-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB_LEGACY \
 @ENABLE_TESTS_TRUE@	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
 @ENABLE_TESTS_TRUE@	-DTEST_NM_SERVICE=\"$(abs_top_srcdir)/tools/test-networkmanager-service.py\" \
 @ENABLE_TESTS_TRUE@	$(GLIB_CFLAGS) \
@@ -687,8 +693,8 @@ with_valgrind = @with_valgrind@
 
 ####### NMClient and non-settings tests #######
 @ENABLE_TESTS_TRUE@test_nm_client_SOURCES = \
-@ENABLE_TESTS_TRUE@	common.c \
-@ENABLE_TESTS_TRUE@	common.h \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/shared/nm-test-utils-impl.c \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/shared/nm-test-libnm-utils.h \
 @ENABLE_TESTS_TRUE@	test-nm-client.c
 
 @ENABLE_TESTS_TRUE@test_nm_client_LDADD = \
@@ -700,8 +706,8 @@ with_valgrind = @with_valgrind@
 
 ####### remote settings client test #######
 @ENABLE_TESTS_TRUE@test_remote_settings_client_SOURCES = \
-@ENABLE_TESTS_TRUE@	common.c \
-@ENABLE_TESTS_TRUE@	common.h \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/shared/nm-test-utils-impl.c \
+@ENABLE_TESTS_TRUE@	$(top_builddir)/shared/nm-test-libnm-utils.h \
 @ENABLE_TESTS_TRUE@	test-remote-settings-client.c
 
 @ENABLE_TESTS_TRUE@test_remote_settings_client_LDADD = \
@@ -770,7 +776,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-test-utils-impl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-nm-client.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-remote-settings-client.Po@am__quote@
 
@@ -795,6 +801,20 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+nm-test-utils-impl.o: $(top_builddir)/shared/nm-test-utils-impl.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-test-utils-impl.o -MD -MP -MF $(DEPDIR)/nm-test-utils-impl.Tpo -c -o nm-test-utils-impl.o `test -f '$(top_builddir)/shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`$(top_builddir)/shared/nm-test-utils-impl.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm-test-utils-impl.Tpo $(DEPDIR)/nm-test-utils-impl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$(top_builddir)/shared/nm-test-utils-impl.c' object='nm-test-utils-impl.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-test-utils-impl.o `test -f '$(top_builddir)/shared/nm-test-utils-impl.c' || echo '$(srcdir)/'`$(top_builddir)/shared/nm-test-utils-impl.c
+
+nm-test-utils-impl.obj: $(top_builddir)/shared/nm-test-utils-impl.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-test-utils-impl.obj -MD -MP -MF $(DEPDIR)/nm-test-utils-impl.Tpo -c -o nm-test-utils-impl.obj `if test -f '$(top_builddir)/shared/nm-test-utils-impl.c'; then $(CYGPATH_W) '$(top_builddir)/shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/shared/nm-test-utils-impl.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/nm-test-utils-impl.Tpo $(DEPDIR)/nm-test-utils-impl.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$(top_builddir)/shared/nm-test-utils-impl.c' object='nm-test-utils-impl.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-test-utils-impl.obj `if test -f '$(top_builddir)/shared/nm-test-utils-impl.c'; then $(CYGPATH_W) '$(top_builddir)/shared/nm-test-utils-impl.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/shared/nm-test-utils-impl.c'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/libnm-glib/tests/common.c b/libnm-glib/tests/common.c
deleted file mode 100644
index f071fb5b..00000000
--- a/libnm-glib/tests/common.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright 2010 - 2014 Red Hat, Inc.
- *
- */
-
-#include "config.h"
-
-#include <dbus/dbus.h>
-#include <glib.h>
-#include <string.h>
-
-#include "NetworkManager.h"
-
-#include "common.h"
-
-static gboolean
-name_exists (GDBusConnection *c, const char *name)
-{
-	GVariant *reply;
-	gboolean exists = FALSE;
-
-	reply = g_dbus_connection_call_sync (c,
-	                                     DBUS_SERVICE_DBUS,
-	                                     DBUS_PATH_DBUS,
-	                                     DBUS_INTERFACE_DBUS,
-	                                     "GetNameOwner",
-	                                     g_variant_new ("(s)", name),
-	                                     NULL,
-	                                     G_DBUS_CALL_FLAGS_NO_AUTO_START,
-	                                     -1,
-	                                     NULL,
-	                                     NULL);
-	if (reply != NULL) {
-		exists = TRUE;
-		g_variant_unref (reply);
-	}
-
-	return exists;
-}
-
-NMTestServiceInfo *
-nm_test_service_init (void)
-{
-	NMTestServiceInfo *info;
-	const char *args[2] = { TEST_NM_SERVICE, NULL };
-	GError *error = NULL;
-	int i;
-
-	info = g_malloc0 (sizeof (*info));
-
-	info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL,  &error);
-	g_assert_no_error (error);
-
-	/* Spawn the test service. info->keepalive_fd will be a pipe to the service's
-	 * stdin; if it closes, the service will exit immediately. We use this to
-	 * make sure the service exits if the test program crashes.
-	 */
-	g_spawn_async_with_pipes (NULL, (char **) args, NULL, 0, NULL, NULL,
-	                          &info->pid, &info->keepalive_fd, NULL, NULL, &error);
-	g_assert_no_error (error);
-
-	/* Wait until the service is registered on the bus */
-	for (i = 1000; i > 0; i--) {
-		if (name_exists (info->bus, "org.freedesktop.NetworkManager"))
-			break;
-		g_usleep (G_USEC_PER_SEC / 50);
-	}
-	g_assert (i > 0);
-
-	/* Grab a proxy to our fake NM service to trigger tests */
-	info->proxy = g_dbus_proxy_new_sync (info->bus,
-	                                     G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
-	                                     G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
-	                                     G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
-	                                     NULL,
-	                                     NM_DBUS_SERVICE,
-	                                     NM_DBUS_PATH,
-	                                     "org.freedesktop.NetworkManager.LibnmGlibTest",
-	                                     NULL, &error);
-	g_assert_no_error (error);
-
-	return info;
-}
-
-void
-nm_test_service_cleanup (NMTestServiceInfo *info)
-{
-	int i;
-
-	g_object_unref (info->proxy);
-	kill (info->pid, SIGTERM);
-
-	/* Wait until the bus notices the service is gone */
-	for (i = 100; i > 0; i--) {
-		if (!name_exists (info->bus, "org.freedesktop.NetworkManager"))
-			break;
-		g_usleep (G_USEC_PER_SEC / 50);
-	}
-	g_assert (i > 0);
-
-	g_object_unref (info->bus);
-	close (info->keepalive_fd);
-
-	memset (info, 0, sizeof (*info));
-	g_free (info);
-}
diff --git a/libnm-glib/tests/common.h b/libnm-glib/tests/common.h
deleted file mode 100644
index 7c49d253..00000000
--- a/libnm-glib/tests/common.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright 2014 Red Hat, Inc.
- */
-
-#include <gio/gio.h>
-
-typedef struct {
-	GDBusConnection *bus;
-	GDBusProxy *proxy;
-	GPid pid;
-	int keepalive_fd;
-} NMTestServiceInfo;
-
-NMTestServiceInfo *nm_test_service_init (void);
-void nm_test_service_cleanup (NMTestServiceInfo *info);
diff --git a/libnm-glib/tests/test-nm-client.c b/libnm-glib/tests/test-nm-client.c
index af3722eb..f528bc26 100644
--- a/libnm-glib/tests/test-nm-client.c
+++ b/libnm-glib/tests/test-nm-client.c
@@ -23,50 +23,22 @@
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
-#include <glib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <signal.h>
 
-#include <NetworkManager.h>
+#include "nm-default.h"
 #include "nm-client.h"
 #include "nm-device-wifi.h"
 #include "nm-device-ethernet.h"
 #include "nm-device-wimax.h"
-#include "nm-glib-compat.h"
+#include "nm-connection.h"
+#include "nm-setting.h"
 
-#include "common.h"
+#include "nm-test-libnm-utils.h"
 
 static GMainLoop *loop = NULL;
-static NMTestServiceInfo *sinfo;
-
-/*******************************************************************/
-
-static NMClient *
-test_client_new (void)
-{
-	NMClient *client;
-	DBusGConnection *bus;
-	GError *error = NULL;
-	gboolean success;
-
-	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-	g_assert_no_error (error);
-
-	client = g_object_new (NM_TYPE_CLIENT,
-	                       NM_OBJECT_DBUS_CONNECTION, bus,
-	                       NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
-	                       NULL);
-	g_assert (client != NULL);
-
-	dbus_g_connection_unref (bus);
-
-	success = g_initable_init (G_INITABLE (client), NULL, &error);
-	g_assert_no_error (error);
-	g_assert (success == TRUE);
-
-	return client;
-}
+static NMTstcServiceInfo *sinfo;
 
 /*******************************************************************/
 
@@ -99,6 +71,29 @@ add_device (const char *method, const char *ifname, char **out_path)
 	return TRUE;
 }
 
+static gboolean
+add_wired_device (const char *method, const char *ifname, char **out_path)
+{
+	const char *empty[] = { NULL };
+	GError *error = NULL;
+	GVariant *ret;
+
+	ret = g_dbus_proxy_call_sync (sinfo->proxy,
+	                              method,
+	                              g_variant_new ("(ss^as)", ifname, "/", empty),
+	                              G_DBUS_CALL_FLAGS_NO_AUTO_START,
+	                              3000,
+	                              NULL,
+	                              &error);
+	g_assert_no_error (error);
+	g_assert (ret);
+	g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
+	if (out_path)
+		g_variant_get (ret, "(o)", out_path);
+	g_variant_unref (ret);
+	return TRUE;
+}
+
 /*******************************************************************/
 
 typedef struct {
@@ -160,14 +155,14 @@ test_device_added (void)
 	NMDevice *device;
 	DeviceAddedInfo info = { loop, FALSE, FALSE, 0, 0 };
 
-	sinfo = nm_test_service_init ();
-	client = test_client_new ();
+	sinfo = nmtstc_service_init ();
+	client = nmtstc_nm_client_new ();
 
 	devices = nm_client_get_devices (client);
 	g_assert (devices == NULL);
 
 	/* Tell the test service to add a new device */
-	add_device ("AddWiredDevice", "eth0", NULL);
+	add_wired_device ("AddWiredDevice", "eth0", NULL);
 
 	g_signal_connect (client,
 	                  "device-added",
@@ -200,7 +195,7 @@ test_device_added (void)
 	g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0");
 
 	g_object_unref (client);
-	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+	g_clear_pointer (&sinfo, nmtstc_service_cleanup);
 }
 
 /*******************************************************************/
@@ -317,8 +312,8 @@ test_wifi_ap_added_removed (void)
 	GError *error = NULL;
 	char *expected_path = NULL;
 
-	sinfo = nm_test_service_init ();
-	client = test_client_new ();
+	sinfo = nmtstc_service_init ();
+	client = nmtstc_nm_client_new ();
 
 	/*************************************/
 	/* Add the wifi device */
@@ -423,7 +418,7 @@ test_wifi_ap_added_removed (void)
 	g_free (expected_path);
 
 	g_object_unref (client);
-	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+	g_clear_pointer (&sinfo, nmtstc_service_cleanup);
 }
 
 /*******************************************************************/
@@ -540,8 +535,8 @@ test_wimax_nsp_added_removed (void)
 	GError *error = NULL;
 	char *expected_path = NULL;
 
-	sinfo = nm_test_service_init ();
-	client = test_client_new ();
+	sinfo = nmtstc_service_init ();
+	client = nmtstc_nm_client_new ();
 
 	/*************************************/
 	/* Add the wimax device */
@@ -646,7 +641,7 @@ test_wimax_nsp_added_removed (void)
 	g_free (expected_path);
 
 	g_object_unref (client);
-	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+	g_clear_pointer (&sinfo, nmtstc_service_cleanup);
 }
 
 /*******************************************************************/
@@ -662,6 +657,7 @@ typedef struct {
 static void
 da_check_quit (DaInfo *info)
 {
+	g_assert (info->quit_count > 0);
 	info->quit_count--;
 	if (info->quit_count == 0) {
 		g_source_remove (info->quit_id);
@@ -724,14 +720,14 @@ test_devices_array (void)
 	GError *error = NULL;
 	GVariant *ret;
 
-	sinfo = nm_test_service_init ();
-	client = test_client_new ();
+	sinfo = nmtstc_service_init ();
+	client = nmtstc_nm_client_new ();
 
 	/*************************************/
 	/* Add some devices */
 	add_device ("AddWifiDevice", "wlan0", &paths[0]);
-	add_device ("AddWiredDevice", "eth0", &paths[1]);
-	add_device ("AddWiredDevice", "eth1", &paths[2]);
+	add_wired_device ("AddWiredDevice", "eth0", &paths[1]);
+	add_wired_device ("AddWiredDevice", "eth1", &paths[2]);
 	info.quit_count = 3;
 
 	g_signal_connect (client,
@@ -808,7 +804,7 @@ test_devices_array (void)
 	g_free (paths[2]);
 
 	g_object_unref (client);
-	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+	g_clear_pointer (&sinfo, nmtstc_service_cleanup);
 }
 
 static void
@@ -830,7 +826,7 @@ test_client_manager_running (void)
 	int running_changed = 0;
 	GError *error = NULL;
 
-	client1 = test_client_new ();
+	client1 = nmtstc_nm_client_new ();
 
 	g_assert (!nm_client_get_manager_running (client1));
 	g_assert_cmpstr (nm_client_get_version (client1), ==, NULL);
@@ -846,8 +842,8 @@ test_client_manager_running (void)
 	g_clear_error (&error);
 
 	/* Now start the test service. */
-	sinfo = nm_test_service_init ();
-	client2 = test_client_new ();
+	sinfo = nmtstc_service_init ();
+	client2 = nmtstc_nm_client_new ();
 
 	/* client2 should know that NM is running, but the previously-created
 	 * client1 hasn't gotten the news yet.
@@ -864,7 +860,7 @@ test_client_manager_running (void)
 	g_source_remove (quit_id);
 
 	/* And kill it */
-	g_clear_pointer (&sinfo, nm_test_service_cleanup);
+	g_clear_pointer (&sinfo, nmtstc_service_cleanup);
 
 	g_assert (nm_client_get_manager_running (client1));
 
@@ -880,14 +876,269 @@ test_client_manager_running (void)
 
 /*******************************************************************/
 
+static GPtrArray *
+_slist_to_array (GPtrArray **connections, GSList *list)
+{
+	GPtrArray *array;
+	const GSList *iter;
+
+	if (!*connections)
+		*connections = array = g_ptr_array_new ();
+	else {
+		array = *connections;
+		g_ptr_array_set_size (array, 0);
+	}
+	for (iter = list; iter; iter = iter->next)
+		g_ptr_array_add (array, iter->data);
+	g_slist_free (list);
+	return array;
+}
+
+static gboolean
+_test_connection_invalid_find_connections (gpointer element, gpointer needle, gpointer user_data)
+{
+	NMRemoteConnection *con = NM_REMOTE_CONNECTION (element);
+	const char *path = needle;
+
+	g_assert (NM_IS_REMOTE_CONNECTION (con));
+	g_assert (path && *path);
+
+	return strcmp (path, nm_connection_get_path ((NMConnection *) con)) == 0;
+}
+
+#define ASSERT_IDX(i) \
+	g_assert_cmpint (idx[i], >=, 0); \
+	g_assert (path##i && *path##i); \
+	g_assert (NM_IS_REMOTE_CONNECTION (connections->pdata[idx[i]])); \
+	g_assert_cmpstr (nm_connection_get_path (connections->pdata[idx[i]]), ==, path##i);
+
+static void
+test_connection_invalid (void)
+{
+	NMTSTC_SERVICE_INFO_SETUP (my_sinfo)
+	gs_unref_object NMConnection *connection = NULL;
+	NMSettingConnection *s_con;
+	gs_unref_object NMRemoteSettings *settings = NULL;
+	gs_unref_ptrarray GPtrArray *connections = NULL;
+	gs_free char *path0 = NULL;
+	gs_free char *path1 = NULL;
+	gs_free char *path2 = NULL;
+	gs_free char *uuid2 = NULL;
+	gsize n_found;
+	gssize idx[3];
+
+	/**************************************************************************
+	 * Add two connection before starting libnm. One valid, one invalid.
+	 *************************************************************************/
+
+	connection = nmtst_create_minimal_connection ("test-connection-invalid-0", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con);
+	nmtst_connection_normalize (connection);
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_UUID, nmtst_uuid_generate (),
+	              NULL);
+	nmtstc_service_add_connection (my_sinfo,
+	                               connection,
+	                               TRUE,
+	                               &path0);
+
+	nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRED);
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "test-connection-invalid-1",
+	              NM_SETTING_CONNECTION_TYPE, "invalid-type-1",
+	              NM_SETTING_CONNECTION_UUID, nmtst_uuid_generate (),
+	              NULL);
+	nmtstc_service_add_connection (my_sinfo,
+	                               connection,
+	                               FALSE,
+	                               &path1);
+
+	nmtst_main_loop_run (loop, 100);
+
+	settings = nmtstc_nm_remote_settings_new ();
+
+	g_test_expect_message ("libnm-glib", G_LOG_LEVEL_WARNING, "*replace_settings: error updating connection*");
+
+	nmtst_main_loop_run (loop, 100);
+
+	g_test_assert_expected_messages ();
+
+	_slist_to_array (&connections, nm_remote_settings_list_connections (settings));
+
+	g_assert_cmpint (connections->len, ==, 2);
+	n_found = nmtst_find_all_indexes (connections->pdata,
+	                                  connections->len,
+	                                  (gpointer *) ((const char *[]) { path0, path1 }),
+	                                  2,
+	                                  _test_connection_invalid_find_connections,
+	                                  NULL,
+	                                  idx);
+	g_assert_cmpint (n_found, ==, 2);
+	ASSERT_IDX (0);
+	ASSERT_IDX (1);
+	nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]);
+	nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0);
+
+	/**************************************************************************
+	 * After having the client up and running, add another invalid connection
+	 *************************************************************************/
+
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "test-connection-invalid-2",
+	              NM_SETTING_CONNECTION_TYPE, "invalid-type-2",
+	              NM_SETTING_CONNECTION_UUID, (uuid2 = g_strdup (nmtst_uuid_generate ())),
+	              NULL);
+	nmtstc_service_add_connection (my_sinfo,
+	                               connection,
+	                               FALSE,
+	                               &path2);
+
+	g_test_expect_message ("libnm-glib", G_LOG_LEVEL_WARNING, "*replace_settings: error updating connection*");
+
+	nmtst_main_loop_run (loop, 100);
+
+	g_test_assert_expected_messages ();
+
+	_slist_to_array (&connections, nm_remote_settings_list_connections (settings));
+
+	g_assert_cmpint (connections->len, ==, 3);
+	n_found = nmtst_find_all_indexes (connections->pdata,
+	                                  connections->len,
+	                                  (gpointer *) ((const char *[]) { path0, path1, path2 }),
+	                                  3,
+	                                  _test_connection_invalid_find_connections,
+	                                  NULL,
+	                                  idx);
+	g_assert_cmpint (n_found, ==, 3);
+	ASSERT_IDX (0);
+	ASSERT_IDX (1);
+	ASSERT_IDX (2);
+	nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]);
+	nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0);
+	nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0);
+
+	/**************************************************************************
+	 * Modify the invalid connection. Connection disappears
+	 *************************************************************************/
+
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "test-connection-invalid-2x",
+	              NULL);
+	nmtstc_service_update_connection (my_sinfo,
+	                                  path2,
+	                                  connection,
+	                                  FALSE);
+
+	g_test_expect_message ("libnm-glib", G_LOG_LEVEL_WARNING, "*replace_settings: error updating connection*");
+
+	nmtst_main_loop_run (loop, 100);
+
+	g_test_assert_expected_messages ();
+
+	_slist_to_array (&connections, nm_remote_settings_list_connections (settings));
+
+	g_assert_cmpint (connections->len, ==, 2);
+	n_found = nmtst_find_all_indexes (connections->pdata,
+	                                  connections->len,
+	                                  (gpointer *) ((const char *[]) { path0, path1, path2 }),
+	                                  3,
+	                                  _test_connection_invalid_find_connections,
+	                                  NULL,
+	                                  idx);
+	g_assert_cmpint (n_found, ==, 2);
+	ASSERT_IDX (0);
+	ASSERT_IDX (1);
+	g_assert_cmpint (idx[2], ==, -1);
+	nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]);
+	nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0);
+
+	/**************************************************************************
+	 * Modify the invalid connection again. Note that the connection stays
+	 * invisible (although it exists, and is valid).
+	 *************************************************************************/
+
+	g_clear_object (&connection);
+	connection = nmtst_create_minimal_connection ("test-connection-invalid-2", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con);
+	nmtst_connection_normalize (connection);
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "test-connection-invalid-2z",
+	              NM_SETTING_CONNECTION_TYPE, "802-3-ethernet",
+	              NM_SETTING_CONNECTION_UUID, uuid2,
+	              NULL);
+
+	nmtstc_service_update_connection (my_sinfo,
+	                                  path2,
+	                                  connection,
+	                                  FALSE);
+
+	nmtst_main_loop_run (loop, 100);
+
+	_slist_to_array (&connections, nm_remote_settings_list_connections (settings));
+
+	g_assert_cmpint (connections->len, ==, 2);
+	n_found = nmtst_find_all_indexes (connections->pdata,
+	                                  connections->len,
+	                                  (gpointer *) ((const char *[]) { path0, path1, path2 }),
+	                                  3,
+	                                  _test_connection_invalid_find_connections,
+	                                  NULL,
+	                                  idx);
+	g_assert_cmpint (n_found, ==, 2);
+	ASSERT_IDX (0);
+	ASSERT_IDX (1);
+	g_assert_cmpint (idx[2], ==, -1);
+	nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]);
+	nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0);
+
+
+	/**************************************************************************
+	 * Modify the invalid connection and make it valid
+	 *************************************************************************/
+
+	g_clear_object (&connection);
+	connection = nmtst_create_minimal_connection ("test-connection-invalid-1", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con);
+	nmtst_connection_normalize (connection);
+	g_object_set (s_con,
+	              NM_SETTING_CONNECTION_ID, "test-connection-invalid-1x",
+	              NM_SETTING_CONNECTION_TYPE, "802-3-ethernet",
+	              NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connections->pdata[idx[1]]),
+	              NULL);
+
+	nmtstc_service_update_connection (my_sinfo,
+	                                  path1,
+	                                  connection,
+	                                  FALSE);
+
+	nmtst_main_loop_run (loop, 100);
+
+	_slist_to_array (&connections, nm_remote_settings_list_connections (settings));
+
+	g_assert_cmpint (connections->len, ==, 2);
+	n_found = nmtst_find_all_indexes (connections->pdata,
+	                                  connections->len,
+	                                  (gpointer *) ((const char *[]) { path0, path1, path2 }),
+	                                  3,
+	                                  _test_connection_invalid_find_connections,
+	                                  NULL,
+	                                  idx);
+	g_assert_cmpint (n_found, ==, 2);
+	ASSERT_IDX (0);
+	ASSERT_IDX (1);
+	g_assert_cmpint (idx[2], ==, -1);
+	nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]);
+	nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[1]]);
+	g_assert_cmpstr ("test-connection-invalid-1x", ==, nm_connection_get_id (connections->pdata[idx[1]]));
+
+#undef ASSERT_IDX
+}
+
+/*******************************************************************/
+
+NMTST_DEFINE ();
+
 int
 main (int argc, char **argv)
 {
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
-
-	g_test_init (&argc, &argv, NULL);
+	nmtst_init (&argc, &argv, TRUE);
 
 	loop = g_main_loop_new (NULL, FALSE);
 
@@ -896,6 +1147,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/libnm-glib/wimax-nsp-added-removed", test_wimax_nsp_added_removed);
 	g_test_add_func ("/libnm-glib/devices-array", test_devices_array);
 	g_test_add_func ("/libnm-glib/client-manager-running", test_client_manager_running);
+	g_test_add_func ("/libnm/connection/invalid", test_connection_invalid);
 
 	return g_test_run ();
 }
diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c
index a109f8df..83227d4b 100644
--- a/libnm-glib/tests/test-remote-settings-client.c
+++ b/libnm-glib/tests/test-remote-settings-client.c
@@ -23,22 +23,22 @@
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
-#include <glib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <signal.h>
 
-#include <NetworkManager.h>
+#include "NetworkManager.h"
 
-#include <nm-setting-connection.h>
-#include <nm-setting-wired.h>
-#include <nm-utils.h>
+#include "nm-setting-connection.h"
+#include "nm-setting-wired.h"
+#include "nm-utils.h"
 
+#include "nm-default.h"
 #include "nm-remote-settings.h"
-#include "common.h"
-#include "gsystem-local-alloc.h"
 
-static NMTestServiceInfo *sinfo;
+#include "nm-test-libnm-utils.h"
+
+static NMTstcServiceInfo *sinfo;
 static NMRemoteSettings *settings = NULL;
 DBusGConnection *bus = NULL;
 NMRemoteConnection *remote = NULL;
@@ -376,7 +376,7 @@ test_service_running (void)
 	g_assert (running == TRUE);
 
 	/* Now kill the test service. */
-	nm_test_service_cleanup (sinfo);
+	nmtstc_service_cleanup (sinfo);
 
 	settings2 = nm_remote_settings_new (bus);
 
@@ -405,7 +405,7 @@ test_service_running (void)
 	g_assert (running == FALSE);
 
 	/* Now restart it */
-	sinfo =  nm_test_service_init ();
+	sinfo =  nmtstc_service_init ();
 
 	quit_id = g_timeout_add_seconds (5, loop_quit, loop);
 	g_main_loop_run (loop);
@@ -422,25 +422,22 @@ test_service_running (void)
 
 /*******************************************************************/
 
+NMTST_DEFINE ();
+
 int
 main (int argc, char **argv)
 {
 	int ret;
 	GError *error = NULL;
 
-#if !GLIB_CHECK_VERSION (2, 35, 0)
-	g_type_init ();
-#endif
-	
-	g_test_init (&argc, &argv, NULL);
+	nmtst_init (&argc, &argv, TRUE);
 
 	bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
 	g_assert_no_error (error);
 
-	sinfo = nm_test_service_init ();
+	sinfo = nmtstc_service_init ();
 
-	settings = nm_remote_settings_new (bus);
-	g_assert (settings != NULL);
+	settings = nmtstc_nm_remote_settings_new ();
 
 	/* FIXME: these tests assume that they get run in order, but g_test_run()
 	 * does not actually guarantee that!
@@ -453,7 +450,7 @@ main (int argc, char **argv)
 
 	ret = g_test_run ();
 
-	nm_test_service_cleanup (sinfo);
+	nmtstc_service_cleanup (sinfo);
 	g_object_unref (settings);
 	dbus_g_connection_unref (bus);