Index: src/applet-dbus.c
===================================================================
--- src/applet-dbus.c	(revision 78)
+++ src/applet-dbus.c	(working copy)
@@ -39,6 +39,7 @@
 
 #define	DBUS_NO_SERVICE_ERROR			"org.freedesktop.DBus.Error.ServiceDoesNotExist"
 
+
 void
 nma_dbus_vpn_set_last_attempt_status (NMApplet *applet, const char *vpn_name, gboolean last_attempt_success)
 {
Index: src/applet.c
===================================================================
--- src/applet.c	(revision 78)
+++ src/applet.c	(working copy)
@@ -42,6 +42,7 @@
 
 #include <nm-device-802-3-ethernet.h>
 #include <nm-device-802-11-wireless.h>
+#include <nm-device-bluetooth.h>
 
 #if !GTK_CHECK_VERSION(2,6,0)
 #include <gnome.h>
@@ -226,12 +227,16 @@
 		speed = nm_device_802_3_ethernet_get_speed (NM_DEVICE_802_3_ETHERNET (device));
 	else if (NM_IS_DEVICE_802_11_WIRELESS (device))
 		speed = nm_device_802_11_wireless_get_bitrate (NM_DEVICE_802_11_WIRELESS (device));
+	else if (NM_IS_DEVICE_BLUETOOTH (device))
+		speed = 0;
 
 	str = nm_device_get_iface (device);
 	if (NM_IS_DEVICE_802_3_ETHERNET (device))
 		iface_and_type = g_strdup_printf (_("Wired Ethernet (%s)"), str);
 	else if (NM_IS_DEVICE_802_11_WIRELESS (device))
 		iface_and_type = g_strdup_printf (_("Wireless Ethernet (%s)"), str);
+	else if (NM_IS_DEVICE_BLUETOOTH (device))
+		iface_and_type = g_strdup_printf (_("Bluetooth Ethernet (%s)"), str);
 	else
 		iface_and_type = g_strdup (str);
 
@@ -292,6 +297,8 @@
 		str = nm_device_802_3_ethernet_get_hw_address (NM_DEVICE_802_3_ETHERNET (device));
 	else if (NM_IS_DEVICE_802_11_WIRELESS (device))
 		str = nm_device_802_11_wireless_get_hw_address (NM_DEVICE_802_11_WIRELESS (device));
+	else if (NM_IS_DEVICE_BLUETOOTH (device))
+		str = nm_device_bluetooth_get_hw_address (NM_DEVICE_BLUETOOTH (device));
 
 	if (str) {
 		label = get_label (info_dialog, applet->info_dialog_xml, "label-hardware-address");
@@ -659,6 +666,8 @@
 		wireless = (NMSettingWireless *) setting;
 		wireless->ssid = nm_access_point_get_essid (info->ap);
 		wireless->mode = 1; /* FIXME: Define something for wireless modes */
+	} else if (NM_IS_DEVICE_BLUETOOTH (info->device)) {
+		setting = nm_setting_bluetooth_new ();
 	} else
 		g_warning ("Unhandled device type '%s'", G_OBJECT_CLASS_NAME (info->device));
 
@@ -833,8 +842,10 @@
 
 	if (NM_IS_DEVICE_802_11_WIRELESS (device)) {
 		menu_item = wireless_menu_item_new (NM_DEVICE_802_11_WIRELESS (device), n_devices);
-	} else if (NM_IS_DEVICE_802_3_ETHERNET (device))
+	} else if (NM_IS_DEVICE_802_3_ETHERNET (device)) {
 		menu_item = wired_menu_item_new (NM_DEVICE_802_3_ETHERNET (device), n_devices);
+	} else if (NM_IS_DEVICE_BLUETOOTH (device))
+		menu_item = bluetooth_menu_item_new (NM_DEVICE_BLUETOOTH (device), menu, applet, n_devices);
 	else
 		g_warning ("Unhandled device type %s", G_OBJECT_CLASS_NAME (device));
 
@@ -900,6 +911,49 @@
 }
 
 
+static void custom_bluetooth_item_selected (GtkWidget *menu_item, NMApplet *applet)
+{
+	nma_other_network_dialog_run (applet, FALSE);
+}
+
+
+static void nma_menu_add_custom_bluetooth_item (GtkWidget *menu, NMApplet *applet)
+{
+	GtkWidget *menu_item;
+	GtkWidget *label;
+
+	menu_item = gtk_menu_item_new ();
+	label = gtk_label_new_with_mnemonic (_("Connect to _Other Bluetooth Network..."));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_container_add (GTK_CONTAINER (menu_item), label);
+	gtk_widget_show_all (menu_item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+	g_signal_connect (menu_item, "activate", G_CALLBACK (custom_bluetooth_item_selected), applet);
+}
+
+
+static void new_bluetooth_item_selected (GtkWidget *menu_item, NMApplet *applet)
+{
+	nma_other_network_dialog_run (applet, TRUE);
+}
+
+
+static void
+nma_menu_add_create_bluetooth_item (GtkWidget *menu, NMApplet *applet)
+{
+	GtkWidget *menu_item;
+	GtkWidget *label;
+
+	menu_item = gtk_menu_item_new ();
+	label = gtk_label_new_with_mnemonic (_("Create New _Bluetooth Network..."));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_container_add (GTK_CONTAINER (menu_item), label);
+	gtk_widget_show_all (menu_item);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+	g_signal_connect (menu_item, "activate", G_CALLBACK (new_bluetooth_item_selected), applet);
+}
+
+
 typedef struct {
 	NMApplet *	applet;
 	NMDevice *device;
@@ -1110,6 +1164,7 @@
 	GSList *iter;
 	gint n_wireless_interfaces = 0;
 	gint n_wired_interfaces = 0;
+	gint n_bluetooth_interfaces = 0;
 
 	if (nm_client_get_state (applet->nm_client) == NM_STATE_ASLEEP) {
 		nma_menu_add_text_item (menu, _("Networking disabled"));
@@ -1127,11 +1182,14 @@
 		if (NM_IS_DEVICE_802_11_WIRELESS (device)) {
 			if (nm_client_wireless_get_enabled (applet->nm_client))
 				n_wireless_interfaces++;
-		} else if (NM_IS_DEVICE_802_3_ETHERNET (device))
+		} else if (NM_IS_DEVICE_802_3_ETHERNET (device)) {
 			n_wired_interfaces++;
+		} else if (NM_IS_DEVICE_BLUETOOTH (device))
+			if (nm_client_bluetooth_get_enabled (applet->nm_client))
+				n_bluetooth_interfaces = 1;
 	}
 
-	if (n_wired_interfaces == 0 && n_wireless_interfaces == 0) {
+	if (n_wired_interfaces == 0 && n_wireless_interfaces == 0 && n_bluetooth_interfaces == 0) {
 		nma_menu_add_text_item (menu, _("No network devices have been found"));
 		goto out;
 	}
@@ -1149,6 +1207,8 @@
 			n_devices = n_wireless_interfaces;
 		else if (NM_IS_DEVICE_802_3_ETHERNET (device))
 			n_devices = n_wired_interfaces++;
+		else if (NM_IS_DEVICE_BLUETOOTH (device) && (n_bluetooth_interfaces > 0))
+			n_devices = n_bluetooth_interfaces++;
 
 		nma_menu_add_device_item (menu, device, n_devices, applet);
 		nma_menu_device_add_networks (menu, device, applet);
@@ -1167,6 +1227,15 @@
 		nma_menu_add_create_network_item (menu, applet);
 	}
 
+	if (n_bluetooth_interfaces > 0 && nm_client_bluetooth_get_enabled (applet->nm_client)) {
+		/* Add the "Other bluetooth network..." entry */
+		/* FIXME: add Bluetooth custom and server dialogs
+		nma_menu_add_separator_item (GTK_MENU_SHELL (menu));
+		nma_menu_add_custom_bluetooth_item (menu, applet);
+		nma_menu_add_create_bluetooth_item (menu, applet);
+		*/
+	}
+
  out:
 	g_slist_free (devices);
 }
@@ -1183,7 +1252,17 @@
 	nm_client_wireless_set_enabled (applet->nm_client, state);
 }
 
+static void
+nma_set_bluetooth_enabled_cb (GtkWidget *widget, NMApplet *applet)
+{
+	gboolean state;
 
+	g_return_if_fail (applet != NULL);
+
+	state = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget));
+	nm_client_bluetooth_set_enabled (applet->nm_client, state);
+}
+
 static void
 nma_set_networking_enabled_cb (GtkWidget *widget, NMApplet *applet)
 {
@@ -1329,6 +1408,7 @@
 {
 	NMState state;
 	gboolean have_wireless = FALSE;
+	gboolean have_bluetooth = FALSE;
 
 	state = nm_client_get_state (applet->nm_client);
 
@@ -1338,19 +1418,22 @@
 	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (applet->stop_wireless_item),
 							  nm_client_wireless_get_enabled (applet->nm_client));
 
+	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (applet->stop_bluetooth_item),
+							  nm_client_bluetooth_get_enabled (applet->nm_client));
+
 	gtk_widget_set_sensitive (applet->info_menu_item,
 						 state == NM_STATE_CONNECTED);
 
 	if (state != NM_STATE_ASLEEP) {
 		GSList *list;
 		GSList *iter;
-	
+
 		list = nm_client_get_devices (applet->nm_client);
 		for (iter = list; iter; iter = iter->next) {
-			if (NM_IS_DEVICE_802_11_WIRELESS (iter->data)) {
+			if (NM_IS_DEVICE_802_11_WIRELESS (iter->data))
 				have_wireless = TRUE;
-				break;
-			}
+			else if (NM_IS_DEVICE_BLUETOOTH (iter->data))
+				have_bluetooth = TRUE;
 		}
 		g_slist_free (list);
 	}
@@ -1359,6 +1442,12 @@
 		gtk_widget_show_all (applet->stop_wireless_item);
 	else
 		gtk_widget_hide (applet->stop_wireless_item);
+
+	if (have_bluetooth)
+		gtk_widget_show_all (applet->stop_bluetooth_item);
+	else
+		gtk_widget_hide (applet->stop_bluetooth_item);
+
 }
 
 
@@ -1409,6 +1498,14 @@
 				   applet);
 	gtk_menu_shell_append (menu, applet->stop_wireless_item);
 
+	/* 'Enable Bluetooth' item */
+	applet->stop_bluetooth_item = gtk_check_menu_item_new_with_mnemonic (_("Enable _Bluetooth"));
+	g_signal_connect (applet->stop_bluetooth_item,
+				   "toggled",
+				   G_CALLBACK (nma_set_bluetooth_enabled_cb),
+				   applet);
+	gtk_menu_shell_append (menu, applet->stop_bluetooth_item);
+
 	/* 'Connection Information' item */
 	applet->info_menu_item = gtk_image_menu_item_new_with_mnemonic (_("Connection _Information"));
 	g_signal_connect (applet->info_menu_item,
@@ -2057,6 +2154,54 @@
 	return handled;
 }
 
+static gboolean
+foo_bluetooth_state_change (NMDeviceBluetooth *device, NMDeviceState state, NMApplet *applet)
+{
+	char *iface;
+	char *tip = NULL;
+	char *name;
+	gboolean handled = FALSE;
+
+	iface = nm_device_get_iface (NM_DEVICE (device));
+
+	switch (state) {
+	case NM_DEVICE_STATE_PREPARE:
+		tip = g_strdup_printf (_("Preparing device %s for the Bluetooth network..."), iface);
+		break;
+	case NM_DEVICE_STATE_CONFIG:
+		tip = g_strdup_printf (_("Configuring device %s for the Bluetooth network..."), iface);
+		break;
+	case NM_DEVICE_STATE_IP_CONFIG:
+		tip = g_strdup_printf (_("Requesting a network address from the Bluetooth network..."));
+		break;
+	case NM_DEVICE_STATE_ACTIVATED:
+		foo_set_icon (applet, applet->wired_icon, ICON_LAYER_LINK);
+		tip = g_strdup (_("Bluetooth network connection"));
+
+#ifdef ENABLE_NOTIFY
+		name = nm_device_bluetooth_get_name (device);
+		tip = g_strdup_printf (_("You are now connected to the bluetooth network '%s'."), name);
+		nma_send_event_notification (applet, NOTIFY_URGENCY_LOW, _("Connection Established"),
+							    tip, "nm-device-blueooth");
+		g_free (tip);
+#endif
+
+		handled = TRUE;
+		break;
+	default:
+		break;
+	}
+
+	g_free (iface);
+
+	if (tip) {
+		gtk_status_icon_set_tooltip (applet->status_icon, tip);
+		g_free (tip);
+	}
+
+	return handled;
+}
+
 static void
 foo_device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
 {
@@ -2073,6 +2218,8 @@
 		handled = foo_wired_state_change (NM_DEVICE_802_3_ETHERNET (device), state, applet);
 	else if (NM_IS_DEVICE_802_11_WIRELESS (device))
 		handled = foo_wireless_state_change (NM_DEVICE_802_11_WIRELESS (device), state, applet);
+	else if (NM_IS_DEVICE_BLUETOOTH (device))
+		handled = foo_bluetooth_state_change (NM_DEVICE_BLUETOOTH (device), state, applet);
 
 	if (!handled)
 		foo_common_state_change (device, state, applet);
Index: src/applet.h
===================================================================
--- src/applet.h	(revision 78)
+++ src/applet.h	(working copy)
@@ -145,6 +145,7 @@
 	GtkWidget *		context_menu;
 	GtkWidget *		enable_networking_item;
 	GtkWidget *		stop_wireless_item;
+	GtkWidget *		stop_bluetooth_item;
 	GtkWidget *		info_menu_item;
 
 	GtkWidget *		passphrase_dialog;
Index: src/menu-items.c
===================================================================
--- src/menu-items.c	(revision 78)
+++ src/menu-items.c	(working copy)
@@ -38,6 +38,7 @@
 #include "menu-items.h"
 #include "applet-dbus.h"
 
+#define	GN_UUID		"00001117-0000-1000-8000-00805f9b34fb"
 
 /****************************************************************
  *   Wired menu item
@@ -80,19 +81,90 @@
 }
 
 /****************************************************************
- *   Wireless menu item
+ *   Bluetooth menu item
  ****************************************************************/
 
+struct NMNetworkMenuItem
+{
+	GtkCheckMenuItem	*check_item;
+	GtkLabel			*label;
+	GtkWidget			*progress;
+	GtkWidget			*security_image;
+};
+
+
 static gboolean
 label_expose (GtkWidget *widget)
 {
 	/* Bad hack to make the label draw normally, instead of insensitive. */
 	widget->state = GTK_STATE_NORMAL;
-  
+
 	return FALSE;
 }
 
 GtkMenuItem *
+bluetooth_menu_item_new (NMDeviceBluetooth *device,
+					 GtkWidget *menu,
+					 NMApplet *applet,
+					 gint n_devices)
+{
+	char *label;
+	char *mode;
+	gdouble percent;
+	NMNetworkMenuItem *item;
+	GtkCheckMenuItem *gtk_item;
+	gint16 strength;
+
+	g_return_val_if_fail (NM_IS_DEVICE_BLUETOOTH (device), NULL);
+
+	/* Only show bluetooth device with a valid name */
+	if (n_devices < 1 || !(label = nm_device_bluetooth_get_name (device)))
+		return NULL;
+
+	if (n_devices == 1) {
+		GtkMenuItem *item;
+		char *text;
+
+		text = g_strdup (_("Bluetooth Networks"));
+
+		item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (text));
+		g_free (text);
+
+		g_signal_connect (item, "expose-event", G_CALLBACK (label_expose), NULL);
+		gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
+		gtk_widget_show (GTK_WIDGET (item));
+	}
+
+	item = network_menu_item_new (applet->encryption_size_group);
+	gtk_item = network_menu_item_get_check_item (item);
+
+	gtk_label_set_text (GTK_LABEL (item->label), nm_menu_network_escape_essid_for_display (label));
+
+	strength = nm_device_bluetooth_get_strength (device);
+	percent = (double) (100 - 80 * (-56 - strength) / (-56 + 100)) / 100;
+	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (item->progress), percent);
+
+	/* Deal with the encrypted icon */
+	g_object_set (item->security_image, "visible", FALSE, NULL);
+
+	mode = nm_device_bluetooth_get_uuid (device);
+
+	if (mode && g_str_equal (mode, GN_UUID))
+		gtk_image_set_from_pixbuf (GTK_IMAGE (item->security_image), applet->adhoc_icon);
+	else
+		gtk_image_set_from_stock (GTK_IMAGE (item->security_image), NULL, GTK_ICON_SIZE_MENU);
+
+	gtk_check_menu_item_set_active (gtk_item, nm_device_get_state (NM_DEVICE (device)) == NM_DEVICE_STATE_ACTIVATED);
+
+	return GTK_MENU_ITEM (gtk_item);
+}
+
+/****************************************************************
+ *   Wireless menu item
+ ****************************************************************/
+
+GtkMenuItem *
 wireless_menu_item_new (NMDevice80211Wireless *device,
 						gint n_devices)
 {
@@ -131,15 +203,7 @@
  *   Wireless Network menu item
  ****************************************************************/
 
-struct NMNetworkMenuItem
-{
-	GtkCheckMenuItem	*check_item;
-	GtkLabel			*label;
-	GtkWidget			*progress;
-	GtkWidget			*security_image;
-};
 
-
 NMNetworkMenuItem *
 network_menu_item_new (GtkSizeGroup *encryption_size_group)
 {
Index: src/menu-items.h
===================================================================
--- src/menu-items.h	(revision 78)
+++ src/menu-items.h	(working copy)
@@ -27,12 +27,18 @@
 
 #include <nm-device-802-3-ethernet.h>
 #include <nm-device-802-11-wireless.h>
+#include <nm-device-bluetooth.h>
 
 typedef struct NMNetworkMenuItem NMNetworkMenuItem;
 
 GtkMenuItem *wired_menu_item_new (NMDevice8023Ethernet *device,
 								  gint n_devices);
 
+GtkMenuItem *bluetooth_menu_item_new (NMDeviceBluetooth *device,
+									  GtkWidget *menu,
+									  NMApplet *applet,
+									  gint n_devices);
+
 GtkMenuItem *wireless_menu_item_new (NMDevice80211Wireless *device,
 									 gint n_devices);
 
