diff --git a/src/nm-device.c b/src/nm-device.c
index b2527f3..e8b7148 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -197,7 +197,8 @@ constructor (GType type,
 	 * system settings service a chance to figure out whether the device is
 	 * managed or not.
 	 */
-	priv->start_timer = g_timeout_add_seconds (4, device_start, dev);
+	//priv->start_timer = g_timeout_add_seconds (4, device_start, dev);
+	priv->start_timer = g_idle_add (device_start, dev);
 
 	priv->initialized = TRUE;
 	return object;
diff --git a/test/Makefile.am b/test/Makefile.am
index 47bf2a5..b62f06a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -29,6 +29,7 @@ nm_online_LDADD = \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS) \
 	$(HAL_LIBS) \
+	$(top_builddir)/libnm-glib/libnm_glib.la \
 	$(top_builddir)/libnm-util/libnm-util.la
 
 libnm_glib_test_SOURCES = libnm_glib_test.c
diff --git a/test/nm-online.c b/test/nm-online.c
index 3827c74..51f2d4e 100644
--- a/test/nm-online.c
+++ b/test/nm-online.c
@@ -1,24 +1,5 @@
 /* -*- 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 (C) 2006 - 2008 Novell, Inc.
- *
- */
-
-/*
  * nm-online.c - Are we online?
  *
  * Return values:
@@ -27,114 +8,134 @@
  *	1	: offline or not online within given timeout
  *	2	: unspecified error
  *
- * Robert Love <rml@novell.com>
+ * Tambet Ingo <tambet@novell.com>
  */
 
-#define PROGRESS_STEPS 15
+#include "NetworkManager.h"
+#include "nm-client.h"
 
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
+#define RESULT_ONLINE  0
+#define RESULT_OFFLINE 1
+#define RESULT_ERROR   2
 
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib.h>
+typedef struct {
+	NMClient *client;
+	GMainLoop *loop;
+	int timeout;
+	guint timeout_id;
+	int result;
+} OnlineInfo;
 
-#include "NetworkManager.h"
-#include "nm-glib-compat.h"
+static void manager_is_running (OnlineInfo *info);
 
-typedef struct 
+static gboolean
+ready_for_connecting (NMClient *client)
 {
-	int value;
-	double norm;
-	gboolean quiet;
-} Timeout;
+	const GPtrArray *devices;
+	int i;
+	gboolean ready = FALSE;
 
-static GMainLoop *loop;
+	devices = nm_client_get_devices (client);
+	for (i = 0; devices && devices->len > i; i++) {
+		NMDevice *device = NM_DEVICE (g_ptr_array_index (devices, i));
 
-static DBusHandlerResult dbus_filter (DBusConnection *connection G_GNUC_UNUSED,
-				      DBusMessage *message,
-				      void *user_data G_GNUC_UNUSED)
-{
-	NMState state;
+		if (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED)
+			ready = TRUE;
+	}
 
-	if (!dbus_message_is_signal (message, NM_DBUS_INTERFACE, "StateChanged"))
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	return ready;
+}
 
-	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
-		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+static gboolean
+timeout_cb (gpointer data)
+{
+	OnlineInfo *info = (OnlineInfo *) data;
 
-	if (state == NM_STATE_CONNECTED)
-		g_main_loop_quit (loop);
+	info->result = RESULT_OFFLINE;
+	g_main_loop_quit (info->loop);
 
-	return DBUS_HANDLER_RESULT_HANDLED;
+	return FALSE;
 }
 
-static NMState check_online (DBusConnection *connection)
+static void
+state_changed (NMClient *client,
+			   GParamSpec *pspec,
+			   gpointer user_data)
 {
-	DBusMessage *message, *reply;
-	DBusError error;
-	dbus_uint32_t state;
-	
-	message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH,
-						NM_DBUS_INTERFACE, "state");
-	if (!message)
-		exit (2);
-
-	dbus_error_init (&error);
-	reply = dbus_connection_send_with_reply_and_block (connection, message,
-							   -1, &error);
-	dbus_message_unref (message);
-	if (!reply) 
-		return NM_STATE_UNKNOWN;
-
-	if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &state,
-				    DBUS_TYPE_INVALID))
-		exit (2);
-
-	return state;
+	manager_is_running ((OnlineInfo *) user_data);
 }
 
-static gboolean handle_timeout (gpointer data)
+static void
+manager_is_running (OnlineInfo *info)
 {
-	int i = PROGRESS_STEPS;
-	Timeout *timeout = (Timeout *) data;
-
-	if (!timeout->quiet) {
-		g_print ("\rConnecting");
-		for (; i > 0; i--)
-			putchar ((timeout->value >= (i * timeout->norm)) ? ' ' : '.');
-		if (timeout->value)
-			g_print (" %4is", timeout->value);
-		fflush (stdout);
+	NMState state;
+	gboolean done = TRUE;
+
+	state = nm_client_get_state (info->client);
+	switch (state) {
+	case NM_STATE_CONNECTED:
+		/* Done */
+		info->result = RESULT_ONLINE;
+		break;
+	case NM_STATE_ASLEEP:
+		/* Networking disabled */
+		info->result = RESULT_OFFLINE;
+		break;
+	case NM_STATE_DISCONNECTED:
+		/* Disconnected, is it likely we start connecting? */
+		if (!ready_for_connecting (info->client)) {
+			info->result = RESULT_OFFLINE;
+			break;
+		}
+		/* Fall through */
+	case NM_STATE_CONNECTING:
+		/* Connecting, wait until done */
+		done = FALSE;
+		if (info->timeout_id == 0) {
+			g_signal_connect (info->client, "notify::" NM_CLIENT_STATE, G_CALLBACK (state_changed), info);
+			info->timeout_id = g_timeout_add_seconds (info->timeout, timeout_cb, info);
+		}
+		break;
+	default:
+		info->result = RESULT_ERROR;
+		break;
 	}
 
-	timeout->value--;
-	if (timeout->value < 0) {
-		if (!timeout->quiet)
-			g_print ("\n");
-		exit (1);
+	if (done) {
+		/* Done */
+		g_main_loop_quit (info->loop);
 	}
+}
 
-	return TRUE;
+static gboolean
+idle_cb (gpointer data)
+{
+	manager_is_running ((OnlineInfo *) data);
+	return FALSE;
 }
 
-int main (int argc, char *argv[])
+static void
+manager_running_changed (NMClient *client,
+						 GParamSpec *pspec,
+						 gpointer user_data)
 {
-	DBusConnection *connection;
-	DBusError error;
-	NMState state;
-	gint t_secs = -1;
+	if (nm_client_get_manager_running (client))
+		/* It just started up, give it a bit of time to discover devices etc */
+		g_timeout_add_seconds (1, idle_cb, user_data);
+}
+
+int
+main (int argc, char *argv[])
+{
+	OnlineInfo *info;
+	GOptionContext *opt_ctx;
+	gboolean success;
+	int timeout = -1;
 	gboolean exit_no_nm = FALSE;
 	gboolean quiet = FALSE;
-	Timeout timeout;
-	GOptionContext *opt_ctx = NULL;
-	gboolean success;
-
+	int res;
 	GOptionEntry options[] = {
-		{"timeout", 't', 0, G_OPTION_ARG_INT, &t_secs, "Time to wait for a connection, in seconds (default is 30)", NULL},
+		{"timeout", 't', 0, G_OPTION_ARG_INT, &timeout, "Time to wait for a connection, in seconds (default is 30)", NULL},
 		{"exit", 'x', 0, G_OPTION_ARG_NONE, &exit_no_nm, "Exit immediately if NetworkManager is not running or connecting", NULL},
 		{"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Don't print anything", NULL},
 		{NULL}
@@ -146,65 +147,49 @@ int main (int argc, char *argv[])
 	g_option_context_set_help_enabled (opt_ctx, TRUE);
 	g_option_context_add_main_entries (opt_ctx, options, NULL);
 
-	g_option_context_set_summary (opt_ctx,
-		"Waits for a successful connection in NetworkManager.");
-
+	g_option_context_set_summary (opt_ctx, "Waits for a successful connection in NetworkManager.");
 	success = g_option_context_parse (opt_ctx, &argc, &argv, NULL);
 	g_option_context_free (opt_ctx);
 
 	if (!success) {
-		g_error ("Invalid option.  Please use --help to see a list of valid options.");
-		return 2;
-	}
-	
-	if (t_secs > -1)
-		timeout.value = t_secs;
-	else
-		timeout.value = 30;
-	if (timeout.value < 0 || timeout.value > 3600)  {
-		g_error ("Invalid option.  Please use --help to see a list of valid options.");
-		return 2;
+		g_print ("Invalid option.  Please use --help to see a list of valid options.");
+		return RESULT_ERROR;
 	}
 
-	g_type_init ();
-	loop = g_main_loop_new (NULL, FALSE);
-
-	dbus_error_init (&error);
-	connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-	if (connection == NULL) {
-		dbus_error_free (&error);
-		return 2;
+	if (timeout < 0)
+		timeout = 30;
+	if (timeout > 3600) {
+		g_print ("Invalid option.  Please use --help to see a list of valid options.");
+		return RESULT_ERROR;
 	}
 
-	dbus_connection_setup_with_g_main (connection, NULL);
-
-	if (!dbus_connection_add_filter (connection, dbus_filter, NULL, NULL))
-		return 2;
+	g_type_init ();
 
-	dbus_bus_add_match (connection,
-			    "type='signal',"
-			    "interface='" NM_DBUS_INTERFACE "',"
-			    "sender='" NM_DBUS_SERVICE "',"
-			    "path='" NM_DBUS_PATH "'", &error);
-	if (dbus_error_is_set (&error)) {
-		dbus_error_free (&error);
-		return 2;
+	info = g_slice_new0 (OnlineInfo);
+	info->client = nm_client_new ();
+	info->loop = g_main_loop_new (NULL, FALSE);
+	info->result = RESULT_OFFLINE;
+	info->timeout = timeout;
+
+	if (nm_client_get_manager_running (info->client)) {
+		g_idle_add (idle_cb, info);
+	} else {
+		if (exit_no_nm) {
+			info->result = RESULT_OFFLINE;
+			goto done;
+		}
+
+		g_signal_connect (info->client, "notify::" NM_CLIENT_MANAGER_RUNNING,
+						  G_CALLBACK (manager_running_changed), info);
 	}
 
-	/* Check after we setup the filter to ensure that we cannot race. */
-	state = check_online (connection);
-	if (state == NM_STATE_CONNECTED)
-		return 0;
-	if (exit_no_nm && (state != NM_STATE_CONNECTING))
-		return 1;
-
-	if (timeout.value) {
-		timeout.norm = (double) timeout.value / (double) PROGRESS_STEPS;
-		g_timeout_add_seconds (1, handle_timeout, &timeout);
-	}
-	timeout.quiet = quiet;
+	g_main_loop_run (info->loop);
 
-	g_main_loop_run (loop);
+ done:
+	g_main_loop_unref (info->loop);
+	g_object_unref (info->client);
+	res = info->result;
+	g_slice_free (OnlineInfo, info);
 
-	return 0;
+	return res;
 }
