diff --git a/configure.ac b/configure.ac
index 81d9b59..7a365d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -489,6 +489,8 @@ panels/printers/gnome-printers-panel.desktop.in
 panels/privacy/Makefile
 panels/privacy/gnome-privacy-panel.desktop.in
 panels/network/Makefile
+panels/network/wireless-security/Makefile
+panels/network/connection-editor/Makefile
 panels/network/gnome-network-panel.desktop.in
 panels/notifications/Makefile
 panels/notifications/gnome-notifications-panel.desktop.in
diff --git a/egg-list-box b/egg-list-box
--- a/egg-list-box
+++ b/egg-list-box
@@ -1 +1 @@
-Subproject commit b32d1270655f7c6c83550ae1adc0934105c0cc00
+Subproject commit b32d1270655f7c6c83550ae1adc0934105c0cc00-dirty
diff --git a/panels/network/Makefile.am b/panels/network/Makefile.am
index 3ee94bf..ff7a0b6 100644
--- a/panels/network/Makefile.am
+++ b/panels/network/Makefile.am
@@ -1,5 +1,7 @@
 cappletname = network
 
+SUBDIRS = wireless-security connection-editor
+
 INCLUDES = 						\
 	$(PANEL_CFLAGS)					\
 	$(NETWORK_PANEL_CFLAGS)				\
@@ -7,6 +9,7 @@ INCLUDES = 						\
 	-DGNOMECC_UI_DIR="\"$(uidir)\""			\
 	-DGNOMELOCALEDIR="\"$(datadir)/locale\""	\
 	-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\""		\
+	-I$(srcdir)/wireless-security			\
 	$(NULL)
 
 noinst_LTLIBRARIES = libnetwork.la
@@ -32,18 +35,6 @@ libnetwork_la_SOURCES =					\
 	net-vpn.h					\
 	net-proxy.c					\
 	net-proxy.h					\
-	panel-cell-renderer-mode.c			\
-	panel-cell-renderer-mode.h			\
-	panel-cell-renderer-security.c			\
-	panel-cell-renderer-security.h			\
-	panel-cell-renderer-signal.c			\
-	panel-cell-renderer-signal.h			\
-	panel-cell-renderer-separator.c			\
-	panel-cell-renderer-separator.h			\
-	panel-cell-renderer-text.c			\
-	panel-cell-renderer-text.h			\
-	panel-cell-renderer-pixbuf.c			\
-	panel-cell-renderer-pixbuf.h			\
 	network-dialogs.c				\
 	network-dialogs.h				\
 	cc-network-panel.c				\
@@ -52,7 +43,9 @@ libnetwork_la_SOURCES =					\
 	rfkill-glib.h					\
 	rfkill.h
 
-libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS)
+libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS) $(builddir)/connection-editor/libconnection-editor.la
+
+libnetwork_la_LDFLAGS = $(PANEL_LDFLAGS)
 
 uidir = $(pkgdatadir)/ui
 dist_ui_DATA =						\
@@ -61,6 +54,7 @@ dist_ui_DATA =						\
 	network-wifi.ui					\
 	network-simple.ui				\
 	network-mobile.ui				\
+	network-ethernet.ui				\
 	network.ui
 
 @INTLTOOL_DESKTOP_RULE@
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index bf48559..2a4ea1c 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -97,7 +97,7 @@ enum {
         PROP_ARGV
 };
 
-static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id);
+static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
 static void handle_argv (CcNetworkPanel *panel);
 
 static void
@@ -598,6 +598,28 @@ handle_argv (CcNetworkPanel *panel)
         g_debug ("Could not handle argv operation, no matching device yet?");
 }
 
+static void
+state_changed_cb (NMDevice *device,
+                  NMDeviceState new_state,
+                  NMDeviceState old_state,
+                  NMDeviceStateReason reason,
+                  CcNetworkPanel *panel)
+{
+        GtkListStore *store;
+        GtkTreeIter iter;
+
+        if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) {
+                return;
+        }
+
+        store = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
+                                                        "liststore_devices"));
+
+        gtk_list_store_set (store, &iter,
+                            PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device),
+                           -1);
+}
+
 static gboolean
 panel_add_device (CcNetworkPanel *panel, NMDevice *device)
 {
@@ -611,7 +633,7 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
         GType device_g_type;
 
         /* do we have an existing object with this id? */
-        if (find_in_model_by_id (panel, nm_device_get_udi (device)) != NULL)
+        if (find_in_model_by_id (panel, nm_device_get_udi (device), NULL) != NULL)
                 goto out;
 
         type = nm_device_get_device_type (device);
@@ -671,6 +693,8 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
                             PANEL_DEVICES_COLUMN_SORT, panel_device_to_sortable_string (device),
                             PANEL_DEVICES_COLUMN_OBJECT, net_device,
                             -1);
+        g_signal_connect (device, "state-changed",
+                          G_CALLBACK (state_changed_cb), panel);
 
 out:
         return FALSE;
@@ -938,7 +962,7 @@ out:
 }
 
 static NetObject *
-find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
+find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out)
 {
         gboolean ret;
         NetObject *object_tmp;
@@ -967,6 +991,8 @@ find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
                 }
         } while (object == NULL && gtk_tree_model_iter_next (model, &iter));
 out:
+        if (iter_out)
+                *iter_out = iter;
         return object;
 }
 
@@ -983,7 +1009,7 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
 
         /* does already exist */
         id = nm_connection_get_path (connection);
-        if (find_in_model_by_id (panel, id) != NULL)
+        if (find_in_model_by_id (panel, id, NULL) != NULL)
                 return;
 
         /* add as a virtual object */
diff --git a/panels/network/connection-editor/8021x-security-page.ui b/panels/network/connection-editor/8021x-security-page.ui
new file mode 100644
index 0000000..7bc8c3a
--- /dev/null
+++ b/panels/network/connection-editor/8021x-security-page.ui
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkGrid" id="grid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">50</property>
+        <property name="margin_right">50</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="row_spacing">10</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="heading_sec">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">802.1x _Security</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">8021x_switch</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkSwitch" id="8021x_switch">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">2</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">page 1</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkGrid" id="grid1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">50</property>
+        <property name="margin_right">50</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
+        <property name="row_spacing">10</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkEntry" id="entry1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+            <property name="width_chars">35</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry2">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry3">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry4">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">3</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry5">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">4</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry6">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">5</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry7">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">6</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry8">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">7</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry9">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">8</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry10">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">9</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Anony_mous identity</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Inner _authentication</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label2">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">page 2</property>
+      </object>
+      <packing>
+        <property name="position">1</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child type="tab">
+      <placeholder/>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/Makefile.am b/panels/network/connection-editor/Makefile.am
new file mode 100644
index 0000000..1e1e3b4
--- /dev/null
+++ b/panels/network/connection-editor/Makefile.am
@@ -0,0 +1,50 @@
+noinst_LTLIBRARIES = libconnection-editor.la
+
+libconnection_editor_la_SOURCES = 		\
+	net-connection-editor.h			\
+	net-connection-editor.c			\
+	ce-page.h				\
+	ce-page.c				\
+	ce-page-details.h			\
+	ce-page-details.c			\
+	ce-page-wifi.h				\
+	ce-page-wifi.c				\
+	ce-page-ip4.h				\
+	ce-page-ip4.c				\
+	ce-page-ip6.h				\
+	ce-page-ip6.c				\
+	ce-page-security.h			\
+	ce-page-security.c			\
+	ce-page-reset.h				\
+	ce-page-reset.c				\
+	ce-page-ethernet.h			\
+	ce-page-ethernet.c			\
+	ce-page-8021x-security.h		\
+	ce-page-8021x-security.c
+
+libconnection_editor_la_CPPFLAGS = 		\
+	-I$(srcdir)/../wireless-security	\
+	$(NETWORK_PANEL_CFLAGS) 		\
+        $(NETWORK_MANAGER_CFLAGS)		\
+	-DGNOMECC_UI_DIR=\""$(uidir)"\"
+
+libconnection_editor_la_LIBADD = 		\
+	$(builddir)/../wireless-security/libwireless-security.la \
+	$(NETWORK_PANEL_LIBS) 			\
+	$(NETWORK_MANAGER_LIBS)
+
+uidir = $(pkgdatadir)/ui
+ui_DATA = 					\
+	connection-editor.ui			\
+	details-page.ui				\
+	wifi-page.ui				\
+	ip4-page.ui				\
+	ip6-page.ui				\
+	reset-page.ui				\
+	security-page.ui			\
+	ethernet-page.ui			\
+	8021x-security-page.ui
+
+EXTRA_DIST = \
+	$(ui_DATA)
+
diff --git a/panels/network/connection-editor/ce-page-8021x-security.c b/panels/network/connection-editor/ce-page-8021x-security.c
new file mode 100644
index 0000000..036da84
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-8021x-security.c
@@ -0,0 +1,194 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2008 - 2012 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <NetworkManager.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-wireless.h>
+#include <nm-utils.h>
+
+#include "wireless-security.h"
+#include "ce-page-ethernet.h"
+#include "ce-page-8021x-security.h"
+
+G_DEFINE_TYPE (CEPage8021xSecurity, ce_page_8021x_security, CE_TYPE_PAGE)
+
+static void
+enable_toggled (GObject *sw, GParamSpec *pspec, gpointer user_data)
+{
+	CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data);
+
+	gtk_widget_set_sensitive (page->security_widget, gtk_switch_get_active (page->enabled));
+	ce_page_changed (CE_PAGE (page));
+}
+
+static void
+stuff_changed (WirelessSecurity *sec, gpointer user_data)
+{
+        ce_page_changed (CE_PAGE (user_data));
+}
+
+static void
+finish_setup (CEPage8021xSecurity *page, gpointer unused, GError *error, gpointer user_data)
+{
+	GtkWidget *parent;
+        GtkWidget *vbox;
+        GtkWidget *heading;
+
+	if (error)
+		return;
+
+        vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox"));
+        heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec"));
+
+        page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+	page->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (page)->connection, TRUE, FALSE);
+	if (!page->security) {
+		g_warning ("Could not load 802.1x user interface.");
+		return;
+	}
+
+	wireless_security_set_changed_notify (page->security, stuff_changed, page);
+	page->security_widget = wireless_security_get_widget (page->security);
+	parent = gtk_widget_get_parent (page->security_widget);
+	if (parent)
+		gtk_container_remove (GTK_CONTAINER (parent), page->security_widget);
+
+	gtk_switch_set_active (page->enabled, page->initial_have_8021x);
+	g_signal_connect (page->enabled, "notify::active", G_CALLBACK (enable_toggled), page);
+	gtk_widget_set_sensitive (page->security_widget, page->initial_have_8021x);
+
+        gtk_size_group_add_widget (page->group, heading);
+        wireless_security_add_to_size_group (page->security, page->group);
+
+	gtk_container_add (GTK_CONTAINER (vbox), page->security_widget);
+
+}
+
+CEPage *
+ce_page_8021x_security_new (NMConnection     *connection,
+                            NMClient         *client,
+                            NMRemoteSettings *settings)
+{
+	CEPage8021xSecurity *page;
+
+	page = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY,
+	                                            connection,
+	                                            client,
+	                                            settings,
+	                                            GNOMECC_UI_DIR "/8021x-security-page.ui",
+	                                            _("Security")));
+
+	if (nm_connection_get_setting_802_1x (connection))
+		page->initial_have_8021x = TRUE;
+
+	page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "8021x_switch"));
+
+	g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL);
+
+	if (page->initial_have_8021x)
+                CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME;
+
+	return CE_PAGE (page);
+}
+
+static gboolean
+validate (CEPage *cepage, NMConnection *connection, GError **error)
+{
+	CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (cepage);
+	gboolean valid = TRUE;
+
+	if (gtk_switch_get_active (page->enabled)) {
+		NMConnection *tmp_connection;
+		NMSetting *s_8021x;
+
+		/* FIXME: get failed property and error out of wireless security objects */
+		valid = wireless_security_validate (page->security, NULL);
+		if (valid) {
+			NMSetting *s_con;
+
+			/* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */
+			tmp_connection = nm_connection_new ();
+			nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ());
+
+			/* temp connection needs a 'connection' setting too, since most of
+			 * the EAP methods need the UUID for CA cert ignore stuff.
+			 */
+			s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+			nm_connection_add_setting (tmp_connection, nm_setting_duplicate (s_con));
+
+			ws_802_1x_fill_connection (page->security, "wpa_eap_auth_combo", tmp_connection);
+
+			s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
+			nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
+
+			g_object_unref (tmp_connection);
+		} else
+			g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Invalid 802.1x security");
+	} else {
+		nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
+		valid = TRUE;
+	}
+
+	return valid;
+}
+
+static void
+ce_page_8021x_security_init (CEPage8021xSecurity *page)
+{
+}
+
+static void
+dispose (GObject *object)
+{
+	CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (object);
+
+	if (page->security) {
+		wireless_security_unref (page->security);
+                page->security = NULL;
+        }
+
+        g_clear_object (&page->group);
+
+	G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object);
+}
+
+static void
+ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (security_class);
+	CEPageClass *parent_class = CE_PAGE_CLASS (security_class);
+
+	/* virtual methods */
+	object_class->dispose = dispose;
+
+	parent_class->validate = validate;
+}
diff --git a/panels/network/connection-editor/ce-page-8021x-security.h b/panels/network/connection-editor/ce-page-8021x-security.h
new file mode 100644
index 0000000..f61de9e
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-8021x-security.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2008 - 2012 Red Hat, Inc.
+ */
+
+#ifndef __CE_PAGE_8021X_SECURITY_H
+#define __CE_PAGE_8021X_SECURITY_H
+
+#include <nm-connection.h>
+#include "wireless-security.h"
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "ce-page.h"
+
+#define CE_TYPE_PAGE_8021X_SECURITY            (ce_page_8021x_security_get_type ())
+#define CE_PAGE_8021X_SECURITY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurity))
+#define CE_PAGE_8021X_SECURITY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass))
+#define CE_IS_PAGE_8021X_SECURITY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_8021X_SECURITY))
+#define CE_IS_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_8021X_SECURITY))
+#define CE_PAGE_8021X_SECURITY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass))
+
+typedef struct CEPage8021xSecurity      CEPage8021xSecurity;
+typedef struct CEPage8021xSecurityClass CEPage8021xSecurityClass;
+
+struct CEPage8021xSecurity {
+	CEPage parent;
+
+        GtkSwitch *enabled;
+        GtkWidget *security_widget;
+        WirelessSecurity *security;
+        GtkSizeGroup *group;
+        gboolean initial_have_8021x;
+};
+
+struct CEPage8021xSecurityClass {
+	CEPageClass parent;
+};
+
+GType ce_page_8021x_security_get_type (void);
+
+CEPage *ce_page_8021x_security_new (NMConnection     *connection,
+                                    NMClient         *client,
+                                    NMRemoteSettings *settings);
+
+#endif  /* __CE_PAGE_8021X_SECURITY_H */
diff --git a/panels/network/connection-editor/ce-page-details.c b/panels/network/connection-editor/ce-page-details.c
new file mode 100644
index 0000000..9fbe9fa
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-details.c
@@ -0,0 +1,247 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include <nm-utils.h>
+#include <nm-device-wifi.h>
+#include <nm-device-ethernet.h>
+
+#include "../panel-common.h"
+#include "ce-page-details.h"
+
+G_DEFINE_TYPE (CEPageDetails, ce_page_details, CE_TYPE_PAGE)
+
+static gchar *
+get_ap_security_string (NMAccessPoint *ap)
+{
+        NM80211ApSecurityFlags wpa_flags, rsn_flags;
+        NM80211ApFlags flags;
+        GString *str;
+
+        flags = nm_access_point_get_flags (ap);
+        wpa_flags = nm_access_point_get_wpa_flags (ap);
+        rsn_flags = nm_access_point_get_rsn_flags (ap);
+
+        str = g_string_new ("");
+        if ((flags & NM_802_11_AP_FLAGS_PRIVACY) &&
+            (wpa_flags == NM_802_11_AP_SEC_NONE) &&
+            (rsn_flags == NM_802_11_AP_SEC_NONE)) {
+                /* TRANSLATORS: this WEP WiFi security */
+                g_string_append_printf (str, "%s, ", _("WEP"));
+        }
+        if (wpa_flags != NM_802_11_AP_SEC_NONE) {
+                /* TRANSLATORS: this WPA WiFi security */
+                g_string_append_printf (str, "%s, ", _("WPA"));
+        }
+        if (rsn_flags != NM_802_11_AP_SEC_NONE) {
+                /* TRANSLATORS: this WPA WiFi security */
+                g_string_append_printf (str, "%s, ", _("WPA2"));
+        }
+        if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ||
+            (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
+                /* TRANSLATORS: this Enterprise WiFi security */
+                g_string_append_printf (str, "%s, ", _("Enterprise"));
+        }
+        if (str->len > 0)
+                g_string_set_size (str, str->len - 2);
+        else {
+                g_string_append (str, C_("Wifi security", "None"));
+        }
+        return g_string_free (str, FALSE);
+}
+
+static void
+update_last_used (CEPageDetails *page, NMConnection *connection)
+{
+        gchar *last_used = NULL;
+        GDateTime *now = NULL;
+        GDateTime *then = NULL;
+        gint days;
+        GTimeSpan diff;
+        guint64 timestamp;
+        NMSettingConnection *s_con;
+
+        s_con = nm_connection_get_setting_connection (connection);
+        if (s_con == NULL)
+                goto out;
+        timestamp = nm_setting_connection_get_timestamp (s_con);
+        if (timestamp == 0) {
+                last_used = g_strdup (_("Never"));
+                goto out;
+        }
+
+        /* calculate the amount of time that has elapsed */
+        now = g_date_time_new_now_utc ();
+        then = g_date_time_new_from_unix_utc (timestamp);
+
+        diff = g_date_time_difference  (now, then);
+        days = diff / G_TIME_SPAN_DAY;
+        if (days == 0)
+                last_used = g_strdup (_("Today"));
+        else if (days == 1)
+                last_used = g_strdup (_("Yesterday"));
+        else
+                last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days);
+out:
+        panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", last_used);
+        if (now != NULL)
+                g_date_time_unref (now);
+        if (then != NULL)
+                g_date_time_unref (then);
+        g_free (last_used);
+}
+
+static void
+connect_details_page (CEPageDetails *page)
+{
+        guint speed;
+        guint strength;
+        NMDeviceState state;
+        NMAccessPoint *active_ap;
+        const gchar *str;
+        gboolean device_is_active;
+
+        if (NM_IS_DEVICE_WIFI (page->device))
+                active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device));
+        else
+                active_ap = NULL;
+
+        state = nm_device_get_state (page->device);
+
+        device_is_active = FALSE;
+        speed = 0;
+        if (active_ap && page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) {
+                device_is_active = TRUE;
+                if (NM_IS_DEVICE_WIFI (page->device))
+                        speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
+        } else {
+                NMActiveConnection *ac;
+                const gchar *p1, *p2;
+
+                ac = nm_device_get_active_connection (page->device);
+                p1 = ac ? nm_active_connection_get_connection (ac) : NULL;
+                p2 = nm_connection_get_path (CE_PAGE (page)->connection);
+                if (g_strcmp0 (p1, p2) == 0) {
+                        device_is_active = TRUE;
+                        if (NM_IS_DEVICE_WIFI (page->device))
+                                speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
+                        else if (NM_IS_DEVICE_ETHERNET (page->device))
+                                speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (page->device));
+                }
+        }
+        if (speed > 0)
+                str = g_strdup_printf (_("%d Mb/s"), speed);
+        else
+                str = NULL;
+        panel_set_device_widget_details (CE_PAGE (page)->builder, "speed", str);
+
+        if (NM_IS_DEVICE_WIFI (page->device))
+                str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (page->device));
+        else if (NM_IS_DEVICE_ETHERNET (page->device))
+                str = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (page->device));
+
+        panel_set_device_widget_details (CE_PAGE (page)->builder, "mac", str);
+
+        str = NULL;
+        if (device_is_active && active_ap)
+                str = get_ap_security_string (active_ap);
+        panel_set_device_widget_details (CE_PAGE (page)->builder, "security", str);
+
+        strength = 0;
+        if (page->ap != NULL)
+                strength = nm_access_point_get_strength (page->ap);
+
+        if (strength <= 0)
+                str = NULL;
+        else if (strength < 20)
+                str = C_("Signal strength", "None");
+        else if (strength < 40)
+                str = C_("Signal strength", "Weak");
+        else if (strength < 50)
+                str = C_("Signal strength", "Ok");
+        else if (strength < 80)
+                str = C_("Signal strength", "Good");
+        else
+                str = C_("Signal strength", "Excellent");
+        panel_set_device_widget_details (CE_PAGE (page)->builder, "strength", str);
+
+        /* set IP entries */
+        if (device_is_active)
+                panel_set_device_widgets (CE_PAGE (page)->builder, page->device);
+        else
+                panel_unset_device_widgets (CE_PAGE (page)->builder);
+
+        if (!device_is_active && CE_PAGE (page)->connection)
+                update_last_used (page, CE_PAGE (page)->connection);
+        else
+                panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", NULL);
+
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        return TRUE;
+}
+
+static void
+ce_page_details_init (CEPageDetails *page)
+{
+}
+
+static void
+ce_page_details_class_init (CEPageDetailsClass *class)
+{
+        CEPageClass *page_class= CE_PAGE_CLASS (class);
+
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_details_new (NMConnection     *connection,
+                     NMClient         *client,
+                     NMRemoteSettings *settings,
+                     NMDevice         *device,
+                     NMAccessPoint    *ap)
+{
+        CEPageDetails *page;
+
+        page = CE_PAGE_DETAILS (ce_page_new (CE_TYPE_PAGE_DETAILS,
+                                             connection,
+                                             client,
+                                             settings,
+                                             GNOMECC_UI_DIR "/details-page.ui",
+                                             _("Details")));
+
+        page->device = device;
+        page->ap = ap;
+
+        connect_details_page (page);
+
+        return CE_PAGE (page);
+}
+
diff --git a/panels/network/connection-editor/ce-page-details.h b/panels/network/connection-editor/ce-page-details.h
new file mode 100644
index 0000000..5cb8f56
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-details.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#ifndef __CE_PAGE_DETAILS_H
+#define __CE_PAGE_DETAILS_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_DETAILS          (ce_page_details_get_type ())
+#define CE_PAGE_DETAILS(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_DETAILS, CEPageDetails))
+#define CE_PAGE_DETAILS_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass))
+#define CE_IS_PAGE_DETAILS(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_DETAILS))
+#define CE_IS_PAGE_DETAILS_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_DETAILS))
+#define CE_PAGE_DETAILS_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass))
+
+typedef struct _CEPageDetails          CEPageDetails;
+typedef struct _CEPageDetailsClass     CEPageDetailsClass;
+
+struct _CEPageDetails
+{
+        CEPage parent;
+
+        NMDevice *device;
+        NMAccessPoint *ap;
+};
+
+struct _CEPageDetailsClass
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_details_get_type (void);
+
+CEPage *ce_page_details_new      (NMConnection     *connection,
+                                  NMClient         *client,
+                                  NMRemoteSettings *settings,
+                                  NMDevice         *device,
+                                  NMAccessPoint    *ap);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_DETAILS_H */
+
diff --git a/panels/network/connection-editor/ce-page-ethernet.c b/panels/network/connection-editor/ce-page-ethernet.c
new file mode 100644
index 0000000..9ecb747
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-ethernet.c
@@ -0,0 +1,214 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include <nm-utils.h>
+#include <nm-device-ethernet.h>
+
+#include <net/if_arp.h>
+
+#include "ce-page-ethernet.h"
+
+G_DEFINE_TYPE (CEPageEthernet, ce_page_ethernet, CE_TYPE_PAGE)
+
+static void
+all_user_changed (GtkToggleButton *b, CEPageEthernet *page)
+{
+        gboolean all_users;
+        NMSettingConnection *sc;
+
+        sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
+        all_users = gtk_toggle_button_get_active (b);
+
+        g_object_set (sc, "permissions", NULL, NULL);
+        if (!all_users)
+                nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL);
+}
+
+static void
+mtu_changed (GtkSpinButton *mtu, CEPageEthernet *page)
+{
+        if (gtk_spin_button_get_value_as_int (mtu) == 0)
+                gtk_widget_hide (page->mtu_label);
+        else
+                gtk_widget_show (page->mtu_label);
+}
+
+static void
+connect_ethernet_page (CEPageEthernet *page)
+{
+        NMSettingWired *setting = page->setting_wired;
+        NMSettingConnection *sc;
+        int mtu_def;
+        char **mac_list;
+        const GByteArray *s_mac;
+        char *s_mac_str;
+        GtkWidget *widget;
+        const gchar *name;
+
+        name = nm_setting_connection_get_id (page->setting_connection);
+        gtk_entry_set_text (page->name, name);
+
+        /* Device MAC address */
+        mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_ETHERNET,
+                                         NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
+        s_mac = nm_setting_wired_get_mac_address (setting);
+        s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL;
+        ce_page_setup_mac_combo (page->device_mac, s_mac_str, mac_list);
+        g_free (s_mac_str);
+        g_strfreev (mac_list);
+        g_signal_connect_swapped (page->device_mac, "changed", G_CALLBACK (ce_page_changed), page);
+
+        /* Cloned MAC address */
+        ce_page_mac_to_entry (nm_setting_wired_get_cloned_mac_address (setting),
+                              ARPHRD_ETHER, page->cloned_mac);
+        g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page);
+
+        /* MTU */
+        mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRED_MTU);
+        g_signal_connect (page->mtu, "output",
+                          G_CALLBACK (ce_spin_output_with_default),
+                          GINT_TO_POINTER (mtu_def));
+        gtk_spin_button_set_value (page->mtu, (gdouble) nm_setting_wired_get_mtu (setting));
+        g_signal_connect (page->mtu, "value-changed",
+                          G_CALLBACK (mtu_changed), page);
+        mtu_changed (page->mtu, page);
+
+        g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page);
+        g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "auto_connect_check"));
+        sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
+        g_object_bind_property (sc, "autoconnect",
+                                widget, "active",
+                                G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "all_user_check"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
+                                      nm_setting_connection_get_num_permissions (sc) == 0);
+        g_signal_connect (widget, "toggled",
+                          G_CALLBACK (all_user_changed), page);
+}
+
+static void
+ui_to_setting (CEPageEthernet *page)
+{
+        GByteArray *device_mac = NULL;
+        GByteArray *cloned_mac = NULL;
+        GtkWidget *entry;
+
+        entry = gtk_bin_get_child (GTK_BIN (page->device_mac));
+        if (entry)
+                device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
+        cloned_mac = ce_page_entry_to_mac (page->cloned_mac, ARPHRD_ETHER, NULL);
+
+        g_object_set (page->setting_wired,
+                      NM_SETTING_WIRED_MAC_ADDRESS, device_mac,
+                      NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac,
+                      NM_SETTING_WIRED_MTU, (guint32) gtk_spin_button_get_value_as_int (page->mtu),
+                      NULL);
+
+        if (device_mac)
+                g_byte_array_free (device_mac, TRUE);
+        if (cloned_mac)
+                g_byte_array_free (cloned_mac, TRUE);
+
+        g_object_set (page->setting_connection,
+                      NM_SETTING_CONNECTION_ID, gtk_entry_get_text (page->name),
+                      NULL);
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        CEPageEthernet *self = CE_PAGE_ETHERNET (page);
+        gboolean invalid = FALSE;
+        GByteArray *ignore;
+        GtkWidget *entry;
+
+        entry = gtk_bin_get_child (GTK_BIN (self->device_mac));
+        if (entry) {
+                ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
+                if (invalid)
+                        return FALSE;
+                if (ignore)
+                        g_byte_array_free (ignore, TRUE);
+        }
+
+        ignore = ce_page_entry_to_mac (self->cloned_mac, ARPHRD_ETHER, &invalid);
+        if (invalid)
+                return FALSE;
+        if (ignore)
+                g_byte_array_free (ignore, TRUE);
+
+        ui_to_setting (self);
+
+        return nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error) &&
+               nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error);
+}
+
+static void
+ce_page_ethernet_init (CEPageEthernet *page)
+{
+}
+
+static void
+ce_page_ethernet_class_init (CEPageEthernetClass *class)
+{
+        CEPageClass *page_class= CE_PAGE_CLASS (class);
+
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_ethernet_new (NMConnection     *connection,
+                      NMClient         *client,
+                      NMRemoteSettings *settings)
+{
+        CEPageEthernet *page;
+
+        page = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET,
+                                              connection,
+                                              client,
+                                              settings,
+                                              GNOMECC_UI_DIR "/ethernet-page.ui",
+                                              _("Identity")));
+
+        page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name"));
+        page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"));
+        page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac"));
+        page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu"));
+        page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu"));
+
+        page->setting_connection = nm_connection_get_setting_connection (connection);
+        page->setting_wired = nm_connection_get_setting_wired (connection);
+
+        connect_ethernet_page (page);
+
+        return CE_PAGE (page);
+}
diff --git a/panels/network/connection-editor/ce-page-ethernet.h b/panels/network/connection-editor/ce-page-ethernet.h
new file mode 100644
index 0000000..daa24a2
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-ethernet.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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 ethernet.
+ *
+ * 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.
+ */
+
+#ifndef __CE_PAGE_ETHERNET_H
+#define __CE_PAGE_ETHERNET_H
+
+#include <glib-object.h>
+
+#include <nm-setting-wired.h>
+
+#include <gtk/gtk.h>
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_ETHERNET          (ce_page_ethernet_get_type ())
+#define CE_PAGE_ETHERNET(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernet))
+#define CE_PAGE_ETHERNET_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass))
+#define CE_IS_PAGE_ETHERNET(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_ETHERNET))
+#define CE_IS_PAGE_ETHERNET_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_ETHERNET))
+#define CE_PAGE_ETHERNET_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass))
+
+typedef struct _CEPageEthernet          CEPageEthernet;
+typedef struct _CEPageEthernetClass     CEPageEthernetClass;
+
+struct _CEPageEthernet
+{
+        CEPage parent;
+
+        NMSettingConnection *setting_connection;
+        NMSettingWired *setting_wired;
+
+        GtkEntry        *name;
+        GtkComboBoxText *device_mac;
+        GtkEntry        *cloned_mac;
+        GtkSpinButton   *mtu;
+        GtkWidget       *mtu_label;
+};
+
+struct _CEPageEthernetClass
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_ethernet_get_type (void);
+
+CEPage *ce_page_ethernet_new      (NMConnection     *connection,
+                                   NMClient         *client,
+                                   NMRemoteSettings *settings);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_ETHERNET_H */
+
diff --git a/panels/network/connection-editor/ce-page-ip4.c b/panels/network/connection-editor/ce-page-ip4.c
new file mode 100644
index 0000000..1eb1626
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-ip4.c
@@ -0,0 +1,898 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "ce-page-ip4.h"
+#include <nm-utils.h>
+
+#include "egg-list-box/egg-list-box.h"
+
+G_DEFINE_TYPE (CEPageIP4, ce_page_ip4, CE_TYPE_PAGE)
+
+enum {
+        METHOD_COL_NAME,
+        METHOD_COL_METHOD
+};
+
+enum {
+        IP4_METHOD_AUTO,
+        IP4_METHOD_MANUAL,
+        IP4_METHOD_LINK_LOCAL,
+        IP4_METHOD_SHARED,
+        IP4_METHOD_DISABLED
+};
+
+static void
+method_changed (GtkComboBox *combo, CEPageIP4 *page)
+{
+        gboolean addr_enabled;
+        gboolean dns_enabled;
+        gboolean routes_enabled;
+        guint method;
+        GtkWidget *widget;
+
+        method = gtk_combo_box_get_active (combo);
+        switch (method) {
+        case IP4_METHOD_AUTO:
+                addr_enabled = FALSE;
+                dns_enabled = TRUE;
+                routes_enabled = TRUE;
+                break;
+        case IP4_METHOD_MANUAL:
+                addr_enabled = TRUE;
+                dns_enabled = TRUE;
+                routes_enabled = TRUE;
+                break;
+        case IP4_METHOD_LINK_LOCAL:
+        default:
+                addr_enabled = FALSE;
+                dns_enabled = FALSE;
+                routes_enabled = FALSE;
+                break;
+        }
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
+        gtk_widget_set_visible (widget, addr_enabled);
+        gtk_widget_set_sensitive (page->dns_list, dns_enabled);
+        gtk_widget_set_sensitive (page->routes_list, routes_enabled);
+        gtk_widget_set_sensitive (page->never_default, routes_enabled);
+
+        ce_page_changed (CE_PAGE (page));
+}
+
+static void
+update_separator (GtkWidget **separator,
+                  GtkWidget  *child,
+                  GtkWidget  *before,
+                  gpointer    user_data)
+{
+  if (before == NULL)
+    return;
+
+  if (*separator == NULL)
+    {
+      *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_widget_show (*separator);
+      g_object_ref_sink (*separator);
+    }
+}
+
+static void
+update_row_sensitivity (CEPageIP4 *page, GtkWidget *list)
+{
+        GList *children, *l;
+        gint rows = 0;
+
+        children = gtk_container_get_children (GTK_CONTAINER (list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkWidget *button;
+
+                button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
+                if (button != NULL)
+                        rows++;
+        }
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkWidget *button;
+
+                button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
+                if (button != NULL)
+                        gtk_widget_set_sensitive (button, rows > 1);
+        }
+        g_list_free (children);
+}
+
+static void
+remove_row (GtkButton *button, CEPageIP4 *page)
+{
+        GtkWidget *row;
+        GtkWidget *list;
+
+        row = gtk_widget_get_parent (GTK_WIDGET (button));
+        list = gtk_widget_get_parent (row);
+
+        gtk_container_remove (GTK_CONTAINER (list), row);
+
+        ce_page_changed (CE_PAGE (page));
+
+        update_row_sensitivity (page, list);
+}
+
+static gint
+sort_first_last (gconstpointer a, gconstpointer b, gpointer data)
+{
+        gboolean afirst, bfirst, alast, blast;
+
+        afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first"));
+        bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first"));
+        alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last"));
+        blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last"));
+
+        if (afirst)
+                return -1;
+        if (bfirst)
+                return 1;
+        if (alast)
+                return 1;
+        if (blast)
+                return -1;
+
+        return 0;
+}
+
+static void
+add_address_row (CEPageIP4   *page,
+                 const gchar *address,
+                 const gchar *network,
+                 const gchar *gateway)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *delete_button;
+        GtkWidget *image;
+
+        row = gtk_grid_new ();
+        widget = gtk_label_new (_("Address"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
+        widget = gtk_label_new (_("Netmask"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
+        widget = gtk_label_new (_("Gateway"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "address", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), address);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "network", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), network);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "gateway", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), gateway);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
+
+        delete_button = gtk_button_new ();
+        g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
+        image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (delete_button), image);
+        gtk_grid_attach (GTK_GRID (row), delete_button, 3, 2, 1, 1);
+        g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
+
+        gtk_widget_set_margin_left (row, 10);
+        gtk_widget_set_margin_right (row, 10);
+        gtk_widget_set_margin_top (row, 10);
+        gtk_widget_set_margin_bottom (row, 10);
+        gtk_widget_set_halign (row, GTK_ALIGN_FILL);
+        gtk_widget_show_all (row);
+        gtk_container_add (GTK_CONTAINER (page->address_list), row);
+
+        update_row_sensitivity (page, page->address_list);
+}
+
+static void
+add_empty_address_row (CEPageIP4 *page)
+{
+        add_address_row (page, "", "", "");
+}
+
+static void
+add_section_toolbar (CEPageIP4 *page, GtkWidget *section, GCallback add_cb)
+{
+        GtkWidget *toolbar;
+        GtkToolItem *item;
+        GtkStyleContext *context;
+        GtkWidget *box;
+        GtkWidget *button;
+        GtkWidget *image;
+
+        toolbar = gtk_toolbar_new ();
+        gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
+        gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
+        context = gtk_widget_get_style_context (toolbar);
+        gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+        gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
+        gtk_container_add (GTK_CONTAINER (section), toolbar);
+
+        item = gtk_separator_tool_item_new ();
+        gtk_tool_item_set_expand (item, TRUE);
+        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 0);
+
+        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        item = gtk_tool_item_new ();
+        gtk_container_add (GTK_CONTAINER (item), box);
+        button = gtk_button_new ();
+        g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_cb), page);
+        image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (button), image);
+        gtk_container_add (GTK_CONTAINER (box), button);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 1);
+}
+
+static void
+add_address_section (CEPageIP4 *page)
+{
+        GtkWidget *widget;
+        GtkWidget *frame;
+        GtkWidget *list;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_add (GTK_CONTAINER (widget), frame);
+        page->address_list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
+        gtk_container_add (GTK_CONTAINER (frame), list);
+
+        add_section_toolbar (page, widget, G_CALLBACK (add_empty_address_row));
+
+        for (i = 0; i < nm_setting_ip4_config_get_num_addresses (page->setting); i++) {
+                NMIP4Address *addr;
+                struct in_addr tmp_addr;
+                gchar address[INET_ADDRSTRLEN + 1];
+                gchar network[INET_ADDRSTRLEN + 1];
+                gchar gateway[INET_ADDRSTRLEN + 1];
+
+                addr = nm_setting_ip4_config_get_address (page->setting, i);
+                if (!addr)
+                        continue;
+
+                tmp_addr.s_addr = nm_ip4_address_get_address (addr);
+                (void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address));
+
+                tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_address_get_prefix (addr));
+                (void) inet_ntop (AF_INET, &tmp_addr, &network[0], sizeof (network));
+
+                tmp_addr.s_addr = nm_ip4_address_get_gateway (addr);
+                (void) inet_ntop (AF_INET, &tmp_addr, &gateway[0], sizeof (gateway));
+
+                add_address_row (page, address, network, gateway);
+        }
+        if (nm_setting_ip4_config_get_num_addresses (page->setting) == 0)
+                add_empty_address_row (page);
+
+        gtk_widget_show_all (widget);
+}
+
+static void
+add_dns_row (CEPageIP4   *page,
+             const gchar *address)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *delete_button;
+        GtkWidget *image;
+
+        row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        widget = gtk_label_new (_("Server"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "address", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), address);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
+
+        delete_button = gtk_button_new ();
+        g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
+        image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (delete_button), image);
+        gtk_box_pack_start (GTK_BOX (row), delete_button, FALSE, FALSE, 0);
+        g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
+
+        gtk_widget_set_margin_left (row, 10);
+        gtk_widget_set_margin_right (row, 10);
+        gtk_widget_set_margin_top (row, 10);
+        gtk_widget_set_margin_bottom (row, 10);
+        gtk_widget_set_halign (row, GTK_ALIGN_FILL);
+        gtk_widget_show_all (row);
+        gtk_container_add (GTK_CONTAINER (page->dns_list), row);
+
+        update_row_sensitivity (page, page->dns_list);
+}
+
+static void
+add_empty_dns_row (CEPageIP4 *page)
+{
+        add_dns_row (page, "");
+}
+
+static void
+add_dns_section (CEPageIP4 *page)
+{
+        GtkWidget *widget;
+        GtkWidget *frame;
+        GtkWidget *list;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_section"));
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_add (GTK_CONTAINER (widget), frame);
+        page->dns_list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
+        gtk_container_add (GTK_CONTAINER (frame), list);
+        page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch"));
+        gtk_switch_set_active (page->auto_dns, !nm_setting_ip4_config_get_ignore_auto_dns (page->setting));
+
+        add_section_toolbar (page, widget, G_CALLBACK (add_empty_dns_row));
+
+        for (i = 0; i < nm_setting_ip4_config_get_num_dns (page->setting); i++) {
+                struct in_addr tmp_addr;
+                gchar address[INET_ADDRSTRLEN + 1];
+
+                tmp_addr.s_addr = nm_setting_ip4_config_get_dns (page->setting, i);
+                (void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address));
+
+                add_dns_row (page, address);
+        }
+        if (nm_setting_ip4_config_get_num_dns (page->setting) == 0)
+                add_empty_dns_row (page);
+
+        gtk_widget_show_all (widget);
+}
+
+static void
+add_route_row (CEPageIP4   *page,
+               const gchar *address,
+               const gchar *netmask,
+               const gchar *gateway,
+               gint         metric)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *delete_button;
+        GtkWidget *image;
+
+        row = gtk_grid_new ();
+        widget = gtk_label_new (_("Address"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
+        widget = gtk_label_new (_("Netmask"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
+        widget = gtk_label_new (_("Gateway"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
+        widget = gtk_label_new (_("Metric"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 4, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "address", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), address);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "netmask", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), netmask);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "gateway", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), gateway);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "metric", widget);
+        if (metric > 0) {
+                gchar *s = g_strdup_printf ("%d", metric);
+                gtk_entry_set_text (GTK_ENTRY (widget), s);
+                g_free (s);
+        }
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 4, 1, 1);
+
+        delete_button = gtk_button_new ();
+        g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
+        image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (delete_button), image);
+        gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER);
+        gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER);
+        gtk_grid_attach (GTK_GRID (row), delete_button, 3, 1, 1, 4);
+        g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
+
+        gtk_widget_set_margin_left (row, 10);
+        gtk_widget_set_margin_right (row, 10);
+        gtk_widget_set_margin_top (row, 10);
+        gtk_widget_set_margin_bottom (row, 10);
+        gtk_widget_set_halign (row, GTK_ALIGN_FILL);
+
+        gtk_widget_show_all (row);
+        gtk_container_add (GTK_CONTAINER (page->routes_list), row);
+
+        update_row_sensitivity (page, page->routes_list);
+}
+
+static void
+add_empty_route_row (CEPageIP4 *page)
+{
+        add_route_row (page, "", "", "", 0);
+}
+
+static void
+add_routes_section (CEPageIP4 *page)
+{
+        GtkWidget *widget;
+        GtkWidget *frame;
+        GtkWidget *list;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_add (GTK_CONTAINER (widget), frame);
+        page->routes_list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
+        gtk_container_add (GTK_CONTAINER (frame), list);
+        page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
+        gtk_switch_set_active (page->auto_routes, !nm_setting_ip4_config_get_ignore_auto_routes (page->setting));
+
+        add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row));
+
+        for (i = 0; i < nm_setting_ip4_config_get_num_routes (page->setting); i++) {
+                NMIP4Route *route;
+                struct in_addr tmp_addr;
+                gchar address[INET_ADDRSTRLEN + 1];
+                gchar netmask[INET_ADDRSTRLEN + 1];
+                gchar gateway[INET_ADDRSTRLEN + 1];
+                gint metric;
+
+                route = nm_setting_ip4_config_get_route (page->setting, i);
+                if (!route)
+                        continue;
+
+                tmp_addr.s_addr = nm_ip4_route_get_dest (route);
+                (void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address));
+
+                tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route));
+                (void) inet_ntop (AF_INET, &tmp_addr, &netmask[0], sizeof (netmask));
+
+                tmp_addr.s_addr = nm_ip4_route_get_next_hop (route);
+                (void) inet_ntop (AF_INET, &tmp_addr, &gateway[0], sizeof (gateway));
+                metric = nm_ip4_route_get_metric (route);
+                add_route_row (page, address, netmask, gateway, metric);
+        }
+        if (nm_setting_ip4_config_get_num_routes (page->setting) == 0)
+                add_empty_route_row (page);
+
+        gtk_widget_show_all (widget);
+}
+
+static void
+free_addr (gpointer addr)
+{
+        g_array_free ((GArray *)addr, TRUE);
+}
+
+static void
+connect_ip4_page (CEPageIP4 *page)
+{
+        GtkWidget *content;
+        const gchar *str_method;
+        gboolean disabled;
+        GtkListStore *store;
+        GtkTreeIter iter;
+        guint method;
+
+        add_address_section (page);
+        add_dns_section (page);
+        add_routes_section (page);
+
+        page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "switch_enable"));
+
+        str_method = nm_setting_ip4_config_get_method (page->setting);
+        disabled = g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0;
+        gtk_switch_set_active (page->enabled, !disabled);
+        g_signal_connect_swapped (page->enabled, "notify::active", G_CALLBACK (ce_page_changed), page);
+        content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content"));
+        g_object_bind_property (page->enabled, "active",
+                                content, "sensitive",
+                                G_BINDING_SYNC_CREATE);
+
+        page->method = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_addresses"));
+
+        store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Automatic (DHCP)"),
+                                           METHOD_COL_METHOD, IP4_METHOD_AUTO,
+                                           -1);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Manual"),
+                                           METHOD_COL_METHOD, IP4_METHOD_MANUAL,
+                                           -1);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Link-Local Only"),
+                                           METHOD_COL_METHOD, IP4_METHOD_LINK_LOCAL,
+                                           -1);
+
+        gtk_combo_box_set_model (page->method, GTK_TREE_MODEL (store));
+
+        method = IP4_METHOD_AUTO;
+        if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) {
+                method = IP4_METHOD_LINK_LOCAL;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) {
+                method = IP4_METHOD_MANUAL;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
+                method = IP4_METHOD_SHARED;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) {
+                method = IP4_METHOD_DISABLED;
+        }
+
+        page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default),
+                                      nm_setting_ip4_config_get_never_default (page->setting));
+
+        g_signal_connect (page->method, "changed", G_CALLBACK (method_changed), page);
+        if (method != IP4_METHOD_SHARED && method != IP4_METHOD_DISABLED)
+                gtk_combo_box_set_active (page->method, method);
+}
+
+static gboolean
+parse_netmask (const char *str, guint32 *prefix)
+{
+        struct in_addr tmp_addr;
+        glong tmp_prefix;
+
+        errno = 0;
+
+        /* Is it a prefix? */
+        if (!strchr (str, '.')) {
+                tmp_prefix = strtol (str, NULL, 10);
+                if (!errno && tmp_prefix >= 0 && tmp_prefix <= 32) {
+                        *prefix = tmp_prefix;
+                        return TRUE;
+                }
+        }
+
+        /* Is it a netmask? */
+        if (inet_pton (AF_INET, str, &tmp_addr) > 0) {
+                *prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr);
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+static gboolean
+ui_to_setting (CEPageIP4 *page)
+{
+        gboolean valid = FALSE;
+        const gchar *method;
+        gboolean ignore_auto_dns;
+        gboolean ignore_auto_routes;
+        gboolean never_default;
+        GPtrArray *addresses = NULL;
+        GArray *dns_servers = NULL;
+        GPtrArray *routes = NULL;
+        GList *children, *l;
+
+        if (!gtk_switch_get_active (page->enabled)) {
+                method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
+        } else {
+                switch (gtk_combo_box_get_active (page->method)) {
+                case IP4_METHOD_MANUAL:
+                        method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+                        break;
+                case IP4_METHOD_LINK_LOCAL:
+                        method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL;
+                        break;
+                default:
+                case IP4_METHOD_AUTO:
+                        method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
+                        break;
+                }
+        }
+
+        addresses = g_ptr_array_new_with_free_func (free_addr);
+        children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkEntry *entry;
+                const gchar *text_address;
+                const gchar *text_netmask;
+                const gchar *text_gateway;
+                struct in_addr tmp_addr;
+                struct in_addr tmp_gateway = { 0 };
+                guint32 prefix;
+                guint32 empty_val = 0;
+                GArray *addr;
+
+                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
+                if (!entry)
+                        continue;
+
+                text_address = gtk_entry_get_text (entry);
+                text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "network")));
+                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
+
+                if (!*text_address && !*text_netmask && !*text_gateway) {
+                        /* ignore empty rows */
+                        continue;
+                }
+
+                if (inet_pton (AF_INET, text_address, &tmp_addr) <= 0) {
+                        g_warning ("IPv4 address %s missing or invalid", text_address);
+                        goto out;
+                }
+
+
+                if (!parse_netmask (text_netmask, &prefix)) {
+                        g_warning ("IPv4 prefix %s is invalid", text_netmask);
+                        goto out;
+                }
+
+                if (text_gateway && inet_pton (AF_INET, text_gateway, &tmp_gateway) <= 0) {
+                        g_warning ("IPv4 gateway %s is invalid", text_gateway);
+                        goto out;
+                }
+
+                addr = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+                g_array_append_val (addr, tmp_addr.s_addr);
+                g_array_append_val (addr, prefix);
+                if (tmp_gateway.s_addr)
+                        g_array_append_val (addr, tmp_gateway.s_addr);
+                else
+                        g_array_append_val (addr, empty_val);
+                g_ptr_array_add (addresses, addr);
+        }
+        g_list_free (children);
+
+        if (addresses->len == 0) {
+                g_ptr_array_free (addresses, TRUE);
+                addresses = NULL;
+        }
+
+        dns_servers = g_array_new (FALSE, FALSE, sizeof (guint));
+        children = gtk_container_get_children (GTK_CONTAINER (page->dns_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkEntry *entry;
+                const gchar *text;
+                struct in_addr tmp_addr;
+
+                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
+                if (!entry)
+                        continue;
+
+                text = gtk_entry_get_text (entry);
+                if (!*text) {
+                        /* ignore empty rows */
+                        continue;
+                }
+
+                if (inet_pton (AF_INET, text, &tmp_addr) <= 0) {
+                        g_warning ("IPv4 dns server %s invalid", text);
+                        goto out;
+                }
+
+                g_array_append_val (dns_servers, tmp_addr.s_addr);
+        }
+        g_list_free (children);
+
+
+        routes = g_ptr_array_new_with_free_func (free_addr);
+        children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkEntry *entry;
+                const gchar *text_address;
+                const gchar *text_netmask;
+                const gchar *text_gateway;
+                const gchar *text_metric;
+                struct in_addr tmp_addr = { 0 };
+                guint32 address, netmask, gateway, metric;
+                GArray *route;
+
+                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
+                if (!entry)
+                        continue;
+
+                text_address = gtk_entry_get_text (entry);
+                text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "netmask")));
+                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
+                text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric")));
+
+                if (!*text_address && !*text_netmask && !*text_gateway && !*text_metric) {
+                        /* ignore empty rows */
+                        continue;
+                }
+
+                if (inet_pton (AF_INET, text_address, &tmp_addr) <= 0) {
+                        g_warning ("IPv4 route address %s invalid", text_address);
+                        goto out;
+                }
+                address = tmp_addr.s_addr;
+
+                if (!parse_netmask (text_netmask, &netmask)) {
+                        g_warning ("IPv4 route netmask %s invalid", text_netmask);
+                        goto out;
+                }
+
+                if (inet_pton (AF_INET, text_gateway, &tmp_addr) <= 0) {
+                        g_warning ("IPv4 route gateway %s invalid", text_gateway);
+                        goto out;
+                }
+                gateway = tmp_addr.s_addr;
+
+                metric = 0;
+                if (*text_metric) {
+                        errno = 0;
+                        metric = strtoul (text_metric, NULL, 10);
+                        if (errno) {
+                                g_warning ("IPv4 route metric %s invalid", text_metric);
+                                goto out;
+                        }
+                }
+
+                route = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4);
+                g_array_append_val (route, address);
+                g_array_append_val (route, netmask);
+                g_array_append_val (route, gateway);
+                g_array_append_val (route, metric);
+                g_ptr_array_add (routes, route);
+        }
+        g_list_free (children);
+
+        if (routes->len == 0) {
+                g_ptr_array_free (routes, TRUE);
+                routes = NULL;
+        }
+        ignore_auto_dns = !gtk_switch_get_active (page->auto_dns);
+        ignore_auto_routes = !gtk_switch_get_active (page->auto_routes);
+        never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default));
+
+        g_object_set (page->setting,
+                      NM_SETTING_IP4_CONFIG_METHOD, method,
+                      NM_SETTING_IP4_CONFIG_ADDRESSES, addresses,
+                      NM_SETTING_IP4_CONFIG_DNS, dns_servers,
+                      NM_SETTING_IP4_CONFIG_ROUTES, routes,
+                      NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
+                      NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
+                      NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
+                      NULL);
+
+        valid = TRUE;
+
+out:
+        if (addresses)
+                g_ptr_array_free (addresses, TRUE);
+
+        if (dns_servers)
+                g_array_free (dns_servers, TRUE);
+
+        if (routes)
+                g_ptr_array_free (routes, TRUE);
+
+        return valid;
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        if (!ui_to_setting (CE_PAGE_IP4 (page)))
+                return FALSE;
+
+        return nm_setting_verify (NM_SETTING (CE_PAGE_IP4 (page)->setting), NULL, error);
+}
+
+static void
+ce_page_ip4_init (CEPageIP4 *page)
+{
+}
+
+static void
+ce_page_ip4_class_init (CEPageIP4Class *class)
+{
+        CEPageClass *page_class= CE_PAGE_CLASS (class);
+
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_ip4_new (NMConnection     *connection,
+                   NMClient         *client,
+                   NMRemoteSettings *settings)
+{
+        CEPageIP4 *page;
+
+        page = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4,
+                                           connection,
+                                           client,
+                                           settings,
+                                           GNOMECC_UI_DIR "/ip4-page.ui",
+                                           _("IPv4")));
+
+        page->setting = nm_connection_get_setting_ip4_config (connection);
+        if (!page->setting) {
+                page->setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+                nm_connection_add_setting (connection, NM_SETTING (page->setting));
+        }
+
+        connect_ip4_page (page);
+
+        return CE_PAGE (page);
+}
diff --git a/panels/network/connection-editor/ce-page-ip4.h b/panels/network/connection-editor/ce-page-ip4.h
new file mode 100644
index 0000000..ca38d3e
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-ip4.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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 ip4.
+ *
+ * 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.
+ */
+
+#ifndef __CE_PAGE_IP4_H
+#define __CE_PAGE_IP4_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_IP4          (ce_page_ip4_get_type ())
+#define CE_PAGE_IP4(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP4, CEPageIP4))
+#define CE_PAGE_IP4_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP4, CEPageIP4Class))
+#define CE_IS_PAGE_IP4(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP4))
+#define CE_IS_PAGE_IP4_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP4))
+#define CE_PAGE_IP4_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP4, CEPageIP4Class))
+
+typedef struct _CEPageIP4          CEPageIP4;
+typedef struct _CEPageIP4Class     CEPageIP4Class;
+
+struct _CEPageIP4
+{
+        CEPage parent;
+
+        NMSettingIP4Config *setting;
+
+        GtkSwitch      *enabled;
+        GtkComboBox    *method;
+        GtkWidget      *address_list;
+        GtkSwitch      *auto_dns;
+        GtkWidget      *dns_list;
+        GtkSwitch      *auto_routes;
+        GtkWidget      *routes_list;
+        GtkWidget      *never_default;
+};
+
+struct _CEPageIP4Class
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_ip4_get_type (void);
+
+CEPage *ce_page_ip4_new      (NMConnection     *connection,
+                              NMClient         *client,
+                              NMRemoteSettings *settings);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_IP4_H */
+
diff --git a/panels/network/connection-editor/ce-page-ip6.c b/panels/network/connection-editor/ce-page-ip6.c
new file mode 100644
index 0000000..1621370
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-ip6.c
@@ -0,0 +1,859 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "ce-page-ip6.h"
+#include <nm-utils.h>
+
+#include "egg-list-box/egg-list-box.h"
+
+G_DEFINE_TYPE (CEPageIP6, ce_page_ip6, CE_TYPE_PAGE)
+
+enum {
+        METHOD_COL_NAME,
+        METHOD_COL_METHOD
+};
+
+enum {
+        IP6_METHOD_AUTO,
+        IP6_METHOD_DHCP,
+        IP6_METHOD_MANUAL,
+        IP6_METHOD_LINK_LOCAL,
+        IP6_METHOD_SHARED,
+        IP6_METHOD_IGNORE
+};
+
+static void
+method_changed (GtkComboBox *combo, CEPageIP6 *page)
+{
+        gboolean addr_enabled;
+        gboolean dns_enabled;
+        gboolean routes_enabled;
+        guint method;
+        GtkWidget *widget;
+
+        method = gtk_combo_box_get_active (combo);
+        switch (method) {
+        case IP6_METHOD_AUTO:
+        case IP6_METHOD_DHCP:
+                addr_enabled = FALSE;
+                dns_enabled = TRUE;
+                routes_enabled = TRUE;
+                break;
+        case IP6_METHOD_MANUAL:
+                addr_enabled = TRUE;
+                dns_enabled = TRUE;
+                routes_enabled = TRUE;
+                break;
+        case IP6_METHOD_LINK_LOCAL:
+        default:
+                addr_enabled = FALSE;
+                dns_enabled = FALSE;
+                routes_enabled = FALSE;
+                break;
+        }
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
+        gtk_widget_set_visible (widget, addr_enabled);
+        gtk_widget_set_sensitive (page->dns_list, dns_enabled);
+        gtk_widget_set_sensitive (page->routes_list, routes_enabled);
+        gtk_widget_set_sensitive (page->never_default, routes_enabled);
+
+        ce_page_changed (CE_PAGE (page));
+}
+
+static void
+update_separator (GtkWidget **separator,
+                  GtkWidget  *child,
+                  GtkWidget  *before,
+                  gpointer    user_data)
+{
+  if (before == NULL)
+    return;
+
+  if (*separator == NULL)
+    {
+      *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_widget_show (*separator);
+      g_object_ref_sink (*separator);
+    }
+}
+
+static void
+update_row_sensitivity (CEPageIP6 *page, GtkWidget *list)
+{
+        GList *children, *l;
+        gint rows = 0;
+
+        children = gtk_container_get_children (GTK_CONTAINER (list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkWidget *button;
+
+                button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
+                if (button != NULL)
+                        rows++;
+        }
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkWidget *button;
+
+                button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
+                if (button != NULL)
+                        gtk_widget_set_sensitive (button, rows > 1);
+        }
+        g_list_free (children);
+}
+
+static void
+remove_row (GtkButton *button, CEPageIP6 *page)
+{
+        GtkWidget *row;
+        GtkWidget *list;
+
+        row = gtk_widget_get_parent (GTK_WIDGET (button));
+        list = gtk_widget_get_parent (row);
+
+        gtk_container_remove (GTK_CONTAINER (list), row);
+
+        ce_page_changed (CE_PAGE (page));
+
+        update_row_sensitivity (page, list);
+}
+
+static gint
+sort_first_last (gconstpointer a, gconstpointer b, gpointer data)
+{
+        gboolean afirst, bfirst, alast, blast;
+
+        afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first"));
+        bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first"));
+        alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last"));
+        blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last"));
+
+        if (afirst)
+                return -1;
+        if (bfirst)
+                return 1;
+        if (alast)
+                return 1;
+        if (blast)
+                return -1;
+
+        return 0;
+}
+
+static void
+add_address_row (CEPageIP6   *page,
+                 const gchar *address,
+                 const gchar *network,
+                 const gchar *gateway)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *delete_button;
+        GtkWidget *image;
+
+        row = gtk_grid_new ();
+        widget = gtk_label_new (_("Address"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
+        widget = gtk_label_new (_("Prefix"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
+        widget = gtk_label_new (_("Gateway"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "address", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), address);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "prefix", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), network);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "gateway", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), gateway);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
+
+        delete_button = gtk_button_new ();
+        g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
+        image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (delete_button), image);
+        gtk_grid_attach (GTK_GRID (row), delete_button, 3, 2, 1, 1);
+        g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
+
+        gtk_widget_set_margin_left (row, 10);
+        gtk_widget_set_margin_right (row, 10);
+        gtk_widget_set_margin_top (row, 10);
+        gtk_widget_set_margin_bottom (row, 10);
+        gtk_widget_set_halign (row, GTK_ALIGN_FILL);
+        gtk_widget_show_all (row);
+        gtk_container_add (GTK_CONTAINER (page->address_list), row);
+
+        update_row_sensitivity (page, page->address_list);
+}
+
+static void
+add_empty_address_row (CEPageIP6 *page)
+{
+        add_address_row (page, "", "", "");
+}
+
+static void
+add_section_toolbar (CEPageIP6 *page, GtkWidget *section, GCallback add_cb)
+{
+        GtkWidget *toolbar;
+        GtkToolItem *item;
+        GtkStyleContext *context;
+        GtkWidget *box;
+        GtkWidget *button;
+        GtkWidget *image;
+
+        toolbar = gtk_toolbar_new ();
+        gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
+        gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
+        context = gtk_widget_get_style_context (toolbar);
+        gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+        gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
+        gtk_container_add (GTK_CONTAINER (section), toolbar);
+
+        item = gtk_separator_tool_item_new ();
+        gtk_tool_item_set_expand (item, TRUE);
+        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 0);
+
+        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        item = gtk_tool_item_new ();
+        gtk_container_add (GTK_CONTAINER (item), box);
+        button = gtk_button_new ();
+        g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_cb), page);
+        image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (button), image);
+        gtk_container_add (GTK_CONTAINER (box), button);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 1);
+}
+
+static void
+add_address_section (CEPageIP6 *page)
+{
+        GtkWidget *widget;
+        GtkWidget *frame;
+        GtkWidget *list;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_add (GTK_CONTAINER (widget), frame);
+        page->address_list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
+        gtk_container_add (GTK_CONTAINER (frame), list);
+
+        add_section_toolbar (page, widget, G_CALLBACK (add_empty_address_row));
+
+        for (i = 0; i < nm_setting_ip6_config_get_num_addresses (page->setting); i++) {
+                NMIP6Address *addr;
+                const struct in6_addr *tmp_addr;
+                gchar address[INET6_ADDRSTRLEN + 1];
+                gchar network[INET6_ADDRSTRLEN + 1];
+                gchar gateway[INET6_ADDRSTRLEN + 1];
+
+                addr = nm_setting_ip6_config_get_address (page->setting, i);
+                if (!addr)
+                        continue;
+
+                tmp_addr = nm_ip6_address_get_address (addr);
+                (void) inet_ntop (AF_INET6, tmp_addr, &address[0], sizeof (address));
+
+                snprintf (network, sizeof (network), "%u", nm_ip6_address_get_prefix (addr));
+
+                tmp_addr = nm_ip6_address_get_gateway (addr);
+                if (tmp_addr && !IN6_IS_ADDR_UNSPECIFIED (tmp_addr))
+                        (void) inet_ntop (AF_INET6, tmp_addr, &gateway[0], sizeof (gateway));
+                else
+                        gateway[0] = '\0';
+
+                add_address_row (page, address, network, gateway);
+        }
+        if (nm_setting_ip6_config_get_num_addresses (page->setting) == 0)
+                add_empty_address_row (page);
+
+        gtk_widget_show_all (widget);
+}
+
+static void
+add_dns_row (CEPageIP6   *page,
+             const gchar *address)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *delete_button;
+        GtkWidget *image;
+
+        row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        widget = gtk_label_new (_("Server"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "address", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), address);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
+
+        delete_button = gtk_button_new ();
+        g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
+        image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (delete_button), image);
+        gtk_box_pack_start (GTK_BOX (row), delete_button, FALSE, FALSE, 0);
+        g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
+
+        gtk_widget_set_margin_left (row, 10);
+        gtk_widget_set_margin_right (row, 10);
+        gtk_widget_set_margin_top (row, 10);
+        gtk_widget_set_margin_bottom (row, 10);
+        gtk_widget_set_halign (row, GTK_ALIGN_FILL);
+        gtk_widget_show_all (row);
+        gtk_container_add (GTK_CONTAINER (page->dns_list), row);
+
+        update_row_sensitivity (page, page->dns_list);
+}
+
+static void
+add_empty_dns_row (CEPageIP6 *page)
+{
+        add_dns_row (page, "");
+}
+
+static void
+add_dns_section (CEPageIP6 *page)
+{
+        GtkWidget *widget;
+        GtkWidget *frame;
+        GtkWidget *list;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_section"));
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_add (GTK_CONTAINER (widget), frame);
+        page->dns_list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
+        gtk_container_add (GTK_CONTAINER (frame), list);
+        page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch"));
+        gtk_switch_set_active (page->auto_dns, !nm_setting_ip6_config_get_ignore_auto_dns (page->setting));
+
+        add_section_toolbar (page, widget, G_CALLBACK (add_empty_dns_row));
+
+        for (i = 0; i < nm_setting_ip6_config_get_num_dns (page->setting); i++) {
+                const struct in6_addr *tmp_addr;
+                gchar address[INET6_ADDRSTRLEN + 1];
+
+                tmp_addr = nm_setting_ip6_config_get_dns (page->setting, i);
+                (void) inet_ntop (AF_INET, tmp_addr, &address[0], sizeof (address));
+
+                add_dns_row (page, address);
+        }
+        if (nm_setting_ip6_config_get_num_dns (page->setting) == 0)
+                add_empty_dns_row (page);
+
+        gtk_widget_show_all (widget);
+}
+
+static void
+add_route_row (CEPageIP6   *page,
+               const gchar *address,
+               gint         prefix,
+               const gchar *gateway,
+               gint         metric)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *delete_button;
+        GtkWidget *image;
+
+        row = gtk_grid_new ();
+        widget = gtk_label_new (_("Address"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
+        widget = gtk_label_new (_("Prefix"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
+        widget = gtk_label_new (_("Gateway"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
+        widget = gtk_label_new (_("Metric"));
+        gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
+        gtk_grid_attach (GTK_GRID (row), widget, 1, 4, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "address", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), address);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "prefix", widget);
+        if (prefix > 0) {
+                gchar *s = g_strdup_printf ("%d", prefix);
+                gtk_entry_set_text (GTK_ENTRY (widget), s);
+                g_free (s);
+        }
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "gateway", widget);
+        gtk_entry_set_text (GTK_ENTRY (widget), gateway);
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
+        widget = gtk_entry_new ();
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+        g_object_set_data (G_OBJECT (row), "metric", widget);
+        if (metric > 0) {
+                gchar *s = g_strdup_printf ("%d", metric);
+                gtk_entry_set_text (GTK_ENTRY (widget), s);
+                g_free (s);
+        }
+        gtk_widget_set_margin_left (widget, 10);
+        gtk_widget_set_margin_right (widget, 10);
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_grid_attach (GTK_GRID (row), widget, 2, 4, 1, 1);
+
+        delete_button = gtk_button_new ();
+        g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
+        image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON (delete_button), image);
+        gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER);
+        gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER);
+        gtk_grid_attach (GTK_GRID (row), delete_button, 3, 1, 1, 4);
+        g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
+
+        gtk_widget_set_margin_left (row, 10);
+        gtk_widget_set_margin_right (row, 10);
+        gtk_widget_set_margin_top (row, 10);
+        gtk_widget_set_margin_bottom (row, 10);
+        gtk_widget_set_halign (row, GTK_ALIGN_FILL);
+
+        gtk_widget_show_all (row);
+        gtk_container_add (GTK_CONTAINER (page->routes_list), row);
+
+        update_row_sensitivity (page, page->routes_list);
+}
+
+static void
+add_empty_route_row (CEPageIP6 *page)
+{
+        add_route_row (page, "", 0, "", 0);
+}
+
+static void
+add_routes_section (CEPageIP6 *page)
+{
+        GtkWidget *widget;
+        GtkWidget *frame;
+        GtkWidget *list;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
+
+        frame = gtk_frame_new (NULL);
+        gtk_container_add (GTK_CONTAINER (widget), frame);
+        page->routes_list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
+        gtk_container_add (GTK_CONTAINER (frame), list);
+        page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
+        gtk_switch_set_active (page->auto_routes, !nm_setting_ip6_config_get_ignore_auto_routes (page->setting));
+
+        add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row));
+
+        for (i = 0; i < nm_setting_ip6_config_get_num_routes (page->setting); i++) {
+                NMIP6Route *route;
+                const struct in6_addr *tmp_addr;
+                gchar address[INET6_ADDRSTRLEN + 1];
+                gchar gateway[INET6_ADDRSTRLEN + 1];
+                gint prefix, metric;
+
+                route = nm_setting_ip6_config_get_route (page->setting, i);
+                if (!route)
+                        continue;
+
+                tmp_addr = nm_ip6_route_get_dest (route);
+                (void) inet_ntop (AF_INET6, tmp_addr, &address[0], sizeof (address));
+                prefix = nm_ip6_route_get_prefix (route);
+                tmp_addr = nm_ip6_route_get_next_hop (route);
+                (void) inet_ntop (AF_INET6, tmp_addr, &gateway[0], sizeof (gateway));
+                metric = nm_ip6_route_get_metric (route);
+                add_route_row (page, address, prefix, gateway, metric);
+        }
+        if (nm_setting_ip6_config_get_num_routes (page->setting) == 0)
+                add_empty_route_row (page);
+
+        gtk_widget_show_all (widget);
+}
+
+static void
+connect_ip6_page (CEPageIP6 *page)
+{
+        GtkWidget *content;
+        const gchar *str_method;
+        gboolean disabled;
+        GtkListStore *store;
+        GtkTreeIter iter;
+        guint method;
+
+        add_address_section (page);
+        add_dns_section (page);
+        add_routes_section (page);
+
+        page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "switch_enable"));
+
+        str_method = nm_setting_ip6_config_get_method (page->setting);
+        disabled = g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0;
+        gtk_switch_set_active (page->enabled, !disabled);
+        g_signal_connect_swapped (page->enabled, "notify::active", G_CALLBACK (ce_page_changed), page);
+        content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content"));
+        g_object_bind_property (page->enabled, "active",
+                                content, "sensitive",
+                                G_BINDING_SYNC_CREATE);
+
+        page->method = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_addresses"));
+
+        store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Automatic"),
+                                           METHOD_COL_METHOD, IP6_METHOD_AUTO,
+                                           -1);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Automatic, DHCP only"),
+                                           METHOD_COL_METHOD, IP6_METHOD_DHCP,
+                                           -1);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Manual"),
+                                           METHOD_COL_METHOD, IP6_METHOD_MANUAL,
+                                           -1);
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           METHOD_COL_NAME, _("Link-Local Only"),
+                                           METHOD_COL_METHOD, IP6_METHOD_LINK_LOCAL,
+                                           -1);
+
+        gtk_combo_box_set_model (page->method, GTK_TREE_MODEL (store));
+
+        method = IP6_METHOD_AUTO;
+        if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
+                method = IP6_METHOD_DHCP;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) {
+                method = IP6_METHOD_LINK_LOCAL;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) {
+                method = IP6_METHOD_MANUAL;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) {
+                method = IP6_METHOD_SHARED;
+        } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
+                method = IP6_METHOD_IGNORE;
+        }
+
+        page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default),
+                                      nm_setting_ip6_config_get_never_default (page->setting));
+
+        g_signal_connect (page->method, "changed", G_CALLBACK (method_changed), page);
+        if (method != IP6_METHOD_SHARED && method != IP6_METHOD_IGNORE)
+                gtk_combo_box_set_active (page->method, method);
+}
+
+static gboolean
+ui_to_setting (CEPageIP6 *page)
+{
+        gboolean valid = FALSE;
+        const gchar *method;
+        gboolean ignore_auto_dns;
+        gboolean ignore_auto_routes;
+        gboolean never_default;
+        GList *children, *l;
+
+        if (!gtk_switch_get_active (page->enabled)) {
+                method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
+        } else {
+                switch (gtk_combo_box_get_active (page->method)) {
+                case IP6_METHOD_MANUAL:
+                        method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+                        break;
+                case IP6_METHOD_LINK_LOCAL:
+                        method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
+                        break;
+                case IP6_METHOD_DHCP:
+                        method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
+                        break;
+                default:
+                case IP6_METHOD_AUTO:
+                        method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
+                        break;
+                }
+        }
+
+        nm_setting_ip6_config_clear_addresses (page->setting);
+        children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkEntry *entry;
+                const gchar *text_address;
+                const gchar *text_prefix;
+                const gchar *text_gateway;
+                struct in6_addr tmp_addr;
+                struct in6_addr tmp_gateway;
+                guint32 prefix;
+                gchar *end;
+                NMIP6Address *addr;
+                gboolean have_gateway = FALSE;
+
+                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
+                if (!entry)
+                        continue;
+
+                text_address = gtk_entry_get_text (entry);
+                text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix")));
+                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
+
+                if (!*text_address && !*text_prefix && !*text_gateway) {
+                        /* ignore empty rows */
+                        continue;
+                }
+
+                if (inet_pton (AF_INET6, text_address, &tmp_addr) <= 0) {
+                        g_warning ("IPv6 address %s missing or invalid", text_address);
+                        goto out;
+                }
+
+                prefix = strtoul (text_prefix, &end, 10);
+                if (!end || *end || prefix == 0 || prefix > 128) {
+                        g_warning ("IPv6 prefix %s is invalid", text_prefix);
+                        goto out;
+                }
+
+                if (text_gateway && *text_gateway) {
+                        if (inet_pton (AF_INET6, text_gateway, &tmp_gateway) <= 0) {
+                                g_warning ("IPv6 gateway %s is invalid", text_gateway);
+                                goto out;
+                        }
+                        if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_gateway))
+                                have_gateway = TRUE;
+                }
+
+                addr = nm_ip6_address_new ();
+                nm_ip6_address_set_address (addr, &tmp_addr);
+                nm_ip6_address_set_prefix (addr, prefix);
+                if (have_gateway)
+                        nm_ip6_address_set_gateway (addr, &tmp_gateway);
+                nm_setting_ip6_config_add_address (page->setting, addr);
+        }
+        g_list_free (children);
+
+        nm_setting_ip6_config_clear_dns (page->setting);
+        children = gtk_container_get_children (GTK_CONTAINER (page->dns_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkEntry *entry;
+                const gchar *text;
+                struct in6_addr tmp_addr;
+
+                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
+                if (!entry)
+                        continue;
+
+                text = gtk_entry_get_text (entry);
+                if (!*text) {
+                        /* ignore empty rows */
+                        continue;
+                }
+
+                if (inet_pton (AF_INET6, text, &tmp_addr) <= 0) {
+                        g_warning ("IPv6 dns server %s invalid", text);
+                        goto out;
+                }
+
+                nm_setting_ip6_config_add_dns (page->setting, &tmp_addr);
+        }
+        g_list_free (children);
+
+        nm_setting_ip6_config_clear_routes (page->setting);
+        children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
+        for (l = children; l; l = l->next) {
+                GtkWidget *row = l->data;
+                GtkEntry *entry;
+                const gchar *text_address;
+                const gchar *text_prefix;
+                const gchar *text_gateway;
+                const gchar *text_metric;
+                struct in6_addr dest, gateway;
+                guint32 prefix, metric;
+                gchar *end;
+                NMIP6Route *route;
+
+                entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
+                if (!entry)
+                        continue;
+
+                text_address = gtk_entry_get_text (entry);
+                text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix")));
+                text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
+                text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric")));
+
+                if (!*text_address && !*text_prefix && !*text_gateway && !*text_metric) {
+                        /* ignore empty rows */
+                        continue;
+                }
+
+                if (inet_pton (AF_INET6, text_address, &dest) <= 0) {
+                        g_warning ("IPv6 route address %s invalid", text_address);
+                        goto out;
+                }
+
+                prefix = strtoul (text_prefix, &end, 10);
+                if (!end || *end || prefix == 0 || prefix > 128) {
+                        g_warning ("IPv6 route prefix %s invalid", text_prefix);
+                        goto out;
+                }
+
+                if (inet_pton (AF_INET6, text_gateway, &gateway) <= 0) {
+                        g_warning ("IPv6 route gateway %s invalid", text_gateway);
+                        goto out;
+                }
+
+                metric = 0;
+                if (*text_metric) {
+                        errno = 0;
+                        metric = strtoul (text_metric, NULL, 10);
+                        if (errno) {
+                                g_warning ("IPv6 route metric %s invalid", text_metric);
+                                goto out;
+                        }
+                }
+
+                route = nm_ip6_route_new ();
+                nm_ip6_route_set_dest (route, &dest);
+                nm_ip6_route_set_prefix (route, prefix);
+                nm_ip6_route_set_next_hop (route, &gateway);
+                nm_ip6_route_set_metric (route, metric);
+                nm_setting_ip6_config_add_route (page->setting, route);
+                nm_ip6_route_unref (route);
+        }
+        g_list_free (children);
+
+        ignore_auto_dns = !gtk_switch_get_active (page->auto_dns);
+        ignore_auto_routes = !gtk_switch_get_active (page->auto_routes);
+        never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default));
+
+        g_object_set (page->setting,
+                      NM_SETTING_IP6_CONFIG_METHOD, method,
+                      NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
+                      NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
+                      NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
+                      NULL);
+
+        valid = TRUE;
+
+out:
+
+        return valid;
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        if (!ui_to_setting (CE_PAGE_IP6 (page)))
+                return FALSE;
+
+        return nm_setting_verify (NM_SETTING (CE_PAGE_IP6 (page)->setting), NULL, error);
+}
+
+static void
+ce_page_ip6_init (CEPageIP6 *page)
+{
+}
+
+static void
+ce_page_ip6_class_init (CEPageIP6Class *class)
+{
+        CEPageClass *page_class= CE_PAGE_CLASS (class);
+
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_ip6_new (NMConnection     *connection,
+                   NMClient         *client,
+                   NMRemoteSettings *settings)
+{
+        CEPageIP6 *page;
+
+        page = CE_PAGE_IP6 (ce_page_new (CE_TYPE_PAGE_IP6,
+                                           connection,
+                                           client,
+                                           settings,
+                                           GNOMECC_UI_DIR "/ip6-page.ui",
+                                           _("IPv6")));
+
+        page->setting = nm_connection_get_setting_ip6_config (connection);
+        if (!page->setting) {
+                page->setting = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ());
+                nm_connection_add_setting (connection, NM_SETTING (page->setting));
+        }
+
+        connect_ip6_page (page);
+
+        return CE_PAGE (page);
+}
diff --git a/panels/network/connection-editor/ce-page-ip6.h b/panels/network/connection-editor/ce-page-ip6.h
new file mode 100644
index 0000000..71d8821
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-ip6.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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 ip6.
+ *
+ * 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.
+ */
+
+#ifndef __CE_PAGE_IP6_H
+#define __CE_PAGE_IP6_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_IP6          (ce_page_ip6_get_type ())
+#define CE_PAGE_IP6(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP6, CEPageIP6))
+#define CE_PAGE_IP6_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP6, CEPageIP6Class))
+#define CE_IS_PAGE_IP6(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP6))
+#define CE_IS_PAGE_IP6_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP6))
+#define CE_PAGE_IP6_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP6, CEPageIP6Class))
+
+typedef struct _CEPageIP6          CEPageIP6;
+typedef struct _CEPageIP6Class     CEPageIP6Class;
+
+struct _CEPageIP6
+{
+        CEPage parent;
+
+        NMSettingIP6Config *setting;
+
+        GtkSwitch      *enabled;
+        GtkComboBox    *method;
+        GtkWidget      *address_list;
+        GtkSwitch      *auto_dns;
+        GtkWidget      *dns_list;
+        GtkSwitch      *auto_routes;
+        GtkWidget      *routes_list;
+        GtkWidget      *never_default;
+};
+
+struct _CEPageIP6Class
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_ip6_get_type (void);
+
+CEPage *ce_page_ip6_new      (NMConnection     *connection,
+                              NMClient         *client,
+                              NMRemoteSettings *settings);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_IP6_H */
+
diff --git a/panels/network/connection-editor/ce-page-reset.c b/panels/network/connection-editor/ce-page-reset.c
new file mode 100644
index 0000000..eb80508
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-reset.c
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "net-connection-editor.h"
+#include "ce-page-reset.h"
+
+G_DEFINE_TYPE (CEPageReset, ce_page_reset, CE_TYPE_PAGE)
+
+
+static void
+forget_cb (GtkButton *button, CEPageReset *page)
+{
+        net_connection_editor_forget (page->editor);
+}
+
+static void
+reset_cb (GtkButton *button, CEPageReset *page)
+{
+        net_connection_editor_reset (page->editor);
+}
+
+static void
+connect_reset_page (CEPageReset *page)
+{
+        GtkWidget *widget;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_forget"));
+        g_signal_connect (widget, "clicked", G_CALLBACK (forget_cb), page);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_reset"));
+        g_signal_connect (widget, "clicked", G_CALLBACK (reset_cb), page);
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        return TRUE;
+}
+
+static void
+ce_page_reset_init (CEPageReset *page)
+{
+}
+
+static void
+ce_page_reset_class_init (CEPageResetClass *class)
+{
+        CEPageClass *page_class= CE_PAGE_CLASS (class);
+
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_reset_new (NMConnection        *connection,
+                   NMClient            *client,
+                   NMRemoteSettings    *settings,
+                   NetConnectionEditor *editor)
+{
+        CEPageReset *page;
+
+        page = CE_PAGE_RESET (ce_page_new (CE_TYPE_PAGE_RESET,
+                                           connection,
+                                           client,
+                                           settings,
+                                           GNOMECC_UI_DIR "/reset-page.ui",
+                                           _("Reset")));
+        page->editor = editor;
+
+        connect_reset_page (page);
+
+        return CE_PAGE (page);
+}
diff --git a/panels/network/connection-editor/ce-page-reset.h b/panels/network/connection-editor/ce-page-reset.h
new file mode 100644
index 0000000..be221c7
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-reset.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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 reset.
+ *
+ * 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.
+ */
+
+#ifndef __CE_PAGE_RESET_H
+#define __CE_PAGE_RESET_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include "net-connection-editor.h"
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_RESET          (ce_page_reset_get_type ())
+#define CE_PAGE_RESET(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_RESET, CEPageReset))
+#define CE_PAGE_RESET_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_RESET, CEPageResetClass))
+#define CE_IS_PAGE_RESET(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_RESET))
+#define CE_IS_PAGE_RESET_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_RESET))
+#define CE_PAGE_RESET_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_RESET, CEPageResetClass))
+
+typedef struct _CEPageReset          CEPageReset;
+typedef struct _CEPageResetClass     CEPageResetClass;
+
+struct _CEPageReset
+{
+        CEPage parent;
+
+        NetConnectionEditor *editor;
+};
+
+struct _CEPageResetClass
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_reset_get_type (void);
+
+CEPage *ce_page_reset_new      (NMConnection        *connection,
+                                NMClient            *client,
+                                NMRemoteSettings    *settings,
+                                NetConnectionEditor *editor);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_RESET_H */
+
diff --git a/panels/network/connection-editor/ce-page-security.c b/panels/network/connection-editor/ce-page-security.c
new file mode 100644
index 0000000..108e489
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-security.c
@@ -0,0 +1,480 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include <nm-utils.h>
+#include <nm-connection.h>
+
+#include "wireless-security.h"
+#include "ce-page-security.h"
+
+G_DEFINE_TYPE (CEPageSecurity, ce_page_security, CE_TYPE_PAGE)
+
+enum {
+        S_NAME_COLUMN,
+        S_SEC_COLUMN,
+        S_ADHOC_VALID_COLUMN
+};
+
+static gboolean
+find_proto (NMSettingWirelessSecurity *sec, const char *item)
+{
+        guint32 i;
+
+        for (i = 0; i < nm_setting_wireless_security_get_num_protos (sec); i++) {
+                if (!strcmp (item, nm_setting_wireless_security_get_proto (sec, i)))
+                        return TRUE;
+        }
+        return FALSE;
+}
+
+static NMUtilsSecurityType
+get_default_type_for_security (NMSettingWirelessSecurity *sec)
+{
+        const char *key_mgmt, *auth_alg;
+
+        g_return_val_if_fail (sec != NULL, NMU_SEC_NONE);
+
+        key_mgmt = nm_setting_wireless_security_get_key_mgmt (sec);
+        auth_alg = nm_setting_wireless_security_get_auth_alg (sec);
+
+        /* No IEEE 802.1x */
+        if (!strcmp (key_mgmt, "none"))
+                return NMU_SEC_STATIC_WEP;
+
+        if (!strcmp (key_mgmt, "ieee8021x")) {
+                if (auth_alg && !strcmp (auth_alg, "leap"))
+                        return NMU_SEC_LEAP;
+                return NMU_SEC_DYNAMIC_WEP;
+        }
+
+        if (   !strcmp (key_mgmt, "wpa-none")
+            || !strcmp (key_mgmt, "wpa-psk")) {
+                if (find_proto (sec, "rsn"))
+                        return NMU_SEC_WPA2_PSK;
+                else if (find_proto (sec, "wpa"))
+                        return NMU_SEC_WPA_PSK;
+                else
+                        return NMU_SEC_WPA_PSK;
+        }
+
+        if (!strcmp (key_mgmt, "wpa-eap")) {
+                if (find_proto (sec, "rsn"))
+                        return NMU_SEC_WPA2_ENTERPRISE;
+                else if (find_proto (sec, "wpa"))
+                        return NMU_SEC_WPA_ENTERPRISE;
+                else
+                        return NMU_SEC_WPA_ENTERPRISE;
+        }
+
+        return NMU_SEC_INVALID;
+}
+
+static WirelessSecurity *
+security_combo_get_active (CEPageSecurity *page)
+{
+        GtkTreeIter iter;
+        GtkTreeModel *model;
+        WirelessSecurity *sec = NULL;
+
+        model = gtk_combo_box_get_model (page->security_combo);
+        gtk_combo_box_get_active_iter (page->security_combo, &iter);
+        gtk_tree_model_get (model, &iter, S_SEC_COLUMN, &sec, -1);
+
+        return sec;
+}
+
+static void
+wsec_size_group_clear (GtkSizeGroup *group)
+{
+        GSList *children;
+        GSList *iter;
+
+        g_return_if_fail (group != NULL);
+
+        children = gtk_size_group_get_widgets (group);
+        for (iter = children; iter; iter = g_slist_next (iter))
+                gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data));
+}
+
+static void
+security_combo_changed (GtkComboBox *combo,
+                        gpointer     user_data)
+{
+        CEPageSecurity *page = CE_PAGE_SECURITY (user_data);
+        GtkWidget *vbox;
+        GList *l, *children;
+        WirelessSecurity *sec;
+
+        wsec_size_group_clear (page->group);
+
+        vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox"));
+        children = gtk_container_get_children (GTK_CONTAINER (vbox));
+        for (l = children; l; l = l->next) {
+                gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (l->data));
+        }
+
+        sec = security_combo_get_active (page);
+        if (sec) {
+                GtkWidget *sec_widget;
+                GtkWidget *parent;
+
+                sec_widget = wireless_security_get_widget (sec);
+                g_assert (sec_widget);
+                parent = gtk_widget_get_parent (sec_widget);
+                if (parent)
+                        gtk_container_remove (GTK_CONTAINER (parent), sec_widget);
+
+                gtk_size_group_add_widget (page->group, page->security_heading);
+                wireless_security_add_to_size_group (sec, page->group);
+
+                gtk_container_add (GTK_CONTAINER (vbox), sec_widget);
+                wireless_security_unref (sec);
+        }
+
+        ce_page_changed (CE_PAGE (page));
+}
+
+static void
+stuff_changed_cb (WirelessSecurity *sec, gpointer user_data)
+{
+        ce_page_changed (CE_PAGE (user_data));
+}
+
+static void
+add_security_item (CEPageSecurity   *page,
+                   WirelessSecurity *sec,
+                   GtkListStore     *model,
+                   GtkTreeIter      *iter,
+                   const char       *text,
+                   gboolean          adhoc_valid)
+{
+        wireless_security_set_changed_notify (sec, stuff_changed_cb, page);
+        gtk_list_store_append (model, iter);
+        gtk_list_store_set (model, iter,
+                            S_NAME_COLUMN, text,
+                            S_SEC_COLUMN, sec,
+                            S_ADHOC_VALID_COLUMN, adhoc_valid,
+                            -1);
+        wireless_security_unref (sec);
+}
+
+static void
+set_sensitive (GtkCellLayout *cell_layout,
+               GtkCellRenderer *cell,
+               GtkTreeModel *tree_model,
+               GtkTreeIter *iter,
+               gpointer data)
+{
+        gboolean *adhoc = data;
+        gboolean sensitive = TRUE, adhoc_valid = TRUE;
+
+        gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &adhoc_valid, -1);
+        if (*adhoc && !adhoc_valid)
+                sensitive = FALSE;
+
+        g_object_set (cell, "sensitive", sensitive, NULL);
+}
+
+static void
+finish_setup (CEPageSecurity *page)
+{
+        NMConnection *connection = CE_PAGE (page)->connection;
+        NMSettingWireless *sw;
+        NMSettingWirelessSecurity *sws;
+        gboolean is_adhoc = FALSE;
+        GtkListStore *sec_model;
+        GtkTreeIter iter;
+        const gchar *mode;
+        const gchar *security;
+        guint32 dev_caps = 0;
+        NMUtilsSecurityType default_type = NMU_SEC_NONE;
+        int active = -1;
+        int item = 0;
+        GtkComboBox *combo;
+        GtkCellRenderer *renderer;
+
+        sw = nm_connection_get_setting_wireless (connection);
+        g_assert (sw);
+
+        page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+        page->security_heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec"));
+        page->security_combo = combo = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_sec"));
+
+        dev_caps =   NM_WIFI_DEVICE_CAP_CIPHER_WEP40
+                   | NM_WIFI_DEVICE_CAP_CIPHER_WEP104
+                   | NM_WIFI_DEVICE_CAP_CIPHER_TKIP
+                   | NM_WIFI_DEVICE_CAP_CIPHER_CCMP
+                   | NM_WIFI_DEVICE_CAP_WPA
+                   | NM_WIFI_DEVICE_CAP_RSN;
+
+        mode = nm_setting_wireless_get_mode (sw);
+        if (mode && !strcmp (mode, "adhoc"))
+                is_adhoc = TRUE;
+        page->adhoc = is_adhoc;
+
+        sws = nm_connection_get_setting_wireless_security (connection);
+        security = nm_setting_wireless_get_security (sw);
+        if (!security || strcmp (security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0)
+                sws = NULL;
+        if (sws)
+                default_type = get_default_type_for_security (sws);
+
+        sec_model = gtk_list_store_new (3, G_TYPE_STRING, wireless_security_get_g_type (), G_TYPE_BOOLEAN);
+
+        if (nm_utils_security_valid (NMU_SEC_NONE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+                gtk_list_store_insert_with_values (sec_model, &iter, -1,
+                                                   S_NAME_COLUMN, C_("Wi-Fi/Ethernet security", "None"),
+                                                   S_ADHOC_VALID_COLUMN, TRUE,
+                                                   -1);
+                if (default_type == NMU_SEC_NONE)
+                        active = item;
+                item++;
+        }
+
+        if (nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+                WirelessSecurityWEPKey *ws_wep;
+                NMWepKeyType wep_type = NM_WEP_KEY_TYPE_KEY;
+
+                if (default_type == NMU_SEC_STATIC_WEP) {
+                        sws = nm_connection_get_setting_wireless_security (connection);
+                        if (sws)
+                                wep_type = nm_setting_wireless_security_get_wep_key_type (sws);
+                        if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN)
+                                wep_type = NM_WEP_KEY_TYPE_KEY;
+                }
+
+                ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_KEY, FALSE, FALSE);
+                if (ws_wep) {
+                        add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model,
+                                           &iter, _("WEP 40/128-bit Key (Hex or ASCII)"),
+                                           TRUE);
+                        if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_KEY))
+                                active = item;
+                        item++;
+                }
+
+                ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_PASSPHRASE, FALSE, FALSE);
+                if (ws_wep) {
+                        add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model,
+                                           &iter, _("WEP 128-bit Passphrase"), TRUE);
+                        if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE))
+                                active = item;
+                        item++;
+                }
+        }
+
+        if (nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+                WirelessSecurityLEAP *ws_leap;
+
+                ws_leap = ws_leap_new (connection, FALSE);
+                if (ws_leap) {
+                        add_security_item (page, WIRELESS_SECURITY (ws_leap), sec_model,
+                                           &iter, _("LEAP"), FALSE);
+                        if ((active < 0) && (default_type == NMU_SEC_LEAP))
+                                active = item;
+                        item++;
+                }
+        }
+
+        if (nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+                WirelessSecurityDynamicWEP *ws_dynamic_wep;
+
+                ws_dynamic_wep = ws_dynamic_wep_new (connection, TRUE, FALSE);
+                if (ws_dynamic_wep) {
+                        add_security_item (page, WIRELESS_SECURITY (ws_dynamic_wep), sec_model,
+                                           &iter, _("Dynamic WEP (802.1x)"), FALSE);
+                        if ((active < 0) && (default_type == NMU_SEC_DYNAMIC_WEP))
+                                active = item;
+                        item++;
+                }
+        }
+
+        if (nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0) ||
+            nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+                WirelessSecurityWPAPSK *ws_wpa_psk;
+
+                ws_wpa_psk = ws_wpa_psk_new (connection, FALSE);
+                if (ws_wpa_psk) {
+                        add_security_item (page, WIRELESS_SECURITY (ws_wpa_psk), sec_model,
+                                           &iter, _("WPA & WPA2 Personal"), FALSE);
+                        if ((active < 0) && ((default_type == NMU_SEC_WPA_PSK) || (default_type == NMU_SEC_WPA2_PSK)))
+                                active = item;
+                        item++;
+                }
+        }
+
+        if (nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0) ||
+            nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
+                WirelessSecurityWPAEAP *ws_wpa_eap;
+
+                ws_wpa_eap = ws_wpa_eap_new (connection, TRUE, FALSE);
+                if (ws_wpa_eap) {
+                        add_security_item (page, WIRELESS_SECURITY (ws_wpa_eap), sec_model,
+                                           &iter, _("WPA & WPA2 Enterprise"), FALSE);
+                        if ((active < 0) && ((default_type == NMU_SEC_WPA_ENTERPRISE) || (default_type == NMU_SEC_WPA2_ENTERPRISE)))
+                                active = item;
+                        item++;
+                }
+        }
+
+        gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model));
+        gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
+
+        renderer = gtk_cell_renderer_text_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", S_NAME_COLUMN, NULL);
+        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &page->adhoc, NULL);
+
+        gtk_combo_box_set_active (combo, active < 0 ? 0 : (guint32) active);
+        g_object_unref (G_OBJECT (sec_model));
+
+        page->security_combo = combo;
+
+        security_combo_changed (combo, page);
+        g_signal_connect (combo, "changed",
+                          G_CALLBACK (security_combo_changed), page);
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        NMSettingWireless *sw;
+        WirelessSecurity *sec;
+        gboolean valid = FALSE;
+        const char *mode;
+
+        sw = nm_connection_get_setting_wireless (connection);
+
+        mode = nm_setting_wireless_get_mode (sw);
+        if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0)
+                CE_PAGE_SECURITY (page)->adhoc = TRUE;
+        else
+                CE_PAGE_SECURITY (page)->adhoc = FALSE;
+
+        sec = security_combo_get_active (CE_PAGE_SECURITY (page));
+        if (sec) {
+                const GByteArray *ssid = nm_setting_wireless_get_ssid (sw);
+
+                if (ssid) {
+                        /* FIXME: get failed property and error out of wifi security objects */
+                        valid = wireless_security_validate (sec, ssid);
+                        if (valid)
+                                wireless_security_fill_connection (sec, connection);
+                        else
+                                g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Invalid Wi-Fi security");
+                } else {
+                        g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Missing SSID");
+                        valid = FALSE;
+                }
+
+                if (CE_PAGE_SECURITY (page)->adhoc) {
+                        if (!wireless_security_adhoc_compatible (sec)) {
+                                g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Security not compatible with Ad-Hoc mode");
+                                valid = FALSE;
+                        }
+                }
+
+                wireless_security_unref (sec);
+        } else {
+                /* No security, unencrypted */
+                g_object_set (sw, NM_SETTING_WIRELESS_SEC, NULL, NULL);
+                nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+                nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
+                valid = TRUE;
+        }
+
+        return valid;
+}
+
+static void
+ce_page_security_init (CEPageSecurity *page)
+{
+}
+
+static void
+dispose (GObject *object)
+{
+        CEPageSecurity *page = CE_PAGE_SECURITY (object);
+
+        g_clear_object (&page->group);
+
+        G_OBJECT_CLASS (ce_page_security_parent_class)->dispose (object);
+}
+
+static void
+ce_page_security_class_init (CEPageSecurityClass *class)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (class);
+        CEPageClass *page_class = CE_PAGE_CLASS (class);
+
+        object_class->dispose = dispose;
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_security_new (NMConnection      *connection,
+                      NMClient          *client,
+                      NMRemoteSettings  *settings)
+{
+        CEPageSecurity *page;
+        const gchar *security;
+        NMUtilsSecurityType default_type = NMU_SEC_NONE;
+        NMSettingWirelessSecurity *sws;
+
+        page = CE_PAGE_SECURITY (ce_page_new (CE_TYPE_PAGE_SECURITY,
+                                              connection,
+                                              client,
+                                              settings,
+                                              GNOMECC_UI_DIR "/security-page.ui",
+                                              _("Security")));
+
+        sws = nm_connection_get_setting_wireless_security (connection);
+        security = nm_setting_wireless_get_security (nm_connection_get_setting_wireless (connection));
+        if (!security || strcmp (security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0)
+                sws = NULL;
+        if (sws)
+                default_type = get_default_type_for_security (sws);
+
+        if (default_type == NMU_SEC_STATIC_WEP
+            || default_type == NMU_SEC_LEAP
+            || default_type == NMU_SEC_WPA_PSK
+            || default_type == NMU_SEC_WPA2_PSK) {
+                CE_PAGE (page)->security_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
+        }
+
+        if (default_type == NMU_SEC_DYNAMIC_WEP
+            || default_type == NMU_SEC_WPA_ENTERPRISE
+            || default_type == NMU_SEC_WPA2_ENTERPRISE) {
+                CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME;
+        }
+
+        g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL);
+
+        return CE_PAGE (page);
+}
diff --git a/panels/network/connection-editor/ce-page-security.h b/panels/network/connection-editor/ce-page-security.h
new file mode 100644
index 0000000..ab19bb7
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-security.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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 security.
+ *
+ * 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.
+ */
+
+#ifndef __CE_PAGE_SECURITY_H
+#define __CE_PAGE_SECURITY_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_SECURITY          (ce_page_security_get_type ())
+#define CE_PAGE_SECURITY(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_SECURITY, CEPageSecurity))
+#define CE_PAGE_SECURITY_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_SECURITY, CEPageSecurityClass))
+#define CE_IS_PAGE_SECURITY(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_SECURITY))
+#define CE_IS_PAGE_SECURITY_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_SECURITY))
+#define CE_PAGE_SECURITY_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_SECURITY, CEPageSecurityClass))
+
+typedef struct _CEPageSecurity          CEPageSecurity;
+typedef struct _CEPageSecurityClass     CEPageSecurityClass;
+
+struct _CEPageSecurity
+{
+        CEPage parent;
+
+        GtkComboBox *security_combo;
+        GtkWidget   *security_heading;
+        GtkSizeGroup *group;
+        gboolean     adhoc;
+};
+
+struct _CEPageSecurityClass
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_security_get_type (void);
+
+CEPage *ce_page_security_new      (NMConnection     *connection,
+                                   NMClient         *client,
+                                   NMRemoteSettings *settings);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_SECURITY_H */
+
diff --git a/panels/network/connection-editor/ce-page-wifi.c b/panels/network/connection-editor/ce-page-wifi.c
new file mode 100644
index 0000000..96ee0b1
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-wifi.c
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include <nm-setting-wireless.h>
+#include <nm-utils.h>
+#include <nm-device-wifi.h>
+
+#include <net/if_arp.h>
+
+#include "ce-page-wifi.h"
+
+G_DEFINE_TYPE (CEPageWifi, ce_page_wifi, CE_TYPE_PAGE)
+
+static void
+all_user_changed (GtkToggleButton *b, CEPageWifi *page)
+{
+        gboolean all_users;
+        NMSettingConnection *sc;
+
+        sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
+        all_users = gtk_toggle_button_get_active (b);
+
+        g_object_set (sc, "permissions", NULL, NULL);
+        if (!all_users)
+                nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL);
+}
+
+static void
+connect_wifi_page (CEPageWifi *page)
+{
+        NMSettingConnection *sc;
+        GtkWidget *widget;
+        const GByteArray *ssid;
+        gchar *utf8_ssid;
+        GPtrArray *bssid_array;
+        gchar **bssid_list;
+        const GByteArray *s_bssid;
+        gchar *s_bssid_str;
+        gchar **mac_list;
+        const GByteArray *s_mac;
+        gchar *s_mac_str;
+        gint i;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "entry_ssid"));
+
+        ssid = nm_setting_wireless_get_ssid (page->setting);
+        if (ssid)
+                utf8_ssid = nm_utils_ssid_to_utf8 (ssid);
+        else
+                utf8_ssid = g_strdup ("");
+        gtk_entry_set_text (GTK_ENTRY (widget), utf8_ssid);
+        g_free (utf8_ssid);
+
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "combo_bssid"));
+
+        bssid_array = g_ptr_array_new ();
+        for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (page->setting); i++) {
+                g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (page->setting, i)));
+        }
+        g_ptr_array_add (bssid_array, NULL);
+        bssid_list = (gchar **) g_ptr_array_free (bssid_array, FALSE);
+        s_bssid = nm_setting_wireless_get_bssid (page->setting);
+        s_bssid_str = s_bssid ? nm_utils_hwaddr_ntoa (s_bssid->data, ARPHRD_ETHER) : NULL;
+        ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_bssid_str, bssid_list);
+        g_free (s_bssid_str);
+        g_strfreev (bssid_list);
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "combo_mac"));
+        mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_WIFI,
+                                         NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
+        s_mac = nm_setting_wireless_get_mac_address (page->setting);
+        s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL;
+        ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_mac_str, mac_list);
+        g_free (s_mac_str);
+        g_strfreev (mac_list);
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "entry_cloned_mac"));
+        ce_page_mac_to_entry (nm_setting_wireless_get_cloned_mac_address (page->setting),
+                              ARPHRD_ETHER, GTK_ENTRY (widget));
+        g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "auto_connect_check"));
+        sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
+        g_object_bind_property (sc, "autoconnect",
+                                widget, "active",
+                                G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+        widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
+                                                     "all_user_check"));
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
+                                      nm_setting_connection_get_num_permissions (sc) == 0);
+
+        g_signal_connect (widget, "toggled",
+                          G_CALLBACK (all_user_changed), page);
+}
+
+static void
+ui_to_setting (CEPageWifi *page)
+{
+        GByteArray *ssid;
+        GByteArray *bssid = NULL;
+        GByteArray *device_mac = NULL;
+        GByteArray *cloned_mac = NULL;
+        GtkWidget *entry;
+        const gchar *utf8_ssid;
+
+        entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid"));
+        utf8_ssid = gtk_entry_get_text (GTK_ENTRY (entry));
+        if (!utf8_ssid || !*utf8_ssid)
+                ssid = NULL;
+        else {
+                ssid = g_byte_array_sized_new (strlen (utf8_ssid));
+                g_byte_array_append (ssid, (const guint8*)utf8_ssid, strlen (utf8_ssid));
+        }
+        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_bssid")));
+        bssid = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
+        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")));
+        device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
+        entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac"));
+        cloned_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
+
+        g_object_set (page->setting,
+                      NM_SETTING_WIRELESS_SSID, ssid,
+                      NM_SETTING_WIRELESS_BSSID, bssid,
+                      NM_SETTING_WIRELESS_MAC_ADDRESS, device_mac,
+                      NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac,
+                      NULL);
+
+        if (ssid)
+                g_byte_array_free (ssid, TRUE);
+        if (bssid)
+                g_byte_array_free (bssid, TRUE);
+        if (device_mac)
+                g_byte_array_free (device_mac, TRUE);
+        if (cloned_mac)
+                g_byte_array_free (cloned_mac, TRUE);
+}
+
+static gboolean
+validate (CEPage        *page,
+          NMConnection  *connection,
+          GError       **error)
+{
+        GtkWidget *entry;
+        GByteArray *ignore;
+        gboolean invalid;
+        gboolean success;
+        gchar *security;
+        NMSettingWireless *setting;
+
+        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid")));
+        ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
+        if (invalid)
+                return FALSE;
+        if (ignore)
+                g_byte_array_free (ignore, TRUE);
+
+        entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_mac")));
+        ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
+        if (invalid)
+                return FALSE;
+        if (ignore)
+                g_byte_array_free (ignore, TRUE);
+
+        entry = GTK_WIDGET (gtk_builder_get_object (page->builder, "entry_cloned_mac"));
+        ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
+        if (invalid)
+                return FALSE;
+        if (ignore)
+                g_byte_array_free (ignore, TRUE);
+
+
+        ui_to_setting (CE_PAGE_WIFI (page));
+
+        /* A hack to not check the wifi security here */
+        setting = CE_PAGE_WIFI (page)->setting;
+        security = g_strdup (nm_setting_wireless_get_security (setting));
+        g_object_set (setting, NM_SETTING_WIRELESS_SEC, NULL, NULL);
+        success = nm_setting_verify (NM_SETTING (setting), NULL, error);
+        g_object_set (setting, NM_SETTING_WIRELESS_SEC, security, NULL);
+        g_free (security);
+
+        return success;
+}
+
+static void
+ce_page_wifi_init (CEPageWifi *page)
+{
+}
+
+static void
+ce_page_wifi_class_init (CEPageWifiClass *class)
+{
+        CEPageClass *page_class= CE_PAGE_CLASS (class);
+
+        page_class->validate = validate;
+}
+
+CEPage *
+ce_page_wifi_new (NMConnection     *connection,
+                      NMClient         *client,
+                      NMRemoteSettings *settings)
+{
+        CEPageWifi *page;
+
+        page = CE_PAGE_WIFI (ce_page_new (CE_TYPE_PAGE_WIFI,
+                                          connection,
+                                          client,
+                                          settings,
+                                          GNOMECC_UI_DIR "/wifi-page.ui",
+                                          _("Identity")));
+
+        page->setting = nm_connection_get_setting_wireless (connection);
+
+        connect_wifi_page (page);
+
+        return CE_PAGE (page);
+}
diff --git a/panels/network/connection-editor/ce-page-wifi.h b/panels/network/connection-editor/ce-page-wifi.h
new file mode 100644
index 0000000..88087e7
--- /dev/null
+++ b/panels/network/connection-editor/ce-page-wifi.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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 wifi.
+ *
+ * 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.
+ */
+
+#ifndef __CE_PAGE_WIFI_H
+#define __CE_PAGE_WIFI_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include "ce-page.h"
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE_WIFI          (ce_page_wifi_get_type ())
+#define CE_PAGE_WIFI(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_WIFI, CEPageWifi))
+#define CE_PAGE_WIFI_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_WIFI, CEPageWifiClass))
+#define CE_IS_PAGE_WIFI(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_WIFI))
+#define CE_IS_PAGE_WIFI_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_WIFI))
+#define CE_PAGE_WIFI_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_WIFI, CEPageWifiClass))
+
+typedef struct _CEPageWifi          CEPageWifi;
+typedef struct _CEPageWifiClass     CEPageWifiClass;
+
+struct _CEPageWifi
+{
+        CEPage parent;
+
+        NMSettingWireless *setting;
+};
+
+struct _CEPageWifiClass
+{
+        CEPageClass parent_class;
+};
+
+GType   ce_page_wifi_get_type (void);
+
+CEPage *ce_page_wifi_new      (NMConnection     *connection,
+                               NMClient         *client,
+                               NMRemoteSettings *settings);
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_WIFI_H */
+
diff --git a/panels/network/connection-editor/ce-page.c b/panels/network/connection-editor/ce-page.c
new file mode 100644
index 0000000..f6c1f40
--- /dev/null
+++ b/panels/network/connection-editor/ce-page.c
@@ -0,0 +1,548 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <net/if_arp.h>
+#include <netinet/ether.h>
+
+#include <nm-utils.h>
+
+#include <glib/gi18n.h>
+
+#include "ce-page.h"
+
+
+G_DEFINE_ABSTRACT_TYPE (CEPage, ce_page, G_TYPE_OBJECT)
+
+enum {
+        PROP_0,
+        PROP_CONNECTION,
+        PROP_INITIALIZED,
+};
+
+enum {
+        CHANGED,
+        INITIALIZED,
+        LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+gboolean
+ce_page_validate (CEPage *page, NMConnection *connection, GError **error)
+{
+        g_return_val_if_fail (CE_IS_PAGE (page), FALSE);
+        g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+        if (CE_PAGE_GET_CLASS (page)->validate)
+                return CE_PAGE_GET_CLASS (page)->validate (page, connection, error);
+
+        return TRUE;
+}
+
+static void
+dispose (GObject *object)
+{
+        CEPage *self = CE_PAGE (object);
+
+        g_clear_object (&self->page);
+        g_clear_object (&self->builder);
+        g_clear_object (&self->connection);
+
+        G_OBJECT_CLASS (ce_page_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+        CEPage *self = CE_PAGE (object);
+
+        g_free (self->title);
+
+        G_OBJECT_CLASS (ce_page_parent_class)->finalize (object);
+}
+
+GtkWidget *
+ce_page_get_page (CEPage *self)
+{
+        g_return_val_if_fail (CE_IS_PAGE (self), NULL);
+
+        return self->page;
+}
+
+const char *
+ce_page_get_title (CEPage *self)
+{
+        g_return_val_if_fail (CE_IS_PAGE (self), NULL);
+
+        return self->title;
+}
+
+gboolean
+ce_page_get_initialized (CEPage *self)
+{
+        g_return_val_if_fail (CE_IS_PAGE (self), FALSE);
+
+        return self->initialized;
+}
+
+void
+ce_page_changed (CEPage *self)
+{
+        g_return_if_fail (CE_IS_PAGE (self));
+
+        g_signal_emit (self, signals[CHANGED], 0);
+}
+
+static void
+get_property (GObject    *object,
+              guint       prop_id,
+              GValue     *value,
+              GParamSpec *pspec)
+{
+        CEPage *self = CE_PAGE (object);
+
+        switch (prop_id) {
+        case PROP_CONNECTION:
+                g_value_set_object (value, self->connection);
+                break;
+        case PROP_INITIALIZED:
+                g_value_set_boolean (value, self->initialized);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+set_property (GObject      *object,
+              guint         prop_id,
+              const GValue *value,
+              GParamSpec   *pspec)
+{
+        CEPage *self = CE_PAGE (object);
+
+        switch (prop_id) {
+        case PROP_CONNECTION:
+                if (self->connection)
+                        g_object_unref (self->connection);
+                self->connection = g_value_dup_object (value);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+ce_page_init (CEPage *self)
+{
+        self->builder = gtk_builder_new ();
+}
+
+static void
+ce_page_class_init (CEPageClass *page_class)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (page_class);
+
+        /* virtual methods */
+        object_class->dispose      = dispose;
+        object_class->finalize     = finalize;
+        object_class->get_property = get_property;
+        object_class->set_property = set_property;
+
+        /* Properties */
+        g_object_class_install_property
+                (object_class, PROP_CONNECTION,
+                 g_param_spec_object ("connection",
+                                      "Connection",
+                                      "Connection",
+                                      NM_TYPE_CONNECTION,
+                                      G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+        g_object_class_install_property
+                (object_class, PROP_INITIALIZED,
+                 g_param_spec_boolean ("initialized",
+                                       "Initialized",
+                                       "Initialized",
+                                       FALSE,
+                                       G_PARAM_READABLE));
+
+        signals[CHANGED] =
+                g_signal_new ("changed",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (CEPageClass, changed),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+
+        signals[INITIALIZED] =
+                g_signal_new ("initialized",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (CEPageClass, initialized),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__POINTER,
+                              G_TYPE_NONE, 1, G_TYPE_POINTER);
+}
+
+CEPage *
+ce_page_new (GType             type,
+             NMConnection     *connection,
+             NMClient         *client,
+             NMRemoteSettings *settings,
+             const gchar      *ui_file,
+             const gchar      *title)
+{
+        CEPage *page;
+        GError *error = NULL;
+
+        page = CE_PAGE (g_object_new (type,
+                                      "connection", connection,
+                                      NULL));
+        page->title = g_strdup (title);
+        page->client = client;
+        page->settings= settings;
+
+        if (ui_file) {
+                if (!gtk_builder_add_from_file (page->builder, ui_file, &error)) {
+                        g_warning ("Couldn't load builder file: %s", error->message);
+                        g_error_free (error);
+                        g_object_unref (page);
+                        return NULL;
+                }
+                page->page = GTK_WIDGET (gtk_builder_get_object (page->builder, "page"));
+                if (!page->page) {
+                        g_warning ("Couldn't load page widget from %s", ui_file);
+                        g_object_unref (page);
+                        return NULL;
+                }
+
+                g_object_ref_sink (page->page);
+        }
+
+        return page;
+}
+
+static void
+emit_initialized (CEPage *page,
+                  GError *error)
+{
+        page->initialized = TRUE;
+        g_signal_emit (page, signals[INITIALIZED], 0, error);
+}
+
+void
+ce_page_complete_init (CEPage      *page,
+                       const gchar *setting_name,
+                       GHashTable  *secrets,
+                       GError      *error)
+{
+        GHashTable *setting_hash;
+        GError *update_error = NULL;
+
+        if (error
+            && !dbus_g_error_has_name (error, "org.freedesktop.NetworkManager.Settings.InvalidSetting")
+            && !dbus_g_error_has_name (error, "org.freedesktop.NetworkManager.AgentManager.NoSecrets")) {
+                emit_initialized (page, error);
+                return;
+        } else if (!setting_name || !secrets || !g_hash_table_size (secrets)) {
+                /* Success, no secrets */
+                emit_initialized (page, NULL);
+                return;
+        }
+
+        setting_hash = g_hash_table_lookup (secrets, setting_name);
+        if (!setting_hash) {
+                /* Success, no secrets */
+                emit_initialized (page, NULL);
+                return;
+        }
+
+        if (nm_connection_update_secrets (page->connection,
+                                          setting_name,
+                                          secrets,
+                                          &update_error)) {
+                emit_initialized (page, NULL);
+                return;
+        }
+
+        if (!update_error) {
+                g_set_error_literal (&update_error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN,
+                                     "Failed to update connection secrets due to an unknown error.");
+        }
+
+        emit_initialized (page, update_error);
+        g_clear_error (&update_error);
+}
+
+gchar **
+ce_page_get_mac_list (NMClient    *client,
+                      GType        device_type,
+                      const gchar *mac_property)
+{
+        const GPtrArray *devices;
+        GPtrArray *macs;
+        int i;
+
+        macs = g_ptr_array_new ();
+        devices = nm_client_get_devices (client);
+        for (i = 0; devices && (i < devices->len); i++) {
+                NMDevice *dev = g_ptr_array_index (devices, i);
+                const char *iface;
+                char *mac, *item;
+
+                if (!G_TYPE_CHECK_INSTANCE_TYPE (dev, device_type))
+                        continue;
+
+                g_object_get (G_OBJECT (dev), mac_property, &mac, NULL);
+                iface = nm_device_get_iface (NM_DEVICE (dev));
+                item = g_strdup_printf ("%s (%s)", mac, iface);
+                g_free (mac);
+                g_ptr_array_add (macs, item);
+        }
+
+        g_ptr_array_add (macs, NULL);
+        return (char **)g_ptr_array_free (macs, FALSE);
+}
+
+void
+ce_page_setup_mac_combo (GtkComboBoxText  *combo,
+                         const gchar      *current_mac,
+                         gchar           **mac_list)
+{
+        gchar **m, *active_mac = NULL;
+        gint current_mac_len;
+        GtkWidget *entry;
+
+        if (current_mac)
+                current_mac_len = strlen (current_mac);
+        else
+                current_mac_len = -1;
+
+        for (m= mac_list; m && *m; m++) {
+                gtk_combo_box_text_append_text (combo, *m);
+                if (current_mac &&
+                    g_ascii_strncasecmp (*m, current_mac, current_mac_len) == 0
+                    && ((*m)[current_mac_len] == '\0' || (*m)[current_mac_len] == ' '))
+                        active_mac = *m;
+        }
+
+        if (current_mac) {
+                if (!active_mac) {
+                        gtk_combo_box_text_prepend_text (combo, current_mac);
+                }
+
+                entry = gtk_bin_get_child (GTK_BIN (combo));
+                if (entry)
+                        gtk_entry_set_text (GTK_ENTRY (entry), active_mac ? active_mac : current_mac);
+        }
+}
+
+void
+ce_page_mac_to_entry (const GByteArray *mac,
+                      gint              type,
+                      GtkEntry         *entry)
+{
+        char *str_addr;
+
+        g_return_if_fail (entry != NULL);
+        g_return_if_fail (GTK_IS_ENTRY (entry));
+
+        if (!mac || !mac->len)
+                return;
+
+        if (mac->len != nm_utils_hwaddr_len (type))
+                return;
+
+        str_addr = nm_utils_hwaddr_ntoa (mac->data, type);
+        gtk_entry_set_text (entry, str_addr);
+        g_free (str_addr);
+}
+
+static gboolean
+utils_ether_addr_valid (const struct ether_addr *test_addr)
+{
+        guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+        guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+        guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
+        guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
+
+        g_return_val_if_fail (test_addr != NULL, FALSE);
+
+        /* Compare the AP address the card has with invalid ethernet MAC addresses. */
+        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr1, ETH_ALEN))
+                return FALSE;
+
+        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr2, ETH_ALEN))
+                return FALSE;
+
+        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr3, ETH_ALEN))
+                return FALSE;
+        if (!memcmp (test_addr->ether_addr_octet, &invalid_addr4, ETH_ALEN))
+                return FALSE;
+
+        if (test_addr->ether_addr_octet[0] & 1)  /* Multicast addresses */
+                return FALSE;
+        
+        return TRUE;
+}
+
+GByteArray *
+ce_page_entry_to_mac (GtkEntry *entry,
+                      gint      type,
+                      gboolean *invalid)
+{
+        const char *temp, *sp;
+        char *buf = NULL;
+        GByteArray *mac;
+
+        g_return_val_if_fail (entry != NULL, NULL);
+        g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+
+        if (invalid)
+                *invalid = FALSE;
+
+        temp = gtk_entry_get_text (entry);
+        if (!temp || !strlen (temp))
+                return NULL;
+
+        sp = strchr (temp, ' ');
+        if (sp)
+                temp = buf = g_strndup (temp, sp - temp);
+
+        mac = nm_utils_hwaddr_atoba (temp, type);
+        g_free (buf);
+        if (!mac) {
+                if (invalid)
+                        *invalid = TRUE;
+                return NULL;
+        }
+
+        if (type == ARPHRD_ETHER && !utils_ether_addr_valid ((struct ether_addr *)mac->data)) {
+                g_byte_array_free (mac, TRUE);
+                if (invalid)
+                        *invalid = TRUE;
+                return NULL;
+        }
+
+        return mac;
+}
+
+const gchar *
+ce_page_get_security_setting (CEPage *page)
+{
+        return page->security_setting;
+}
+
+gint
+ce_get_property_default (NMSetting *setting, const gchar *property_name)
+{
+        GParamSpec *spec;
+        GValue value = { 0, };
+
+        spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name);
+        g_return_val_if_fail (spec != NULL, -1);
+
+        g_value_init (&value, spec->value_type);
+        g_param_value_set_default (spec, &value);
+
+        if (G_VALUE_HOLDS_CHAR (&value))
+                return (int) g_value_get_schar (&value);
+        else if (G_VALUE_HOLDS_INT (&value))
+                return g_value_get_int (&value);
+        else if (G_VALUE_HOLDS_INT64 (&value))
+                return (int) g_value_get_int64 (&value);
+        else if (G_VALUE_HOLDS_LONG (&value))
+                return (int) g_value_get_long (&value);
+        else if (G_VALUE_HOLDS_UINT (&value))
+                return (int) g_value_get_uint (&value);
+        else if (G_VALUE_HOLDS_UINT64 (&value))
+                return (int) g_value_get_uint64 (&value);
+        else if (G_VALUE_HOLDS_ULONG (&value))
+                return (int) g_value_get_ulong (&value);
+        else if (G_VALUE_HOLDS_UCHAR (&value))
+                return (int) g_value_get_uchar (&value);
+        g_return_val_if_fail (FALSE, 0);
+        return 0;
+}
+
+gint
+ce_spin_output_with_default (GtkSpinButton *spin, gpointer user_data)
+{
+        gint defvalue = GPOINTER_TO_INT (user_data);
+        gint val;
+        gchar *buf = NULL;
+
+        val = gtk_spin_button_get_value_as_int (spin);
+        if (val == defvalue)
+                buf = g_strdup (_("automatic"));
+        else
+                buf = g_strdup_printf ("%d", val);
+
+        if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin))))
+                gtk_entry_set_text (GTK_ENTRY (spin), buf);
+
+        g_free (buf);
+        return TRUE;
+}
+
+gchar *
+ce_page_get_next_available_name (GSList *connections, const gchar *format)
+{
+        GSList *names = NULL, *l;
+        gchar *cname = NULL;
+        gint i = 0;
+
+        for (l = connections; l; l = l->next) {
+                const gchar *id;
+
+                id = nm_connection_get_id (NM_CONNECTION (l->data));
+                g_assert (id);
+                names = g_slist_append (names, (gpointer) id);
+        }
+
+        /* Find the next available unique connection name */
+        while (!cname && (i++ < 10000)) {
+                gchar *temp;
+                gboolean found = FALSE;
+
+                temp = g_strdup_printf (format, i);
+                for (l = names; l; l = l->next) {
+                        if (!strcmp (l->data, temp)) {
+                                found = TRUE;
+                                break;
+                        }
+                }
+                if (!found)
+                        cname = temp;
+                else
+                        g_free (temp);
+        }
+        g_slist_free (names);
+
+        return cname;
+}
diff --git a/panels/network/connection-editor/ce-page.h b/panels/network/connection-editor/ce-page.h
new file mode 100644
index 0000000..58cd41d
--- /dev/null
+++ b/panels/network/connection-editor/ce-page.h
@@ -0,0 +1,114 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#ifndef __CE_PAGE_H
+#define __CE_PAGE_H
+
+#include <glib-object.h>
+
+#include <nm-connection.h>
+#include <nm-client.h>
+#include <nm-remote-settings.h>
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define CE_TYPE_PAGE          (ce_page_get_type ())
+#define CE_PAGE(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE, CEPage))
+#define CE_PAGE_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE, CEPageClass))
+#define CE_IS_PAGE(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE))
+#define CE_IS_PAGE_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE))
+#define CE_PAGE_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE, CEPageClass))
+
+typedef struct _CEPage          CEPage;
+typedef struct _CEPageClass     CEPageClass;
+
+struct _CEPage
+{
+        GObject parent;
+
+        gboolean initialized;
+        GtkBuilder *builder;
+        GtkWidget *page;
+        gchar *title;
+        const gchar *security_setting;
+
+        NMConnection *connection;
+        NMClient *client;
+        NMRemoteSettings *settings;
+};
+
+struct _CEPageClass
+{
+        GObjectClass parent_class;
+
+        gboolean (*validate) (CEPage *page, NMConnection *connection, GError **error);
+        void (*changed)     (CEPage *page);
+        void (*initialized) (CEPage *page, GError *error);
+};
+
+GType        ce_page_get_type        (void);
+
+GtkWidget   *ce_page_get_page        (CEPage           *page);
+const gchar *ce_page_get_title       (CEPage           *page);
+const gchar *ce_page_get_security_setting (CEPage           *page);
+gboolean     ce_page_validate        (CEPage           *page,
+                                      NMConnection     *connection,
+                                      GError          **error);
+gboolean     ce_page_get_initialized (CEPage           *page);
+void         ce_page_changed         (CEPage           *page);
+CEPage      *ce_page_new             (GType             type,
+                                      NMConnection     *connection,
+                                      NMClient         *client,
+                                      NMRemoteSettings *settings,
+                                      const gchar      *ui_file,
+                                      const gchar      *title);
+void         ce_page_complete_init   (CEPage           *page,
+                                      const gchar      *setting_name,
+                                      GHashTable       *secrets,
+                                      GError           *error);
+
+gchar      **ce_page_get_mac_list    (NMClient         *client,
+                                      GType             device_type,
+                                      const gchar      *mac_property);
+void         ce_page_setup_mac_combo (GtkComboBoxText  *combo,
+                                      const gchar      *current_mac,
+                                      gchar           **mac_list);
+void         ce_page_mac_to_entry    (const GByteArray *mac,
+                                      gint              type,
+                                      GtkEntry         *entry);
+GByteArray  *ce_page_entry_to_mac    (GtkEntry         *entry,
+                                      gint              type,
+                                      gboolean         *invalid);
+gint         ce_get_property_default (NMSetting        *setting,
+                                      const gchar      *property_name);
+gint         ce_spin_output_with_default (GtkSpinButton *spin,
+                                          gpointer       user_data);
+
+gchar * ce_page_get_next_available_name (GSList *connections, const gchar *format);
+
+
+
+G_END_DECLS
+
+#endif /* __CE_PAGE_H */
+
diff --git a/panels/network/connection-editor/connection-editor.ui b/panels/network/connection-editor/connection-editor.ui
new file mode 100644
index 0000000..94562f5
--- /dev/null
+++ b/panels/network/connection-editor/connection-editor.ui
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="details_store">
+    <columns>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name page -->
+      <column type="gint"/>
+    </columns>
+  </object>
+  <object class="GtkDialog" id="details_dialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="default_width">600</property>
+    <property name="default_height">300</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area">
+            <property name="can_focus">False</property>
+            <property name="valign">end</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="details_cancel_button">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="details_apply_button">
+                <property name="label" translatable="yes">_Apply</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box6">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkScrolledWindow" id="details_sidebar">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTreeView" id="details_page_list">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="model">details_store</property>
+                    <property name="headers_visible">False</property>
+                    <property name="headers_clickable">False</property>
+                    <property name="search_column">0</property>
+                    <child internal-child="selection">
+                      <object class="GtkTreeSelection" id="details_page_list_selection"/>
+                    </child>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="details_column">
+                        <child>
+                          <object class="GtkCellRendererText" id="details_cell">
+                            <property name="xpad">10</property>
+                          </object>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
+                        </child>
+                        <child>
+                          <object class="GtkCellRendererText" id="padding_cell">
+                            <property name="xpad">20</property>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkNotebook" id="details_notebook">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="show_tabs">False</property>
+                <property name="show_border">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">details_cancel_button</action-widget>
+      <action-widget response="0">details_apply_button</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/details-page.ui b/panels/network/connection-editor/details-page.ui
new file mode 100644
index 0000000..2cb2255
--- /dev/null
+++ b/panels/network/connection-editor/details-page.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkGrid" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="valign">start</property>
+    <property name="margin_left">50</property>
+    <property name="margin_right">50</property>
+    <property name="margin_top">12</property>
+    <property name="margin_bottom">12</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="row_spacing">10</property>
+    <property name="column_spacing">6</property>
+    <child>
+      <object class="GtkLabel" id="heading_strength">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Signal Strength</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_strength">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="xalign">0</property>
+        <property name="label">Weak</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_speed">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Link speed</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_speed">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">1Mb/sec</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_security">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Security</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_ipv4">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">IPv4 Address</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_ipv6">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">IPv6 Address</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Hardware Address</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_route">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Default Route</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">6</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_dns">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="yalign">0</property>
+        <property name="label" translatable="yes">DNS</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">7</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_last_used">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">Last Used</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">8</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_security">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">WPA</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_ipv4">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">127.0.0.1</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_ipv6">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">::1</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">4</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">AA:BB:CC:DD:55:66:77:88</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">5</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_route">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">127.0.0.1</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">6</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_dns">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="yalign">0</property>
+        <property name="label">127.0.0.1</property>
+        <property name="wrap">True</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">7</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_last_used">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="xalign">0</property>
+        <property name="label">today</property>
+        <property name="selectable">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">8</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/ethernet-page.ui b/panels/network/connection-editor/ethernet-page.ui
new file mode 100644
index 0000000..d081079
--- /dev/null
+++ b/panels/network/connection-editor/ethernet-page.ui
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">10000</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkListStore" id="model1">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Automatic</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Twisted Pair (TP)</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Attachment Unit Interface (AUI)</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">BNC</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Media Independent Interface (MII)</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="model2">
+    <columns>
+      <!-- column-name < -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Automatic</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">10 Mb/s</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">100 Mb/s</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">1 Gb/s</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">10 Gb/s</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkGrid" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">50</property>
+    <property name="margin_right">50</property>
+    <property name="margin_top">12</property>
+    <property name="margin_bottom">12</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="row_spacing">10</property>
+    <property name="column_spacing">6</property>
+    <child>
+      <object class="GtkLabel" id="heading_name">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">_Name</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">entry_name</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="entry_name">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="invisible_char">●</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">_MAC Address</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">combo_mac</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="combo_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="has_entry">True</property>
+        <property name="entry_text_column">0</property>
+        <property name="id_column">1</property>
+        <child internal-child="entry">
+          <object class="GtkEntry" id="comboboxtext-entry">
+            <property name="can_focus">False</property>
+            <property name="invisible_char">●</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="entry_cloned_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="invisible_char">●</property>
+        <property name="invisible_char_set">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_mtu">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">M_TU</property>
+        <property name="use_underline">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_cloned_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="valign">center</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">_Cloned Address</property>
+        <property name="use_underline">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="auto_connect_check">
+        <property name="label" translatable="yes">Connect _automatically</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="valign">end</property>
+        <property name="vexpand">True</property>
+        <property name="use_underline">True</property>
+        <property name="xalign">0</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="all_user_check">
+        <property name="label" translatable="yes">Make available to other _users</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="use_underline">True</property>
+        <property name="xalign">0</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_mtu">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">bytes</property>
+      </object>
+      <packing>
+        <property name="left_attach">2</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkSpinButton" id="spin_mtu">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="invisible_char">●</property>
+        <property name="invisible_char_set">True</property>
+        <property name="adjustment">adjustment1</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <object class="GtkLabel" id="filler">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="left_attach">2</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkSizeGroup" id="sizegroup1">
+    <widgets>
+      <widget name="label_mtu"/>
+      <widget name="filler"/>
+    </widgets>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/ip4-page.ui b/panels/network/connection-editor/ip4-page.ui
new file mode 100644
index 0000000..c6dd152
--- /dev/null
+++ b/panels/network/connection-editor/ip4-page.ui
@@ -0,0 +1,296 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkScrolledWindow" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="hscrollbar_policy">never</property>
+    <child>
+      <object class="GtkViewport" id="viewport1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <child>
+          <object class="GtkBox" id="box2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">20</property>
+            <property name="margin_right">20</property>
+            <property name="margin_top">10</property>
+            <property name="margin_bottom">10</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">10</property>
+            <child>
+              <object class="GtkBox" id="box5">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkLabel" id="heading_enable">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">IPv_4</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">switch_enable</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="switch_enable">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">end</property>
+                    <property name="hexpand">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="page_content">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">10</property>
+                <child>
+                  <object class="GtkBox" id="box7">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_addresses">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Addresses</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">combo_addresses</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBoxText" id="combo_addresses">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">end</property>
+                        <property name="hexpand">True</property>
+                        <property name="entry_text_column">0</property>
+                        <property name="id_column">1</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="address_section">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">24</property>
+                    <property name="margin_bottom">6</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_dns">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">DNS</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Automatic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSwitch" id="auto_dns_switch">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="halign">end</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="dns_section">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">24</property>
+                    <property name="margin_bottom">5</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_routes">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Routes</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Automatic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSwitch" id="auto_routes_switch">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="routes_section">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="never_default_check">
+                    <property name="label" translatable="yes">Use this connection _only for resources on its network</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="xalign">0</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">7</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/ip6-page.ui b/panels/network/connection-editor/ip6-page.ui
new file mode 100644
index 0000000..283eff8
--- /dev/null
+++ b/panels/network/connection-editor/ip6-page.ui
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkScrolledWindow" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="hscrollbar_policy">never</property>
+    <child>
+      <object class="GtkViewport" id="viewport1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <child>
+          <object class="GtkBox" id="box2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">20</property>
+            <property name="margin_right">20</property>
+            <property name="margin_top">10</property>
+            <property name="margin_bottom">10</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">10</property>
+            <child>
+              <object class="GtkBox" id="box5">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkLabel" id="heading_enable">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">IPv_6</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">switch_enable</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="switch_enable">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">end</property>
+                    <property name="hexpand">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="page_content">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">10</property>
+                <child>
+                  <object class="GtkBox" id="box7">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_addresses">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Addresses</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">combo_addresses</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBoxText" id="combo_addresses">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">end</property>
+                        <property name="hexpand">True</property>
+                        <property name="entry_text_column">0</property>
+                        <property name="id_column">1</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="address_section">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">24</property>
+                    <property name="margin_bottom">6</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_dns">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">DNS</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Automatic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSwitch" id="auto_dns_switch">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="halign">end</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="dns_section">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">24</property>
+                    <property name="margin_bottom">5</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_routes">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Routes</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Automatic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSwitch" id="auto_routes_switch">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="routes_section">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="never_default_check">
+                    <property name="label" translatable="yes">Use this connection _only for resources on its network</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="xalign">0</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">7</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkWindow" id="window1">
+    <property name="can_focus">False</property>
+    <child>
+      <placeholder/>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/net-connection-editor.c b/panels/network/connection-editor/net-connection-editor.c
new file mode 100644
index 0000000..dca3df9
--- /dev/null
+++ b/panels/network/connection-editor/net-connection-editor.c
@@ -0,0 +1,563 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include <nm-utils.h>
+#include <nm-device-wifi.h>
+
+#include "net-connection-editor.h"
+#include "ce-page-details.h"
+#include "ce-page-wifi.h"
+#include "ce-page-ip4.h"
+#include "ce-page-ip6.h"
+#include "ce-page-security.h"
+#include "ce-page-reset.h"
+#include "ce-page-ethernet.h"
+#include "ce-page-8021x-security.h"
+
+#include "egg-list-box/egg-list-box.h"
+
+enum {
+        DONE,
+        LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (NetConnectionEditor, net_connection_editor, G_TYPE_OBJECT)
+
+static void
+selection_changed (GtkTreeSelection *selection, NetConnectionEditor *editor)
+{
+        GtkWidget *widget;
+        GtkTreeModel *model;
+        GtkTreeIter iter;
+        gint page;
+
+        gtk_tree_selection_get_selected (selection, &model, &iter);
+        gtk_tree_model_get (model, &iter, 1, &page, -1);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (editor->builder,
+                                                     "details_notebook"));
+        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), page);
+}
+
+static void
+cancel_editing (NetConnectionEditor *editor)
+{
+        gtk_widget_hide (editor->window);
+        g_signal_emit (editor, signals[DONE], 0, FALSE);
+}
+
+static void
+update_connection (NetConnectionEditor *editor)
+{
+        GHashTable *settings;
+
+        settings = nm_connection_to_hash (editor->connection, NM_SETTING_HASH_FLAG_ALL);
+        nm_connection_replace_settings (editor->orig_connection, settings, NULL);
+        g_hash_table_destroy (settings);
+}
+
+static void
+update_complete (NetConnectionEditor *editor, GError *error)
+{
+        gtk_widget_hide (editor->window);
+        g_signal_emit (editor, signals[DONE], 0, !error);
+}
+
+static void
+updated_connection_cb (NMRemoteConnection *connection,
+                       GError             *error,
+                       gpointer            data)
+{
+        NetConnectionEditor *editor = data;
+
+        nm_connection_clear_secrets (NM_CONNECTION (connection));
+
+        update_complete (editor, error);
+}
+
+static void
+added_connection_cb (NMRemoteSettings   *settings,
+                     NMRemoteConnection *connection,
+                     GError             *error,
+                     gpointer            data)
+{
+        NetConnectionEditor *editor = data;
+
+        if (error) {
+                g_warning ("Failed to add connection: %s", error->message);
+                /* Leave the editor open */
+                return;
+        }
+
+        update_complete (editor, error);
+}
+
+static void
+apply_edits (NetConnectionEditor *editor)
+{
+        update_connection (editor);
+
+        if (editor->is_new_connection) {
+                nm_remote_settings_add_connection (editor->settings,
+                                                   editor->orig_connection,
+                                                   added_connection_cb,
+                                                   editor);
+        } else {
+                nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (editor->orig_connection),
+                                                     updated_connection_cb, editor);
+        }
+}
+
+static void
+net_connection_editor_init (NetConnectionEditor *editor)
+{
+        GError *error = NULL;
+        GtkTreeSelection *selection;
+
+        editor->builder = gtk_builder_new ();
+
+        gtk_builder_add_from_file (editor->builder,
+                                   GNOMECC_UI_DIR "/connection-editor.ui",
+                                   &error);
+        if (error != NULL) {
+                g_warning ("Could not load ui file: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+
+        editor->window = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_dialog"));
+        selection = GTK_TREE_SELECTION (gtk_builder_get_object (editor->builder,
+                                                                "details_page_list_selection"));
+        g_signal_connect (selection, "changed",
+                          G_CALLBACK (selection_changed), editor);
+}
+
+void
+net_connection_editor_run (NetConnectionEditor *editor)
+{
+        GtkWidget *button;
+
+        button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_cancel_button"));
+        g_signal_connect_swapped (button, "clicked",
+                                  G_CALLBACK (cancel_editing), editor);
+        g_signal_connect_swapped (editor->window, "delete-event",
+                                  G_CALLBACK (cancel_editing), editor);
+
+        button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"));
+        g_signal_connect_swapped (button, "clicked",
+                                  G_CALLBACK (apply_edits), editor);
+
+        net_connection_editor_present (editor);
+}
+
+static void
+net_connection_editor_finalize (GObject *object)
+{
+        NetConnectionEditor *editor = NET_CONNECTION_EDITOR (object);
+
+        g_clear_object (&editor->connection);
+        g_clear_object (&editor->orig_connection);
+        if (editor->window) {
+                gtk_widget_destroy (editor->window);
+                editor->window = NULL;
+        }
+        g_clear_object (&editor->parent_window);
+        g_clear_object (&editor->builder);
+        g_clear_object (&editor->device);
+        g_clear_object (&editor->settings);
+        g_clear_object (&editor->client);
+        g_clear_object (&editor->ap);
+
+        G_OBJECT_CLASS (net_connection_editor_parent_class)->finalize (object);
+}
+
+static void
+net_connection_editor_class_init (NetConnectionEditorClass *class)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+        object_class->finalize = net_connection_editor_finalize;
+
+        signals[DONE] = g_signal_new ("done",
+                                      G_OBJECT_CLASS_TYPE (object_class),
+                                      G_SIGNAL_RUN_FIRST,
+                                      G_STRUCT_OFFSET (NetConnectionEditorClass, done),
+                                      NULL, NULL,
+                                      NULL,
+                                      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+static void
+net_connection_editor_update_title (NetConnectionEditor *editor)
+{
+        gchar *id;
+
+        if (editor->is_new_connection)
+                id = g_strdup (_("New Profile"));
+        else {
+                NMSettingWireless *sw;
+                sw = nm_connection_get_setting_wireless (editor->connection);
+                if (sw) {
+                        const GByteArray *ssid;
+                        ssid = nm_setting_wireless_get_ssid (sw);
+                        id = nm_utils_ssid_to_utf8 (ssid);
+                } else {
+                        id = g_strdup (nm_connection_get_id (editor->connection));
+                }
+        }
+        gtk_window_set_title (GTK_WINDOW (editor->window), id);
+        g_free (id);
+}
+
+static gboolean
+editor_is_initialized (NetConnectionEditor *editor)
+{
+        return editor->initializing_pages == NULL;
+}
+
+static void
+update_sensitivity (NetConnectionEditor *editor)
+{
+        NMSettingConnection *sc;
+        gboolean sensitive;
+        GtkWidget *widget;
+        GSList *l;
+
+        if (!editor_is_initialized (editor))
+                return;
+
+        sc = nm_connection_get_setting_connection (editor->connection);
+
+        if (nm_setting_connection_get_read_only (sc)) {
+                sensitive = FALSE;
+        } else {
+                sensitive = editor->can_modify;
+        }
+
+        for (l = editor->pages; l; l = l->next) {
+                widget = ce_page_get_page (CE_PAGE (l->data));
+                gtk_widget_set_sensitive (widget, sensitive);
+        }
+}
+
+static void
+validate (NetConnectionEditor *editor)
+{
+        gboolean valid = FALSE;
+        GSList *l;
+
+        if (!editor_is_initialized (editor))
+                goto done;
+
+        valid = TRUE;
+        for (l = editor->pages; l; l = l->next) {
+                GError *error = NULL;
+
+                if (!ce_page_validate (CE_PAGE (l->data), editor->connection, &error)) {
+                        valid = FALSE;
+                        if (error) {
+                                g_warning ("Invalid setting %s: %s", ce_page_get_title (CE_PAGE (l->data)), error->message);
+                                g_error_free (error);
+                        } else {
+                                g_warning ("Invalid setting %s", ce_page_get_title (CE_PAGE (l->data)));
+                        }
+                }
+        }
+
+        update_sensitivity (editor);
+done:
+        gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")), valid);
+}
+
+static void
+page_changed (CEPage *page, gpointer user_data)
+{
+        NetConnectionEditor *editor= user_data;
+
+        validate (editor);
+}
+
+static gboolean
+idle_validate (gpointer user_data)
+{
+        validate (NET_CONNECTION_EDITOR (user_data));
+
+        return G_SOURCE_REMOVE;
+}
+
+static void
+recheck_initialization (NetConnectionEditor *editor)
+{
+        GtkNotebook *notebook;
+
+        if (!editor_is_initialized (editor))
+                return;
+
+        notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_notebook"));
+        gtk_notebook_set_current_page (notebook, 0);
+
+        g_idle_add (idle_validate, editor);
+}
+
+static void
+page_initialized (CEPage *page, GError *error, NetConnectionEditor *editor)
+{
+        GtkNotebook *notebook;
+        GtkWidget *widget;
+        gint position;
+        GList *children, *l;
+        gint i;
+
+        notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_notebook"));
+        widget = ce_page_get_page (page);
+        position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (page), "position"));
+        g_object_set_data (G_OBJECT (widget), "position", GINT_TO_POINTER (position));
+        children = gtk_container_get_children (GTK_CONTAINER (notebook));
+        for (l = children, i = 0; l; l = l->next, i++) {
+                gint pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (l->data), "position"));
+                if (pos > position)
+                        break;
+        }
+        g_list_free (children);
+        gtk_notebook_insert_page (notebook, widget, NULL, i);
+
+        editor->initializing_pages = g_slist_remove (editor->initializing_pages, page);
+        editor->pages = g_slist_append (editor->pages, page);
+
+        recheck_initialization (editor);
+}
+
+typedef struct {
+        NetConnectionEditor *editor;
+        CEPage *page;
+        const gchar *setting_name;
+        gboolean canceled;
+} GetSecretsInfo;
+
+static void
+get_secrets_cb (NMRemoteConnection *connection,
+                GHashTable         *secrets,
+                GError             *error,
+                gpointer            user_data)
+{
+        GetSecretsInfo *info = user_data;
+
+        if (info->canceled) {
+                g_free (info);
+                return;
+        }
+
+        ce_page_complete_init (info->page, info->setting_name, secrets, error);
+        g_free (info);
+}
+
+static void
+get_secrets_for_page (NetConnectionEditor *editor,
+                      CEPage              *page,
+                      const gchar         *setting_name)
+{
+        GetSecretsInfo *info;
+
+        info = g_new0 (GetSecretsInfo, 1);
+        info->editor = editor;
+        info->page = page;
+        info->setting_name = setting_name;
+
+        nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (editor->orig_connection),
+                                          setting_name,
+                                          get_secrets_cb,
+                                          info);
+}
+
+static void
+add_page (NetConnectionEditor *editor, CEPage *page)
+{
+        GtkListStore *store;
+        GtkTreeIter iter;
+        const gchar *title;
+        gint position;
+
+        store = GTK_LIST_STORE (gtk_builder_get_object (editor->builder,
+                                                "details_store"));
+        title = ce_page_get_title (page);
+        position = g_slist_length (editor->initializing_pages);
+        g_object_set_data (G_OBJECT (page), "position", GINT_TO_POINTER (position));
+        gtk_list_store_insert_with_values (store, &iter, -1,
+                                           0, title,
+                                           1, position,
+                                           -1);
+        editor->initializing_pages = g_slist_append (editor->initializing_pages, page);
+
+        g_signal_connect (page, "changed", G_CALLBACK (page_changed), editor);
+        g_signal_connect (page, "initialized", G_CALLBACK (page_initialized), editor);
+}
+
+static void
+net_connection_editor_set_connection (NetConnectionEditor *editor,
+                                      NMConnection        *connection)
+{
+        GSList *pages, *l;
+        NMSettingConnection *sc;
+        const gchar *type;
+
+        editor->is_new_connection = !nm_remote_settings_get_connection_by_uuid (editor->settings,
+                                                                                 nm_connection_get_uuid (connection));
+
+        if (editor->is_new_connection) {
+                GtkWidget *button;
+
+                button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"));
+                gtk_button_set_label (GTK_BUTTON (button), _("_Add"));
+        }
+
+        editor->connection = nm_connection_duplicate (connection);
+        editor->orig_connection = g_object_ref (connection);
+
+        net_connection_editor_update_title (editor);
+
+        sc = nm_connection_get_setting_connection (connection);
+        type = nm_setting_connection_get_connection_type (sc);
+
+        add_page (editor, ce_page_details_new (editor->connection, editor->client, editor->settings, editor->device, editor->ap));
+
+        if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0)
+                add_page (editor, ce_page_security_new (editor->connection, editor->client, editor->settings));
+        else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0)
+                add_page (editor, ce_page_8021x_security_new (editor->connection, editor->client, editor->settings));
+
+        if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0)
+                add_page (editor, ce_page_wifi_new (editor->connection, editor->client, editor->settings));
+        else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0)
+                add_page (editor, ce_page_ethernet_new (editor->connection, editor->client, editor->settings));
+
+        add_page (editor, ce_page_ip4_new (editor->connection, editor->client, editor->settings));
+        add_page (editor, ce_page_ip6_new (editor->connection, editor->client, editor->settings));
+
+        add_page (editor, ce_page_reset_new (editor->connection, editor->client, editor->settings, editor));
+
+        pages = g_slist_copy (editor->initializing_pages);
+        for (l = pages; l; l = l->next) {
+                CEPage *page = l->data;
+                const gchar *security_setting;
+
+                security_setting = ce_page_get_security_setting (page);
+                if (!security_setting) {
+                        ce_page_complete_init (page, NULL, NULL, NULL);
+                } else {
+                        get_secrets_for_page (editor, page, security_setting);
+                }
+        }
+        g_slist_free (pages);
+}
+
+static void
+permission_changed (NMClient                 *client,
+                    NMClientPermission        permission,
+                    NMClientPermissionResult  result,
+                    NetConnectionEditor      *editor)
+{
+        if (permission != NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM)
+                return;
+
+        if (result == NM_CLIENT_PERMISSION_RESULT_YES || result == NM_CLIENT_PERMISSION_RESULT_AUTH)
+                editor->can_modify = TRUE;
+        else
+                editor->can_modify = FALSE;
+
+        validate (editor);
+}
+
+NetConnectionEditor *
+net_connection_editor_new (GtkWindow        *parent_window,
+                           NMConnection     *connection,
+                           NMDevice         *device,
+                           NMAccessPoint    *ap,
+                           NMClient         *client,
+                           NMRemoteSettings *settings)
+{
+        NetConnectionEditor *editor;
+
+        editor = g_object_new (NET_TYPE_CONNECTION_EDITOR, NULL);
+
+        if (parent_window) {
+                editor->parent_window = g_object_ref (parent_window);
+                gtk_window_set_transient_for (GTK_WINDOW (editor->window),
+                                              parent_window);
+        }
+        if (ap)
+                editor->ap = g_object_ref (ap);
+        editor->device = g_object_ref (device);
+        editor->client = g_object_ref (client);
+        editor->settings = g_object_ref (settings);
+
+        editor->can_modify = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM);
+        editor->permission_id = g_signal_connect (editor->client, "permission-changed",
+                                                  G_CALLBACK (permission_changed), editor);
+
+        net_connection_editor_set_connection (editor, connection);
+
+        return editor;
+}
+
+void
+net_connection_editor_present (NetConnectionEditor *editor)
+{
+        gtk_window_present (GTK_WINDOW (editor->window));
+}
+
+static void
+forgotten_cb (NMRemoteConnection *connection,
+              GError             *error,
+              gpointer            data)
+{
+        NetConnectionEditor *editor = data;
+
+        if (error != NULL) {
+                g_warning ("Failed to delete conneciton %s: %s",
+                           nm_connection_get_id (NM_CONNECTION (connection)),
+                           error->message);
+        }
+
+        cancel_editing (editor);
+}
+
+void
+net_connection_editor_forget (NetConnectionEditor *editor)
+{
+        nm_remote_connection_delete (NM_REMOTE_CONNECTION (editor->orig_connection), forgotten_cb, editor);
+}
+
+void
+net_connection_editor_reset (NetConnectionEditor *editor)
+{
+        GHashTable *settings;
+
+        settings = nm_connection_to_hash (editor->orig_connection, NM_SETTING_HASH_FLAG_ALL);
+        nm_connection_replace_settings (editor->connection, settings, NULL);
+        g_hash_table_destroy (settings);
+}
diff --git a/panels/network/connection-editor/net-connection-editor.h b/panels/network/connection-editor/net-connection-editor.h
new file mode 100644
index 0000000..31dc486
--- /dev/null
+++ b/panels/network/connection-editor/net-connection-editor.h
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 of the License, 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.
+ */
+
+#ifndef __NET_CONNECTION_EDITOR_H
+#define __NET_CONNECTION_EDITOR_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include <nm-client.h>
+#include <nm-access-point.h>
+#include <nm-remote-settings.h>
+
+G_BEGIN_DECLS
+
+#define NET_TYPE_CONNECTION_EDITOR         (net_connection_editor_get_type ())
+#define NET_CONNECTION_EDITOR(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditor))
+#define NET_CONNECTION_EDITOR_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditorClass))
+#define NET_IS_CONNECTION_EDITOR(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_CONNECTION_EDITOR))
+#define NET_IS_CONNECTION_EDITOR_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_CONNECTION_EDITOR))
+#define NET_CONNECTION_EDITOR_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditorClass))
+
+typedef struct _NetConnectionEditor          NetConnectionEditor;
+typedef struct _NetConnectionEditorClass     NetConnectionEditorClass;
+
+struct _NetConnectionEditor
+{
+         GObject parent;
+
+        GtkWidget        *parent_window;
+        NMClient         *client;
+        NMDevice         *device;
+        NMRemoteSettings *settings;
+
+        NMConnection     *connection;
+        NMConnection     *orig_connection;
+        gboolean          is_new_connection;
+        NMAccessPoint    *ap;
+
+        GtkBuilder       *builder;
+        GtkWidget        *window;
+
+        GSList *initializing_pages;
+        GSList *pages;
+
+        guint                    permission_id;
+        NMClientPermissionResult can_modify;
+};
+
+struct _NetConnectionEditorClass
+{
+        GObjectClass parent_class;
+
+        void (*done) (NetConnectionEditor *details, gboolean success);
+};
+
+GType                net_connection_editor_get_type (void);
+NetConnectionEditor *net_connection_editor_new      (GtkWindow        *parent_window,
+                                                     NMConnection     *connection,
+                                                     NMDevice         *device,
+                                                     NMAccessPoint    *ap,
+                                                     NMClient         *client,
+                                                     NMRemoteSettings *settings);
+void                 net_connection_editor_run      (NetConnectionEditor   *editor);
+void                 net_connection_editor_present  (NetConnectionEditor   *editor);
+void                 net_connection_editor_forget   (NetConnectionEditor   *editor);
+void                 net_connection_editor_reset    (NetConnectionEditor   *editor);
+
+G_END_DECLS
+
+#endif /* __NET_CONNECTION_EDITOR_H */
+
diff --git a/panels/network/connection-editor/reset-page.ui b/panels/network/connection-editor/reset-page.ui
new file mode 100644
index 0000000..594817e
--- /dev/null
+++ b/panels/network/connection-editor/reset-page.ui
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkGrid" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">50</property>
+    <property name="margin_right">50</property>
+    <property name="margin_top">12</property>
+    <property name="margin_bottom">12</property>
+    <property name="row_spacing">20</property>
+    <property name="column_spacing">20</property>
+    <child>
+      <object class="GtkButton" id="button_reset">
+        <property name="label" translatable="yes">_Reset</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">True</property>
+        <property name="valign">center</property>
+        <property name="use_underline">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkButton" id="button_forget">
+        <property name="label" translatable="yes">_Forget</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">True</property>
+        <property name="valign">center</property>
+        <property name="use_underline">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_reset">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Reset the settings for this network, including passwords, but remember it as a preferred network</property>
+        <property name="wrap">True</property>
+        <property name="max_width_chars">40</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label_forget">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hexpand">True</property>
+        <property name="xalign">0</property>
+        <property name="label" translatable="yes">Remove all details relating to this network and do not try to automatically connect</property>
+        <property name="wrap">True</property>
+        <property name="max_width_chars">30</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/security-page.ui b/panels/network/connection-editor/security-page.ui
new file mode 100644
index 0000000..f2252ed
--- /dev/null
+++ b/panels/network/connection-editor/security-page.ui
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkGrid" id="grid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">50</property>
+        <property name="margin_right">50</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="row_spacing">10</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="heading_sec">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">S_ecurity</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">combo_sec</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="combo_sec">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="hexpand">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">2</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">page 1</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkGrid" id="grid1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_left">50</property>
+        <property name="margin_right">50</property>
+        <property name="margin_top">12</property>
+        <property name="margin_bottom">12</property>
+        <property name="row_spacing">10</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkEntry" id="entry1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+            <property name="width_chars">35</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry2">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry3">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry4">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">3</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry5">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">4</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry6">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">5</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry7">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">6</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry8">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">7</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry9">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">8</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="entry10">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">9</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Anony_mous identity</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Inner _authentication</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label2">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">page 2</property>
+      </object>
+      <packing>
+        <property name="position">1</property>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child type="tab">
+      <placeholder/>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/connection-editor/wifi-page.ui b/panels/network/connection-editor/wifi-page.ui
new file mode 100644
index 0000000..8e99d15
--- /dev/null
+++ b/panels/network/connection-editor/wifi-page.ui
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkGrid" id="page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">50</property>
+    <property name="margin_right">50</property>
+    <property name="margin_top">12</property>
+    <property name="margin_bottom">12</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="row_spacing">10</property>
+    <property name="column_spacing">6</property>
+    <child>
+      <object class="GtkLabel" id="heading_ssid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">_SSID</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">entry_ssid</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_bssid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">_BSSID</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">combo_bssid</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="entry_ssid">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="invisible_char">●</property>
+        <property name="text" translatable="yes">My Home Network</property>
+        <property name="invisible_char_set">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">_MAC Address</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">combo_mac</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="entry_cloned_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="invisible_char">●</property>
+        <property name="invisible_char_set">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="heading_cloned_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">_Cloned Address</property>
+        <property name="use_underline">True</property>
+        <property name="mnemonic_widget">entry_cloned_mac</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">3</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="combo_bssid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="has_entry">True</property>
+        <property name="entry_text_column">0</property>
+        <property name="id_column">1</property>
+        <child internal-child="entry">
+          <object class="GtkEntry" id="comboboxtext-entry2">
+            <property name="can_focus">False</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkComboBoxText" id="combo_mac">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="has_entry">True</property>
+        <property name="entry_text_column">0</property>
+        <property name="id_column">1</property>
+        <child internal-child="entry">
+          <object class="GtkEntry" id="comboboxtext-entry4">
+            <property name="can_focus">False</property>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="auto_connect_check">
+        <property name="label" translatable="yes">Connect _automatically</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="valign">end</property>
+        <property name="vexpand">True</property>
+        <property name="use_underline">True</property>
+        <property name="xalign">0</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">4</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkCheckButton" id="all_user_check">
+        <property name="label" translatable="yes">Make available to _other users</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="use_underline">True</property>
+        <property name="xalign">0</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+        <property name="width">2</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/net-device-ethernet.c b/panels/network/net-device-ethernet.c
index 3ac6faa..6455313 100644
--- a/panels/network/net-device-ethernet.c
+++ b/panels/network/net-device-ethernet.c
@@ -28,9 +28,14 @@
 #include <nm-device.h>
 #include <nm-device-ethernet.h>
 #include <nm-remote-connection.h>
+#include <nm-utils.h>
 
 #include "panel-common.h"
 
+#include "egg-list-box/egg-list-box.h"
+#include "connection-editor/net-connection-editor.h"
+#include "connection-editor/ce-page.h"
+
 #include "net-device-ethernet.h"
 
 G_DEFINE_TYPE (NetDeviceEthernet, net_device_ethernet, NET_TYPE_DEVICE_SIMPLE)
@@ -51,15 +56,589 @@ device_ethernet_get_speed (NetDeviceSimple *device_simple)
                 return NULL;
 }
 
+static GSList *
+valid_connections_for_device (NMRemoteSettings *remote_settings,
+                              NetDevice        *device)
+{
+        GSList *all, *filtered, *iterator, *valid;
+        NMConnection *connection;
+        NMSettingConnection *s_con;
+
+        all = nm_remote_settings_list_connections (remote_settings);
+        filtered = nm_device_filter_connections (net_device_get_nm_device (device), all);
+        g_slist_free (all);
+
+        valid = NULL;
+        for (iterator = filtered; iterator; iterator = iterator->next) {
+                connection = iterator->data;
+                s_con = nm_connection_get_setting_connection (connection);
+                if (!s_con)
+                        continue;
+
+                if (nm_setting_connection_get_master (s_con))
+                        continue;
+
+                valid = g_slist_prepend (valid, connection);
+        }
+        g_slist_free (filtered);
+
+        return g_slist_reverse (valid);
+}
+
+static GtkWidget *
+device_ethernet_add_to_notebook (NetObject    *object,
+                                 GtkNotebook  *notebook,
+                                 GtkSizeGroup *heading_size_group)
+{
+        NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+        GtkWidget *vbox;
+
+        vbox = GTK_WIDGET (gtk_builder_get_object (device->builder, "vbox6"));
+        g_object_ref (vbox);
+        gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (vbox)), vbox);
+        gtk_notebook_append_page (notebook, vbox, NULL);
+        g_object_unref (vbox);
+        return vbox;
+}
+
+static void
+add_details_row (GtkWidget *details, gint top, const gchar *heading, const gchar *value)
+{
+        GtkWidget *label;
+
+        label = gtk_label_new (heading);
+        gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
+        gtk_widget_set_halign (label, GTK_ALIGN_END);
+        gtk_widget_set_hexpand (label, TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
+
+        gtk_grid_attach (GTK_GRID (details), label, 0, top, 1, 1);
+
+        label = gtk_label_new (value);
+        gtk_widget_set_halign (label, GTK_ALIGN_START);
+        gtk_widget_set_hexpand (label, TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+        gtk_grid_attach (GTK_GRID (details), label, 1, top, 1, 1);
+}
+
+static gchar *
+get_last_used_string (NMConnection *connection)
+{
+        gchar *last_used = NULL;
+        GDateTime *now = NULL;
+        GDateTime *then = NULL;
+        gint days;
+        GTimeSpan diff;
+        guint64 timestamp;
+        NMSettingConnection *s_con;
+
+        s_con = nm_connection_get_setting_connection (connection);
+        if (s_con == NULL)
+                goto out;
+        timestamp = nm_setting_connection_get_timestamp (s_con);
+        if (timestamp == 0) {
+                last_used = g_strdup (_("never"));
+                goto out;
+        }
+
+        /* calculate the amount of time that has elapsed */
+        now = g_date_time_new_now_utc ();
+        then = g_date_time_new_from_unix_utc (timestamp);
+        diff = g_date_time_difference  (now, then);
+        days = diff / G_TIME_SPAN_DAY;
+        if (days == 0)
+                last_used = g_strdup (_("today"));
+        else if (days == 1)
+                last_used = g_strdup (_("yesterday"));
+        else
+                last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days);
+out:
+        if (now != NULL)
+                g_date_time_unref (now);
+        if (then != NULL)
+                g_date_time_unref (then);
+
+        return last_used;
+}
+
+static void
+add_details (GtkWidget *details, NMDevice *device, NMConnection *connection)
+{
+        NMIP4Config *ip4_config = NULL;
+        NMIP6Config *ip6_config = NULL;
+        gchar *ip4_address = NULL;
+        gchar *ip4_route = NULL;
+        gchar *ip4_dns = NULL;
+        gchar *ip6_address = NULL;
+        gint i = 0;
+
+        ip4_config = nm_device_get_ip4_config (device);
+        if (ip4_config) {
+                ip4_address = panel_get_ip4_address_as_string (ip4_config, "address");
+                ip4_route = panel_get_ip4_address_as_string (ip4_config, "gateway");
+                ip4_dns = panel_get_ip4_dns_as_string (ip4_config);
+        }
+        ip6_config = nm_device_get_ip6_config (device);
+        if (ip6_config) {
+                ip6_address = panel_get_ip6_address_as_string (ip6_config);
+        }
+
+        if (ip4_address && ip6_address) {
+                add_details_row (details, i++, _("IP4 Address"), ip4_address);
+                add_details_row (details, i++, _("IP6 Address"), ip6_address);
+        } else if (ip4_address) {
+                add_details_row (details, i++, _("IP Address"), ip4_address);
+        } else if (ip6_address) {
+                add_details_row (details, i++, _("IP Address"), ip6_address);
+        }
+
+        add_details_row (details, i++, _("Hardware Address"),
+                         nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)));
+
+        if (ip4_route)
+                add_details_row (details, i++, _("Default Route"), ip4_route);
+        if (ip4_dns)
+                add_details_row (details, i++, _("DNS"), ip4_dns);
+
+        if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) {
+                gchar *last_used;
+                last_used = get_last_used_string (connection);
+                add_details_row (details, i++, _("Last used"), last_used);
+                g_free (last_used);
+        }
+
+        g_free (ip4_address);
+        g_free (ip4_route);
+        g_free (ip4_dns);
+        g_free (ip6_address);
+}
+
+static void populate_ui (NetDeviceEthernet *device);
+
+static gboolean
+device_state_to_off_switch (NMDeviceState state)
+{
+        switch (state) {
+                case NM_DEVICE_STATE_UNMANAGED:
+                case NM_DEVICE_STATE_UNAVAILABLE:
+                case NM_DEVICE_STATE_DISCONNECTED:
+                case NM_DEVICE_STATE_DEACTIVATING:
+                case NM_DEVICE_STATE_FAILED:
+                        return FALSE;
+                default:
+                        return TRUE;
+        }
+}
+
+static void
+device_ethernet_refresh_ui (NetDeviceEthernet *device)
+{
+        NMDevice *nm_device;
+        NMDeviceState state;
+        GtkWidget *widget;
+        GString *status;
+        gchar *speed = NULL;
+
+        nm_device = net_device_get_nm_device (NET_DEVICE (device));
+
+        widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "label_device"));
+        gtk_label_set_label (GTK_LABEL (widget), net_object_get_title (NET_OBJECT (device)));
+
+        widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "image_device"));
+        gtk_image_set_from_icon_name (GTK_IMAGE (widget),
+                                      panel_device_to_icon_name (nm_device),
+                                      GTK_ICON_SIZE_DIALOG);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "device_off_switch"));
+        state = nm_device_get_state (nm_device);
+        gtk_widget_set_visible (widget,
+                                state != NM_DEVICE_STATE_UNAVAILABLE
+                                && state != NM_DEVICE_STATE_UNMANAGED);
+        device->updating_device = TRUE;
+        gtk_switch_set_active (GTK_SWITCH (widget), device_state_to_off_switch (state));
+        device->updating_device = FALSE;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "label_status"));
+        status = g_string_new (panel_device_state_to_localized_string (nm_device));
+        if (state != NM_DEVICE_STATE_UNAVAILABLE)
+                speed = net_device_simple_get_speed (NET_DEVICE_SIMPLE (device));
+        if (speed)
+                g_string_append_printf (status, " - %s", speed);
+        gtk_label_set_label (GTK_LABEL (widget), status->str);
+        g_string_free (status, TRUE);
+
+        populate_ui (device);
+}
+
+static void
+editor_done (NetConnectionEditor *editor,
+             gboolean             success,
+             NetDeviceEthernet   *device)
+{
+        g_object_unref (editor);
+        device_ethernet_refresh_ui (device);
+}
+
+static void
+show_details_for_row (GtkButton *button, NetDeviceEthernet *device)
+{
+        GtkWidget *row;
+        NMConnection *connection;
+        GtkWidget *window;
+        NetConnectionEditor *editor;
+        NMClient *client;
+        NMRemoteSettings *settings;
+        NMDevice *nmdev;
+
+        window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+        row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row"));
+        connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection"));
+
+        nmdev = net_device_get_nm_device (NET_DEVICE (device));
+        client = net_object_get_client (NET_OBJECT (device));
+        settings = net_object_get_remote_settings (NET_OBJECT (device));
+        editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings);
+        g_signal_connect (editor, "done", G_CALLBACK (editor_done), device);
+        net_connection_editor_run (editor);
+}
+
+static void
+add_row (NetDeviceEthernet *device, NMConnection *connection)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *box;
+        GtkWidget *details;
+        NMDevice *nmdev;
+        NMActiveConnection *aconn;
+        gboolean active;
+        GtkWidget *image;
+
+        active = FALSE;
+
+        nmdev = net_device_get_nm_device (NET_DEVICE (device));
+        aconn = nm_device_get_active_connection (nmdev);
+        if (aconn) {
+                const gchar *path1, *path2;
+                path1 = nm_active_connection_get_connection (aconn);
+                path2 = nm_connection_get_path (connection);
+                active = g_strcmp0 (path1, path2) == 0;
+        }
+
+        row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+        gtk_box_pack_start (GTK_BOX (row), box, FALSE, TRUE, 0);
+        widget = gtk_label_new (nm_connection_get_id (connection));
+        gtk_widget_set_margin_left (widget, 12);
+        gtk_widget_set_margin_right (widget, 12);
+        gtk_widget_set_margin_top (widget, 12);
+        gtk_widget_set_margin_bottom (widget, 12);
+        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
+
+        if (active) {
+                widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
+                gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+                gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+                gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
+
+                details = gtk_grid_new ();
+                gtk_grid_set_row_spacing (GTK_GRID (details), 10);
+                gtk_grid_set_column_spacing (GTK_GRID (details), 10);
+
+                gtk_box_pack_start (GTK_BOX (row), details, FALSE, TRUE, 0);
+
+                add_details (details, nmdev, connection);
+        }
+
+        /* filler */
+        widget = gtk_label_new ("");
+        gtk_widget_set_hexpand (widget, TRUE);
+        gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
+
+        image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU);
+        gtk_widget_show (image);
+        widget = gtk_button_new ();
+        gtk_widget_set_margin_left (widget, 12);
+        gtk_widget_set_margin_right (widget, 12);
+        gtk_widget_set_margin_top (widget, 12);
+        gtk_widget_set_margin_bottom (widget, 12);
+        gtk_widget_show (widget);
+        gtk_container_add (GTK_CONTAINER (widget), image);
+        gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+        gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
+        g_object_set_data (G_OBJECT (row), "edit", widget);
+        g_object_set_data (G_OBJECT (widget), "row", row);
+        g_signal_connect (widget, "clicked",
+                          G_CALLBACK (show_details_for_row), device);
+
+        gtk_widget_show_all (row);
+
+        g_object_set_data (G_OBJECT (row), "connection", connection);
+
+        gtk_container_add (GTK_CONTAINER (device->list), row);
+}
+
+static void
+connection_removed (NMRemoteConnection *connection,
+                    NetDeviceEthernet  *device)
+{
+        device_ethernet_refresh_ui (device);
+}
+
+static void
+populate_ui (NetDeviceEthernet *device)
+{
+        NMRemoteSettings *settings;
+        GList *children, *c;
+        GSList *connections, *l;
+        NMConnection *connection;
+        gint n_connections;
+
+        children = gtk_container_get_children (GTK_CONTAINER (device->list));
+        for (c = children; c; c = c->next) {
+                gtk_container_remove (GTK_CONTAINER (device->list), c->data);
+        }
+        g_list_free (children);
+
+        children = gtk_container_get_children (GTK_CONTAINER (device->details));
+        for (c = children; c; c = c->next) {
+                gtk_container_remove (GTK_CONTAINER (device->details), c->data);
+        }
+        g_list_free (children);
+
+        settings = net_object_get_remote_settings (NET_OBJECT (device));
+        connections = valid_connections_for_device (settings, NET_DEVICE (device));
+
+
+        for (l = connections; l; l = l->next) {
+                NMConnection *connection = l->data;
+                if (!g_object_get_data (G_OBJECT (connection), "removed_signal_handler")) {
+                        g_signal_connect (connection, "removed",
+                                          G_CALLBACK (connection_removed), device);
+                        g_object_set_data (G_OBJECT (connection), "removed_signal_handler", GINT_TO_POINTER (TRUE));
+                }
+        }
+        n_connections = g_slist_length (connections);
+
+        if (n_connections > 4) {
+                gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window),
+                                                GTK_POLICY_NEVER,
+                                                GTK_POLICY_AUTOMATIC);
+                gtk_widget_set_vexpand (device->scrolled_window, TRUE);
+        } else {
+                gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window),
+                                                GTK_POLICY_NEVER,
+                                                GTK_POLICY_NEVER);
+                gtk_widget_set_vexpand (device->scrolled_window, FALSE);
+        }
+
+        if (n_connections > 1) {
+                gtk_widget_hide (device->details);
+                gtk_widget_hide (device->details_button);
+                for (l = connections; l; l = l->next) {
+                        NMConnection *connection = l->data;
+                        add_row (device, connection);
+                }
+                gtk_widget_show (device->scrolled_window);
+        } else if (n_connections == 1) {
+                connection = connections->data;
+                gtk_widget_hide (device->scrolled_window);
+                add_details (device->details, net_device_get_nm_device (NET_DEVICE (device)), connection);
+                gtk_widget_show_all (device->details);
+                gtk_widget_show (device->details_button);
+                g_object_set_data (G_OBJECT (device->details_button), "row", device->details_button);
+                g_object_set_data (G_OBJECT (device->details_button), "connection", connection);
+
+        } else {
+                gtk_widget_hide (device->scrolled_window);
+                gtk_widget_hide (device->details);
+                gtk_widget_hide (device->details_button);
+        }
+}
+
+static void
+remote_settings_read_cb (NMRemoteSettings  *settings,
+                         NetDeviceEthernet *device)
+{
+        device_ethernet_refresh_ui (device);
+}
+
+static void
+update_separator (GtkWidget **separator,
+                  GtkWidget  *child,
+                  GtkWidget  *before,
+                  gpointer    user_data)
+{
+  if (before == NULL)
+    return;
+
+  if (*separator == NULL)
+    {
+      *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_widget_show (*separator);
+      g_object_ref_sink (*separator);
+    }
+}
+
+static void
+add_profile (GtkButton *button, NetDeviceEthernet *device)
+{
+        NMRemoteSettings *settings;
+        NMConnection *connection;
+        NMSettingConnection *sc;
+        gchar *uuid, *id;
+        NetConnectionEditor *editor;
+        GtkWidget *window;
+        NMClient *client;
+        NMDevice *nmdev;
+        GSList *connections;
+
+        connection = nm_connection_new ();
+        sc = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+        nm_connection_add_setting (connection, NM_SETTING (sc));
+
+        uuid = nm_utils_uuid_generate ();
+
+        settings = net_object_get_remote_settings (NET_OBJECT (device));
+        connections = nm_remote_settings_list_connections (settings);
+        id = ce_page_get_next_available_name (connections, _("Profile %d"));
+        g_slist_free (connections);
+
+        g_object_set (sc,
+                      NM_SETTING_CONNECTION_UUID, uuid,
+                      NM_SETTING_CONNECTION_ID, id,
+                      NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+                      NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+                      NULL);
+
+        nm_connection_add_setting (connection, nm_setting_wired_new ());
+
+        g_free (uuid);
+        g_free (id);
+
+        window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+        nmdev = net_device_get_nm_device (NET_DEVICE (device));
+        client = net_object_get_client (NET_OBJECT (device));
+        editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings);
+        g_signal_connect (editor, "done", G_CALLBACK (editor_done), device);
+        net_connection_editor_run (editor);
+}
+
+static void
+device_off_toggled (GtkSwitch         *sw,
+                    GParamSpec        *pspec,
+                    NetDeviceEthernet *device)
+{
+        NMClient *client;
+        NMDevice *nm_device;
+        NMConnection *connection;
+        NMActiveConnection *a;
+
+        if (device->updating_device)
+                return;
+
+        client = net_object_get_client (NET_OBJECT (device));
+        nm_device = net_device_get_nm_device (NET_DEVICE (device));
+
+        if (gtk_switch_get_active (sw)) {
+                connection = net_device_get_find_connection (NET_DEVICE (device));
+                if (connection != NULL) {
+                        nm_client_activate_connection (client,
+                                                       connection,
+                                                       nm_device,
+                                                       NULL, NULL, NULL);
+                }
+        } else {
+                a = nm_device_get_active_connection (nm_device);
+                if (a) {
+                        nm_client_deactivate_connection (client, a);
+                }
+        }
+}
+
+static void
+device_ethernet_constructed (GObject *object)
+{
+        NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+        NMRemoteSettings *settings;
+        GtkWidget *list;
+        GtkWidget *swin;
+        GtkWidget *widget;
+
+        widget = GTK_WIDGET (gtk_builder_get_object (device->builder,
+                                                     "device_off_switch"));
+        g_signal_connect (widget, "notify::active",
+                          G_CALLBACK (device_off_toggled), device);
+
+        device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (device->builder, "list"));
+        device->list = list = GTK_WIDGET (egg_list_box_new ());
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_add_to_scrolled (EGG_LIST_BOX (list), GTK_SCROLLED_WINDOW (swin));
+        gtk_widget_show (list);
+
+        device->details = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details"));
+
+        device->details_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details_button"));
+        g_signal_connect (device->details_button, "clicked",
+                          G_CALLBACK (show_details_for_row), device);
+
+        device->add_profile_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "add_profile_button"));
+        g_signal_connect (device->add_profile_button, "clicked",
+                          G_CALLBACK (add_profile), device);
+
+        settings = net_object_get_remote_settings (NET_OBJECT (object));
+        g_signal_connect (settings, "connections-read",
+                          G_CALLBACK (remote_settings_read_cb), object);
+}
+
+static void
+device_ethernet_finalize (GObject *object)
+{
+        NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+
+        g_object_unref (device->builder);
+
+        G_OBJECT_CLASS (net_device_ethernet_parent_class)->finalize (object);
+}
+
+static void
+device_ethernet_refresh (NetObject *object)
+{
+        NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+        device_ethernet_refresh_ui (device);
+}
+
 static void
 net_device_ethernet_class_init (NetDeviceEthernetClass *klass)
 {
         NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass);
+        NetObjectClass *obj_class = NET_OBJECT_CLASS (klass);
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
         simple_class->get_speed = device_ethernet_get_speed;
+        obj_class->refresh = device_ethernet_refresh;
+        obj_class->add_to_notebook = device_ethernet_add_to_notebook;
+        object_class->constructed = device_ethernet_constructed;
+        object_class->finalize = device_ethernet_finalize;
 }
 
 static void
-net_device_ethernet_init (NetDeviceEthernet *device_ethernet)
+net_device_ethernet_init (NetDeviceEthernet *device)
 {
+        GError *error = NULL;
+
+        device->builder = gtk_builder_new ();
+        gtk_builder_add_from_file (device->builder,
+                                   GNOMECC_UI_DIR "/network-ethernet.ui",
+                                   &error);
+        if (error != NULL) {
+                g_warning ("Could not load interface file: %s", error->message);
+                g_error_free (error);
+                return;
+        }
 }
diff --git a/panels/network/net-device-ethernet.h b/panels/network/net-device-ethernet.h
index 5c22937..84d0e43 100644
--- a/panels/network/net-device-ethernet.h
+++ b/panels/network/net-device-ethernet.h
@@ -41,16 +41,24 @@ typedef struct _NetDeviceEthernetClass     NetDeviceEthernetClass;
 
 struct _NetDeviceEthernet
 {
-         NetDeviceSimple                 parent;
-         NetDeviceEthernetPrivate          *priv;
+        NetDeviceSimple parent;
+
+        GtkBuilder *builder;
+
+        GtkWidget *list;
+        GtkWidget *scrolled_window;
+        GtkWidget *details;
+        GtkWidget *details_button;
+        GtkWidget *add_profile_button;
+        gboolean   updating_device;
 };
 
 struct _NetDeviceEthernetClass
 {
-        NetDeviceSimpleClass             parent_class;
+        NetDeviceSimpleClass parent_class;
 };
 
-GType            net_device_ethernet_get_type      (void);
+GType net_device_ethernet_get_type (void);
 
 G_END_DECLS
 
diff --git a/panels/network/net-device-simple.c b/panels/network/net-device-simple.c
index fbd9a1e..633781d 100644
--- a/panels/network/net-device-simple.c
+++ b/panels/network/net-device-simple.c
@@ -124,8 +124,10 @@ nm_device_simple_refresh_ui (NetDeviceSimple *device_simple)
         status = g_string_new (panel_device_state_to_localized_string (nm_device));
         if (state != NM_DEVICE_STATE_UNAVAILABLE)
                 speed = net_device_simple_get_speed (device_simple);
-        if (speed)
+        if (speed) {
                 g_string_append_printf (status, " - %s", speed);
+                g_free (speed);
+        }
         gtk_label_set_label (GTK_LABEL (widget), status->str);
         g_string_free (status, TRUE);
         gtk_widget_set_tooltip_text (widget,
diff --git a/panels/network/net-device-wifi.c b/panels/network/net-device-wifi.c
index 278991a..6cca1f9 100644
--- a/panels/network/net-device-wifi.c
+++ b/panels/network/net-device-wifi.c
@@ -38,19 +38,25 @@
 
 #include "network-dialogs.h"
 #include "panel-common.h"
-#include "panel-cell-renderer-mode.h"
-#include "panel-cell-renderer-signal.h"
-#include "panel-cell-renderer-security.h"
-#include "panel-cell-renderer-separator.h"
-#include "panel-cell-renderer-text.h"
-#include "panel-cell-renderer-pixbuf.h"
 
+#include "egg-list-box/egg-list-box.h"
+
+#include "connection-editor/net-connection-editor.h"
 #include "net-device-wifi.h"
 
 #define NET_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiPrivate))
 
+typedef enum {
+  NM_AP_SEC_UNKNOWN,
+  NM_AP_SEC_NONE,
+  NM_AP_SEC_WEP,
+  NM_AP_SEC_WPA,
+  NM_AP_SEC_WPA2
+} NMAccessPointSecurity;
+
 static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi);
 static void show_wifi_list (NetDeviceWifi *device_wifi);
+static void populate_ap_list (NetDeviceWifi *device_wifi);
 
 struct _NetDeviceWifiPrivate
 {
@@ -135,46 +141,6 @@ get_access_point_security (NMAccessPoint *ap)
         return type;
 }
 
-static void
-add_access_point (NetDeviceWifi *device_wifi, NMAccessPoint *ap, NMAccessPoint *active, NMDevice *device)
-{
-        const GByteArray *ssid;
-        const gchar *object_path;
-        const gchar *ssid_text;
-        gboolean is_active_ap;
-        gchar *title;
-        GtkListStore *liststore_network;
-        GtkTreeIter treeiter;
-        NetDeviceWifiPrivate *priv = device_wifi->priv;
-
-        ssid = nm_access_point_get_ssid (ap);
-        if (ssid == NULL)
-                return;
-        ssid_text = nm_utils_escape_ssid (ssid->data, ssid->len);
-        title = g_markup_escape_text (ssid_text, -1);
-
-        is_active_ap = active && nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE);
-        liststore_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
-                                            "liststore_network"));
-
-        object_path = nm_object_get_path (NM_OBJECT (ap));
-        gtk_list_store_insert_with_values (liststore_network,
-                                           &treeiter,
-                                           -1,
-                                           COLUMN_ACCESS_POINT_ID, object_path,
-                                           COLUMN_TITLE, title,
-                                           COLUMN_SORT, ssid_text,
-                                           COLUMN_STRENGTH, nm_access_point_get_strength (ap),
-                                           COLUMN_MODE, nm_access_point_get_mode (ap),
-                                           COLUMN_SECURITY, get_access_point_security (ap),
-                                           COLUMN_ACTIVE, is_active_ap,
-                                           COLUMN_AP_IN_RANGE, TRUE,
-                                           COLUMN_AP_OUT_OF_RANGE, FALSE,
-                                           COLUMN_AP_IS_SAVED, FALSE,
-                                           -1);
-        g_free (title);
-}
-
 static GPtrArray *
 panel_get_strongest_unique_aps (const GPtrArray *aps)
 {
@@ -300,29 +266,6 @@ wireless_enabled_toggled (NMClient       *client,
         device_wifi->priv->updating_device = FALSE;
 }
 
-#if 0
-static void
-update_off_switch_from_device_state (GtkSwitch *sw,
-                                     NMDeviceState state,
-                                     NetDeviceWifi *device_wifi)
-{
-        device_wifi->priv->updating_device = TRUE;
-        switch (state) {
-                case NM_DEVICE_STATE_UNMANAGED:
-                case NM_DEVICE_STATE_UNAVAILABLE:
-                case NM_DEVICE_STATE_DISCONNECTED:
-                case NM_DEVICE_STATE_DEACTIVATING:
-                case NM_DEVICE_STATE_FAILED:
-                        gtk_switch_set_active (sw, FALSE);
-                        break;
-                default:
-                        gtk_switch_set_active (sw, TRUE);
-                        break;
-        }
-        device_wifi->priv->updating_device = FALSE;
-}
-#endif
-
 static NMConnection *
 find_connection_for_device (NetDeviceWifi *device_wifi,
                             NMDevice       *device)
@@ -461,133 +404,6 @@ device_get_hotspot_security_details (NetDeviceWifi *device_wifi,
 }
 
 static void
-device_wifi_refresh_aps (NetDeviceWifi *device_wifi)
-{
-        const GPtrArray *aps;
-        GPtrArray *aps_unique = NULL;
-        GtkListStore *liststore_network;
-        guint i;
-        NMAccessPoint *active_ap;
-        NMAccessPoint *ap;
-        NMDevice *nm_device;
-
-        /* populate access points */
-        liststore_network = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder,
-                                                                    "liststore_network"));
-        device_wifi->priv->updating_device = TRUE;
-        gtk_list_store_clear (liststore_network);
-        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
-        aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device));
-        aps_unique = panel_get_strongest_unique_aps (aps);
-        active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
-
-        for (i = 0; i < aps_unique->len; i++) {
-                ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i));
-                add_access_point (device_wifi, ap, active_ap, nm_device);
-        }
-
-        device_wifi->priv->updating_device = FALSE;
-        g_ptr_array_unref (aps_unique);
-}
-
-static gboolean
-find_ssid_in_store (GtkTreeModel *model, GtkTreeIter *iter, const gchar *ssid)
-{
-        gboolean found;
-        gchar *sort;
-
-        found = gtk_tree_model_get_iter_first (model, iter);
-
-        while (found) {
-                gtk_tree_model_get (model, iter,
-                                    COLUMN_SORT, &sort,
-                                    -1);
-                if (g_strcmp0 (ssid, sort) == 0) {
-                        g_free (sort);
-                        return TRUE;
-                }
-                g_free (sort);
-                found = gtk_tree_model_iter_next (model, iter);
-        }
-
-        return FALSE;
-
-}
-
-static void
-add_saved_connection (NetDeviceWifi *device_wifi, NMConnection *connection, NMDevice *nm_device)
-{
-        const GByteArray *ssid;
-        const gchar *id;
-        const gchar *ssid_text;
-        gchar *title;
-        GtkListStore *store;
-        GtkTreeIter iter;
-        NMSetting *setting;
-
-        setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME);
-
-        if (setting == NULL)
-                return;
-
-        ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting));
-        ssid_text = nm_utils_escape_ssid (ssid->data, ssid->len);
-        title = g_markup_escape_text (ssid_text, -1);
-        g_debug ("got saved %s", title);
-
-        id = nm_connection_get_path (connection);
-
-        store = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder,
-                                                        "liststore_network"));
-        if (find_ssid_in_store (GTK_TREE_MODEL (store), &iter, ssid_text))
-                gtk_list_store_set (store, &iter,
-                                    COLUMN_CONNECTION_ID, id,
-                                    COLUMN_AP_IS_SAVED, TRUE,
-                                    -1);
-        else
-                gtk_list_store_insert_with_values (store, &iter,
-                                                   -1,
-                                                   COLUMN_CONNECTION_ID, id,
-                                                   COLUMN_TITLE, title,
-                                                   COLUMN_SORT, ssid_text,
-                                                   COLUMN_STRENGTH, 0,
-                                                   COLUMN_MODE, 0,
-                                                   COLUMN_SECURITY, 0,
-                                                   COLUMN_ACTIVE, FALSE,
-                                                   COLUMN_AP_IN_RANGE, FALSE,
-                                                   COLUMN_AP_OUT_OF_RANGE, TRUE,
-                                                   COLUMN_AP_IS_SAVED, TRUE,
-                                                   -1);
-        g_free (title);
-}
-
-static void
-device_wifi_refresh_saved_connections (NetDeviceWifi *device_wifi)
-{
-        GSList *connections;
-        GSList *filtered;
-        GSList *l;
-        NMDevice *nm_device;
-        NMRemoteSettings *remote_settings;
-
-        /* add stored connections */
-        device_wifi->priv->updating_device = TRUE;
-        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
-        connections = nm_remote_settings_list_connections (remote_settings);
-        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
-        filtered = nm_device_filter_connections (nm_device, connections);
-        for (l = filtered; l; l = l->next) {
-                NMConnection *connection = l->data;
-                if (!connection_is_shared (connection))
-                        add_saved_connection (device_wifi, connection, nm_device);
-        }
-        device_wifi->priv->updating_device = FALSE;
-
-        g_slist_free (connections);
-        g_slist_free (filtered);
-}
-
-static void
 nm_device_wifi_refresh_hotspot (NetDeviceWifi *device_wifi)
 {
         const GByteArray *ssid;
@@ -625,26 +441,17 @@ nm_device_wifi_refresh_hotspot (NetDeviceWifi *device_wifi)
 }
 
 static void
-update_last_used (NetDeviceWifi *device_wifi)
+update_last_used (NetDeviceWifi *device_wifi, NMConnection *connection)
 {
-        NetDeviceWifiPrivate *priv = device_wifi->priv;
         gchar *last_used = NULL;
         GDateTime *now = NULL;
         GDateTime *then = NULL;
         gint days;
         GTimeSpan diff;
         guint64 timestamp;
-        NMRemoteConnection *connection;
-        NMRemoteSettings *settings;
         NMSettingConnection *s_con;
 
-        if (priv->selected_connection_id == NULL)
-                goto out;
-
-        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
-        connection = nm_remote_settings_get_connection_by_path (settings,
-                                                                priv->selected_connection_id);
-        s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
+        s_con = nm_connection_get_setting_connection (connection);
         if (s_con == NULL)
                 goto out;
         timestamp = nm_setting_connection_get_timestamp (s_con);
@@ -689,7 +496,9 @@ nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi)
         NMDeviceState state;
         NMClient *client;
         NMAccessPoint *ap;
+        NMConnection *connection;
         NetDeviceWifiPrivate *priv = device_wifi->priv;
+        GtkWidget *dialog;
 
         is_hotspot = device_is_hotspot (device_wifi);
         if (is_hotspot) {
@@ -699,13 +508,11 @@ nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi)
 
         nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
 
-        if (priv->selected_ap_id) {
-                ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (nm_device),
-                                                              priv->selected_ap_id);
-        }
-        else {
-                ap = NULL;
-        }
+        dialog = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
+                                                     "details_dialog"));
+
+        ap = g_object_get_data (G_OBJECT (dialog), "ap");
+        connection = g_object_get_data (G_OBJECT (dialog), "connection");
 
         active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
 
@@ -728,20 +535,6 @@ nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi)
                                          "speed",
                                          str_tmp);
 
-        /* set device state, with status and optionally speed */
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "label_status"));
-        if (ap != active_ap) {
-                if (ap)
-                        gtk_label_set_label (GTK_LABEL (widget), _("Not connected"));
-                else
-                        gtk_label_set_label (GTK_LABEL (widget), _("Out of range"));
-                gtk_widget_set_tooltip_text (widget, "");
-        } else {
-                gtk_label_set_label (GTK_LABEL (widget),
-                                     panel_device_state_to_localized_string (nm_device));
-                gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (nm_device));
-        }
-
         /* device MAC */
         str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device));
         panel_set_device_widget_details (device_wifi->priv->builder,
@@ -778,29 +571,6 @@ nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi)
                                          "strength",
                                          str);
 
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "label_device"));
-        gtk_label_set_label (GTK_LABEL (widget),
-                             priv->selected_ssid_title ? priv->selected_ssid_title : net_object_get_title (NET_OBJECT (device_wifi)));
-
-        /* only disconnect when connection active */
-        if (ap == active_ap) {
-                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                             "button_disconnect1"));
-                gtk_widget_set_sensitive (widget, state == NM_DEVICE_STATE_ACTIVATED);
-                gtk_widget_show (widget);
-                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                             "button_connect1"));
-                gtk_widget_hide (widget);
-        } else {
-                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                             "button_disconnect1"));
-                gtk_widget_hide (widget);
-                widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                             "button_connect1"));
-                gtk_widget_show (widget);
-                gtk_widget_set_sensitive (widget, ap != NULL);
-        }
-
         /* device MAC */
         if (ap != active_ap)
                 str = NULL;
@@ -814,14 +584,17 @@ nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi)
         else
                 panel_set_device_widgets (priv->builder, nm_device);
 
-        if (ap != active_ap)
-                update_last_used (device_wifi);
+        if (ap != active_ap && connection)
+                update_last_used (device_wifi, connection);
         else
                 panel_set_device_widget_details (priv->builder, "last_used", NULL);
 
+        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "heading_status"));
+        gtk_label_set_label (GTK_LABEL (widget),
+                             panel_device_state_to_localized_string (nm_device));
+
         /* update list of APs */
-        device_wifi_refresh_aps (device_wifi);
-        device_wifi_refresh_saved_connections (device_wifi);
+        populate_ap_list (device_wifi);
 }
 
 static void
@@ -847,138 +620,6 @@ device_off_toggled (GtkSwitch *sw,
         nm_client_wireless_set_enabled (client, active);
 }
 
-
-static gboolean
-find_connection_id_in_store (GtkTreeModel *model,
-                             GtkTreeIter  *iter,
-                             const gchar  *connection_id)
-{
-        gboolean found;
-        gchar *id;
-
-        found = gtk_tree_model_get_iter_first (model, iter);
-        while (found) {
-                gtk_tree_model_get (model, iter,
-                                    COLUMN_CONNECTION_ID, &id,
-                                    -1);
-                if (g_strcmp0 (connection_id, id) == 0) {
-                        g_free (id);
-                        return TRUE;
-                }
-                g_free (id);
-                found = gtk_tree_model_iter_next (model, iter);
-        }
-        return FALSE;
-}
-
-static void
-forget_network_connection_delete_cb (NMRemoteConnection *connection,
-                                     GError *error,
-                                     gpointer user_data)
-{
-        gboolean ret;
-        GtkTreeIter iter;
-        GtkTreeModel *model;
-        GtkTreeView *treeview;
-
-        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (user_data);
-
-        if (error != NULL) {
-                g_warning ("failed to delete connection %s: %s",
-                           nm_object_get_path (NM_OBJECT (connection)),
-                           error->message);
-                return;
-        }
-
-        /* remove the entry from the list */
-        treeview = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder,
-                                                         "treeview_list"));
-        model = gtk_tree_view_get_model (treeview);
-        ret = find_connection_id_in_store (model, &iter,
-                                           device_wifi->priv->selected_connection_id);
-        if (ret)
-                gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-        show_wifi_list (device_wifi);
-}
-
-static void
-forget_network_response_cb (GtkWidget *dialog,
-                            gint response,
-                            NetDeviceWifi *device_wifi)
-{
-        NMRemoteConnection *connection;
-        NMRemoteSettings *remote_settings;
-
-        if (response != GTK_RESPONSE_OK)
-                goto out;
-
-        remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
-        connection = nm_remote_settings_get_connection_by_path (remote_settings, device_wifi->priv->selected_connection_id);
-        if (connection == NULL) {
-                g_warning ("failed to get remote connection");
-                goto out;
-        }
-
-        /* delete the connection */
-        g_debug ("deleting %s", device_wifi->priv->selected_connection_id);
-        nm_remote_connection_delete (connection,
-                                     forget_network_connection_delete_cb,
-                                     device_wifi);
-out:
-        gtk_widget_destroy (dialog);
-}
-
-static void
-disconnect_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi)
-{
-        NMDevice *device;
-        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
-        if (device == NULL)
-                return;
-        nm_device_disconnect (device, NULL, NULL);
-}
-
-static void activate_connection (NetDeviceWifi *device, const gchar *id);
-
-static void
-connect_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi)
-{
-        if (device_wifi->priv->selected_connection_id)
-                activate_connection (device_wifi, device_wifi->priv->selected_connection_id);
-}
-
-static void
-forget_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi)
-{
-        gchar *ssid_pretty = NULL;
-        gchar *warning = NULL;
-        GtkWidget *dialog;
-        GtkWidget *window;
-        CcNetworkPanel *panel;
-
-        ssid_pretty = g_strdup_printf ("<b>%s</b>", device_wifi->priv->selected_ssid_title);
-        warning = g_strdup_printf (_("Network details for %s including password and any custom configuration will be lost."), ssid_pretty);
-        panel = net_object_get_panel (NET_OBJECT (device_wifi));
-        window = gtk_widget_get_toplevel (GTK_WIDGET (panel));
-        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
-                                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                         GTK_MESSAGE_OTHER,
-                                         GTK_BUTTONS_NONE,
-                                         NULL);
-        gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), warning);
-        gtk_dialog_add_buttons (GTK_DIALOG (dialog),
-                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                _("Forget"), GTK_RESPONSE_OK,
-                                NULL);
-        g_signal_connect (dialog, "response",
-                          G_CALLBACK (forget_network_response_cb), device_wifi);
-        gtk_window_present (GTK_WINDOW (dialog));
-
-        g_free (ssid_pretty);
-        g_free (warning);
-}
-
-
 static void
 connect_to_hidden_network (NetDeviceWifi *device_wifi)
 {
@@ -1029,25 +670,6 @@ connection_activate_cb (NMClient *client,
         }
 }
 
-static void
-activate_connection (NetDeviceWifi *device_wifi,
-                     const gchar   *connection_id)
-{
-        NMDevice *device;
-        NMClient *client;
-        NMRemoteSettings *settings;
-        NMRemoteConnection *connection;
-
-        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
-        client = net_object_get_client (NET_OBJECT (device_wifi));
-        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
-        connection = nm_remote_settings_get_connection_by_path (settings, connection_id);
-        nm_client_activate_connection (client,
-                                       NM_CONNECTION (connection),
-                                       device, NULL,
-                                       connection_activate_cb, device_wifi);
-}
-
 static gboolean
 is_8021x (NMDevice   *device,
           const char *ap_object_path)
@@ -1165,65 +787,6 @@ out:
         return;
 }
 
-static gint
-wireless_ap_model_sort_cb (GtkTreeModel *model,
-                           GtkTreeIter *a,
-                           GtkTreeIter *b,
-                           gpointer user_data)
-{
-        gboolean active_a;
-        gboolean active_b;
-        gboolean ap_a;
-        gboolean ap_b;
-        gchar *str_a;
-        gchar *str_b;
-        gint retval;
-        gint strength_a;
-        gint strength_b;
-
-        gtk_tree_model_get (model, a,
-                            COLUMN_SORT, &str_a,
-                            COLUMN_STRENGTH, &strength_a,
-                            COLUMN_ACTIVE, &active_a,
-                            COLUMN_AP_IN_RANGE, &ap_a,
-                            -1);
-        gtk_tree_model_get (model, b,
-                            COLUMN_SORT, &str_b,
-                            COLUMN_STRENGTH, &strength_b,
-                            COLUMN_ACTIVE, &active_b,
-                            COLUMN_AP_IN_RANGE, &ap_b,
-                            -1);
-
-        /* active entry first */
-        if (active_a) {
-                retval = -1;
-                goto out;
-        }
-
-        if (active_b) {
-                retval = 1;
-                goto out;
-        }
-
-        /* aps before connections */
-        if (ap_a && !ap_b) {
-                retval = -1;
-                goto out;
-        }
-        if (!ap_a && ap_b) {
-                retval = 1;
-                goto out;
-        }
-
-        /* case sensitive search like before */
-        retval = strength_b - strength_a;
-out:
-        g_free (str_a);
-        g_free (str_b);
-
-        return retval;
-}
-
 static GByteArray *
 ssid_to_byte_array (const gchar *ssid)
 {
@@ -1358,7 +921,7 @@ show_hotspot_ui (NetDeviceWifi *device_wifi)
 
         /* show hotspot tab */
         widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 3);
+        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1);
 
         /* force switch to on as this succeeded */
         sw = GTK_SWITCH (gtk_builder_get_object (device_wifi->priv->builder,
@@ -1605,6 +1168,14 @@ stop_hotspot_response_cb (GtkWidget *dialog, gint response, NetDeviceWifi *devic
 {
         if (response == GTK_RESPONSE_OK) {
                 stop_shared_connection (device_wifi);
+        } else {
+                GtkWidget *sw;
+
+                sw = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
+                                                         "switch_hotspot_off"));
+                device_wifi->priv->updating_device = TRUE;
+                gtk_switch_set_active (GTK_SWITCH (sw), TRUE);
+                device_wifi->priv->updating_device = FALSE;
         }
         gtk_widget_destroy (dialog);
 }
@@ -1638,205 +1209,28 @@ switch_hotspot_changed_cb (GtkSwitch *sw,
 }
 
 static void
-connect_wifi_network (NetDeviceWifi *device_wifi,
-                      GtkTreeView *tv,
-                      GtkTreePath *path)
+show_wifi_list (NetDeviceWifi *device_wifi)
 {
-        gboolean ap_in_range;
-        gchar *ap_object_path;
-        gchar *ssid;
-        gchar *connection_id;
-        GtkTreeIter iter;
-        GtkTreeModel *model;
-        NM80211Mode mode;
-
-        model = gtk_tree_view_get_model (tv);
-        gtk_tree_model_get_iter (model, &iter, path);
-
-        gtk_tree_model_get (model, &iter,
-                            COLUMN_ACCESS_POINT_ID, &ap_object_path,
-                            COLUMN_CONNECTION_ID, &connection_id,
-                            COLUMN_TITLE, &ssid,
-                            COLUMN_AP_IN_RANGE, &ap_in_range,
-                            COLUMN_MODE, &mode,
-                            -1);
-        if (ap_in_range) {
-                if (connection_id)
-                        activate_connection (device_wifi, connection_id);
-                else
-                        wireless_try_to_connect (device_wifi, ssid, ap_object_path);
-        } else {
-                g_warning ("can't connect");
-        }
-
-        g_free (ap_object_path);
-        g_free (connection_id);
-        g_free (ssid);
+        GtkWidget *widget;
+        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
+        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
 }
 
 static void
-show_wifi_details (NetDeviceWifi *device_wifi,
-                   GtkTreeView *tv,
-                   GtkTreePath *path)
+remote_settings_read_cb (NMRemoteSettings *remote_settings,
+                         NetDeviceWifi *device_wifi)
 {
-        GtkWidget *widget;
-        gboolean ret;
-        gboolean in_range;
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        gchar *path_str;
-
-        model = gtk_tree_view_get_model (tv);
-        path_str = gtk_tree_path_to_string (path);
-        ret = gtk_tree_model_get_iter_from_string (model, &iter, path_str);
-        if (!ret)
-                goto out;
+        gboolean is_hotspot;
 
-        /* get parameters about the selected connection */
-        g_free (device_wifi->priv->selected_connection_id);
-        g_free (device_wifi->priv->selected_ssid_title);
-        gtk_tree_model_get (model, &iter,
-                            COLUMN_ACCESS_POINT_ID, &device_wifi->priv->selected_ap_id,
-                            COLUMN_CONNECTION_ID, &device_wifi->priv->selected_connection_id,
-                            COLUMN_TITLE, &device_wifi->priv->selected_ssid_title,
-                            COLUMN_AP_IN_RANGE, &in_range,
-                            -1);
-        g_debug ("ssid = %s, in-range = %i",
-                 device_wifi->priv->selected_ssid_title, in_range);
+        populate_ap_list (device_wifi);
 
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
-
-        nm_device_wifi_refresh_ui (device_wifi);
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1);
-
-out:
-        g_free (path_str);
-}
-
-static void
-show_wifi_list (NetDeviceWifi *device_wifi)
-{
-        GtkWidget *widget;
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view"));
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
-}
-
-static gboolean
-arrow_visible (GtkTreeModel *model,
-               GtkTreeIter  *iter)
-{
-        gboolean active;
-        gboolean ap_is_saved;
-        gboolean ret;
-        gchar *sort;
-
-        gtk_tree_model_get (model, iter,
-                            COLUMN_ACTIVE, &active,
-                            COLUMN_AP_IS_SAVED, &ap_is_saved,
-                            COLUMN_SORT, &sort,
-                            -1);
-
-        if (active || ap_is_saved)
-                ret = TRUE;
-        else
-                ret = FALSE;
-
-        g_free (sort);
-
-        return ret;
-}
-
-static void
-set_arrow_image (GtkCellLayout   *layout,
-                 GtkCellRenderer *cell,
-                 GtkTreeModel    *model,
-                 GtkTreeIter     *iter,
-                 gpointer         user_data)
-{
-        NetDeviceWifi *device = user_data;
-        const gchar *icon;
-
-        if (arrow_visible (model, iter)) {
-                GtkWidget *widget;
-
-                widget = GTK_WIDGET (gtk_builder_get_object (device->priv->builder,
-                                                             "treeview_list"));
-
-                if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-                        icon = "go-previous";
-                else
-                        icon = "go-next";
-        }
-        else {
-                icon = "";
-        }
-
-        g_object_set (cell, "icon-name", icon, NULL);
-}
-
-static void
-edit_connection (GtkButton *button, NetDeviceWifi *device_wifi)
-{
-        net_object_edit (NET_OBJECT (device_wifi));
-}
-
-static void
-remote_settings_read_cb (NMRemoteSettings *remote_settings,
-                         NetDeviceWifi *device_wifi)
-{
-        gboolean is_hotspot;
-
-        device_wifi_refresh_saved_connections (device_wifi);
-
-        /* go straight to the hotspot UI */
-        is_hotspot = device_is_hotspot (device_wifi);
-        if (is_hotspot) {
-                nm_device_wifi_refresh_hotspot (device_wifi);
-                show_hotspot_ui (device_wifi);
-        }
-}
-
-static gboolean
-separator_visible (GtkTreeModel *model,
-                   GtkTreeIter  *iter)
-{
-        gboolean active;
-        gboolean ap_is_saved;
-        gboolean ap_in_range;
-        gchar *sort;
-        gboolean ret;
-
-        gtk_tree_model_get (model, iter,
-                            COLUMN_ACTIVE, &active,
-                            COLUMN_AP_IS_SAVED, &ap_is_saved,
-                            COLUMN_AP_IN_RANGE, &ap_in_range,
-                            COLUMN_SORT, &sort,
-                            -1);
-
-        if (!active && ap_is_saved && ap_in_range)
-                ret = TRUE;
-        else
-                ret = FALSE;
-
-        g_free (sort);
-
-        return ret;
-
-}
-
-static void
-set_draw_separator (GtkCellLayout   *layout,
-                    GtkCellRenderer *cell,
-                    GtkTreeModel    *model,
-                    GtkTreeIter     *iter,
-                    gpointer         user_data)
-{
-        gboolean draw;
-
-        draw = separator_visible (model, iter);
-
-        g_object_set (cell, "draw", draw, NULL);
-}
+        /* go straight to the hotspot UI */
+        is_hotspot = device_is_hotspot (device_wifi);
+        if (is_hotspot) {
+                nm_device_wifi_refresh_hotspot (device_wifi);
+                show_hotspot_ui (device_wifi);
+        }
+}
 
 static void
 switch_page_cb (GtkNotebook   *notebook,
@@ -1879,6 +1273,9 @@ net_device_wifi_constructed (GObject *object)
         g_signal_connect (remote_settings, "connections-read",
                           G_CALLBACK (remote_settings_read_cb), device_wifi);
 
+        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "heading_list"));
+        g_object_bind_property (device_wifi, "title", widget, "label", 0);
+
         nm_device_wifi_refresh_ui (device_wifi);
 }
 
@@ -1938,45 +1335,571 @@ net_device_wifi_class_init (NetDeviceWifiClass *klass)
 }
 
 static void
-activate_ssid_cb (PanelCellRendererText *cell,
-                  const gchar           *path,
-                  NetDeviceWifi         *device_wifi)
+really_forgotten (NMRemoteConnection *connection,
+                  GError             *error,
+                  gpointer            user_data)
+{
+        NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (user_data);
+
+        if (error != NULL) {
+                g_warning ("failed to delete connection %s: %s",
+                           nm_object_get_path (NM_OBJECT (connection)),
+                           error->message);
+                return;
+        }
+
+        /* remove the entry from the list */
+        populate_ap_list (device_wifi);
+}
+
+static void
+really_forget (GtkDialog *dialog, gint response, gpointer data)
+{
+        GtkWidget *forget = data;
+        GtkWidget *row;
+        GList *rows;
+        GList *r;
+        NMRemoteConnection *connection;
+        NetDeviceWifi *device_wifi;
+
+        gtk_widget_destroy (GTK_WIDGET (dialog));
+
+        if (response == GTK_RESPONSE_CANCEL)
+                return;
+
+        device_wifi = NET_DEVICE_WIFI (g_object_get_data (G_OBJECT (forget), "net"));
+        rows = g_object_steal_data (G_OBJECT (forget), "rows");
+        for (r = rows; r; r = r->next) {
+                row = r->data;
+                connection = g_object_get_data (G_OBJECT (row), "connection");
+                nm_remote_connection_delete (connection, really_forgotten, device_wifi);
+                gtk_widget_destroy (row);
+        }
+        g_list_free (rows);
+}
+
+static void
+forget_selected (GtkButton *forget, NetDeviceWifi *device_wifi)
+{
+        GtkWidget *window;
+        GtkWidget *dialog;
+
+        window = gtk_widget_get_toplevel (GTK_WIDGET (forget));
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                         GTK_MESSAGE_OTHER,
+                                         GTK_BUTTONS_NONE,
+                                         NULL);
+        gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
+                                       _("Network details for the selected networks, including passwords and any custom configuration will be lost."));
+
+        gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+                                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                _("_Forget"), GTK_RESPONSE_OK,
+                                NULL);
+        g_signal_connect (dialog, "response",
+                          G_CALLBACK (really_forget), forget);
+        gtk_window_present (GTK_WINDOW (dialog));
+}
+
+static void
+check_toggled (GtkToggleButton *check, GtkWidget *forget)
+{
+        gboolean active;
+        GtkWidget *row;
+        GList *rows;
+
+        row = gtk_widget_get_parent (GTK_WIDGET (check));
+        active = gtk_toggle_button_get_active (check);
+        rows = g_object_steal_data (G_OBJECT (forget), "rows");
+
+        if (active) {
+                rows = g_list_prepend (rows, row);
+        } else {
+                rows = g_list_remove (rows, row);
+        }
+
+        g_object_set_data_full (G_OBJECT (forget), "rows", rows, (GDestroyNotify)g_list_free);
+        gtk_widget_set_sensitive (forget, rows != NULL);
+}
+
+static void
+make_row (GtkSizeGroup   *rows,
+          GtkSizeGroup   *icons,
+          GtkWidget      *forget,
+          NMDevice       *device,
+          NMConnection   *connection,
+          NMAccessPoint  *ap,
+          NMAccessPoint  *active_ap,
+          GtkWidget     **row_out,
+          GtkWidget     **check_out,
+          GtkWidget     **edit_out)
+{
+        GtkWidget *row;
+        GtkWidget *widget;
+        GtkWidget *box;
+        gchar *title;
+        gboolean active;
+        gboolean in_range;
+        gboolean connecting;
+        guint security;
+        guint strength;
+        const GByteArray *ssid;
+        const gchar *icon_name;
+        guint64 timestamp;
+        GtkSizeGroup *spinner_button_group;
+        NMDeviceState state;
+
+        g_assert (connection || ap);
+
+        state = nm_device_get_state (device);
+
+        if (connection != NULL) {
+                NMSettingWireless *sw;
+                NMSettingConnection *sc;
+                sw = nm_connection_get_setting_wireless (connection);
+                ssid = nm_setting_wireless_get_ssid (sw);
+                sc = nm_connection_get_setting_connection (connection);
+                timestamp = nm_setting_connection_get_timestamp (sc);
+        } else {
+                ssid = nm_access_point_get_ssid (ap);
+                timestamp = 0;
+        }
+
+        title = g_markup_escape_text (nm_utils_escape_ssid (ssid->data, ssid->len), -1);
+
+        if (ap != NULL) {
+                in_range = TRUE;
+                active = (ap == active_ap) && (state == NM_DEVICE_STATE_ACTIVATED);
+                connecting = (ap == active_ap) &&
+                             (state == NM_DEVICE_STATE_PREPARE ||
+                              state == NM_DEVICE_STATE_CONFIG ||
+                              state == NM_DEVICE_STATE_IP_CONFIG ||
+                              state == NM_DEVICE_STATE_IP_CHECK ||
+                              state == NM_DEVICE_STATE_NEED_AUTH);
+                security = get_access_point_security (ap);
+                strength = nm_access_point_get_strength (ap);
+        } else {
+                in_range = FALSE;
+                active = FALSE;
+                connecting = FALSE;
+                security = 0;
+                strength = 0;
+        }
+
+        row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
+        gtk_widget_set_margin_left (row, 12);
+        gtk_widget_set_margin_right (row, 12);
+        gtk_size_group_add_widget (rows, row);
+
+        widget = NULL;
+        if (forget) {
+                widget = gtk_check_button_new ();
+                g_signal_connect (widget, "toggled",
+                                  G_CALLBACK (check_toggled), forget);
+                gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+                gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+                gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+        }
+        if (check_out)
+                *check_out = widget;
+
+        widget = gtk_label_new (title);
+        gtk_widget_set_margin_top (widget, 12);
+        gtk_widget_set_margin_bottom (widget, 12);
+        gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+
+        if (active) {
+                widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
+                gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+                gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+                gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+        }
+
+        gtk_box_pack_start (GTK_BOX (row), gtk_label_new (""), TRUE, FALSE, 0);
+
+        spinner_button_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
+        g_object_set_data_full (G_OBJECT (row), "spinner_button_group", spinner_button_group, g_object_unref);
+        widget = NULL;
+        if (connection) {
+                GtkWidget *image;
+                image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU);
+                gtk_widget_show (image);
+                widget = gtk_button_new ();
+                gtk_widget_set_no_show_all (widget, TRUE);
+                if (!connecting)
+                        gtk_widget_show (widget);
+                gtk_container_add (GTK_CONTAINER (widget), image);
+                gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+                gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+                gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+                gtk_size_group_add_widget (spinner_button_group, widget);
+                g_object_set_data (G_OBJECT (row), "edit", widget);
+        }
+        if (edit_out)
+                *edit_out = widget;
+
+        widget = gtk_spinner_new ();
+        gtk_widget_set_no_show_all (widget, TRUE);
+        if (connecting) {
+                gtk_widget_show (widget);
+                gtk_spinner_start (GTK_SPINNER (widget));
+        }
+        gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+        gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+        gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
+        gtk_size_group_add_widget (spinner_button_group, widget);
+        g_object_set_data (G_OBJECT (row), "spinner", widget);
+
+        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+        gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
+        gtk_size_group_add_widget (icons, box);
+        gtk_box_pack_start (GTK_BOX (row), box, FALSE, FALSE, 0);
+
+        if (in_range) {
+                if (security != NM_AP_SEC_UNKNOWN &&
+                    security != NM_AP_SEC_NONE) {
+                        widget = gtk_image_new_from_icon_name ("network-wireless-encrypted-symbolic", GTK_ICON_SIZE_MENU);
+                } else {
+                        widget = gtk_label_new ("");
+                }
+                gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
+
+                if (strength < 20)
+                        icon_name = "network-wireless-signal-none-symbolic";
+                else if (strength < 40)
+                        icon_name = "network-wireless-signal-weak-symbolic";
+                else if (strength < 50)
+                        icon_name = "network-wireless-signal-ok-symbolic";
+                else if (strength < 80)
+                        icon_name = "network-wireless-signal-good-symbolic";
+                else
+                        icon_name = "network-wireless-signal-excellent-symbolic";
+                widget = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
+                gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
+        }
+
+        gtk_widget_show_all (row);
+
+        g_free (title);
+
+        g_object_set_data (G_OBJECT (row), "ap", ap);
+        g_object_set_data (G_OBJECT (row), "connection", connection);
+
+        g_object_set_data (G_OBJECT (row), "timestamp", GUINT_TO_POINTER (timestamp));
+        g_object_set_data (G_OBJECT (row), "active", GUINT_TO_POINTER (active));
+        g_object_set_data (G_OBJECT (row), "strength", GUINT_TO_POINTER (strength));
+
+        *row_out = row;
+}
+
+static void
+update_separator (GtkWidget **separator,
+                  GtkWidget  *child,
+                  GtkWidget  *before,
+                  gpointer    user_data)
+{
+  if (before == NULL)
+    return;
+
+  if (*separator == NULL)
+    {
+      *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+      gtk_widget_show (*separator);
+      g_object_ref_sink (*separator);
+    }
+}
+
+static gint
+history_sort (gconstpointer a, gconstpointer b, gpointer data)
 {
-        GtkTreeView *tv;
-        GtkTreePath *tpath;
+        guint64 ta, tb;
+
+        ta = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "timestamp"));
+        tb = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "timestamp"));
 
-        g_debug ("activate ssid!\n");
+        if (ta > tb) return -1;
+        if (tb > ta) return 1;
 
-        tv = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder,
-                                                    "treeview_list"));
-        tpath = gtk_tree_path_new_from_string (path);
+        return 0;
+}
+
+static gint
+ap_sort (gconstpointer a, gconstpointer b, gpointer data)
+{
+        gboolean aa, ab;
+        guint sa, sb;
+
+#if 0
+        aa = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "active"));
+        ab = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "active"));
+        if (aa) return -1;
+        if (ab) return 1;
+#endif
 
-        connect_wifi_network (device_wifi, tv, tpath);
+        sa = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "strength"));
+        sb = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "strength"));
+        if (sa > sb) return -1;
+        if (sb > sa) return 1;
 
-        gtk_tree_path_free (tpath);
+        return 0;
 }
 
 static void
-activate_arrow_cb (PanelCellRendererText *cell,
-                  const gchar           *path,
-                  NetDeviceWifi         *device_wifi)
+editor_done (NetConnectionEditor *editor,
+             gboolean             success,
+             NetDeviceWifi       *device_wifi)
 {
-        GtkTreeView *tv;
-        GtkTreeModel *model;
-        GtkTreePath *tpath;
-        GtkTreeIter iter;
-
-        g_debug ("activate arrow!\n");
-
-        tv = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder,
-                                                    "treeview_list"));
-        model = gtk_tree_view_get_model (tv);
-        tpath = gtk_tree_path_new_from_string (path);
-        gtk_tree_model_get_iter (model, &iter, tpath);
-
-        if (arrow_visible (model, &iter))
-                show_wifi_details (device_wifi, tv, tpath);
-        gtk_tree_path_free (tpath);
+        g_object_unref (editor);
+}
+
+static void
+show_details_for_row (GtkButton *button, NetDeviceWifi *device_wifi)
+{
+        GtkWidget *row;
+        NMConnection *connection;
+        NMAccessPoint *ap;
+        GtkWidget *window;
+        NetConnectionEditor *editor;
+        NMClient *client;
+        NMRemoteSettings *settings;
+        NMDevice *device;
+
+        window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+        row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row"));
+        connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection"));
+        ap = NM_ACCESS_POINT (g_object_get_data (G_OBJECT (row), "ap"));
+
+        device = net_device_get_nm_device (NET_DEVICE (device_wifi));
+        client = net_object_get_client (NET_OBJECT (device_wifi));
+        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
+        editor = net_connection_editor_new (GTK_WINDOW (window), connection, device, ap, client, settings);
+        g_signal_connect (editor, "done", G_CALLBACK (editor_done), device_wifi);
+        net_connection_editor_run (editor);
+}
+
+static void
+open_history (NetDeviceWifi *device_wifi)
+{
+        GtkWidget *dialog;
+        GtkWidget *window;
+        CcNetworkPanel *panel;
+        GtkWidget *button;
+        GtkWidget *forget;
+        GtkWidget *swin;
+        NMRemoteSettings *settings;
+        GSList *connections;
+        GSList *filtered;
+        GSList *l;
+        const GPtrArray *aps;
+        GPtrArray *aps_unique = NULL;
+        NMAccessPoint *active_ap;
+        guint i;
+        NMDevice *nm_device;
+        GtkWidget *list;
+        GtkWidget *row;
+        GtkSizeGroup *rows;
+        GtkSizeGroup *icons;
+
+        dialog = gtk_dialog_new ();
+        panel = net_object_get_panel (NET_OBJECT (device_wifi));
+        window = gtk_widget_get_toplevel (GTK_WIDGET (panel));
+        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
+        gtk_window_set_title (GTK_WINDOW (dialog), _("History"));
+        gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+        gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
+
+        button = gtk_button_new_with_mnemonic (_("_Close"));
+        gtk_widget_set_can_default (button, TRUE);
+        gtk_widget_show (button);
+        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 0);
+        g_signal_connect_swapped (button, "clicked",
+                                  G_CALLBACK (gtk_widget_destroy), dialog);
+
+        forget = gtk_button_new_with_mnemonic (_("_Forget"));
+        gtk_widget_show (forget);
+        gtk_widget_set_sensitive (forget, FALSE);
+        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), forget, 0);
+        g_signal_connect (forget, "clicked",
+                          G_CALLBACK (forget_selected), device_wifi);
+        gtk_container_child_set (GTK_CONTAINER (gtk_widget_get_parent (forget)), forget, "secondary", TRUE, NULL);
+        g_object_set_data (G_OBJECT (forget), "net", device_wifi);
+
+        swin = gtk_scrolled_window_new (NULL, NULL);
+        gtk_widget_show (swin);
+        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN);
+        gtk_widget_set_margin_left (swin, 50);
+        gtk_widget_set_margin_right (swin, 50);
+        gtk_widget_set_margin_top (swin, 12);
+        gtk_widget_set_margin_bottom (swin, 12);
+        gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), swin, TRUE, TRUE, 0);
+
+        list = GTK_WIDGET (egg_list_box_new ());
+        gtk_widget_show (list);
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), history_sort, NULL, NULL);
+        egg_list_box_add_to_scrolled (EGG_LIST_BOX (list), GTK_SCROLLED_WINDOW (swin));
+
+        rows = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+        icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+        g_object_set_data_full (G_OBJECT (list), "rows", rows, g_object_unref);
+        g_object_set_data_full (G_OBJECT (list), "icons", icons, g_object_unref);
+
+        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
+
+        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
+        connections = nm_remote_settings_list_connections (settings);
+        filtered = nm_device_filter_connections (nm_device, connections);
+
+        aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device));
+        aps_unique = panel_get_strongest_unique_aps (aps);
+        active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
+
+        for (l = filtered; l; l = l->next) {
+                NMConnection *connection = l->data;
+                NMAccessPoint *ap = NULL;
+                NMSetting *setting;
+                const GByteArray *ssid;
+                if (connection_is_shared (connection))
+                        continue;
+
+                setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME);
+                ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting));
+                for (i = 0; i < aps_unique->len; i++) {
+                        const GByteArray *ssid_ap;
+                        ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i));
+                        ssid_ap = nm_access_point_get_ssid (ap);
+                        if (nm_utils_same_ssid (ssid, ssid_ap, TRUE))
+                                break;
+                        ap = NULL;
+                }
+
+                make_row (rows, icons, forget, nm_device, connection, ap, active_ap, &row, NULL, &button);
+                gtk_container_add (GTK_CONTAINER (list), row);
+                if (button) {
+                        g_signal_connect (button, "clicked",
+                                          G_CALLBACK (show_details_for_row), device_wifi);
+                        g_object_set_data (G_OBJECT (button), "row", row);
+                }
+        }
+
+        gtk_window_present (GTK_WINDOW (dialog));
+}
+
+static void
+populate_ap_list (NetDeviceWifi *device_wifi)
+{
+        GtkWidget *swin;
+        GtkWidget *list;
+        GtkSizeGroup *rows;
+        GtkSizeGroup *icons;
+        NMDevice *nm_device;
+        NMRemoteSettings *settings;
+        GSList *connections;
+        GSList *filtered;
+        GSList *l;
+        const GPtrArray *aps;
+        GPtrArray *aps_unique = NULL;
+        NMAccessPoint *active_ap;
+        guint i;
+        GtkWidget *row;
+        GtkWidget *button;
+        GList *children, *child;
+
+        swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
+                                                   "scrolledwindow_list"));
+        list = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (swin))));
+
+        children = gtk_container_get_children (GTK_CONTAINER (list));
+        for (child = children; child; child = child->next) {
+                gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (child->data));
+        }
+        g_list_free (children);
+
+        rows = GTK_SIZE_GROUP (g_object_get_data (G_OBJECT (list), "rows"));
+        icons = GTK_SIZE_GROUP (g_object_get_data (G_OBJECT (list), "icons"));
+
+        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
+
+        settings = net_object_get_remote_settings (NET_OBJECT (device_wifi));
+        connections = nm_remote_settings_list_connections (settings);
+        filtered = nm_device_filter_connections (nm_device, connections);
+
+        aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device));
+        aps_unique = panel_get_strongest_unique_aps (aps);
+        active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
+
+        for (i = 0; i < aps_unique->len; i++) {
+                const GByteArray *ssid_ap;
+                NMAccessPoint *ap;
+                NMConnection *connection = NULL;
+                ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i));
+                ssid_ap = nm_access_point_get_ssid (ap);
+                for (l = filtered; l; l = l->next) {
+                        connection = l->data;
+                        NMSetting *setting;
+                        const GByteArray *ssid;
+
+                        if (connection_is_shared (connection))
+                                continue;
+
+                        setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME);
+                        ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting));
+                        if (nm_utils_same_ssid (ssid, ssid_ap, TRUE))
+                                break;
+                        connection = NULL;
+                }
+
+                make_row (rows, icons, NULL, nm_device, connection, ap, active_ap, &row, NULL, &button);
+                gtk_container_add (GTK_CONTAINER (list), row);
+                if (button) {
+                        g_signal_connect (button, "clicked",
+                                          G_CALLBACK (show_details_for_row), device_wifi);
+                        g_object_set_data (G_OBJECT (button), "row", row);
+                }
+        }
+}
+
+static void
+ap_activated (EggListBox *list, GtkWidget *row, NetDeviceWifi *device_wifi)
+{
+        NMConnection *connection;
+        NMAccessPoint *ap;
+        NMClient *client;
+        NMDevice *nm_device;
+        GtkWidget *spinner;
+        GtkWidget *edit;
+
+        connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection"));
+        ap = NM_ACCESS_POINT (g_object_get_data (G_OBJECT (row), "ap"));
+        spinner = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "spinner"));
+        edit = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "edit"));
+
+        if (ap != NULL) {
+                gtk_widget_hide (edit);
+                gtk_widget_show (spinner);
+                gtk_spinner_start (GTK_SPINNER (spinner));
+                if (connection != NULL) {
+                        client = net_object_get_client (NET_OBJECT (device_wifi));
+                        nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi));
+                        nm_client_activate_connection (client,
+                                                       connection,
+                                                       nm_device, NULL,
+                                                       connection_activate_cb, device_wifi);
+                } else {
+                        const GByteArray *ssid;
+                        gchar *ssid_text;
+                        const gchar *object_path;
+                        ssid = nm_access_point_get_ssid (ap);
+                        ssid_text = g_markup_escape_text (nm_utils_escape_ssid (ssid->data, ssid->len), -1);
+                        object_path = nm_object_get_path (NM_OBJECT (ap));
+                        wireless_try_to_connect (device_wifi, ssid_text, object_path);
+                        g_free (ssid_text);
+                }
+        }
 }
 
 static void
@@ -1984,17 +1907,10 @@ net_device_wifi_init (NetDeviceWifi *device_wifi)
 {
         GError *error = NULL;
         GtkWidget *widget;
-        GtkCellRenderer *renderer1;
-        GtkCellRenderer *renderer2;
-        GtkCellRenderer *renderer3;
-        GtkCellRenderer *renderer4;
-        GtkCellRenderer *renderer5;
-        GtkCellRenderer *renderer6;
-        GtkCellRenderer *renderer7;
-        GtkCellRenderer *renderer8;
-        GtkTreeSortable *sortable;
-        GtkTreeViewColumn *column;
-        GtkCellArea *area;
+        GtkWidget *swin;
+        GtkWidget *list;
+        GtkSizeGroup *rows;
+        GtkSizeGroup *icons;
 
         device_wifi->priv = NET_DEVICE_WIFI_GET_PRIVATE (device_wifi);
 
@@ -2014,154 +1930,21 @@ net_device_wifi_init (NetDeviceWifi *device_wifi)
         g_signal_connect (widget, "notify::active",
                           G_CALLBACK (device_off_toggled), device_wifi);
 
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                     "button_options1"));
-        g_signal_connect (widget, "clicked",
-                          G_CALLBACK (edit_connection), device_wifi);
-
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                     "button_forget1"));
-        g_signal_connect (widget, "clicked",
-                          G_CALLBACK (forget_button_clicked_cb), device_wifi);
-
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                     "button_disconnect1"));
-        g_signal_connect (widget, "clicked",
-                          G_CALLBACK (disconnect_button_clicked_cb), device_wifi);
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                     "button_connect1"));
-        g_signal_connect (widget, "clicked",
-                          G_CALLBACK (connect_button_clicked_cb), device_wifi);
-
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                     "treeview_list"));
-
-        /* sort networks in drop down */
-        sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (device_wifi->priv->builder,
-                                                              "liststore_network"));
-        gtk_tree_sortable_set_sort_column_id (sortable,
-                                              COLUMN_SORT,
-                                              GTK_SORT_ASCENDING);
-        gtk_tree_sortable_set_sort_func (sortable,
-                                         COLUMN_SORT,
-                                         wireless_ap_model_sort_cb,
-                                         device_wifi,
-                                         NULL);
-
-
-        column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (device_wifi->priv->builder,
-                                                               "treeview_list_column"));
-        area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
-
-        renderer1 = gtk_cell_renderer_pixbuf_new ();
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer1, FALSE);
-        g_object_set (renderer1,
-                      "follow-state", TRUE,
-                      "icon-name", "object-select-symbolic",
-                      "xpad", 6,
-                      "ypad", 6,
-                      NULL);
-        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer1,
-                                        "visible", COLUMN_ACTIVE,
-                                        NULL);
-        gtk_cell_area_cell_set (area, renderer1, "align", TRUE, NULL);
-
-        renderer2 = panel_cell_renderer_text_new ();
-        g_object_set (renderer2,
-                      "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
-                      "ellipsize", PANGO_ELLIPSIZE_END,
-                      NULL);
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer2, TRUE);
-        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer2,
-                                        "markup", COLUMN_TITLE,
-                                        NULL);
-        gtk_cell_area_cell_set (area, renderer2,
-                                "align", TRUE,
-                                "expand", TRUE,
-                                NULL);
-        g_signal_connect (renderer2, "activate",
-                          G_CALLBACK (activate_ssid_cb), device_wifi);
-
-        renderer3 = panel_cell_renderer_mode_new ();
-        gtk_cell_renderer_set_padding (renderer3, 4, 0);
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column),
-                                    renderer3,
-                                    FALSE);
-        g_object_set (renderer3, "follow-state", TRUE, NULL);
-        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer3,
-                                        "ap-mode", COLUMN_MODE,
-                                        NULL);
-
-        renderer4 = gtk_cell_renderer_text_new ();
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer4, FALSE);
-        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer4,
-                                        "visible", COLUMN_AP_OUT_OF_RANGE,
-                                        NULL);
-        g_object_set (renderer4,
-                      "text", _("Out of range"),
-                      "mode", GTK_CELL_RENDERER_MODE_INERT,
-                      "xalign", 1.0,
-                      NULL);
-
-        renderer5 = panel_cell_renderer_signal_new ();
-        gtk_cell_renderer_set_padding (renderer5, 4, 0);
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column),
-                                    renderer5,
-                                    FALSE);
-        g_object_set (renderer5, "follow-state", TRUE, NULL);
-        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer5,
-                                        "signal", COLUMN_STRENGTH,
-                                        "visible", COLUMN_AP_IN_RANGE,
-                                        NULL);
-
-        renderer6 = panel_cell_renderer_security_new ();
-        gtk_cell_renderer_set_padding (renderer6, 4, 0);
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column),
-                                    renderer6,
-                                    FALSE);
-        g_object_set (renderer6, "follow-state", TRUE, NULL);
-        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer6,
-                                        "security", COLUMN_SECURITY,
-                                        "visible", COLUMN_AP_IN_RANGE,
-                                        NULL);
-
-        renderer7 = panel_cell_renderer_separator_new ();
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer7, FALSE);
-        g_object_set (renderer7,
-                      "visible", TRUE,
-                      "sensitive", FALSE,
-                      "draw", TRUE,
-                      NULL);
-        gtk_cell_renderer_set_fixed_size (renderer7, 1, -1);
-        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer7,
-                                            set_draw_separator, device_wifi, NULL);
-
-        renderer8 = panel_cell_renderer_pixbuf_new ();
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer8, FALSE);
-        g_object_set (renderer8,
-                      "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
-                      "follow-state", TRUE,
-                      "visible", TRUE,
-                      "xpad", 6,
-                      "ypad", 6,
-                      NULL);
-        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer8,
-                                            set_arrow_image, device_wifi, NULL);
-        g_signal_connect (renderer8, "activate",
-                          G_CALLBACK (activate_arrow_cb), device_wifi);
-
-        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
-                                                     "button_back1"));
-        g_signal_connect_swapped (widget, "clicked",
-                                  G_CALLBACK (show_wifi_list), device_wifi);
-
-        /* draw focus around everything but the arrow */
-        gtk_cell_area_add_focus_sibling (area, renderer2, renderer1);
-        gtk_cell_area_add_focus_sibling (area, renderer2, renderer3);
-        gtk_cell_area_add_focus_sibling (area, renderer2, renderer4);
-        gtk_cell_area_add_focus_sibling (area, renderer2, renderer5);
-        gtk_cell_area_add_focus_sibling (area, renderer2, renderer6);
-        gtk_cell_area_add_focus_sibling (area, renderer2, renderer7);
+        swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
+                                                   "scrolledwindow_list"));
+        list = GTK_WIDGET (egg_list_box_new ());
+        gtk_widget_show (list);
+        egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+        egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+        egg_list_box_set_sort_func (EGG_LIST_BOX (list), ap_sort, NULL, NULL);
+        egg_list_box_add_to_scrolled (EGG_LIST_BOX (list), GTK_SCROLLED_WINDOW (swin));
+        g_signal_connect (list, "child-activated",
+                          G_CALLBACK (ap_activated), device_wifi);
+
+        rows = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+        icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+        g_object_set_data_full (G_OBJECT (list), "rows", rows, g_object_unref);
+        g_object_set_data_full (G_OBJECT (list), "icons", icons, g_object_unref);
 
         /* setup view */
         widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
@@ -2182,6 +1965,11 @@ net_device_wifi_init (NetDeviceWifi *device_wifi)
                                   G_CALLBACK (connect_to_hidden_network), device_wifi);
 
         widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
+                                                     "history_button"));
+        g_signal_connect_swapped (widget, "clicked",
+                                  G_CALLBACK (open_history), device_wifi);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder,
                                                      "switch_hotspot_off"));
         g_signal_connect (widget, "notify::active",
                           G_CALLBACK (switch_hotspot_changed_cb), device_wifi);
diff --git a/panels/network/network-ethernet.ui b/panels/network/network-ethernet.ui
new file mode 100644
index 0000000..58abe65
--- /dev/null
+++ b/panels/network/network-ethernet.ui
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkImage" id="image1">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="icon_name">emblem-system-symbolic</property>
+  </object>
+  <object class="GtkWindow" id="window_tmp">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkVBox" id="vbox6">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <object class="GtkGrid" id="grid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="column_spacing">6</property>
+            <child>
+              <object class="GtkImage" id="image_device">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">end</property>
+                <property name="valign">start</property>
+                <property name="xalign">1</property>
+                <property name="pixel_size">48</property>
+                <property name="icon_name">network-wired</property>
+                <property name="icon-size">6</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox4">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">start</property>
+                <property name="valign">center</property>
+                <property name="hexpand">True</property>
+                <child>
+                  <object class="GtkLabel" id="label_device">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label">Wired</property>
+                    <property name="ellipsize">end</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1.2"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label_status">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label">Cable unplugged</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="list">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="margin_top">12</property>
+                <property name="hexpand">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">3</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="details">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_top">12</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="row_spacing">10</property>
+                <property name="column_spacing">10</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+                <property name="width">3</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSwitch" id="device_off_switch">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="halign">end</property>
+                <property name="valign">center</property>
+                <property name="hexpand">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">0</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="actions">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_top">18</property>
+            <child>
+              <object class="GtkButton" id="add_profile_button">
+                <property name="label" translatable="yes">_Add Profile…</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">start</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="details_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">end</property>
+                <property name="image">image1</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkSizeGroup" id="sizegroup1"/>
+</interface>
diff --git a/panels/network/network-simple.ui b/panels/network/network-simple.ui
index a5ceb47..194e25f 100644
--- a/panels/network/network-simple.ui
+++ b/panels/network/network-simple.ui
@@ -1,6 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkOffscreenWindow" id="offscreenwindow1">
+    <property name="can_focus">False</property>
+    <child>
+      <placeholder/>
+    </child>
+  </object>
   <object class="GtkWindow" id="window_tmp">
     <property name="can_focus">False</property>
     <child>
@@ -82,174 +88,6 @@
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="heading_mac">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">Hardware Address</property>
-                <property name="mnemonic_widget">label_mac</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">1</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="heading_ipv4">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">IPv4 Address</property>
-                <property name="mnemonic_widget">label_ipv4</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">3</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="heading_ipv6">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">IPv6 Address</property>
-                <property name="mnemonic_widget">label_ipv6</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">4</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="heading_route">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">Default Route</property>
-                <property name="mnemonic_widget">label_route</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">5</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="heading_dns">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="yalign">0</property>
-                <property name="label" translatable="yes">DNS</property>
-                <property name="mnemonic_widget">label_dns</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">6</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_mac">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">AA:BB:CC:DD:55:66:77:88</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">1</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_ipv4">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">127.0.0.1</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">3</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_ipv6">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">::1</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">4</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_route">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">127.0.0.1</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">5</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_dns">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="yalign">0</property>
-                <property name="label">127.0.0.1</property>
-                <property name="wrap">True</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">6</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
               <object class="GtkAlignment" id="alignment_switch">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
@@ -272,13 +110,189 @@
               </packing>
             </child>
             <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
-            </child>
-            <child>
-              <placeholder/>
+              <object class="GtkGrid" id="grid1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_top">20</property>
+                <property name="row_spacing">10</property>
+                <property name="column_spacing">6</property>
+                <property name="row_homogeneous">True</property>
+                <property name="column_homogeneous">True</property>
+                <child>
+                  <object class="GtkLabel" id="heading_mac">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Hardware Address</property>
+                    <property name="mnemonic_widget">label_mac</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="heading_ipv4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">IPv4 Address</property>
+                    <property name="mnemonic_widget">label_ipv4</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="heading_ipv6">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">IPv6 Address</property>
+                    <property name="mnemonic_widget">label_ipv6</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="heading_route">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Default Route</property>
+                    <property name="mnemonic_widget">label_route</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">3</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="heading_dns">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="yalign">0</property>
+                    <property name="label" translatable="yes">DNS</property>
+                    <property name="mnemonic_widget">label_dns</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">4</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label_mac">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label">AA:BB:CC:DD:55:66:77:88</property>
+                    <property name="selectable">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label_ipv4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label">127.0.0.1</property>
+                    <property name="selectable">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label_ipv6">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label">::1</property>
+                    <property name="selectable">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label_route">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label">127.0.0.1</property>
+                    <property name="selectable">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">3</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label_dns">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="xalign">0</property>
+                    <property name="yalign">0</property>
+                    <property name="label">127.0.0.1</property>
+                    <property name="wrap">True</property>
+                    <property name="selectable">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">4</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">3</property>
+                <property name="height">1</property>
+              </packing>
             </child>
           </object>
           <packing>
@@ -321,13 +335,5 @@
       </object>
     </child>
   </object>
-  <object class="GtkSizeGroup" id="sizegroup1">
-    <widgets>
-      <widget name="heading_mac"/>
-      <widget name="heading_ipv4"/>
-      <widget name="heading_ipv6"/>
-      <widget name="heading_route"/>
-      <widget name="heading_dns"/>
-    </widgets>
-  </object>
+  <object class="GtkSizeGroup" id="sizegroup1"/>
 </interface>
diff --git a/panels/network/network-wifi.ui b/panels/network/network-wifi.ui
index cbb4354..fa3a055 100644
--- a/panels/network/network-wifi.ui
+++ b/panels/network/network-wifi.ui
@@ -1,79 +1,25 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
-  <object class="GtkDialog" id="hotspot-dialog">
+  <object class="GtkDialog" id="details_dialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
     <property name="modal">True</property>
-    <property name="destroy_with_parent">True</property>
+    <property name="default_width">600</property>
+    <property name="default_height">300</property>
     <property name="type_hint">dialog</property>
     <child internal-child="vbox">
-      <object class="GtkBox" id="hotspot-dialog-vbox1">
+      <object class="GtkBox" id="dialog-vbox2">
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
-        <property name="spacing">14</property>
-        <child>
-          <object class="GtkBox" id="hotspot-dialog-box1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="border_width">5</property>
-            <property name="spacing">12</property>
-            <child>
-              <object class="GtkImage" id="hotspot-dialog-image">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="icon_name">network-wireless</property>
-                <property name="icon-size">6</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="hotspot-dialog-title">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Wi-Fi Hotspot</property>
-                <attributes>
-                  <attribute name="weight" value="bold"/>
-                  <attribute name="scale" value="1.2"/>
-                </attributes>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="hotspot-dialog-content">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="wrap">True</property>
-            <property name="width_chars">60</property>
-            <property name="max_width_chars">60</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
+        <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkButtonBox" id="hotspot-dialog-action_area1">
+          <object class="GtkButtonBox" id="dialog-action_area2">
             <property name="can_focus">False</property>
+            <property name="valign">end</property>
             <property name="layout_style">end</property>
             <child>
-              <object class="GtkButton" id="hotspot-cancel-button">
+              <object class="GtkButton" id="details_cancel_button">
                 <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
@@ -83,23 +29,21 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="position">0</property>
+                <property name="position">2</property>
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="hotspot-turn-on-button">
-                <property name="label" translatable="yes">_Turn On</property>
+              <object class="GtkButton" id="details_apply_button">
+                <property name="label">gtk-apply</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_underline">True</property>
+                <property name="use_stock">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="position">1</property>
+                <property name="position">3</property>
               </packing>
             </child>
           </object>
@@ -107,144 +51,48 @@
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="pack_type">end</property>
-            <property name="position">2</property>
+            <property name="position">0</property>
           </packing>
         </child>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="-6">hotspot-cancel-button</action-widget>
-      <action-widget response="-5">hotspot-turn-on-button</action-widget>
-    </action-widgets>
-  </object>
-  <object class="GtkListStore" id="liststore_network">
-    <columns>
-      <!-- column-name ap-id -->
-      <column type="gchararray"/>
-      <!-- column-name connection-id -->
-      <column type="gchararray"/>
-      <!-- column-name title -->
-      <column type="gchararray"/>
-      <!-- column-name sortable -->
-      <column type="gchararray"/>
-      <!-- column-name strength -->
-      <column type="guint"/>
-      <!-- column-name mode -->
-      <column type="guint"/>
-      <!-- column-name security -->
-      <column type="guint"/>
-      <!-- column-name active -->
-      <column type="gboolean"/>
-      <!-- column-name ap-in-range -->
-      <column type="gboolean"/>
-      <!-- column-name ap-out-of-range -->
-      <column type="gboolean"/>
-      <!-- column-name is-saved -->
-      <column type="gboolean"/>
-    </columns>
-  </object>
-  <object class="GtkWindow" id="window_tmp">
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkNotebook" id="notebook_view">
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
         <child>
-          <object class="GtkBox" id="box3">
+          <object class="GtkBox" id="box6">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
             <child>
-              <object class="GtkBox" id="box_list">
+              <object class="GtkScrolledWindow" id="details_sidebar">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="margin_bottom">12</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <object class="GtkBox" id="box_list_heading">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_right">12</property>
-                    <property name="margin_top">12</property>
-                    <property name="margin_bottom">12</property>
-                    <child>
-                      <object class="GtkLabel" id="heading_list">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="halign">start</property>
-                        <property name="hexpand">True</property>
-                        <property name="label" translatable="yes">Wi-Fi</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                          <attribute name="scale" value="1.2"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkSwitch" id="device_off_switch">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="halign">end</property>
-                        <property name="valign">start</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="shadow_type">in</property>
                 <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow_list">
-                    <property name="height_request">300</property>
+                  <object class="GtkTreeView" id="details_page_list">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_right">12</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <property name="shadow_type">in</property>
-                    <property name="hscrollbar_policy">never</property>
+                    <property name="model">details_store</property>
+                    <property name="headers_visible">False</property>
+                    <property name="headers_clickable">False</property>
+                    <property name="search_column">0</property>
+                    <child internal-child="selection">
+                      <object class="GtkTreeSelection" id="details_page_list_selection"/>
+                    </child>
                     <child>
-                      <object class="GtkTreeView" id="treeview_list">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="vexpand">True</property>
-                        <property name="model">liststore_network</property>
-                        <property name="headers_visible">False</property>
-                        <property name="headers_clickable">False</property>
-                        <property name="search_column">0</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection" id="treeview-selection1">
-                            <property name="mode">none</property>
+                      <object class="GtkTreeViewColumn" id="details_column">
+                        <child>
+                          <object class="GtkCellRendererText" id="details_cell">
+                            <property name="xpad">10</property>
                           </object>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
                         </child>
                         <child>
-                          <object class="GtkTreeViewColumn" id="treeview_list_column">
-                            <property name="title">Column</property>
+                          <object class="GtkCellRendererText" id="padding_cell">
+                            <property name="xpad">20</property>
                           </object>
                         </child>
                       </object>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
               <packing>
@@ -254,502 +102,1618 @@
               </packing>
             </child>
             <child>
-              <object class="GtkBox" id="list_actions">
-                <property name="visible">True</property>
-                <property name="orientation">horizontal</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkButton" id="start_hotspot_button">
-                    <property name="label" translatable="yes">_Use as Hotspot…</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="halign">start</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_bottom">12</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="connect_hidden_button">
-                    <property name="label" translatable="yes">_Connect to Hidden Network…</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="halign">start</property>
-                    <property name="margin_left">12</property>
-                    <property name="margin_bottom">12</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-              </packing>
-            </child>
-          </object>
-        </child>
-        <child type="tab">
-          <object class="GtkLabel" id="label1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label">list</property>
-          </object>
-          <packing>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkVBox" id="vbox5">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="border_width">12</property>
-            <property name="spacing">6</property>
-            <child>
-              <object class="GtkGrid" id="grid2">
+              <object class="GtkNotebook" id="details_notebook">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="valign">start</property>
-                <property name="row_spacing">10</property>
-                <property name="column_spacing">6</property>
+                <property name="can_focus">True</property>
+                <property name="show_tabs">False</property>
+                <property name="show_border">False</property>
                 <child>
-                  <object class="GtkVBox" id="vbox3">
+                  <object class="GtkBox" id="box8">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="valign">start</property>
-                    <property name="hexpand">True</property>
-                    <property name="spacing">3</property>
+                    <property name="orientation">vertical</property>
                     <child>
-                      <object class="GtkLabel" id="label_device">
+                      <object class="GtkBox" id="auto_connect_box">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Wi-Fi</property>
-                        <property name="ellipsize">end</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                          <attribute name="scale" value="1.2"/>
-                        </attributes>
+                        <property name="halign">end</property>
+                        <property name="valign">center</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label8">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">Automatic _Connect</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">automatic_connect_switch</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSwitch" id="automatic_connect_switch">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="label_status">
+                      <object class="GtkGrid" id="grid1">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label">Not connected</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                        <property name="valign">start</property>
+                        <property name="margin_left">50</property>
+                        <property name="margin_right">50</property>
+                        <property name="margin_top">12</property>
+                        <property name="margin_bottom">12</property>
+                        <property name="hexpand">True</property>
+                        <property name="vexpand">True</property>
+                        <property name="row_spacing">10</property>
+                        <property name="column_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="heading_strength">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Signal Strength</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_strength">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">Weak</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">0</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_speed">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Link speed</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_speed">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">1Mb/sec</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">1</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_security">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Security</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">2</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_ipv4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">IPv4 Address</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">3</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_ipv6">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">IPv6 Address</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">4</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_mac">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Hardware Address</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">5</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_route">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Default Route</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">6</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_dns">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="yalign">0</property>
+                            <property name="label" translatable="yes">DNS</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">7</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="heading_last_used">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Last used</property>
+                            <style>
+                              <class name="dim-label"/>
+                            </style>
+                          </object>
+                          <packing>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">8</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_security">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">WPA</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">2</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_ipv4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">127.0.0.1</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">3</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_ipv6">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">::1</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">4</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_mac">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">AA:BB:CC:DD:55:66:77:88</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">5</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_route">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">127.0.0.1</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">6</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_dns">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="yalign">0</property>
+                            <property name="label">127.0.0.1</property>
+                            <property name="wrap">True</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">7</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label_last_used">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label">today</property>
+                            <property name="selectable">True</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="top_attach">8</property>
+                            <property name="width">1</property>
+                            <property name="height">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+                <child type="tab">
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">details</property>
+                  </object>
+                  <packing>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="box5">
+                  <object class="GtkGrid" id="grid3">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="orientation">vertical</property>
+                    <property name="margin_left">50</property>
+                    <property name="margin_right">50</property>
+                    <property name="margin_top">12</property>
+                    <property name="margin_bottom">12</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="row_spacing">10</property>
+                    <property name="column_spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_ssid">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_SSID</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">entry_ssid</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
                     <child>
-                      <object class="GtkButton" id="button_disconnect1">
-                        <property name="label" translatable="yes">_Disconnect</property>
+                      <object class="GtkLabel" id="heading_bssid">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_BSSID</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">entry_bssid</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="heading_sec">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">S_ecurity</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">combo_sec</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_password">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_Password</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">entry_password</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">3</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_ssid">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="no_show_all">True</property>
-                        <property name="halign">end</property>
-                        <property name="valign">center</property>
                         <property name="hexpand">True</property>
-                        <property name="use_underline">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">My Home Network</property>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkButton" id="button_connect1">
-                        <property name="label" translatable="yes">_Connect</property>
+                      <object class="GtkEntry" id="entry_bssid">
+                        <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="no_show_all">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="invisible_char">●</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBoxText" id="combo_sec">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="entry_text_column">0</property>
+                        <property name="id_column">1</property>
+                        <items>
+                          <item translatable="yes">WPA</item>
+                          <item translatable="yes">None</item>
+                        </items>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">2</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_password">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="visibility">False</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">blablabla</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">3</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="show_password_check">
+                        <property name="label" translatable="yes">Show P_assword</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="valign">center</property>
                         <property name="use_underline">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">4</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkLabel" id="label9">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">4</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkCheckButton" id="all_user_check">
+                        <property name="label" translatable="yes">Make available to other users</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="valign">end</property>
+                        <property name="vexpand">True</property>
+                        <property name="xalign">0</property>
+                        <property name="draw_indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">5</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </object>
                   <packing>
-                    <property name="left_attach">2</property>
-                    <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="heading_last_used">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">Last used</property>
-                    <property name="mnemonic_widget">label_last_used</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_last_used">
-                    <property name="visible">True</property>
-                    <property name="selectable">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">today</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">3</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="heading_mac">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">Hardware Address</property>
-                    <property name="mnemonic_widget">label_mac</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_mac">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">AA:BB:CC:DD:55:66:77:88</property>
-                    <property name="selectable">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">1</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel" id="heading_security">
+                <child type="tab">
+                  <object class="GtkLabel" id="label6">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">Security</property>
-                    <property name="mnemonic_widget">label_security</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
+                    <property name="label" translatable="yes">identity</property>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">2</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="position">1</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="label_security">
+                  <object class="GtkScrolledWindow" id="scrolledwindow1">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">WPA</property>
-                    <property name="selectable">True</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <child>
+                      <object class="GtkViewport" id="viewport1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkBox" id="box2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="margin_left">20</property>
+                            <property name="margin_right">20</property>
+                            <property name="margin_top">10</property>
+                            <property name="margin_bottom">10</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">10</property>
+                            <child>
+                              <object class="GtkBox" id="box5">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkLabel" id="heading_ipv4_ipv4">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">IPv_4</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">switch_ipv4_ipv4</property>
+                                    <attributes>
+                                      <attribute name="weight" value="bold"/>
+                                    </attributes>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkSwitch" id="switch_ipv4_ipv4">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="halign">end</property>
+                                    <property name="hexpand">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="box7">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkLabel" id="heading_ipv4_addresses">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">_Addresses</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">combo_ipv4_addresses</property>
+                                    <attributes>
+                                      <attribute name="weight" value="bold"/>
+                                    </attributes>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkComboBoxText" id="combo_ipv4_addresses">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="halign">end</property>
+                                    <property name="hexpand">True</property>
+                                    <property name="entry_text_column">0</property>
+                                    <property name="id_column">1</property>
+                                    <items>
+                                      <item translatable="yes">Manual</item>
+                                      <item translatable="yes">Automatic (DHCP)</item>
+                                      <item translatable="yes">Automatic (DHCP) addresses only</item>
+                                      <item translatable="yes">Link-local only</item>
+                                      <item translatable="yes">Shared with other computers</item>
+                                      <item translatable="yes">Disabled</item>
+                                    </items>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="details_ipv4_address_section">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <child>
+                                  <object class="GtkLabel" id="label10">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">Address
+section
+goes
+here</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="details_ipv4_dns_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_top">24</property>
+                                <property name="margin_bottom">6</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">DNS</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="details_ipv4_dns_section">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <child>
+                                  <object class="GtkLabel" id="label11">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">DNS
+section
+goes
+here</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">4</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="details_ipv4_routes_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_top">24</property>
+                                <property name="margin_bottom">6</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Routes</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">5</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="details_ipv4_routes_section">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <child>
+                                  <object class="GtkLabel" id="label12">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">Routes
+section
+goes
+here</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">6</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="details_ipv4_auto_routes_check">
+                                <property name="label" translatable="yes">_Ignore automatically obtained routes</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">7</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="details_ipv4_network_resources_check">
+                                <property name="label" translatable="yes">Use this connection _only for resources on its network</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">8</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">2</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel" id="heading_strength">
+                <child type="tab">
+                  <object class="GtkLabel" id="label7">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">Strength</property>
-                    <property name="mnemonic_widget">label_strength</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
+                    <property name="label" translatable="yes">ipv4</property>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="position">2</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="label_strength">
+                  <object class="GtkScrolledWindow" id="scrolledwindow2">
                     <property name="visible">True</property>
-                    <property name="selectable">True</property>
                     <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">Weak</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <object class="GtkViewport" id="viewport2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkBox" id="box10">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">10</property>
+                            <child>
+                              <object class="GtkBox" id="box11">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkLabel" id="heading_ipv6_ipv6">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">IPv_6</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">switch_ipv6_ipv6</property>
+                                    <attributes>
+                                      <attribute name="weight" value="bold"/>
+                                    </attributes>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkSwitch" id="switch_ipv6_ipv6">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="halign">end</property>
+                                    <property name="hexpand">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="box12">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkLabel" id="heading_ipv6_addresses">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">_Addresses</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">combo_ipv6_addresses</property>
+                                    <attributes>
+                                      <attribute name="weight" value="bold"/>
+                                    </attributes>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkComboBoxText" id="combo_ipv6_addresses">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="halign">end</property>
+                                    <property name="hexpand">True</property>
+                                    <property name="entry_text_column">0</property>
+                                    <property name="id_column">1</property>
+                                    <items>
+                                      <item translatable="yes">Manual</item>
+                                      <item translatable="yes">Automatic (DHCP)</item>
+                                      <item translatable="yes">Automatic (DHCP) addresses only</item>
+                                      <item translatable="yes">Link-local only</item>
+                                      <item translatable="yes">Shared with other computers</item>
+                                      <item translatable="yes">Disabled</item>
+                                    </items>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="details_ipv6_address_section">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <child>
+                                  <object class="GtkLabel" id="label13">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">Address
+section
+goes
+here</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="details_ipv6_dns_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_top">24</property>
+                                <property name="margin_bottom">6</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">DNS</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="details_ipv6_dns_section">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <child>
+                                  <object class="GtkLabel" id="label14">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">DNS
+section
+goes
+here</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">4</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="details_ipv6_routes_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_top">24</property>
+                                <property name="margin_bottom">6</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Routes</property>
+                                <attributes>
+                                  <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">5</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="details_ipv6_routes_section">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="orientation">vertical</property>
+                                <child>
+                                  <object class="GtkLabel" id="label15">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">Routes
+section
+goes
+here</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">6</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="details_ipv6_auto_routes_check">
+                                <property name="label" translatable="yes">_Ignore automatically obtained routes</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">7</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="details_ipv6_network_resources_check">
+                                <property name="label" translatable="yes">Use this connection _only for resources on its network</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">8</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel" id="heading_speed">
+                <child type="tab">
+                  <object class="GtkLabel" id="label2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">Link speed</property>
-                    <property name="mnemonic_widget">label_speed</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">5</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_speed">
-                    <property name="visible">True</property>
-                    <property name="selectable">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">1Mb/sec</property>
+                    <property name="label" translatable="yes">ipv6</property>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">5</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">3</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="heading_ipv4">
+                  <object class="GtkGrid" id="grid4">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">IPv4 Address</property>
-                    <property name="mnemonic_widget">label_ipv4</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">6</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_ipv4">
-                    <property name="visible">True</property>
-                    <property name="selectable">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">127.0.0.1</property>
+                    <property name="margin_left">50</property>
+                    <property name="margin_right">50</property>
+                    <property name="margin_top">12</property>
+                    <property name="margin_bottom">12</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="row_spacing">10</property>
+                    <property name="column_spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="heading_hw_mac">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_MAC Address</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">label_hw_mac</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="heading_hw_cloned_mac">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_Cloned MAC Address</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">entry_hw_cloned_mac</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_hw_mac">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">00:24:16:31:8G:7A</property>
+                        <property name="selectable">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_hw_cloned_mac">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="invisible_char">●</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">6</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">4</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel" id="heading_ipv6">
+                <child type="tab">
+                  <object class="GtkLabel" id="label3">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">IPv6 Address</property>
-                    <property name="mnemonic_widget">label_ipv6</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
+                    <property name="label" translatable="yes">hardware</property>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">7</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_ipv6">
-                    <property name="visible">True</property>
-                    <property name="selectable">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">::1</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">7</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">4</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkLabel" id="heading_route">
+                  <object class="GtkGrid" id="grid5">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">Default Route</property>
-                    <property name="mnemonic_widget">label_route</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">8</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_route">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label">127.0.0.1</property>
-                    <property name="selectable">True</property>
+                    <property name="margin_left">50</property>
+                    <property name="margin_right">50</property>
+                    <property name="margin_top">12</property>
+                    <property name="margin_bottom">12</property>
+                    <property name="row_spacing">10</property>
+                    <property name="column_spacing">10</property>
+                    <child>
+                      <object class="GtkButton" id="button_reset">
+                        <property name="label" translatable="yes">_Reset</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="valign">start</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="button_forget">
+                        <property name="label" translatable="yes">_Forget</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="valign">start</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">0</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_reset">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Reset the settings for this connection to their defaults, but remember as a preferred connection.</property>
+                        <property name="wrap">True</property>
+                        <property name="max_width_chars">40</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_forget">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="hexpand">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Remove all details relating to this network and do not try to automatically connect to it.</property>
+                        <property name="wrap">True</property>
+                        <property name="max_width_chars">30</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">1</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">8</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">5</property>
                   </packing>
                 </child>
-                <child>
-                  <object class="GtkLabel" id="heading_dns">
+                <child type="tab">
+                  <object class="GtkLabel" id="label5">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">1</property>
-                    <property name="yalign">0</property>
-                    <property name="label" translatable="yes">DNS</property>
-                    <property name="mnemonic_widget">label_dns</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">9</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label_dns">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                    <property name="label">127.0.0.1</property>
-                    <property name="wrap">True</property>
-                    <property name="selectable">True</property>
+                    <property name="label" translatable="yes">reset</property>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">9</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
+                    <property name="position">5</property>
+                    <property name="tab_fill">False</property>
                   </packing>
                 </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">details_cancel_button</action-widget>
+      <action-widget response="0">details_apply_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkListStore" id="details_store">
+    <columns>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name page -->
+      <column type="gint"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Details</col>
+        <col id="1">0</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Identity</col>
+        <col id="1">1</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">IPv4</col>
+        <col id="1">2</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">IPv6</col>
+        <col id="1">3</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Hardware</col>
+        <col id="1">4</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Reset</col>
+        <col id="1">5</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkDialog" id="hotspot-dialog">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="hotspot-dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">14</property>
+        <child>
+          <object class="GtkBox" id="hotspot-dialog-box1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="border_width">5</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkImage" id="hotspot-dialog-image">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="icon_name">network-wireless</property>
+                <property name="icon-size">6</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="hotspot-dialog-title">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Wi-Fi Hotspot</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                  <attribute name="scale" value="1.2"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="hotspot-dialog-content">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="wrap">True</property>
+            <property name="width_chars">60</property>
+            <property name="max_width_chars">60</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="hotspot-dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="hotspot-cancel-button">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="hotspot-turn-on-button">
+                <property name="label" translatable="yes">_Turn On</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">hotspot-cancel-button</action-widget>
+      <action-widget response="-5">hotspot-turn-on-button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkWindow" id="window_tmp">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkNotebook" id="notebook_view">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="show_tabs">False</property>
+        <property name="show_border">False</property>
+        <child>
+          <object class="GtkBox" id="box3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkBox" id="box_list">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_bottom">18</property>
+                <property name="orientation">vertical</property>
                 <child>
-                  <object class="GtkBox" id="box1">
+                  <object class="GtkBox" id="box_list_heading">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="orientation">vertical</property>
+                    <property name="margin_left">12</property>
+                    <property name="margin_right">12</property>
+                    <property name="margin_top">12</property>
+                    <property name="margin_bottom">12</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <object class="GtkButton" id="button_back1">
+                      <object class="GtkImage" id="heading_image">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="halign">start</property>
-                        <property name="valign">center</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">network-wireless</property>
+                        <property name="icon-size">6</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="box4">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="hexpand">True</property>
+                        <property name="orientation">vertical</property>
+                        <child>
+                          <object class="GtkLabel" id="heading_list">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Wi-Fi</property>
+                            <attributes>
+                              <attribute name="weight" value="bold"/>
+                              <attribute name="scale" value="1.2"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
                         <child>
-                          <object class="GtkArrow" id="arrow1">
+                          <object class="GtkLabel" id="heading_status">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="arrow_type">left</property>
+                            <property name="xalign">0</property>
+                            <property name="label">Connected</property>
                           </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
                       <packing>
                         <property name="expand">False</property>
                         <property name="fill">True</property>
-                        <property name="position">0</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
-                      <placeholder/>
+                      <object class="GtkSwitch" id="device_off_switch">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="halign">end</property>
+                        <property name="valign">center</property>
+                        <property name="hexpand">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="expand">True</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScrolledWindow" id="scrolledwindow_list">
+                    <property name="height_request">300</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="margin_left">12</property>
+                    <property name="margin_right">12</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="shadow_type">in</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </object>
@@ -760,85 +1724,75 @@
               </packing>
             </child>
             <child>
-              <object class="GtkBox" id="box2">
+              <object class="GtkBox" id="list_actions">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="margin_top">12</property>
+                <property name="margin_left">12</property>
+                <property name="margin_right">12</property>
+                <property name="margin_bottom">12</property>
+                <property name="hexpand">True</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkButton" id="button_forget1">
-                    <property name="label" translatable="yes">_Forget Network</property>
+                  <object class="GtkButton" id="start_hotspot_button">
+                    <property name="label" translatable="yes">_Use as Hotspot…</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="halign">start</property>
-                    <property name="valign">end</property>
                     <property name="use_underline">True</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">True</property>
+                    <property name="fill">False</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkButton" id="button_options1">
-                    <property name="label" translatable="yes">_Settings…</property>
+                  <object class="GtkButton" id="connect_hidden_button">
+                    <property name="label" translatable="yes">_Connect to Hidden Network…</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">center</property>
+                    <property name="use_underline">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="history_button">
+                    <property name="label" translatable="yes">_History</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="halign">end</property>
-                    <property name="valign">end</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
                     <property name="use_underline">True</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="fill">True</property>
+                    <property name="fill">False</property>
                     <property name="position">2</property>
                   </packing>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
+                <property name="expand">False</property>
                 <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
           </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child type="tab">
-          <object class="GtkLabel" id="label2">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label">details</property>
-          </object>
-          <packing>
-            <property name="position">1</property>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="label5">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label">label</property>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
         </child>
         <child type="tab">
-          <object class="GtkLabel" id="label3">
+          <object class="GtkLabel" id="label1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="label">hidden</property>
+            <property name="label">list</property>
           </object>
           <packing>
-            <property name="position">2</property>
             <property name="tab_fill">False</property>
           </packing>
         </child>
@@ -1067,7 +2021,7 @@
             </child>
           </object>
           <packing>
-            <property name="position">3</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child type="tab">
@@ -1077,7 +2031,7 @@
             <property name="label">hotspot</property>
           </object>
           <packing>
-            <property name="position">3</property>
+            <property name="position">1</property>
             <property name="tab_fill">False</property>
           </packing>
         </child>
diff --git a/panels/network/panel-cell-renderer-mode.c b/panels/network/panel-cell-renderer-mode.c
deleted file mode 100644
index 7bc443d..0000000
--- a/panels/network/panel-cell-renderer-mode.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "panel-cell-renderer-mode.h"
-
-enum {
-        PROP_0,
-        PROP_AP_MODE,
-        PROP_LAST
-};
-
-G_DEFINE_TYPE (PanelCellRendererMode, panel_cell_renderer_mode, GTK_TYPE_CELL_RENDERER_PIXBUF)
-
-static gpointer parent_class = NULL;
-
-/**
- * panel_cell_renderer_mode_get_property:
- **/
-static void
-panel_cell_renderer_mode_get_property (GObject *object, guint param_id,
-                                       GValue *value, GParamSpec *pspec)
-{
-        PanelCellRendererMode *renderer = PANEL_CELL_RENDERER_MODE (object);
-
-        switch (param_id) {
-        case PROP_AP_MODE:
-                g_value_set_uint (value, renderer->mode);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-/**
- * panel_cell_renderer_set_name:
- **/
-static void
-panel_cell_renderer_set_name (PanelCellRendererMode *renderer)
-{
-        const gchar *icon_name = NULL;
-
-        if (renderer->mode == NM_802_11_MODE_ADHOC)
-                icon_name = "network-workgroup-symbolic";
-
-        g_object_set (renderer, "icon-name", icon_name, NULL);
-}
-
-/**
- * panel_cell_renderer_mode_set_property:
- **/
-static void
-panel_cell_renderer_mode_set_property (GObject *object, guint param_id,
-                                       const GValue *value, GParamSpec *pspec)
-{
-        PanelCellRendererMode *renderer = PANEL_CELL_RENDERER_MODE (object);
-
-        switch (param_id) {
-        case PROP_AP_MODE:
-                renderer->mode = g_value_get_uint (value);
-                panel_cell_renderer_set_name (renderer);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-/**
- * panel_cell_renderer_finalize:
- **/
-static void
-panel_cell_renderer_finalize (GObject *object)
-{
-        PanelCellRendererMode *renderer;
-        renderer = PANEL_CELL_RENDERER_MODE (object);
-        g_free (renderer->icon_name);
-        G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * panel_cell_renderer_mode_class_init:
- **/
-static void
-panel_cell_renderer_mode_class_init (PanelCellRendererModeClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-        object_class->finalize = panel_cell_renderer_finalize;
-
-        parent_class = g_type_class_peek_parent (class);
-
-        object_class->get_property = panel_cell_renderer_mode_get_property;
-        object_class->set_property = panel_cell_renderer_mode_set_property;
-
-        g_object_class_install_property (object_class, PROP_AP_MODE,
-                                         g_param_spec_uint ("ap-mode", NULL,
-                                                            NULL,
-                                                            0, G_MAXUINT, 0,
-                                                            G_PARAM_READWRITE));
-}
-
-/**
- * panel_cell_renderer_mode_init:
- **/
-static void
-panel_cell_renderer_mode_init (PanelCellRendererMode *renderer)
-{
-        renderer->mode = 0;
-        renderer->icon_name = NULL;
-}
-
-/**
- * panel_cell_renderer_mode_new:
- **/
-GtkCellRenderer *
-panel_cell_renderer_mode_new (void)
-{
-        return g_object_new (PANEL_TYPE_CELL_RENDERER_MODE, NULL);
-}
-
diff --git a/panels/network/panel-cell-renderer-mode.h b/panels/network/panel-cell-renderer-mode.h
deleted file mode 100644
index 3c18f6e..0000000
--- a/panels/network/panel-cell-renderer-mode.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- */
-
-#ifndef PANEL_CELL_RENDERER_MODE_H
-#define PANEL_CELL_RENDERER_MODE_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "nm-device.h"
-#include "nm-access-point.h"
-
-#define PANEL_TYPE_CELL_RENDERER_MODE           (panel_cell_renderer_mode_get_type())
-#define PANEL_CELL_RENDERER_MODE(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_MODE, PanelCellRendererMode))
-#define PANEL_CELL_RENDERER_MODE_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_MODE, PanelCellRendererModeClass))
-#define PANEL_IS_CELL_RENDERER_MODE(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_MODE))
-#define PANEL_IS_CELL_RENDERER_MODE_CLASS(cls)  (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_MODE))
-#define PANEL_CELL_RENDERER_MODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_MODE, PanelCellRendererModeClass))
-
-G_BEGIN_DECLS
-
-typedef struct _PanelCellRendererMode           PanelCellRendererMode;
-typedef struct _PanelCellRendererModeClass      PanelCellRendererModeClass;
-
-struct _PanelCellRendererMode
-{
-        GtkCellRendererPixbuf    parent;
-        guint                    mode;
-        gchar                   *icon_name;
-};
-
-struct _PanelCellRendererModeClass
-{
-        GtkCellRendererPixbufClass parent_class;
-};
-
-GType            panel_cell_renderer_mode_get_type      (void);
-GtkCellRenderer *panel_cell_renderer_mode_new           (void);
-
-G_END_DECLS
-
-#endif /* PANEL_CELL_RENDERER_MODE_H */
-
diff --git a/panels/network/panel-cell-renderer-pixbuf.c b/panels/network/panel-cell-renderer-pixbuf.c
deleted file mode 100644
index 72650c9..0000000
--- a/panels/network/panel-cell-renderer-pixbuf.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Pixbuf: C; tab-width: 8; indent-tabs-pixbuf: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- *
- * Written by Matthias Clasen
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "panel-cell-renderer-pixbuf.h"
-
-enum {
-        ACTIVATE,
-        LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PanelCellRendererPixbuf, panel_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER_PIXBUF)
-
-static gint
-activate (GtkCellRenderer      *cell,
-          GdkEvent             *event,
-          GtkWidget            *widget,
-          const gchar          *path,
-          const GdkRectangle   *background_area,
-          const GdkRectangle   *cell_area,
-          GtkCellRendererState  flags)
-{
-        g_signal_emit (cell,  signals[ACTIVATE], 0, path);
-
-        return TRUE;
-}
-
-static void
-panel_cell_renderer_pixbuf_class_init (PanelCellRendererPixbufClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-        GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
-
-        cell_renderer_class->activate = activate;
-
-        signals[ACTIVATE] =
-                g_signal_new ("activate",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (PanelCellRendererPixbufClass, activate),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__STRING,
-                              G_TYPE_NONE, 1, G_TYPE_STRING);
-}
-
-static void
-panel_cell_renderer_pixbuf_init (PanelCellRendererPixbuf *renderer)
-{
-}
-
-GtkCellRenderer *
-panel_cell_renderer_pixbuf_new (void)
-{
-        return g_object_new (PANEL_TYPE_CELL_RENDERER_PIXBUF, NULL);
-}
diff --git a/panels/network/panel-cell-renderer-pixbuf.h b/panels/network/panel-cell-renderer-pixbuf.h
deleted file mode 100644
index 839af92..0000000
--- a/panels/network/panel-cell-renderer-pixbuf.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Pixbuf: C; tab-width: 8; indent-tabs-pixbuf: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- *
- * Written by Matthias Clasen
- */
-
-#ifndef PANEL_CELL_RENDERER_PIXBUF_H
-#define PANEL_CELL_RENDERER_PIXBUF_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#define PANEL_TYPE_CELL_RENDERER_PIXBUF           (panel_cell_renderer_pixbuf_get_type())
-#define PANEL_CELL_RENDERER_PIXBUF(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_PIXBUF, PanelCellRendererPixbuf))
-#define PANEL_CELL_RENDERER_PIXBUF_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_PIXBUF, PanelCellRendererPixbufClass))
-#define PANEL_IS_CELL_RENDERER_PIXBUF(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_PIXBUF))
-#define PANEL_IS_CELL_RENDERER_PIXBUF_CLASS(cls)  (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_PIXBUF))
-#define PANEL_CELL_RENDERER_PIXBUF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_PIXBUF, PanelCellRendererPixbufClass))
-
-G_BEGIN_DECLS
-
-typedef struct _PanelCellRendererPixbuf           PanelCellRendererPixbuf;
-typedef struct _PanelCellRendererPixbufClass      PanelCellRendererPixbufClass;
-
-struct _PanelCellRendererPixbuf
-{
-        GtkCellRendererPixbuf parent;
-};
-
-struct _PanelCellRendererPixbufClass
-{
-        GtkCellRendererPixbufClass parent_class;
-
-        void (*activate) (PanelCellRendererPixbuf *pixbuf,
-                          const gchar           *path);
-};
-
-GType            panel_cell_renderer_pixbuf_get_type (void);
-GtkCellRenderer *panel_cell_renderer_pixbuf_new      (void);
-
-G_END_DECLS
-
-#endif /* PANEL_CELL_RENDERER_PIXBUF_H */
-
diff --git a/panels/network/panel-cell-renderer-security.c b/panels/network/panel-cell-renderer-security.c
deleted file mode 100644
index a964bcf..0000000
--- a/panels/network/panel-cell-renderer-security.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- Security: C; tab-width: 8; indent-tabs-security: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Red Hat, Inc
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "panel-cell-renderer-security.h"
-
-enum {
-        PROP_0,
-        PROP_SECURITY,
-        PROP_LAST
-};
-
-G_DEFINE_TYPE (PanelCellRendererSecurity, panel_cell_renderer_security, GTK_TYPE_CELL_RENDERER_PIXBUF)
-
-static gpointer parent_class = NULL;
-
-/**
- * panel_cell_renderer_security_get_property:
- **/
-static void
-panel_cell_renderer_security_get_property (GObject *object, guint param_id,
-                                       GValue *value, GParamSpec *pspec)
-{
-        PanelCellRendererSecurity *renderer = PANEL_CELL_RENDERER_SECURITY (object);
-
-        switch (param_id) {
-        case PROP_SECURITY:
-                g_value_set_uint (value, renderer->security);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-/**
- * panel_cell_renderer_set_name:
- **/
-static void
-panel_cell_renderer_set_name (PanelCellRendererSecurity *renderer)
-{
-        const gchar *icon_name = NULL;
-
-        if (renderer->security != NM_AP_SEC_UNKNOWN &&
-            renderer->security != NM_AP_SEC_NONE)
-                icon_name = "network-wireless-encrypted-symbolic";
-
-        if (icon_name != NULL) {
-                g_object_set (renderer,
-                              "icon-name", icon_name,
-                              NULL);
-        } else {
-                g_object_set (renderer,
-                              "icon-name", "",
-                              NULL);
-        }
-}
-
-/**
- * panel_cell_renderer_security_set_property:
- **/
-static void
-panel_cell_renderer_security_set_property (GObject *object, guint param_id,
-                                       const GValue *value, GParamSpec *pspec)
-{
-        PanelCellRendererSecurity *renderer = PANEL_CELL_RENDERER_SECURITY (object);
-
-        switch (param_id) {
-        case PROP_SECURITY:
-                renderer->security = g_value_get_uint (value);
-                panel_cell_renderer_set_name (renderer);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-/**
- * panel_cell_renderer_finalize:
- **/
-static void
-panel_cell_renderer_finalize (GObject *object)
-{
-        PanelCellRendererSecurity *renderer;
-        renderer = PANEL_CELL_RENDERER_SECURITY (object);
-        g_free (renderer->icon_name);
-        G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * panel_cell_renderer_security_class_init:
- **/
-static void
-panel_cell_renderer_security_class_init (PanelCellRendererSecurityClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-        object_class->finalize = panel_cell_renderer_finalize;
-
-        parent_class = g_type_class_peek_parent (class);
-
-        object_class->get_property = panel_cell_renderer_security_get_property;
-        object_class->set_property = panel_cell_renderer_security_set_property;
-
-        g_object_class_install_property (object_class, PROP_SECURITY,
-                                         g_param_spec_uint ("security", NULL,
-                                                            NULL,
-                                                            0, G_MAXUINT, 0,
-                                                            G_PARAM_READWRITE));
-}
-
-/**
- * panel_cell_renderer_security_init:
- **/
-static void
-panel_cell_renderer_security_init (PanelCellRendererSecurity *renderer)
-{
-        renderer->security = 0;
-        renderer->icon_name = NULL;
-}
-
-/**
- * panel_cell_renderer_security_new:
- **/
-GtkCellRenderer *
-panel_cell_renderer_security_new (void)
-{
-        return g_object_new (PANEL_TYPE_CELL_RENDERER_SECURITY, NULL);
-}
-
diff --git a/panels/network/panel-cell-renderer-security.h b/panels/network/panel-cell-renderer-security.h
deleted file mode 100644
index e297abe..0000000
--- a/panels/network/panel-cell-renderer-security.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Security: C; tab-width: 8; indent-tabs-security: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2011 Red Hat, Inc
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- */
-
-#ifndef PANEL_CELL_RENDERER_SECURITY_H
-#define PANEL_CELL_RENDERER_SECURITY_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "nm-device.h"
-#include "nm-access-point.h"
-
-#define PANEL_TYPE_CELL_RENDERER_SECURITY           (panel_cell_renderer_security_get_type())
-#define PANEL_CELL_RENDERER_SECURITY(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_SECURITY, PanelCellRendererSecurity))
-#define PANEL_CELL_RENDERER_SECURITY_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_SECURITY, PanelCellRendererSecurityClass))
-#define PANEL_IS_CELL_RENDERER_SECURITY(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_SECURITY))
-#define PANEL_IS_CELL_RENDERER_SECURITY_CLASS(cls)  (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_SECURITY))
-#define PANEL_CELL_RENDERER_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_SECURITY, PanelCellRendererSecurityClass))
-
-G_BEGIN_DECLS
-
-typedef struct _PanelCellRendererSecurity           PanelCellRendererSecurity;
-typedef struct _PanelCellRendererSecurityClass      PanelCellRendererSecurityClass;
-
-typedef enum {
-  NM_AP_SEC_UNKNOWN,
-  NM_AP_SEC_NONE,
-  NM_AP_SEC_WEP,
-  NM_AP_SEC_WPA,
-  NM_AP_SEC_WPA2
-} NMAccessPointSecurity;
-
-struct _PanelCellRendererSecurity
-{
-        GtkCellRendererPixbuf    parent;
-        guint                    security;
-        gchar                   *icon_name;
-};
-
-struct _PanelCellRendererSecurityClass
-{
-        GtkCellRendererPixbufClass parent_class;
-};
-
-GType            panel_cell_renderer_security_get_type      (void);
-GtkCellRenderer *panel_cell_renderer_security_new           (void);
-
-G_END_DECLS
-
-#endif /* PANEL_CELL_RENDERER_SECURITY_H */
-
diff --git a/panels/network/panel-cell-renderer-separator.c b/panels/network/panel-cell-renderer-separator.c
deleted file mode 100644
index ae4d5d2..0000000
--- a/panels/network/panel-cell-renderer-separator.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- Separator: C; tab-width: 8; indent-tabs-separator: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- *
- * Written by Matthias Clasen
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "panel-cell-renderer-separator.h"
-
-enum {
-        PROP_0,
-        PROP_DRAW,
-        PROP_LAST
-};
-
-G_DEFINE_TYPE (PanelCellRendererSeparator, panel_cell_renderer_separator, GTK_TYPE_CELL_RENDERER)
-
-static void
-panel_cell_renderer_separator_get_property (GObject    *object,
-                                            guint       param_id,
-                                            GValue     *value,
-                                            GParamSpec *pspec)
-{
-        PanelCellRendererSeparator *renderer = PANEL_CELL_RENDERER_SEPARATOR (object);
-
-        switch (param_id) {
-        case PROP_DRAW:
-                g_value_set_boolean (value, renderer->draw);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-static void
-panel_cell_renderer_separator_set_property (GObject      *object,
-                                            guint         param_id,
-                                            const GValue *value,
-                                            GParamSpec   *pspec)
-{
-        PanelCellRendererSeparator *renderer = PANEL_CELL_RENDERER_SEPARATOR (object);
-
-        switch (param_id) {
-        case PROP_DRAW:
-                renderer->draw = g_value_get_boolean (value);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-static void
-render (GtkCellRenderer      *cell,
-        cairo_t              *cr,
-        GtkWidget            *widget,
-        const GdkRectangle   *background_area,
-        const GdkRectangle   *cell_area,
-        GtkCellRendererState  flags)
-{
-        PanelCellRendererSeparator *renderer = PANEL_CELL_RENDERER_SEPARATOR (cell);
-        GtkStyleContext *context;
-        gint x, y, w, h, xpad, ypad;
-
-        if (!renderer->draw)
-                return;
-
-        context = gtk_widget_get_style_context (widget);
-
-        gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
-
-        x = cell_area->x + xpad;
-        y = cell_area->y + ypad;
-        w = cell_area->width - xpad * 2;
-        h = cell_area->height - ypad * 2;
-
-        gtk_render_line (context, cr, x + w / 2, y, x + w / 2, y + h - 1);
-}
-
-static void
-panel_cell_renderer_separator_class_init (PanelCellRendererSeparatorClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-        GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
-
-        object_class->get_property = panel_cell_renderer_separator_get_property;
-        object_class->set_property = panel_cell_renderer_separator_set_property;
-
-        cell_renderer_class->render = render;
-
-        g_object_class_install_property (object_class, PROP_DRAW,
-                                         g_param_spec_boolean ("draw", "draw", "draw",
-                                                               TRUE,
-                                                               G_PARAM_READWRITE));
-}
-
-static void
-panel_cell_renderer_separator_init (PanelCellRendererSeparator *renderer)
-{
-        renderer->draw = TRUE;
-}
-
-GtkCellRenderer *
-panel_cell_renderer_separator_new (void)
-{
-        return g_object_new (PANEL_TYPE_CELL_RENDERER_SEPARATOR, NULL);
-}
diff --git a/panels/network/panel-cell-renderer-separator.h b/panels/network/panel-cell-renderer-separator.h
deleted file mode 100644
index 29dfa1d..0000000
--- a/panels/network/panel-cell-renderer-separator.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Separator: C; tab-width: 8; indent-tabs-separator: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- *
- * Written by Matthias Clasen
- */
-
-#ifndef PANEL_CELL_RENDERER_SEPARATOR_H
-#define PANEL_CELL_RENDERER_SEPARATOR_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "nm-device.h"
-#include "nm-access-point.h"
-
-#define PANEL_TYPE_CELL_RENDERER_SEPARATOR           (panel_cell_renderer_separator_get_type())
-#define PANEL_CELL_RENDERER_SEPARATOR(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_SEPARATOR, PanelCellRendererSeparator))
-#define PANEL_CELL_RENDERER_SEPARATOR_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_SEPARATOR, PanelCellRendererSeparatorClass))
-#define PANEL_IS_CELL_RENDERER_SEPARATOR(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_SEPARATOR))
-#define PANEL_IS_CELL_RENDERER_SEPARATOR_CLASS(cls)  (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_SEPARATOR))
-#define PANEL_CELL_RENDERER_SEPARATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_SEPARATOR, PanelCellRendererSeparatorClass))
-
-G_BEGIN_DECLS
-
-typedef struct _PanelCellRendererSeparator           PanelCellRendererSeparator;
-typedef struct _PanelCellRendererSeparatorClass      PanelCellRendererSeparatorClass;
-
-struct _PanelCellRendererSeparator
-{
-        GtkCellRenderer parent;
-        gboolean draw;
-};
-
-struct _PanelCellRendererSeparatorClass
-{
-        GtkCellRendererClass parent_class;
-};
-
-GType            panel_cell_renderer_separator_get_type (void);
-GtkCellRenderer *panel_cell_renderer_separator_new      (void);
-
-G_END_DECLS
-
-#endif /* PANEL_CELL_RENDERER_SEPARATOR_H */
-
diff --git a/panels/network/panel-cell-renderer-signal.c b/panels/network/panel-cell-renderer-signal.c
deleted file mode 100644
index fbdfcee..0000000
--- a/panels/network/panel-cell-renderer-signal.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-signal: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "panel-cell-renderer-signal.h"
-
-enum {
-        PROP_0,
-        PROP_SIGNAL,
-        PROP_LAST
-};
-
-G_DEFINE_TYPE (PanelCellRendererSignal, panel_cell_renderer_signal, GTK_TYPE_CELL_RENDERER_PIXBUF)
-
-static gpointer parent_class = NULL;
-
-/**
- * panel_cell_renderer_signal_get_property:
- **/
-static void
-panel_cell_renderer_signal_get_property (GObject *object, guint param_id,
-                                       GValue *value, GParamSpec *pspec)
-{
-        PanelCellRendererSignal *renderer = PANEL_CELL_RENDERER_SIGNAL (object);
-
-        switch (param_id) {
-        case PROP_SIGNAL:
-                g_value_set_uint (value, renderer->signal);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-/**
- * panel_cell_renderer_set_name:
- **/
-static void
-panel_cell_renderer_set_name (PanelCellRendererSignal *renderer)
-{
-        const gchar *icon_name = NULL;
-        GIcon *icon;
-
-        /* the 'Other...' entry */
-        if (renderer->signal <= 0) {
-                g_object_set (renderer, "gicon", NULL, NULL);
-                return;
-        }
-
-        if (renderer->signal < 20)
-                icon_name = "network-wireless-signal-none-symbolic";
-        else if (renderer->signal < 40)
-                icon_name = "network-wireless-signal-weak-symbolic";
-        else if (renderer->signal < 50)
-                icon_name = "network-wireless-signal-ok-symbolic";
-        else if (renderer->signal < 80)
-                icon_name = "network-wireless-signal-good-symbolic";
-        else
-                icon_name = "network-wireless-signal-excellent-symbolic";
-
-        icon = g_themed_icon_new_with_default_fallbacks (icon_name);
-        g_object_set (renderer, "gicon", icon, NULL);
-        g_object_unref (icon);
-}
-
-/**
- * panel_cell_renderer_signal_set_property:
- **/
-static void
-panel_cell_renderer_signal_set_property (GObject *object, guint param_id,
-                                       const GValue *value, GParamSpec *pspec)
-{
-        PanelCellRendererSignal *renderer = PANEL_CELL_RENDERER_SIGNAL (object);
-
-        switch (param_id) {
-        case PROP_SIGNAL:
-                renderer->signal = g_value_get_uint (value);
-                panel_cell_renderer_set_name (renderer);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-                break;
-        }
-}
-
-/**
- * panel_cell_renderer_finalize:
- **/
-static void
-panel_cell_renderer_finalize (GObject *object)
-{
-        PanelCellRendererSignal *renderer;
-        renderer = PANEL_CELL_RENDERER_SIGNAL (object);
-        g_free (renderer->icon_name);
-        G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * panel_cell_renderer_signal_class_init:
- **/
-static void
-panel_cell_renderer_signal_class_init (PanelCellRendererSignalClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-        object_class->finalize = panel_cell_renderer_finalize;
-
-        parent_class = g_type_class_peek_parent (class);
-
-        object_class->get_property = panel_cell_renderer_signal_get_property;
-        object_class->set_property = panel_cell_renderer_signal_set_property;
-
-        g_object_class_install_property (object_class, PROP_SIGNAL,
-                                         g_param_spec_uint ("signal", NULL,
-                                                            NULL,
-                                                            0, G_MAXUINT, 0,
-                                                            G_PARAM_READWRITE));
-}
-
-/**
- * panel_cell_renderer_signal_init:
- **/
-static void
-panel_cell_renderer_signal_init (PanelCellRendererSignal *renderer)
-{
-        renderer->signal = 0;
-        renderer->icon_name = NULL;
-}
-
-/**
- * panel_cell_renderer_signal_new:
- **/
-GtkCellRenderer *
-panel_cell_renderer_signal_new (void)
-{
-        return g_object_new (PANEL_TYPE_CELL_RENDERER_SIGNAL, NULL);
-}
-
diff --git a/panels/network/panel-cell-renderer-signal.h b/panels/network/panel-cell-renderer-signal.h
deleted file mode 100644
index 3829e2f..0000000
--- a/panels/network/panel-cell-renderer-signal.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-signal: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- */
-
-#ifndef PANEL_CELL_RENDERER_SIGNAL_H
-#define PANEL_CELL_RENDERER_SIGNAL_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include "nm-device.h"
-#include "nm-access-point.h"
-
-#define PANEL_TYPE_CELL_RENDERER_SIGNAL                 (panel_cell_renderer_signal_get_type())
-#define PANEL_CELL_RENDERER_SIGNAL(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_SIGNAL, PanelCellRendererSignal))
-#define PANEL_CELL_RENDERER_SIGNAL_CLASS(cls)           (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_SIGNAL, PanelCellRendererSignalClass))
-#define PANEL_IS_CELL_RENDERER_SIGNAL(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_SIGNAL))
-#define PANEL_IS_CELL_RENDERER_SIGNAL_CLASS(cls)        (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_SIGNAL))
-#define PANEL_CELL_RENDERER_SIGNAL_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_SIGNAL, PanelCellRendererSignalClass))
-
-G_BEGIN_DECLS
-
-typedef struct _PanelCellRendererSignal         PanelCellRendererSignal;
-typedef struct _PanelCellRendererSignalClass    PanelCellRendererSignalClass;
-
-struct _PanelCellRendererSignal
-{
-        GtkCellRendererPixbuf    parent;
-        guint                    signal;
-        gchar                   *icon_name;
-};
-
-struct _PanelCellRendererSignalClass
-{
-        GtkCellRendererPixbufClass parent_class;
-};
-
-GType            panel_cell_renderer_signal_get_type    (void);
-GtkCellRenderer *panel_cell_renderer_signal_new         (void);
-
-G_END_DECLS
-
-#endif /* PANEL_CELL_RENDERER_SIGNAL_H */
-
diff --git a/panels/network/panel-cell-renderer-text.c b/panels/network/panel-cell-renderer-text.c
deleted file mode 100644
index 5731da6..0000000
--- a/panels/network/panel-cell-renderer-text.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Text: C; tab-width: 8; indent-tabs-text: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- *
- * Written by Matthias Clasen
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include "panel-cell-renderer-text.h"
-
-enum {
-        ACTIVATE,
-        LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PanelCellRendererText, panel_cell_renderer_text, GTK_TYPE_CELL_RENDERER_TEXT)
-
-static gint
-activate (GtkCellRenderer      *cell,
-          GdkEvent             *event,
-          GtkWidget            *widget,
-          const gchar          *path,
-          const GdkRectangle   *background_area,
-          const GdkRectangle   *cell_area,
-          GtkCellRendererState  flags)
-{
-        g_signal_emit (cell,  signals[ACTIVATE], 0, path);
-
-        return TRUE;
-}
-
-static void
-panel_cell_renderer_text_class_init (PanelCellRendererTextClass *class)
-{
-        GObjectClass *object_class = G_OBJECT_CLASS (class);
-        GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
-
-        cell_renderer_class->activate = activate;
-
-        signals[ACTIVATE] =
-                g_signal_new ("activate",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (PanelCellRendererTextClass, activate),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__STRING,
-                              G_TYPE_NONE, 1, G_TYPE_STRING);
-}
-
-static void
-panel_cell_renderer_text_init (PanelCellRendererText *renderer)
-{
-}
-
-GtkCellRenderer *
-panel_cell_renderer_text_new (void)
-{
-        return g_object_new (PANEL_TYPE_CELL_RENDERER_TEXT, NULL);
-}
diff --git a/panels/network/panel-cell-renderer-text.h b/panels/network/panel-cell-renderer-text.h
deleted file mode 100644
index c4c2e45..0000000
--- a/panels/network/panel-cell-renderer-text.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Text: C; tab-width: 8; indent-tabs-text: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * Licensed under the GNU General Public License Version 2
- *
- * 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 of the License, 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.
- *
- * Written by Matthias Clasen
- */
-
-#ifndef PANEL_CELL_RENDERER_TEXT_H
-#define PANEL_CELL_RENDERER_TEXT_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#define PANEL_TYPE_CELL_RENDERER_TEXT           (panel_cell_renderer_text_get_type())
-#define PANEL_CELL_RENDERER_TEXT(obj)           (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_TEXT, PanelCellRendererText))
-#define PANEL_CELL_RENDERER_TEXT_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_TEXT, PanelCellRendererTextClass))
-#define PANEL_IS_CELL_RENDERER_TEXT(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_TEXT))
-#define PANEL_IS_CELL_RENDERER_TEXT_CLASS(cls)  (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_TEXT))
-#define PANEL_CELL_RENDERER_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_TEXT, PanelCellRendererTextClass))
-
-G_BEGIN_DECLS
-
-typedef struct _PanelCellRendererText           PanelCellRendererText;
-typedef struct _PanelCellRendererTextClass      PanelCellRendererTextClass;
-
-struct _PanelCellRendererText
-{
-        GtkCellRendererText parent;
-};
-
-struct _PanelCellRendererTextClass
-{
-        GtkCellRendererTextClass parent_class;
-
-        void (*activate) (PanelCellRendererText *text,
-                          const gchar           *path);
-};
-
-GType            panel_cell_renderer_text_get_type (void);
-GtkCellRenderer *panel_cell_renderer_text_new      (void);
-
-G_END_DECLS
-
-#endif /* PANEL_CELL_RENDERER_TEXT_H */
-
diff --git a/panels/network/panel-common.c b/panels/network/panel-common.c
index fe7baf4..cafdc32 100644
--- a/panels/network/panel-common.c
+++ b/panels/network/panel-common.c
@@ -655,3 +655,21 @@ panel_unset_device_widgets (GtkBuilder *builder)
         panel_set_device_widget_details (builder, "dns", NULL);
         panel_set_device_widget_details (builder, "route", NULL);
 }
+
+gchar *
+panel_get_ip4_address_as_string (NMIP4Config *ip4, const gchar *what)
+{
+        return get_ipv4_config_address_as_string (ip4, what);
+}
+
+gchar *
+panel_get_ip4_dns_as_string (NMIP4Config *ip4)
+{
+        return get_ipv4_config_name_servers_as_string (ip4);
+}
+
+gchar *
+panel_get_ip6_address_as_string (NMIP6Config *ip6)
+{
+        return get_ipv6_config_address_as_string (ip6);
+}
diff --git a/panels/network/panel-common.h b/panels/network/panel-common.h
index c55d46b..9288e4f 100644
--- a/panels/network/panel-common.h
+++ b/panels/network/panel-common.h
@@ -45,6 +45,9 @@ gboolean         panel_set_device_widget_header                (GtkBuilder *buil
 void             panel_set_device_widgets                      (GtkBuilder *builder,
                                                                 NMDevice *device);
 void             panel_unset_device_widgets                    (GtkBuilder *builder);
+gchar           *panel_get_ip4_address_as_string               (NMIP4Config *config, const gchar *what);
+gchar           *panel_get_ip4_dns_as_string                   (NMIP4Config *config);
+gchar           *panel_get_ip6_address_as_string               (NMIP6Config *config);
 
 G_END_DECLS
 
diff --git a/panels/network/wireless-security/Makefile.am b/panels/network/wireless-security/Makefile.am
new file mode 100644
index 0000000..a2d3fba
--- /dev/null
+++ b/panels/network/wireless-security/Makefile.am
@@ -0,0 +1,59 @@
+noinst_LTLIBRARIES = libwireless-security.la
+
+libwireless_security_la_SOURCES = \
+	wireless-security.h \
+	wireless-security.c \
+	ws-wep-key.h \
+	ws-wep-key.c \
+	ws-wpa-psk.h \
+	ws-wpa-psk.c \
+	ws-leap.h \
+	ws-leap.c \
+	ws-wpa-eap.h \
+	ws-wpa-eap.c \
+	ws-dynamic-wep.h \
+	ws-dynamic-wep.c \
+	eap-method.h \
+	eap-method.c \
+	eap-method-tls.h \
+	eap-method-tls.c \
+	eap-method-leap.h \
+	eap-method-leap.c \
+	eap-method-fast.h \
+	eap-method-fast.c \
+	eap-method-ttls.h \
+	eap-method-ttls.c \
+	eap-method-peap.h \
+	eap-method-peap.c \
+	eap-method-simple.h \
+	eap-method-simple.c \
+	helpers.h \
+	helpers.c
+
+libwireless_security_la_CPPFLAGS = \
+	$(NETWORK_PANEL_CFLAGS) \
+        $(NETWORK_MANAGER_CFLAGS)                       \
+	-DUIDIR=\""$(uidir)"\"
+
+libwireless_security_la_LIBADD = \
+	$(NETWORK_PANEL_LIBS) \
+	$(NETWORK_MANAGER_LIBS)
+
+uidir = $(pkgdatadir)/ui
+ui_DATA = \
+	eap-method-leap.ui \
+	eap-method-fast.ui \
+	eap-method-peap.ui \
+	eap-method-simple.ui \
+	eap-method-tls.ui \
+	eap-method-ttls.ui \
+	nag-user-dialog.ui \
+	ws-dynamic-wep.ui \
+	ws-leap.ui \
+	ws-wep-key.ui \
+	ws-wpa-eap.ui \
+	ws-wpa-psk.ui
+
+EXTRA_DIST = \
+	$(ui_DATA)
+
diff --git a/panels/network/wireless-security/eap-method-fast.c b/panels/network/wireless-security/eap-method-fast.c
new file mode 100644
index 0000000..e34c3f5
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-fast.c
@@ -0,0 +1,443 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */
+
+/* EAP-FAST authentication method (RFC4851)
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2012 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-8021x.h>
+
+#include "eap-method.h"
+#include "wireless-security.h"
+
+#define I_NAME_COLUMN   0
+#define I_METHOD_COLUMN 1
+
+struct _EAPMethodFAST {
+	EAPMethod parent;
+
+	GtkSizeGroup *size_group;
+	WirelessSecurity *sec_parent;
+	gboolean is_editor;
+};
+
+static void
+destroy (EAPMethod *parent)
+{
+	EAPMethodFAST *method = (EAPMethodFAST *) parent;
+
+	if (method->size_group)
+		g_object_unref (method->size_group);
+}
+
+static gboolean
+validate (EAPMethod *parent)
+{
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap = NULL;
+	const char *file;
+	gboolean provisioning;
+	gboolean valid = FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton"));
+	g_assert (widget);
+	provisioning = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button"));
+	g_assert (widget);
+	file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	if (!provisioning && !file)
+		return FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo"));
+	g_assert (widget);
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	valid = eap_method_validate (eap);
+	eap_method_unref (eap);
+	return valid;
+}
+
+static void
+add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
+{
+	EAPMethodFAST *method = (EAPMethodFAST *) parent;
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap;
+
+	if (method->size_group)
+		g_object_unref (method->size_group);
+	method->size_group = g_object_ref (group);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo"));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	eap_method_add_to_size_group (eap, group);
+	eap_method_unref (eap);
+}
+
+static void
+fill_connection (EAPMethod *parent, NMConnection *connection)
+{
+	NMSetting8021x *s_8021x;
+	GtkWidget *widget;
+	const char *text;
+	char *filename;
+	EAPMethod *eap = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean enabled;
+	int pac_provisioning = 0;
+
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	g_assert (s_8021x);
+
+	nm_setting_802_1x_add_eap_method (s_8021x, "fast");
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (text && strlen (text))
+		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button"));
+	g_assert (widget);
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, filename, NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton"));
+	enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+	if (!enabled)
+		g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "0", NULL);
+	else {
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo"));
+		pac_provisioning = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+		switch (pac_provisioning) {
+		case 0:  /* Anonymous */
+			g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "1", NULL);
+			break;
+		case 1:  /* Authenticated */
+			g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "2", NULL);
+			break;
+		case 2:  /* Both - anonymous and authenticated */
+			g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "3", NULL);
+			break;
+		default: /* Should not happen */
+			g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "1", NULL);
+			break;
+		}
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo"));
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_method_fill_connection (eap, connection);
+	eap_method_unref (eap);
+}
+
+static void
+inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data)
+{
+	EAPMethod *parent = (EAPMethod *) user_data;
+	EAPMethodFAST *method = (EAPMethodFAST *) parent;
+	GtkWidget *vbox;
+	EAPMethod *eap = NULL;
+	GList *elt, *children;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkWidget *eap_widget;
+
+	vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_vbox"));
+	g_assert (vbox);
+
+	/* Remove any previous wireless security widgets */
+	children = gtk_container_get_children (GTK_CONTAINER (vbox));
+	for (elt = children; elt; elt = g_list_next (elt))
+		gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data));
+	g_list_free (children);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_widget = eap_method_get_widget (eap);
+	g_assert (eap_widget);
+	gtk_widget_unparent (eap_widget);
+
+	if (method->size_group)
+		eap_method_add_to_size_group (eap, method->size_group);
+	gtk_container_add (GTK_CONTAINER (vbox), eap_widget);
+
+	eap_method_unref (eap);
+
+	wireless_security_changed_cb (combo, method->sec_parent);
+}
+
+static GtkWidget *
+inner_auth_combo_init (EAPMethodFAST *method,
+                       NMConnection *connection,
+                       NMSetting8021x *s_8021x,
+                       gboolean secrets_only)
+{
+	EAPMethod *parent = (EAPMethod *) method;
+	GtkWidget *combo;
+	GtkListStore *auth_model;
+	GtkTreeIter iter;
+	EAPMethodSimple *em_gtc;
+	EAPMethodSimple *em_mschap_v2;
+	guint32 active = 0;
+	const char *phase2_auth = NULL;
+
+	auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_type ());
+
+	if (s_8021x) {
+		if (nm_setting_802_1x_get_phase2_auth (s_8021x))
+			phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x);
+		else if (nm_setting_802_1x_get_phase2_autheap (s_8021x))
+			phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x);
+	}
+
+	em_gtc = eap_method_simple_new (method->sec_parent,
+	                                connection,
+	                                EAP_METHOD_SIMPLE_TYPE_GTC,
+	                                TRUE,
+	                                method->is_editor,
+	                                secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("GTC"),
+	                    I_METHOD_COLUMN, em_gtc,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_gtc));
+
+	/* Check for defaulting to GTC */
+	if (phase2_auth && !strcasecmp (phase2_auth, "gtc"))
+		active = 0;
+
+	em_mschap_v2 = eap_method_simple_new (method->sec_parent,
+	                                      connection,
+	                                      EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
+	                                      TRUE,
+	                                      method->is_editor, secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("MSCHAPv2"),
+	                    I_METHOD_COLUMN, em_mschap_v2,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_mschap_v2));
+
+	/* Check for defaulting to MSCHAPv2 */
+	if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2"))
+		active = 1;
+
+	combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo"));
+	g_assert (combo);
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model));
+	g_object_unref (G_OBJECT (auth_model));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
+
+	g_signal_connect (G_OBJECT (combo), "changed",
+	                  (GCallback) inner_auth_combo_changed_cb,
+	                  method);
+	return combo;
+}
+
+static void
+update_secrets (EAPMethod *parent, NMConnection *connection)
+{
+	eap_method_phase2_update_secrets_helper (parent,
+	                                         connection,
+	                                         "eap_fast_inner_auth_combo",
+	                                         I_METHOD_COLUMN);
+}
+
+static void
+pac_toggled_cb (GtkWidget *widget, gpointer user_data)
+{
+	EAPMethod *parent = (EAPMethod *) user_data;
+	EAPMethodFAST *method = (EAPMethodFAST *) parent;
+	gboolean enabled = FALSE;
+	GtkWidget *provision_combo;
+
+	provision_combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo"));
+	g_return_if_fail (provision_combo);
+
+	enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+	gtk_widget_set_sensitive (provision_combo, enabled);
+
+	wireless_security_changed_cb (widget, method->sec_parent);
+}
+
+EAPMethodFAST *
+eap_method_fast_new (WirelessSecurity *ws_parent,
+                     NMConnection *connection,
+                     gboolean is_editor,
+                     gboolean secrets_only)
+{
+	EAPMethod *parent;
+	EAPMethodFAST *method;
+	GtkWidget *widget;
+	GtkFileFilter *filter;
+	NMSetting8021x *s_8021x = NULL;
+	const char *filename;
+	gboolean provisioning_enabled = TRUE;
+
+	parent = eap_method_init (sizeof (EAPMethodFAST),
+	                          validate,
+	                          add_to_size_group,
+	                          fill_connection,
+	                          update_secrets,
+	                          destroy,
+	                          UIDIR "/eap-method-fast.ui",
+	                          "eap_fast_notebook",
+	                          "eap_fast_anon_identity_entry",
+	                          FALSE);
+	if (!parent)
+		return NULL;
+
+	method = (EAPMethodFAST *) parent;
+	method->sec_parent = ws_parent;
+	method->is_editor = is_editor;
+
+	if (connection)
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo"));
+	g_assert (widget);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+	if (s_8021x) {
+		const char *fast_prov;
+
+		fast_prov = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021x);
+		if (fast_prov) {
+			if (!strcmp (fast_prov, "0"))
+				provisioning_enabled = FALSE;
+			else if (!strcmp (fast_prov, "1"))
+				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+			else if (!strcmp (fast_prov, "2"))
+				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+			else if (!strcmp (fast_prov, "3"))
+				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
+		}
+	}
+	gtk_widget_set_sensitive (widget, provisioning_enabled);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton"));
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), provisioning_enabled);
+	g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (pac_toggled_cb), parent);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry"));
+	if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x))
+		gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x));
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button"));
+	g_assert (widget);
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
+	gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget),
+	                                   _("Choose a PAC file..."));
+	g_signal_connect (G_OBJECT (widget), "selection-changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	filter = gtk_file_filter_new ();
+	gtk_file_filter_add_pattern (filter, "*.pac");
+	gtk_file_filter_set_name (filter, _("PAC files (*.pac)"));
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
+	filter = gtk_file_filter_new ();
+	gtk_file_filter_add_pattern (filter, "*");
+	gtk_file_filter_set_name (filter, _("All files"));
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
+
+	if (connection && s_8021x) {
+		filename = nm_setting_802_1x_get_pac_file (s_8021x);
+		if (filename)
+			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+	}
+
+	widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only);
+	inner_auth_combo_changed_cb (widget, (gpointer) method);
+
+	if (secrets_only) {
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo"));
+		gtk_widget_hide (widget);
+	}
+
+	return method;
+}
+
diff --git a/panels/network/wireless-security/eap-method-fast.h b/panels/network/wireless-security/eap-method-fast.h
new file mode 100644
index 0000000..32b9a4b
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-fast.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */
+
+/* EAP-FAST authentication method (RFC4851)
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2012 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_FAST_H
+#define EAP_METHOD_FAST_H
+
+#include "wireless-security.h"
+
+typedef struct _EAPMethodFAST EAPMethodFAST;
+
+EAPMethodFAST *eap_method_fast_new (WirelessSecurity *ws_parent,
+                                    NMConnection *connection,
+                                    gboolean is_editor,
+                                    gboolean secrets_only);
+
+#endif /* EAP_METHOD_FAST_H */
+
diff --git a/panels/network/wireless-security/eap-method-fast.ui b/panels/network/wireless-security/eap-method-fast.ui
new file mode 100644
index 0000000..fdfc7f8
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-fast.ui
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="eap_fast_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table13">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">5</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="eap_fast_anon_identity_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Anony_mous identity</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_fast_anon_identity_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_fast_anon_identity_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_fast_pac_file_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">PAC _file</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_fast_pac_file_button</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="eap_fast_pac_file_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="eap_fast_inner_auth_vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="right_attach">2</property>
+            <property name="top_attach">4</property>
+            <property name="bottom_attach">5</property>
+            <property name="x_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_fast_inner_auth_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Inner authentication</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_fast_inner_auth_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="eap_fast_inner_auth_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model8</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer8"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="eap_fast_pac_provision_checkbutton">
+            <property name="label" translatable="yes">PAC pro_visioning</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="xalign">0.5</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="eap_fast_pac_provision_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model9</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer9"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label61">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkListStore" id="model8">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes"> </col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="model9">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Anonymous</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Authenticated</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Both</col>
+      </row>
+    </data>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/eap-method-leap.c b/panels/network/wireless-security/eap-method-leap.c
new file mode 100644
index 0000000..93bb32d
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-leap.c
@@ -0,0 +1,183 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <nm-setting-8021x.h>
+
+#include "eap-method.h"
+#include "wireless-security.h"
+#include "helpers.h"
+
+struct _EAPMethodLEAP {
+	EAPMethod parent;
+
+	gboolean new_connection;
+};
+
+static void
+show_toggled_cb (GtkCheckButton *button, EAPMethod *method)
+{
+	GtkWidget *widget;
+	gboolean visible;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_leap_password_entry"));
+	g_assert (widget);
+
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static gboolean
+validate (EAPMethod *parent)
+{
+	GtkWidget *widget;
+	const char *text;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!text || !strlen (text))
+		return FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!text || !strlen (text))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (EAPMethod *parent, NMConnection *connection)
+{
+	EAPMethodLEAP *method = (EAPMethodLEAP *) parent;
+	NMSetting8021x *s_8021x;
+	GtkWidget *widget;
+
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	g_assert (s_8021x);
+
+	nm_setting_802_1x_add_eap_method (s_8021x, "leap");
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
+	g_assert (widget);
+	g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry"));
+	g_assert (widget);
+	g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+
+	/* Default to agent-owned secrets for new connections */
+	if (method->new_connection) {
+		g_object_set (s_8021x,
+		              NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
+		              NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE,
+		              NULL);
+	}
+}
+
+static void
+update_secrets (EAPMethod *parent, NMConnection *connection)
+{
+	helper_fill_secret_entry (connection,
+	                          parent->builder,
+	                          "eap_leap_password_entry",
+	                          NM_TYPE_SETTING_802_1X,
+	                          (HelperSecretFunc) nm_setting_802_1x_get_password);
+}
+
+EAPMethodLEAP *
+eap_method_leap_new (WirelessSecurity *ws_parent,
+                     NMConnection *connection,
+                     gboolean secrets_only)
+{
+	EAPMethodLEAP *method;
+	EAPMethod *parent;
+	GtkWidget *widget;
+
+	parent = eap_method_init (sizeof (EAPMethodLEAP),
+	                          validate,
+	                          add_to_size_group,
+	                          fill_connection,
+	                          update_secrets,
+	                          NULL,
+	                          UIDIR "/eap-method-leap.ui",
+	                          "eap_leap_notebook",
+	                          "eap_leap_username_entry",
+	                          FALSE);
+	if (!parent)
+		return NULL;
+
+	method = (EAPMethodLEAP *) parent;
+	method->new_connection = secrets_only ? FALSE : TRUE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+	if (connection) {
+		NMSetting8021x *s_8021x;
+
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+		if (s_8021x && nm_setting_802_1x_get_identity (s_8021x))
+			gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x));
+	}
+
+	if (secrets_only)
+		gtk_widget_set_sensitive (widget, FALSE);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	/* Fill secrets, if any */
+	if (connection)
+		update_secrets (parent, connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapleap"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) show_toggled_cb,
+	                  parent);
+
+	return method;
+}
+
diff --git a/panels/network/wireless-security/eap-method-leap.h b/panels/network/wireless-security/eap-method-leap.h
new file mode 100644
index 0000000..e3525ba
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-leap.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_LEAP_H
+#define EAP_METHOD_LEAP_H
+
+#include "wireless-security.h"
+
+typedef struct _EAPMethodLEAP EAPMethodLEAP;
+
+EAPMethodLEAP *eap_method_leap_new (WirelessSecurity *ws_parent,
+                                    NMConnection *connection,
+                                    gboolean secrets_only);
+
+#endif /* EAP_METHOD_LEAP_H */
+
diff --git a/panels/network/wireless-security/eap-method-leap.ui b/panels/network/wireless-security/eap-method-leap.ui
new file mode 100644
index 0000000..8b475fb
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-leap.ui
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="eap_leap_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table9">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">3</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_leap_username_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Username</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_leap_username_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_leap_password_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_leap_password_entry</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_leap_password_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_checkbutton_eapleap">
+            <property name="label" translatable="yes">Sho_w password</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="xalign">0</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_leap_username_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label43">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/eap-method-peap.c b/panels/network/wireless-security/eap-method-peap.c
new file mode 100644
index 0000000..4d2041c
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-peap.c
@@ -0,0 +1,414 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-8021x.h>
+
+#include "eap-method.h"
+#include "wireless-security.h"
+
+#define I_NAME_COLUMN   0
+#define I_METHOD_COLUMN 1
+
+struct _EAPMethodPEAP {
+	EAPMethod parent;
+
+	GtkSizeGroup *size_group;
+	WirelessSecurity *sec_parent;
+	gboolean is_editor;
+};
+
+static void
+destroy (EAPMethod *parent)
+{
+	EAPMethodPEAP *method = (EAPMethodPEAP *) parent;
+
+	if (method->size_group)
+		g_object_unref (method->size_group);
+}
+
+static gboolean
+validate (EAPMethod *parent)
+{
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap = NULL;
+	gboolean valid = FALSE;
+
+	if (!eap_method_validate_filepicker (parent->builder, "eap_peap_ca_cert_button", TYPE_CA_CERT, NULL, NULL))
+		return FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo"));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	valid = eap_method_validate (eap);
+	eap_method_unref (eap);
+	return valid;
+}
+
+static void
+add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
+{
+	EAPMethodPEAP *method = (EAPMethodPEAP *) parent;
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap;
+
+	if (method->size_group)
+		g_object_unref (method->size_group);
+	method->size_group = g_object_ref (group);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo"));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	eap_method_add_to_size_group (eap, group);
+	eap_method_unref (eap);
+}
+
+static void
+fill_connection (EAPMethod *parent, NMConnection *connection)
+{
+	NMSetting8021x *s_8021x;
+	NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+	GtkWidget *widget;
+	const char *text;
+	char *filename;
+	EAPMethod *eap = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	int peapver_active = 0;
+	GError *error = NULL;
+
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	g_assert (s_8021x);
+
+	nm_setting_802_1x_add_eap_method (s_8021x, "peap");
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (text && strlen (text))
+		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button"));
+	g_assert (widget);
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+		g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)");
+		g_clear_error (&error);
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo"));
+	peapver_active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+	switch (peapver_active) {
+	case 1:  /* PEAP v0 */
+		g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL);
+		break;
+	case 2:  /* PEAP v1 */
+		g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL);
+		break;
+	default: /* Automatic */
+		g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, NULL, NULL);
+		break;
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo"));
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_method_fill_connection (eap, connection);
+	eap_method_unref (eap);
+}
+static void
+inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data)
+{
+	EAPMethod *parent = (EAPMethod *) user_data;
+	EAPMethodPEAP *method = (EAPMethodPEAP *) parent;
+	GtkWidget *vbox;
+	EAPMethod *eap = NULL;
+	GList *elt, *children;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkWidget *eap_widget;
+
+	vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_vbox"));
+	g_assert (vbox);
+
+	/* Remove any previous wireless security widgets */
+	children = gtk_container_get_children (GTK_CONTAINER (vbox));
+	for (elt = children; elt; elt = g_list_next (elt))
+		gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data));
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_widget = eap_method_get_widget (eap);
+	g_assert (eap_widget);
+	gtk_widget_unparent (eap_widget);
+
+	if (method->size_group)
+		eap_method_add_to_size_group (eap, method->size_group);
+	gtk_container_add (GTK_CONTAINER (vbox), eap_widget);
+
+	eap_method_unref (eap);
+
+	wireless_security_changed_cb (combo, method->sec_parent);
+}
+
+static GtkWidget *
+inner_auth_combo_init (EAPMethodPEAP *method,
+                       NMConnection *connection,
+                       NMSetting8021x *s_8021x,
+                       gboolean secrets_only)
+{
+	EAPMethod *parent = (EAPMethod *) method;
+	GtkWidget *combo;
+	GtkListStore *auth_model;
+	GtkTreeIter iter;
+	EAPMethodSimple *em_mschap_v2;
+	EAPMethodSimple *em_md5;
+	EAPMethodSimple *em_gtc;
+	guint32 active = 0;
+	const char *phase2_auth = NULL;
+
+	auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_type ());
+
+	if (s_8021x) {
+		if (nm_setting_802_1x_get_phase2_auth (s_8021x))
+			phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x);
+		else if (nm_setting_802_1x_get_phase2_autheap (s_8021x))
+			phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x);
+	}
+
+	em_mschap_v2 = eap_method_simple_new (method->sec_parent,
+	                                      connection,
+	                                      EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
+	                                      TRUE,
+	                                      method->is_editor,
+	                                      secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("MSCHAPv2"),
+	                    I_METHOD_COLUMN, em_mschap_v2,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_mschap_v2));
+
+	/* Check for defaulting to MSCHAPv2 */
+	if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2"))
+		active = 0;
+
+	em_md5 = eap_method_simple_new (method->sec_parent,
+	                                connection,
+	                                EAP_METHOD_SIMPLE_TYPE_MD5,
+	                                TRUE,
+	                                method->is_editor,
+	                                secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("MD5"),
+	                    I_METHOD_COLUMN, em_md5,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_md5));
+
+	/* Check for defaulting to MD5 */
+	if (phase2_auth && !strcasecmp (phase2_auth, "md5"))
+		active = 1;
+
+	em_gtc = eap_method_simple_new (method->sec_parent,
+	                                connection,
+	                                EAP_METHOD_SIMPLE_TYPE_GTC,
+	                                TRUE,
+	                                method->is_editor,
+	                                secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("GTC"),
+	                    I_METHOD_COLUMN, em_gtc,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_gtc));
+
+	/* Check for defaulting to GTC */
+	if (phase2_auth && !strcasecmp (phase2_auth, "gtc"))
+		active = 2;
+
+	combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo"));
+	g_assert (combo);
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model));
+	g_object_unref (G_OBJECT (auth_model));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
+
+	g_signal_connect (G_OBJECT (combo), "changed",
+	                  (GCallback) inner_auth_combo_changed_cb,
+	                  method);
+	return combo;
+}
+
+static void
+update_secrets (EAPMethod *parent, NMConnection *connection)
+{
+	eap_method_phase2_update_secrets_helper (parent,
+	                                         connection,
+	                                         "eap_peap_inner_auth_combo",
+	                                         I_METHOD_COLUMN);
+}
+
+EAPMethodPEAP *
+eap_method_peap_new (WirelessSecurity *ws_parent,
+                     NMConnection *connection,
+                     gboolean is_editor,
+                     gboolean secrets_only)
+{
+	EAPMethod *parent;
+	EAPMethodPEAP *method;
+	GtkWidget *widget;
+	GtkFileFilter *filter;
+	NMSetting8021x *s_8021x = NULL;
+	const char *filename;
+
+	parent = eap_method_init (sizeof (EAPMethodPEAP),
+	                          validate,
+	                          add_to_size_group,
+	                          fill_connection,
+	                          update_secrets,
+	                          destroy,
+	                          UIDIR "/eap-method-peap.ui",
+	                          "eap_peap_notebook",
+	                          "eap_peap_anon_identity_entry",
+	                          FALSE);
+	if (!parent)
+		return NULL;
+
+	eap_method_nag_init (parent, "eap_peap_ca_cert_button", connection);
+
+	method = (EAPMethodPEAP *) parent;
+	method->sec_parent = ws_parent;
+	method->is_editor = is_editor;
+
+	if (connection)
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button"));
+	g_assert (widget);
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
+	gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget),
+	                                   _("Choose a Certificate Authority certificate..."));
+	g_signal_connect (G_OBJECT (widget), "selection-changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+	filter = eap_method_default_file_chooser_filter_new (FALSE);
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
+	if (connection && s_8021x) {
+		if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+			filename = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+			if (filename)
+				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+		}
+	}
+
+	widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only);
+	inner_auth_combo_changed_cb (widget, (gpointer) method);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo"));
+	g_assert (widget);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+	if (s_8021x) {
+		const char *peapver;
+
+		peapver = nm_setting_802_1x_get_phase1_peapver (s_8021x);
+		if (peapver) {
+			/* Index 0 is "Automatic" */
+			if (!strcmp (peapver, "0"))
+				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+			else if (!strcmp (peapver, "1"))
+				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
+		}
+	}
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry"));
+	if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x))
+		gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x));
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	if (secrets_only) {
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo"));
+		gtk_widget_hide (widget);
+	}
+
+	return method;
+}
+
diff --git a/panels/network/wireless-security/eap-method-peap.h b/panels/network/wireless-security/eap-method-peap.h
new file mode 100644
index 0000000..752306c
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-peap.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_PEAP_H
+#define EAP_METHOD_PEAP_H
+
+#include "wireless-security.h"
+
+typedef struct _EAPMethodPEAP EAPMethodPEAP;
+
+EAPMethodPEAP *eap_method_peap_new (WirelessSecurity *ws_parent,
+                                    NMConnection *connection,
+                                    gboolean is_editor,
+                                    gboolean secrets_only);
+
+#endif /* EAP_METHOD_PEAP_H */
+
diff --git a/panels/network/wireless-security/eap-method-peap.ui b/panels/network/wireless-security/eap-method-peap.ui
new file mode 100644
index 0000000..4202237
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-peap.ui
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="model8">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes"> </col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="model9">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Automatic</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Version 0</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Version 1</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkNotebook" id="eap_peap_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table13">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">5</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="eap_peap_anon_identity_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Anony_mous identity</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_peap_anon_identity_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_peap_anon_identity_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_peap_ca_cert_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">C_A certificate</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_peap_ca_cert_button</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="eap_peap_ca_cert_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="eap_peap_inner_auth_vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="right_attach">2</property>
+            <property name="top_attach">4</property>
+            <property name="bottom_attach">5</property>
+            <property name="x_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_peap_inner_auth_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Inner authentication</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_peap_inner_auth_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="eap_peap_inner_auth_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model8</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer8"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_peap_version_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">PEAP _version</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_peap_version_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="eap_peap_version_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model9</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer9"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label61">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/eap-method-simple.c b/panels/network/wireless-security/eap-method-simple.c
new file mode 100644
index 0000000..43063dd
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-simple.c
@@ -0,0 +1,305 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-connection.h>
+
+#include "eap-method.h"
+#include "wireless-security.h"
+#include "helpers.h"
+
+struct _EAPMethodSimple {
+	EAPMethod parent;
+
+	EAPMethodSimpleType type;
+	gboolean is_editor;
+	gboolean new_connection;
+};
+
+static void
+show_toggled_cb (GtkCheckButton *button, EAPMethod *method)
+{
+	GtkWidget *widget;
+	gboolean visible;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_simple_password_entry"));
+	g_assert (widget);
+
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static gboolean
+validate (EAPMethod *parent)
+{
+	GtkWidget *widget;
+	const char *text;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!text || !strlen (text))
+		return FALSE;
+
+	/* Check if the password should always be requested */
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
+	g_assert (widget);
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+		return TRUE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!text || !strlen (text))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (EAPMethod *parent, NMConnection *connection)
+{
+	EAPMethodSimple *method = (EAPMethodSimple *) parent;
+	NMSetting8021x *s_8021x;
+	GtkWidget *widget;
+	gboolean not_saved = FALSE;
+	const char *eap = NULL;
+	NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	g_assert (s_8021x);
+
+	/* If this is the main EAP method, clear any existing methods because the
+	 * user-selected on will replace it.
+	 */
+	if (parent->phase2 == FALSE)
+		nm_setting_802_1x_clear_eap_methods (s_8021x);
+
+	switch (method->type) {
+		case EAP_METHOD_SIMPLE_TYPE_PAP:
+			eap = "pap";
+			break;
+		case EAP_METHOD_SIMPLE_TYPE_MSCHAP:
+			eap = "mschap";
+			break;
+		case EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2:
+			eap = "mschapv2";
+			break;
+		case EAP_METHOD_SIMPLE_TYPE_MD5:
+			eap = "md5";
+			break;
+		case EAP_METHOD_SIMPLE_TYPE_CHAP:
+			eap = "chap";
+			break;
+		case EAP_METHOD_SIMPLE_TYPE_GTC:
+			eap = "gtc";
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+	}
+
+	if (parent->phase2)
+		g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap, NULL);
+	else
+		nm_setting_802_1x_add_eap_method (s_8021x, eap);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
+	g_assert (widget);
+	g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+
+	/* Save the password always ask setting */
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
+	g_assert (widget);
+	not_saved = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+	nm_setting_get_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, &flags, NULL);
+	flags &= ~(NM_SETTING_SECRET_FLAG_NOT_SAVED);
+	if (not_saved)
+		flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED;
+	nm_setting_set_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, flags, NULL);
+
+	/* Fill the connection's password if we're in the applet so that it'll get
+	 * back to NM.  From the editor though, since the connection isn't going
+	 * back to NM in response to a GetSecrets() call, we don't save it if the
+	 * user checked "Always Ask".
+	 */
+	if (method->is_editor == FALSE || not_saved == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
+		g_assert (widget);
+		g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+	}
+
+	/* Default to agent-owned secrets for new connections */
+	if (method->new_connection && (not_saved == FALSE)) {
+		g_object_set (s_8021x,
+		              NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
+		              NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE,
+		              NULL);
+	}
+}
+
+static void
+update_secrets (EAPMethod *parent, NMConnection *connection)
+{
+	helper_fill_secret_entry (connection,
+	                          parent->builder,
+	                          "eap_simple_password_entry",
+	                          NM_TYPE_SETTING_802_1X,
+	                          (HelperSecretFunc) nm_setting_802_1x_get_password);
+}
+
+static void
+password_always_ask_changed (GtkButton *button, EAPMethodSimple *method)
+{
+	EAPMethod *parent = (EAPMethod *) method;
+	GtkWidget *password_entry;
+	GtkWidget *show_checkbox;
+	gboolean always_ask;
+
+	always_ask = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+
+	password_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
+	g_assert (password_entry);
+
+	show_checkbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple"));
+	g_assert (show_checkbox);
+
+	if (always_ask) {
+		gtk_entry_set_text (GTK_ENTRY (password_entry), "");
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_checkbox), FALSE);
+	}
+
+	gtk_widget_set_sensitive (password_entry, !always_ask);
+	gtk_widget_set_sensitive (show_checkbox, !always_ask);
+}
+
+EAPMethodSimple *
+eap_method_simple_new (WirelessSecurity *ws_parent,
+                       NMConnection *connection,
+                       EAPMethodSimpleType type,
+                       gboolean phase2,
+                       gboolean is_editor,
+                       gboolean secrets_only)
+{
+	EAPMethod *parent;
+	EAPMethodSimple *method;
+	GtkWidget *widget;
+	gboolean not_saved = FALSE;
+	NMSetting8021x *s_8021x = NULL;
+
+	parent = eap_method_init (sizeof (EAPMethodSimple),
+	                          validate,
+	                          add_to_size_group,
+	                          fill_connection,
+	                          update_secrets,
+	                          NULL,
+	                          UIDIR "/eap-method-simple.ui",
+	                          "eap_simple_notebook",
+	                          "eap_simple_username_entry",
+	                          phase2);
+	if (!parent)
+		return NULL;
+
+	method = (EAPMethodSimple *) parent;
+	method->type = type;
+	method->is_editor = is_editor;
+	method->new_connection = secrets_only ? FALSE : TRUE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+	if (connection) {
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+		if (s_8021x && nm_setting_802_1x_get_identity (s_8021x))
+			gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x));
+	}
+
+	if (secrets_only)
+		gtk_widget_set_sensitive (widget, FALSE);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+	if (is_editor) {
+		/* We only desensitize the password entry from the editor, because
+		 * from nm-applet if the entry was desensitized, there'd be no way to
+		 * get the password back to NetworkManager when NM asked for it.  Since
+		 * the editor only sets up the initial connection though, it's safe to
+		 * do there.
+		 */
+		g_signal_connect (G_OBJECT (widget), "toggled",
+		                  G_CALLBACK (password_always_ask_changed),
+		                  method);
+	}
+
+	if (secrets_only)
+		gtk_widget_hide (widget);
+
+	if (s_8021x) {
+		NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+		nm_setting_get_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, &flags, NULL);
+		not_saved = (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED);
+	}
+
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), not_saved);
+
+	/* Fill secrets if there's a static (ie, not OTP) password */
+	if (connection && (not_saved == FALSE))
+		update_secrets (EAP_METHOD (method), connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) show_toggled_cb,
+	                  method);
+
+	return method;
+}
+
diff --git a/panels/network/wireless-security/eap-method-simple.h b/panels/network/wireless-security/eap-method-simple.h
new file mode 100644
index 0000000..8a955dc
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-simple.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_SIMPLE_H
+#define EAP_METHOD_SIMPLE_H
+
+#include "wireless-security.h"
+
+typedef enum {
+	EAP_METHOD_SIMPLE_TYPE_PAP = 0,
+	EAP_METHOD_SIMPLE_TYPE_MSCHAP,
+	EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
+	EAP_METHOD_SIMPLE_TYPE_MD5,
+	EAP_METHOD_SIMPLE_TYPE_CHAP,
+	EAP_METHOD_SIMPLE_TYPE_GTC
+} EAPMethodSimpleType;
+
+typedef struct _EAPMethodSimple EAPMethodSimple;
+
+EAPMethodSimple *eap_method_simple_new (WirelessSecurity *ws_parent,
+                                        NMConnection *connection,
+                                        EAPMethodSimpleType type,
+                                        gboolean phase2,
+                                        gboolean is_editor,
+                                        gboolean secrets_only);
+
+#endif /* EAP_METHOD_SIMPLE_H */
+
diff --git a/panels/network/wireless-security/eap-method-simple.ui b/panels/network/wireless-security/eap-method-simple.ui
new file mode 100644
index 0000000..854c86f
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-simple.ui
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="eap_simple_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table11">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">3</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_simple_username_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Username</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_simple_username_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_simple_password_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_simple_password_entry</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_simple_password_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_simple_username_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkAlignment" id="alignment1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkVBox" id="vbox5">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkCheckButton" id="eap_password_always_ask">
+                    <property name="label" translatable="yes">As_k for this password every time</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="xalign">0.5</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="show_checkbutton_eapsimple">
+                    <property name="label" translatable="yes">Sho_w password</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="xalign">0</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label53">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/eap-method-tls.c b/panels/network/wireless-security/eap-method-tls.c
new file mode 100644
index 0000000..da02873
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-tls.c
@@ -0,0 +1,481 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-8021x.h>
+
+#include "eap-method.h"
+#include "wireless-security.h"
+#include "helpers.h"
+
+struct _EAPMethodTLS {
+	EAPMethod parent;
+
+	gboolean new_connection;
+};
+
+
+static void
+show_toggled_cb (GtkCheckButton *button, EAPMethod *method)
+{
+	GtkWidget *widget;
+	gboolean visible;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_tls_private_key_password_entry"));
+	g_assert (widget);
+
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static gboolean
+validate (EAPMethod *parent)
+{
+	NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+	GtkWidget *widget;
+	const char *password, *identity;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
+	g_assert (widget);
+	identity = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!identity || !strlen (identity))
+		return FALSE;
+
+	if (!eap_method_validate_filepicker (parent->builder, "eap_tls_ca_cert_button", TYPE_CA_CERT, NULL, NULL))
+		return FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
+	g_assert (widget);
+	password = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (!password || !strlen (password))
+		return FALSE;
+
+	if (!eap_method_validate_filepicker (parent->builder,
+	                                     "eap_tls_private_key_button",
+	                                     TYPE_PRIVATE_KEY,
+	                                     password,
+	                                     &format))
+		return FALSE;
+
+	if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
+		if (!eap_method_validate_filepicker (parent->builder, "eap_tls_user_cert_button", TYPE_CLIENT_CERT, NULL, NULL))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (EAPMethod *parent, NMConnection *connection)
+{
+	EAPMethodTLS *method = (EAPMethodTLS *) parent;
+	NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+	NMSetting8021x *s_8021x;
+	GtkWidget *widget;
+	char *ca_filename, *pk_filename, *cc_filename;
+	const char *password = NULL;
+	GError *error = NULL;
+	const char *secret_flag_prop = NULL;
+
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	g_assert (s_8021x);
+
+	if (parent->phase2)
+		g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL);
+	else
+		nm_setting_802_1x_add_eap_method (s_8021x, "tls");
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
+	g_assert (widget);
+	g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+
+	/* TLS private key */
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
+	g_assert (widget);
+	password = gtk_entry_get_text (GTK_ENTRY (widget));
+	g_assert (password);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"));
+	g_assert (widget);
+	pk_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	g_assert (pk_filename);
+
+	if (parent->phase2) {
+		if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+			g_warning ("Couldn't read phase2 private key '%s': %s", pk_filename, error ? error->message : "(unknown)");
+			g_clear_error (&error);
+		}
+		secret_flag_prop = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS;
+	} else {
+		if (!nm_setting_802_1x_set_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+			g_warning ("Couldn't read private key '%s': %s", pk_filename, error ? error->message : "(unknown)");
+			g_clear_error (&error);
+		}
+		secret_flag_prop = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS;
+	}
+	g_free (pk_filename);
+
+	/* Default to agent-owned secrets for new connections */
+	if (method->new_connection) {
+		g_object_set (s_8021x,
+		              secret_flag_prop, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
+		              NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE,
+		              NULL);
+	}
+
+	/* TLS client certificate */
+	if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
+		/* If the key is pkcs#12 nm_setting_802_1x_set_private_key() already
+		 * set the client certificate for us.
+		 */
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"));
+		g_assert (widget);
+		cc_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+		g_assert (cc_filename);
+
+		format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+		if (parent->phase2) {
+			if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+				g_warning ("Couldn't read phase2 client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)");
+				g_clear_error (&error);
+			}
+		} else {
+			if (!nm_setting_802_1x_set_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+				g_warning ("Couldn't read client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)");
+				g_clear_error (&error);
+			}
+		}
+		g_free (cc_filename);
+	}
+
+	/* TLS CA certificate */
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"));
+	g_assert (widget);
+	ca_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+
+	format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+	if (parent->phase2) {
+		if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+			g_warning ("Couldn't read phase2 CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)");
+			g_clear_error (&error);
+		}
+	} else {
+		if (!nm_setting_802_1x_set_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+			g_warning ("Couldn't read CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)");
+			g_clear_error (&error);
+		}
+	}
+}
+
+static void
+private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean changed)
+{
+	NMSetting8021x *setting;
+	NMSetting8021xCKFormat cert_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+	const char *password;
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
+	g_assert (widget);
+	password = gtk_entry_get_text (GTK_ENTRY (widget));
+
+	setting = (NMSetting8021x *) nm_setting_802_1x_new ();
+	nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &cert_format, NULL);
+	g_object_unref (setting);
+
+	/* With PKCS#12, the client cert must be the same as the private key */
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"));
+	if (cert_format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
+		gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget));
+		gtk_widget_set_sensitive (widget, FALSE);
+	} else if (changed)
+		gtk_widget_set_sensitive (widget, TRUE);
+
+	/* Warn the user if the private key is unencrypted */
+	if (!eap_method_is_encrypted_private_key (filename)) {
+		GtkWidget *dialog;
+		GtkWidget *toplevel;
+		GtkWindow *parent_window = NULL;
+
+		toplevel = gtk_widget_get_toplevel (parent->ui_widget);
+		if (gtk_widget_is_toplevel (toplevel))
+			parent_window = GTK_WINDOW (toplevel);
+
+		dialog = gtk_message_dialog_new (parent_window,
+		                                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+		                                 GTK_MESSAGE_WARNING,
+		                                 GTK_BUTTONS_OK,
+		                                 "%s",
+		                                 _("Unencrypted private keys are insecure"));
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+		                                          "%s",
+		                                          _("The selected private key does not appear to be protected by a password.  This could allow your security credentials to be compromised.  Please select a password-protected private key.\n\n(You can password-protect your private key with openssl)"));
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	}
+}
+
+static void
+private_key_picker_file_set_cb (GtkWidget *chooser, gpointer user_data)
+{
+	EAPMethod *parent = (EAPMethod *) user_data;
+	char *filename;
+
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
+	if (filename)
+		private_key_picker_helper (parent, filename, TRUE);
+	g_free (filename);
+}
+
+static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_data)
+{
+	if (!gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (widget))) {
+		g_signal_handlers_block_by_func (widget, reset_filter, user_data);
+		gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), GTK_FILE_FILTER (user_data));
+		g_signal_handlers_unblock_by_func (widget, reset_filter, user_data);
+	}
+}
+
+typedef const char * (*PathFunc) (NMSetting8021x *setting);
+typedef NMSetting8021xCKScheme (*SchemeFunc)  (NMSetting8021x *setting);
+
+static void
+setup_filepicker (GtkBuilder *builder,
+                  const char *name,
+                  const char *title,
+                  WirelessSecurity *ws_parent,
+                  EAPMethod *parent,
+                  NMSetting8021x *s_8021x,
+                  SchemeFunc scheme_func,
+                  PathFunc path_func,
+                  gboolean privkey,
+                  gboolean client_cert)
+{
+	GtkWidget *widget;
+	GtkFileFilter *filter;
+	const char *filename = NULL;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, name));
+	g_assert (widget);
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
+	gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), title);
+
+	if (s_8021x && path_func && scheme_func) {
+		if (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+			filename = path_func (s_8021x);
+			if (filename)
+				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+		}
+	}
+
+	/* Connect a special handler for private keys to intercept PKCS#12 key types
+	 * and desensitize the user cert button.
+	 */
+	if (privkey) {
+		g_signal_connect (G_OBJECT (widget), "selection-changed",
+		                  (GCallback) private_key_picker_file_set_cb,
+		                  parent);
+		if (filename)
+			private_key_picker_helper (parent, filename, FALSE);
+	}
+
+	g_signal_connect (G_OBJECT (widget), "selection-changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	filter = eap_method_default_file_chooser_filter_new (privkey);
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
+
+	/* For some reason, GTK+ calls set_current_filter (..., NULL) from 
+	 * gtkfilechooserdefault.c::show_and_select_files_finished_loading() on our
+	 * dialog; so force-reset the filter to what we want it to be whenever
+	 * it gets cleared.
+	 */
+	if (client_cert)
+		g_signal_connect (G_OBJECT (widget), "notify::filter", (GCallback) reset_filter, filter);
+}
+
+static void
+update_secrets (EAPMethod *parent, NMConnection *connection)
+{
+	NMSetting8021x *s_8021x;
+	HelperSecretFunc password_func;
+	SchemeFunc scheme_func;
+	PathFunc path_func;
+	const char *filename;
+	GtkWidget *widget;
+
+	if (parent->phase2) {
+		password_func = (HelperSecretFunc) nm_setting_802_1x_get_phase2_private_key_password;
+		scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme;
+		path_func = nm_setting_802_1x_get_phase2_private_key_path;
+	} else {
+		password_func = (HelperSecretFunc) nm_setting_802_1x_get_private_key_password;
+		scheme_func = nm_setting_802_1x_get_private_key_scheme;
+		path_func = nm_setting_802_1x_get_private_key_path;
+	}
+
+	helper_fill_secret_entry (connection,
+	                          parent->builder,
+	                          "eap_tls_private_key_password_entry",
+	                          NM_TYPE_SETTING_802_1X,
+	                          password_func);
+
+	/* Set the private key filepicker button path if we have a private key */
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	if (s_8021x && (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH)) {
+		filename = path_func (s_8021x);
+		if (filename) {
+			widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"));
+			g_assert (widget);
+			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+		}
+	}
+}
+
+EAPMethodTLS *
+eap_method_tls_new (WirelessSecurity *ws_parent,
+                    NMConnection *connection,
+                    gboolean phase2,
+                    gboolean secrets_only)
+{
+	EAPMethodTLS *method;
+	EAPMethod *parent;
+	GtkWidget *widget;
+	NMSetting8021x *s_8021x = NULL;
+
+	parent = eap_method_init (sizeof (EAPMethodTLS),
+	                          validate,
+	                          add_to_size_group,
+	                          fill_connection,
+	                          update_secrets,
+	                          NULL,
+	                          UIDIR "/eap-method-tls.ui",
+	                          "eap_tls_notebook",
+	                          "eap_tls_identity_entry",
+	                          phase2);
+	if (!parent)
+		return NULL;
+
+	method = (EAPMethodTLS *) parent;
+	method->new_connection = secrets_only ? FALSE : TRUE;
+
+	eap_method_nag_init (parent, "eap_tls_ca_cert_button", connection);
+
+	if (connection)
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+	if (s_8021x && nm_setting_802_1x_get_identity (s_8021x))
+		gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x));
+
+	setup_filepicker (parent->builder, "eap_tls_user_cert_button",
+	                  _("Choose your personal certificate..."),
+	                  ws_parent, parent, s_8021x,
+	                  phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme : nm_setting_802_1x_get_client_cert_scheme,
+	                  phase2 ? nm_setting_802_1x_get_phase2_client_cert_path : nm_setting_802_1x_get_client_cert_path,
+	                  FALSE, TRUE);
+	setup_filepicker (parent->builder, "eap_tls_ca_cert_button",
+	                  _("Choose a Certificate Authority certificate..."),
+	                  ws_parent, parent, s_8021x,
+	                  phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme : nm_setting_802_1x_get_ca_cert_scheme,
+	                  phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path : nm_setting_802_1x_get_ca_cert_path,
+	                  FALSE, FALSE);
+	setup_filepicker (parent->builder, "eap_tls_private_key_button",
+	                  _("Choose your private key..."),
+	                  ws_parent, parent, s_8021x,
+	                  phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : nm_setting_802_1x_get_private_key_scheme,
+	                  phase2 ? nm_setting_802_1x_get_phase2_private_key_path : nm_setting_802_1x_get_private_key_path,
+	                  TRUE, FALSE);
+
+	/* Fill secrets, if any */
+	if (connection)
+		update_secrets (parent, connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eaptls"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) show_toggled_cb,
+	                  parent);
+
+	if (secrets_only) {
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"));
+		gtk_widget_hide (widget);
+	}
+
+	return method;
+}
+
diff --git a/panels/network/wireless-security/eap-method-tls.h b/panels/network/wireless-security/eap-method-tls.h
new file mode 100644
index 0000000..147a75f
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-tls.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_TLS_H
+#define EAP_METHOD_TLS_H
+
+#include "wireless-security.h"
+
+typedef struct _EAPMethodTLS EAPMethodTLS;
+
+EAPMethodTLS *eap_method_tls_new (WirelessSecurity *ws_parent,
+                                  NMConnection *connection,
+                                  gboolean phase2,
+                                  gboolean secrets_only);
+
+#endif /* EAP_METHOD_TLS_H */
+
diff --git a/panels/network/wireless-security/eap-method-tls.ui b/panels/network/wireless-security/eap-method-tls.ui
new file mode 100644
index 0000000..028e73e
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-tls.ui
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="eap_tls_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table8">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">6</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_tls_identity_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">I_dentity</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_tls_identity_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_tls_identity_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_tls_user_cert_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_User certificate</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_tls_user_cert_button</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_tls_ca_cert_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">C_A certificate</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_tls_ca_cert_button</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="eap_tls_ca_cert_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_tls_private_key_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Private _key</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_tls_private_key_button</property>
+          </object>
+          <packing>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="eap_tls_private_key_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_tls_private_key_password_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Private key password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_tls_private_key_password_entry</property>
+          </object>
+          <packing>
+            <property name="top_attach">4</property>
+            <property name="bottom_attach">5</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_tls_private_key_password_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">4</property>
+            <property name="bottom_attach">5</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_checkbutton_eaptls">
+            <property name="label" translatable="yes">Sho_w password</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="xalign">0</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">5</property>
+            <property name="bottom_attach">6</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="eap_tls_user_cert_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label34">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/eap-method-ttls.c b/panels/network/wireless-security/eap-method-ttls.c
new file mode 100644
index 0000000..65346c2
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-ttls.c
@@ -0,0 +1,391 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-8021x.h>
+
+#include "eap-method.h"
+#include "wireless-security.h"
+
+#define I_NAME_COLUMN   0
+#define I_METHOD_COLUMN 1
+
+struct _EAPMethodTTLS {
+	EAPMethod parent;
+
+	GtkSizeGroup *size_group;
+	WirelessSecurity *sec_parent;
+	gboolean is_editor;
+};
+
+static void
+destroy (EAPMethod *parent)
+{
+	EAPMethodTTLS *method = (EAPMethodTTLS *) parent;
+
+	if (method->size_group)
+		g_object_unref (method->size_group);
+}
+
+static gboolean
+validate (EAPMethod *parent)
+{
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap = NULL;
+	gboolean valid = FALSE;
+
+	if (!eap_method_validate_filepicker (parent->builder, "eap_ttls_ca_cert_button", TYPE_CA_CERT, NULL, NULL))
+		return FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	valid = eap_method_validate (eap);
+	eap_method_unref (eap);
+	return valid;
+}
+
+static void
+add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
+{
+	EAPMethodTTLS *method = (EAPMethodTTLS *) parent;
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap;
+
+	if (method->size_group)
+		g_object_unref (method->size_group);
+	method->size_group = g_object_ref (group);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_label"));
+	g_assert (widget);
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	eap_method_add_to_size_group (eap, group);
+	eap_method_unref (eap);
+}
+
+static void
+fill_connection (EAPMethod *parent, NMConnection *connection)
+{
+	NMSetting8021x *s_8021x;
+	NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+	GtkWidget *widget;
+	const char *text;
+	char *filename;
+	EAPMethod *eap = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GError *error = NULL;
+
+	s_8021x = nm_connection_get_setting_802_1x (connection);
+	g_assert (s_8021x);
+
+	nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry"));
+	g_assert (widget);
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	if (text && strlen (text))
+		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button"));
+	g_assert (widget);
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) {
+		g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)");
+		g_clear_error (&error);
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_method_fill_connection (eap, connection);
+	eap_method_unref (eap);
+}
+
+static void
+inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data)
+{
+	EAPMethod *parent = (EAPMethod *) user_data;
+	EAPMethodTTLS *method = (EAPMethodTTLS *) parent;
+	GtkWidget *vbox;
+	EAPMethod *eap = NULL;
+	GList *elt, *children;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkWidget *eap_widget;
+
+	vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_vbox"));
+	g_assert (vbox);
+
+	/* Remove any previous wireless security widgets */
+	children = gtk_container_get_children (GTK_CONTAINER (vbox));
+	for (elt = children; elt; elt = g_list_next (elt))
+		gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data));
+	g_list_free (children);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter);
+	gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_widget = eap_method_get_widget (eap);
+	g_assert (eap_widget);
+	gtk_widget_unparent (eap_widget);
+
+	if (method->size_group)
+		eap_method_add_to_size_group (eap, method->size_group);
+	gtk_container_add (GTK_CONTAINER (vbox), eap_widget);
+
+	eap_method_unref (eap);
+
+	wireless_security_changed_cb (combo, method->sec_parent);
+}
+
+static GtkWidget *
+inner_auth_combo_init (EAPMethodTTLS *method,
+                       NMConnection *connection,
+                       NMSetting8021x *s_8021x,
+                       gboolean secrets_only)
+{
+	EAPMethod *parent = (EAPMethod *) method;
+	GtkWidget *combo;
+	GtkListStore *auth_model;
+	GtkTreeIter iter;
+	EAPMethodSimple *em_pap;
+	EAPMethodSimple *em_mschap;
+	EAPMethodSimple *em_mschap_v2;
+	EAPMethodSimple *em_chap;
+	guint32 active = 0;
+	const char *phase2_auth = NULL;
+
+	auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_type ());
+
+	if (s_8021x) {
+		if (nm_setting_802_1x_get_phase2_auth (s_8021x))
+			phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x);
+		else if (nm_setting_802_1x_get_phase2_autheap (s_8021x))
+			phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x);
+	}
+
+	em_pap = eap_method_simple_new (method->sec_parent,
+	                                connection,
+	                                EAP_METHOD_SIMPLE_TYPE_PAP,
+	                                TRUE,
+	                                method->is_editor,
+	                                secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("PAP"),
+	                    I_METHOD_COLUMN, em_pap,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_pap));
+
+	/* Check for defaulting to PAP */
+	if (phase2_auth && !strcasecmp (phase2_auth, "pap"))
+		active = 0;
+
+	em_mschap = eap_method_simple_new (method->sec_parent,
+	                                   connection,
+	                                   EAP_METHOD_SIMPLE_TYPE_MSCHAP,
+	                                   TRUE,
+	                                   method->is_editor,
+	                                   secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("MSCHAP"),
+	                    I_METHOD_COLUMN, em_mschap,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_mschap));
+
+	/* Check for defaulting to MSCHAP */
+	if (phase2_auth && !strcasecmp (phase2_auth, "mschap"))
+		active = 1;
+
+	em_mschap_v2 = eap_method_simple_new (method->sec_parent,
+	                                      connection,
+	                                      EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
+	                                      TRUE,
+	                                      method->is_editor, secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("MSCHAPv2"),
+	                    I_METHOD_COLUMN, em_mschap_v2,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_mschap_v2));
+
+	/* Check for defaulting to MSCHAPv2 */
+	if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2"))
+		active = 2;
+
+	em_chap = eap_method_simple_new (method->sec_parent,
+	                                 connection,
+	                                 EAP_METHOD_SIMPLE_TYPE_CHAP,
+	                                 TRUE,
+	                                 method->is_editor,
+	                                 secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    I_NAME_COLUMN, _("CHAP"),
+	                    I_METHOD_COLUMN, em_chap,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_chap));
+
+	/* Check for defaulting to CHAP */
+	if (phase2_auth && !strcasecmp (phase2_auth, "chap"))
+		active = 3;
+
+	combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
+	g_assert (combo);
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model));
+	g_object_unref (G_OBJECT (auth_model));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
+
+	g_signal_connect (G_OBJECT (combo), "changed",
+	                  (GCallback) inner_auth_combo_changed_cb,
+	                  method);
+	return combo;
+}
+
+static void
+update_secrets (EAPMethod *parent, NMConnection *connection)
+{
+	eap_method_phase2_update_secrets_helper (parent,
+	                                         connection,
+	                                         "eap_ttls_inner_auth_combo",
+	                                         I_METHOD_COLUMN);
+}
+
+EAPMethodTTLS *
+eap_method_ttls_new (WirelessSecurity *ws_parent,
+                     NMConnection *connection,
+                     gboolean is_editor,
+                     gboolean secrets_only)
+{
+	EAPMethod *parent;
+	EAPMethodTTLS *method;
+	GtkWidget *widget;
+	GtkFileFilter *filter;
+	NMSetting8021x *s_8021x = NULL;
+	const char *filename;
+
+	parent = eap_method_init (sizeof (EAPMethodTTLS),
+	                          validate,
+	                          add_to_size_group,
+	                          fill_connection,
+	                          update_secrets,
+	                          destroy,
+	                          UIDIR "/eap-method-ttls.ui",
+	                          "eap_ttls_notebook",
+	                          "eap_ttls_anon_identity_entry",
+	                          FALSE);
+	if (!parent)
+		return NULL;
+
+	eap_method_nag_init (parent, "eap_ttls_ca_cert_button", connection);
+
+	method = (EAPMethodTTLS *) parent;
+	method->sec_parent = ws_parent;
+	method->is_editor = is_editor;
+
+	if (connection)
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button"));
+	g_assert (widget);
+	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
+	gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget),
+	                                   _("Choose a Certificate Authority certificate..."));
+	g_signal_connect (G_OBJECT (widget), "selection-changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+	filter = eap_method_default_file_chooser_filter_new (FALSE);
+	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);
+	if (connection && s_8021x) {
+		if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+			filename = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+			if (filename)
+				gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename);
+		}
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry"));
+	if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x))
+		gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x));
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  ws_parent);
+
+	widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only);
+	inner_auth_combo_changed_cb (widget, (gpointer) method);
+
+	if (secrets_only) {
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_label"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo"));
+		gtk_widget_hide (widget);
+	}
+
+	return method;
+}
+
diff --git a/panels/network/wireless-security/eap-method-ttls.h b/panels/network/wireless-security/eap-method-ttls.h
new file mode 100644
index 0000000..16467f6
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-ttls.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_TTLS_H
+#define EAP_METHOD_TTLS_H
+
+#include "wireless-security.h"
+
+typedef struct _EAPMethodTTLS EAPMethodTTLS;
+
+EAPMethodTTLS *eap_method_ttls_new (WirelessSecurity *ws_parent,
+                                    NMConnection *connection,
+                                    gboolean is_editor,
+                                    gboolean secrets_only);
+
+#endif /* EAP_METHOD_TLS_H */
+
diff --git a/panels/network/wireless-security/eap-method-ttls.ui b/panels/network/wireless-security/eap-method-ttls.ui
new file mode 100644
index 0000000..39465cf
--- /dev/null
+++ b/panels/network/wireless-security/eap-method-ttls.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="model6">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes"> </col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkNotebook" id="eap_ttls_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table10">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">4</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="eap_ttls_anon_identity_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Anony_mous identity</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_ttls_anon_identity_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="eap_ttls_anon_identity_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_ttls_ca_cert_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">C_A certificate</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_ttls_ca_cert_button</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="eap_ttls_ca_cert_button">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="eap_ttls_inner_auth_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Inner authentication</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">eap_ttls_inner_auth_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="eap_ttls_inner_auth_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model6</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer6"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="eap_ttls_inner_auth_vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">6</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="right_attach">2</property>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label49">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/eap-method.c b/panels/network/wireless-security/eap-method.c
new file mode 100644
index 0000000..a3fd832
--- /dev/null
+++ b/panels/network/wireless-security/eap-method.c
@@ -0,0 +1,660 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2012 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-8021x.h>
+#include "eap-method.h"
+#include "nm-utils.h"
+
+GType
+eap_method_get_g_type (void)
+{
+	static GType type_id = 0;
+
+	if (!type_id) {
+		type_id = g_boxed_type_register_static ("EAPMethod",
+		                                        (GBoxedCopyFunc) eap_method_ref,
+		                                        (GBoxedFreeFunc) eap_method_unref);
+	}
+
+	return type_id;
+}
+
+GtkWidget *
+eap_method_get_widget (EAPMethod *method)
+{
+	g_return_val_if_fail (method != NULL, NULL);
+
+	return method->ui_widget;
+}
+
+gboolean
+eap_method_validate (EAPMethod *method)
+{
+	g_return_val_if_fail (method != NULL, FALSE);
+
+	g_assert (method->validate);
+	return (*(method->validate)) (method);
+}
+
+void
+eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group)
+{
+	g_return_if_fail (method != NULL);
+	g_return_if_fail (group != NULL);
+
+	g_assert (method->add_to_size_group);
+	return (*(method->add_to_size_group)) (method, group);
+}
+
+void
+eap_method_fill_connection (EAPMethod *method, NMConnection *connection)
+{
+	g_return_if_fail (method != NULL);
+	g_return_if_fail (connection != NULL);
+
+	g_assert (method->fill_connection);
+	return (*(method->fill_connection)) (method, connection);
+}
+
+void
+eap_method_update_secrets (EAPMethod *method, NMConnection *connection)
+{
+	g_return_if_fail (method != NULL);
+	g_return_if_fail (connection != NULL);
+
+	if (method->update_secrets)
+		method->update_secrets (method, connection);
+}
+
+typedef struct {
+	EAPMethod *method;
+	NMConnection *connection;
+} NagDialogResponseInfo;
+
+static void
+nag_dialog_destroyed (gpointer data, GObject *dialog_ptr)
+{
+	NagDialogResponseInfo *info = (NagDialogResponseInfo *) data;
+
+	memset (info, '\0', sizeof (NagDialogResponseInfo));
+	g_free (info);
+}
+
+static GSettings *
+_get_ca_ignore_settings (const char *uuid)
+{
+	GSettings *settings;
+	char *path = NULL;
+
+	path = g_strdup_printf ("/org/gnome/nm-applet/eap/%s", uuid);
+	settings = g_settings_new_with_path ("org.gnome.nm-applet.eap", path);
+	g_free (path);
+
+	return settings;
+}
+
+static void
+_set_ignore_ca_cert (const char *uuid, gboolean phase2, gboolean ignore)
+{
+	GSettings *settings;
+	const char *key;
+
+	g_return_if_fail (uuid != NULL);
+
+	settings = _get_ca_ignore_settings (uuid);
+	key = phase2 ? "ignore-phase2-ca-cert" : "ignore-ca-cert";
+	g_settings_set_boolean (settings, key, ignore);
+	g_object_unref (settings);
+}
+
+static void
+nag_dialog_response_cb (GtkDialog *nag_dialog,
+                        gint response,
+                        gpointer user_data)
+{
+	NagDialogResponseInfo *info = (NagDialogResponseInfo *) user_data;
+	EAPMethod *method = (EAPMethod *) info->method;
+	NMConnection *connection = (NMConnection *) info->connection;
+	GtkWidget *widget;
+
+	if (response == GTK_RESPONSE_NO) {
+		/* Grab the value of the "don't bother me" checkbox */
+		widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_checkbox"));
+		g_assert (widget);
+
+		method->ignore_ca_cert = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+		/* And save it */
+		_set_ignore_ca_cert (nm_connection_get_uuid (connection),
+		                     method->phase2,
+		                     method->ignore_ca_cert);
+	}
+
+	gtk_widget_hide (GTK_WIDGET (nag_dialog));
+}
+
+static gboolean 
+nag_dialog_delete_event_cb (GtkDialog *nag_dialog, GdkEvent *e, gpointer user_data) 
+{ 
+	// FIXME?: By emitting response signal, dismissing nag dialog with upper right "x" icon,
+	// Alt-F4, or Esc would have the same behaviour as clicking "Ignore" button.
+	//g_signal_emit_by_name (nag_dialog, "response", GTK_RESPONSE_NO, user_data);
+	return TRUE;  /* do not destroy */
+} 
+
+GtkWidget *
+eap_method_nag_user (EAPMethod *method)
+{
+	GtkWidget *widget;
+	char *filename = NULL;
+
+	g_return_val_if_fail (method != NULL, NULL);
+
+	if (!method->nag_dialog || method->ignore_ca_cert)
+		return NULL;
+
+	/* Checkbox should be unchecked each time dialog comes up */
+	widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_checkbox"));
+	g_assert (widget);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+
+	/* Nag the user if the CA Cert is blank, since it's a security risk. */
+	widget = GTK_WIDGET (gtk_builder_get_object (method->builder, method->ca_cert_chooser));
+	g_assert (widget);
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	if (filename != NULL) {
+		g_free (filename);
+		return NULL;
+	}
+
+	gtk_window_present (GTK_WINDOW (method->nag_dialog));
+	return method->nag_dialog;
+}
+
+#define NAG_DIALOG_UI UIDIR "/nag-user-dialog.ui"
+
+static gboolean
+_get_ignore_ca_cert (const char *uuid, gboolean phase2)
+{
+	GSettings *settings;
+	const char *key;
+	gboolean ignore = FALSE;
+
+	g_return_val_if_fail (uuid != NULL, FALSE);
+
+	settings = _get_ca_ignore_settings (uuid);
+
+	key = phase2 ? "ignore-phase2-ca-cert" : "ignore-ca-cert";
+	ignore = g_settings_get_boolean (settings, key);
+
+	g_object_unref (settings);
+	return ignore;
+}
+
+gboolean
+eap_method_nag_init (EAPMethod *method,
+                     const char *ca_cert_chooser,
+                     NMConnection *connection)
+{
+	GtkWidget *dialog, *widget;
+	NagDialogResponseInfo *info;
+	GError *error = NULL;
+	char *text;
+
+	g_return_val_if_fail (method != NULL, FALSE);
+	g_return_val_if_fail (ca_cert_chooser != NULL, FALSE);
+
+	method->nag_builder = gtk_builder_new ();
+	if (!gtk_builder_add_from_file (method->nag_builder, NAG_DIALOG_UI, &error)) {
+		g_warning ("Couldn't load UI builder file " NAG_DIALOG_UI ": %s",
+		           error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	method->ca_cert_chooser = g_strdup (ca_cert_chooser);
+	if (connection) {
+		NMSettingConnection *s_con;
+		const char *uuid;
+
+		s_con = nm_connection_get_setting_connection (connection);
+		g_assert (s_con);
+		uuid = nm_setting_connection_get_uuid (s_con);
+		g_assert (uuid);
+
+		/* Figure out if the user wants to ignore missing CA cert */
+		method->ignore_ca_cert = _get_ignore_ca_cert (uuid, method->phase2);
+	}
+
+	info = g_malloc0 (sizeof (NagDialogResponseInfo));
+	info->method = method;
+	info->connection = connection;
+
+	dialog = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "nag_user_dialog"));
+	g_assert (dialog);
+	g_signal_connect (dialog, "response", G_CALLBACK (nag_dialog_response_cb), info);
+	g_signal_connect (dialog, "delete-event", G_CALLBACK (nag_dialog_delete_event_cb), info);
+	g_object_weak_ref (G_OBJECT (dialog), nag_dialog_destroyed, info);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "content_label"));
+	g_assert (widget);
+
+	text = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",
+	                        _("No Certificate Authority certificate chosen"),
+	                        _("Not using a Certificate Authority (CA) certificate can result in connections to insecure, rogue Wi-Fi networks.  Would you like to choose a Certificate Authority certificate?"));
+	gtk_label_set_markup (GTK_LABEL (widget), text);
+	g_free (text);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_button"));
+	gtk_button_set_label (GTK_BUTTON (widget), _("Ignore"));
+	g_assert (widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "change_button"));
+	gtk_button_set_label (GTK_BUTTON (widget), _("Choose CA Certificate"));
+	g_assert (widget);
+
+	method->nag_dialog = dialog;
+	return TRUE;
+}
+
+void
+eap_method_phase2_update_secrets_helper (EAPMethod *method,
+                                         NMConnection *connection,
+                                         const char *combo_name,
+                                         guint32 column)
+{
+	GtkWidget *combo;
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	g_return_if_fail (method != NULL);
+	g_return_if_fail (connection != NULL);
+	g_return_if_fail (combo_name != NULL);
+
+	combo = GTK_WIDGET (gtk_builder_get_object (method->builder, combo_name));
+	g_assert (combo);
+
+	/* Let each EAP phase2 method try to update its secrets */
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+	if (gtk_tree_model_get_iter_first (model, &iter)) {
+		do {
+			EAPMethod *eap = NULL;
+
+			gtk_tree_model_get (model, &iter, column, &eap, -1);
+			if (eap) {
+				eap_method_update_secrets (eap, connection);
+				eap_method_unref (eap);
+			}
+		} while (gtk_tree_model_iter_next (model, &iter));
+	}
+}
+
+EAPMethod *
+eap_method_init (gsize obj_size,
+                 EMValidateFunc validate,
+                 EMAddToSizeGroupFunc add_to_size_group,
+                 EMFillConnectionFunc fill_connection,
+                 EMUpdateSecretsFunc update_secrets,
+                 EMDestroyFunc destroy,
+                 const char *ui_file,
+                 const char *ui_widget_name,
+                 const char *default_field,
+                 gboolean phase2)
+{
+	EAPMethod *method;
+	GError *error = NULL;
+
+	g_return_val_if_fail (obj_size > 0, NULL);
+	g_return_val_if_fail (ui_file != NULL, NULL);
+	g_return_val_if_fail (ui_widget_name != NULL, NULL);
+
+	method = g_slice_alloc0 (obj_size);
+	g_assert (method);
+
+	method->refcount = 1;
+	method->obj_size = obj_size;
+	method->validate = validate;
+	method->add_to_size_group = add_to_size_group;
+	method->fill_connection = fill_connection;
+	method->update_secrets = update_secrets;
+	method->destroy = destroy;
+	method->default_field = default_field;
+	method->phase2 = phase2;
+
+	method->builder = gtk_builder_new ();
+	if (!gtk_builder_add_from_file (method->builder, ui_file, &error)) {
+		g_warning ("Couldn't load UI builder file %s: %s",
+		           ui_file, error->message);
+		eap_method_unref (method);
+		return NULL;
+	}
+
+	method->ui_widget = GTK_WIDGET (gtk_builder_get_object (method->builder, ui_widget_name));
+	if (!method->ui_widget) {
+		g_warning ("Couldn't load UI widget '%s' from UI file %s",
+		           ui_widget_name, ui_file);
+		eap_method_unref (method);
+		return NULL;
+	}
+	g_object_ref_sink (method->ui_widget);
+
+	return method;
+}
+
+
+EAPMethod *
+eap_method_ref (EAPMethod *method)
+{
+	g_return_val_if_fail (method != NULL, NULL);
+	g_return_val_if_fail (method->refcount > 0, NULL);
+
+	method->refcount++;
+	return method;
+}
+
+void
+eap_method_unref (EAPMethod *method)
+{
+	g_return_if_fail (method != NULL);
+	g_return_if_fail (method->refcount > 0);
+
+	method->refcount--;
+	if (method->refcount == 0) {
+		if (method->destroy)
+			method->destroy (method);
+
+		if (method->nag_dialog)
+			gtk_widget_destroy (method->nag_dialog);
+		if (method->nag_builder)
+			g_object_unref (method->nag_builder);
+		g_free (method->ca_cert_chooser);
+		if (method->builder)
+			g_object_unref (method->builder);
+		if (method->ui_widget)
+			g_object_unref (method->ui_widget);
+
+		g_slice_free1 (method->obj_size, method);
+	}
+}
+
+gboolean
+eap_method_validate_filepicker (GtkBuilder *builder,
+                                const char *name,
+                                guint32 item_type,
+                                const char *password,
+                                NMSetting8021xCKFormat *out_format)
+{
+	GtkWidget *widget;
+	char *filename;
+	NMSetting8021x *setting;
+	gboolean success = FALSE;
+	GError *error = NULL;
+
+	if (item_type == TYPE_PRIVATE_KEY) {
+		g_return_val_if_fail (password != NULL, FALSE);
+		g_return_val_if_fail (strlen (password), FALSE);
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, name));
+	g_assert (widget);
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+	if (!filename)
+		return (item_type == TYPE_CA_CERT) ? TRUE : FALSE;
+
+	if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+		goto out;
+
+	setting = (NMSetting8021x *) nm_setting_802_1x_new ();
+
+	if (item_type == TYPE_PRIVATE_KEY) {
+		if (!nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, &error)) {
+			g_warning ("Error: couldn't verify private key: %d %s",
+			           error ? error->code : -1, error ? error->message : "(none)");
+			g_clear_error (&error);
+		} else
+			success = TRUE;
+	} else if (item_type == TYPE_CLIENT_CERT) {
+		if (!nm_setting_802_1x_set_client_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, &error)) {
+			g_warning ("Error: couldn't verify client certificate: %d %s",
+			           error ? error->code : -1, error ? error->message : "(none)");
+			g_clear_error (&error);
+		} else
+			success = TRUE;
+	} else if (item_type == TYPE_CA_CERT) {
+		if (!nm_setting_802_1x_set_ca_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, &error)) {
+			g_warning ("Error: couldn't verify CA certificate: %d %s",
+			           error ? error->code : -1, error ? error->message : "(none)");
+			g_clear_error (&error);
+		} else
+			success = TRUE;
+	} else
+		g_warning ("%s: invalid item type %d.", __func__, item_type);
+
+	g_object_unref (setting);
+
+out:
+	g_free (filename);
+	return success;
+}
+
+static const char *
+find_tag (const char *tag, const char *buf, gsize len)
+{
+	gsize i, taglen;
+
+	taglen = strlen (tag);
+	if (len < taglen)
+		return NULL;
+
+	for (i = 0; i < len - taglen + 1; i++) {
+		if (memcmp (buf + i, tag, taglen) == 0)
+			return buf + i;
+	}
+	return NULL;
+}
+
+static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----";
+static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----";
+static const char *pem_pkcs8_enc_key_begin = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
+static const char *pem_pkcs8_dec_key_begin = "-----BEGIN PRIVATE KEY-----";
+static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----";
+static const char *proc_type_tag = "Proc-Type: 4,ENCRYPTED";
+static const char *dek_info_tag = "DEK-Info:";
+
+static gboolean
+file_has_extension (const char *filename, const char *extensions[])
+{
+	char *p, *ext;
+	int i = 0;
+	gboolean found = FALSE;
+
+	p = strrchr (filename, '.');
+	if (!p)
+		return FALSE;
+
+	ext = g_ascii_strdown (p, -1);
+	if (ext) {
+		while (extensions[i]) {
+			if (!strcmp (ext, extensions[i++])) {
+				found = TRUE;
+				break;
+			}
+		}
+	}
+	g_free (ext);
+
+	return found;
+}
+
+static gboolean
+pem_file_is_encrypted (const char *buffer, gsize bytes_read)
+{
+	/* Check if the private key is encrypted or not by looking for the
+	 * old OpenSSL-style proc-type and dec-info tags.
+	 */
+	if (find_tag (proc_type_tag, (const char *) buffer, bytes_read)) {
+		if (find_tag (dek_info_tag, (const char *) buffer, bytes_read))
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static gboolean
+file_is_der_or_pem (const char *filename,
+                    gboolean privkey,
+                    gboolean *out_privkey_encrypted)
+{
+	int fd;
+	unsigned char buffer[8192];
+	ssize_t bytes_read;
+	gboolean success = FALSE;
+
+	fd = open (filename, O_RDONLY);
+	if (fd < 0)
+		return FALSE;
+
+	bytes_read = read (fd, buffer, sizeof (buffer) - 1);
+	if (bytes_read < 400)  /* needs to be lower? */
+		goto out;
+	buffer[bytes_read] = '\0';
+
+	/* Check for DER signature */
+	if (bytes_read > 2 && buffer[0] == 0x30 && buffer[1] == 0x82) {
+		success = TRUE;
+		goto out;
+	}
+
+	/* Check for PEM signatures */
+	if (privkey) {
+		if (find_tag (pem_rsa_key_begin, (const char *) buffer, bytes_read)) {
+			success = TRUE;
+			if (out_privkey_encrypted)
+				*out_privkey_encrypted = pem_file_is_encrypted ((const char *) buffer, bytes_read);
+			goto out;
+		}
+
+		if (find_tag (pem_dsa_key_begin, (const char *) buffer, bytes_read)) {
+			success = TRUE;
+			if (out_privkey_encrypted)
+				*out_privkey_encrypted = pem_file_is_encrypted ((const char *) buffer, bytes_read);
+			goto out;
+		}
+
+		if (find_tag (pem_pkcs8_enc_key_begin, (const char *) buffer, bytes_read)) {
+			success = TRUE;
+			if (out_privkey_encrypted)
+				*out_privkey_encrypted = TRUE;
+			goto out;
+		}
+
+		if (find_tag (pem_pkcs8_dec_key_begin, (const char *) buffer, bytes_read)) {
+			success = TRUE;
+			if (out_privkey_encrypted)
+				*out_privkey_encrypted = FALSE;
+			goto out;
+		}
+	} else {
+		if (find_tag (pem_cert_begin, (const char *) buffer, bytes_read)) {
+			success = TRUE;
+			goto out;
+		}
+	}
+
+out:
+	close (fd);
+	return success;
+}
+
+static gboolean
+default_filter_privkey (const GtkFileFilterInfo *filter_info, gpointer user_data)
+{
+	const char *extensions[] = { ".der", ".pem", ".p12", NULL };
+	gboolean require_encrypted = !!user_data;
+	gboolean is_encrypted = TRUE;
+
+	if (!filter_info->filename)
+		return FALSE;
+
+	if (!file_has_extension (filter_info->filename, extensions))
+		return FALSE;
+
+	if (   !file_is_der_or_pem (filter_info->filename, TRUE, &is_encrypted)
+	    && !nm_utils_file_is_pkcs12 (filter_info->filename))
+		return FALSE;
+
+	return require_encrypted ? is_encrypted : TRUE;
+}
+
+static gboolean
+default_filter_cert (const GtkFileFilterInfo *filter_info, gpointer user_data)
+{
+	const char *extensions[] = { ".der", ".pem", ".crt", ".cer", NULL };
+
+	if (!filter_info->filename)
+		return FALSE;
+
+	if (!file_has_extension (filter_info->filename, extensions))
+		return FALSE;
+
+	if (!file_is_der_or_pem (filter_info->filename, FALSE, NULL))
+		return FALSE;
+
+	return TRUE;
+}
+
+GtkFileFilter *
+eap_method_default_file_chooser_filter_new (gboolean privkey)
+{
+	GtkFileFilter *filter;
+
+	filter = gtk_file_filter_new ();
+	if (privkey) {
+		gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, default_filter_privkey, NULL, NULL);
+		gtk_file_filter_set_name (filter, _("DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12)"));
+	} else {
+		gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, default_filter_cert, NULL, NULL);
+		gtk_file_filter_set_name (filter, _("DER or PEM certificates (*.der, *.pem, *.crt, *.cer)"));
+	}
+	return filter;
+}
+
+gboolean
+eap_method_is_encrypted_private_key (const char *path)
+{
+	GtkFileFilterInfo info = { .filename = path };
+
+	return default_filter_privkey (&info, (gpointer) TRUE);
+}
+
diff --git a/panels/network/wireless-security/eap-method.h b/panels/network/wireless-security/eap-method.h
new file mode 100644
index 0000000..fdfa1a8
--- /dev/null
+++ b/panels/network/wireless-security/eap-method.h
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2012 Red Hat, Inc.
+ */
+
+#ifndef EAP_METHOD_H
+#define EAP_METHOD_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <nm-connection.h>
+#include <nm-setting-8021x.h>
+
+typedef struct _EAPMethod EAPMethod;
+
+typedef void        (*EMAddToSizeGroupFunc) (EAPMethod *method, GtkSizeGroup *group);
+typedef void        (*EMFillConnectionFunc) (EAPMethod *method, NMConnection *connection);
+typedef void        (*EMUpdateSecretsFunc)  (EAPMethod *method, NMConnection *connection);
+typedef void        (*EMDestroyFunc)        (EAPMethod *method);
+typedef gboolean    (*EMValidateFunc)       (EAPMethod *method);
+
+struct _EAPMethod {
+	guint32 refcount;
+	gsize obj_size;
+
+	GtkBuilder *builder;
+	GtkWidget *ui_widget;
+
+	GtkBuilder *nag_builder;
+	char *ca_cert_chooser;
+	const char *default_field;
+	GtkWidget *nag_dialog;
+
+	gboolean phase2;
+	gboolean secrets_only;
+	gboolean ignore_ca_cert;
+
+	EMAddToSizeGroupFunc add_to_size_group;
+	EMFillConnectionFunc fill_connection;
+	EMUpdateSecretsFunc update_secrets;
+	EMValidateFunc validate;
+	EMDestroyFunc destroy;
+};
+
+#define EAP_METHOD(x) ((EAPMethod *) x)
+
+
+GtkWidget *eap_method_get_widget (EAPMethod *method);
+
+gboolean eap_method_validate (EAPMethod *method);
+
+void eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group);
+
+void eap_method_fill_connection (EAPMethod *method, NMConnection *connection);
+
+void eap_method_update_secrets (EAPMethod *method, NMConnection *connection);
+
+GtkWidget * eap_method_nag_user (EAPMethod *method);
+
+EAPMethod *eap_method_ref (EAPMethod *method);
+
+void eap_method_unref (EAPMethod *method);
+
+GType eap_method_get_g_type (void);
+
+/* Below for internal use only */
+
+#include "eap-method-tls.h"
+#include "eap-method-leap.h"
+#include "eap-method-fast.h"
+#include "eap-method-ttls.h"
+#include "eap-method-peap.h"
+#include "eap-method-simple.h"
+
+EAPMethod *eap_method_init (gsize obj_size,
+                            EMValidateFunc validate,
+                            EMAddToSizeGroupFunc add_to_size_group,
+                            EMFillConnectionFunc fill_connection,
+                            EMUpdateSecretsFunc update_secrets,
+                            EMDestroyFunc destroy,
+                            const char *ui_file,
+                            const char *ui_widget_name,
+                            const char *default_field,
+                            gboolean phase2);
+
+GtkFileFilter * eap_method_default_file_chooser_filter_new (gboolean privkey);
+
+gboolean eap_method_is_encrypted_private_key (const char *path);
+
+#define TYPE_CLIENT_CERT 0
+#define TYPE_CA_CERT     1
+#define TYPE_PRIVATE_KEY 2
+
+gboolean eap_method_validate_filepicker (GtkBuilder *builder,
+                                         const char *name,
+                                         guint32 item_type,
+                                         const char *password,
+                                         NMSetting8021xCKFormat *out_format);
+
+gboolean eap_method_nag_init (EAPMethod *method,
+                              const char *ca_cert_chooser,
+                              NMConnection *connection);
+
+void eap_method_phase2_update_secrets_helper (EAPMethod *method,
+                                              NMConnection *connection,
+                                              const char *combo_name,
+                                              guint32 column);
+
+#endif /* EAP_METHOD_H */
+
diff --git a/panels/network/wireless-security/helpers.c b/panels/network/wireless-security/helpers.c
new file mode 100644
index 0000000..5d7941d
--- /dev/null
+++ b/panels/network/wireless-security/helpers.c
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2009 Red Hat, Inc.
+ */
+
+#include "helpers.h"
+
+void
+helper_fill_secret_entry (NMConnection *connection,
+                          GtkBuilder *builder,
+                          const char *entry_name,
+                          GType setting_type,
+                          HelperSecretFunc func)
+{
+	GtkWidget *widget;
+	NMSetting *setting;
+	const char *tmp;
+
+	g_return_if_fail (connection != NULL);
+	g_return_if_fail (builder != NULL);
+	g_return_if_fail (entry_name != NULL);
+	g_return_if_fail (func != NULL);
+
+	setting = nm_connection_get_setting (connection, setting_type);
+	if (setting) {
+		tmp = (*func) (setting);
+		if (tmp) {
+			widget = GTK_WIDGET (gtk_builder_get_object (builder, entry_name));
+			g_assert (widget);
+			gtk_entry_set_text (GTK_ENTRY (widget), tmp);
+		}
+	}
+}
+
diff --git a/panels/network/wireless-security/helpers.h b/panels/network/wireless-security/helpers.h
new file mode 100644
index 0000000..75c01ea
--- /dev/null
+++ b/panels/network/wireless-security/helpers.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2009 Red Hat, Inc.
+ */
+
+#ifndef _HELPERS_H_
+#define _HELPERS_H_
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <nm-connection.h>
+#include <nm-setting.h>
+
+typedef const char * (*HelperSecretFunc)(NMSetting *);
+
+void helper_fill_secret_entry (NMConnection *connection,
+                               GtkBuilder *builder,
+                               const char *entry_name,
+                               GType setting_type,
+                               HelperSecretFunc func);
+
+#endif  /* _HELPERS_H_ */
+
diff --git a/panels/network/wireless-security/nag-user-dialog.ui b/panels/network/wireless-security/nag-user-dialog.ui
new file mode 100644
index 0000000..d821e11
--- /dev/null
+++ b/panels/network/wireless-security/nag-user-dialog.ui
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.6 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkDialog" id="nag_user_dialog">
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="window_position">center</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox2">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">14</property>
+        <child>
+          <object class="GtkHBox" id="hbox5">
+            <property name="visible">True</property>
+            <property name="border_width">5</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkImage" id="image4">
+                <property name="visible">True</property>
+                <property name="yalign">0</property>
+                <property name="stock">gtk-dialog-warning</property>
+                <property name="icon-size">6</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="content_vbox">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkLabel" id="content_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="yalign">0</property>
+                    <property name="label">alert text</property>
+                    <property name="use_markup">True</property>
+                    <property name="wrap">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="ignore_checkbox">
+                    <property name="label" translatable="yes">Don't _warn me again</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area2">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="ignore_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment3">
+                    <property name="visible">True</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox4">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkImage" id="image3">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-no</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label57">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">No</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="change_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox3">
+                        <property name="visible">True</property>
+                        <property name="spacing">2</property>
+                        <child>
+                          <object class="GtkImage" id="image2">
+                            <property name="visible">True</property>
+                            <property name="stock">gtk-ok</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label56">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">Yes</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-9">ignore_button</action-widget>
+      <action-widget response="-8">change_button</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/wireless-security.c b/panels/network/wireless-security/wireless-security.c
new file mode 100644
index 0000000..fc77777
--- /dev/null
+++ b/panels/network/wireless-security/wireless-security.c
@@ -0,0 +1,551 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2012 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-8021x.h>
+
+#include "wireless-security.h"
+#include "eap-method.h"
+
+GType
+wireless_security_get_g_type (void)
+{
+	static GType type_id = 0;
+
+	if (!type_id) {
+		type_id = g_boxed_type_register_static ("WirelessSecurity",
+		                                        (GBoxedCopyFunc) wireless_security_ref,
+		                                        (GBoxedFreeFunc) wireless_security_unref);
+	}
+
+	return type_id;
+}
+
+GtkWidget *
+wireless_security_get_widget (WirelessSecurity *sec)
+{
+	g_return_val_if_fail (sec != NULL, NULL);
+
+	return sec->ui_widget;
+}
+
+void
+wireless_security_set_changed_notify (WirelessSecurity *sec,
+                                      WSChangedFunc func,
+                                      gpointer user_data)
+{
+	g_return_if_fail (sec != NULL);
+
+	sec->changed_notify = func;
+	sec->changed_notify_data = user_data;
+}
+
+void
+wireless_security_changed_cb (GtkWidget *ignored, gpointer user_data)
+{
+	WirelessSecurity *sec = WIRELESS_SECURITY (user_data);
+
+	if (sec->changed_notify)
+		(*(sec->changed_notify)) (sec, sec->changed_notify_data);
+}
+
+gboolean
+wireless_security_validate (WirelessSecurity *sec, const GByteArray *ssid)
+{
+	g_return_val_if_fail (sec != NULL, FALSE);
+
+	g_assert (sec->validate);
+	return (*(sec->validate)) (sec, ssid);
+}
+
+void
+wireless_security_add_to_size_group (WirelessSecurity *sec, GtkSizeGroup *group)
+{
+	g_return_if_fail (sec != NULL);
+	g_return_if_fail (group != NULL);
+
+	g_assert (sec->add_to_size_group);
+	return (*(sec->add_to_size_group)) (sec, group);
+}
+
+void
+wireless_security_fill_connection (WirelessSecurity *sec,
+                                   NMConnection *connection)
+{
+	g_return_if_fail (sec != NULL);
+	g_return_if_fail (connection != NULL);
+
+	g_assert (sec->fill_connection);
+	return (*(sec->fill_connection)) (sec, connection);
+}
+
+void
+wireless_security_update_secrets (WirelessSecurity *sec, NMConnection *connection)
+{
+	g_return_if_fail (sec != NULL);
+	g_return_if_fail (connection != NULL);
+
+	if (sec->update_secrets)
+		sec->update_secrets (sec, connection);
+}
+
+WirelessSecurity *
+wireless_security_ref (WirelessSecurity *sec)
+{
+	g_return_val_if_fail (sec != NULL, NULL);
+	g_return_val_if_fail (sec->refcount > 0, NULL);
+
+	sec->refcount++;
+	return sec;
+}
+
+void
+wireless_security_unref (WirelessSecurity *sec)
+{
+	g_return_if_fail (sec != NULL);
+	g_return_if_fail (sec->refcount > 0);
+
+	sec->refcount--;
+	if (sec->refcount == 0) {
+		if (sec->destroy)
+			sec->destroy (sec);
+
+		if (sec->builder)
+			g_object_unref (sec->builder);
+		if (sec->ui_widget)
+			g_object_unref (sec->ui_widget);
+		g_slice_free1 (sec->obj_size, sec);
+	}
+}
+
+WirelessSecurity *
+wireless_security_init (gsize obj_size,
+                        WSValidateFunc validate,
+                        WSAddToSizeGroupFunc add_to_size_group,
+                        WSFillConnectionFunc fill_connection,
+                        WSUpdateSecretsFunc update_secrets,
+                        WSDestroyFunc destroy,
+                        const char *ui_file,
+                        const char *ui_widget_name,
+                        const char *default_field)
+{
+	WirelessSecurity *sec;
+	GError *error = NULL;
+
+	g_return_val_if_fail (obj_size > 0, NULL);
+	g_return_val_if_fail (ui_file != NULL, NULL);
+	g_return_val_if_fail (ui_widget_name != NULL, NULL);
+
+	sec = g_slice_alloc0 (obj_size);
+	g_assert (sec);
+
+	sec->refcount = 1;
+	sec->obj_size = obj_size;
+
+	sec->validate = validate;
+	sec->add_to_size_group = add_to_size_group;
+	sec->fill_connection = fill_connection;
+	sec->update_secrets = update_secrets;
+	sec->destroy = destroy;
+	sec->default_field = default_field;
+
+	sec->builder = gtk_builder_new ();
+	if (!gtk_builder_add_from_file (sec->builder, ui_file, &error)) {
+		g_warning ("Couldn't load UI builder file %s: %s",
+		           ui_file, error->message);
+		g_error_free (error);
+		wireless_security_unref (sec);
+		return NULL;
+	}
+
+	sec->ui_widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, ui_widget_name));
+	if (!sec->ui_widget) {
+		g_warning ("Couldn't load UI widget '%s' from UI file %s",
+		           ui_widget_name, ui_file);
+		wireless_security_unref (sec);
+		return NULL;
+	}
+	g_object_ref_sink (sec->ui_widget);
+
+	sec->adhoc_compatible = TRUE;
+
+	return sec;
+}
+
+GtkWidget *
+wireless_security_nag_user (WirelessSecurity *sec)
+{
+	g_return_val_if_fail (sec != NULL, NULL);
+
+	if (sec->nag_user)
+		return (*(sec->nag_user)) (sec);
+	return NULL;
+}
+
+gboolean
+wireless_security_adhoc_compatible (WirelessSecurity *sec)
+{
+	g_return_val_if_fail (sec != NULL, FALSE);
+
+	return sec->adhoc_compatible;
+}
+
+void
+wireless_security_clear_ciphers (NMConnection *connection)
+{
+	NMSettingWirelessSecurity *s_wireless_sec;
+
+	g_return_if_fail (connection != NULL);
+
+	s_wireless_sec = nm_connection_get_setting_wireless_security (connection);
+	g_assert (s_wireless_sec);
+
+	nm_setting_wireless_security_clear_protos (s_wireless_sec);
+	nm_setting_wireless_security_clear_pairwise (s_wireless_sec);
+	nm_setting_wireless_security_clear_groups (s_wireless_sec);
+}
+
+void
+ws_802_1x_add_to_size_group (WirelessSecurity *sec,
+                             GtkSizeGroup *size_group,
+                             const char *label_name,
+                             const char *combo_name)
+{
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, label_name));
+	g_assert (widget);
+	gtk_size_group_add_widget (size_group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	eap_method_add_to_size_group (eap, size_group);
+	eap_method_unref (eap);
+}
+
+gboolean
+ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name)
+{
+	GtkWidget *widget;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap = NULL;
+	gboolean valid = FALSE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name));
+	g_assert (widget);
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+	valid = eap_method_validate (eap);
+	eap_method_unref (eap);
+	return valid;
+}
+
+void
+ws_802_1x_auth_combo_changed (GtkWidget *combo,
+                              WirelessSecurity *sec,
+                              const char *vbox_name,
+                              GtkSizeGroup *size_group)
+{
+	GtkWidget *vbox;
+	EAPMethod *eap = NULL;
+	GList *elt, *children;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkWidget *eap_widget;
+	GtkWidget *eap_default_widget = NULL;
+
+	vbox = GTK_WIDGET (gtk_builder_get_object (sec->builder, vbox_name));
+	g_assert (vbox);
+
+	/* Remove any previous wireless security widgets */
+	children = gtk_container_get_children (GTK_CONTAINER (vbox));
+	for (elt = children; elt; elt = g_list_next (elt))
+		gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data));
+
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter);
+	gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_widget = eap_method_get_widget (eap);
+	g_assert (eap_widget);
+	gtk_widget_unparent (eap_widget);
+
+	if (size_group)
+		eap_method_add_to_size_group (eap, size_group);
+	gtk_container_add (GTK_CONTAINER (vbox), eap_widget);
+
+	/* Refocus the EAP method's default widget */
+	if (eap->default_field) {
+		eap_default_widget = GTK_WIDGET (gtk_builder_get_object (eap->builder, eap->default_field));
+		if (eap_default_widget)
+			gtk_widget_grab_focus (eap_default_widget);
+	}
+
+	eap_method_unref (eap);
+
+	wireless_security_changed_cb (combo, WIRELESS_SECURITY (sec));
+}
+
+GtkWidget *
+ws_802_1x_auth_combo_init (WirelessSecurity *sec,
+                           const char *combo_name,
+                           const char *combo_label,
+                           GCallback auth_combo_changed_cb,
+                           NMConnection *connection,
+                           gboolean is_editor,
+                           gboolean secrets_only)
+{
+	GtkWidget *combo, *widget;
+	GtkListStore *auth_model;
+	GtkTreeIter iter;
+	EAPMethodSimple *em_md5;
+	EAPMethodTLS *em_tls;
+	EAPMethodLEAP *em_leap;
+	EAPMethodFAST *em_fast;
+	EAPMethodTTLS *em_ttls;
+	EAPMethodPEAP *em_peap;
+	const char *default_method = NULL, *ctype = NULL;
+	int active = -1, item = 0;
+	gboolean wired = FALSE;
+
+	/* Grab the default EAP method out of the security object */
+	if (connection) {
+		NMSettingConnection *s_con;
+		NMSetting8021x *s_8021x;
+
+		s_con = nm_connection_get_setting_connection (connection);
+		if (s_con)
+			ctype = nm_setting_connection_get_connection_type (s_con);
+		if (   (g_strcmp0 (ctype, NM_SETTING_WIRED_SETTING_NAME) == 0)
+		    || nm_connection_get_setting_wired (connection))
+			wired = TRUE;
+
+		s_8021x = nm_connection_get_setting_802_1x (connection);
+		if (s_8021x && nm_setting_802_1x_get_num_eap_methods (s_8021x))
+			default_method = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+	}
+
+	auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_type ());
+
+	if (wired) {
+		em_md5 = eap_method_simple_new (sec,
+		                                connection,
+		                                EAP_METHOD_SIMPLE_TYPE_MD5,
+		                                FALSE,
+		                                is_editor,
+		                                secrets_only);
+		gtk_list_store_append (auth_model, &iter);
+		gtk_list_store_set (auth_model, &iter,
+			                AUTH_NAME_COLUMN, _("MD5"),
+			                AUTH_METHOD_COLUMN, em_md5,
+			                -1);
+		eap_method_unref (EAP_METHOD (em_md5));
+		if (default_method && (active < 0) && !strcmp (default_method, "md5"))
+			active = item;
+		item++;
+	}
+
+	em_tls = eap_method_tls_new (sec, connection, FALSE, secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    AUTH_NAME_COLUMN, _("TLS"),
+	                    AUTH_METHOD_COLUMN, em_tls,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_tls));
+	if (default_method && (active < 0) && !strcmp (default_method, "tls"))
+		active = item;
+	item++;
+
+	if (!wired) {
+		em_leap = eap_method_leap_new (sec, connection, secrets_only);
+		gtk_list_store_append (auth_model, &iter);
+		gtk_list_store_set (auth_model, &iter,
+		                    AUTH_NAME_COLUMN, _("LEAP"),
+		                    AUTH_METHOD_COLUMN, em_leap,
+		                    -1);
+		eap_method_unref (EAP_METHOD (em_leap));
+		if (default_method && (active < 0) && !strcmp (default_method, "leap"))
+			active = item;
+		item++;
+	}
+
+	em_fast = eap_method_fast_new (sec, connection, is_editor, secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    AUTH_NAME_COLUMN, _("FAST"),
+	                    AUTH_METHOD_COLUMN, em_fast,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_fast));
+	if (default_method && (active < 0) && !strcmp (default_method, "fast"))
+		active = item;
+	item++;
+
+	em_ttls = eap_method_ttls_new (sec, connection, is_editor, secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    AUTH_NAME_COLUMN, _("Tunneled TLS"),
+	                    AUTH_METHOD_COLUMN, em_ttls,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_ttls));
+	if (default_method && (active < 0) && !strcmp (default_method, "ttls"))
+		active = item;
+	item++;
+
+	em_peap = eap_method_peap_new (sec, connection, is_editor, secrets_only);
+	gtk_list_store_append (auth_model, &iter);
+	gtk_list_store_set (auth_model, &iter,
+	                    AUTH_NAME_COLUMN, _("Protected EAP (PEAP)"),
+	                    AUTH_METHOD_COLUMN, em_peap,
+	                    -1);
+	eap_method_unref (EAP_METHOD (em_peap));
+	if (default_method && (active < 0) && !strcmp (default_method, "peap"))
+		active = item;
+	item++;
+
+	combo = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name));
+	g_assert (combo);
+
+	gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model));
+	g_object_unref (G_OBJECT (auth_model));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active < 0 ? 0 : (guint32) active);
+
+	g_signal_connect (G_OBJECT (combo), "changed", auth_combo_changed_cb, sec);
+
+	if (secrets_only) {
+		gtk_widget_hide (combo);
+		widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_label));
+		gtk_widget_hide (widget);
+	}
+
+	return combo;
+}
+
+void
+ws_802_1x_fill_connection (WirelessSecurity *sec,
+                           const char *combo_name,
+                           NMConnection *connection)
+{
+	GtkWidget *widget;
+	NMSettingWireless *s_wireless;
+	NMSettingWirelessSecurity *s_wireless_sec;
+	NMSetting8021x *s_8021x;
+	EAPMethod *eap = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	s_wireless = nm_connection_get_setting_wireless (connection);
+	g_assert (s_wireless);
+
+	g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+
+	/* Blow away the old wireless security setting by adding a clear one */
+	s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+	nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec);
+
+	/* Blow away the old 802.1x setting by adding a clear one */
+	s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+	nm_connection_add_setting (connection, (NMSetting *) s_8021x);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name));
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
+	g_assert (eap);
+
+	eap_method_fill_connection (eap, connection);
+	eap_method_unref (eap);
+}
+
+void
+ws_802_1x_update_secrets (WirelessSecurity *sec,
+                          const char *combo_name,
+                          NMConnection *connection)
+{
+	GtkWidget *widget;
+	EAPMethod *eap = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+
+	g_return_if_fail (sec != NULL);
+	g_return_if_fail (combo_name != NULL);
+	g_return_if_fail (connection != NULL);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name));
+	g_return_if_fail (widget != NULL);
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+
+	/* Let each EAP method try to update its secrets */
+	if (gtk_tree_model_get_iter_first (model, &iter)) {
+		do {
+			gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
+			if (eap) {
+				eap_method_update_secrets (eap, connection);
+				eap_method_unref (eap);
+			}
+		} while (gtk_tree_model_iter_next (model, &iter));
+	}
+}
+
+GtkWidget *
+ws_802_1x_nag_user (WirelessSecurity *sec,
+                    const char *combo_name)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	EAPMethod *eap = NULL;
+	GtkWidget *widget;	
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name));
+	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
+	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
+	gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1);
+	g_return_val_if_fail (eap != NULL, NULL);
+
+	widget = eap_method_nag_user (eap);
+	eap_method_unref (eap);
+	return widget;
+}
+
diff --git a/panels/network/wireless-security/wireless-security.h b/panels/network/wireless-security/wireless-security.h
new file mode 100644
index 0000000..eea98c3
--- /dev/null
+++ b/panels/network/wireless-security/wireless-security.h
@@ -0,0 +1,147 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef WIRELESS_SECURITY_H
+#define WIRELESS_SECURITY_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include <nm-connection.h>
+
+typedef struct _WirelessSecurity WirelessSecurity;
+
+typedef void (*WSChangedFunc) (WirelessSecurity *sec, gpointer user_data);
+
+typedef void (*WSAddToSizeGroupFunc) (WirelessSecurity *sec, GtkSizeGroup *group);
+typedef void (*WSFillConnectionFunc) (WirelessSecurity *sec, NMConnection *connection);
+typedef void (*WSUpdateSecretsFunc)  (WirelessSecurity *sec, NMConnection *connection);
+typedef void (*WSDestroyFunc)        (WirelessSecurity *sec);
+typedef gboolean (*WSValidateFunc)   (WirelessSecurity *sec, const GByteArray *ssid);
+typedef GtkWidget * (*WSNagUserFunc) (WirelessSecurity *sec);
+
+struct _WirelessSecurity {
+	guint32 refcount;
+	gsize obj_size;
+	GtkBuilder *builder;
+	GtkWidget *ui_widget;
+	WSChangedFunc changed_notify;
+	gpointer changed_notify_data;
+	const char *default_field;
+	gboolean adhoc_compatible;
+
+	WSAddToSizeGroupFunc add_to_size_group;
+	WSFillConnectionFunc fill_connection;
+	WSUpdateSecretsFunc update_secrets;
+	WSValidateFunc validate;
+	WSNagUserFunc nag_user;
+	WSDestroyFunc destroy;
+};
+
+#define WIRELESS_SECURITY(x) ((WirelessSecurity *) x)
+
+
+GtkWidget *wireless_security_get_widget (WirelessSecurity *sec);
+
+void wireless_security_set_changed_notify (WirelessSecurity *sec,
+                                           WSChangedFunc func,
+                                           gpointer user_data);
+
+gboolean wireless_security_validate (WirelessSecurity *sec, const GByteArray *ssid);
+
+void wireless_security_add_to_size_group (WirelessSecurity *sec,
+                                          GtkSizeGroup *group);
+
+void wireless_security_fill_connection (WirelessSecurity *sec,
+                                        NMConnection *connection);
+
+void wireless_security_update_secrets (WirelessSecurity *sec,
+                                       NMConnection *connection);
+
+GtkWidget * wireless_security_nag_user (WirelessSecurity *sec);
+
+gboolean wireless_security_adhoc_compatible (WirelessSecurity *sec);
+
+WirelessSecurity *wireless_security_ref (WirelessSecurity *sec);
+
+void wireless_security_unref (WirelessSecurity *sec);
+
+GType wireless_security_get_g_type (void);
+
+/* Below for internal use only */
+
+#include "ws-wep-key.h"
+#include "ws-wpa-psk.h"
+#include "ws-leap.h"
+#include "ws-wpa-eap.h"
+#include "ws-dynamic-wep.h"
+
+WirelessSecurity *wireless_security_init (gsize obj_size,
+                                          WSValidateFunc validate,
+                                          WSAddToSizeGroupFunc add_to_size_group,
+                                          WSFillConnectionFunc fill_connection,
+                                          WSUpdateSecretsFunc update_secrets,
+                                          WSDestroyFunc destroy,
+                                          const char *ui_file,
+                                          const char *ui_widget_name,
+                                          const char *default_field);
+
+void wireless_security_changed_cb (GtkWidget *entry, gpointer user_data);
+
+void wireless_security_clear_ciphers (NMConnection *connection);
+
+#define AUTH_NAME_COLUMN   0
+#define AUTH_METHOD_COLUMN 1
+
+GtkWidget *ws_802_1x_auth_combo_init (WirelessSecurity *sec,
+                                      const char *combo_name,
+                                      const char *combo_label,
+                                      GCallback auth_combo_changed_cb,
+                                      NMConnection *connection,
+                                      gboolean is_editor,
+                                      gboolean secrets_only);
+
+void ws_802_1x_auth_combo_changed (GtkWidget *combo,
+                                   WirelessSecurity *sec,
+                                   const char *vbox_name,
+                                   GtkSizeGroup *size_group);
+
+gboolean ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name);
+
+void ws_802_1x_add_to_size_group (WirelessSecurity *sec,
+                                  GtkSizeGroup *size_group,
+                                  const char *label_name,
+                                  const char *combo_name);
+
+void ws_802_1x_fill_connection (WirelessSecurity *sec,
+                                const char *combo_name,
+                                NMConnection *connection);
+
+void ws_802_1x_update_secrets (WirelessSecurity *sec,
+                               const char *combo_name,
+                               NMConnection *connection);
+
+GtkWidget * ws_802_1x_nag_user (WirelessSecurity *sec,
+                                const char *combo_name);
+
+#endif /* WIRELESS_SECURITY_H */
+
diff --git a/panels/network/wireless-security/ws-dynamic-wep.c b/panels/network/wireless-security/ws-dynamic-wep.c
new file mode 100644
index 0000000..7d9ea3a
--- /dev/null
+++ b/panels/network/wireless-security/ws-dynamic-wep.c
@@ -0,0 +1,143 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <string.h>
+#include <nm-setting-wireless.h>
+
+#include "wireless-security.h"
+#include "eap-method.h"
+
+struct _WirelessSecurityDynamicWEP {
+	WirelessSecurity parent;
+
+	GtkSizeGroup *size_group;
+};
+
+static void
+destroy (WirelessSecurity *parent)
+{
+	WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent;
+
+	if (sec->size_group)
+		g_object_unref (sec->size_group);
+}
+
+static gboolean
+validate (WirelessSecurity *parent, const GByteArray *ssid)
+{
+	return ws_802_1x_validate (parent, "dynamic_wep_auth_combo");
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+	WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent;
+
+	if (sec->size_group)
+		g_object_unref (sec->size_group);
+	sec->size_group = g_object_ref (group);
+
+	ws_802_1x_add_to_size_group (parent,
+	                             sec->size_group,
+	                             "dynamic_wep_auth_label",
+	                             "dynamic_wep_auth_combo");
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+	NMSettingWirelessSecurity *s_wireless_sec;
+
+	ws_802_1x_fill_connection (parent, "dynamic_wep_auth_combo", connection);
+
+	s_wireless_sec = nm_connection_get_setting_wireless_security (connection);
+	g_assert (s_wireless_sec);
+
+	g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL);
+
+	nm_setting_wireless_security_add_pairwise (s_wireless_sec, "wep40");
+	nm_setting_wireless_security_add_pairwise (s_wireless_sec, "wep104");
+	nm_setting_wireless_security_add_group (s_wireless_sec, "wep40");
+	nm_setting_wireless_security_add_group (s_wireless_sec, "wep104");
+}
+
+static void
+auth_combo_changed_cb (GtkWidget *combo, gpointer user_data)
+{
+	WirelessSecurity *parent = WIRELESS_SECURITY (user_data);
+	WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent;
+
+	ws_802_1x_auth_combo_changed (combo,
+	                              parent,
+	                              "dynamic_wep_method_vbox",
+	                              sec->size_group);
+}
+
+static GtkWidget *
+nag_user (WirelessSecurity *parent)
+{
+	return ws_802_1x_nag_user (parent, "dynamic_wep_auth_combo");
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+	ws_802_1x_update_secrets (parent, "dynamic_wep_auth_combo", connection);
+}
+
+WirelessSecurityDynamicWEP *
+ws_dynamic_wep_new (NMConnection *connection,
+                    gboolean is_editor,
+                    gboolean secrets_only)
+{
+	WirelessSecurity *parent;
+	GtkWidget *widget;
+
+	parent = wireless_security_init (sizeof (WirelessSecurityDynamicWEP),
+	                                 validate,
+	                                 add_to_size_group,
+	                                 fill_connection,
+	                                 update_secrets,
+	                                 destroy,
+	                                 UIDIR "/ws-dynamic-wep.ui",
+	                                 "dynamic_wep_notebook",
+	                                 NULL);
+	if (!parent)
+		return NULL;
+
+	parent->nag_user = nag_user;
+	parent->adhoc_compatible = FALSE;
+
+	widget = ws_802_1x_auth_combo_init (parent,
+	                                    "dynamic_wep_auth_combo",
+	                                    "dynamic_wep_auth_label",
+	                                    (GCallback) auth_combo_changed_cb,
+	                                    connection,
+	                                    is_editor,
+	                                    secrets_only);
+	auth_combo_changed_cb (widget, (gpointer) parent);
+
+	return (WirelessSecurityDynamicWEP *) parent;
+}
+
diff --git a/panels/network/wireless-security/ws-dynamic-wep.h b/panels/network/wireless-security/ws-dynamic-wep.h
new file mode 100644
index 0000000..54979f4
--- /dev/null
+++ b/panels/network/wireless-security/ws-dynamic-wep.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef WS_DYNAMIC_WEP_H
+#define WS_DYNAMIC_WEP_H
+
+#include <nm-connection.h>
+
+typedef struct _WirelessSecurityDynamicWEP WirelessSecurityDynamicWEP;
+
+WirelessSecurityDynamicWEP *ws_dynamic_wep_new (NMConnection *connection,
+                                                gboolean is_editor,
+                                                gboolean secrets_only);
+
+#endif /* WS_DYNAMIC_WEP_H */
+
diff --git a/panels/network/wireless-security/ws-dynamic-wep.ui b/panels/network/wireless-security/ws-dynamic-wep.ui
new file mode 100644
index 0000000..d6bc12b
--- /dev/null
+++ b/panels/network/wireless-security/ws-dynamic-wep.ui
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="model7">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes"> </col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkNotebook" id="dynamic_wep_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table12">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">3</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkLabel" id="dynamic_wep_auth_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Au_thentication</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">dynamic_wep_auth_combo</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="dynamic_wep_auth_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model7</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer7"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="dynamic_wep_method_vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">6</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label55">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/ws-leap.c b/panels/network/wireless-security/ws-leap.c
new file mode 100644
index 0000000..16327cb
--- /dev/null
+++ b/panels/network/wireless-security/ws-leap.c
@@ -0,0 +1,192 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <nm-setting-wireless.h>
+
+#include "wireless-security.h"
+#include "helpers.h"
+
+struct _WirelessSecurityLEAP {
+	WirelessSecurity parent;
+	gboolean new_connection;
+};
+
+static void
+show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec)
+{
+	GtkWidget *widget;
+	gboolean visible;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "leap_password_entry"));
+	g_assert (widget);
+
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static gboolean
+validate (WirelessSecurity *parent, const GByteArray *ssid)
+{
+	GtkWidget *entry;
+	const char *text;
+
+	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry"));
+	g_assert (entry);
+	text = gtk_entry_get_text (GTK_ENTRY (entry));
+	if (!text || !strlen (text))
+		return FALSE;
+
+	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry"));
+	g_assert (entry);
+	text = gtk_entry_get_text (GTK_ENTRY (entry));
+	if (!text || !strlen (text))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_label"));
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_label"));
+	gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+	WirelessSecurityLEAP *sec = (WirelessSecurityLEAP *) parent;
+	NMSettingWireless *s_wireless;
+	NMSettingWirelessSecurity *s_wireless_sec;
+	GtkWidget *widget;
+	const char *leap_password = NULL, *leap_username = NULL;
+
+	s_wireless = nm_connection_get_setting_wireless (connection);
+	g_assert (s_wireless);
+
+	g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+
+	/* Blow away the old security setting by adding a clear one */
+	s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+	nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry"));
+	leap_username = gtk_entry_get_text (GTK_ENTRY (widget));
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry"));
+	leap_password = gtk_entry_get_text (GTK_ENTRY (widget));
+
+	g_object_set (s_wireless_sec,
+	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+	              NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
+	              NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username,
+	              NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, leap_password,
+	              NULL);
+
+	/* Default to agent-owned secrets for new connections */
+	if (sec->new_connection) {
+		g_object_set (s_wireless_sec,
+		              NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
+		              NULL);
+	}
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+	helper_fill_secret_entry (connection,
+	                          parent->builder,
+	                          "leap_password_entry",
+	                          NM_TYPE_SETTING_WIRELESS_SECURITY,
+	                          (HelperSecretFunc) nm_setting_wireless_security_get_leap_password);
+}
+
+WirelessSecurityLEAP *
+ws_leap_new (NMConnection *connection, gboolean secrets_only)
+{
+	WirelessSecurity *parent;
+	WirelessSecurityLEAP *sec;
+	GtkWidget *widget;
+	NMSettingWirelessSecurity *wsec = NULL;
+
+	parent = wireless_security_init (sizeof (WirelessSecurityLEAP),
+	                                 validate,
+	                                 add_to_size_group,
+	                                 fill_connection,
+	                                 update_secrets,
+	                                 NULL,
+	                                 UIDIR "/ws-leap.ui",
+	                                 "leap_notebook",
+	                                 "leap_username_entry");
+	if (!parent)
+		return NULL;
+
+	if (connection) {
+		wsec = nm_connection_get_setting_wireless_security (connection);
+		if (wsec) {
+			const char *auth_alg;
+
+			/* Ignore if wireless security doesn't specify LEAP */
+			auth_alg = nm_setting_wireless_security_get_auth_alg (wsec);
+			if (!auth_alg || strcmp (auth_alg, "leap"))
+				wsec = NULL;
+		}
+	}
+
+	parent->adhoc_compatible = FALSE;
+	sec = (WirelessSecurityLEAP *) parent;
+	sec->new_connection = secrets_only ? FALSE : TRUE;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  sec);
+	if (wsec)
+		update_secrets (WIRELESS_SECURITY (sec), connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  sec);
+	if (wsec)
+		gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_wireless_security_get_leap_username (wsec));
+
+	if (secrets_only)
+		gtk_widget_hide (widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_leap"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) show_toggled_cb,
+	                  sec);
+
+	return sec;
+}
+
diff --git a/panels/network/wireless-security/ws-leap.h b/panels/network/wireless-security/ws-leap.h
new file mode 100644
index 0000000..6f1d705
--- /dev/null
+++ b/panels/network/wireless-security/ws-leap.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef WS_LEAP_H
+#define WS_LEAP_H
+
+#include <nm-connection.h>
+
+typedef struct _WirelessSecurityLEAP WirelessSecurityLEAP;
+
+WirelessSecurityLEAP * ws_leap_new (NMConnection *connection, gboolean secrets_only);
+
+#endif /* WS_LEAP_H */
+
diff --git a/panels/network/wireless-security/ws-leap.ui b/panels/network/wireless-security/ws-leap.ui
new file mode 100644
index 0000000..76bca3a
--- /dev/null
+++ b/panels/network/wireless-security/ws-leap.ui
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="leap_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table5">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">3</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <object class="GtkLabel" id="leap_username_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Username</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">leap_username_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="leap_password_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">leap_password_entry</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="leap_password_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_checkbutton_leap">
+            <property name="label" translatable="yes">Sho_w password</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="xalign">0</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="leap_username_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="GtkLabel1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/ws-wep-key.c b/panels/network/wireless-security/ws-wep-key.c
new file mode 100644
index 0000000..6af08df
--- /dev/null
+++ b/panels/network/wireless-security/ws-wep-key.c
@@ -0,0 +1,349 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include <ctype.h>
+#include <string.h>
+
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+
+#include "wireless-security.h"
+
+struct _WirelessSecurityWEPKey {
+	WirelessSecurity parent;
+
+	NMWepKeyType type;
+	char keys[4][65];
+	guint8 cur_index;
+};
+
+static void
+show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec)
+{
+	GtkWidget *widget;
+	gboolean visible;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "wep_key_entry"));
+	g_assert (widget);
+
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static void
+key_index_combo_changed_cb (GtkWidget *combo, WirelessSecurity *parent)
+{
+	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent;
+	GtkWidget *entry;
+	const char *key;
+	int key_index;
+
+	/* Save WEP key for old key index */
+	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry"));
+	key = gtk_entry_get_text (GTK_ENTRY (entry));
+	if (key)
+		strcpy (sec->keys[sec->cur_index], key);
+	else
+		memset (sec->keys[sec->cur_index], 0, sizeof (sec->keys[sec->cur_index]));
+
+	key_index = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
+	g_return_if_fail (key_index <= 3);
+	g_return_if_fail (key_index >= 0);
+
+	/* Populate entry with key from new index */
+	gtk_entry_set_text (GTK_ENTRY (entry), sec->keys[key_index]);
+	sec->cur_index = key_index;
+
+	wireless_security_changed_cb (combo, parent);
+}
+
+static void
+destroy (WirelessSecurity *parent)
+{
+	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent;
+	int i;
+
+	for (i = 0; i < 4; i++)
+		memset (sec->keys[i], 0, sizeof (sec->keys[i]));
+}
+
+static gboolean
+validate (WirelessSecurity *parent, const GByteArray *ssid)
+{
+	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent;
+	GtkWidget *entry;
+	const char *key;
+	int i;
+
+	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry"));
+	g_assert (entry);
+
+	key = gtk_entry_get_text (GTK_ENTRY (entry));
+	if (!key)
+		return FALSE;
+
+	if (sec->type == NM_WEP_KEY_TYPE_KEY) {
+		if ((strlen (key) == 10) || (strlen (key) == 26)) {
+			for (i = 0; i < strlen (key); i++) {
+				if (!isxdigit (key[i]))
+					return FALSE;
+			}
+		} else if ((strlen (key) == 5) || (strlen (key) == 13)) {
+			for (i = 0; i < strlen (key); i++) {
+				if (!isascii (key[i]))
+					return FALSE;
+			}
+		} else {
+			return FALSE;
+		}
+	} else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) {
+		if (!strlen (key) || (strlen (key) > 64))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_label"));
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_label"));
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_label"));
+	gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent;
+	NMSettingWireless *s_wireless;
+	NMSettingWirelessSecurity *s_wsec;
+	GtkWidget *widget;
+	gint auth_alg;
+	const char *key;
+	int i;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_combo"));
+	auth_alg = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry"));
+	key = gtk_entry_get_text (GTK_ENTRY (widget));
+	strcpy (sec->keys[sec->cur_index], key);
+
+	s_wireless = nm_connection_get_setting_wireless (connection);
+	g_assert (s_wireless);
+
+	g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+
+	/* Blow away the old security setting by adding a clear one */
+	s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+	nm_connection_add_setting (connection, (NMSetting *) s_wsec);
+
+	g_object_set (s_wsec,
+	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+	              NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, sec->cur_index,
+	              NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, (auth_alg == 1) ? "shared" : "open",
+	              NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, sec->type,
+	              NULL);
+
+	for (i = 0; i < 4; i++) {
+		if (strlen (sec->keys[i]))
+			nm_setting_wireless_security_set_wep_key (s_wsec, i, sec->keys[i]);
+	}
+}
+
+static void
+wep_entry_filter_cb (GtkEntry *   entry,
+                     const gchar *text,
+                     gint         length,
+                     gint *       position,
+                     gpointer     data)
+{
+	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) data;
+	GtkEditable *editable = GTK_EDITABLE (entry);
+	int i, count = 0;
+	gchar *result;
+
+	result = g_malloc0 (length + 1);
+
+	if (sec->type == NM_WEP_KEY_TYPE_KEY) {
+		for (i = 0; i < length; i++) {
+			if (isxdigit(text[i]) || isascii(text[i]))
+				result[count++] = text[i];
+		}
+	} else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) {
+		for (i = 0; i < length; i++)
+			result[count++] = text[i];
+	}
+
+	if (count > 0) {
+		g_signal_handlers_block_by_func (G_OBJECT (editable),
+			                             G_CALLBACK (wep_entry_filter_cb),
+			                             data);
+		gtk_editable_insert_text (editable, result, count, position);
+		g_signal_handlers_unblock_by_func (G_OBJECT (editable),
+			                               G_CALLBACK (wep_entry_filter_cb),
+			                               data);
+	}
+
+	g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
+	g_free (result);
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+	WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent;
+	NMSettingWirelessSecurity *s_wsec;
+	GtkWidget *widget;
+	const char *tmp;
+	int i;
+
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	for (i = 0; s_wsec && i < 4; i++) {
+		tmp = nm_setting_wireless_security_get_wep_key (s_wsec, i);
+		if (tmp)
+			strcpy (sec->keys[i], tmp);
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry"));
+	if (strlen (sec->keys[sec->cur_index]))
+		gtk_entry_set_text (GTK_ENTRY (widget), sec->keys[sec->cur_index]);
+}
+
+WirelessSecurityWEPKey *
+ws_wep_key_new (NMConnection *connection,
+                NMWepKeyType type,
+                gboolean adhoc_create,
+                gboolean secrets_only)
+{
+	WirelessSecurity *parent;
+	WirelessSecurityWEPKey *sec;
+	GtkWidget *widget;
+	NMSettingWirelessSecurity *s_wsec = NULL;
+	guint8 default_key_idx = 0;
+	gboolean is_adhoc = adhoc_create;
+	gboolean is_shared_key = FALSE;
+
+	parent = wireless_security_init (sizeof (WirelessSecurityWEPKey),
+	                                 validate,
+	                                 add_to_size_group,
+	                                 fill_connection,
+	                                 update_secrets,
+	                                 destroy,
+	                                 UIDIR "/ws-wep-key.ui",
+	                                 "wep_key_notebook",
+	                                 "wep_key_entry");
+	if (!parent)
+		return NULL;
+	
+	sec = (WirelessSecurityWEPKey *) parent;
+	sec->type = type;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry"));
+	g_assert (widget);
+	gtk_entry_set_width_chars (GTK_ENTRY (widget), 28);
+
+	if (connection) {
+		NMSettingWireless *s_wireless;
+		const char *mode, *auth_alg;
+
+		s_wireless = nm_connection_get_setting_wireless (connection);
+		mode = s_wireless ? nm_setting_wireless_get_mode (s_wireless) : NULL;
+		if (mode && !strcmp (mode, "adhoc"))
+			is_adhoc = TRUE;
+
+		s_wsec = nm_connection_get_setting_wireless_security (connection);
+		if (s_wsec) {
+			auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+			if (auth_alg && !strcmp (auth_alg, "shared"))
+				is_shared_key = TRUE;
+		}
+	}
+
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  sec);
+	g_signal_connect (G_OBJECT (widget), "insert-text",
+	                  (GCallback) wep_entry_filter_cb,
+	                  sec);
+	if (sec->type == NM_WEP_KEY_TYPE_KEY)
+		gtk_entry_set_max_length (GTK_ENTRY (widget), 26);
+	else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE)
+		gtk_entry_set_max_length (GTK_ENTRY (widget), 64);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_combo"));
+	if (connection && s_wsec)
+		default_key_idx = nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec);
+
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), default_key_idx);
+	sec->cur_index = default_key_idx;
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) key_index_combo_changed_cb,
+	                  sec);
+
+	/* Key index is useless with adhoc networks */
+	if (is_adhoc || secrets_only) {
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_label"));
+		gtk_widget_hide (widget);
+	}
+
+	/* Fill the key entry with the key for that index */
+	if (connection)
+		update_secrets (WIRELESS_SECURITY (sec), connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wep"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) show_toggled_cb,
+	                  sec);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_combo"));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), is_shared_key ? 1 : 0);
+
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  sec);
+
+	/* Don't show auth method for adhoc (which always uses open-system) or
+	 * when in "simple" mode.
+	 */
+	if (is_adhoc || secrets_only) {
+		/* Ad-Hoc connections can't use Shared Key auth */
+		if (is_adhoc)
+			gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_label"));
+		gtk_widget_hide (widget);
+	}
+
+	return sec;
+}
+
diff --git a/panels/network/wireless-security/ws-wep-key.h b/panels/network/wireless-security/ws-wep-key.h
new file mode 100644
index 0000000..fdd70da
--- /dev/null
+++ b/panels/network/wireless-security/ws-wep-key.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef WS_WEP_KEY_H
+#define WS_WEP_KEY_H
+
+#include <nm-setting-wireless-security.h>
+
+typedef struct _WirelessSecurityWEPKey WirelessSecurityWEPKey;
+
+WirelessSecurityWEPKey *ws_wep_key_new (NMConnection *connection,
+                                        NMWepKeyType type,
+                                        gboolean adhoc_create,
+                                        gboolean secrets_only);
+
+#endif /* WS_WEP_KEY_H */
+
diff --git a/panels/network/wireless-security/ws-wep-key.ui b/panels/network/wireless-security/ws-wep-key.ui
new file mode 100644
index 0000000..b50aa62
--- /dev/null
+++ b/panels/network/wireless-security/ws-wep-key.ui
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="model4">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">1 (Default)</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">2</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">3</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">4</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="model3">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Open System</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Shared Key</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkNotebook" id="wep_key_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="table6">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">4</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="wep_key_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Key</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">wep_key_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="wep_key_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label31">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_checkbutton_wep">
+            <property name="label" translatable="yes">Sho_w key</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="xalign">0</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="auth_method_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Au_thentication</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">auth_method_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="auth_method_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model3</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer3"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">3</property>
+            <property name="bottom_attach">4</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="key_index_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">WEP inde_x</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">key_index_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="key_index_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model4</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer4"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="label23">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/ws-wpa-eap.c b/panels/network/wireless-security/ws-wpa-eap.c
new file mode 100644
index 0000000..d0dad00
--- /dev/null
+++ b/panels/network/wireless-security/ws-wpa-eap.c
@@ -0,0 +1,139 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <string.h>
+#include <nm-setting-wireless.h>
+
+#include "wireless-security.h"
+#include "eap-method.h"
+
+struct _WirelessSecurityWPAEAP {
+	WirelessSecurity parent;
+
+	GtkSizeGroup *size_group;
+};
+
+
+static void
+destroy (WirelessSecurity *parent)
+{
+	WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent;
+
+	if (sec->size_group)
+		g_object_unref (sec->size_group);
+}
+
+static gboolean
+validate (WirelessSecurity *parent, const GByteArray *ssid)
+{
+	return ws_802_1x_validate (parent, "wpa_eap_auth_combo");
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+	WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent;
+
+	if (sec->size_group)
+		g_object_unref (sec->size_group);
+	sec->size_group = g_object_ref (group);
+
+	ws_802_1x_add_to_size_group (parent,
+	                             sec->size_group,
+	                             "wpa_eap_auth_label",
+	                             "wpa_eap_auth_combo");
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+	NMSettingWirelessSecurity *s_wireless_sec;
+
+	ws_802_1x_fill_connection (parent, "wpa_eap_auth_combo", connection);
+
+	s_wireless_sec = nm_connection_get_setting_wireless_security (connection);
+	g_assert (s_wireless_sec);
+
+	g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
+}
+
+static void
+auth_combo_changed_cb (GtkWidget *combo, gpointer user_data)
+{
+	WirelessSecurity *parent = WIRELESS_SECURITY (user_data);
+	WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent;
+
+	ws_802_1x_auth_combo_changed (combo,
+	                              parent,
+	                              "wpa_eap_method_vbox",
+	                              sec->size_group);
+}
+
+static GtkWidget *
+nag_user (WirelessSecurity *parent)
+{
+	return ws_802_1x_nag_user (parent, "wpa_eap_auth_combo");
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+	ws_802_1x_update_secrets (parent, "wpa_eap_auth_combo", connection);
+}
+
+WirelessSecurityWPAEAP *
+ws_wpa_eap_new (NMConnection *connection,
+                gboolean is_editor,
+                gboolean secrets_only)
+{
+	WirelessSecurity *parent;
+	GtkWidget *widget;
+
+	parent = wireless_security_init (sizeof (WirelessSecurityWPAEAP),
+	                                 validate,
+	                                 add_to_size_group,
+	                                 fill_connection,
+	                                 update_secrets,
+	                                 destroy,
+	                                 UIDIR "/ws-wpa-eap.ui",
+	                                 "wpa_eap_notebook",
+	                                 NULL);
+	if (!parent)
+		return NULL;
+
+	parent->nag_user = nag_user;
+	parent->adhoc_compatible = FALSE;
+
+	widget = ws_802_1x_auth_combo_init (parent,
+	                                    "wpa_eap_auth_combo",
+	                                    "wpa_eap_auth_label",
+	                                    (GCallback) auth_combo_changed_cb,
+	                                    connection,
+	                                    is_editor,
+	                                    secrets_only);
+	auth_combo_changed_cb (widget, parent);
+
+	return (WirelessSecurityWPAEAP *) parent;
+}
+
diff --git a/panels/network/wireless-security/ws-wpa-eap.h b/panels/network/wireless-security/ws-wpa-eap.h
new file mode 100644
index 0000000..5c8faea
--- /dev/null
+++ b/panels/network/wireless-security/ws-wpa-eap.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef WS_WPA_EAP_H
+#define WS_WPA_EAP_H
+
+#include <nm-connection.h>
+
+typedef struct _WirelessSecurityWPAEAP WirelessSecurityWPAEAP;
+
+WirelessSecurityWPAEAP * ws_wpa_eap_new (NMConnection *connection,
+                                         gboolean is_editor,
+                                         gboolean secrets_only);
+
+#endif /* WS_WPA_EAP_H */
+
diff --git a/panels/network/wireless-security/ws-wpa-eap.ui b/panels/network/wireless-security/ws-wpa-eap.ui
new file mode 100644
index 0000000..5d71936
--- /dev/null
+++ b/panels/network/wireless-security/ws-wpa-eap.ui
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="model5">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes"> </col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkNotebook" id="wpa_eap_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="wpa_eap_table">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">2</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="wpa_eap_auth_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">Au_thentication</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">wpa_eap_auth_combo</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="wpa_eap_auth_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="model">model5</property>
+            <child>
+              <object class="GtkCellRendererText" id="renderer5"/>
+              <attributes>
+                <attribute name="text">0</attribute>
+              </attributes>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="wpa_eap_method_vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="GtkLabel3">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/panels/network/wireless-security/ws-wpa-psk.c b/panels/network/wireless-security/ws-wpa-psk.c
new file mode 100644
index 0000000..f19b25a
--- /dev/null
+++ b/panels/network/wireless-security/ws-wpa-psk.c
@@ -0,0 +1,200 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <nm-setting-wireless.h>
+
+#include "wireless-security.h"
+#include "helpers.h"
+
+#define WPA_PMK_LEN 32
+
+struct _WirelessSecurityWPAPSK {
+	WirelessSecurity parent;
+};
+
+static void
+show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec)
+{
+	GtkWidget *widget;
+	gboolean visible;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "wpa_psk_entry"));
+	g_assert (widget);
+
+	visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+	gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
+}
+
+static gboolean
+validate (WirelessSecurity *parent, const GByteArray *ssid)
+{
+	GtkWidget *entry;
+	const char *key;
+	guint32 len;
+	int i;
+
+	entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry"));
+	g_assert (entry);
+
+	key = gtk_entry_get_text (GTK_ENTRY (entry));
+	len = strlen (key);
+	if ((len < 8) || (len > 64))
+		return FALSE;
+
+	if (len == 64) {
+		/* Hex PSK */
+		for (i = 0; i < len; i++) {
+			if (!isxdigit (key[i]))
+				return FALSE;
+		}
+	}
+
+	/* passphrase can be between 8 and 63 characters inclusive */
+
+	return TRUE;
+}
+
+static void
+add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group)
+{
+	GtkWidget *widget;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_label"));
+	gtk_size_group_add_widget (group, widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_label"));
+	gtk_size_group_add_widget (group, widget);
+}
+
+static void
+fill_connection (WirelessSecurity *parent, NMConnection *connection)
+{
+	GtkWidget *widget;
+	const char *key;
+	NMSettingWireless *s_wireless;
+	NMSettingWirelessSecurity *s_wireless_sec;
+	const char *mode;
+	gboolean is_adhoc = FALSE;
+
+	s_wireless = nm_connection_get_setting_wireless (connection);
+	g_assert (s_wireless);
+
+	mode = nm_setting_wireless_get_mode (s_wireless);
+	if (mode && !strcmp (mode, "adhoc"))
+		is_adhoc = TRUE;
+
+	g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+
+	/* Blow away the old security setting by adding a clear one */
+	s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+	nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry"));
+	key = gtk_entry_get_text (GTK_ENTRY (widget));
+	g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_PSK, key, NULL);
+
+	wireless_security_clear_ciphers (connection);
+	if (is_adhoc) {
+		/* Ad-Hoc settings as specified by the supplicant */
+		g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
+		nm_setting_wireless_security_add_proto (s_wireless_sec, "wpa");
+		nm_setting_wireless_security_add_pairwise (s_wireless_sec, "none");
+
+		/* Ad-hoc can only have _one_ group cipher... default to TKIP to be more
+		 * compatible for now.  Maybe we'll support selecting CCMP later.
+		 */
+		nm_setting_wireless_security_add_group (s_wireless_sec, "tkip");
+	} else {
+		g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
+
+		/* Just leave ciphers and protocol empty, the supplicant will
+		 * figure that out magically based on the AP IEs and card capabilities.
+		 */
+	}
+}
+
+static void
+update_secrets (WirelessSecurity *parent, NMConnection *connection)
+{
+	helper_fill_secret_entry (connection,
+	                          parent->builder,
+	                          "wpa_psk_entry",
+	                          NM_TYPE_SETTING_WIRELESS_SECURITY,
+	                          (HelperSecretFunc) nm_setting_wireless_security_get_psk);
+}
+
+WirelessSecurityWPAPSK *
+ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only)
+{
+	WirelessSecurity *parent;
+	WirelessSecurityWPAPSK *sec;
+	GtkWidget *widget;
+
+	parent = wireless_security_init (sizeof (WirelessSecurityWPAPSK),
+	                                 validate,
+	                                 add_to_size_group,
+	                                 fill_connection,
+	                                 update_secrets,
+	                                 NULL,
+	                                 UIDIR "/ws-wpa-psk.ui",
+	                                 "wpa_psk_notebook",
+	                                 "wpa_psk_entry");
+	if (!parent)
+		return NULL;
+
+	parent->adhoc_compatible = FALSE;
+	sec = (WirelessSecurityWPAPSK *) parent;
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "changed",
+	                  (GCallback) wireless_security_changed_cb,
+	                  sec);
+	gtk_entry_set_width_chars (GTK_ENTRY (widget), 28);
+
+	/* Fill secrets, if any */
+	if (connection)
+		update_secrets (WIRELESS_SECURITY (sec), connection);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wpa"));
+	g_assert (widget);
+	g_signal_connect (G_OBJECT (widget), "toggled",
+	                  (GCallback) show_toggled_cb,
+	                  sec);
+
+	/* Hide WPA/RSN for now since this can be autodetected by NM and the
+	 * supplicant when connecting to the AP.
+	 */
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_combo"));
+	g_assert (widget);
+	gtk_widget_hide (widget);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_label"));
+	g_assert (widget);
+	gtk_widget_hide (widget);
+
+	return sec;
+}
+
diff --git a/panels/network/wireless-security/ws-wpa-psk.h b/panels/network/wireless-security/ws-wpa-psk.h
new file mode 100644
index 0000000..a89552f
--- /dev/null
+++ b/panels/network/wireless-security/ws-wpa-psk.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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 of the License, 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.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ */
+
+#ifndef WS_WPA_PSK_H
+#define WS_WPA_PSK_H
+
+typedef struct _WirelessSecurityWPAPSK WirelessSecurityWPAPSK;
+
+WirelessSecurityWPAPSK * ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only);
+
+#endif /* WS_WEP_KEY_H */
+
diff --git a/panels/network/wireless-security/ws-wpa-psk.ui b/panels/network/wireless-security/ws-wpa-psk.ui
new file mode 100644
index 0000000..5bc756a
--- /dev/null
+++ b/panels/network/wireless-security/ws-wpa-psk.ui
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkNotebook" id="wpa_psk_notebook">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="show_tabs">False</property>
+    <property name="show_border">False</property>
+    <child>
+      <object class="GtkTable" id="wpa_psk_table">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="n_rows">3</property>
+        <property name="n_columns">2</property>
+        <property name="column_spacing">6</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="wpa_psk_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">wpa_psk_entry</property>
+          </object>
+          <packing>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="wpa_psk_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="max_length">64</property>
+            <property name="visibility">False</property>
+            <property name="activates_default">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="wpa_psk_type_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Type</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">wpa_psk_type_combo</property>
+          </object>
+          <packing>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label32">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">0</property>
+          </object>
+          <packing>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkCheckButton" id="show_checkbutton_wpa">
+            <property name="label" translatable="yes">Sho_w password</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+            <property name="xalign">0.5</property>
+            <property name="draw_indicator">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">1</property>
+            <property name="bottom_attach">2</property>
+            <property name="x_options">GTK_FILL</property>
+            <property name="y_options"/>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBox" id="wpa_psk_type_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="right_attach">2</property>
+            <property name="top_attach">2</property>
+            <property name="bottom_attach">3</property>
+            <property name="y_options">GTK_FILL</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="tab">
+      <object class="GtkLabel" id="GtkLabel2">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="tab_fill">False</property>
+      </packing>
+    </child>
+  </object>
+</interface>
