[gnome-packagekit/glib2-merge-candidate: 5/11] Convert all the client applications to use packagekit-glib2



commit 3a903d9acdfc6db79bf381641997d8eecabb6c42
Author: Richard Hughes <richard hughsie com>
Date:   Tue Oct 6 12:09:23 2009 +0100

    Convert all the client applications to use packagekit-glib2
    
    This involves switching them to use GpkTask and a 100% async model.
    There will be lots of bugs introduced with this commit, but hopefully
    with glib2 the codebase will be more supportable and understandable.
    
    Testing is very welcome, as we've only got 6 months to shake out all
    the bugs from the conversion.

 src/Makefile.am                 |   33 +-
 src/gpk-animated-icon.c         |    5 +-
 src/gpk-application.c           | 2703 ++++++++++++++----------------
 src/gpk-auto-refresh.c          |  208 ++-
 src/gpk-backend-status.c        |  207 ++--
 src/gpk-cell-renderer-info.c    |    5 +-
 src/gpk-cell-renderer-info.h    |    2 +-
 src/gpk-cell-renderer-restart.c |    7 +-
 src/gpk-cell-renderer-restart.h |    2 +-
 src/gpk-cell-renderer-size.c    |    3 -
 src/gpk-check-update.c          | 1021 +++++-------
 src/gpk-common.c                |  272 ++--
 src/gpk-common.h                |   16 +-
 src/gpk-dbus-task.c             | 3521 ++++++++++++++-------------------------
 src/gpk-dbus-task.h             |   32 +-
 src/gpk-dbus.c                  |   18 +-
 src/gpk-desktop.c               |    8 +-
 src/gpk-desktop.h               |    2 +-
 src/gpk-dialog.c                |   63 +-
 src/gpk-dialog.h                |    4 +-
 src/gpk-error.c                 |    7 +-
 src/gpk-firmware.c              |  589 ++++----
 src/gpk-hardware.c              |  135 +-
 src/gpk-helper-chooser.c        |   31 +-
 src/gpk-helper-chooser.h        |    4 +-
 src/gpk-helper-run.c            |   14 +-
 src/gpk-inhibit.c               |    2 +-
 src/gpk-install-catalog.c       |    2 +-
 src/gpk-language.c              |    2 +-
 src/gpk-log.c                   |  143 +-
 src/gpk-modal-dialog.c          |   62 +-
 src/gpk-modal-dialog.h          |    6 +-
 src/gpk-prefs.c                 |  140 ++-
 src/gpk-repo.c                  |  484 +++---
 src/gpk-self-test.c             |    2 +
 src/gpk-service-pack.c          |  414 +++--
 src/gpk-update-icon.c           |    4 +-
 src/gpk-update-viewer.c         | 2479 ++++++++++++----------------
 src/gpk-watch.c                 | 1335 ++++++++--------
 39 files changed, 6268 insertions(+), 7719 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index fb6624a..677b196 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ INCLUDES =						\
 	$(GUDEV_CFLAGS)					\
 	$(GNOME_MENUS_CFLAGS)				\
 	-DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE \
+	-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE	\
 	-DG_UDEV_API_IS_SUBJECT_TO_CHANGE		\
 	$(DEVKIT_CFLAGS)				\
 	$(CANBERRA_CFLAGS)				\
@@ -80,28 +81,16 @@ libgpkshared_a_SOURCES =				\
 	gpk-language.h					\
 	gpk-modal-dialog.c				\
 	gpk-modal-dialog.h				\
-	gpk-helper-repo-signature.c			\
-	gpk-helper-repo-signature.h			\
-	gpk-helper-eula.c				\
-	gpk-helper-eula.h				\
 	gpk-helper-run.c				\
 	gpk-helper-run.h				\
-	gpk-helper-deps-remove.c			\
-	gpk-helper-deps-remove.h			\
-	gpk-helper-deps-install.c			\
-	gpk-helper-deps-install.h			\
-	gpk-helper-deps-update.c			\
-	gpk-helper-deps-update.h			\
-	gpk-helper-untrusted.c				\
-	gpk-helper-untrusted.h				\
 	gpk-helper-chooser.c				\
 	gpk-helper-chooser.h				\
-	gpk-helper-media-change.c			\
-	gpk-helper-media-change.h			\
 	gpk-gnome.c					\
 	gpk-gnome.h					\
 	gpk-common.c					\
 	gpk-common.h					\
+	gpk-task.c					\
+	gpk-task.h					\
 	gpk-error.c					\
 	gpk-error.h					\
 	$(NULL)
@@ -330,24 +319,12 @@ gpk_self_test_SOURCES =					\
 	gpk-vendor.h					\
 	gpk-desktop.c					\
 	gpk-desktop.h					\
-	gpk-helper-repo-signature.c			\
-	gpk-helper-repo-signature.h			\
-	gpk-helper-eula.c				\
-	gpk-helper-eula.h				\
+	gpk-task.c					\
+	gpk-task.h					\
 	gpk-helper-run.c				\
 	gpk-helper-run.h				\
-	gpk-helper-deps-remove.c			\
-	gpk-helper-deps-remove.h			\
-	gpk-helper-deps-install.c			\
-	gpk-helper-deps-install.h			\
-	gpk-helper-deps-update.c			\
-	gpk-helper-deps-update.h			\
-	gpk-helper-untrusted.c				\
-	gpk-helper-untrusted.h				\
 	gpk-helper-chooser.c				\
 	gpk-helper-chooser.h				\
-	gpk-helper-media-change.c			\
-	gpk-helper-media-change.h			\
 	gpk-marshal.c					\
 	gpk-marshal.h					\
 	gpk-dialog.c					\
diff --git a/src/gpk-animated-icon.c b/src/gpk-animated-icon.c
index 8217b59..c8556c7 100644
--- a/src/gpk-animated-icon.c
+++ b/src/gpk-animated-icon.c
@@ -24,7 +24,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
@@ -266,12 +266,9 @@ gpk_animated_icon_destroy (GtkObject *object)
 static void
 gpk_animated_icon_class_init (GpkAnimatedIconClass *class)
 {
-	GtkImageClass *image_class;
 	GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
 	object_class->destroy = gpk_animated_icon_destroy;
-
 	parent_class = g_type_class_peek_parent (class);
-	image_class = GTK_IMAGE_CLASS (class);
 }
 
 /**
diff --git a/src/gpk-application.c b/src/gpk-application.c
index efb7f19..56405e8 100644
--- a/src/gpk-application.c
+++ b/src/gpk-application.c
@@ -29,27 +29,23 @@
 #include <gconf/gconf-client.h>
 #include <math.h>
 #include <string.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
 #include "egg-markdown.h"
 
-#include "gpk-common.h"
-#include "gpk-gnome.h"
-#include "gpk-error.h"
-#include "gpk-enum.h"
-#include "gpk-application.h"
 #include "gpk-animated-icon.h"
-#include "gpk-dialog.h"
+#include "gpk-application.h"
 #include "gpk-cell-renderer-uri.h"
+#include "gpk-common.h"
 #include "gpk-desktop.h"
-#include "gpk-helper-repo-signature.h"
-#include "gpk-helper-eula.h"
+#include "gpk-dialog.h"
+#include "gpk-enum.h"
+#include "gpk-error.h"
+#include "gpk-gnome.h"
 #include "gpk-helper-run.h"
-#include "gpk-helper-deps-remove.h"
-#include "gpk-helper-deps-install.h"
-#include "gpk-helper-media-change.h"
+#include "gpk-task.h"
 
 static void     gpk_application_finalize   (GObject	    *object);
 
@@ -86,9 +82,7 @@ struct GpkApplicationPrivate
 	GtkListStore		*details_store;
 	EggMarkdown		*markdown;
 	PkControl		*control;
-	PkClient		*client_primary;
-	PkClient		*client_secondary;
-	PkConnection		*pconnection;
+	PkTask			*task;
 	PkDesktop		*desktop;
 	gchar			*group;
 	gchar			*url;
@@ -103,19 +97,12 @@ struct GpkApplicationPrivate
 	PkSearchType		 search_type;
 	PkSearchMode		 search_mode;
 	PkActionMode		 action;
-	PkPackageList		*package_list;
+	PkPackageSack		*package_sack;
 	GtkWidget		*image_status;
-	GpkHelperRepoSignature	*helper_repo_signature;
-	GpkHelperEula		*helper_eula;
 	GpkHelperRun		*helper_run;
-	GpkHelperDepsRemove	*helper_deps_remove;
-	GpkHelperDepsInstall	*helper_deps_install;
-	GpkHelperMediaChange	*helper_media_change;
-#if !PK_CHECK_VERSION(0,5,2)
-	gboolean		 dep_check_info_only; /* bodge to tell apart the differing uses of GetDepends */
-#endif
 	guint			 status_id;
 	PkStatusEnum		 status_last;
+	GCancellable		*cancellable;
 };
 
 enum {
@@ -161,8 +148,7 @@ static guint	     signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (GpkApplication, gpk_application, G_TYPE_OBJECT)
 
-static void gpk_application_categories_finished (GpkApplication *application);
-static gboolean gpk_application_perform_search (GpkApplication *application);
+static void gpk_application_perform_search (GpkApplication *application);
 
 /**
  * gpk_application_class_init:
@@ -242,7 +228,7 @@ gpk_application_state_get_checkbox (PkBitfield state)
 	state_local = state;
 	pk_bitfield_remove (state_local, GPK_STATE_COLLECTION);
 
-	/* installed or in list */
+	/* installed or in array */
 	if (state_local == pk_bitfield_value (GPK_STATE_INSTALLED) ||
 	    state_local == pk_bitfield_value (GPK_STATE_IN_LIST))
 		return TRUE;
@@ -368,7 +354,7 @@ gpk_application_set_buttons_apply_clear (GpkApplication *application)
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
 	/* okay to apply? */
-	len = PK_OBJ_LIST (application->priv->package_list)->len;
+	len = pk_package_sack_get_size (application->priv->package_sack);
 	if (len == 0) {
 		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
 		gtk_widget_set_sensitive (widget, FALSE);
@@ -387,7 +373,7 @@ gpk_application_set_buttons_apply_clear (GpkApplication *application)
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
 
-	/* for all current items, reset the state if in the list */
+	/* for all current items, reset the state if in the array */
 	while (valid) {
 		gtk_tree_model_get (model, &iter,
 				    PACKAGES_COLUMN_STATE, &state,
@@ -454,9 +440,9 @@ static gboolean
 gpk_application_install (GpkApplication *application)
 {
 	gboolean ret;
-	PkPackageId *id;
 	gchar *package_id_selected = NULL;
 	gchar *summary_selected = NULL;
+	PkPackage *package;
 
 	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
 
@@ -469,10 +455,9 @@ gpk_application_install (GpkApplication *application)
 
 	/* changed mind, or wrong mode */
 	if (application->priv->action == PK_ACTION_REMOVE) {
-		ret = pk_package_list_contains (application->priv->package_list, package_id_selected);
+		ret = pk_package_sack_remove_package_by_id (application->priv->package_sack, package_id_selected);
 		if (ret) {
-			egg_debug ("removed %s from package list", package_id_selected);
-			pk_package_list_remove (application->priv->package_list, package_id_selected);
+			egg_debug ("removed %s from package array", package_id_selected);
 
 			/* correct buttons */
 			gpk_application_allow_install (application, FALSE);
@@ -481,13 +466,13 @@ gpk_application_install (GpkApplication *application)
 			gpk_application_set_buttons_apply_clear (application);
 			return TRUE;
 		}
-		egg_warning ("wrong mode and not in list");
+		egg_warning ("wrong mode and not in array");
 		return FALSE;
 	}
 
 	/* already added */
-	ret = !pk_package_list_contains (application->priv->package_list, package_id_selected);
-	if (!ret) {
+	package = pk_package_sack_find_by_id (application->priv->package_sack, package_id_selected);
+	if (package != NULL) {
 		egg_warning ("already added");
 		goto out;
 	}
@@ -495,10 +480,15 @@ gpk_application_install (GpkApplication *application)
 	/* set mode */
 	application->priv->action = PK_ACTION_INSTALL;
 
-	/* add to list */
-	id = pk_package_id_new_from_string (package_id_selected);
-	pk_package_list_add (application->priv->package_list, PK_INFO_ENUM_AVAILABLE, id, summary_selected);
-	pk_package_id_free (id);
+	/* add to array */
+	package = pk_package_new ();
+	pk_package_set_id (package, package_id_selected, NULL);
+	g_object_set (package,
+		      "info", PK_INFO_ENUM_AVAILABLE,
+		      "summary", summary_selected,
+		      NULL);
+	pk_package_sack_add_package (application->priv->package_sack, package);
+	g_object_unref (package);
 
 	/* correct buttons */
 	gpk_application_allow_install (application, FALSE);
@@ -531,18 +521,57 @@ gpk_application_strcmp_indirect (gchar **a, gchar **b)
 }
 
 /**
- * gpk_application_menu_files_cb:
+ * gpk_application_get_files_cb:
  **/
 static void
-gpk_application_menu_files_cb (GtkAction *action, GpkApplication *application)
+gpk_application_get_files_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
 	gboolean ret;
-	GError *error = NULL;
-	gchar **package_ids = NULL;
+	gchar **files = NULL;
 	gchar *package_id_selected = NULL;
+	gchar **split = NULL;
+	gchar *title = NULL;
+	GError *error = NULL;
+	GPtrArray *array = NULL;
+	GPtrArray *array_sort = NULL;
+	GtkWidget *dialog;
+	GtkWindow *window;
+	PkItemErrorCode *error_item = NULL;
+	PkItemFiles *item;
+	PkResults *results;
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get files: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get files: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_files_array (results);
+	if (array->len != 1)
+		goto out;
+
+	/* assume only one option */
+	item = g_ptr_array_index (array, 0);
+
 	/* get selection */
 	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
 	if (!ret) {
@@ -550,22 +579,182 @@ gpk_application_menu_files_cb (GtkAction *action, GpkApplication *application)
 		goto out;
 	}
 
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_primary, &error);
+	/* convert to pointer array */
+	array_sort = pk_strv_to_ptr_array (item->files);
+	g_ptr_array_sort (array_sort, (GCompareFunc) gpk_application_strcmp_indirect);
+
+	/* title */
+	split = pk_package_id_split (package_id_selected);
+	/* TRANSLATORS: title: how many files are installed by the application */
+	title = g_strdup_printf (ngettext ("%i file installed by %s",
+					   "%i files installed by %s",
+					   array_sort->len), array_sort->len, split[PK_PACKAGE_ID_NAME]);
+
+	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
+	gpk_dialog_embed_file_list_widget (GTK_DIALOG (dialog), array_sort);
+	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 250);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+out:
+	g_free (title);
+	g_strfreev (files);
+	g_strfreev (split);
+	g_free (package_id_selected);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (array_sort != NULL)
+		g_ptr_array_unref (array_sort);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+
+/**
+ * gpk_application_status_changed_timeout_cb:
+ **/
+static gboolean
+gpk_application_status_changed_timeout_cb (GpkApplication *application)
+{
+	const gchar *text;
+	GtkWidget *widget;
+
+	/* set the text and show */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "label_status"));
+	text = gpk_status_enum_to_localised_text (application->priv->status_last);
+	gtk_label_set_label (GTK_LABEL (widget), text);
+
+	/* set icon */
+	gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (application->priv->image_status),
+					   application->priv->status_last, GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+	/* show containing box */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
+	gtk_widget_show (widget);
+
+	/* never repeat */
+	application->priv->status_id = 0;
+	return FALSE;
+}
+
+#if 0
+	if (application->priv->action == PK_ACTION_INSTALL ||
+	    application->priv->action == PK_ACTION_REMOVE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_clear"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
+		gtk_widget_set_sensitive (widget, FALSE);
+	}
+#endif
+
+/**
+ * gpk_application_progress_cb:
+ **/
+static void
+gpk_application_progress_cb (PkProgress *progress, PkProgressType type, GpkApplication *application)
+{
+	PkStatusEnum status;
+	gint percentage;
+	gboolean allow_cancel;
+	GtkWidget *widget;
+
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+
+	g_object_get (progress,
+		      "status", &status,
+		      "percentage", &percentage,
+		      "allow-cancel", &allow_cancel,
+		      NULL);
+
+	if (type == PK_PROGRESS_TYPE_STATUS) {
+		egg_debug ("now %s", pk_status_enum_to_text (status));
+
+		if (status == PK_STATUS_ENUM_FINISHED) {
+
+			/* re-enable UI */
+			widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
+			gtk_widget_set_sensitive (widget, TRUE);
+
+			/* we've not yet shown, so don't bother */
+			if (application->priv->status_id > 0) {
+				g_source_remove (application->priv->status_id);
+				application->priv->status_id = 0;
+			}
+
+			widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
+			gtk_widget_hide (widget);
+			widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "progressbar_progress"));
+			gtk_widget_hide (widget);
+			gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (application->priv->image_status), FALSE);
+			goto out;
+		}
+
+		/* already pending show */
+		if (application->priv->status_id > 0)
+			goto out;
+
+		/* only show after some time in the transaction */
+		application->priv->status_id = g_timeout_add (GPK_UI_STATUS_SHOW_DELAY, (GSourceFunc) gpk_application_status_changed_timeout_cb, application);
+
+		/* save for the callback */
+		application->priv->status_last = status;
+
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "progressbar_progress"));
+		if (percentage > 0) {
+			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget), (gfloat) percentage / 100.0f);
+			gtk_widget_show (widget);
+		} else {
+			gtk_widget_hide (widget);
+		}
+
+	} else if (type == PK_PROGRESS_TYPE_ALLOW_CANCEL) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_cancel"));
+		gtk_widget_set_sensitive (widget, allow_cancel);
+	}
+out:
+	return;
+}
+
+/**
+ * gpk_application_menu_files_cb:
+ **/
+static void
+gpk_application_menu_files_cb (GtkAction *action, GpkApplication *application)
+{
+	gboolean ret;
+	gchar **package_ids = NULL;
+	gchar *package_id_selected = NULL;
+
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+
+	/* get selection */
+	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
 	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
+		egg_warning ("no package selected");
 		goto out;
 	}
 
 	/* set correct view */
 	package_ids = pk_package_ids_from_id (package_id_selected);
-	ret = pk_client_get_files (application->priv->client_primary, package_ids, &error);
-	if (!ret) {
-		egg_warning ("cannot get file lists for %s: %s", package_id_selected, error->message);
-		g_error_free (error);
-		goto out;
-	}
+	pk_client_get_files_async (PK_CLIENT(application->priv->task), package_ids, application->priv->cancellable,
+				   (PkProgressCallback) gpk_application_progress_cb, application,
+				   (GAsyncReadyCallback) gpk_application_get_files_cb, application);
 out:
 	g_free (package_id_selected);
 	g_strfreev (package_ids);
@@ -578,9 +767,9 @@ static gboolean
 gpk_application_remove (GpkApplication *application)
 {
 	gboolean ret;
-	PkPackageId *id;
 	gchar *package_id_selected = NULL;
 	gchar *summary_selected = NULL;
+	PkPackage *package;
 
 	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
 
@@ -593,10 +782,9 @@ gpk_application_remove (GpkApplication *application)
 
 	/* changed mind, or wrong mode */
 	if (application->priv->action == PK_ACTION_INSTALL) {
-		ret = pk_package_list_contains (application->priv->package_list, package_id_selected);
+		ret = pk_package_sack_remove_package_by_id (application->priv->package_sack, package_id_selected);
 		if (ret) {
-			egg_debug ("removed %s from package list", package_id_selected);
-			pk_package_list_remove (application->priv->package_list, package_id_selected);
+			egg_debug ("removed %s from package array", package_id_selected);
 
 			/* correct buttons */
 			gpk_application_allow_install (application, TRUE);
@@ -605,21 +793,26 @@ gpk_application_remove (GpkApplication *application)
 			gpk_application_set_buttons_apply_clear (application);
 			return TRUE;
 		}
-		egg_warning ("wrong mode and not in list");
+		egg_warning ("wrong mode and not in array");
 		return FALSE;
 	}
 
 	/* already added */
-	ret = !pk_package_list_contains (application->priv->package_list, package_id_selected);
+	ret = (pk_package_sack_find_by_id (application->priv->package_sack, package_id_selected) == NULL);
 	if (!ret) {
 		egg_warning ("already added");
 		goto out;
 	}
 
 	application->priv->action = PK_ACTION_REMOVE;
-	id = pk_package_id_new_from_string (package_id_selected);
-	pk_package_list_add (application->priv->package_list, PK_INFO_ENUM_AVAILABLE, id, summary_selected);
-	pk_package_id_free (id);
+	package = pk_package_new ();
+	pk_package_set_id (package, package_id_selected, NULL);
+	g_object_set (package,
+		      "info", PK_INFO_ENUM_AVAILABLE,
+		      "summary", summary_selected,
+		      NULL);
+	pk_package_sack_add_package (application->priv->package_sack, package);
+	g_object_unref (package);
 
 	/* correct buttons */
 	gpk_application_allow_install (application, TRUE);
@@ -690,15 +883,45 @@ gpk_application_menu_run_cb (GtkAction *action, GpkApplication *application)
 }
 
 /**
- * gpk_application_menu_requires_cb:
+ * gpk_application_get_requires_cb:
  **/
 static void
-gpk_application_menu_requires_cb (GtkAction *action, GpkApplication *application)
+gpk_application_get_requires_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
+	PkResults *results;
 	GError *error = NULL;
-	gboolean ret;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	GtkWindow *window;
+	gchar *name = NULL;
+	gchar *title = NULL;
+	gchar *message = NULL;
 	gchar **package_ids = NULL;
+	GtkWidget *dialog;
 	gchar *package_id_selected = NULL;
+	gboolean ret;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get requires: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get requires: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
 
 	/* get selection */
 	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
@@ -707,41 +930,124 @@ gpk_application_menu_requires_cb (GtkAction *action, GpkApplication *application
 		goto out;
 	}
 
-	/* cancel any previous request */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel, and adding to queue: %s", error->message);
-		g_error_free (error);
+	/* get data */
+	array = pk_results_get_package_array (results);
+
+	/* empty array */
+	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+	if (array->len == 0) {
+		gpk_error_dialog_modal (window,
+					/* TRANSLATORS: no packages returned */
+					_("No packages"),
+					/* TRANSLATORS: this package is not required by any others */
+					_("No other packages require this package"), NULL);
 		goto out;
 	}
 
-	/* get the requires */
 	package_ids = pk_package_ids_from_id (package_id_selected);
-#if !PK_CHECK_VERSION(0,5,2)
-	application->priv->dep_check_info_only = TRUE;
-#endif
-	ret = pk_client_get_requires (application->priv->client_primary, PK_FILTER_ENUM_NONE,
-				      package_ids, TRUE, &error);
+	name = gpk_dialog_package_id_name_join_locale (package_ids);
+	/* TRANSLATORS: title: how many packages require this package */
+	title = g_strdup_printf (ngettext ("%i package requires %s",
+					   "%i packages require %s",
+					   array->len), array->len, name);
+
+	/* TRANSLATORS: show a array of packages for the package */
+	message = g_strdup_printf (ngettext ("Packages listed below require %s to function correctly.",
+					     "Packages listed below require %s to function correctly.",
+					     array->len), name);
+
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
+	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+	gpk_dialog_embed_package_list_widget (GTK_DIALOG (dialog), array);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+out:
+	g_free (package_id_selected);
+	g_strfreev (package_ids);
+	g_free (name);
+	g_free (title);
+	g_free (message);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_application_menu_requires_cb:
+ **/
+static void
+gpk_application_menu_requires_cb (GtkAction *action, GpkApplication *application)
+{
+	gboolean ret;
+	gchar **package_ids = NULL;
+	gchar *package_id_selected = NULL;
+
+	/* get selection */
+	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
 	if (!ret) {
-		egg_warning ("failed to get requires: %s", error->message);
-		g_error_free (error);
+		egg_warning ("no package selected");
 		goto out;
 	}
+
+	/* get the requires */
+	package_ids = pk_package_ids_from_id (package_id_selected);
+	pk_client_get_requires_async (PK_CLIENT(application->priv->task), PK_FILTER_ENUM_NONE,
+				      package_ids, TRUE, application->priv->cancellable,
+				      (PkProgressCallback) gpk_application_progress_cb, application,
+				      (GAsyncReadyCallback) gpk_application_get_requires_cb, application);
 out:
 	g_free (package_id_selected);
 	g_strfreev (package_ids);
 }
 
 /**
- * gpk_application_menu_depends_cb:
+ * gpk_application_get_depends_cb:
  **/
 static void
-gpk_application_menu_depends_cb (GtkAction *action, GpkApplication *application)
+gpk_application_get_depends_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
+	PkResults *results;
 	GError *error = NULL;
-	gboolean ret;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	GtkWindow *window;
+	gchar *name = NULL;
+	gchar *title = NULL;
+	gchar *message = NULL;
 	gchar **package_ids = NULL;
+	GtkWidget *dialog;
 	gchar *package_id_selected = NULL;
+	gboolean ret;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get depends: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get depends: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_package_array (results);
 
 	/* get selection */
 	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
@@ -750,26 +1056,73 @@ gpk_application_menu_depends_cb (GtkAction *action, GpkApplication *application)
 		goto out;
 	}
 
-	/* cancel any previous request */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel, and adding to queue: %s", error->message);
-		g_error_free (error);
+	/* empty array */
+	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+	if (array->len == 0) {
+		gpk_error_dialog_modal (window,
+					/* TRANSLATORS: no packages returned */
+					_("No packages"),
+					/* TRANSLATORS: this package does not depend on any others */
+					_("This package does not depends on any others"), NULL);
 		goto out;
 	}
 
-	/* get the depends */
 	package_ids = pk_package_ids_from_id (package_id_selected);
-#if !PK_CHECK_VERSION(0,5,2)
-	application->priv->dep_check_info_only = TRUE;
-#endif
-	ret = pk_client_get_depends (application->priv->client_primary, PK_FILTER_ENUM_NONE,
-				     package_ids, TRUE, &error);
+	name = gpk_dialog_package_id_name_join_locale (package_ids);
+	/* TRANSLATORS: title: show the number of other packages we depend on */
+	title = g_strdup_printf (ngettext ("%i additional package is required for %s",
+					   "%i additional packages are required for %s",
+					   array->len), array->len, name);
+
+	/* TRANSLATORS: message: show the array of dependant packages for this package */
+	message = g_strdup_printf (ngettext ("Packages listed below are required for %s to function correctly.",
+					     "Packages listed below are required for %s to function correctly.",
+					     array->len), name);
+
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
+	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+	gpk_dialog_embed_package_list_widget (GTK_DIALOG (dialog), array);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+	g_free (package_id_selected);
+	g_strfreev (package_ids);
+	g_free (name);
+	g_free (title);
+	g_free (message);
+}
+
+/**
+ * gpk_application_menu_depends_cb:
+ **/
+static void
+gpk_application_menu_depends_cb (GtkAction *action, GpkApplication *application)
+{
+	gboolean ret;
+	gchar **package_ids = NULL;
+	gchar *package_id_selected = NULL;
+
+	/* get selection */
+	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
 	if (!ret) {
-		egg_warning ("failed to get depends: %s", error->message);
-		g_error_free (error);
+		egg_warning ("no package selected");
 		goto out;
 	}
+
+	/* get the depends */
+	package_ids = pk_package_ids_from_id (package_id_selected);
+	pk_client_get_depends_async (PK_CLIENT(application->priv->task), PK_FILTER_ENUM_NONE,
+				     package_ids, TRUE, application->priv->cancellable,
+				     (PkProgressCallback) gpk_application_progress_cb, application,
+				     (GAsyncReadyCallback) gpk_application_get_depends_cb, application);
 out:
 	g_free (package_id_selected);
 	g_strfreev (package_ids);
@@ -790,7 +1143,7 @@ gpk_application_get_full_repo_name (GpkApplication *application, const gchar *da
 		return _("Invalid");
 	}
 
-	/* try to find in cached repo list */
+	/* try to find in cached repo array */
 	repo_name = (const gchar *) g_hash_table_lookup (application->priv->repos, data);
 	if (repo_name == NULL) {
 		egg_warning ("no repo name, falling back to %s", data);
@@ -876,7 +1229,7 @@ gpk_application_clear_details (GpkApplication *application)
 static void
 gpk_application_clear_packages (GpkApplication *application)
 {
-	/* clear existing list */
+	/* clear existing array */
 	gtk_list_store_clear (application->priv->packages_store);
 	application->priv->has_package = FALSE;
 }
@@ -894,139 +1247,33 @@ gpk_application_text_format_display (GpkApplication *application, const gchar *a
 }
 
 /**
- * gpk_application_details_cb:
+ * gpk_application_add_item_to_results:
  **/
 static void
-gpk_application_details_cb (PkClient *client, PkDetailsObj *details, GpkApplication *application)
-{
-	GtkWidget *widget;
-	gchar *text;
-	gchar *value;
-	const gchar *repo_name;
-	const gchar *group;
-	gboolean installed;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	installed = g_strcmp0 (details->id->data, "installed") == 0;
-
-	/* hide to start */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow_detail"));
-	gtk_widget_show (widget);
-
-	gtk_list_store_clear (application->priv->details_store);
-
-	/* if a collection, mark as such */
-	if (g_strcmp0 (details->id->data, "meta") == 0)
-		/* TRANSLATORS: the type of package is a collection (metagroup) */
-		gpk_application_add_detail_item (application, _("Type"), _("Collection"), NULL);
-
-	/* homepage */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_homepage"));
-	if (egg_strzero (details->url) == FALSE) {
-		gtk_widget_set_sensitive (widget, TRUE);
-
-		/* TRANSLATORS: tooltip: go to the web address */
-		text = g_strdup_printf (_("Visit %s"), details->url);
-		gtk_widget_set_tooltip_text (widget, text);
-		g_free (text);
-
-		/* TRANSLATORS: add an entry to go to the project home page */
-		gpk_application_add_detail_item (application, _("Project"), _("Homepage"), details->url);
-
-		/* save the url for the button */
-		g_free (application->priv->url);
-		application->priv->url = g_strdup (details->url);
-
-	} else {
-		gtk_widget_set_sensitive (widget, FALSE);
-	}
-
-	/* group */
-	if (details->group != PK_GROUP_ENUM_UNKNOWN) {
-		group = gpk_group_enum_to_localised_text (details->group);
-		/* TRANSLATORS: the group the package belongs in */
-		gpk_application_add_detail_item (application, _("Group"), group, NULL);
-	}
-
-	/* group */
-	if (!egg_strzero (details->license)) {
-		/* TRANSLATORS: the licence string for the package */
-		gpk_application_add_detail_item (application, _("License"), details->license, NULL);
-	}
-
-	/* menu path */
-	value = gpk_desktop_guess_best_file (application->priv->desktop, details->id->name);
-	if (value != NULL) {
-		text = gpk_desktop_get_menu_path (value);
-		if (text != NULL) {
-			/* TRANSLATORS: the path in the menu, e.g. Applications -> Games */
-			gpk_application_add_detail_item (application, _("Menu"), text, NULL);
-		}
-		g_free (text);
-	}
-	g_free (value);
-
-	/* set the description */
-	text = gpk_application_text_format_display (application, details->description);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
-	gpk_application_set_text_buffer (widget, text);
-	g_free (text);
-
-	/* if non-zero, set the size */
-	if (details->size > 0) {
-		/* set the size */
-		value = g_format_size_for_display (details->size);
-		if (g_strcmp0 (details->id->data, "meta") == 0)
-			/* TRANSLATORS: the size of the meta package */
-			gpk_application_add_detail_item (application, _("Size"), value, NULL);
-		else if (installed)
-			/* TRANSLATORS: the installed size in bytes of the package */
-			gpk_application_add_detail_item (application, _("Installed size"), value, NULL);
-		else
-			/* TRANSLATORS: the download size of the package */
-			gpk_application_add_detail_item (application, _("Download size"), value, NULL);
-		g_free (value);
-	}
-
-	/* set the repo text, or hide if installed */
-	if (!installed && g_strcmp0 (details->id->data, "meta") != 0) {
-		/* get the full name of the repo from the repo_id */
-		repo_name = gpk_application_get_full_repo_name (application, details->id->data);
-		/* TRANSLATORS: where the package came from, the software source name */
-		gpk_application_add_detail_item (application, _("Source"), repo_name, NULL);
-	}
-}
-
-/**
- * gpk_application_add_obj_to_results:
- **/
-static void
-gpk_application_add_obj_to_results (GpkApplication *application, const PkPackageObj *obj)
+gpk_application_add_item_to_results (GpkApplication *application, const PkItemPackage *item)
 {
 	GtkTreeIter iter;
 	gchar *summary;
 	const gchar *icon = NULL;
 	gchar *text;
-	gchar *package_id;
 	gboolean in_queue;
 	gboolean installed;
 	gboolean checkbox;
 	gboolean enabled;
 	PkBitfield state = 0;
 	static guint package_cnt = 0;
+	gchar **split;
 
 	/* format if required */
 	egg_markdown_set_output (application->priv->markdown, EGG_MARKDOWN_OUTPUT_PANGO);
-	summary = egg_markdown_parse (application->priv->markdown, obj->summary);
-	package_id = pk_package_id_to_string (obj->id);
+	summary = egg_markdown_parse (application->priv->markdown, item->summary);
 
 	/* mark as got so we don't warn */
 	application->priv->has_package = TRUE;
 
-	/* are we in the package list? */
-	in_queue = pk_package_list_contains (application->priv->package_list, package_id);
-	installed = (obj->info == PK_INFO_ENUM_INSTALLED) || (obj->info == PK_INFO_ENUM_COLLECTION_INSTALLED);
+	/* are we in the package array? */
+	in_queue = (pk_package_sack_find_by_id (application->priv->package_sack, item->package_id) != NULL);
+	installed = (item->info == PK_INFO_ENUM_INSTALLED) || (item->info == PK_INFO_ENUM_COLLECTION_INSTALLED);
 
 	if (installed)
 		pk_bitfield_add (state, GPK_STATE_INSTALLED);
@@ -1034,18 +1281,20 @@ gpk_application_add_obj_to_results (GpkApplication *application, const PkPackage
 		pk_bitfield_add (state, GPK_STATE_IN_LIST);
 
 	/* special icon */
-	if (obj->info == PK_INFO_ENUM_COLLECTION_INSTALLED || obj->info == PK_INFO_ENUM_COLLECTION_AVAILABLE)
+	if (item->info == PK_INFO_ENUM_COLLECTION_INSTALLED || item->info == PK_INFO_ENUM_COLLECTION_AVAILABLE)
 		pk_bitfield_add (state, GPK_STATE_COLLECTION);
 
 	/* use the application icon if available */
-	icon = gpk_desktop_guess_icon_name (application->priv->desktop, obj->id->name);
+	split = pk_package_id_split (item->package_id);
+	icon = gpk_desktop_guess_icon_name (application->priv->desktop, split[PK_PACKAGE_ID_NAME]);
+	g_strfreev (split);
 	if (icon == NULL)
 		icon = gpk_application_state_get_icon (state);
 
 	checkbox = gpk_application_state_get_checkbox (state);
 
 	/* use two lines */
-	text = gpk_package_id_format_twoline (obj->id, summary);
+	text = gpk_package_id_format_twoline (item->package_id, summary);
 
 	/* can we modify this? */
 	enabled = gpk_application_get_checkbox_enable (application, state);
@@ -1053,11 +1302,11 @@ gpk_application_add_obj_to_results (GpkApplication *application, const PkPackage
 	gtk_list_store_append (application->priv->packages_store, &iter);
 	gtk_list_store_set (application->priv->packages_store, &iter,
 			    PACKAGES_COLUMN_STATE, state,
-			    PACKAGES_COLUMN_CHECKBOX, installed ^ in_queue,
+			    PACKAGES_COLUMN_CHECKBOX, checkbox,
 			    PACKAGES_COLUMN_CHECKBOX_VISIBLE, enabled,
 			    PACKAGES_COLUMN_TEXT, text,
-			    PACKAGES_COLUMN_SUMMARY, obj->summary,
-			    PACKAGES_COLUMN_ID, package_id,
+			    PACKAGES_COLUMN_SUMMARY, item->summary,
+			    PACKAGES_COLUMN_ID, item->package_id,
 			    PACKAGES_COLUMN_IMAGE, icon,
 			    -1);
 
@@ -1067,72 +1316,11 @@ gpk_application_add_obj_to_results (GpkApplication *application, const PkPackage
 			gtk_main_iteration ();
 	}
 
-	g_free (package_id);
 	g_free (summary);
 	g_free (text);
 }
 
 /**
- * gpk_application_package_cb:
- **/
-static void
-gpk_application_package_cb (PkClient *client, const PkPackageObj *obj, GpkApplication *application)
-{
-	PkRoleEnum role;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	egg_debug ("package = %s:%s:%s", pk_info_enum_to_text (obj->info), obj->id->name, obj->summary);
-
-	/* ignore not search data */
-#if PK_CHECK_VERSION(0,5,1)
-	g_object_get (client,
-		      "role", &role,
-		      NULL);
-#else
-	pk_client_get_role (client, &role, NULL, NULL);
-#endif
-	if (role == PK_ROLE_ENUM_GET_DEPENDS ||
-	    role == PK_ROLE_ENUM_GET_REQUIRES ||
-	    role == PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES)
-		return;
-
-	/* ignore progress */
-	if (obj->info != PK_INFO_ENUM_INSTALLED && obj->info != PK_INFO_ENUM_AVAILABLE &&
-	    obj->info != PK_INFO_ENUM_COLLECTION_INSTALLED && obj->info != PK_INFO_ENUM_COLLECTION_AVAILABLE)
-		return;
-
-	/* add to list */
-	gpk_application_add_obj_to_results (application, obj);
-}
-
-/**
- * gpk_application_error_code_cb:
- **/
-static void
-gpk_application_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *details, GpkApplication *application)
-{
-	GtkWindow *window;
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	/* obvious message, don't tell the user */
-	if (code == PK_ERROR_ENUM_TRANSACTION_CANCELLED)
-		return;
-
-	/* ignore the ones we can handle */
-	if (code == PK_ERROR_ENUM_NO_LICENSE_AGREEMENT ||
-	    code == PK_ERROR_ENUM_MEDIA_CHANGE_REQUIRED ||
-	    pk_error_code_is_need_untrusted (code)) {
-		egg_debug ("error ignored as we're handling %s\n%s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (code),
-				gpk_error_enum_to_localised_message (code), details);
-}
-
-/**
  * gpk_application_suggest_better_search:
  **/
 static void
@@ -1176,130 +1364,6 @@ gpk_application_suggest_better_search (GpkApplication *application)
 }
 
 /**
- * gpk_application_finished_get_depends:
- **/
-static void
-gpk_application_finished_get_depends (GpkApplication *application, PkPackageList *list)
-{
-	GtkWindow *window;
-	gchar *name = NULL;
-	gchar *title = NULL;
-	gchar *message = NULL;
-	gchar **package_ids = NULL;
-	guint length;
-	GtkWidget *dialog;
-	gchar *package_id_selected = NULL;
-	gboolean ret;
-
-	/* get selection */
-	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
-	if (!ret) {
-		egg_warning ("no package selected");
-		goto out;
-	}
-
-	/* empty list */
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	if (pk_package_list_get_size (list) == 0) {
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: no packages returned */
-					_("No packages"),
-					/* TRANSLATORS: this package does not depend on any others */
-					_("This package does not depends on any others"), NULL);
-		goto out;
-	}
-
-	length = pk_package_list_get_size (list);
-	package_ids = pk_package_ids_from_id (package_id_selected);
-	name = gpk_dialog_package_id_name_join_locale (package_ids);
-	/* TRANSLATORS: title: show the number of other packages we depend on */
-	title = g_strdup_printf (ngettext ("%i additional package is required for %s",
-					   "%i additional packages are required for %s",
-					   length), length, name);
-
-	/* TRANSLATORS: message: show the list of dependant packages for this package */
-	message = g_strdup_printf (ngettext ("Packages listed below are required for %s to function correctly.",
-					     "Packages listed below are required for %s to function correctly.",
-					     length), name);
-
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
-	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
-	gpk_dialog_embed_package_list_widget (GTK_DIALOG (dialog), list);
-
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-out:
-	g_free (package_id_selected);
-	g_strfreev (package_ids);
-	g_free (name);
-	g_free (title);
-	g_free (message);
-}
-
-/**
- * gpk_application_finished_get_requires:
- **/
-static void
-gpk_application_finished_get_requires (GpkApplication *application, PkPackageList *list)
-{
-	GtkWindow *window;
-	gchar *name = NULL;
-	gchar *title = NULL;
-	gchar *message = NULL;
-	gchar **package_ids = NULL;
-	guint length;
-	GtkWidget *dialog;
-	gchar *package_id_selected = NULL;
-	gboolean ret;
-
-	/* get selection */
-	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
-	if (!ret) {
-		egg_warning ("no package selected");
-		goto out;
-	}
-
-	/* empty list */
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	if (pk_package_list_get_size (list) == 0) {
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: no packages returned */
-					_("No packages"),
-					/* TRANSLATORS: this package is not required by any others */
-					_("No other packages require this package"), NULL);
-		goto out;
-	}
-
-	length = pk_package_list_get_size (list);
-	package_ids = pk_package_ids_from_id (package_id_selected);
-	name = gpk_dialog_package_id_name_join_locale (package_ids);
-	/* TRANSLATORS: title: how many packages require this package */
-	title = g_strdup_printf (ngettext ("%i package requires %s",
-					   "%i packages require %s",
-					   length), length, name);
-
-	/* TRANSLATORS: show a list of packages for the package */
-	message = g_strdup_printf (ngettext ("Packages listed below require %s to function correctly.",
-					     "Packages listed below require %s to function correctly.",
-					     length), name);
-
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
-	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
-	gpk_dialog_embed_package_list_widget (GTK_DIALOG (dialog), list);
-
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-out:
-	g_free (package_id_selected);
-	g_strfreev (package_ids);
-	g_free (name);
-	g_free (title);
-	g_free (message);
-}
-
-/**
  * gpk_application_perform_search_idle_cb:
  **/
 static gboolean
@@ -1310,24 +1374,6 @@ gpk_application_perform_search_idle_cb (GpkApplication *application)
 }
 
 /**
- * gpk_application_primary_requeue:
- **/
-static gboolean
-gpk_application_primary_requeue (GpkApplication *application)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	/* retry new action */
-	ret = pk_client_requeue (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("Failed to requeue: %s", error->message);
-		g_error_free (error);
-	}
-	return ret;
-}
-
-/**
  * gpk_application_select_exact_match:
  *
  * NOTE: we have to do this in the finished_cb, as if we do this as we return
@@ -1343,11 +1389,11 @@ gpk_application_select_exact_match (GpkApplication *application, const gchar *te
 	GtkTreeModel *model;
 	GtkTreeSelection *selection = NULL;
 	gchar *package_id;
-	PkPackageId *id;
+	gchar **split;
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	/* get the first iter in the list */
+	/* get the first iter in the array */
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
@@ -1358,15 +1404,15 @@ gpk_application_select_exact_match (GpkApplication *application, const gchar *te
 		if (package_id != NULL) {
 
 			/* exact match, so select and scroll */
-			id = pk_package_id_new_from_string (package_id);
-			if (g_strcmp0 (id->name, text) == 0) {
+			split = pk_package_id_split (package_id);
+			if (g_strcmp0 (split[PK_PACKAGE_ID_NAME], text) == 0) {
 				selection = gtk_tree_view_get_selection (treeview);
 				gtk_tree_selection_select_iter (selection, &iter);
 				path = gtk_tree_model_get_path (model, &iter);
 				gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0.5f, 0.5f);
 				gtk_tree_path_free (path);
 			}
-			pk_package_id_free (id);
+			g_strfreev (split);
 
 			/* no point continuing for a second match */
 			if (selection != NULL)
@@ -1382,238 +1428,155 @@ gpk_application_select_exact_match (GpkApplication *application, const gchar *te
  * gpk_application_run_installed:
  **/
 static void
-gpk_application_run_installed (GpkApplication *application)
+gpk_application_run_installed (GpkApplication *application, PkResults *results)
 {
 	guint i;
-	guint len;
-	PkPackageList *list;
-	const PkPackageObj *obj;
 	GPtrArray *array;
+	const PkItemPackage *item;
+	GPtrArray *package_ids_array;
 	gchar **package_ids = NULL;
 
-	/* get the package list and filter on INSTALLED */
-	array = g_ptr_array_new ();
-	list = pk_client_get_package_list (application->priv->client_primary);
-	len = PK_OBJ_LIST (list)->len;
-	for (i=0; i<len; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		if (obj->info == PK_INFO_ENUM_INSTALLING)
-			g_ptr_array_add (array, pk_package_id_to_string (obj->id));
+	/* get the package array and filter on INSTALLED */
+	package_ids_array = g_ptr_array_new_with_free_func (g_free);
+	array = pk_results_get_package_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->info == PK_INFO_ENUM_INSTALLING)
+			g_ptr_array_add (package_ids_array, g_strdup (item->package_id));
 	}
 
 	/* nothing to show */
-	if (array->len == 0) {
+	if (package_ids_array->len == 0) {
 		egg_debug ("nothing to do");
 		goto out;
 	}
 
 	/* this is async */
-	package_ids = pk_package_ids_from_array (array);
+	package_ids = pk_ptr_array_to_strv (package_ids_array);
 	gpk_helper_run_show (application->priv->helper_run, package_ids);
 
 out:
 	g_strfreev (package_ids);
-	g_object_unref (list);
-	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-	g_ptr_array_free (array, TRUE);
+	g_ptr_array_unref (package_ids_array);
+	g_ptr_array_unref (array);
 }
 
+#if 0
 /**
  * gpk_application_finished_cb:
  **/
 static void
 gpk_application_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkApplication *application)
 {
-	GtkWidget *widget;
-	PkRoleEnum role;
-	PkPackageList *list;
-
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	/* get role */
-#if PK_CHECK_VERSION(0,5,1)
-	g_object_get (client,
-		      "role", &role,
-		      NULL);
-#else
-	pk_client_get_role (client, &role, NULL, NULL);
-#endif
-	egg_debug ("role: %s, exit: %s", pk_role_enum_to_text (role), pk_exit_enum_to_text (exit_enum));
-
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "progressbar_progress"));
-	gtk_widget_hide (widget);
-
-	/* reset UI */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	gpk_application_set_buttons_apply_clear (application);
-
-	/* need to handle retry with only_trusted=FALSE */
-	if (client == application->priv->client_primary &&
-	    exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) {
-		egg_debug ("need to handle untrusted");
-		pk_client_set_only_trusted (client, FALSE);
-		gpk_application_primary_requeue (application);
-		return;
-	}
-
-	/* if secondary, ignore */
-	if (client == application->priv->client_primary &&
-	    (exit_enum == PK_EXIT_ENUM_KEY_REQUIRED ||
-	     exit_enum == PK_EXIT_ENUM_EULA_REQUIRED)) {
-		egg_debug ("ignoring primary sig-required or eula");
-		return;
-	}
+//	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "progressbar_progress"));
+//	gtk_widget_hide (widget);
 
-	if (role == PK_ROLE_ENUM_GET_CATEGORIES) {
-		/* get complex group list */
-		gpk_application_categories_finished (application);
-	}
-
-#if PK_CHECK_VERSION(0,5,2)
-	/* simulating */
-	if (role == PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (application->priv->client_primary);
-		gpk_helper_deps_install_show (application->priv->helper_deps_install, application->priv->package_list, list);
-		g_object_unref (list);
-	}
-
-	/* get reqs */
-	if (role == PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (application->priv->client_primary);
-		gpk_helper_deps_remove_show (application->priv->helper_deps_remove, application->priv->package_list, list);
-		g_object_unref (list);
-	}
-
-	/* get deps */
-	if (role == PK_ROLE_ENUM_GET_DEPENDS &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (application->priv->client_primary);
-		gpk_application_finished_get_depends (application, list);
-		g_object_unref (list);
-	}
-
-	/* get reqs */
-	if (role == PK_ROLE_ENUM_GET_REQUIRES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (application->priv->client_primary);
-		gpk_application_finished_get_requires (application, list);
-		g_object_unref (list);
-	}
-#else
-	/* get deps */
-	if (role == PK_ROLE_ENUM_GET_DEPENDS &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (application->priv->client_primary);
-		if (application->priv->dep_check_info_only)
-			gpk_application_finished_get_depends (application, list);
-		else
-			gpk_helper_deps_install_show (application->priv->helper_deps_install, application->priv->package_list, list);
-		g_object_unref (list);
-	}
-
-	/* get reqs */
-	if (role == PK_ROLE_ENUM_GET_REQUIRES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (application->priv->client_primary);
-		if (application->priv->dep_check_info_only)
-			gpk_application_finished_get_requires (application, list);
-		else
-			gpk_helper_deps_remove_show (application->priv->helper_deps_remove, application->priv->package_list, list);
-		g_object_unref (list);
-	}
+}
 #endif
 
-	/* we've just agreed to auth or a EULA */
-	if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE ||
-	    role == PK_ROLE_ENUM_ACCEPT_EULA) {
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS)
-			gpk_application_primary_requeue (application);
-	}
+/**
+ * gpk_application_cancel_cb:
+ **/
+static void
+gpk_application_cancel_cb (GtkWidget *button_widget, GpkApplication *application)
+{
+	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	/* do we need to update the search? */
-	if (role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
-	    role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
-		/* refresh the search as the items may have changed and the filter has not changed */
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS) {
-			/* idle add in the background */
-			g_idle_add ((GSourceFunc) gpk_application_perform_search_idle_cb, application);
+	g_cancellable_cancel (application->priv->cancellable);
 
-			/* find applications that were installed, and offer to run them */
-			gpk_application_run_installed (application);
+	/* switch buttons around */
+	application->priv->search_mode = PK_MODE_UNKNOWN;
+}
 
-			/* clear if success */
-			pk_obj_list_clear (PK_OBJ_LIST (application->priv->package_list));
-			application->priv->action = PK_ACTION_NONE;
-			gpk_application_set_buttons_apply_clear (application);
-		}
-	}
+/**
+ * gpk_application_search_cb:
+ **/
+static void
+gpk_application_search_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	PkItemPackage *item;
+	guint i;
+	GtkWidget *widget;
+	GtkWindow *window;
 
-	/* we've just agreed to auth or a EULA */
-	if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE ||
-	    role == PK_ROLE_ENUM_ACCEPT_EULA) {
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS)
-			gpk_application_primary_requeue (application);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to search: %s", error->message);
+		g_error_free (error);
+		goto out;
 	}
 
-	if (role == PK_ROLE_ENUM_SEARCH_NAME ||
-	    role == PK_ROLE_ENUM_SEARCH_DETAILS ||
-	    role == PK_ROLE_ENUM_SEARCH_GROUP ||
-	    role == PK_ROLE_ENUM_GET_PACKAGES) {
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to search: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 
-		/* were there no entries found? */
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS && !application->priv->has_package) {
-			gpk_application_suggest_better_search (application);
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
 		}
+		goto out;
+	}
 
-		/* if there is an exact match, select it */
-		gpk_application_select_exact_match (application, application->priv->search_text);
-
-		/* focus back to the text extry */
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
-		gtk_widget_grab_focus (widget);
+	/* get data */
+	array = pk_results_get_package_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		gpk_application_add_item_to_results (application, item);
 	}
-}
 
-/**
- * gpk_application_cancel_cb:
- **/
-static void
-gpk_application_cancel_cb (GtkWidget *button_widget, GpkApplication *application)
-{
-	gboolean ret;
+	/* were there no entries found? */
+	if (!application->priv->has_package)
+		gpk_application_suggest_better_search (application);
 
-	g_return_if_fail (GPK_IS_APPLICATION (application));
+	/* if there is an exact match, select it */
+	gpk_application_select_exact_match (application, application->priv->search_text);
 
-	ret = pk_client_cancel (application->priv->client_primary, NULL);
-	egg_debug ("canceled? %i", ret);
+	/* focus back to the text extry */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
+	gtk_widget_grab_focus (widget);
 
-	/* switch buttons around */
-	if (ret) {
-		application->priv->search_mode = PK_MODE_UNKNOWN;
-	}
+	/* reset UI */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	gpk_application_set_buttons_apply_clear (application);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
  * gpk_application_perform_search_name_details_file:
  **/
-static gboolean
+static void
 gpk_application_perform_search_name_details_file (GpkApplication *application)
 {
 	GtkEntry *entry;
 	GtkWindow *window;
 	GError *error = NULL;
 	gboolean ret;
+	gchar **searches = NULL;
 
 	entry = GTK_ENTRY (gtk_builder_get_object (application->priv->builder, "entry_text"));
 	g_free (application->priv->search_text);
@@ -1622,10 +1585,10 @@ gpk_application_perform_search_name_details_file (GpkApplication *application)
 	/* have we got input? */
 	if (egg_strzero (application->priv->search_text)) {
 		egg_debug ("no input");
-		return FALSE;
+		goto out;
 	}
 
-	ret = pk_strvalidate (application->priv->search_text);
+	ret = !egg_strzero (application->priv->search_text);
 	if (!ret) {
 		egg_debug ("invalid input text, will fail");
 		/* TODO - make the dialog turn red... */
@@ -1635,34 +1598,33 @@ gpk_application_perform_search_name_details_file (GpkApplication *application)
 					_("Invalid search text"),
 					/* TRANSLATORS: message: tell the user that's not allowed */
 					_("The search text contains invalid characters"), NULL);
-		return FALSE;
+		goto out;
 	}
 	egg_debug ("find %s", application->priv->search_text);
 
-	/* reset */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to reset client: %s", error->message);
-		g_error_free (error);
-		return FALSE;
-	}
-
 	/* do the search */
+	searches = g_strsplit (application->priv->search_text, " ", -1);
 	if (application->priv->search_type == PK_SEARCH_NAME) {
-		ret = pk_client_search_name (application->priv->client_primary,
+		pk_client_search_name_async (PK_CLIENT(application->priv->task),
 					     application->priv->filters_current,
-					     application->priv->search_text, &error);
+					     searches, application->priv->cancellable,
+					     (PkProgressCallback) gpk_application_progress_cb, application,
+					     (GAsyncReadyCallback) gpk_application_search_cb, application);
 	} else if (application->priv->search_type == PK_SEARCH_DETAILS) {
-		ret = pk_client_search_details (application->priv->client_primary,
+		pk_client_search_details_async (PK_CLIENT(application->priv->task),
 					     application->priv->filters_current,
-					     application->priv->search_text, &error);
+					     searches, application->priv->cancellable,
+					     (PkProgressCallback) gpk_application_progress_cb, application,
+					     (GAsyncReadyCallback) gpk_application_search_cb, application);
 	} else if (application->priv->search_type == PK_SEARCH_FILE) {
-		ret = pk_client_search_file (application->priv->client_primary,
+		pk_client_search_file_async (PK_CLIENT(application->priv->task),
 					     application->priv->filters_current,
-					     application->priv->search_text, &error);
+					     searches, application->priv->cancellable,
+					     (PkProgressCallback) gpk_application_progress_cb, application,
+					     (GAsyncReadyCallback) gpk_application_search_cb, application);
 	} else {
 		egg_warning ("invalid search type");
-		return FALSE;
+		goto out;
 	}
 
 	if (!ret) {
@@ -1673,54 +1635,36 @@ gpk_application_perform_search_name_details_file (GpkApplication *application)
 					/* TRANSLATORS: low level failure, details to follow */
 					_("Running the transaction failed"), error->message);
 		g_error_free (error);
-		return FALSE;
+		goto out;
 	}
-
-	return TRUE;
+out:
+	g_strfreev (searches);
 }
 
 /**
  * gpk_application_perform_search_others:
  **/
-static gboolean
+static void
 gpk_application_perform_search_others (GpkApplication *application)
 {
-	gboolean ret;
-	GtkWindow *window;
-	GError *error = NULL;
-
-	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
-	g_return_val_if_fail (application->priv->group != NULL, FALSE);
+	gchar **groups;
 
-	/* cancel this, we don't care about old results that are pending */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to reset client: %s", error->message);
-		g_error_free (error);
-		return FALSE;
-	}
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+	g_return_if_fail (application->priv->group != NULL);
 
 	if (application->priv->search_mode == PK_MODE_GROUP) {
-		ret = pk_client_search_group (application->priv->client_primary,
-					      application->priv->filters_current,
-					      application->priv->group, &error);
+		groups = g_strsplit (application->priv->group, " ", -1);
+		pk_client_search_group_async (PK_CLIENT(application->priv->task),
+					      application->priv->filters_current, groups, application->priv->cancellable,
+					      (PkProgressCallback) gpk_application_progress_cb, application,
+					      (GAsyncReadyCallback) gpk_application_search_cb, application);
+		g_strfreev (groups);
 	} else {
-		ret = pk_client_get_packages (application->priv->client_primary,
-					      application->priv->filters_current, &error);
-	}
-
-	if (!ret) {
-		window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: title: could not get group data */
-					_("The group could not be queried"),
-					/* TRANSLATORS: low level failure */
-					_("Running the transaction failed"), error->message);
-		g_error_free (error);
-		return FALSE;
+		pk_client_get_packages_async (PK_CLIENT(application->priv->task),
+					      application->priv->filters_current, application->priv->cancellable,
+					      (PkProgressCallback) gpk_application_progress_cb, application,
+					      (GAsyncReadyCallback) gpk_application_search_cb, application);
 	}
-
-	return TRUE;
 }
 
 /**
@@ -1731,11 +1675,14 @@ gpk_application_populate_selected (GpkApplication *application)
 {
 	guint i;
 	guint len;
-	PkPackageList *list;
-	const PkPackageObj *obj;
+	PkItemPackage *item;
+	PkPackage *package;
+	PkInfoEnum info;
+	const gchar *package_id;
+	gchar *summary;
 
-	list = application->priv->package_list;
-	len = PK_OBJ_LIST (list)->len;
+	/* get size */
+	len = pk_package_sack_get_size (application->priv->package_sack);
 
 	/* nothing in queue */
 	if (len == 0) {
@@ -1745,8 +1692,16 @@ gpk_application_populate_selected (GpkApplication *application)
 
 	/* dump queue to package window */
 	for (i=0; i<len; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		gpk_application_add_obj_to_results (application, obj);
+		package = pk_package_sack_get_index (application->priv->package_sack, i);
+		package_id = pk_package_get_id (package);
+		g_object_get (package,
+			      "info", &info,
+			      "summary", &summary,
+			      NULL);
+		item = pk_item_package_new (info, package_id, summary);
+		gpk_application_add_item_to_results (application, item);
+		pk_item_package_unref (item);
+		g_free (summary);
 	}
 out:
 	return TRUE;
@@ -1755,27 +1710,24 @@ out:
 /**
  * gpk_application_perform_search:
  **/
-static gboolean
+static void
 gpk_application_perform_search (GpkApplication *application)
 {
-	gboolean ret = FALSE;
-
-	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
+	g_return_if_fail (GPK_IS_APPLICATION (application));
 
 	gpk_application_clear_details (application);
 	gpk_application_clear_packages (application);
 
 	if (application->priv->search_mode == PK_MODE_NAME_DETAILS_FILE) {
-		ret = gpk_application_perform_search_name_details_file (application);
+		gpk_application_perform_search_name_details_file (application);
 	} else if (application->priv->search_mode == PK_MODE_GROUP ||
 		   application->priv->search_mode == PK_MODE_ALL_PACKAGES) {
-		ret = gpk_application_perform_search_others (application);
+		gpk_application_perform_search_others (application);
 	} else if (application->priv->search_mode == PK_MODE_SELECTED) {
-		ret = gpk_application_populate_selected (application);
+		gpk_application_populate_selected (application);
 	} else {
 		egg_debug ("doing nothing");
 	}
-	return ret;
 }
 
 /**
@@ -1798,16 +1750,14 @@ static gboolean
 gpk_application_quit (GpkApplication *application)
 {
 	gint len;
-	gboolean ret;
 	GtkResponseType result;
-	GError *error = NULL;
 	GtkWindow *window;
 	GtkWidget *dialog;
 
 	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
 
 	/* do we have any items queued for removal or installation? */
-	len = PK_OBJ_LIST (application->priv->package_list)->len;
+	len = pk_package_sack_get_size (application->priv->package_sack);
 	if (len != 0) {
 		window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
 		dialog = gtk_message_dialog_new (window, GTK_DIALOG_MODAL,
@@ -1830,18 +1780,7 @@ gpk_application_quit (GpkApplication *application)
 	}
 
 	/* we might have visual stuff running, close them down */
-	ret = pk_client_cancel (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-	ret = pk_client_cancel (application->priv->client_secondary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
+	g_cancellable_cancel (application->priv->cancellable);
 
 	egg_debug ("emitting action-close");
 	g_signal_emit (application, signals [ACTION_CLOSE], 0);
@@ -1895,7 +1834,7 @@ gpk_application_text_changed_cb (GtkEntry *entry, GdkEventKey *event, GpkApplica
 	}
 
 	/* check for invalid chars */
-	valid = pk_strvalidate (package);
+	valid = !egg_strzero (package);
 
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
 	if (valid == FALSE || egg_strzero (package))
@@ -1972,12 +1911,12 @@ gpk_application_button_clear_cb (GtkWidget *widget_button, GpkApplication *appli
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	/* get the first iter in the list */
+	/* get the first iter in the array */
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
 
-	/* for all current items, reset the state if in the list */
+	/* for all current items, reset the state if in the array */
 	while (valid) {
 		gtk_tree_model_get (model, &iter, PACKAGES_COLUMN_STATE, &state, -1);
 		ret = pk_bitfield_contain (state, GPK_STATE_IN_LIST);
@@ -1998,7 +1937,7 @@ gpk_application_button_clear_cb (GtkWidget *widget_button, GpkApplication *appli
 	}
 
 	/* clear queue */
-	pk_obj_list_clear (PK_OBJ_LIST (application->priv->package_list));
+	pk_package_sack_clear (application->priv->package_sack);
 
 	/* force a button refresh */
 	selection = gtk_tree_view_get_selection (treeview);
@@ -2008,72 +1947,135 @@ gpk_application_button_clear_cb (GtkWidget *widget_button, GpkApplication *appli
 }
 
 /**
+ * gpk_application_install_packages_cb:
+ **/
+static void
+gpk_application_install_packages_cb (PkTask *task, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
+
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to install packages: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to install packages: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* idle add in the background */
+	g_idle_add ((GSourceFunc) gpk_application_perform_search_idle_cb, application);
+
+	/* find applications that were installed, and offer to run them */
+	gpk_application_run_installed (application, results);
+
+	/* clear if success */
+	pk_package_sack_clear (application->priv->package_sack);
+	application->priv->action = PK_ACTION_NONE;
+	gpk_application_set_buttons_apply_clear (application);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_application_remove_packages_cb:
+ **/
+static void
+gpk_application_remove_packages_cb (PkTask *task, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
+
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to remove packages: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to remove packages: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* idle add in the background */
+	g_idle_add ((GSourceFunc) gpk_application_perform_search_idle_cb, application);
+
+	/* clear if success */
+	pk_package_sack_clear (application->priv->package_sack);
+	application->priv->action = PK_ACTION_NONE;
+	gpk_application_set_buttons_apply_clear (application);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_application_button_apply_cb:
  **/
 static void
 gpk_application_button_apply_cb (GtkWidget *widget, GpkApplication *application)
 {
-	gboolean ret = FALSE;
-	GError *error = NULL;
 	gchar **package_ids = NULL;
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	package_ids = pk_package_list_to_strv (application->priv->package_list);
+	package_ids = pk_package_sack_get_ids (application->priv->package_sack);
 	if (application->priv->action == PK_ACTION_INSTALL) {
 
-		/* reset client */
-		ret = pk_client_reset (application->priv->client_primary, &error);
-		if (!ret) {
-			egg_warning ("failed to cancel: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
-
 		/* install */
-#if PK_CHECK_VERSION(0,5,2)
-		ret = pk_client_simulate_install_packages (application->priv->client_primary, package_ids, &error);
-#else
-		application->priv->dep_check_info_only = FALSE;
-		ret = pk_client_get_depends (application->priv->client_primary, pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED), package_ids, TRUE, &error);
-#endif
-		if (!ret) {
-			egg_warning ("failed to get depends: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
+		pk_task_install_packages_async (application->priv->task, package_ids, application->priv->cancellable,
+						(PkProgressCallback) gpk_application_progress_cb, application,
+						(GAsyncReadyCallback) gpk_application_install_packages_cb, application);
 
-		/* make package list insensitive */
+		/* make package array insensitive */
 		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
 		gtk_widget_set_sensitive (widget, FALSE);
-	}
-	if (application->priv->action == PK_ACTION_REMOVE) {
-		/* reset client */
-		ret = pk_client_reset (application->priv->client_primary, &error);
-		if (!ret) {
-			egg_warning ("failed to cancel: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
 
-		/* remove */
-#if PK_CHECK_VERSION(0,5,2)
-		ret = pk_client_simulate_remove_packages (application->priv->client_primary, package_ids, &error);
-#else
-		application->priv->dep_check_info_only = FALSE;
-		ret = pk_client_get_requires (application->priv->client_primary, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_ids, TRUE, &error);
-#endif
-		if (!ret) {
-			egg_warning ("failed to get requires: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
+	} else if (application->priv->action == PK_ACTION_REMOVE) {
 
-		/* make package list insensitive */
+		/* install */
+		pk_task_remove_packages_async (application->priv->task, package_ids, TRUE, FALSE, application->priv->cancellable,
+					       (PkProgressCallback) gpk_application_progress_cb, application,
+					       (GAsyncReadyCallback) gpk_application_remove_packages_cb, application);
+
+		/* make package array insensitive */
 		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
 		gtk_widget_set_sensitive (widget, FALSE);
 	}
-out:
 	g_strfreev (package_ids);
 	return;
 }
@@ -2156,7 +2158,7 @@ gpk_application_groups_treeview_changed_cb (GtkTreeSelection *selection, GpkAppl
 	gpk_application_clear_details (application);
 	gpk_application_clear_packages (application);
 
-	/* clear the search text if we clicked the group list */
+	/* clear the search text if we clicked the group array */
 	entry = GTK_ENTRY (gtk_builder_get_object (application->priv->builder, "entry_text"));
 	gtk_entry_set_text (entry, "");
 
@@ -2192,6 +2194,159 @@ gpk_application_groups_treeview_changed_cb (GtkTreeSelection *selection, GpkAppl
 }
 
 /**
+ * gpk_application_get_details_cb:
+ **/
+static void
+gpk_application_get_details_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	PkItemDetails *item;
+	GtkWidget *widget;
+	gchar *text;
+	gchar *value;
+	const gchar *repo_name;
+	const gchar *group;
+	gboolean installed;
+	gchar **split = NULL;
+	GtkWindow *window;
+
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of categories: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get cats: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_details_array (results);
+	if (array->len != 1) {
+		egg_warning ("not one entry %i", array->len);
+		goto out;
+	}
+
+	/* only choose the first item */
+	item = g_ptr_array_index (array, 0);
+
+	/* hide to start */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow_detail"));
+	gtk_widget_show (widget);
+
+	gtk_list_store_clear (application->priv->details_store);
+
+	split = pk_package_id_split (item->package_id);
+	installed = g_strcmp0 (split[PK_PACKAGE_ID_DATA], "installed") == 0;
+
+	/* if a collection, mark as such */
+	if (g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") == 0)
+		/* TRANSLATORS: the type of package is a collection (metagroup) */
+		gpk_application_add_detail_item (application, _("Type"), _("Collection"), NULL);
+
+	/* homepage */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_homepage"));
+	if (egg_strzero (item->url) == FALSE) {
+		gtk_widget_set_sensitive (widget, TRUE);
+
+		/* TRANSLATORS: tooltip: go to the web address */
+		text = g_strdup_printf (_("Visit %s"), item->url);
+		gtk_widget_set_tooltip_text (widget, text);
+		g_free (text);
+
+		/* TRANSLATORS: add an entry to go to the project home page */
+		gpk_application_add_detail_item (application, _("Project"), _("Homepage"), item->url);
+
+		/* save the url for the button */
+		g_free (application->priv->url);
+		application->priv->url = g_strdup (item->url);
+
+	} else {
+		gtk_widget_set_sensitive (widget, FALSE);
+	}
+
+	/* group */
+	if (item->group != PK_GROUP_ENUM_UNKNOWN) {
+		group = gpk_group_enum_to_localised_text (item->group);
+		/* TRANSLATORS: the group the package belongs in */
+		gpk_application_add_detail_item (application, _("Group"), group, NULL);
+	}
+
+	/* group */
+	if (!egg_strzero (item->license)) {
+		/* TRANSLATORS: the licence string for the package */
+		gpk_application_add_detail_item (application, _("License"), item->license, NULL);
+	}
+
+	/* menu path */
+	value = gpk_desktop_guess_best_file (application->priv->desktop, split[PK_PACKAGE_ID_NAME]);
+	if (value != NULL) {
+		text = gpk_desktop_get_menu_path (value);
+		if (text != NULL) {
+			/* TRANSLATORS: the path in the menu, e.g. Applications -> Games */
+			gpk_application_add_detail_item (application, _("Menu"), text, NULL);
+		}
+		g_free (text);
+	}
+	g_free (value);
+
+	/* set the description */
+	text = gpk_application_text_format_display (application, item->description);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
+	gpk_application_set_text_buffer (widget, text);
+	g_free (text);
+
+	/* if non-zero, set the size */
+	if (item->size > 0) {
+		/* set the size */
+		value = g_format_size_for_display (item->size);
+		if (g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") == 0)
+			/* TRANSLATORS: the size of the meta package */
+			gpk_application_add_detail_item (application, _("Size"), value, NULL);
+		else if (installed)
+			/* TRANSLATORS: the installed size in bytes of the package */
+			gpk_application_add_detail_item (application, _("Installed size"), value, NULL);
+		else
+			/* TRANSLATORS: the download size of the package */
+			gpk_application_add_detail_item (application, _("Download size"), value, NULL);
+		g_free (value);
+	}
+
+	/* set the repo text, or hide if installed */
+	if (!installed && g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") != 0) {
+		/* get the full name of the repo from the repo_id */
+		repo_name = gpk_application_get_full_repo_name (application, split[PK_PACKAGE_ID_DATA]);
+		/* TRANSLATORS: where the package came from, the software source name */
+		gpk_application_add_detail_item (application, _("Source"), repo_name, NULL);
+	}
+out:
+	g_strfreev (split);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_application_packages_treeview_clicked_cb:
  **/
 static void
@@ -2201,7 +2356,6 @@ gpk_application_packages_treeview_clicked_cb (GtkTreeSelection *selection, GpkAp
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gboolean ret;
-	GError *error = NULL;
 	gboolean show_install = TRUE;
 	gboolean show_remove = TRUE;
 	PkBitfield state;
@@ -2261,35 +2415,31 @@ gpk_application_packages_treeview_clicked_cb (GtkTreeSelection *selection, GpkAp
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_run"));
 	gtk_widget_set_sensitive (widget, ret);
 
-	/* cancel any previous request */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel, and adding to queue: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
 	/* get the details */
 	package_ids = pk_package_ids_from_id (package_id);
-	ret = pk_client_get_details (application->priv->client_primary, package_ids, &error);
-	if (!ret) {
-		egg_warning ("failed to get details: %s", error->message);
-		g_error_free (error);
-	}
+	pk_client_get_details_async (PK_CLIENT(application->priv->task), package_ids, application->priv->cancellable,
+				     (PkProgressCallback) gpk_application_progress_cb, application,
+				     (GAsyncReadyCallback) gpk_application_get_details_cb, application);
 out:
 	g_free (package_id);
 	g_strfreev (package_ids);
 }
 
 /**
- * gpk_application_connection_changed_cb:
+ * gpk_application_notify_network_state_cb:
  **/
 static void
-gpk_application_connection_changed_cb (PkConnection *pconnection, gboolean connected, GpkApplication *application)
+gpk_application_notify_network_state_cb (PkControl *control, GParamSpec *pspec, GpkApplication *application)
 {
+	PkNetworkEnum state;
+
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	egg_debug ("connected=%i", connected);
+	/* show icon? */
+	g_object_get (control,
+		      "network-state", &state,
+		      NULL);
+	egg_debug ("state=%i", state);
 }
 
 /**
@@ -2656,33 +2806,54 @@ gpk_application_menu_log_cb (GtkAction *action, GpkApplication *application)
 }
 
 /**
- * gpk_application_menu_refresh_cb:
+ * gpk_application_refresh_cache_cb:
  **/
 static void
-gpk_application_menu_refresh_cb (GtkAction *action, GpkApplication *application)
+gpk_application_refresh_cache_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
-	gboolean ret;
+	PkResults *results;
 	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
 
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to refresh: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	/* set correct view */
-	ret = pk_client_refresh_cache (application->priv->client_primary, TRUE, &error);
-	if (!ret) {
-		egg_warning ("cannot get refresh cache: %s", error->message);
-		g_error_free (error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to refresh: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
 		goto out;
 	}
 out:
-	return;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_application_menu_refresh_cb:
+ **/
+static void
+gpk_application_menu_refresh_cb (GtkAction *action, GpkApplication *application)
+{
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+	pk_client_refresh_cache_async (PK_CLIENT(application->priv->task), TRUE, application->priv->cancellable,
+				       (PkProgressCallback) gpk_application_progress_cb, application,
+				       (GAsyncReadyCallback) gpk_application_refresh_cache_cb, application);
 }
 
 /**
@@ -2929,303 +3100,6 @@ gpk_application_menu_filter_arch_cb (GtkWidget *widget, GpkApplication *applicat
 }
 
 /**
- * gpk_application_status_changed_timeout_cb:
- **/
-static gboolean
-gpk_application_status_changed_timeout_cb (GpkApplication *application)
-{
-	const gchar *text;
-	GtkWidget *widget;
-
-	/* set the text and show */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "label_status"));
-	text = gpk_status_enum_to_localised_text (application->priv->status_last);
-	gtk_label_set_label (GTK_LABEL (widget), text);
-
-	/* set icon */
-	gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (application->priv->image_status),
-					   application->priv->status_last, GTK_ICON_SIZE_LARGE_TOOLBAR);
-
-	/* show containing box */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
-	gtk_widget_show (widget);
-
-	/* never repeat */
-	application->priv->status_id = 0;
-	return FALSE;
-}
-
-/**
- * gpk_application_status_changed_cb:
- **/
-static void
-gpk_application_status_changed_cb (PkClient *client, PkStatusEnum status, GpkApplication *application)
-{
-	GtkWidget *widget;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	if (application->priv->action == PK_ACTION_INSTALL ||
-	    application->priv->action == PK_ACTION_REMOVE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_clear"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
-		gtk_widget_set_sensitive (widget, FALSE);
-	}
-
-	if (status == PK_STATUS_ENUM_FINISHED) {
-
-		/* re-enable UI */
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
-		gtk_widget_set_sensitive (widget, TRUE);
-
-		/* we've not yet shown, so don't bother */
-		if (application->priv->status_id > 0) {
-			g_source_remove (application->priv->status_id);
-			application->priv->status_id = 0;
-		}
-
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
-		gtk_widget_hide (widget);
-		gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (application->priv->image_status), FALSE);
-		goto out;
-	}
-
-	/* already pending show */
-	if (application->priv->status_id > 0)
-		goto out;
-
-	/* only show after some time in the transaction */
-	application->priv->status_id = g_timeout_add (GPK_UI_STATUS_SHOW_DELAY, (GSourceFunc) gpk_application_status_changed_timeout_cb, application);
-
-out:
-	/* save for the callback */
-	application->priv->status_last = status;
-}
-
-/**
- * gpk_application_allow_cancel_cb:
- **/
-static void
-gpk_application_allow_cancel_cb (PkClient *client, gboolean allow_cancel, GpkApplication *application)
-{
-	GtkWidget *widget;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_cancel"));
-	gtk_widget_set_sensitive (widget, allow_cancel);
-}
-
-/**
- * gpk_application_repo_signature_event_cb:
- **/
-static void
-gpk_application_repo_signature_event_cb (GpkHelperRepoSignature *helper_repo_signature, GtkResponseType type, const gchar *key_id, const gchar *package_id, GpkApplication *application)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_secondary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* install signature */
-	ret = pk_client_install_signature (application->priv->client_secondary, PK_SIGTYPE_ENUM_GPG, key_id, package_id, &error);
-	if (!ret) {
-		egg_warning ("cannot install signature: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return;
-}
-
-/**
- * gpk_application_eula_event_cb:
- **/
-static void
-gpk_application_eula_event_cb (GpkHelperEula *helper_eula, GtkResponseType type, const gchar *eula_id, GpkApplication *application)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_secondary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* install signature */
-	ret = pk_client_accept_eula (application->priv->client_secondary, eula_id, &error);
-	if (!ret) {
-		egg_warning ("cannot accept eula: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return;
-}
-
-/**
- * gpk_application_deps_remove_event_cb:
- **/
-static void
-gpk_application_deps_remove_event_cb (GpkHelperDepsRemove *helper_deps_remove, GtkResponseType type, GpkApplication *application)
-{
-	gboolean ret;
-	GError *error = NULL;
-	gchar **package_ids = NULL;
-	GtkWidget *widget;
-
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* actually remove packages this time */
-	package_ids = pk_package_list_to_strv (application->priv->package_list);
-	ret = pk_client_remove_packages (application->priv->client_primary, package_ids, TRUE, FALSE, &error);
-	if (!ret) {
-		egg_warning ("cannot remove packages: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* make package list insensitive */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
-	gtk_widget_set_sensitive (widget, FALSE);
-out:
-	g_strfreev (package_ids);
-}
-
-/**
- * gpk_application_deps_install_event_cb:
- **/
-static void
-gpk_application_deps_install_event_cb (GpkHelperDepsInstall *helper_deps_install, GtkResponseType type, GpkApplication *application)
-{
-	gboolean ret;
-	GError *error = NULL;
-	gchar **package_ids = NULL;
-	GtkWidget *widget;
-
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* actually remove packages this time */
-	package_ids = pk_package_list_to_strv (application->priv->package_list);
-#if PK_CHECK_VERSION(0,5,0)
-	ret = pk_client_install_packages (application->priv->client_primary, TRUE, package_ids, &error);
-#else
-	ret = pk_client_install_packages (application->priv->client_primary, package_ids, &error);
-#endif
-	if (!ret) {
-		egg_warning ("cannot install packages: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* make package list insensitive */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
-	gtk_widget_set_sensitive (widget, FALSE);
-
-out:
-	g_strfreev (package_ids);
-}
-
-/**
- * gpk_application_media_change_event_cb:
- **/
-static void
-gpk_application_media_change_event_cb (GpkHelperMediaChange *helper_media_change, GtkResponseType type, GpkApplication *application)
-{
-	if (type != GTK_RESPONSE_YES)
-		goto out;
-
-	/* requeue */
-	gpk_application_primary_requeue (application);
-out:
-	return;
-}
-
-/**
- * gpk_application_eula_required_cb:
- **/
-static void
-gpk_application_eula_required_cb (PkClient *client, const gchar *eula_id, const gchar *package_id,
-				    const gchar *vendor_name, const gchar *license_agreement, GpkApplication *application)
-{
-	/* use the helper */
-	gpk_helper_eula_show (application->priv->helper_eula, eula_id, package_id, vendor_name, license_agreement);
-}
-
-#if PK_CHECK_VERSION(0,4,7)
-/**
- * gpk_application_media_change_required_cb:
- **/
-static void
-gpk_application_media_change_required_cb (PkClient *client, PkMediaTypeEnum type, const gchar *media_id, const gchar *media_text, GpkApplication *application)
-{
-	/* use the helper */
-	gpk_helper_media_change_show (application->priv->helper_media_change, type, media_id, media_text);
-}
-#endif
-
-/**
- * gpk_application_repo_signature_required_cb:
- **/
-static void
-gpk_application_repo_signature_required_cb (PkClient *client, const gchar *package_id, const gchar *repository_name,
-					      const gchar *key_url, const gchar *key_userid, const gchar *key_id,
-					      const gchar *key_fingerprint, const gchar *key_timestamp,
-					      PkSigTypeEnum type, GpkApplication *application)
-{
-	/* use the helper */
-	gpk_helper_repo_signature_show (application->priv->helper_repo_signature, package_id, repository_name, key_url, key_userid, key_id, key_fingerprint, key_timestamp);
-}
-
-/**
  * gpk_application_package_row_activated_cb:
  **/
 static void
@@ -3283,23 +3157,6 @@ gpk_application_group_row_separator_func (GtkTreeModel *model, GtkTreeIter *iter
 }
 
 /**
- * pk_application_repo_detail_cb:
- **/
-static void
-pk_application_repo_detail_cb (PkClient *client, const gchar *repo_id,
-			       const gchar *description, gboolean enabled,
-			       GpkApplication *application)
-{
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	egg_debug ("repo = %s:%s", repo_id, description);
-	/* no problem, just no point adding as we will fallback to the repo_id */
-	if (description == NULL)
-		return;
-	g_hash_table_insert (application->priv->repos, g_strdup (repo_id), g_strdup (description));
-}
-
-/**
  * gpk_application_treeview_renderer_clicked:
  **/
 static void
@@ -3354,7 +3211,7 @@ gpk_application_add_welcome (GpkApplication *application)
 
 	/* enter something nice */
 	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_SEARCH_GROUP)) {
-		/* TRANSLATORS: welcome text if we can click the group list */
+		/* TRANSLATORS: welcome text if we can click the group array */
 		welcome = _("Enter a package name and then click find, or click a group to get started.");
 	} else {
 		/* TRANSLATORS: welcome text if we have to search by name */
@@ -3372,206 +3229,128 @@ gpk_application_add_welcome (GpkApplication *application)
 }
 
 /**
- * gpk_application_create_group_list_enum:
+ * gpk_application_create_group_array_enum:
  **/
-static gboolean
-gpk_application_create_group_list_enum (GpkApplication *application)
+static void
+gpk_application_create_group_array_enum (GpkApplication *application)
 {
 	GtkWidget *widget;
 	guint i;
-	GtkTreeIter iter;
-	const gchar *icon_name;
-	gboolean ret;
 
 	/* set to no indent */
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
 	gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (widget), FALSE);
 	gtk_tree_view_set_level_indentation  (GTK_TREE_VIEW (widget), 0);
 
-	/* add an "all" entry if we can GetPackages */
-	ret = gconf_client_get_bool (application->priv->gconf_client, GPK_CONF_APPLICATION_SHOW_ALL_PACKAGES, NULL);
-	if (ret && pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_PACKAGES)) {
-		gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
-		icon_name = gpk_role_enum_to_icon_name (PK_ROLE_ENUM_GET_PACKAGES);
-		gtk_tree_store_set (application->priv->groups_store, &iter,
-				    /* TRANSLATORS: title: all of the packages on the system and availble in sources */
-				    GROUPS_COLUMN_NAME, _("All packages"),
-				    /* TRANSLATORS: tooltip: all packages */
-				    GROUPS_COLUMN_SUMMARY, _("Show all packages"),
-				    GROUPS_COLUMN_ID, "all-packages",
-				    GROUPS_COLUMN_ACTIVE, TRUE,
-				    GROUPS_COLUMN_ICON, icon_name, -1);
-	}
-
-	/* no group information */
-	if (application->priv->groups == 0)
-		return FALSE;
-
-	/* add these at the top of the list */
-	if (pk_bitfield_contain (application->priv->groups, PK_GROUP_ENUM_COLLECTIONS))
-		gpk_application_group_add_data (application, PK_GROUP_ENUM_COLLECTIONS);
-	if (pk_bitfield_contain (application->priv->groups, PK_GROUP_ENUM_NEWEST))
-		gpk_application_group_add_data (application, PK_GROUP_ENUM_NEWEST);
-
-	/* add group item for selected items */
-	gpk_application_group_add_selected (application);
-
-	/* add a separator only if we can do both */
-	gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
-	gtk_tree_store_set (application->priv->groups_store, &iter,
-			    GROUPS_COLUMN_ID, "separator", -1);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
-	gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (widget),
-					      gpk_application_group_row_separator_func, NULL, NULL);
-
 	/* create group tree view if we can search by group */
 	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_SEARCH_GROUP)) {
 		/* add all the groups supported (except collections, which we handled above */
-		for (i=0; i<PK_GROUP_ENUM_UNKNOWN; i++) {
+		for (i=0; i<PK_GROUP_ENUM_LAST; i++) {
 			if (pk_bitfield_contain (application->priv->groups, i) &&
 			    i != PK_GROUP_ENUM_COLLECTIONS && i != PK_GROUP_ENUM_NEWEST)
 				gpk_application_group_add_data (application, i);
 		}
 	}
-
-	/* we populated the menu  */
-	return TRUE;
 }
 
 /**
- * gpk_application_categories_finished:
+ * gpk_application_get_categories_cb:
  **/
 static void
-gpk_application_categories_finished (GpkApplication *application)
+gpk_application_get_categories_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
-	PkObjList *list;
-	const PkCategoryObj *obj;
-	const PkCategoryObj *obj2;
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
 	GtkTreeIter iter;
 	GtkTreeIter iter2;
 	guint i, j;
 	GtkTreeView *treeview;
-	const gchar *icon_name;
-	gboolean ret;
-
-	/* set to expanders with indent */
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
-	gtk_tree_view_set_show_expanders (treeview, TRUE);
-	gtk_tree_view_set_level_indentation  (treeview, 3);
+	PkItemCategory *item;
+	PkItemCategory *item2;
+	GtkWindow *window;
 
-	/* add an "all" entry if we can GetPackages */
-	ret = gconf_client_get_bool (application->priv->gconf_client, GPK_CONF_APPLICATION_SHOW_ALL_PACKAGES, NULL);
-	if (ret && pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_PACKAGES)) {
-		gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
-		icon_name = gpk_role_enum_to_icon_name (PK_ROLE_ENUM_GET_PACKAGES);
-		gtk_tree_store_set (application->priv->groups_store, &iter,
-				    /* TRANSLATORS: title: all of the packages on the system and availble in sources */
-				    GROUPS_COLUMN_NAME, _("All packages"),
-				    /* TRANSLATORS: tooltip: all packages */
-				    GROUPS_COLUMN_SUMMARY, _("Show all packages"),
-				    GROUPS_COLUMN_ID, "all-packages",
-				    GROUPS_COLUMN_ACTIVE, TRUE,
-				    GROUPS_COLUMN_ICON, icon_name, -1);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of categories: %s", error->message);
+		g_error_free (error);
+		goto out;
 	}
 
-	/* add these at the top of the list */
-	if (pk_bitfield_contain (application->priv->groups, PK_GROUP_ENUM_COLLECTIONS))
-		gpk_application_group_add_data (application, PK_GROUP_ENUM_COLLECTIONS);
-	if (pk_bitfield_contain (application->priv->groups, PK_GROUP_ENUM_NEWEST))
-		gpk_application_group_add_data (application, PK_GROUP_ENUM_NEWEST);
-
-	/* add group item for selected items */
-	gpk_application_group_add_selected (application);
-
-	/* add a separator */
-	gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
-	gtk_tree_store_set (application->priv->groups_store, &iter,
-			    GROUPS_COLUMN_ID, "separator", -1);
-	gtk_tree_view_set_row_separator_func (treeview,
-					      gpk_application_group_row_separator_func, NULL, NULL);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get cats: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 
-	/* get return values */
-#if PK_CHECK_VERSION(0,5,0)
-	list = pk_client_get_category_list (application->priv->client_primary);
-#else
-	list = pk_client_get_cached_objects (application->priv->client_primary); /* removed in 0.5.x */
-#endif
-	if (list->len == 0) {
-		egg_warning ("no results from GetCategories");
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
 		goto out;
 	}
 
-	for (i=0; i < list->len; i++) {
-		obj = pk_obj_list_index (list, i);
+	/* set to expanders with indent */
+	treeview = GTK_TREE_VIEW (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
+	gtk_tree_view_set_show_expanders (treeview, TRUE);
+	gtk_tree_view_set_level_indentation  (treeview, 3);
+
+	/* add repos with descriptions */
+	array = pk_results_get_category_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
 
 		gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
 		gtk_tree_store_set (application->priv->groups_store, &iter,
-				    GROUPS_COLUMN_NAME, obj->name,
-				    GROUPS_COLUMN_SUMMARY, obj->summary,
-				    GROUPS_COLUMN_ID, obj->cat_id,
-				    GROUPS_COLUMN_ICON, obj->icon,
+				    GROUPS_COLUMN_NAME, item->name,
+				    GROUPS_COLUMN_SUMMARY, item->summary,
+				    GROUPS_COLUMN_ID, item->cat_id,
+				    GROUPS_COLUMN_ICON, item->icon,
 				    GROUPS_COLUMN_ACTIVE, FALSE,
 				    -1);
 		j = 0;
 		do {
 			/* only allows groups two layers deep */
-			obj2 = pk_obj_list_index (list, j);
-			if (g_strcmp0 (obj2->parent_id, obj->cat_id) == 0) {
+			item2 = g_ptr_array_index (array, j);
+			if (g_strcmp0 (item2->parent_id, item->cat_id) == 0) {
 				gtk_tree_store_append (application->priv->groups_store, &iter2, &iter);
 				gtk_tree_store_set (application->priv->groups_store, &iter2,
-						    GROUPS_COLUMN_NAME, obj2->name,
-						    GROUPS_COLUMN_SUMMARY, obj2->summary,
-						    GROUPS_COLUMN_ID, obj2->cat_id,
-						    GROUPS_COLUMN_ICON, obj2->icon,
+						    GROUPS_COLUMN_NAME, item2->name,
+						    GROUPS_COLUMN_SUMMARY, item2->summary,
+						    GROUPS_COLUMN_ID, item2->cat_id,
+						    GROUPS_COLUMN_ICON, item2->icon,
 						    GROUPS_COLUMN_ACTIVE, TRUE,
 						    -1);
-				pk_obj_list_remove (list, obj2);
+				g_ptr_array_remove (array, item2);
 			} else
 				j++;
-		} while (j < list->len);
+		} while (j < array->len);
 	}
 
 	/* open all expanders */
 	gtk_tree_view_collapse_all (treeview);
-	g_object_unref (list);
 out:
-	return;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_application_create_group_list_categories:
+ * gpk_application_create_group_array_categories:
  **/
-static gboolean
-gpk_application_create_group_list_categories (GpkApplication *application)
+static void
+gpk_application_create_group_array_categories (GpkApplication *application)
 {
-	GError *error = NULL;
-	gboolean ret = FALSE;
-
-	/* check we can do this */
-	if (!pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_CATEGORIES)) {
-		egg_warning ("backend does not support complex groups");
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
 	/* get categories supported */
-	pk_client_set_synchronous (application->priv->client_primary, TRUE, NULL);
-	ret = pk_client_get_categories (application->priv->client_primary, &error);
-	pk_client_set_synchronous (application->priv->client_primary, FALSE, NULL);
-	if (!ret) {
-		egg_warning ("failed to get categories: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return ret;
+	pk_client_get_categories_async (PK_CLIENT(application->priv->task), application->priv->cancellable,
+				        (PkProgressCallback) gpk_application_progress_cb, application,
+				        (GAsyncReadyCallback) gpk_application_get_categories_cb, application);
 }
 
 /**
@@ -3595,9 +3374,9 @@ gpk_application_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfE
 		ret = gconf_value_get_bool (value);
 		gtk_tree_store_clear (application->priv->groups_store);
 		if (ret)
-			gpk_application_create_group_list_categories (application);
+			gpk_application_create_group_array_categories (application);
 		else
-			gpk_application_create_group_list_enum (application);
+			gpk_application_create_group_array_enum (application);
 	} else if (g_strcmp0 (gconf_entry->key, GPK_CONF_AUTOCOMPLETE) == 0) {
 		ret = gconf_value_get_bool (value);
 		entry = GTK_ENTRY (gtk_builder_get_object (application->priv->builder, "entry_text"));
@@ -3612,60 +3391,233 @@ gpk_application_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfE
 }
 
 /**
- * gpk_application_files_cb:
+ * pk_backend_status_get_properties_cb:
  **/
 static void
-gpk_application_files_cb (PkClient *client, const gchar *package_id,
-			  const gchar *filelist, GpkApplication *application)
+pk_backend_status_get_properties_cb (GObject *object, GAsyncResult *res, GpkApplication *application)
 {
-	GPtrArray *array;
-	gchar **files;
-	gchar *title;
-	GtkWindow *window;
-	GtkWidget *dialog;
-	PkPackageId *id;
-	gchar *package_id_selected = NULL;
+	GtkWidget *widget;
+	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
 	gboolean ret;
+	PkBitfield filters;
+	gboolean enabled;
+	GtkTreeIter iter;
+	const gchar *icon_name;
 
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	/* get selection */
-	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
 	if (!ret) {
-		egg_warning ("no package selected");
+		/* TRANSLATORS: daemon is broken */
+		g_print ("%s: %s\n", _("Exiting as properties could not be retrieved"), error->message);
+		g_error_free (error);
 		goto out;
 	}
 
-	files = g_strsplit (filelist, ";", -1);
+	/* get values */
+	g_object_get (control,
+		      "roles", &application->priv->roles,
+		      "filters", &filters,
+		      "groups", &application->priv->groups,
+		      NULL);
 
-	/* convert to pointer array */
-	array = pk_strv_to_ptr_array (files);
-	g_ptr_array_sort (array, (GCompareFunc) gpk_application_strcmp_indirect);
+	/* Remove description/file array if needed. */
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_DETAILS) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow2"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_FILES) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_files"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_DEPENDS) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_depends"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_REQUIRES) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_requires"));
+		gtk_widget_hide (widget);
+	}
 
-	/* title */
-	id = pk_package_id_new_from_string (package_id_selected);
-	/* TRANSLATORS: title: how many files are installed by the application */
-	title = g_strdup_printf (ngettext ("%i file installed by %s",
-					   "%i files installed by %s",
-					   array->len), array->len, id->name);
+	/* hide the group selector if we don't support search-groups */
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_SEARCH_GROUP) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow_groups"));
+		gtk_widget_hide (widget);
+	}
 
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
-	gpk_dialog_embed_file_list_widget (GTK_DIALOG (dialog), array);
-	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
-	gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 250);
+	/* hide the refresh cache button if we can't do it */
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_REFRESH_CACHE) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_refresh"));
+		gtk_widget_hide (widget);
+	}
 
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
+	/* hide the software-sources button if we can't do it */
+	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_REPO_LIST) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_sources"));
+		gtk_widget_hide (widget);
+	}
 
-	g_free (title);
-	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-	g_ptr_array_free (array, TRUE);
-	g_strfreev (files);
-	pk_package_id_free (id);
+
+	/* hide the filters we can't support */
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_installed"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_DEVELOPMENT) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_devel"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_GUI) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_gui"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_FREE) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_free"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_ARCH) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_arch"));
+		gtk_widget_hide (widget);
+	}
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_SOURCE) == FALSE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_source"));
+		gtk_widget_hide (widget);
+	}
+
+	/* BASENAME, use by default, or hide */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_basename"));
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_BASENAME)) {
+		enabled = gconf_client_get_bool (application->priv->gconf_client,
+						 GPK_CONF_APPLICATION_FILTER_BASENAME, NULL);
+		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), enabled);
+		/* work round a gtk2+ bug: toggled should be fired when doing gtk_check_menu_item_set_active */
+		gpk_application_menu_filter_basename_cb (widget, application);
+	} else {
+		gtk_widget_hide (widget);
+	}
+
+	/* NEWEST, use by default, or hide */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_newest"));
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NEWEST)) {
+		/* set from remembered state */
+		enabled = gconf_client_get_bool (application->priv->gconf_client,
+						 GPK_CONF_APPLICATION_FILTER_NEWEST, NULL);
+		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), enabled);
+		/* work round a gtk2+ bug: toggled should be fired when doing gtk_check_menu_item_set_active */
+		gpk_application_menu_filter_newest_cb (widget, application);
+	} else {
+		gtk_widget_hide (widget);
+	}
+
+	/* ARCH, use by default, or hide */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_arch"));
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_ARCH)) {
+		/* set from remembered state */
+		enabled = gconf_client_get_bool (application->priv->gconf_client,
+						 GPK_CONF_APPLICATION_FILTER_ARCH, NULL);
+		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), enabled);
+		/* work round a gtk2+ bug: toggled should be fired when doing gtk_check_menu_item_set_active */
+		gpk_application_menu_filter_arch_cb (widget, application);
+	} else {
+		gtk_widget_hide (widget);
+	}
+
+	/* add an "all" entry if we can GetPackages */
+	ret = gconf_client_get_bool (application->priv->gconf_client, GPK_CONF_APPLICATION_SHOW_ALL_PACKAGES, NULL);
+	if (ret && pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_PACKAGES)) {
+		gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
+		icon_name = gpk_role_enum_to_icon_name (PK_ROLE_ENUM_GET_PACKAGES);
+		gtk_tree_store_set (application->priv->groups_store, &iter,
+				    /* TRANSLATORS: title: all of the packages on the system and availble in sources */
+				    GROUPS_COLUMN_NAME, _("All packages"),
+				    /* TRANSLATORS: tooltip: all packages */
+				    GROUPS_COLUMN_SUMMARY, _("Show all packages"),
+				    GROUPS_COLUMN_ID, "all-packages",
+				    GROUPS_COLUMN_ACTIVE, TRUE,
+				    GROUPS_COLUMN_ICON, icon_name, -1);
+	}
+
+	/* add these at the top of the array */
+	if (pk_bitfield_contain (application->priv->groups, PK_GROUP_ENUM_COLLECTIONS))
+		gpk_application_group_add_data (application, PK_GROUP_ENUM_COLLECTIONS);
+	if (pk_bitfield_contain (application->priv->groups, PK_GROUP_ENUM_NEWEST))
+		gpk_application_group_add_data (application, PK_GROUP_ENUM_NEWEST);
+
+	/* add group item for selected items */
+	gpk_application_group_add_selected (application);
+
+	/* add a separator */
+	gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
+	gtk_tree_store_set (application->priv->groups_store, &iter,
+			    GROUPS_COLUMN_ID, "separator", -1);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
+	gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (widget),
+					      gpk_application_group_row_separator_func, NULL, NULL);
+
+	/* simple array or category tree? */
+	ret = gconf_client_get_bool (application->priv->gconf_client, GPK_CONF_APPLICATION_CATEGORY_GROUPS, NULL);
+	if (ret && pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_CATEGORIES))
+		gpk_application_create_group_array_categories (application);
+	else
+		gpk_application_create_group_array_enum (application);
 out:
-	g_free (package_id_selected);
+	return;
+}
+
+/**
+ * gpk_application_get_repo_list_cb:
+ **/
+static void
+gpk_application_get_repo_list_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	PkItemRepoDetail *item;
+	guint i;
+	GtkWindow *window;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of repos: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to repo list: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* if obvious message, don't tell the user */
+		if (error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+			gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+						gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* add repos wih descriptions */
+	array = pk_results_get_repo_detail_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		egg_debug ("repo = %s:%s", item->repo_id, item->description);
+		/* no problem, just no point adding as we will fallback to the repo_id */
+		if (item->description == NULL)
+			continue;
+		g_hash_table_insert (application->priv->repos, g_strdup (item->repo_id), g_strdup (item->description));
+	}
+
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -3679,11 +3631,10 @@ gpk_application_init (GpkApplication *application)
 	GtkWidget *image;
 	GtkEntryCompletion *completion;
 	GtkTreeSelection *selection;
-	gboolean enabled;
 	gboolean ret;
 	gchar *mode;
 	GError *error = NULL;
-	GSList *list;
+	GSList *array;
 	guint retval;
 	GtkBox *box;
 
@@ -3692,15 +3643,13 @@ gpk_application_init (GpkApplication *application)
 	application->priv->url = NULL;
 	application->priv->search_text = NULL;
 	application->priv->has_package = FALSE;
-#if !PK_CHECK_VERSION(0,5,2)
-	application->priv->dep_check_info_only = FALSE;
-#endif
 	application->priv->details_event_id = 0;
 	application->priv->status_id = 0;
 	application->priv->status_last = PK_STATUS_ENUM_UNKNOWN;
-	application->priv->package_list = pk_package_list_new ();
+	application->priv->package_sack = pk_package_sack_new ();
 
 	application->priv->gconf_client = gconf_client_get_default ();
+	application->priv->cancellable = g_cancellable_new ();
 	application->priv->repos = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
 	application->priv->search_type = PK_SEARCH_UNKNOWN;
@@ -3717,7 +3666,7 @@ gpk_application_init (GpkApplication *application)
 				 (GConfClientNotifyFunc) gpk_application_gconf_key_changed_cb,
 				 application, NULL, NULL);
 
-	/* create list stores */
+	/* create array stores */
 	application->priv->packages_store = gtk_list_store_new (PACKAGES_COLUMN_LAST,
 							        G_TYPE_STRING,
 								G_TYPE_UINT64,
@@ -3746,49 +3695,15 @@ gpk_application_init (GpkApplication *application)
 	application->priv->control = pk_control_new ();
 
 	/* this is what we use mainly */
-	application->priv->client_primary = pk_client_new ();
-	pk_client_set_use_buffer (application->priv->client_primary, TRUE, NULL);
-	g_signal_connect (application->priv->client_primary, "files",
-			  G_CALLBACK (gpk_application_files_cb), application);
-	g_signal_connect (application->priv->client_primary, "package",
-			  G_CALLBACK (gpk_application_package_cb), application);
-	g_signal_connect (application->priv->client_primary, "details",
-			  G_CALLBACK (gpk_application_details_cb), application);
-	g_signal_connect (application->priv->client_primary, "error-code",
-			  G_CALLBACK (gpk_application_error_code_cb), application);
-	g_signal_connect (application->priv->client_primary, "finished",
-			  G_CALLBACK (gpk_application_finished_cb), application);
-	g_signal_connect (application->priv->client_primary, "status-changed",
-			  G_CALLBACK (gpk_application_status_changed_cb), application);
-	g_signal_connect (application->priv->client_primary, "allow-cancel",
-			  G_CALLBACK (gpk_application_allow_cancel_cb), application);
-	g_signal_connect (application->priv->client_primary, "repo-detail",
-			  G_CALLBACK (pk_application_repo_detail_cb), application);
-	g_signal_connect (application->priv->client_primary, "repo-signature-required",
-			  G_CALLBACK (gpk_application_repo_signature_required_cb), application);
-	g_signal_connect (application->priv->client_primary, "eula-required",
-			  G_CALLBACK (gpk_application_eula_required_cb), application);
-#if PK_CHECK_VERSION(0,4,7)
-	g_signal_connect (application->priv->client_primary, "media-change-required",
-			  G_CALLBACK (gpk_application_media_change_required_cb), application);
-#endif
-
-	/* this is for auth and eula callbacks */
-	application->priv->client_secondary = pk_client_new ();
-	pk_client_set_use_buffer (application->priv->client_secondary, TRUE, NULL);
-	g_signal_connect (application->priv->client_secondary, "error-code",
-			  G_CALLBACK (gpk_application_error_code_cb), application);
-	g_signal_connect (application->priv->client_secondary, "finished",
-			  G_CALLBACK (gpk_application_finished_cb), application);
-
-	/* get bitfield */
-	application->priv->roles = pk_control_get_actions (application->priv->control, NULL);
-	application->priv->filters = pk_control_get_filters (application->priv->control, NULL);
-	application->priv->groups = pk_control_get_groups (application->priv->control, NULL);
+	application->priv->task = PK_TASK(gpk_task_new ());
+	g_object_set (application->priv->task,
+		      "background", FALSE,
+		      NULL);
 
-	application->priv->pconnection = pk_connection_new ();
-	g_signal_connect (application->priv->pconnection, "connection-changed",
-			  G_CALLBACK (gpk_application_connection_changed_cb), application);
+	/* get properties */
+	pk_control_get_properties_async (application->priv->control, NULL, (GAsyncReadyCallback) pk_backend_status_get_properties_cb, application);
+	g_signal_connect (application->priv->control, "notify::network-state",
+			  G_CALLBACK (gpk_application_notify_network_state_cb), application);
 
 	/* get localised data from sqlite database */
 	application->priv->desktop = pk_desktop_new ();
@@ -3799,7 +3714,7 @@ gpk_application_init (GpkApplication *application)
 	/* get UI */
 	application->priv->builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (application->priv->builder, GPK_DATA "/gpk-application.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -3815,29 +3730,9 @@ gpk_application_init (GpkApplication *application)
 	main_window = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "window_manager"));
 
 	/* helpers */
-	application->priv->helper_repo_signature = gpk_helper_repo_signature_new ();
-	g_signal_connect (application->priv->helper_repo_signature, "event", G_CALLBACK (gpk_application_repo_signature_event_cb), application);
-	gpk_helper_repo_signature_set_parent (application->priv->helper_repo_signature, GTK_WINDOW (main_window));
-
-	application->priv->helper_eula = gpk_helper_eula_new ();
-	g_signal_connect (application->priv->helper_eula, "event", G_CALLBACK (gpk_application_eula_event_cb), application);
-	gpk_helper_eula_set_parent (application->priv->helper_eula, GTK_WINDOW (main_window));
-
 	application->priv->helper_run = gpk_helper_run_new ();
 	gpk_helper_run_set_parent (application->priv->helper_run, GTK_WINDOW (main_window));
 
-	application->priv->helper_deps_remove = gpk_helper_deps_remove_new ();
-	g_signal_connect (application->priv->helper_deps_remove, "event", G_CALLBACK (gpk_application_deps_remove_event_cb), application);
-	gpk_helper_deps_remove_set_parent (application->priv->helper_deps_remove, GTK_WINDOW (main_window));
-
-	application->priv->helper_deps_install = gpk_helper_deps_install_new ();
-	g_signal_connect (application->priv->helper_deps_install, "event", G_CALLBACK (gpk_application_deps_install_event_cb), application);
-	gpk_helper_deps_install_set_parent (application->priv->helper_deps_install, GTK_WINDOW (main_window));
-
-	application->priv->helper_media_change = gpk_helper_media_change_new ();
-	g_signal_connect (application->priv->helper_media_change, "event", G_CALLBACK (gpk_application_media_change_event_cb), application);
-	gpk_helper_media_change_set_parent (application->priv->helper_media_change, GTK_WINDOW (main_window));
-
 	/* Hide window first so that the dialogue resizes itself without redrawing */
 	gtk_widget_hide (main_window);
 	gtk_window_set_icon_name (GTK_WINDOW (main_window), GPK_ICON_SOFTWARE_INSTALLER);
@@ -3861,9 +3756,9 @@ gpk_application_init (GpkApplication *application)
 
 	/* set F1 = contents */
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menu_about"));
-	list = gtk_accel_groups_from_object (G_OBJECT (main_window));
-	if (list != NULL)
-		gtk_menu_set_accel_group (GTK_MENU (widget), GTK_ACCEL_GROUP (list->data));
+	array = gtk_accel_groups_from_object (G_OBJECT (main_window));
+	if (array != NULL)
+		gtk_menu_set_accel_group (GTK_MENU (widget), GTK_ACCEL_GROUP (array->data));
 
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_help"));
 	gtk_menu_item_set_accel_path (GTK_MENU_ITEM (widget),
@@ -4006,42 +3901,6 @@ gpk_application_init (GpkApplication *application)
 	g_signal_connect (widget, "toggled",
 			  G_CALLBACK (gpk_application_menu_filter_arch_cb), application);
 
-	/* Remove description/file list if needed. */
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_DETAILS) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow2"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_FILES) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_files"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_DEPENDS) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_depends"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_REQUIRES) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_requires"));
-		gtk_widget_hide (widget);
-	}
-
-	/* hide the group selector if we don't support search-groups */
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_SEARCH_GROUP) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow_groups"));
-		gtk_widget_hide (widget);
-	}
-
-	/* hide the refresh cache button if we can't do it */
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_REFRESH_CACHE) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_refresh"));
-		gtk_widget_hide (widget);
-	}
-
-	/* hide the software-sources button if we can't do it */
-	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_REPO_LIST) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_sources"));
-		gtk_widget_hide (widget);
-	}
-
 	/* simple find button */
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
 	g_signal_connect (widget, "clicked",
@@ -4080,70 +3939,6 @@ gpk_application_init (GpkApplication *application)
 	g_signal_connect (widget, "icon-press",
 			  G_CALLBACK (gpk_application_entry_text_icon_press_cb), application);
 
-	/* hide the filters we can't support */
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_INSTALLED) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_installed"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_DEVELOPMENT) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_devel"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_GUI) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_gui"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_FREE) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_free"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_ARCH) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_arch"));
-		gtk_widget_hide (widget);
-	}
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_SOURCE) == FALSE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_source"));
-		gtk_widget_hide (widget);
-	}
-
-	/* BASENAME, use by default, or hide */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_basename"));
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_BASENAME)) {
-		enabled = gconf_client_get_bool (application->priv->gconf_client,
-						 GPK_CONF_APPLICATION_FILTER_BASENAME, NULL);
-		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), enabled);
-		/* work round a gtk2+ bug: toggled should be fired when doing gtk_check_menu_item_set_active */
-		gpk_application_menu_filter_basename_cb (widget, application);
-	} else {
-		gtk_widget_hide (widget);
-	}
-
-	/* NEWEST, use by default, or hide */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_newest"));
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_NEWEST)) {
-		/* set from remembered state */
-		enabled = gconf_client_get_bool (application->priv->gconf_client,
-						 GPK_CONF_APPLICATION_FILTER_NEWEST, NULL);
-		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), enabled);
-		/* work round a gtk2+ bug: toggled should be fired when doing gtk_check_menu_item_set_active */
-		gpk_application_menu_filter_newest_cb (widget, application);
-	} else {
-		gtk_widget_hide (widget);
-	}
-
-	/* ARCH, use by default, or hide */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_arch"));
-	if (pk_bitfield_contain (application->priv->filters, PK_FILTER_ENUM_ARCH)) {
-		/* set from remembered state */
-		enabled = gconf_client_get_bool (application->priv->gconf_client,
-						 GPK_CONF_APPLICATION_FILTER_ARCH, NULL);
-		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), enabled);
-		/* work round a gtk2+ bug: toggled should be fired when doing gtk_check_menu_item_set_active */
-		gpk_application_menu_filter_arch_cb (widget, application);
-	} else {
-		gtk_widget_hide (widget);
-	}
-
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
 	g_signal_connect (widget, "key-press-event",
 			  G_CALLBACK (gpk_application_text_changed_cb), application);
@@ -4172,7 +3967,7 @@ gpk_application_init (GpkApplication *application)
 	g_signal_connect (GTK_TREE_VIEW (widget), "row-activated",
 			  G_CALLBACK (gpk_application_package_row_activated_cb), application);
 
-	/* use a list store for the extra data */
+	/* use a array store for the extra data */
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
 	gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (application->priv->details_store));
 
@@ -4210,29 +4005,10 @@ gpk_application_init (GpkApplication *application)
 	g_signal_connect (selection, "changed",
 			  G_CALLBACK (gpk_application_groups_treeview_changed_cb), application);
 
-	/* simple list or category tree? */
-	ret = gconf_client_get_bool (application->priv->gconf_client, GPK_CONF_APPLICATION_CATEGORY_GROUPS, NULL);
-	if (ret)
-		ret = gpk_application_create_group_list_categories (application);
-
-	/* fallback to creating a simple list if we can't do category list */
-	if (!ret)
-		gpk_application_create_group_list_enum (application);
-
-	/* reset client */
-	ret = pk_client_reset (application->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out_build;
-	}
-
 	/* get repos, so we can show the full name in the software source box */
-	ret = pk_client_get_repo_list (application->priv->client_primary, PK_FILTER_ENUM_NONE, &error);
-	if (!ret) {
-		egg_warning ("failed to get repo list: %s", error->message);
-		g_error_free (error);
-	}
+	pk_client_get_repo_list_async (PK_CLIENT(application->priv->task), PK_FILTER_ENUM_NONE, application->priv->cancellable,
+				       (PkProgressCallback) gpk_application_progress_cb, application,
+				       (GAsyncReadyCallback) gpk_application_get_repo_list_cb, application);
 
 	/* set current action */
 	application->priv->action = PK_ACTION_NONE;
@@ -4303,19 +4079,14 @@ gpk_application_finalize (GObject *object)
 	g_object_unref (application->priv->packages_store);
 	g_object_unref (application->priv->details_store);
 	g_object_unref (application->priv->control);
-	g_object_unref (application->priv->client_primary);
-	g_object_unref (application->priv->client_secondary);
-	g_object_unref (application->priv->pconnection);
+	g_object_unref (PK_CLIENT(application->priv->task));
 	g_object_unref (application->priv->desktop);
 	g_object_unref (application->priv->gconf_client);
 	g_object_unref (application->priv->markdown);
 	g_object_unref (application->priv->builder);
-	g_object_unref (application->priv->helper_eula);
 	g_object_unref (application->priv->helper_run);
-	g_object_unref (application->priv->helper_deps_remove);
-	g_object_unref (application->priv->helper_deps_install);
-	g_object_unref (application->priv->helper_media_change);
-	g_object_unref (application->priv->helper_repo_signature);
+	g_object_unref (application->priv->cancellable);
+	g_object_unref (application->priv->package_sack);
 
 	if (application->priv->status_id > 0)
 		g_source_remove (application->priv->status_id);
diff --git a/src/gpk-auto-refresh.c b/src/gpk-auto-refresh.c
index 12a3d2c..76972b8 100644
--- a/src/gpk-auto-refresh.c
+++ b/src/gpk-auto-refresh.c
@@ -34,7 +34,7 @@
 #endif /* HAVE_UNISTD_H */
 #include <glib/gi18n.h>
 #include <gconf/gconf-client.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <devkit-power-gobject/devicekit-power.h>
 
 #include "egg-debug.h"
@@ -171,142 +171,187 @@ gpk_auto_refresh_get_frequency_prefs (GpkAutoRefresh *arefresh, const gchar *key
 }
 
 /**
+ * gpk_auto_refresh_get_time_refresh_cache_cb:
+ **/
+static void
+gpk_auto_refresh_get_time_refresh_cache_cb (GObject *object, GAsyncResult *res, GpkAutoRefresh *arefresh)
+{
+	PkControl *control = PK_CONTROL (object);
+	GError *error = NULL;
+	guint seconds;
+	guint thresh;
+
+	/* get the result */
+	seconds = pk_control_get_time_since_action_finish (control, res, &error);
+	if (seconds == 0) {
+		egg_warning ("failed to get time: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	/* have we passed the timout? */
+	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_GET_UPDATES);
+	if (seconds < thresh) {
+		egg_debug ("not before timeout, thresh=%u, now=%u", thresh, seconds);
+		return;
+	}
+
+	/* send signal */
+	gpk_auto_refresh_signal_refresh_cache (arefresh);
+}
+
+/**
  * gpk_auto_refresh_maybe_refresh_cache:
  **/
-static gboolean
+static void
 gpk_auto_refresh_maybe_refresh_cache (GpkAutoRefresh *arefresh)
 {
-	guint time_s;
 	guint thresh;
-	gboolean ret;
 
-	g_return_val_if_fail (GPK_IS_AUTO_REFRESH (arefresh), FALSE);
+	g_return_if_fail (GPK_IS_AUTO_REFRESH (arefresh));
 
 	/* if we don't want to auto check for updates, don't do this either */
 	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_GET_UPDATES);
 	if (thresh == 0) {
-		egg_debug ("not when policy is to never refresh");
-		return FALSE;
+		egg_debug ("not when policy is to never get updates");
+		return;
 	}
 
 	/* not on battery */
 	if (arefresh->priv->on_battery) {
 		egg_debug ("not when on battery");
-		return FALSE;
+		return;
 	}
 
 	/* only do the refresh cache when the user is idle */
 	if (!arefresh->priv->session_idle) {
 		egg_debug ("not when session active");
-		return FALSE;
+		return;
 	}
 
 	/* get this each time, as it may have changed behind out back */
 	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_REFRESH_CACHE);
 	if (thresh == 0) {
 		egg_debug ("not when policy is to never refresh");
-		return FALSE;
+		return;
 	}
 
 	/* get the time since the last refresh */
-	ret = pk_control_get_time_since_action (arefresh->priv->control,
-						PK_ROLE_ENUM_REFRESH_CACHE, &time_s, NULL);
-	if (!ret) {
-		egg_warning ("failed to get last time");
-		return FALSE;
+	pk_control_get_time_since_action_async (arefresh->priv->control, PK_ROLE_ENUM_REFRESH_CACHE, NULL,
+						(GAsyncReadyCallback) gpk_auto_refresh_get_time_refresh_cache_cb, arefresh);
+}
+
+/**
+ * gpk_auto_refresh_get_time_get_updates_cb:
+ **/
+static void
+gpk_auto_refresh_get_time_get_updates_cb (GObject *object, GAsyncResult *res, GpkAutoRefresh *arefresh)
+{
+	PkControl *control = PK_CONTROL (object);
+	GError *error = NULL;
+	guint seconds;
+	guint thresh;
+
+	/* get the result */
+	seconds = pk_control_get_time_since_action_finish (control, res, &error);
+	if (seconds == 0) {
+		egg_warning ("failed to get time: %s", error->message);
+		g_error_free (error);
+		return;
 	}
 
 	/* have we passed the timout? */
-	if (time_s < thresh) {
-		egg_debug ("not before timeout, thresh=%u, now=%u", thresh, time_s);
-		return FALSE;
+	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_GET_UPDATES);
+	if (seconds < thresh) {
+		egg_debug ("not before timeout, thresh=%u, now=%u", thresh, seconds);
+		return;
 	}
 
-	gpk_auto_refresh_signal_refresh_cache (arefresh);
-	return TRUE;
+	/* send signal */
+	gpk_auto_refresh_signal_get_updates (arefresh);
 }
 
 /**
  * gpk_auto_refresh_maybe_get_updates:
  **/
-static gboolean
+static void
 gpk_auto_refresh_maybe_get_updates (GpkAutoRefresh *arefresh)
 {
-	guint time_s;
 	guint thresh;
-	gboolean ret;
 
-	g_return_val_if_fail (GPK_IS_AUTO_REFRESH (arefresh), FALSE);
+	g_return_if_fail (GPK_IS_AUTO_REFRESH (arefresh));
 
 	if (!arefresh->priv->force_get_updates_login) {
 		arefresh->priv->force_get_updates_login = TRUE;
 		if (gconf_client_get_bool (arefresh->priv->gconf_client, GPK_CONF_FORCE_GET_UPDATES_LOGIN, NULL)) {
 			egg_debug ("forcing get update due to GConf");
 			gpk_auto_refresh_signal_get_updates (arefresh);
-			return TRUE;
+			return;
 		}
 	}
 
-	/* get this each time, as it may have changed behind out back */
+	/* if we don't want to auto check for updates, don't do this either */
 	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_GET_UPDATES);
 	if (thresh == 0) {
-		egg_debug ("not when policy is set to never get updates");
-		return FALSE;
+		egg_debug ("not when policy is to never get updates");
+		return;
 	}
 
 	/* get the time since the last refresh */
-	ret = pk_control_get_time_since_action (arefresh->priv->control,
-						PK_ROLE_ENUM_GET_UPDATES, &time_s, NULL);
-	if (!ret) {
-		egg_warning ("failed to get last time");
-		return FALSE;
+	pk_control_get_time_since_action_async (arefresh->priv->control, PK_ROLE_ENUM_GET_UPDATES, NULL,
+						(GAsyncReadyCallback) gpk_auto_refresh_get_time_get_updates_cb, arefresh);
+}
+
+/**
+ * gpk_auto_refresh_get_time_get_upgrades_cb:
+ **/
+static void
+gpk_auto_refresh_get_time_get_upgrades_cb (GObject *object, GAsyncResult *res, GpkAutoRefresh *arefresh)
+{
+	PkControl *control = PK_CONTROL (object);
+	GError *error = NULL;
+	guint seconds;
+	guint thresh;
+
+	/* get the result */
+	seconds = pk_control_get_time_since_action_finish (control, res, &error);
+	if (seconds == 0) {
+		egg_warning ("failed to get time: %s", error->message);
+		g_error_free (error);
+		return;
 	}
 
 	/* have we passed the timout? */
-	if (time_s < thresh) {
-		egg_debug ("not before timeout, thresh=%u, now=%u", thresh, time_s);
-		return FALSE;
+	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_GET_UPDATES);
+	if (seconds < thresh) {
+		egg_debug ("not before timeout, thresh=%u, now=%u", thresh, seconds);
+		return;
 	}
 
-	gpk_auto_refresh_signal_get_updates (arefresh);
-	return TRUE;
+	/* send signal */
+	gpk_auto_refresh_signal_get_upgrades (arefresh);
 }
 
 /**
  * gpk_auto_refresh_maybe_get_upgrades:
  **/
-static gboolean
+static void
 gpk_auto_refresh_maybe_get_upgrades (GpkAutoRefresh *arefresh)
 {
-	guint time_s;
 	guint thresh;
-	gboolean ret;
 
-	g_return_val_if_fail (GPK_IS_AUTO_REFRESH (arefresh), FALSE);
+	g_return_if_fail (GPK_IS_AUTO_REFRESH (arefresh));
 
 	/* get this each time, as it may have changed behind out back */
 	thresh = gpk_auto_refresh_get_frequency_prefs (arefresh, GPK_CONF_FREQUENCY_GET_UPGRADES);
 	if (thresh == 0) {
 		egg_debug ("not when policy is set to never check for upgrades");
-		return FALSE;
+		return;
 	}
 
 	/* get the time since the last refresh */
-	ret = pk_control_get_time_since_action (arefresh->priv->control,
-						PK_ROLE_ENUM_GET_DISTRO_UPGRADES, &time_s, NULL);
-	if (!ret) {
-		egg_debug ("failed to get last time");
-		return FALSE;
-	}
-
-	/* have we passed the timout? */
-	if (time_s < thresh) {
-		egg_debug ("not before timeout, thresh=%u, now=%u", thresh, time_s);
-		return FALSE;
-	}
-
-	gpk_auto_refresh_signal_get_upgrades (arefresh);
-	return TRUE;
+	pk_control_get_time_since_action_async (arefresh->priv->control, PK_ROLE_ENUM_GET_DISTRO_UPGRADES, NULL,
+						(GAsyncReadyCallback) gpk_auto_refresh_get_time_get_upgrades_cb, arefresh);
 }
 
 /**
@@ -445,13 +490,16 @@ gpk_auto_refresh_convert_network_state (GpkAutoRefresh *arefresh, PkNetworkEnum
 }
 
 /**
- * gpk_auto_refresh_network_status_changed_cb:
+ * gpk_auto_refresh_notify_network_state_cb:
  **/
 static void
-gpk_auto_refresh_network_status_changed_cb (PkControl *control, PkNetworkEnum state, GpkAutoRefresh *arefresh)
+gpk_auto_refresh_notify_network_state_cb (PkControl *control, GParamSpec *pspec, GpkAutoRefresh *arefresh)
 {
+	PkNetworkEnum state;
+
 	g_return_if_fail (GPK_IS_AUTO_REFRESH (arefresh));
 
+	g_object_get (control, "network-state", &state, NULL);
 	arefresh->priv->network_active = gpk_auto_refresh_convert_network_state (arefresh, state);
 	egg_debug ("setting online %i", arefresh->priv->network_active);
 	if (arefresh->priv->network_active)
@@ -503,14 +551,41 @@ gpk_auto_refresh_client_changed_cb (DkpClient *client, GpkAutoRefresh *arefresh)
 }
 
 /**
+ * gpk_auto_refresh_get_properties_cb:
+ **/
+static void
+gpk_auto_refresh_get_properties_cb (GObject *object, GAsyncResult *res, GpkAutoRefresh *arefresh)
+{
+	PkNetworkEnum state;
+	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
+	gboolean ret;
+
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
+	if (!ret) {
+		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
+		egg_warning ("could not get properties");
+		g_error_free (error);
+		goto out;
+	}
+
+	/* get values */
+	g_object_get (control,
+		      "network-state", &state,
+		      NULL);
+	arefresh->priv->network_active = gpk_auto_refresh_convert_network_state (arefresh, state);
+out:
+	return;
+}
+
+/**
  * gpk_auto_refresh_init:
  * @auto_refresh: This class instance
  **/
 static void
 gpk_auto_refresh_init (GpkAutoRefresh *arefresh)
 {
-	PkNetworkEnum state;
-
 	arefresh->priv = GPK_AUTO_REFRESH_GET_PRIVATE (arefresh);
 	arefresh->priv->on_battery = FALSE;
 	arefresh->priv->network_active = FALSE;
@@ -530,10 +605,11 @@ gpk_auto_refresh_init (GpkAutoRefresh *arefresh)
 
 	/* we need to query the last cache refresh time */
 	arefresh->priv->control = pk_control_new ();
-	g_signal_connect (arefresh->priv->control, "network-state-changed",
-			  G_CALLBACK (gpk_auto_refresh_network_status_changed_cb), arefresh);
-	state = pk_control_get_network_state (arefresh->priv->control, NULL);
-	arefresh->priv->network_active = gpk_auto_refresh_convert_network_state (arefresh, state);
+	g_signal_connect (arefresh->priv->control, "notify::network-state",
+			  G_CALLBACK (gpk_auto_refresh_notify_network_state_cb), arefresh);
+
+	/* get network state */
+	pk_control_get_properties_async (arefresh->priv->control, NULL, (GAsyncReadyCallback) gpk_auto_refresh_get_properties_cb, arefresh);
 
 	/* use a DkpClient */
 	arefresh->priv->client = dkp_client_new ();
diff --git a/src/gpk-backend-status.c b/src/gpk-backend-status.c
index eb2aa21..3ccb885 100644
--- a/src/gpk-backend-status.c
+++ b/src/gpk-backend-status.c
@@ -21,26 +21,23 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
+#include <locale.h>
 #include <stdlib.h>
-#include <glib.h>
 #include <glib/gi18n.h>
-#include <dbus/dbus-glib.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
-#include <locale.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 
 #include "gpk-common.h"
 
+static GtkBuilder *builder = NULL;
+
 /**
- * pk_updates_close_cb:
+ * gpk_backend_status_close_cb:
  **/
 static void
-pk_updates_close_cb (GtkWidget *widget, gpointer data)
+gpk_backend_status_close_cb (GtkWidget *widget, gpointer data)
 {
 	GMainLoop *loop = (GMainLoop *) data;
 	egg_debug ("emitting action-close");
@@ -48,112 +45,53 @@ pk_updates_close_cb (GtkWidget *widget, gpointer data)
 }
 
 /**
- * pk_updates_delete_event_cb:
- * @event: The event type, unused.
+ * gpk_backend_status_delete_event_cb:
  **/
 static gboolean
-pk_updates_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+gpk_backend_status_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
 {
-	pk_updates_close_cb (widget, data);
+	gpk_backend_status_close_cb (widget, data);
 	return FALSE;
 }
 
 /**
- * main:
+ * gpk_backend_status_get_properties_cb:
  **/
-int
-main (int argc, char *argv[])
+static void
+gpk_backend_status_get_properties_cb (GObject *object, GAsyncResult *res, GMainLoop *loop)
 {
-	GMainLoop *loop;
-	gboolean verbose = FALSE;
-	gboolean program_version = FALSE;
-	GOptionContext *context;
 	GtkWidget *widget;
-	GtkBuilder *builder;
-	gchar *name;
-	gchar *author;
-	PkRoleEnum roles;
-	PkBitfield filters;
-	PkControl *control;
-	gboolean ret;
-	guint retval;
 	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
+	gboolean ret;
+	PkBitfield filters;
+	PkBitfield roles;
+	gchar *name = NULL;
+	gchar *author = NULL;
 
-	const GOptionEntry options[] = {
-		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
-		  _("Show extra debugging information"), NULL },
-		{ "version", '\0', 0, G_OPTION_ARG_NONE, &program_version,
-		  _("Show the program version and exit"), NULL },
-		{ NULL}
-	};
-
-	setlocale (LC_ALL, "");
-
-	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
-	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-	textdomain (GETTEXT_PACKAGE);
-
-	if (! g_thread_supported ()) {
-		g_thread_init (NULL);
-	}
-	dbus_g_thread_init ();
-	g_type_init ();
-
-	context = g_option_context_new (NULL);
-	g_option_context_set_summary (context, _("PackageKit Backend Details Viewer"));
-	g_option_context_add_main_entries (context, options, NULL);
-	g_option_context_parse (context, &argc, &argv, NULL);
-	g_option_context_free (context);
-
-	if (program_version) {
-		g_print (VERSION "\n");
-		return 0;
-	}
-
-	egg_debug_init (verbose);
-	gtk_init (&argc, &argv);
-
-	loop = g_main_loop_new (NULL, FALSE);
-
-	control = pk_control_new ();
-	roles = pk_control_get_actions (control, NULL);
-	filters = pk_control_get_filters (control, NULL);
-
-	/* general stuff */
-	ret = pk_control_get_backend_detail (control, &name, &author, NULL);
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
 	if (!ret) {
 		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
-		egg_warning (_("Exiting as backend details could not be retrieved"));
-		return 1;
-	}
-
-	/* get UI */
-	builder = gtk_builder_new ();
-	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-backend-status.ui", &error);
-	if (error != NULL) {
-		egg_warning ("failed to load ui: %s", error->message);
+		g_print ("%s: %s\n", _("Exiting as backend details could not be retrieved"), error->message);
 		g_error_free (error);
-		goto out_build;
+		g_main_loop_quit (loop);
+		goto out;
 	}
 
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_backend"));
-	gtk_window_set_icon_name (GTK_WINDOW (widget), GPK_ICON_SOFTWARE_LOG);
-
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
-	g_signal_connect (widget, "clicked",
-			  G_CALLBACK (pk_updates_close_cb), loop);
-
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_backend"));
-	g_signal_connect (widget, "delete_event",
-			  G_CALLBACK (pk_updates_delete_event_cb), loop);
-	gtk_widget_show (GTK_WIDGET (widget));
+	/* get values */
+	g_object_get (control,
+		      "roles", &roles,
+		      "filters", &filters,
+		      "backend-name", &name,
+		      "backend-author", &author,
+		      NULL);
 
+	/* setup GUI */
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_name"));
 	gtk_label_set_label (GTK_LABEL (widget), name);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_author"));
 	gtk_label_set_label (GTK_LABEL (widget), author);
-	g_free (name);
-	g_free (author);
 
 	/* actions */
 	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_CANCEL)) {
@@ -280,13 +218,88 @@ main (int argc, char *argv[])
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_newest"));
 		gtk_image_set_from_icon_name (GTK_IMAGE (widget), "gtk-apply", GTK_ICON_SIZE_MENU);
 	}
+out:
+	g_free (name);
+	g_free (author);
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+	GMainLoop *loop;
+	gboolean verbose = FALSE;
+	gboolean program_version = FALSE;
+	GOptionContext *context;
+	GtkWidget *widget;
+	PkControl *control;
+	guint retval;
+	GError *error = NULL;
+
+	const GOptionEntry options[] = {
+		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+		  _("Show extra debugging information"), NULL },
+		{ "version", '\0', 0, G_OPTION_ARG_NONE, &program_version,
+		  _("Show the program version and exit"), NULL },
+		{ NULL}
+	};
+
+	setlocale (LC_ALL, "");
+
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	if (! g_thread_supported ())
+		g_thread_init (NULL);
+	g_type_init ();
+
+	context = g_option_context_new (NULL);
+	g_option_context_set_summary (context, _("PackageKit Backend Details Viewer"));
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_parse (context, &argc, &argv, NULL);
+	g_option_context_free (context);
+
+	if (program_version) {
+		g_print (VERSION "\n");
+		return 0;
+	}
 
-out_build:
-	g_object_unref (builder);
-	g_object_unref (control);
+	egg_debug_init (verbose);
+	gtk_init (&argc, &argv);
 
+	loop = g_main_loop_new (NULL, FALSE);
+	control = pk_control_new ();
+
+	/* get UI */
+	builder = gtk_builder_new ();
+	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-backend-status.ui", &error);
+	if (retval == 0) {
+		egg_warning ("failed to load ui: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
+	g_signal_connect (widget, "clicked",
+			  G_CALLBACK (gpk_backend_status_close_cb), loop);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_backend"));
+	g_signal_connect (widget, "delete_event",
+			  G_CALLBACK (gpk_backend_status_delete_event_cb), loop);
+	gtk_window_set_icon_name (GTK_WINDOW (widget), GPK_ICON_SOFTWARE_LOG);
+	gtk_widget_show (GTK_WIDGET (widget));
+
+	/* get properties */
+	pk_control_get_properties_async (control, NULL, (GAsyncReadyCallback) gpk_backend_status_get_properties_cb, loop);
+
+	/* wait for results */
 	g_main_loop_run (loop);
+out:
+	g_object_unref (builder);
+	g_object_unref (control);
 	g_main_loop_unref (loop);
-
 	return 0;
 }
diff --git a/src/gpk-cell-renderer-info.c b/src/gpk-cell-renderer-info.c
index 16a3a7d..a0340d5 100644
--- a/src/gpk-cell-renderer-info.c
+++ b/src/gpk-cell-renderer-info.c
@@ -24,7 +24,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 
@@ -140,14 +140,11 @@ gpk_cell_renderer_finalize (GObject *object)
 static void
 gpk_cell_renderer_info_class_init (GpkCellRendererInfoClass *class)
 {
-	GtkCellRendererClass *cell_renderer_class;
 	GObjectClass *object_class = G_OBJECT_CLASS (class);
 	object_class->finalize = gpk_cell_renderer_finalize;
 
 	parent_class = g_type_class_peek_parent (class);
 
-	cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
-
 	object_class->get_property = gpk_cell_renderer_info_get_property;
 	object_class->set_property = gpk_cell_renderer_info_set_property;
 
diff --git a/src/gpk-cell-renderer-info.h b/src/gpk-cell-renderer-info.h
index ec20ca0..b088571 100644
--- a/src/gpk-cell-renderer-info.h
+++ b/src/gpk-cell-renderer-info.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #define GPK_TYPE_CELL_RENDERER_INFO		(gpk_cell_renderer_info_get_type())
 #define GPK_CELL_RENDERER_INFO(obj)		(G_TYPE_CHECK_INSTANCE_CAST((obj), GPK_TYPE_CELL_RENDERER_INFO, GpkCellRendererInfo))
diff --git a/src/gpk-cell-renderer-restart.c b/src/gpk-cell-renderer-restart.c
index 83f5209..566235d 100644
--- a/src/gpk-cell-renderer-restart.c
+++ b/src/gpk-cell-renderer-restart.c
@@ -24,7 +24,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 
@@ -81,22 +81,17 @@ gpk_cell_renderer_restart_set_property (GObject *object, guint param_id,
 static void
 gpk_cell_renderer_finalize (GObject *object)
 {
-	GpkCellRendererRestart *cru;
-	cru = GPK_CELL_RENDERER_RESTART (object);
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
 gpk_cell_renderer_restart_class_init (GpkCellRendererRestartClass *class)
 {
-	GtkCellRendererClass *cell_renderer_class;
 	GObjectClass *object_class = G_OBJECT_CLASS (class);
 	object_class->finalize = gpk_cell_renderer_finalize;
 
 	parent_class = g_type_class_peek_parent (class);
 
-	cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
-
 	object_class->get_property = gpk_cell_renderer_restart_get_property;
 	object_class->set_property = gpk_cell_renderer_restart_set_property;
 
diff --git a/src/gpk-cell-renderer-restart.h b/src/gpk-cell-renderer-restart.h
index 0b1edfa..edd418a 100644
--- a/src/gpk-cell-renderer-restart.h
+++ b/src/gpk-cell-renderer-restart.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #define GPK_TYPE_CELL_RENDERER_RESTART			(gpk_cell_renderer_restart_get_type())
 #define GPK_CELL_RENDERER_RESTART(obj)			(G_TYPE_CHECK_INSTANCE_CAST((obj), GPK_TYPE_CELL_RENDERER_RESTART, GpkCellRendererRestart))
diff --git a/src/gpk-cell-renderer-size.c b/src/gpk-cell-renderer-size.c
index b4a5c6f..1339167 100644
--- a/src/gpk-cell-renderer-size.c
+++ b/src/gpk-cell-renderer-size.c
@@ -91,14 +91,11 @@ gpk_cell_renderer_finalize (GObject *object)
 static void
 gpk_cell_renderer_size_class_init (GpkCellRendererSizeClass *class)
 {
-	GtkCellRendererClass *cell_renderer_class;
 	GObjectClass *object_class = G_OBJECT_CLASS (class);
 	object_class->finalize = gpk_cell_renderer_finalize;
 
 	parent_class = g_type_class_peek_parent (class);
 
-	cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
-
 	object_class->get_property = gpk_cell_renderer_size_get_property;
 	object_class->set_property = gpk_cell_renderer_size_set_property;
 
diff --git a/src/gpk-check-update.c b/src/gpk-check-update.c
index 1a7913c..1c2993c 100644
--- a/src/gpk-check-update.c
+++ b/src/gpk-check-update.c
@@ -37,22 +37,23 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <libnotify/notify.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <canberra-gtk.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
 #include "egg-dbus-monitor.h"
 
-#include "gpk-common.h"
-#include "gpk-gnome.h"
 #include "gpk-auto-refresh.h"
 #include "gpk-check-update.h"
+#include "gpk-common.h"
 #include "gpk-enum.h"
 #include "gpk-error.h"
-#include "gpk-helper-repo-signature.h"
+#include "gpk-gnome.h"
+#include "gpk-task.h"
 
 static void     gpk_check_update_finalize	(GObject	     *object);
+static void	gpk_check_update_libnotify_cb (NotifyNotification *notification, gchar *action, gpointer data);
 
 #define GPK_CHECK_UPDATE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_CHECK_UPDATE, GpkCheckUpdatePrivate))
 
@@ -69,18 +70,17 @@ struct GpkCheckUpdatePrivate
 	gboolean		 icon_inhibit_network_offline;
 	gboolean		 icon_inhibit_update_viewer_connected;
 	gchar			*icon_name;
-	PkTaskList		*tlist;
+	PkTransactionList	*tlist;
 	PkControl		*control;
-	GpkHelperRepoSignature	*helper_repo_signature;
 	GpkAutoRefresh		*arefresh;
-	PkClient		*client_primary;
-	PkClient		*client_secondary;
+	PkTask			*task;
 	GConfClient		*gconf_client;
 	guint			 number_updates_critical_last_shown;
 	NotifyNotification	*notification_updates_available;
 	GPtrArray		*important_updates_array;
 	EggDbusMonitor		*dbus_monitor_viewer;
 	guint			 updates_changed_id;
+	GCancellable		*cancellable;
 };
 
 G_DEFINE_TYPE (GpkCheckUpdate, gpk_check_update, G_TYPE_OBJECT)
@@ -320,7 +320,7 @@ gpk_check_update_popup_menu_cb (GtkStatusIcon *status_icon, guint button, guint3
 		gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
 }
 
-static gboolean gpk_check_update_query_updates (GpkCheckUpdate *cupdate, gboolean policy_action);
+static void gpk_check_update_query_updates (GpkCheckUpdate *cupdate);
 
 /**
  * gpk_check_update_get_updates_post_update_cb:
@@ -333,41 +333,170 @@ gpk_check_update_get_updates_post_update_cb (GpkCheckUpdate *cupdate)
 	/* debug so we can catch polling */
 	egg_debug ("post updates check");
 
-	gpk_check_update_query_updates (cupdate, FALSE);
+	gpk_check_update_query_updates (cupdate);
 	return FALSE;
 }
 
+
 /**
- * gpk_check_update_update_system:
+ * gpk_check_update_finished_notify:
  **/
-static gboolean
-gpk_check_update_update_system (GpkCheckUpdate *cupdate)
+static void
+gpk_check_update_finished_notify (GpkCheckUpdate *cupdate, PkResults *results)
 {
 	gboolean ret;
 	GError *error = NULL;
+	NotifyNotification *notification;
+	PkRestartEnum restart;
+	guint i;
+	GPtrArray *array;
+	const PkItemPackage *item;
+	GString *message_text = NULL;
+	guint skipped_number = 0;
+	const gchar *message;
+	gchar **split;
+
+	/* check we got some packages */
+	array = pk_results_get_package_array (results);
+	egg_debug ("length=%i", array->len);
+	if (array->len == 0) {
+		egg_debug ("no updates");
+		goto out;
+	}
+
+	message_text = g_string_new ("");
+
+	/* find any we skipped */
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+
+		split = pk_package_id_split (item->package_id);
+		egg_debug ("%s, %s, %s", pk_info_enum_to_text (item->info),
+			   split[PK_PACKAGE_ID_NAME], item->summary);
+		if (item->info == PK_INFO_ENUM_BLOCKED) {
+			skipped_number++;
+			g_string_append_printf (message_text, "<b>%s</b> - %s\n",
+						split[PK_PACKAGE_ID_NAME], item->summary);
+		}
+		g_strfreev (split);
+	}
 
-	ret = pk_client_reset (cupdate->priv->client_primary, &error);
+	/* notify the user if there were skipped entries */
+	if (skipped_number > 0) {
+		/* TRANSLATORS: we did the update, but some updates were skipped and not applied */
+		message = ngettext ("One package was skipped:",
+				    "Some packages were skipped:", skipped_number);
+		g_string_prepend (message_text, message);
+		g_string_append_c (message_text, '\n');
+	}
+
+	/* add a message that we need to restart */
+	restart = pk_results_get_require_restart_worst (results);
+	if (restart != PK_RESTART_ENUM_NONE) {
+		message = gpk_restart_enum_to_localised_text (restart);
+
+		/* add a gap if we are putting both */
+		if (skipped_number > 0)
+			g_string_append (message_text, "\n");
+
+		g_string_append (message_text, message);
+		g_string_append_c (message_text, '\n');
+	}
+
+	/* trim off extra newlines */
+	if (message_text->len != 0)
+		g_string_set_size (message_text, message_text->len-1);
+
+	/* do we do the notification? */
+	ret = gconf_client_get_bool (cupdate->priv->gconf_client, GPK_CONF_NOTIFY_UPDATE_COMPLETE, NULL);
 	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
+		egg_debug ("ignoring due to GConf");
 		goto out;
 	}
 
-#if PK_CHECK_VERSION(0,5,0)
-	ret = pk_client_update_system (cupdate->priv->client_primary, TRUE, &error);
-#else
-	ret = pk_client_update_system (cupdate->priv->client_primary, &error);
-#endif
+	/* TRANSLATORS: title: system update completed all okay */
+	notification = notify_notification_new_with_status_icon (_("The system update has completed"),
+								 message_text->str, "help-browser",
+								 cupdate->priv->status_icon);
+	notify_notification_set_timeout (notification, 15000);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+	if (restart == PK_RESTART_ENUM_SYSTEM) {
+		notify_notification_add_action (notification, "restart",
+						/* TRANSLATORS: restart computer as system packages need update */
+						_("Restart computer now"), gpk_check_update_libnotify_cb, cupdate, NULL);
+//		notify_notification_add_action (notification, "do-not-show-complete-restart",
+//						/* TRANSLATORS: don't show this option again (for restart) */
+//						_("Do not show this again"), gpk_check_update_libnotify_cb, cupdate, NULL);
+	} else {
+		notify_notification_add_action (notification, "do-not-show-complete",
+						/* TRANSLATORS: don't show this option again (when finished)  */
+						_("Do not show this again"), gpk_check_update_libnotify_cb, cupdate, NULL);
+	}
+	ret = notify_notification_show (notification, &error);
 	if (!ret) {
-		/* we failed, show the icon */
-		egg_warning ("cannot update system: %s", error->message);
+		egg_warning ("error: %s", error->message);
 		g_error_free (error);
-		gpk_check_update_set_icon_name (cupdate, NULL);
+	}
+out:
+	if (message_text != NULL)
+		g_string_free (message_text, TRUE);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+}
+
+/**
+ * gpk_check_update_update_system_finished_cb:
+ **/
+static void
+gpk_check_update_update_system_finished_cb (PkTask *task, GAsyncResult *res, GpkCheckUpdate *cupdate)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to update system: %s", error->message);
+		g_error_free (error);
+
 		/* we failed, so re-get the update list */
+		gpk_check_update_set_icon_name (cupdate, NULL);
 		g_timeout_add_seconds (2, (GSourceFunc) gpk_check_update_get_updates_post_update_cb, cupdate);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to update system: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		/* ignore some errors */
+		if (error_item->code != PK_ERROR_ENUM_PROCESS_KILL &&
+		    error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED &&
+		    error_item->code != PK_ERROR_ENUM_CANNOT_GET_LOCK) {
+			gpk_error_dialog (gpk_error_enum_to_localised_text (error_item->code),
+					  gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
 	}
+
+	/* play the sound, using sounds from the naming spec */
+	ca_context_play (ca_gtk_context_get (), 0,
+			 /* TODO: add a new sound to the spec */
+			 CA_PROP_EVENT_ID, "complete-download",
+			 /* TRANSLATORS: this is the application name for libcanberra */
+			 CA_PROP_APPLICATION_NAME, _("GNOME PackageKit Update Icon"),
+			 /* TRANSLATORS: this is the sound description */
+			 CA_PROP_EVENT_DESCRIPTION, _("Updated successfully"), NULL);
+
+	/* notify */
+	gpk_check_update_finished_notify (cupdate, results);
+	cupdate->priv->number_updates_critical_last_shown = 0;
 out:
-	return ret;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -378,9 +507,15 @@ out:
 static void
 gpk_check_update_activate_update_cb (GtkStatusIcon *status_icon, GpkCheckUpdate *icon)
 {
+	gboolean ret;
+	GError *error = NULL;
 	const gchar *command = "gpk-update-viewer";
-	if (!g_spawn_command_line_async (command, NULL))
-		egg_warning ("Couldn't execute command: %s", command);
+
+	ret = g_spawn_command_line_async (command, &error);
+	if (!ret) {
+		egg_warning ("Couldn't execute %s: %s", command, error->message);
+		g_error_free (error);
+	}
 }
 
 /**
@@ -417,13 +552,10 @@ gpk_check_update_libnotify_cb (NotifyNotification *notification, gchar *action,
 //		gpk_error_dialog (_("Error details"), _("Package Manager error details"), cupdate->priv->error_details);
 	} else if (g_strcmp0 (action, "cancel") == 0) {
 		/* try to cancel */
-		ret = pk_client_cancel (cupdate->priv->client_primary, &error);
-		if (!ret) {
-			egg_warning ("failed to cancel client: %s", error->message);
-			g_error_free (error);
-		}
+		g_cancellable_cancel (cupdate->priv->cancellable);
 	} else if (g_strcmp0 (action, "update-all-packages") == 0) {
-		gpk_check_update_update_system (cupdate);
+		pk_task_update_system_async (cupdate->priv->task, cupdate->priv->cancellable, NULL, NULL,
+					     (GAsyncReadyCallback) gpk_check_update_update_system_finished_cb, cupdate);
 	} else if (g_strcmp0 (action, "show-update-viewer") == 0) {
 		ret = g_spawn_command_line_async (BINDIR "/gpk-update-viewer", &error);
 		if (!ret) {
@@ -432,24 +564,12 @@ gpk_check_update_libnotify_cb (NotifyNotification *notification, gchar *action,
 		}
 	} else if (g_strcmp0 (action, "update-just-security") == 0) {
 
-		ret = pk_client_reset (cupdate->priv->client_primary, &error);
-		if (!ret) {
-			egg_warning ("cannot reset client: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
-
 		/* just update the important updates */
-		package_ids = pk_package_ids_from_array (cupdate->priv->important_updates_array);
-#if PK_CHECK_VERSION(0,5,0)
-		ret = pk_client_update_packages (cupdate->priv->client_primary, TRUE, package_ids, &error);
-#else
-		ret = pk_client_update_packages (cupdate->priv->client_primary, package_ids, &error);
-#endif
-		if (!ret) {
-			egg_warning ("Individual updates failed: %s", error->message);
-			g_error_free (error);
-		}
+		package_ids = pk_ptr_array_to_strv (cupdate->priv->important_updates_array);
+		egg_warning ("package_ids=%p", package_ids);
+		egg_warning ("package_ids[0]=%s", package_ids[0]);
+		pk_client_update_packages_async (PK_CLIENT(cupdate->priv->task), TRUE, package_ids, cupdate->priv->cancellable, NULL, NULL,
+					       (GAsyncReadyCallback) gpk_check_update_update_system_finished_cb, cupdate);
 		g_strfreev (package_ids);
 
 	} else if (g_strcmp0 (action, "distro-upgrade-info") == 0) {
@@ -461,7 +581,6 @@ gpk_check_update_libnotify_cb (NotifyNotification *notification, gchar *action,
 	} else {
 		egg_warning ("unknown action id: %s", action);
 	}
-out:
 	return;
 }
 
@@ -500,11 +619,7 @@ gpk_check_update_critical_updates_warning (GpkCheckUpdate *cupdate, const gchar
 	cupdate->priv->number_updates_critical_last_shown = array->len;
 
 	/* save for later */
-	if (cupdate->priv->important_updates_array != NULL) {
-		g_ptr_array_foreach (cupdate->priv->important_updates_array, (GFunc) g_free, NULL);
-		g_ptr_array_free (cupdate->priv->important_updates_array, TRUE);
-	}
-	cupdate->priv->important_updates_array = g_ptr_array_new ();
+	g_ptr_array_set_size (cupdate->priv->important_updates_array, 0);
 	for (i=0; i<array->len; i++) {
 		package_id = g_ptr_array_index (array, i);
 		g_ptr_array_add (cupdate->priv->important_updates_array, g_strdup (package_id));
@@ -564,29 +679,30 @@ gpk_check_update_critical_updates_warning (GpkCheckUpdate *cupdate, const gchar
  * gpk_check_update_client_info_to_bitfield:
  **/
 static PkBitfield
-gpk_check_update_client_info_to_bitfield (GpkCheckUpdate *cupdate, PkPackageList *list)
+gpk_check_update_client_info_to_bitfield (GpkCheckUpdate *cupdate, GPtrArray *array)
 {
 	guint i;
-	guint length;
 	PkBitfield infos = 0;
-	const PkPackageObj *obj;
+	const PkItemPackage *item;
+	gchar **split;
 
 	g_return_val_if_fail (GPK_IS_CHECK_UPDATE (cupdate), PK_INFO_ENUM_UNKNOWN);
 
 	/* shortcut */
-	length = pk_package_list_get_size (list);
-	if (length == 0)
+	if (array->len == 0)
 		return PK_INFO_ENUM_UNKNOWN;
 
-	/* add each status to a list */
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		if (obj == NULL) {
-			egg_warning ("not found obj %i", i);
+	/* add each status to a array */
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item == NULL) {
+			egg_warning ("not found item %i", i);
 			break;
 		}
-		egg_debug ("%s %s", obj->id->name, pk_info_enum_to_text (obj->info));
-		pk_bitfield_add (infos, obj->info);
+		split = pk_package_id_split (item->package_id);
+		egg_debug ("%s %s", split[PK_PACKAGE_ID_NAME], pk_info_enum_to_text (item->info));
+		g_strfreev (split);
+		pk_bitfield_add (infos, item->info);
 	}
 	return infos;
 }
@@ -595,7 +711,7 @@ gpk_check_update_client_info_to_bitfield (GpkCheckUpdate *cupdate, PkPackageList
  * gpk_check_update_get_best_update_icon:
  **/
 static const gchar *
-gpk_check_update_get_best_update_icon (GpkCheckUpdate *cupdate, PkPackageList *list)
+gpk_check_update_get_best_update_icon (GpkCheckUpdate *cupdate, GPtrArray *array)
 {
 	gint value;
 	PkBitfield infos;
@@ -603,8 +719,8 @@ gpk_check_update_get_best_update_icon (GpkCheckUpdate *cupdate, PkPackageList *l
 
 	g_return_val_if_fail (GPK_IS_CHECK_UPDATE (cupdate), NULL);
 
-	/* get an enumerated list with all the update types */
-	infos = gpk_check_update_client_info_to_bitfield (cupdate, list);
+	/* get an enumerated array with all the update types */
+	infos = gpk_check_update_client_info_to_bitfield (cupdate, array);
 
 	/* get the most important icon */
 	value = pk_bitfield_contain_priority (infos,
@@ -701,41 +817,6 @@ gpk_check_update_get_update_policy (GpkCheckUpdate *cupdate)
 }
 
 /**
- * gpk_check_update_query_updates:
- **/
-static gboolean
-gpk_check_update_query_updates (GpkCheckUpdate *cupdate, gboolean policy_action)
-{
-	gboolean ret = FALSE;
-	GError *error = NULL;
-
-	g_return_val_if_fail (GPK_IS_CHECK_UPDATE (cupdate), FALSE);
-
-	/* No point if we are already updating */
-	if (pk_task_list_contains_role (cupdate->priv->tlist, PK_ROLE_ENUM_UPDATE_PACKAGES) ||
-	    pk_task_list_contains_role (cupdate->priv->tlist, PK_ROLE_ENUM_UPDATE_SYSTEM)) {
-		egg_debug ("Not checking for updates as already in progress");
-		goto out;
-	}
-
-	ret = pk_client_reset (cupdate->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	ret = pk_client_get_updates (cupdate->priv->client_primary, PK_FILTER_ENUM_NONE, &error);
-	if (!ret) {
-		egg_warning ("cannot get updates: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return ret;
-}
-
-/**
  * gpk_check_update_notify_doing_updates:
  **/
 static void
@@ -773,85 +854,88 @@ out:
 }
 
 /**
- * gpk_check_update_policy_all_idle_cb:
+ * gpk_check_update_get_updates_finished_cb:
  **/
-static gboolean
-gpk_check_update_policy_all_idle_cb (GpkCheckUpdate *cupdate)
-{
-	gboolean ret;
-	ret = gpk_check_update_update_system (cupdate);
-	if (ret)
-		gpk_check_update_notify_doing_updates (cupdate);
-
-	/* never repeat */
-	return FALSE;
-}
-
-/**
- * gpk_check_update_process_updates:
- **/
-static gboolean
-gpk_check_update_process_updates (GpkCheckUpdate *cupdate, PkPackageList *list, gboolean policy_action)
+static void
+gpk_check_update_get_updates_finished_cb (GObject *object, GAsyncResult *res, GpkCheckUpdate *cupdate)
 {
-	const PkPackageObj *obj;
-	guint length;
+	PkClient *client = PK_CLIENT(object);
+	PkResults *results;
+	GError *error = NULL;
+	const PkItemPackage *item;
 	guint i;
 	guint more;
 	guint showing = 0;
-	gboolean ret = FALSE;
-	GString *status_security;
-	GString *status_tooltip;
+	gboolean ret;
+	GString *status_security = NULL;
+	GString *status_tooltip = NULL;
 	GpkUpdateEnum update;
-	GPtrArray *security_array;
+	GPtrArray *security_array = NULL;
 	const gchar *icon;
-	gchar *package_id;
 	gchar **package_ids;
-	GError *error = NULL;
+	gchar **split;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get updates: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
 
-	g_return_val_if_fail (GPK_IS_CHECK_UPDATE (cupdate), FALSE);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get updates: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		/* ignore some errors */
+		if (error_item->code != PK_ERROR_ENUM_PROCESS_KILL &&
+		    error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED &&
+		    error_item->code != PK_ERROR_ENUM_CANNOT_GET_LOCK) {
+			gpk_error_dialog (gpk_error_enum_to_localised_text (error_item->code),
+					  gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
 
 	/* sort by name */
-	pk_package_list_sort (list);
-
-	/* filter out the same package with multiple architectures */
-	pk_package_list_set_fuzzy_arch (list, TRUE);
-	pk_obj_list_remove_duplicate (PK_OBJ_LIST(list));
-
-	/* we have updates to process */
-	status_security = g_string_new ("");
-	status_tooltip = g_string_new ("");
-	security_array = g_ptr_array_new ();
+//	pk_package_list_sort (array);
 
-	/* find packages */
-	length = pk_package_list_get_size (list);
-	egg_debug ("length=%i", length);
+	/* get data */
+	array = pk_results_get_package_array (results);
 
 	/* we have no updates */
-	if (length == 0) {
+	if (array->len == 0) {
 		egg_debug ("no updates");
 		gpk_check_update_set_icon_name (cupdate, NULL);
 		goto out;
 	}
 
+	/* we have updates to process */
+	status_security = g_string_new ("");
+	status_tooltip = g_string_new ("");
+	security_array = g_ptr_array_new_with_free_func (g_free);
+
 	/* find the security updates first */
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		if (obj->info == PK_INFO_ENUM_SECURITY) {
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->info == PK_INFO_ENUM_SECURITY) {
 			/* add to array */
-			package_id = pk_package_id_to_string (obj->id);
-			g_ptr_array_add (security_array, package_id);
+			g_ptr_array_add (security_array, g_strdup (item->package_id));
 		}
 	}
 
 	/* get the security update text */
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		if (obj->info != PK_INFO_ENUM_SECURITY)
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->info != PK_INFO_ENUM_SECURITY)
 			continue;
 
 		/* don't use a huge notification that won't fit on the screen */
-		g_string_append_printf (status_security, "<b>%s</b> - %s\n",
-					obj->id->name, obj->summary);
+		split = pk_package_id_split (item->package_id);
+		g_string_append_printf (status_security, "<b>%s</b> - %s\n", split[PK_PACKAGE_ID_NAME], item->summary);
+		g_strfreev (split);
 		if (++showing == GPK_CHECK_UPDATE_MAX_NUMBER_SECURITY_ENTRIES) {
 			more = security_array->len - showing;
 			if (more > 0) {
@@ -865,7 +949,7 @@ gpk_check_update_process_updates (GpkCheckUpdate *cupdate, PkPackageList *list,
 	}
 
 	/* work out icon (cannot be NULL) */
-	icon = gpk_check_update_get_best_update_icon (cupdate, list);
+	icon = gpk_check_update_get_best_update_icon (cupdate, array);
 	gpk_check_update_set_icon_name (cupdate, icon);
 
 	/* make tooltip */
@@ -873,13 +957,12 @@ gpk_check_update_process_updates (GpkCheckUpdate *cupdate, PkPackageList *list,
 		g_string_set_size (status_security, status_security->len-1);
 	/* TRANSLATORS: tooltip: how many updates are waiting to be applied */
 	g_string_append_printf (status_tooltip, ngettext ("There is %d update available",
-							  "There are %d updates available", length), length);
+							  "There are %d updates available", array->len), array->len);
 	gtk_status_icon_set_tooltip_text (cupdate->priv->status_icon, status_tooltip->str);
 
 	/* if we are just refreshing after a failed update, don't try to do the actions */
-	if (!policy_action) {
+	if (FALSE) { //TODO
 		egg_debug ("skipping actions");
-		ret = TRUE;
 		goto out;
 	}
 
@@ -940,26 +1023,11 @@ gpk_check_update_process_updates (GpkCheckUpdate *cupdate, PkPackageList *list,
 			goto out;
 		}
 
-		ret = pk_client_reset (cupdate->priv->client_primary, &error);
-		if (!ret) {
-			egg_warning ("cannot reset client: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
-
 		/* convert */
-		package_ids = pk_package_ids_from_array (security_array);
-#if PK_CHECK_VERSION(0,5,0)
-		ret = pk_client_update_packages (cupdate->priv->client_primary, TRUE, package_ids, &error);
-#else
-		ret = pk_client_update_packages (cupdate->priv->client_primary, package_ids, &error);
-#endif
-		if (!ret) {
-			egg_warning ("Individual updates failed: %s", error->message);
-			g_error_free (error);
-		} else {
-			gpk_check_update_notify_doing_updates (cupdate);
-		}
+		package_ids = pk_ptr_array_to_strv (security_array);
+		pk_task_update_packages_async (cupdate->priv->task, package_ids, cupdate->priv->cancellable, NULL, NULL,
+					       (GAsyncReadyCallback) gpk_check_update_update_system_finished_cb, cupdate);
+		gpk_check_update_notify_doing_updates (cupdate);
 		g_strfreev (package_ids);
 		goto out;
 	}
@@ -967,29 +1035,85 @@ gpk_check_update_process_updates (GpkCheckUpdate *cupdate, PkPackageList *list,
 	/* just do everything */
 	if (update == GPK_UPDATE_ENUM_ALL) {
 		egg_debug ("we should do the update automatically!");
-		g_idle_add ((GSourceFunc) gpk_check_update_policy_all_idle_cb, cupdate);
+		pk_task_update_system_async (cupdate->priv->task, cupdate->priv->cancellable, NULL, NULL,
+					     (GAsyncReadyCallback) gpk_check_update_update_system_finished_cb, cupdate);
+		gpk_check_update_notify_doing_updates (cupdate);
 		goto out;
 	}
 
 	/* shouldn't happen */
 	egg_warning ("unknown update mode");
 out:
-	g_string_free (status_security, TRUE);
-	g_string_free (status_tooltip, TRUE);
-	g_ptr_array_foreach (security_array, (GFunc) g_free, NULL);
-	g_ptr_array_free (security_array, TRUE);
-	return ret;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (status_security != NULL)
+		g_string_free (status_security, TRUE);
+	if (status_tooltip != NULL)
+		g_string_free (status_tooltip, TRUE);
+	if (security_array != NULL)
+		g_ptr_array_unref (security_array);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_check_update_query_updates_idle_cb:
+ * gpk_check_update_get_active_roles:
  **/
-static gboolean
-gpk_check_update_query_updates_idle_cb (GpkCheckUpdate *cupdate)
+static PkBitfield
+gpk_check_update_get_active_roles (GpkCheckUpdate *cupdate, gchar **tids)
 {
-	egg_debug ("idle cb");
-	gpk_check_update_query_updates (cupdate, TRUE);
-	return FALSE;
+	PkRoleEnum role;
+	PkBitfield roles = 0;
+	guint i;
+	PkProgress *progress;
+	GError *error = NULL;
+
+	for (i=0; tids[i] != NULL; i++) {
+		/* get progress */
+		progress = pk_client_get_progress (PK_CLIENT(cupdate->priv->task), tids[i], cupdate->priv->cancellable, &error);
+		if (progress == NULL) {
+			egg_warning ("failed to get progress of %s: %s", tids[i], error->message);
+			g_error_free (error);
+			goto out;
+		}
+		/* get data */
+		g_object_get (progress,
+			      "role", &role,
+			      NULL);
+		pk_bitfield_add (roles, role);
+		g_object_unref (progress);
+	}
+out:
+	return roles;
+}
+
+/**
+ * gpk_check_update_query_updates:
+ **/
+static void
+gpk_check_update_query_updates (GpkCheckUpdate *cupdate)
+{
+	PkBitfield roles;
+	gchar **tids;
+	g_return_if_fail (GPK_IS_CHECK_UPDATE (cupdate));
+
+	/* No point if we are already updating */
+	tids = pk_transaction_list_get_ids (cupdate->priv->tlist);
+	roles = gpk_check_update_get_active_roles (cupdate, tids);
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_PACKAGES) ||
+	    pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_SYSTEM)) {
+		egg_debug ("Not checking for updates as already in progress");
+		goto out;
+	}
+
+	/* get new update list */
+	pk_client_get_updates_async (PK_CLIENT(cupdate->priv->task), PK_FILTER_ENUM_NONE, cupdate->priv->cancellable, NULL, NULL,
+				     (GAsyncReadyCallback) gpk_check_update_get_updates_finished_cb, cupdate);
+out:
+	g_strfreev (tids);
+	return;
 }
 
 /**
@@ -1000,7 +1124,7 @@ gpk_check_update_query_updates_changed_cb (GpkCheckUpdate *cupdate)
 {
 	egg_debug ("getting new update list (after we waited a short delay)");
 	cupdate->priv->updates_changed_id = 0;
-	gpk_check_update_query_updates (cupdate, TRUE);
+	gpk_check_update_query_updates (cupdate);
 	return FALSE;
 }
 
@@ -1026,7 +1150,7 @@ gpk_check_update_updates_changed_cb (PkControl *control, GpkCheckUpdate *cupdate
 		g_source_remove (cupdate->priv->updates_changed_id);
 
 	/* now try to get newest update list */
-	egg_debug ("updates changed, so getting new update list soon");
+	egg_debug ("updates changed, so getting new update list in %ss", GPK_CHECK_UPDATE_UPDATES_CHANGED_TIMEOUT);
 	cupdate->priv->updates_changed_id =
 		g_timeout_add_seconds (GPK_CHECK_UPDATE_UPDATES_CHANGED_TIMEOUT,
 				       (GSourceFunc) gpk_check_update_query_updates_changed_cb, cupdate);
@@ -1057,46 +1181,71 @@ gpk_check_update_restart_schedule_cb (PkClient *client, GpkCheckUpdate *cupdate)
 }
 
 /**
- * gpk_check_update_task_list_changed_cb:
+ * gpk_check_update_transaction_list_changed_cb:
  **/
 static void
-gpk_check_update_task_list_changed_cb (PkTaskList *tlist, GpkCheckUpdate *cupdate)
+gpk_check_update_transaction_list_changed_cb (PkControl *control, gchar **transaction_ids, GpkCheckUpdate *cupdate)
 {
+	PkBitfield roles;
 	g_return_if_fail (GPK_IS_CHECK_UPDATE (cupdate));
 
 	/* inhibit icon if we are updating */
+	roles = gpk_check_update_get_active_roles (cupdate, transaction_ids);
 	cupdate->priv->icon_inhibit_update_in_progress =
-		(pk_task_list_contains_role (tlist, PK_ROLE_ENUM_UPDATE_SYSTEM) ||
-		 pk_task_list_contains_role (tlist, PK_ROLE_ENUM_UPDATE_PACKAGES));
+		(pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_SYSTEM) ||
+		 pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_PACKAGES));
 	gpk_check_update_set_icon_visibility (cupdate);
 }
 
+
 /**
- * gpk_check_update_auto_refresh_cache_cb:
+ * gpk_check_update_refresh_cache_finished_cb:
  **/
 static void
-gpk_check_update_auto_refresh_cache_cb (GpkAutoRefresh *arefresh, GpkCheckUpdate *cupdate)
+gpk_check_update_refresh_cache_finished_cb (GObject *object, GAsyncResult *res, GpkCheckUpdate *cupdate)
 {
-	gboolean ret;
+	PkClient *client = PK_CLIENT(object);
+	PkResults *results;
 	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
 
-	g_return_if_fail (GPK_IS_CHECK_UPDATE (cupdate));
-
-	ret = pk_client_reset (cupdate->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to refresh the cache: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	ret = pk_client_refresh_cache (cupdate->priv->client_primary, TRUE, &error);
-	if (!ret) {
-		egg_warning ("cannot refresh cache: %s", error->message);
-		g_error_free (error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to refresh the cache: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		/* ignore some errors */
+		if (error_item->code != PK_ERROR_ENUM_PROCESS_KILL &&
+		    error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			gpk_error_dialog (gpk_error_enum_to_localised_text (error_item->code),
+					  gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
 		goto out;
 	}
 out:
-	return;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_check_update_auto_refresh_cache_cb:
+ **/
+static void
+gpk_check_update_auto_refresh_cache_cb (GpkAutoRefresh *arefresh, GpkCheckUpdate *cupdate)
+{
+	g_return_if_fail (GPK_IS_CHECK_UPDATE (cupdate));
+
+	pk_client_refresh_cache_async (PK_CLIENT(cupdate->priv->task), TRUE, cupdate->priv->cancellable, NULL, NULL,
+				       (GAsyncReadyCallback) gpk_check_update_refresh_cache_finished_cb, cupdate);
 }
 
 /**
@@ -1109,49 +1258,50 @@ gpk_check_update_auto_get_updates_cb (GpkAutoRefresh *arefresh, GpkCheckUpdate *
 
 	/* show the icon at login time */
 	egg_debug ("login cb");
-	g_idle_add ((GSourceFunc) gpk_check_update_query_updates_idle_cb, cupdate);
+	gpk_check_update_query_updates (cupdate);
 }
 
 /**
- * gpk_check_update_auto_get_upgrades_cb:
+ * gpk_check_update_get_distro_upgrades_finished_cb:
  **/
 static void
-gpk_check_update_auto_get_upgrades_cb (GpkAutoRefresh *arefresh, GpkCheckUpdate *cupdate)
+gpk_check_update_get_distro_upgrades_finished_cb (GObject *object, GAsyncResult *res, GpkCheckUpdate *cupdate)
 {
-	gboolean ret;
+	PkClient *client = PK_CLIENT(object);
+	PkResults *results;
 	GError *error = NULL;
+	GPtrArray *array = NULL;
+	gboolean ret;
+	guint i;
+	PkItemDistroUpgrade *item;
+	const gchar *title;
+	NotifyNotification *notification;
+	GString *string = NULL;
+	PkItemErrorCode *error_item = NULL;
 
-	ret = pk_client_reset (cupdate->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get upgrades: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	ret = pk_client_get_distro_upgrades (cupdate->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot get updates: %s", error->message);
-		g_error_free (error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get upgrades: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		/* ignore some errors */
+		if (error_item->code != PK_ERROR_ENUM_PROCESS_KILL &&
+		    error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+			gpk_error_dialog (gpk_error_enum_to_localised_text (error_item->code),
+					  gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
 		goto out;
 	}
-out:
-	return;
-}
 
-/**
- * gpk_check_update_process_distro_upgrades:
- **/
-static void
-gpk_check_update_process_distro_upgrades (GpkCheckUpdate *cupdate, PkObjList *array)
-{
-	gboolean ret;
-	GError *error = NULL;
-	guint i;
-	PkDistroUpgradeObj *obj;
-	const gchar *title;
-	NotifyNotification *notification;
-	GString *string = NULL;
-	g_return_if_fail (GPK_IS_CHECK_UPDATE (cupdate));
+	/* process results */
+	array = pk_results_get_distro_upgrade_array (results);
 
 	/* any updates? */
 	if (array->len == 0) {
@@ -1169,8 +1319,8 @@ gpk_check_update_process_distro_upgrades (GpkCheckUpdate *cupdate, PkObjList *ar
 	/* find the upgrade string */
 	string = g_string_new ("");
 	for (i=0; i < array->len; i++) {
-		obj = (PkDistroUpgradeObj *) pk_obj_list_index (array, i);
-		g_string_append_printf (string, "%s (%s)\n", obj->name, pk_distro_upgrade_enum_to_text (obj->state));
+		item = (PkItemDistroUpgrade *) g_ptr_array_index (array, i);
+		g_string_append_printf (string, "%s (%s)\n", item->name, pk_distro_upgrade_enum_to_text (item->state));
 	}
 	if (string->len != 0)
 		g_string_set_size (string, string->len-1);
@@ -1179,8 +1329,8 @@ gpk_check_update_process_distro_upgrades (GpkCheckUpdate *cupdate, PkObjList *ar
 	title = _("Distribution upgrades available");
 	notification = notify_notification_new_with_status_icon (title, string->str, "help-browser", cupdate->priv->status_icon);
 	if (notification == NULL) {
-		egg_warning ("failed to get bubble");
-		return;
+		egg_warning ("failed to make bubble");
+		goto out;
 	}
 	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
 	notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
@@ -1196,18 +1346,38 @@ gpk_check_update_process_distro_upgrades (GpkCheckUpdate *cupdate, PkObjList *ar
 		g_error_free (error);
 	}
 out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
 	if (string != NULL)
 		g_string_free (string, TRUE);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_check_update_auto_get_upgrades_cb:
+ **/
+static void
+gpk_check_update_auto_get_upgrades_cb (GpkAutoRefresh *arefresh, GpkCheckUpdate *cupdate)
+{
+	pk_client_get_distro_upgrades_async (PK_CLIENT(cupdate->priv->task), cupdate->priv->cancellable, NULL, NULL,
+					     (GAsyncReadyCallback) gpk_check_update_get_distro_upgrades_finished_cb, cupdate);
 }
 
 /**
- * gpk_check_update_network_status_changed_cb:
+ * gpk_check_update_notify_network_status_cb:
  **/
 static void
-gpk_check_update_network_status_changed_cb (PkControl *control, PkNetworkEnum state, GpkCheckUpdate *cupdate)
+gpk_check_update_notify_network_status_cb (PkControl *control, GParamSpec *pspec, GpkCheckUpdate *cupdate)
 {
+	PkNetworkEnum status;
+
+	g_object_get (control, "network-state", &status, NULL);
+
 	/* inhibit icon when we are offline */
-	cupdate->priv->icon_inhibit_network_offline = (state == PK_NETWORK_ENUM_OFFLINE);
+	cupdate->priv->icon_inhibit_network_offline = (status == PK_NETWORK_ENUM_OFFLINE);
 	gpk_check_update_set_icon_visibility (cupdate);
 }
 
@@ -1222,306 +1392,42 @@ gpk_cupdate_connection_changed_cb (EggDbusMonitor *monitor, gboolean connected,
 	egg_debug ("update viewer on the bus: %i", connected);
 	cupdate->priv->icon_inhibit_update_viewer_connected = connected;
 	gpk_check_update_set_icon_visibility (cupdate);
-
-	/* if the update viewer is coming back, do a check for updates so we don't
-	 *  show there are updates when the update viewer just said there were none */
-	if (!connected) {
-		egg_debug ("updatdate viewer back cb");
-		g_idle_add ((GSourceFunc) gpk_check_update_query_updates_idle_cb, cupdate);
-	}
 }
 
 /**
- * gpk_check_update_error_code_cb:
+ * gpk_check_update_get_properties_cb:
  **/
 static void
-gpk_check_update_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *details, GpkCheckUpdate *cupdate)
+gpk_check_update_get_properties_cb (GObject *object, GAsyncResult *res, GpkCheckUpdate *cupdate)
 {
-	PkRoleEnum role;
-	gboolean ret;
+	PkNetworkEnum state;
 	GError *error = NULL;
-
-	/* ignore some errors */
-	if (code == PK_ERROR_ENUM_PROCESS_KILL ||
-	    code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
-		egg_debug ("error ignored %s\n%s", pk_error_enum_to_text (code), details);
-		goto out;
-	}
-
-	/* ignore the ones we can handle */
-	if (pk_error_code_is_need_untrusted (code)) {
-		egg_debug ("error ignored as we're handling %s\n%s", pk_error_enum_to_text (code), details);
-		goto out;
-	}
-
-	/* get the role */
-	ret = pk_client_get_role (client, &role, NULL, &error);
-	if (!ret) {
-		egg_warning ("failed to get role: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* if we're doing queries automatically for the user, don't spam them
-	   with locking failure messages */
-	if (code == PK_ERROR_ENUM_CANNOT_GET_LOCK) {
-		if (role == PK_ROLE_ENUM_GET_UPDATES ||
-		    role == PK_ROLE_ENUM_GET_DISTRO_UPGRADES) {
-			egg_debug ("cannot get lock for automatic action, ignoring");
-			goto out;
-		}
-	}
-
-	/* not modal as we are a status icon */
-	gpk_error_dialog (gpk_error_enum_to_localised_text (code),
-			  gpk_error_enum_to_localised_message (code), details);
-out:
-	return;
-}
-
-/**
- * gpk_check_update_repo_signature_event_cb:
- **/
-static void
-gpk_check_update_repo_signature_event_cb (GpkHelperRepoSignature *helper_repo_signature, GtkResponseType type, const gchar *key_id, const gchar *package_id, GpkCheckUpdate *cupdate)
-{
+	PkControl *control = PK_CONTROL(object);
 	gboolean ret;
-	GError *error = NULL;
+	PkBitfield roles;
 
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (cupdate->priv->client_secondary, &error);
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
 	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
+		egg_warning ("details could not be retrieved: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	/* install signature */
-	ret = pk_client_install_signature (cupdate->priv->client_secondary, PK_SIGTYPE_ENUM_GPG, key_id, package_id, &error);
-	if (!ret) {
-		egg_warning ("cannot install signature: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	/* set state */
-	egg_debug ("repo sig cb");
-	gpk_check_update_query_updates (cupdate, TRUE);
+	/* get values */
+	g_object_get (control,
+		      "roles", &roles,
+		      "network-state", &state,
+		      NULL);
+
+	/* coldplug network state */
+	cupdate->priv->icon_inhibit_network_offline = (state == PK_NETWORK_ENUM_OFFLINE);
 out:
 	return;
 }
 
 /**
- * gpk_check_update_repo_signature_required_cb:
- **/
-static void
-gpk_check_update_repo_signature_required_cb (PkClient *client, const gchar *package_id, const gchar *repository_name,
-					      const gchar *key_url, const gchar *key_userid, const gchar *key_id,
-					      const gchar *key_fingerprint, const gchar *key_timestamp,
-					      PkSigTypeEnum type, GpkCheckUpdate *cupdate)
-{
-	/* use the helper */
-	gpk_helper_repo_signature_show (cupdate->priv->helper_repo_signature, package_id,
-					repository_name, key_url, key_userid, key_id, key_fingerprint, key_timestamp);
-}
-
-/**
- * gpk_check_update_primary_requeue:
- **/
-static gboolean
-gpk_check_update_primary_requeue (GpkCheckUpdate *cupdate)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	/* retry new action */
-	ret = pk_client_requeue (cupdate->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("Failed to requeue: %s", error->message);
-		g_error_free (error);
-	}
-	return ret;
-}
-
-/**
- * gpk_check_update_finished_notify:
- **/
-static void
-gpk_check_update_finished_notify (GpkCheckUpdate *cupdate, PkClient *client)
-{
-	gboolean ret;
-	GError *error = NULL;
-	NotifyNotification *notification;
-	PkRestartEnum restart;
-	guint i;
-	guint length;
-	PkPackageList *list;
-	const PkPackageObj *obj;
-	GString *message_text;
-	guint skipped_number = 0;
-	const gchar *message;
-
-	/* check we got some packages */
-	list = pk_client_get_package_list (client);
-	length = pk_package_list_get_size (list);
-	egg_debug ("length=%i", length);
-	if (length == 0) {
-		egg_debug ("no updates");
-		return;
-	}
-
-	message_text = g_string_new ("");
-
-	/* find any we skipped */
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		egg_debug ("%s, %s, %s", pk_info_enum_to_text (obj->info),
-			  obj->id->name, obj->summary);
-		if (obj->info == PK_INFO_ENUM_BLOCKED) {
-			skipped_number++;
-			g_string_append_printf (message_text, "<b>%s</b> - %s\n",
-						obj->id->name, obj->summary);
-		}
-	}
-	g_object_unref (list);
-
-	/* notify the user if there were skipped entries */
-	if (skipped_number > 0) {
-		/* TRANSLATORS: we did the update, but some updates were skipped and not applied */
-		message = ngettext ("One package was skipped:",
-				    "Some packages were skipped:", skipped_number);
-		g_string_prepend (message_text, message);
-		g_string_append_c (message_text, '\n');
-	}
-
-	/* add a message that we need to restart */
-	restart = pk_client_get_require_restart (client);
-	if (restart != PK_RESTART_ENUM_NONE) {
-		message = gpk_restart_enum_to_localised_text (restart);
-
-		/* add a gap if we are putting both */
-		if (skipped_number > 0)
-			g_string_append (message_text, "\n");
-
-		g_string_append (message_text, message);
-		g_string_append_c (message_text, '\n');
-	}
-
-	/* trim off extra newlines */
-	if (message_text->len != 0)
-		g_string_set_size (message_text, message_text->len-1);
-
-	/* do we do the notification? */
-	ret = gconf_client_get_bool (cupdate->priv->gconf_client, GPK_CONF_NOTIFY_UPDATE_COMPLETE, NULL);
-	if (!ret) {
-		egg_debug ("ignoring due to GConf");
-		return;
-	}
-
-	/* TRANSLATORS: title: system update completed all okay */
-	notification = notify_notification_new_with_status_icon (_("The system update has completed"),
-								 message_text->str, "help-browser",
-								 cupdate->priv->status_icon);
-	notify_notification_set_timeout (notification, 15000);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-	if (restart == PK_RESTART_ENUM_SYSTEM) {
-		notify_notification_add_action (notification, "restart",
-						/* TRANSLATORS: restart computer as system packages need update */
-						_("Restart computer now"), gpk_check_update_libnotify_cb, cupdate, NULL);
-//		notify_notification_add_action (notification, "do-not-show-complete-restart",
-//						/* TRANSLATORS: don't show this option again (for restart) */
-//						_("Do not show this again"), gpk_check_update_libnotify_cb, cupdate, NULL);
-	} else {
-		notify_notification_add_action (notification, "do-not-show-complete",
-						/* TRANSLATORS: don't show this option again (when finished)  */
-						_("Do not show this again"), gpk_check_update_libnotify_cb, cupdate, NULL);
-	}
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-	g_string_free (message_text, TRUE);
-}
-
-/**
- * gpk_check_update_finished_cb:
- **/
-static void
-gpk_check_update_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkCheckUpdate *cupdate)
-{
-	PkRoleEnum role;
-	PkPackageList *list;
-	PkObjList *array;
-
-	pk_client_get_role (client, &role, NULL, NULL);
-	egg_debug ("role: %s, exit: %s", pk_role_enum_to_text (role), pk_exit_enum_to_text (exit_enum));
-
-	/* need to handle retry with only_trusted=FALSE */
-	if (client == cupdate->priv->client_primary &&
-	    exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) {
-		egg_debug ("need to handle untrusted");
-		pk_client_set_only_trusted (client, FALSE);
-		gpk_check_update_primary_requeue (cupdate);
-		return;
-	}
-
-	/* we've just agreed to auth */
-	if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE) {
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS)
-			gpk_check_update_primary_requeue (cupdate);
-	}
-
-	/* get-updates */
-	if (role == PK_ROLE_ENUM_GET_UPDATES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		list = pk_client_get_package_list (client);
-		gpk_check_update_process_updates (cupdate, list, TRUE);
-		g_object_unref (list);
-	}
-
-	/* get-upgrades */
-	if (role == PK_ROLE_ENUM_GET_DISTRO_UPGRADES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-#if PK_CHECK_VERSION(0,5,0)
-		array = pk_client_get_distro_upgrade_list (client);
-#else
-		array = pk_client_get_cached_objects (client); /* removed in 0.5.x */
-#endif
-		gpk_check_update_process_distro_upgrades (cupdate, array);
-		g_object_unref (array);
-	}
-
-	/* refresh-cache */
-	if (role == PK_ROLE_ENUM_REFRESH_CACHE &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		egg_debug ("finished refresh cb");
-		gpk_check_update_query_updates (cupdate, TRUE);
-	}
-
-	/* updates */
-	if ((role == PK_ROLE_ENUM_UPDATE_PACKAGES ||
-	     role == PK_ROLE_ENUM_UPDATE_SYSTEM) &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-
-		/* play the sound, using sounds from the naming spec */
-		ca_context_play (ca_gtk_context_get (), 0,
-				 /* TODO: add a new sound to the spec */
-				 CA_PROP_EVENT_ID, "complete-download",
-				 /* TRANSLATORS: this is the application name for libcanberra */
-				 CA_PROP_APPLICATION_NAME, _("GNOME PackageKit Update Icon"),
-				 /* TRANSLATORS: this is the sound description */
-				 CA_PROP_EVENT_DESCRIPTION, _("Updated successfully"), NULL);
-
-		gpk_check_update_finished_notify (cupdate, client);
-		cupdate->priv->number_updates_critical_last_shown = 0;
-	}
-}
-
-/**
  * gpk_check_update_init:
  * @cupdate: This class instance
  **/
@@ -1529,16 +1435,18 @@ static void
 gpk_check_update_init (GpkCheckUpdate *cupdate)
 {
 	gboolean ret;
-	PkNetworkEnum state;
+	PkBitfield roles;
+	gchar **tids;
 
 	cupdate->priv = GPK_CHECK_UPDATE_GET_PRIVATE (cupdate);
 
 	cupdate->priv->updates_changed_id = 0;
 	cupdate->priv->notification_updates_available = NULL;
-	cupdate->priv->important_updates_array = NULL;
+	cupdate->priv->important_updates_array = g_ptr_array_new_with_free_func (g_free);
 	cupdate->priv->icon_name = NULL;
 	cupdate->priv->number_updates_critical_last_shown = 0;
 	cupdate->priv->status_icon = gtk_status_icon_new ();
+	cupdate->priv->cancellable = g_cancellable_new ();
 
 	/* preload all the common GConf keys */
 	cupdate->priv->gconf_client = gconf_client_get_default ();
@@ -1571,47 +1479,34 @@ gpk_check_update_init (GpkCheckUpdate *cupdate)
 			  G_CALLBACK (gpk_cupdate_connection_changed_cb), cupdate);
 
 	/* use an asynchronous query object */
-	cupdate->priv->client_primary = pk_client_new ();
-	pk_client_set_use_buffer (cupdate->priv->client_primary, TRUE, NULL);
-	g_signal_connect (cupdate->priv->client_primary, "finished",
-			  G_CALLBACK (gpk_check_update_finished_cb), cupdate);
-	g_signal_connect (cupdate->priv->client_primary, "error-code",
-			  G_CALLBACK (gpk_check_update_error_code_cb), cupdate);
-	g_signal_connect (cupdate->priv->client_primary, "repo-signature-required",
-			  G_CALLBACK (gpk_check_update_repo_signature_required_cb), cupdate);
-
-	/* this is for the auth callback */
-	cupdate->priv->client_secondary = pk_client_new ();
-	g_signal_connect (cupdate->priv->client_secondary, "error-code",
-			  G_CALLBACK (gpk_check_update_error_code_cb), cupdate);
-	g_signal_connect (cupdate->priv->client_secondary, "finished",
-			  G_CALLBACK (gpk_check_update_finished_cb), cupdate);
-
-	/* helpers */
-	cupdate->priv->helper_repo_signature = gpk_helper_repo_signature_new ();
-	g_signal_connect (cupdate->priv->helper_repo_signature, "event", G_CALLBACK (gpk_check_update_repo_signature_event_cb), cupdate);
+	cupdate->priv->task = PK_TASK(pk_task_new ());
+	g_object_set (cupdate->priv->task,
+		      "background", TRUE,
+		      NULL);
 
 	cupdate->priv->control = pk_control_new ();
 	g_signal_connect (cupdate->priv->control, "updates-changed",
 			  G_CALLBACK (gpk_check_update_updates_changed_cb), cupdate);
+	g_signal_connect (cupdate->priv->control, "transaction-list-changed",
+			  G_CALLBACK (gpk_check_update_transaction_list_changed_cb), cupdate);
 	g_signal_connect (cupdate->priv->control, "restart-schedule",
 			  G_CALLBACK (gpk_check_update_restart_schedule_cb), cupdate);
-	g_signal_connect (cupdate->priv->control, "network-state-changed",
-			  G_CALLBACK (gpk_check_update_network_status_changed_cb), cupdate);
+	g_signal_connect (cupdate->priv->control, "notify::network-state",
+			  G_CALLBACK (gpk_check_update_notify_network_status_cb), cupdate);
 
 	/* we need the task list so we can hide the update icon when we are doing the update */
-	cupdate->priv->tlist = pk_task_list_new ();
-	g_signal_connect (cupdate->priv->tlist, "changed",
-			  G_CALLBACK (gpk_check_update_task_list_changed_cb), cupdate);
+	cupdate->priv->tlist = pk_transaction_list_new ();
 
+	tids = pk_transaction_list_get_ids (cupdate->priv->tlist);
+	roles = gpk_check_update_get_active_roles (cupdate, tids);
+	g_strfreev (tids);
 	/* coldplug update in progress */
 	cupdate->priv->icon_inhibit_update_in_progress =
-		(pk_task_list_contains_role (cupdate->priv->tlist, PK_ROLE_ENUM_UPDATE_SYSTEM) ||
-		 pk_task_list_contains_role (cupdate->priv->tlist, PK_ROLE_ENUM_UPDATE_PACKAGES));
+		(pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_SYSTEM) ||
+		 pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_PACKAGES));
 
-	/* coldplug network state */
-	state = pk_control_get_network_state (cupdate->priv->control, NULL);
-	cupdate->priv->icon_inhibit_network_offline = (state == PK_NETWORK_ENUM_OFFLINE);
+	/* get properties */
+	pk_control_get_properties_async (cupdate->priv->control, cupdate->priv->cancellable, (GAsyncReadyCallback) gpk_check_update_get_properties_cb, cupdate);
 
 	/* coldplug update viewer connected */
 	ret = egg_dbus_monitor_is_connected (cupdate->priv->dbus_monitor_viewer);
@@ -1638,14 +1533,10 @@ gpk_check_update_finalize (GObject *object)
 	g_object_unref (cupdate->priv->arefresh);
 	g_object_unref (cupdate->priv->gconf_client);
 	g_object_unref (cupdate->priv->control);
-	g_object_unref (cupdate->priv->client_primary);
-	g_object_unref (cupdate->priv->client_secondary);
+	g_object_unref (cupdate->priv->task);
 	g_object_unref (cupdate->priv->dbus_monitor_viewer);
-	g_object_unref (cupdate->priv->helper_repo_signature);
-	if (cupdate->priv->important_updates_array != NULL) {
-		g_ptr_array_foreach (cupdate->priv->important_updates_array, (GFunc) g_free, NULL);
-		g_ptr_array_free (cupdate->priv->important_updates_array, TRUE);
-	}
+	g_object_unref (cupdate->priv->cancellable);
+	g_ptr_array_unref (cupdate->priv->important_updates_array);
 	g_free (cupdate->priv->icon_name);
 	if (cupdate->priv->updates_changed_id > 0)
 		g_source_remove (cupdate->priv->updates_changed_id);
diff --git a/src/gpk-common.c b/src/gpk-common.c
index 2b88a8a..c713c6f 100644
--- a/src/gpk-common.c
+++ b/src/gpk-common.c
@@ -29,7 +29,7 @@
 #include <sys/types.h>
 #include <gtk/gtk.h>
 #include <dbus/dbus-glib.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <locale.h>
 
 #include "egg-debug.h"
@@ -50,31 +50,45 @@
 /* static, so local to process */
 static gboolean small_form_factor_mode = FALSE;
 
-#if (!PK_CHECK_VERSION(0,5,0))
+gchar **
+pk_package_array_to_strv (GPtrArray *array)
+{
+	const PkItemPackage *item;
+	gchar **results;
+	guint i;
+
+	results = g_new0 (gchar *, array->len+1);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		results[i] = g_strdup (item->package_id);
+	}
+	return results;
+}
+
 /**
- * gpk_error_code_is_need_untrusted:
- * @error_code: the transactions #PkErrorCodeEnum
+ * pk_strv_to_ptr_array:
+ * @array: the gchar** array of strings
  *
- * Return value: if the error code suggests to try with only_trusted %FALSE
+ * Form a GPtrArray array of strings.
+ * The data in the array is copied.
+ *
+ * Return value: the string array, or %NULL if invalid
  **/
-gboolean
-gpk_error_code_is_need_untrusted (PkErrorCodeEnum error_code)
+GPtrArray *
+pk_strv_to_ptr_array (gchar **array)
 {
-	gboolean ret = FALSE;
-	switch (error_code) {
-		case PK_ERROR_ENUM_GPG_FAILURE:
-		case PK_ERROR_ENUM_BAD_GPG_SIGNATURE:
-		case PK_ERROR_ENUM_MISSING_GPG_SIGNATURE:
-		case PK_ERROR_ENUM_CANNOT_INSTALL_REPO_UNSIGNED:
-		case PK_ERROR_ENUM_CANNOT_UPDATE_REPO_UNSIGNED:
-			ret = TRUE;
-			break;
-		default:
-			break;
-	}
-	return ret;
+	guint i;
+	guint length;
+	GPtrArray *parray;
+
+	g_return_val_if_fail (array != NULL, NULL);
+
+	parray = g_ptr_array_new ();
+	length = g_strv_length (array);
+	for (i=0; i<length; i++)
+		g_ptr_array_add (parray, g_strdup (array[i]));
+	return parray;
 }
-#endif
 
 /**
  * gtk_text_buffer_insert_markup:
@@ -200,15 +214,6 @@ gtk_text_buffer_insert_markup (GtkTextBuffer *buffer, GtkTextIter *iter, const g
 }
 
 /**
- * gpk_window_get_small_form_factor_mode:
- **/
-gboolean
-gpk_window_get_small_form_factor_mode (void)
-{
-	return small_form_factor_mode;
-}
-
-/**
  * gpk_window_set_size_request:
  **/
 gboolean
@@ -281,31 +286,39 @@ gpk_window_set_parent_xid (GtkWindow *window, guint32 xid)
  * Return value: "<b>GTK Toolkit</b>\ngtk2-2.12.2 (i386)"
  **/
 gchar *
-gpk_package_id_format_twoline (const PkPackageId *id, const gchar *summary)
+gpk_package_id_format_twoline (const gchar *package_id, const gchar *summary)
 {
 	gchar *summary_safe;
-	gchar *text;
+	gchar *text = NULL;
 	GString *string;
+	gchar **split = NULL;
 
-	g_return_val_if_fail (id != NULL, NULL);
+	g_return_val_if_fail (package_id != NULL, NULL);
 
 	/* optional */
-	if (egg_strzero (summary)) {
-		string = g_string_new (id->name);
+	split = pk_package_id_split (package_id);
+	if (split == NULL) {
+		egg_warning ("could not parse %s", package_id);
+		goto out;
+	}
+	if (summary == NULL || summary[PK_PACKAGE_ID_NAME] == '\0') {
+		string = g_string_new (split[PK_PACKAGE_ID_NAME]);
 	} else {
 		string = g_string_new ("");
 		summary_safe = g_markup_escape_text (summary, -1);
-		g_string_append_printf (string, "<b>%s</b>\n%s", summary_safe, id->name);
+		g_string_append_printf (string, "<b>%s</b>\n%s", summary_safe, split[PK_PACKAGE_ID_NAME]);
 		g_free (summary_safe);
 	}
 
 	/* some backends don't provide this */
-	if (id->version != NULL)
-		g_string_append_printf (string, "-%s", id->version);
-	if (id->arch != NULL)
-		g_string_append_printf (string, " (%s)", id->arch);
+	if (split[PK_PACKAGE_ID_VERSION][0] != '\0')
+		g_string_append_printf (string, "-%s", split[PK_PACKAGE_ID_VERSION]);
+	if (split[PK_PACKAGE_ID_ARCH][0] != '\0')
+		g_string_append_printf (string, " (%s)", split[PK_PACKAGE_ID_ARCH]);
 
 	text = g_string_free (string, FALSE);
+out:
+	g_strfreev (split);
 	return text;
 }
 
@@ -315,64 +328,28 @@ gpk_package_id_format_twoline (const PkPackageId *id, const gchar *summary)
  * Return value: "<b>GTK Toolkit</b> (gtk2)"
  **/
 gchar *
-gpk_package_id_format_oneline (const PkPackageId *id, const gchar *summary)
+gpk_package_id_format_oneline (const gchar *package_id, const gchar *summary)
 {
 	gchar *summary_safe;
 	gchar *text;
+	gchar **split;
+
+	g_return_val_if_fail (package_id != NULL, NULL);
 
-	if (egg_strzero (summary)) {
+	split = pk_package_id_split (package_id);
+	if (summary == NULL || summary[0] == '\0') {
 		/* just have name */
-		text = g_strdup (id->name);
+		text = g_strdup (split[PK_PACKAGE_ID_NAME]);
 	} else {
 		summary_safe = g_markup_escape_text (summary, -1);
-		text = g_strdup_printf ("<b>%s</b> (%s)", summary_safe, id->name);
+		text = g_strdup_printf ("<b>%s</b> (%s)", summary_safe, split[PK_PACKAGE_ID_NAME]);
 		g_free (summary_safe);
 	}
+	g_strfreev (split);
 	return text;
 }
 
 /**
- * gpk_package_id_name_version:
- **/
-gchar *
-gpk_package_id_name_version (const PkPackageId *id)
-{
-	gchar *text;
-	GString *string;
-
-	if (id == NULL)
-		return g_strdup("");
-
-	string = g_string_new (id->name);
-	if (id->version != NULL)
-		g_string_append_printf (string, "-%s", id->version);
-	text = g_string_free (string, FALSE);
-
-	return text;
-}
-
-/**
- * pk_package_id_get_name:
- **/
-gchar *
-gpk_package_get_name (const gchar *package_id)
-{
-	gchar *package = NULL;
-	PkPackageId *id;
-
-	/* pk_package_id_new_from_string can't accept NULL */
-	if (package_id == NULL)
-		return NULL;
-	id = pk_package_id_new_from_string (package_id);
-	if (id == NULL)
-		package = g_strdup (package_id);
-	else
-		package = g_strdup (id->name);
-	pk_package_id_free (id);
-	return package;
-}
-
-/**
  * gpk_check_privileged_user
  **/
 gboolean
@@ -618,6 +595,52 @@ gpk_strv_join_locale (gchar **array)
 }
 
 /**
+ * gpk_package_entry_completion_get_names_from_file:
+ *
+ * Creates a tree model containing completions from the system package list
+ **/
+static GPtrArray *
+gpk_package_entry_completion_get_names_from_file (const gchar *filename)
+{
+	GPtrArray *array = NULL;
+	gboolean ret;
+	GError *error = NULL;
+	gchar *data = NULL;
+	gchar **lines = NULL;
+	guint i;
+	gchar **split;
+	PkItemPackage *item;
+
+	/* get data */
+	ret = g_file_get_contents (filename, &data, NULL, &error);
+	if (!ret) {
+		egg_warning ("failed to open package list: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* create array of PkItemPackage's */
+	array = g_ptr_array_new_with_free_func ((GDestroyNotify) pk_item_package_unref);
+
+	/* split */
+	lines = g_strsplit (data, "\n", -1);
+	for (i=0; lines[i] != NULL; i++) {
+		split = g_strsplit (lines[i], "\t", 3);
+		if (g_strv_length (split) != 3)
+			continue;
+		item = pk_item_package_new (pk_info_enum_from_text (split[PK_PACKAGE_ID_NAME]),
+					    split[PK_PACKAGE_ID_VERSION],
+					    split[PK_PACKAGE_ID_ARCH]);
+		g_ptr_array_add (array, item);
+		g_strfreev (split);
+	}
+out:
+	g_free (data);
+	g_strfreev (lines);
+	return array;
+}
+
+/**
  * gpk_package_entry_completion_model_new:
  *
  * Creates a tree model containing completions from the system package list
@@ -625,43 +648,43 @@ gpk_strv_join_locale (gchar **array)
 static GtkTreeModel *
 gpk_package_entry_completion_model_new (void)
 {
-	PkPackageList *list;
+	GPtrArray *list;
 	guint i;
-	guint length;
-	gboolean ret;
-	const PkPackageObj *obj;
+	const PkItemPackage *item;
 	GHashTable *hash;
 	gpointer data;
 	GtkListStore *store;
 	GtkTreeIter iter;
+	gchar **split;
 
 	store = gtk_list_store_new (1, G_TYPE_STRING);
 	hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-	list = pk_package_list_new ();
-	ret = pk_obj_list_from_file (PK_OBJ_LIST(list), PK_SYSTEM_PACKAGE_LIST_FILENAME);
-	if (!ret) {
+	list = gpk_package_entry_completion_get_names_from_file (PK_SYSTEM_PACKAGE_LIST_FILENAME);
+	if (list == NULL) {
 		egg_warning ("no package list, try refreshing");
 		return NULL;
 	}
 
-	length = pk_package_list_get_size (list);
-	egg_debug ("loading %i autocomplete items", length);
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		if (obj == NULL || obj->id == NULL || obj->id->name == NULL) {
-			egg_warning ("obj invalid!");
+	egg_debug ("loading %i autocomplete items", list->len);
+	for (i=0; i<list->len; i++) {
+		item = g_ptr_array_index (list, i);
+		if (item == NULL || item->package_id == NULL) {
+			egg_warning ("item invalid!");
 			break;
 		}
-		data = g_hash_table_lookup (hash, (gpointer) obj->id->name);
+
+		split = pk_package_id_split (item->package_id);
+		data = g_hash_table_lookup (hash, (gpointer) split[PK_PACKAGE_ID_NAME]);
 		if (data == NULL) {
 			/* append just the name */
-			g_hash_table_insert (hash, g_strdup (obj->id->name), GINT_TO_POINTER (1));
+			g_hash_table_insert (hash, g_strdup (split[PK_PACKAGE_ID_NAME]), GINT_TO_POINTER (1));
 			gtk_list_store_append (store, &iter);
-			gtk_list_store_set (store, &iter, 0, obj->id->name, -1);
+			gtk_list_store_set (store, &iter, 0, split[PK_PACKAGE_ID_NAME], -1);
 		}
+		g_strfreev (split);
 	}
 	g_hash_table_unref (hash);
-	g_object_unref (list);
+	g_ptr_array_unref (list);
 
 	return GTK_TREE_MODEL (store);
 }
@@ -735,7 +758,6 @@ void
 gpk_common_test (gpointer data)
 {
 	gchar *text;
-	PkPackageId *id;
 	EggTest *test = (EggTest *) data;
 
 	if (!egg_test_start (test, "GpkCommon"))
@@ -845,38 +867,8 @@ gpk_common_test (gpointer data)
 	/************************************************************
 	 ****************     package name text        **************
 	 ************************************************************/
-	egg_test_title (test, "get name null");
-	text = gpk_package_get_name (NULL);
-	if (text == NULL)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, "failed, got %s", text);
-
-	/************************************************************/
-	egg_test_title (test, "get name not id");
-	text = gpk_package_get_name ("ania");
-	if (text != NULL && strcmp (text, "ania") == 0)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, "failed, got %s", text);
-	g_free (text);
-
-	/************************************************************/
-	egg_test_title (test, "get name just id");
-	text = gpk_package_get_name ("simon;1.0.0;i386;moo");
-	if (text != NULL && strcmp (text, "simon") == 0)
-		egg_test_success (test, NULL);
-	else
-		egg_test_failed (test, "failed, got %s", text);
-	g_free (text);
-
-	/************************************************************
-	 ****************     package name text        **************
-	 ************************************************************/
 	egg_test_title (test, "package id pretty valid package id, no summary");
-	id = pk_package_id_new_from_string ("simon;0.0.1;i386;data");
-	text = gpk_package_id_format_twoline (id, NULL);
-	pk_package_id_free (id);
+	text = gpk_package_id_format_twoline ("simon;0.0.1;i386;data", NULL);
 	if (text != NULL && strcmp (text, "simon-0.0.1 (i386)") == 0)
 		egg_test_success (test, NULL);
 	else
@@ -885,9 +877,7 @@ gpk_common_test (gpointer data)
 
 	/************************************************************/
 	egg_test_title (test, "package id pretty valid package id, no summary 2");
-	id = pk_package_id_new_from_string ("simon;0.0.1;;data");
-	text = gpk_package_id_format_twoline (id, NULL);
-	pk_package_id_free (id);
+	text = gpk_package_id_format_twoline ("simon;0.0.1;;data", NULL);
 	if (text != NULL && strcmp (text, "simon-0.0.1") == 0)
 		egg_test_success (test, NULL);
 	else
@@ -896,9 +886,7 @@ gpk_common_test (gpointer data)
 
 	/************************************************************/
 	egg_test_title (test, "package id pretty valid package id, no summary 3");
-	id = pk_package_id_new_from_string ("simon;;;data");
-	text = gpk_package_id_format_twoline (id, NULL);
-	pk_package_id_free (id);
+	text = gpk_package_id_format_twoline ("simon;;;data", NULL);
 	if (text != NULL && strcmp (text, "simon") == 0)
 		egg_test_success (test, NULL);
 	else
@@ -907,9 +895,7 @@ gpk_common_test (gpointer data)
 
 	/************************************************************/
 	egg_test_title (test, "package id pretty valid package id, no summary 4");
-	id = pk_package_id_new_from_string ("simon;0.0.1;;data");
-	text = gpk_package_id_format_twoline (id, "dude");
-	pk_package_id_free (id);
+	text = gpk_package_id_format_twoline ("simon;0.0.1;;data", "dude");
 	if (text != NULL && strcmp (text, "<b>dude</b>\nsimon-0.0.1") == 0)
 		egg_test_success (test, NULL);
 	else
diff --git a/src/gpk-common.h b/src/gpk-common.h
index adfd1ec..e6a6305 100644
--- a/src/gpk-common.h
+++ b/src/gpk-common.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "gpk-animated-icon.h"
 #include "gpk-enum.h"
@@ -94,13 +94,10 @@ void		 gpk_common_test			(gpointer	 data);
 void		 gtk_text_buffer_insert_markup		(GtkTextBuffer	*buffer,
 							 GtkTextIter	*iter,
 							 const gchar	*markup);
-gchar		*gpk_package_get_name			(const gchar	*package_id);
-gchar		*gpk_package_id_format_twoline		(const PkPackageId *id,
+gchar		*gpk_package_id_format_twoline		(const gchar 	*package_id,
 							 const gchar	*summary);
-gchar		*gpk_package_id_format_oneline		(const PkPackageId *id,
+gchar		*gpk_package_id_format_oneline		(const gchar 	*package_id,
 							 const gchar	*summary);
-gchar		*gpk_package_id_name_version		(const PkPackageId *id);
-
 gchar		*gpk_time_to_localised_string		(guint		 time_secs);
 gchar		*gpk_time_to_imprecise_string		(guint		 time_secs);
 gboolean	 gpk_check_privileged_user		(const gchar	*application_name,
@@ -114,12 +111,11 @@ gboolean	 gpk_window_set_size_request		(GtkWindow	*window,
 							 guint		 width,
 							 guint		 height);
 gboolean	 gpk_ignore_session_error		(GError		*error);
-gboolean	 gpk_window_get_small_form_factor_mode 	(void);
 gboolean	 gpk_window_set_parent_xid		(GtkWindow	*window,
 							 guint32	 xid);
-#if (!PK_CHECK_VERSION(0,5,0))
-gboolean	 gpk_error_code_is_need_untrusted	(PkErrorCodeEnum error_code);
-#endif
+GPtrArray	*pk_strv_to_ptr_array			(gchar		**array)
+							 G_GNUC_WARN_UNUSED_RESULT;
+gchar		**pk_package_array_to_strv		(GPtrArray	*array);
 
 G_END_DECLS
 
diff --git a/src/gpk-dbus-task.c b/src/gpk-dbus-task.c
index 7f86fa5..7d6b0c8 100644
--- a/src/gpk-dbus-task.c
+++ b/src/gpk-dbus-task.c
@@ -32,48 +32,32 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <libnotify/notify.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
 
+#include "gpk-common.h"
 #include "gpk-dbus.h"
 #include "gpk-dbus-task.h"
-#include "gpk-modal-dialog.h"
-#include "gpk-common.h"
-#include "gpk-gnome.h"
+#include "gpk-desktop.h"
+#include "gpk-dialog.h"
+#include "gpk-enum.h"
 #include "gpk-error.h"
+#include "gpk-gnome.h"
+#include "gpk-helper-chooser.h"
+#include "gpk-helper-run.h"
 #include "gpk-language.h"
-#include "gpk-dialog.h"
+#include "gpk-modal-dialog.h"
+#include "gpk-task.h"
 #include "gpk-vendor.h"
-#include "gpk-enum.h"
 #include "gpk-x11.h"
-#include "gpk-desktop.h"
-#include "gpk-helper-repo-signature.h"
-#include "gpk-helper-eula.h"
-#include "gpk-helper-run.h"
-#include "gpk-helper-untrusted.h"
-#include "gpk-helper-chooser.h"
 
 static void     gpk_dbus_task_finalize (GObject *object);
-static void	gpk_dbus_task_install_files (GpkDbusTask *task);
 
 #define GPK_DBUS_TASK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_DBUS_TASK, GpkDbusTaskPrivate))
 #define GPK_DBUS_TASK_FINISHED_AUTOCLOSE_DELAY	10 /* seconds */
 
-typedef enum {
-	GPK_DBUS_TASK_ROLE_IS_INSTALLED,
-	GPK_DBUS_TASK_ROLE_SEARCH_FILE,
-	GPK_DBUS_TASK_ROLE_INSTALL_PACKAGE_FILES,
-	GPK_DBUS_TASK_ROLE_INSTALL_PROVIDE_FILES,
-	GPK_DBUS_TASK_ROLE_INSTALL_MIME_TYPES,
-	GPK_DBUS_TASK_ROLE_INSTALL_GSTREAMER_RESOURCES,
-	GPK_DBUS_TASK_ROLE_INSTALL_FONTCONFIG_RESOURCES,
-	GPK_DBUS_TASK_ROLE_INSTALL_PACKAGE_NAMES,
-	GPK_DBUS_TASK_ROLE_INSTALL_CATALOGS,
-	GPK_DBUS_TASK_ROLE_UNKNOWN
-} GpkDbusTaskRole;
-
 /**
  * GpkDbusTaskPrivate:
  *
@@ -83,8 +67,7 @@ struct _GpkDbusTaskPrivate
 {
 	GdkWindow		*parent_window;
 	GConfClient		*gconf_client;
-	PkClient		*client_primary;
-	PkClient		*client_secondary;
+	PkTask			*task;
 	PkDesktop		*desktop;
 	PkControl		*control;
 	PkExitEnum		 exit;
@@ -101,20 +84,15 @@ struct _GpkDbusTaskPrivate
 	guint			 timestamp;
 	gchar			*parent_title;
 	gchar			*parent_icon_name;
-	gchar			*error_details;
+	PkItemErrorCode		*cached_error_code;
 	gint			 timeout;
-	GpkHelperRepoSignature	*helper_repo_signature;
-	GpkHelperEula		*helper_eula;
 	GpkHelperRun		*helper_run;
-#if (!PK_CHECK_VERSION(0,5,0))
-	GpkHelperUntrusted	*helper_untrusted;
-#endif
 	GpkHelperChooser	*helper_chooser;
 	DBusGMethodInvocation	*context;
-	GpkDbusTaskRole		 role;
 	gchar			**package_ids;
 	gchar			**files;
-	PkErrorCodeEnum		 last_exit_code;
+	GCancellable		*cancellable;
+	PkCatalog		*catalog;
 };
 
 G_DEFINE_TYPE (GpkDbusTask, gpk_dbus_task, G_TYPE_OBJECT)
@@ -123,22 +101,22 @@ G_DEFINE_TYPE (GpkDbusTask, gpk_dbus_task, G_TYPE_OBJECT)
  * gpk_dbus_task_set_interaction:
  **/
 gboolean
-gpk_dbus_task_set_interaction (GpkDbusTask *task, PkBitfield interact)
+gpk_dbus_task_set_interaction (GpkDbusTask *dtask, PkBitfield interact)
 {
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
+	g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
 
-	task->priv->show_confirm_search = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_SEARCH);
-	task->priv->show_confirm_deps = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_DEPS);
-	task->priv->show_confirm_install = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_INSTALL);
-	task->priv->show_progress = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_PROGRESS);
-	task->priv->show_finished = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_FINISHED);
-	task->priv->show_warning = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_WARNING);
+	dtask->priv->show_confirm_search = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_SEARCH);
+	dtask->priv->show_confirm_deps = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_DEPS);
+	dtask->priv->show_confirm_install = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_INSTALL);
+	dtask->priv->show_progress = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_PROGRESS);
+	dtask->priv->show_finished = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_FINISHED);
+	dtask->priv->show_warning = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_WARNING);
 
 	/* debug */
 	egg_debug ("confirm_search:%i, confirm_deps:%i, confirm_install:%i, progress:%i, finished:%i, warning:%i",
-		   task->priv->show_confirm_search, task->priv->show_confirm_deps,
-		   task->priv->show_confirm_install, task->priv->show_progress,
-		   task->priv->show_finished, task->priv->show_warning);
+		   dtask->priv->show_confirm_search, dtask->priv->show_confirm_deps,
+		   dtask->priv->show_confirm_install, dtask->priv->show_progress,
+		   dtask->priv->show_finished, dtask->priv->show_warning);
 
 	return TRUE;
 }
@@ -147,24 +125,12 @@ gpk_dbus_task_set_interaction (GpkDbusTask *task, PkBitfield interact)
  * gpk_dbus_task_set_context:
  **/
 gboolean
-gpk_dbus_task_set_context (GpkDbusTask *task, DBusGMethodInvocation *context)
+gpk_dbus_task_set_context (GpkDbusTask *dtask, DBusGMethodInvocation *context)
 {
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
+	g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
 	g_return_val_if_fail (context != NULL, FALSE);
 
-	task->priv->context = context;
-	return TRUE;
-}
-
-/**
- * gpk_dbus_task_set_timeout:
- **/
-gboolean
-gpk_dbus_task_set_timeout (GpkDbusTask *task, gint timeout)
-{
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
-
-	task->priv->timeout = timeout;
+	dtask->priv->context = context;
 	return TRUE;
 }
 
@@ -172,15 +138,15 @@ gpk_dbus_task_set_timeout (GpkDbusTask *task, gint timeout)
  * gpk_dbus_task_set_xid:
  **/
 gboolean
-gpk_dbus_task_set_xid (GpkDbusTask *task, guint32 xid)
+gpk_dbus_task_set_xid (GpkDbusTask *dtask, guint32 xid)
 {
 	GdkDisplay *display;
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
+	g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
 
 	display = gdk_display_get_default ();
-	task->priv->parent_window = gdk_window_foreign_new_for_display (display, xid);
-	egg_debug ("parent_window=%p", task->priv->parent_window);
-	gpk_modal_dialog_set_parent (task->priv->dialog, task->priv->parent_window);
+	dtask->priv->parent_window = gdk_window_foreign_new_for_display (display, xid);
+	egg_debug ("parent_window=%p", dtask->priv->parent_window);
+	gpk_modal_dialog_set_parent (dtask->priv->dialog, dtask->priv->parent_window);
 	return TRUE;
 }
 
@@ -188,190 +154,48 @@ gpk_dbus_task_set_xid (GpkDbusTask *task, guint32 xid)
  * gpk_dbus_task_set_timestamp:
  **/
 gboolean
-gpk_dbus_task_set_timestamp (GpkDbusTask *task, guint32 timestamp)
+gpk_dbus_task_set_timestamp (GpkDbusTask *dtask, guint32 timestamp)
 {
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
-	task->priv->timestamp = timestamp;
+	g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+	dtask->priv->timestamp = timestamp;
 	return TRUE;
 }
 
-/**
- * gpk_dbus_task_repo_signature_event_cb:
- **/
-static void
-gpk_dbus_task_repo_signature_event_cb (GpkHelperRepoSignature *helper_repo_signature, GtkResponseType type, const gchar *key_id, const gchar *package_id, GpkDbusTask *task)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (task->priv->client_secondary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* install signature */
-	ret = pk_client_install_signature (task->priv->client_secondary, PK_SIGTYPE_ENUM_GPG, key_id, package_id, &error);
-	if (!ret) {
-		egg_warning ("cannot install signature: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return;
-}
-
-/**
- * gpk_dbus_task_eula_event_cb:
- **/
-static void
-gpk_dbus_task_eula_event_cb (GpkHelperEula *helper_eula, GtkResponseType type, const gchar *eula_id, GpkDbusTask *task)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	if (type != GTK_RESPONSE_YES) {
-		goto out;
-	}
-
-	/* reset client */
-	ret = pk_client_reset (task->priv->client_secondary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* install signature */
-	ret = pk_client_accept_eula (task->priv->client_secondary, eula_id, &error);
-	if (!ret) {
-		egg_warning ("cannot accept eula: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return;
-}
-
-/**
- * gpk_dbus_task_eula_cb:
- **/
-static void
-gpk_dbus_task_eula_required_cb (PkClient *client, const gchar *eula_id, const gchar *package_id,
-				    const gchar *vendor_name, const gchar *license_agreement, GpkDbusTask *task)
-{
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CUSTOM, pk_bitfield_value (GPK_MODAL_DIALOG_WIDGET_PROGRESS_BAR));
-	gpk_modal_dialog_set_title (task->priv->dialog, _("EULA required"));
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_SIG_CHECK);
-	gpk_modal_dialog_set_percentage (task->priv->dialog, 101);
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* use the helper */
-	gpk_helper_eula_show (task->priv->helper_eula, eula_id, package_id, vendor_name, license_agreement);
-}
-
-/**
- * gpk_dbus_task_repo_signature_required_cb:
- **/
-static void
-gpk_dbus_task_repo_signature_required_cb (PkClient *client, const gchar *package_id, const gchar *repository_name,
-					      const gchar *key_url, const gchar *key_userid, const gchar *key_id,
-					      const gchar *key_fingerprint, const gchar *key_timestamp,
-					      PkSigTypeEnum type, GpkDbusTask *task)
-{
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CUSTOM, pk_bitfield_value (GPK_MODAL_DIALOG_WIDGET_PROGRESS_BAR));
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Signature required"));
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_SIG_CHECK);
-	gpk_modal_dialog_set_percentage (task->priv->dialog, 101);
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* use the helper */
-	gpk_helper_repo_signature_show (task->priv->helper_repo_signature, package_id, repository_name, key_url, key_userid, key_id, key_fingerprint, key_timestamp);
-}
-
-static void gpk_dbus_task_install_package_files_internal (GpkDbusTask *task, gboolean trusted);
-
-#if (!PK_CHECK_VERSION(0,5,0))
-/**
- * gpk_dbus_task_untrusted_event_cb:
- **/
-static void
-gpk_dbus_task_untrusted_event_cb (GpkHelperUntrusted *helper_untrusted, GtkResponseType type, GpkDbusTask *task)
-{
-	GError *error = NULL;
-	const gchar *title;
-
-	if (type != GTK_RESPONSE_YES) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to download");
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-	title = _("Install untrusted");
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-
-	/* install trusted */
-	gpk_dbus_task_install_package_files_internal (task, FALSE);
-out:
-	if (error != NULL)
-		g_error_free (error);
-	return;
-}
-#endif
-
-static void gpk_dbus_task_install_package_ids_dep_check (GpkDbusTask *task);
+static void gpk_dbus_task_install_package_ids (GpkDbusTask *dtask);
 
 /**
  * gpk_dbus_task_chooser_event_cb:
  **/
 static void
-gpk_dbus_task_chooser_event_cb (GpkHelperChooser *helper_chooser, GtkResponseType type, const gchar *package_id, GpkDbusTask *task)
+gpk_dbus_task_chooser_event_cb (GpkHelperChooser *helper_chooser, GtkResponseType type, const gchar *package_id, GpkDbusTask *dtask)
 {
-	GError *error = NULL;
+	GError *error_dbus = NULL;
 
 	/* selected nothing */
 	if (type != GTK_RESPONSE_YES || package_id == NULL) {
 
 		/* failed */
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not choose anything to install");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not choose anything to install");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 
-		if (task->priv->show_warning) {
-			gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+		if (dtask->priv->show_warning) {
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
 			/* TRANSLATORS: we failed to install */
-			gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to install software"));
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install software"));
 			/* TRANSLATORS: we didn't select any applications that were returned */
-			gpk_modal_dialog_set_message (task->priv->dialog, _("No applications were chosen to be installed"));
-			gpk_modal_dialog_present (task->priv->dialog);
-			gpk_modal_dialog_run (task->priv->dialog);
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("No applications were chosen to be installed"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			gpk_modal_dialog_run (dtask->priv->dialog);
 		}
 		goto out;
 	}
 
 	/* install this specific package */
-	task->priv->package_ids = pk_package_ids_from_id (package_id);
+	dtask->priv->package_ids = pk_package_ids_from_id (package_id);
 
 	/* install these packages with deps */
-	gpk_dbus_task_install_package_ids_dep_check (task);
-
+	gpk_dbus_task_install_package_ids (dtask);
 out:
-	if (error != NULL)
-		g_error_free (error);
 	return;
 }
 
@@ -382,10 +206,17 @@ static void
 gpk_dbus_task_libnotify_cb (NotifyNotification *notification, gchar *action, gpointer data)
 {
 	GpkDbusTask *task = GPK_DBUS_TASK (data);
+	gchar *details;
 
+	if (task->priv->cached_error_code == NULL) {
+		egg_warning ("called show error with no error!");
+		return;
+	}
 	if (g_strcmp0 (action, "show-error-details") == 0) {
+		details = g_markup_escape_text (task->priv->cached_error_code->details, -1);
 		/* TRANSLATORS: detailed text about the error */
-		gpk_error_dialog (_("Error details"), _("Package Manager error details"), task->priv->error_details);
+		gpk_error_dialog (_("Error details"), _("Package Manager error details"), details);
+		g_free (details);
 	} else {
 		egg_warning ("unknown action id: %s", action);
 	}
@@ -395,18 +226,18 @@ gpk_dbus_task_libnotify_cb (NotifyNotification *notification, gchar *action, gpo
  * gpk_dbus_task_error_msg:
  **/
 static void
-gpk_dbus_task_error_msg (GpkDbusTask *task, const gchar *title, GError *error)
+gpk_dbus_task_error_msg (GpkDbusTask *dtask, const gchar *title, GError *error)
 {
 	GtkWindow *window;
 	/* TRANSLATORS: default fallback error -- this should never happen */
 	const gchar *message = _("Unknown error. Please refer to the detailed report and report in your distribution bugtracker.");
 	const gchar *details = NULL;
 
-	if (!task->priv->show_warning)
+	if (!dtask->priv->show_warning)
 		return;
 
 	/* setup UI */
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
 
 	/* print a proper error if we have it */
 	if (error != NULL) {
@@ -414,11 +245,11 @@ gpk_dbus_task_error_msg (GpkDbusTask *task, const gchar *title, GError *error)
 		    g_str_has_prefix (error->message, "org.freedesktop.packagekit.")) {
 			/* TRANSLATORS: failed authentication */
 			message = _("You don't have the necessary privileges to perform this action.");
-			gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-permissions");
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-permissions");
 		} else if (error->code == PK_CLIENT_ERROR_CANNOT_START_DAEMON) {
 			/* TRANSLATORS: could not start system service */
 			message = _("The packagekitd service could not be started.");
-			gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-no-service");
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-no-service");
 		} else if (error->code == PK_CLIENT_ERROR_INVALID_INPUT) {
 			/* TRANSLATORS: the user tried to query for something invalid */
 			message = _("The query is not valid.");
@@ -434,643 +265,191 @@ gpk_dbus_task_error_msg (GpkDbusTask *task, const gchar *title, GError *error)
 
 	/* it's a normal UI, not a backtrace so keep in the UI */
 	if (details == NULL) {
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_message (task->priv->dialog, message);
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-		gpk_modal_dialog_run (task->priv->dialog);
+		gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+		gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+		gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+		gpk_modal_dialog_run (dtask->priv->dialog);
 		return;
 	}
 
 	/* hide the main window */
-	window = gpk_modal_dialog_get_window (task->priv->dialog);
-	gpk_error_dialog_modal_with_time (window, title, message, details, task->priv->timestamp);
+	window = gpk_modal_dialog_get_window (dtask->priv->dialog);
+	gpk_error_dialog_modal_with_time (window, title, message, details, dtask->priv->timestamp);
 }
 
 /**
- * gpk_dbus_task_install_package_ids:
- * @task: a valid #GpkDbusTask instance
+ * gpk_dbus_task_handle_error:
  **/
 static void
-gpk_dbus_task_install_package_ids (GpkDbusTask *task)
+gpk_dbus_task_handle_error (GpkDbusTask *dtask, PkItemErrorCode *error_item)
 {
 	gboolean ret;
 	GError *error = NULL;
-	GError *error_local = NULL;
+	const gchar *title;
+	const gchar *message;
+	NotifyNotification *notification;
+	GtkWidget *widget;
 
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
-	/* TRANSLATORS: title: installing packages */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Installing packages"));
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
+	/* ignore some errors */
+	if (error_item->code == PK_ERROR_ENUM_NO_LICENSE_AGREEMENT ||
+	    error_item->code == PK_ERROR_ENUM_PROCESS_KILL ||
+	    error_item->code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+		egg_warning ("ignoring %s", pk_error_enum_to_text (error_item->code));
+	}
 
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this should never happen, low level failure */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client to perform action"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
+	egg_debug ("code was %s", pk_error_enum_to_text (error_item->code));
+
+	/* use a modal dialog if showing progress, else use libnotify */
+	title = gpk_error_enum_to_localised_text (error_item->code);
+	message = gpk_error_enum_to_localised_message (error_item->code);
+	if (dtask->priv->show_progress) {
+		widget = GTK_WIDGET (gpk_modal_dialog_get_window (dtask->priv->dialog));
+		gpk_error_dialog_modal (GTK_WINDOW (widget), title, message, error_item->details);
+		return;
 	}
 
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	/* save this globally */
+	if (dtask->priv->cached_error_code != NULL)
+		pk_item_error_code_unref (dtask->priv->cached_error_code);
+	dtask->priv->cached_error_code = pk_item_error_code_ref (error_item);
 
-#if PK_CHECK_VERSION(0,5,0)
-	ret = pk_client_install_packages (task->priv->client_primary, TRUE, task->priv->package_ids, &error_local);
-#else
-	ret = pk_client_install_packages (task->priv->client_primary, task->priv->package_ids, &error_local);
-#endif
+	/* do the bubble */
+	notification = notify_notification_new (title, message, "help-browser", NULL);
+	notify_notification_set_timeout (notification, 15000);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+	notify_notification_add_action (notification, "show-error-details",
+					/* TRANSLATORS: button: show details about the error */
+					_("Show details"), gpk_dbus_task_libnotify_cb, dtask, NULL);
+	ret = notify_notification_show (notification, &error);
 	if (!ret) {
-		/* TRANSLATORS: error: failed to install, detailed error follows */
-		gpk_dbus_task_error_msg (task, _("Failed to install package"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-out:
-	if (error != NULL)
+		egg_warning ("error: %s", error->message);
 		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	}
 }
 
 /**
- * gpk_dbus_task_install_package_ids_dep_check:
- * @task: a valid #GpkDbusTask instance
+ * gpk_dbus_task_install_packages_cb:
  **/
 static void
-gpk_dbus_task_install_package_ids_dep_check (GpkDbusTask *task)
+gpk_dbus_task_install_packages_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
 {
-	gboolean ret;
 	GError *error = NULL;
-	GError *error_local = NULL;
-
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-	g_return_if_fail (task->priv->package_ids != NULL);
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	PkItemErrorCode *error_item = NULL;
 
-	/* are we dumb and can't check for depends? */
-#if PK_CHECK_VERSION(0,5,2)
-	if (!pk_bitfield_contain (task->priv->roles, PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES)) {
-#else
-	if (!pk_bitfield_contain (task->priv->roles, PK_ROLE_ENUM_GET_DEPENDS)) {
-#endif
-		egg_warning ("skipping depends check");
-		gpk_dbus_task_install_package_ids (task);
-		goto out;
-	}
-
-	/* have we previously said we don't want to be shown the confirmation */
-	ret = gconf_client_get_bool (task->priv->gconf_client, GPK_CONF_SHOW_DEPENDS, NULL);
-	if (!ret) {
-		egg_warning ("we've said we don't want the dep dialog");
-		gpk_dbus_task_install_package_ids (task);
-		goto out;
-	}
-
-	/* optional */
-	if (!task->priv->show_confirm_deps) {
-		egg_warning ("skip confirm as not allowed to interact with user");
-		gpk_dbus_task_install_package_ids (task);
-		goto out;
-	}
-
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
-	/* TRANSLATORS: finding a list of packages that we would also need to download */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Finding other packages we require"));
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-finding-depends");
-
-	/* setup the UI */
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this is an internal error, and should not be seen */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		/* TRANSLATORS: error: failed to install, detailed error follows */
+		gpk_dbus_task_error_msg (dtask, _("Failed to install package"), error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
-
-	/* find out if this would drag in other packages */
-#if PK_CHECK_VERSION(0,5,2)
-	ret = pk_client_simulate_install_packages (task->priv->client_primary, task->priv->package_ids, &error_local);
-#else
-	ret = pk_client_get_depends (task->priv->client_primary, pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED), task->priv->package_ids, TRUE, &error_local);
-#endif
-	if (!ret) {
-		/* TRANSLATORS: error: could not get the extra package list when installing a package */
-		gpk_dbus_task_error_msg (task, _("Could not work out what packages would be also installed"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to install package: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		gpk_dbus_task_handle_error (dtask, error_item);
 		goto out;
 	}
-
-	/* wait for async reply */
-
-out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
-}
-
-/**
- * gpk_dbus_task_error_from_exit_enum:
- **/
-static GError *
-gpk_dbus_task_error_from_exit_enum (PkExitEnum exit)
-{
-	GError *error = NULL;
-
-	/* trivial case */
-	if (exit == PK_EXIT_ENUM_SUCCESS)
-		goto out;
-
-	/* set the correct error type */
-	if (exit == PK_EXIT_ENUM_FAILED)
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "Unspecified failure");
-	else if (exit == PK_EXIT_ENUM_CANCELLED)
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "Transaction was cancelled");
-	else if (exit == PK_EXIT_ENUM_KEY_REQUIRED)
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "A key was required but not provided");
-	else if (exit == PK_EXIT_ENUM_EULA_REQUIRED)
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "A EULA was not agreed to");
-	else if (exit == PK_EXIT_ENUM_KILLED)
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "The transaction was killed");
-	else
-		egg_error ("unknown exit code");
 out:
-	return error;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_dbus_task_install_package_ids_dep_check_idle_cb:
+ * gpk_dbus_task_install_package_ids:
+ * @task: a valid #GpkDbusTask instance
  **/
-static gboolean
-gpk_dbus_task_install_package_ids_dep_check_idle_cb (GpkDbusTask *task)
+static void
+gpk_dbus_task_install_package_ids (GpkDbusTask *dtask)
 {
-	egg_warning ("idle add install package ids dep check");
-	gpk_dbus_task_install_package_ids_dep_check (task);
-	return FALSE;
-}
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+	/* TRANSLATORS: title: installing packages */
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Installing packages"));
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present (dtask->priv->dialog);
 
-/**
- * gpk_dbus_task_install_package_ids_idle_cb:
- **/
-static gboolean
-gpk_dbus_task_install_package_ids_idle_cb (GpkDbusTask *task)
-{
-	egg_warning ("idle add install package ids");
-	gpk_dbus_task_install_package_ids (task);
-	return FALSE;
+	/* install async */
+	pk_task_install_packages_async (dtask->priv->task, dtask->priv->package_ids, NULL, NULL, NULL,
+					(GAsyncReadyCallback) gpk_dbus_task_install_packages_cb, dtask);
 }
 
-/**
- * gpk_dbus_task_install_files_idle_cb:
- **/
-static gboolean
-gpk_dbus_task_install_files_idle_cb (GpkDbusTask *task)
-{
-	egg_warning ("idle add install files");
-	gpk_dbus_task_install_files (task);
-	return FALSE;
-}
+#if 0
 
 /**
  * gpk_dbus_task_finished_cb:
  **/
 static void
-gpk_dbus_task_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkDbusTask *task)
+gpk_dbus_task_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkDbusTask *dtask)
 {
 	PkRoleEnum role = PK_ROLE_ENUM_UNKNOWN;
 	gboolean ret;
 	guint len;
 	guint i;
 	const gchar *name = NULL;
-	GError *error = NULL;
+	GError *error_dbus = NULL;
 	GError *error_local = NULL;
-	PkPackageList *list = NULL;
-	const PkPackageObj *obj;
+	GPtrArray *array = NULL;
+	const PkItemPackage *item;
 	gboolean already_installed = FALSE;
 	gchar *title = NULL;
 	gchar *message = NULL;
 	gchar *text = NULL;
-	PkPackageId *id = NULL;
+	gchar *id = NULL;
 	gchar *info_url = NULL;
 	GtkResponseType button;
 	gchar *package_id = NULL;
 
-	/* get role */
-	pk_client_get_role (client, &role, NULL, NULL);
-	egg_debug ("role: %s, exit: %s", pk_role_enum_to_text (role), pk_exit_enum_to_text (exit_enum));
-
-	/* stop spinning */
-	gpk_modal_dialog_set_percentage (task->priv->dialog, 100);
-
-	/* we failed because we're handling the auth, just ignore */
-	if (client == task->priv->client_primary &&
-	    (exit_enum == PK_EXIT_ENUM_KEY_REQUIRED ||
-	     exit_enum == PK_EXIT_ENUM_EULA_REQUIRED)) {
-		egg_debug ("ignoring primary sig-required or eula");
-		goto out;
-	}
-
-	/* need to handle retry with only_trusted=FALSE */
-	if (client == task->priv->client_primary &&
-	    exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) {
-		egg_debug ("need to handle untrusted");
-		pk_client_set_only_trusted (client, FALSE);
-
-		/* try again */
-		ret = pk_client_requeue (task->priv->client_primary, &error_local);
-		if (!ret) {
-			egg_warning ("Failed to requeue: %s", error_local->message);
-			error = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR, "cannot requeue: %s", error_local->message);
-			dbus_g_method_return_error (task->priv->context, error);
-		}
-		goto out;
-	}
-
-	/* EULA or GPG key auth done */
-	if (client == task->priv->client_secondary &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-
-		/* try again */
-		ret = pk_client_requeue (task->priv->client_primary, &error_local);
-		if (!ret) {
-			egg_warning ("Failed to requeue: %s", error_local->message);
-			error = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR, "cannot requeue: %s", error_local->message);
-			dbus_g_method_return_error (task->priv->context, error);
-		}
-		goto out;
-	}
-
 	if (exit_enum != PK_EXIT_ENUM_SUCCESS) {
 
-#if (!PK_CHECK_VERSION(0,5,0))
-		/* we failed because of failed exit code */
-		ret = pk_error_code_is_need_untrusted (task->priv->last_exit_code);
-		if (ret) {
-			egg_debug ("showing untrusted ui");
-			gpk_helper_untrusted_show (task->priv->helper_untrusted, task->priv->last_exit_code);
-			goto out;
-		}
-#endif
-
 		/* show finished? */
-		if (!task->priv->show_finished)
-			gpk_modal_dialog_close (task->priv->dialog);
+		if (!dtask->priv->show_finished)
+			gpk_modal_dialog_close (dtask->priv->dialog);
 
 		/* fail the transaction and set the correct error */
 		error = gpk_dbus_task_error_from_exit_enum (exit_enum);
-		dbus_g_method_return_error (task->priv->context, error);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-	/* from InstallMimeTypes */
-	if (task->priv->role == GPK_DBUS_TASK_ROLE_INSTALL_MIME_TYPES &&
-	    role == PK_ROLE_ENUM_WHAT_PROVIDES) {
-
-		/* found nothing? */
-		list = pk_client_get_package_list (task->priv->client_primary);
-		len = pk_package_list_get_size (list);
-		if (len == 0) {
-			if (task->priv->show_warning) {
-				info_url = gpk_vendor_get_not_found_url (task->priv->vendor, GPK_VENDOR_URL_TYPE_MIME);
-				/* only show the "more info" button if there is a valid link */
-				if (info_url != NULL)
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
-				else
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				/* TRANSLATORS: title */
-				gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to find software"));
-				/* TRANSLATORS: nothing found in the software sources that helps */
-				gpk_modal_dialog_set_message (task->priv->dialog, _("No new applications can be found to handle this type of file"));
-				gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-package-not-found");
-				/* TRANSLATORS: button: show the user a button to get more help finding stuff */
-				gpk_modal_dialog_set_action (task->priv->dialog, _("More information"));
-				gpk_modal_dialog_present (task->priv->dialog);
-				button = gpk_modal_dialog_run (task->priv->dialog);
-				if (button == GTK_RESPONSE_OK)
-					gpk_gnome_open (info_url);
-				g_free (info_url);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "nothing was found to handle mime type");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-
-		/* populate a chooser */
-		gpk_helper_chooser_show (task->priv->helper_chooser, list);
-		goto out;
-	}
-
-	/* from InstallProvideFiles */
-	if (task->priv->role == GPK_DBUS_TASK_ROLE_INSTALL_PROVIDE_FILES &&
-	    role == PK_ROLE_ENUM_SEARCH_FILE) {
-		/* found nothing? */
-		list = pk_client_get_package_list (task->priv->client_primary);
-		len = pk_package_list_get_size (list);
-		if (len == 0) {
-			if (task->priv->show_warning) {
-				info_url = gpk_vendor_get_not_found_url (task->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
-				/* only show the "more info" button if there is a valid link */
-				if (info_url != NULL)
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
-				else
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				/* TRANSLATORS: failed to fild the package for thefile */
-				gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to find package"));
-				/* TRANSLATORS: nothing found */
-				gpk_modal_dialog_set_message (task->priv->dialog, _("The file could not be found in any packages"));
-				gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-package-not-found");
-				/* TRANSLATORS: button: show the user a button to get more help finding stuff */
-				gpk_modal_dialog_set_action (task->priv->dialog, _("More information"));
-				gpk_modal_dialog_present (task->priv->dialog);
-				button = gpk_modal_dialog_run (task->priv->dialog);
-				if (button == GTK_RESPONSE_OK)
-					gpk_gnome_open (info_url);
-				g_free (info_url);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "no files found");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-
-		/* see what we've got already */
-		for (i=0; i<len; i++) {
-			obj = pk_package_list_get_obj (list, i);
-			if (obj->info == PK_INFO_ENUM_INSTALLED) {
-				already_installed = TRUE;
-				id = obj->id;
-			} else if (obj->info == PK_INFO_ENUM_AVAILABLE) {
-				egg_debug ("package '%s' resolved to:", obj->id->name);
-				id = obj->id;
-			}
-		}
-
-		/* already installed? */
-		if (already_installed) {
-			if (task->priv->show_warning) {
-				/* TRANSLATORS: we've already got a package that provides this file */
-				text = g_strdup_printf (_("The %s package already provides this file"), id->name);
-				gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				/* TRANSLATORS: title */
-				gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to install file"));
-				gpk_modal_dialog_set_message (task->priv->dialog, text);
-				gpk_modal_dialog_present (task->priv->dialog);
-				gpk_modal_dialog_run (task->priv->dialog);
-				g_free (text);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "already provided");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-
-		/* install this specific package */
-		package_id = pk_package_id_to_string (id);
-		/* convert to data */
-		task->priv->package_ids = pk_package_ids_from_id (package_id);
-		g_free (package_id);
-
-		/* install these packages with deps */
-		g_idle_add ((GSourceFunc) gpk_dbus_task_install_package_ids_dep_check_idle_cb, task);
-		goto out;
-	}
-
-	/* from InstallPackageIds */
-#if PK_CHECK_VERSION(0,5,2)
-	if (role == PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES ||
-	    role == PK_ROLE_ENUM_SIMULATE_INSTALL_FILES) {
-#else
-	if (role == PK_ROLE_ENUM_GET_DEPENDS) {
-#endif
-		PkPackageList *new;
-
-		/* these are the new packages */
-		list = pk_client_get_package_list (task->priv->client_primary);
-		new = pk_package_list_new ();
-		len = pk_package_list_get_size (list);
-		for (i=0; i<len; i++) {
-			obj = pk_package_list_get_obj (list, i);
-
-#if PK_CHECK_VERSION(0,5,2)
-			/* not interesting */
-			if (obj->info != PK_INFO_ENUM_UPDATING &&
-			    obj->info != PK_INFO_ENUM_INSTALLING)
-				continue;
-#endif
-
-			/* is this package already local */
-			if (g_strcmp0 (obj->id->data, "local") == 0)
-				continue;
-
-			pk_package_list_add (new, obj->info, obj->id, obj->summary);
-		}
-
-		/* these are the new packages */
-		len = pk_package_list_get_size (new);
-		if (len == 0) {
-			egg_debug ("no deps");
-			goto skip_checks;
-		}
-
-		/* TRANSLATORS: title: tell the user we have to install additional packages */
-		title = g_strdup_printf (ngettext ("%i additional package also has to be installed",
-						   "%i additional packages also have to be installed",
-						   len), len);
-
-		/* message */
-		if (role == PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES)
-			text = gpk_dialog_package_id_name_join_locale (task->priv->package_ids);
-		else {
-			gchar **files;
-			len = g_strv_length (task->priv->files);
-			files = g_new0 (gchar *, len+1);
-			for (i=0; i<len; i++)
-				files[i] = g_path_get_basename (task->priv->files[i]);
-			text = gpk_strv_join_locale (files);
-			g_strfreev (files);
-		}
-		/* TRANSLATORS: message: explain to the user what we are doing in more detail */
-		message = g_strdup_printf (ngettext ("To install %s, an additional package also has to be downloaded.",
-						     "To install %s, additional packages also have to be downloaded.",
-						     len), text);
-		g_free (text);
-
-		gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
-		gpk_modal_dialog_set_package_list (task->priv->dialog, new);
-		g_object_unref (new);
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_message (task->priv->dialog, message);
-		/* TRANSLATORS: title: installing package */
-		gpk_modal_dialog_set_action (task->priv->dialog, _("Install"));
-		gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-install-other-packages");
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-		button = gpk_modal_dialog_run (task->priv->dialog);
-
-		/* did we click no or exit the window? */
-		if (button != GTK_RESPONSE_OK) {
-			gpk_modal_dialog_close (task->priv->dialog);
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to additional deps");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-skip_checks:
-		if (role == PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES)
-			g_idle_add ((GSourceFunc) gpk_dbus_task_install_package_ids_idle_cb, task);
-		else
-			g_idle_add ((GSourceFunc) gpk_dbus_task_install_files_idle_cb, task);
-	}
-
 	/* from InstallPackageIds */
 	if (role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
 	    role == PK_ROLE_ENUM_INSTALL_FILES) {
 
 		/* show summary? */
-		if (task->priv->show_finished) {
-			list = pk_client_get_package_list (client);
+		if (dtask->priv->show_finished) {
+			array = pk_results_get_package_array (client);
 			/* TRANSLATORS: list the packages we just installed */
-			gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_FINISHED, GPK_MODAL_DIALOG_PACKAGE_LIST);
-			gpk_modal_dialog_set_message (task->priv->dialog, _("The following packages were installed:"));
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_FINISHED, GPK_MODAL_DIALOG_PACKAGE_LIST);
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("The following packages were installed:"));
 
 			/* filter out installed */
-			for (i=0; i<PK_OBJ_LIST(list)->len; i++) {
-				obj = pk_obj_list_index (PK_OBJ_LIST (list), i);
-				if (obj->info != PK_INFO_ENUM_INSTALLING) {
-					pk_obj_list_remove_index (PK_OBJ_LIST (list), i);
+			for (i=0; i<array->len; i++) {
+				item = g_ptr_array_index (array, i);
+				if (item->info != PK_INFO_ENUM_INSTALLING) {
+					pk_item_list_remove_index (list, i);
 					i--;
 				}
 			}
-			gpk_modal_dialog_set_package_list (task->priv->dialog, list);
-			gpk_modal_dialog_present (task->priv->dialog);
+			gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+			gpk_modal_dialog_present (dtask->priv->dialog);
 			g_object_unref (list);
 		} else {
-			gpk_modal_dialog_close (task->priv->dialog);
+			gpk_modal_dialog_close (dtask->priv->dialog);
 		}
 
 		/* done! */
-		egg_warning ("doing async return");
-		dbus_g_method_return (task->priv->context, TRUE); /* FIXME: we send true? */
-		goto out;
-	}
-
-	/* IsInstalled */
-	if (task->priv->role == GPK_DBUS_TASK_ROLE_IS_INSTALLED) {
-		list = pk_client_get_package_list (task->priv->client_primary);
-
-		/* one or more entry? */
-		ret = (PK_OBJ_LIST(list)->len > 0);
-		egg_warning ("doing async return");
-		dbus_g_method_return (task->priv->context, ret);
-		goto out;
-	}
-
-	/* SearchFile */
-	if (task->priv->role == GPK_DBUS_TASK_ROLE_SEARCH_FILE) {
-		list = pk_client_get_package_list (task->priv->client_primary);
-
-		/* one or more entry? */
-		len = PK_OBJ_LIST(list)->len;
-		if (len > 0)
-			name = pk_package_list_get_obj (list, 0)->id->name;
-		egg_warning ("doing async return");
-		dbus_g_method_return (task->priv->context, (len > 0), name);
-		goto out;
-	}
-
-	/* InstallPackageNames */
-	if (task->priv->role == GPK_DBUS_TASK_ROLE_INSTALL_PACKAGE_NAMES &&
-	    role == PK_ROLE_ENUM_RESOLVE) {
-
-		/* found nothing? */
-		list = pk_client_get_package_list (task->priv->client_primary);
-		len = pk_package_list_get_size (list);
-		if (len == 0) {
-			if (task->priv->show_warning) {
-				//FIXME: shows package_id in UI
-				/* TRANSLATORS: couldn't resolve name to package */
-				title = g_strdup_printf (_("Could not find packages"));
-				info_url = gpk_vendor_get_not_found_url (task->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
-				/* only show the "more info" button if there is a valid link */
-				if (info_url != NULL)
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
-				else
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				gpk_modal_dialog_set_title (task->priv->dialog, title);
-				/* TRANSLATORS: message: could not find */
-				gpk_modal_dialog_set_message (task->priv->dialog, _("The packages could not be found in any software source"));
-				gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-package-not-found");
-				/* TRANSLATORS: button: a link to the help file */
-				gpk_modal_dialog_set_action (task->priv->dialog, _("More information"));
-				gpk_modal_dialog_present (task->priv->dialog);
-				button = gpk_modal_dialog_run (task->priv->dialog);
-				if (button == GTK_RESPONSE_OK)
-					gpk_gnome_open (info_url);
-				g_free (info_url);
-				g_free (title);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "no package found");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-
-		/* see what we've got already */
-		for (i=0; i<len; i++) {
-			obj = pk_package_list_get_obj (list, i);
-			if (obj->info == PK_INFO_ENUM_INSTALLED) {
-				already_installed = TRUE;
-			} else if (obj->info == PK_INFO_ENUM_AVAILABLE) {
-				egg_debug ("package '%s' resolved", obj->id->name);
-				id = obj->id;
-				//TODO: we need to list these in a gpk-dbus_task-chooser
-			}
-		}
-
-		/* already installed? */
-		if (already_installed) {
-			if (task->priv->show_warning) {
-				//FIXME: shows package_id in UI
-				/* TRANSLATORS: title: package is already installed */
-				gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to install packages"));
-				/* TRANSLATORS: message: package is already installed */
-				gpk_modal_dialog_set_message (task->priv->dialog, _("The package is already installed"));
-				gpk_modal_dialog_present (task->priv->dialog);
-				gpk_modal_dialog_run (task->priv->dialog);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "package already found");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-
-		/* got junk? */
-		if (id == NULL) {
-			if (task->priv->show_warning) {
-				gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				/* TRANSLATORS: failed to install, shouldn't be shown */
-				gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to install package"));
-				/* TRANSLATORS: the search gave us the wrong result. internal error. barf. */
-				gpk_modal_dialog_set_message (task->priv->dialog, _("Incorrect response from search"));
-				gpk_modal_dialog_present (task->priv->dialog);
-				gpk_modal_dialog_run (task->priv->dialog);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "incorrect response from search");
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-
-		/* convert to data */
-		task->priv->package_ids = pk_package_list_to_strv (list);
-
-		/* install these packages with deps */
-		g_idle_add ((GSourceFunc) gpk_dbus_task_install_package_ids_dep_check_idle_cb, task);
+		egg_debug ("doing async return");
+		dbus_g_method_return (dtask->priv->context, TRUE); /* FIXME: we send true? */
 		goto out;
 	}
 
@@ -1079,20 +458,21 @@ out:
 		g_error_free (error);
 	if (error_local != NULL)
 		g_error_free (error_local);
-	if (list != NULL)
-		g_object_unref (list);
+	if (array != NULL)
+		g_ptr_array_unref (array);
 }
+#endif
 
 /**
  * gpk_dbus_task_set_status:
  **/
 static gboolean
-gpk_dbus_task_set_status (GpkDbusTask *task, PkStatusEnum status)
+gpk_dbus_task_set_status (GpkDbusTask *dtask, PkStatusEnum status)
 {
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
+	g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
 
 	/* do we force progress? */
-	if (!task->priv->show_progress) {
+	if (!dtask->priv->show_progress) {
 		if (status == PK_STATUS_ENUM_DOWNLOAD_REPOSITORY ||
 		    status == PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST ||
 		    status == PK_STATUS_ENUM_DOWNLOAD_FILELIST ||
@@ -1100,233 +480,99 @@ gpk_dbus_task_set_status (GpkDbusTask *task, PkStatusEnum status)
 		    status == PK_STATUS_ENUM_DOWNLOAD_GROUP ||
 		    status == PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO ||
 		    status == PK_STATUS_ENUM_REFRESH_CACHE) {
-			gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
-			gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-progress");
-			gpk_modal_dialog_present_with_time (task->priv->dialog, 0);
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-progress");
+			gpk_modal_dialog_present_with_time (dtask->priv->dialog, 0);
 		}
 	}
 
 	/* ignore */
-	if (!task->priv->show_progress) {
+	if (!dtask->priv->show_progress) {
 		egg_warning ("not showing progress");
 		return FALSE;
 	}
 
 	/* set icon */
-	gpk_modal_dialog_set_image_status (task->priv->dialog, status);
+	gpk_modal_dialog_set_image_status (dtask->priv->dialog, status);
 
 	/* set label */
-	gpk_modal_dialog_set_title (task->priv->dialog, gpk_status_enum_to_localised_text (status));
+	gpk_modal_dialog_set_title (dtask->priv->dialog, gpk_status_enum_to_localised_text (status));
 
 	/* spin */
 	if (status == PK_STATUS_ENUM_WAIT)
-		gpk_modal_dialog_set_percentage (task->priv->dialog, PK_CLIENT_PERCENTAGE_INVALID);
+		gpk_modal_dialog_set_percentage (dtask->priv->dialog, -1);
 
 	/* do visual stuff when finished */
 	if (status == PK_STATUS_ENUM_FINISHED) {
 		/* make insensitive */
-		gpk_modal_dialog_set_allow_cancel (task->priv->dialog, FALSE);
+		gpk_modal_dialog_set_allow_cancel (dtask->priv->dialog, FALSE);
 
 		/* stop spinning */
-		gpk_modal_dialog_set_percentage (task->priv->dialog, 100);
+		gpk_modal_dialog_set_percentage (dtask->priv->dialog, 100);
 	}
 	return TRUE;
 }
 
 /**
- * gpk_dbus_task_progress_changed_cb:
- **/
-static void
-gpk_dbus_task_progress_changed_cb (PkClient *client, guint percentage, guint subpercentage,
-				guint elapsed, guint remaining, GpkDbusTask *task)
-{
-	/* ignore */
-	gpk_modal_dialog_set_percentage (task->priv->dialog, percentage);
-	gpk_modal_dialog_set_remaining (task->priv->dialog, remaining);
-}
-
-/**
- * gpk_dbus_task_status_changed_cb:
- **/
-static void
-gpk_dbus_task_status_changed_cb (PkClient *client, PkStatusEnum status, GpkDbusTask *task)
-{
-	gpk_dbus_task_set_status (task, status);
-}
-
-/**
- * gpk_dbus_task_error_code_cb:
- **/
-static void
-gpk_dbus_task_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *details, GpkDbusTask *task)
-{
-	gboolean ret;
-	GError *error = NULL;
-	const gchar *title;
-	const gchar *message;
-	NotifyNotification *notification;
-	GtkWidget *widget;
-
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-
-	/* save for later */
-	task->priv->last_exit_code = code;
-
-	/* have we handled? */
-	if (code == PK_ERROR_ENUM_NO_LICENSE_AGREEMENT) {
-		egg_warning ("did not auth, but should be already handled");
-		return;
-	}
-
-	/* have we handled? */
-	if (pk_error_code_is_need_untrusted (code)) {
-		egg_warning ("will handled in finished");
-		return;
-	}
-
-	/* ignore some errors */
-	if (code == PK_ERROR_ENUM_PROCESS_KILL ||
-	    code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
-		egg_debug ("error ignored %s\n%s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	egg_debug ("code was %s", pk_error_enum_to_text (code));
-
-	/* use a modal dialog if showing progress, else use libnotify */
-	title = gpk_error_enum_to_localised_text (code);
-	message = gpk_error_enum_to_localised_message (code);
-	if (task->priv->show_progress) {
-		widget = GTK_WIDGET (gpk_modal_dialog_get_window (task->priv->dialog));
-		gpk_error_dialog_modal (GTK_WINDOW (widget), title, message, details);
-		return;
-	}
-
-	/* save this globally */
-	g_free (task->priv->error_details);
-	task->priv->error_details = g_markup_escape_text (details, -1);
-
-	/* do the bubble */
-	notification = notify_notification_new (title, message, "help-browser", NULL);
-	notify_notification_set_timeout (notification, 15000);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-	notify_notification_add_action (notification, "show-error-details",
-					/* TRANSLATORS: button: show details about the error */
-					_("Show details"), gpk_dbus_task_libnotify_cb, task, NULL);
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-}
-
-/**
- * gpk_dbus_task_package_cb:
- **/
-static void
-gpk_dbus_task_package_cb (PkClient *client, const PkPackageObj *obj, GpkDbusTask *task)
-{
-	gchar *text;
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-
-	if (!task->priv->show_progress)
-		return;
-
-	text = gpk_package_id_format_twoline (obj->id, obj->summary);
-	gpk_modal_dialog_set_message (task->priv->dialog, text);
-	g_free (text);
-}
-
-/**
- * gpk_dbus_task_allow_cancel_cb:
- **/
-static void
-gpk_dbus_task_allow_cancel_cb (PkClient *client, gboolean allow_cancel, GpkDbusTask *task)
-{
-	gpk_modal_dialog_set_allow_cancel (task->priv->dialog, allow_cancel);
-}
-
-/**
  * gpk_dbus_task_button_close_cb:
  **/
 static void
-gpk_dbus_task_button_close_cb (GtkWidget *widget, GpkDbusTask *task)
+gpk_dbus_task_button_close_cb (GtkWidget *widget, GpkDbusTask *dtask)
 {
 	/* close, don't abort */
-	gpk_modal_dialog_close (task->priv->dialog);
+	gpk_modal_dialog_close (dtask->priv->dialog);
 }
 
 /**
  * gpk_dbus_task_button_cancel_cb:
  **/
 static void
-gpk_dbus_task_button_cancel_cb (GtkWidget *widget, GpkDbusTask *task)
+gpk_dbus_task_button_cancel_cb (GtkWidget *widget, GpkDbusTask *dtask)
 {
-	gboolean ret;
-	GError *error = NULL;
-
 	/* we might have a transaction running */
-	ret = pk_client_cancel (task->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	ret = pk_client_cancel (task->priv->client_secondary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return;
+	g_cancellable_cancel (dtask->priv->cancellable);
 }
 
 /**
- * gpk_dbus_task_install_package_files_internal:
+ * gpk_dbus_task_install_files_cb:
  **/
 static void
-gpk_dbus_task_install_package_files_internal (GpkDbusTask *task, gboolean trusted)
+gpk_dbus_task_install_files_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
 {
-	gboolean ret;
 	GError *error = NULL;
-	GError *error_local = NULL;
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
 	guint length;
 	const gchar *title;
+	PkItemErrorCode *error_item = NULL;
 
-	/* FIXME: we need to move this into PkClient sooner or later */
-	task->priv->last_exit_code = PK_ERROR_ENUM_UNKNOWN;
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this should never happen, low level failure */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client to perform action"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		/* TRANSLATORS: error: failed to install, detailed error follows */
+		length = g_strv_length (dtask->priv->files);
+		title = ngettext ("Failed to install file", "Failed to install files", length);
+		gpk_dbus_task_error_msg (dtask, title, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
-
-	/* install local file */
-	ret = pk_client_install_files (task->priv->client_primary, trusted, task->priv->files, &error_local);
-	if (!ret) {
-		length = g_strv_length (task->priv->files);
-		/* TRANSLATORS: title: detailed internal error why the file install failed */
-		title = ngettext ("Failed to install file", "Failed to install files", length);
-		gpk_dbus_task_error_msg (task, title, error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to install file: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		gpk_dbus_task_handle_error (dtask, error_item);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -1369,266 +615,6 @@ gpk_dbus_task_ptr_array_to_bullets (GPtrArray *array, const gchar *prefix)
 }
 
 /**
- * gpk_dbus_task_install_package_files_get_user_temp:
- *
- * Return (and create if does not exist) a temporary directory
- * that is writable only by the user, and readable by root.
- *
- * Return value: the temp directory, or %NULL for create error
- **/
-static gchar *
-gpk_dbus_task_install_package_files_get_user_temp (GpkDbusTask *task, const gchar *subfolder, GError **error)
-{
-	GFile *file;
-	gboolean ret;
-	gchar *path = NULL;
-
-	/* build path in home folder */
-	path = g_build_filename (g_get_home_dir (), ".PackageKit", subfolder, NULL);
-
-	/* find if exists */
-	file = g_file_new_for_path (path);
-	ret = g_file_query_exists (file, NULL);
-	if (ret)
-		goto out;
-
-	/* create as does not exist */
-	ret = g_file_make_directory_with_parents (file, NULL, error);
-	g_object_unref (file);
-	if (!ret) {
-		/* return nothing.. */
-		g_free (path);
-		path = NULL;
-	}
-out:
-	return path;
-}
-
-GMainLoop *_loop = NULL;
-
-/**
- * gpk_dbus_task_install_package_files_ready_callback:
- **/
-static void
-gpk_dbus_task_install_package_files_ready_callback (GObject *source_object, GAsyncResult *res, GpkDbusTask *task)
-{
-	gboolean ret;
-	GError *error_local = NULL;
-
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-
-	ret = g_file_copy_finish (G_FILE (source_object), res, &error_local);
-	if (!ret) {
-		egg_warning ("failed to copy file: %s", error_local->message);
-		g_error_free (error_local);
-	}
-
-	g_main_loop_quit (_loop);
-}
-
-/**
- * gpk_dbus_task_install_package_files_progress_callback:
- **/
-static void
-gpk_dbus_task_install_package_files_progress_callback (goffset current_num_bytes, goffset total_num_bytes, GpkDbusTask *task)
-{
-	guint percentage;
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-	percentage = (current_num_bytes * 100) / total_num_bytes;
-	gpk_modal_dialog_set_percentage (task->priv->dialog, percentage);
-}
-
-/**
- * gpk_dbus_task_install_package_files_copy_non_native:
- *
- * Copy the new file into a new file that can be read by packagekitd, and
- * that can't be written into by other users.
- *
- * Return value: the new file path, or %NULL for copy error
- **/
-static gchar *
-gpk_dbus_task_install_package_files_copy_non_native (GpkDbusTask *task, const gchar *filename, GError **error)
-{
-	GFile *file = NULL;
-	GFile *dest = NULL;
-	gchar *basename = NULL;
-	gchar *dest_path = NULL;
-	gchar *new_path = NULL;
-	gchar *cache_path = NULL;
-	GError *error_local = NULL;
-
-	/* create the non FUSE temp directory */
-	cache_path = gpk_dbus_task_install_package_files_get_user_temp (task, "native-cache", &error_local);
-	if (cache_path == NULL) {
-		*error = g_error_new (1, 0, "failed to create temp directory: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	/* get the final location */
-	file = g_file_new_for_path (filename);
-	basename = g_file_get_basename (file);
-	dest_path = g_build_filename (cache_path, basename, NULL);
-
-	/* copy the file */
-	dest = g_file_new_for_path (dest_path);
-	g_file_copy_async (file, dest, G_FILE_COPY_OVERWRITE, 0, NULL,
-			   (GFileProgressCallback) gpk_dbus_task_install_package_files_progress_callback, task,
-			   (GAsyncReadyCallback) gpk_dbus_task_install_package_files_ready_callback, task);
-	_loop = g_main_loop_new (NULL, FALSE);
-	g_main_loop_run (_loop);
-	g_main_loop_unref (_loop);
-
-	/* return the modified file item */
-	new_path = g_strdup (dest_path);
-
-out:
-	if (file != NULL)
-		g_object_unref (file);
-	if (dest != NULL)
-		g_object_unref (dest);
-	g_free (basename);
-	g_free (cache_path);
-	g_free (dest_path);
-	return new_path;
-}
-
-/**
- * gpk_dbus_task_install_package_files_native_check:
- *
- * Allow the user to confirm the package copy to ~/.PackageKit/native-cache
- * as we cannot access FUSE mounts as the root user.
- *
- * Return value: %TRUE if the method succeeded
- **/
-static gboolean
-gpk_dbus_task_install_package_files_native_check (GpkDbusTask *task, GPtrArray *array, GError **error)
-{
-	guint i;
-	const gchar *data;
-	gchar *cache_path = NULL;
-	gchar *filename;
-	gboolean ret;
-	gboolean native;
-	GPtrArray *array_missing;
-	const gchar *message_part;
-	const gchar *title;
-	gchar *message;
-	GtkResponseType button;
-	GError *error_local = NULL;
-	GFile *file;
-
-	/* check if any files are non-native and need to be copied */
-	array_missing = g_ptr_array_new ();
-	for (i=0; i<array->len; i++) {
-		data = (const gchar *) g_ptr_array_index (array, i);
-		/* if file is non-native, it's on a FUSE mount (probably created by GVFS).
-		 * See https://bugzilla.redhat.com/show_bug.cgi?id=456094 */
-		file = g_file_new_for_path (data);
-		native = g_file_is_native (file);
-		g_object_unref (file);
-		if (!native) {
-			egg_debug ("%s is non-native", data);
-			g_ptr_array_add (array_missing, g_strdup (data));
-		}
-	}
-
-	/* optional */
-	ret = gconf_client_get_bool (task->priv->gconf_client, GPK_CONF_SHOW_COPY_CONFIRM, NULL);
-	if (ret && array_missing->len > 0) {
-		/* TRANSLATORS: title: we have to copy the private files to a public location */
-		title = ngettext ("Do you want to copy this file?",
-				  "Do you want to copy these files?", array_missing->len);
-		/* TRANSLATORS: message: explain to the user what we are doing */
-		message_part = ngettext ("This package file has to be copied from a private directory so it can be installed:",
-					 "Several package files have to be copied from a private directory so they can be installed:",
-					 array_missing->len);
-		message = gpk_dbus_task_ptr_array_to_bullets (array_missing, message_part);
-
-		/* show UI */
-		gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_message (task->priv->dialog, message);
-		gpk_modal_dialog_set_image (task->priv->dialog, "dialog-warning");
-		/* TRANSLATORS: button: copy file from one directory to another */
-		gpk_modal_dialog_set_action (task->priv->dialog, ngettext ("Copy file", "Copy files", array_missing->len));
-		gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-installing-private-files");
-		g_free (message);
-
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-		button = gpk_modal_dialog_run (task->priv->dialog);
-		/* did we click no or exit the window? */
-		if (button != GTK_RESPONSE_OK) {
-			*error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "Aborted the copy");
-			ret = FALSE;
-			goto out;
-		}
-	}
-
-	/* setup UI */
-	if (array_missing->len > 0) {
-		/* TRANSLATORS: title: we are about to copy files, which may take a few seconds */
-		title = ngettext ("Copying file",
-				  "Copying files", array_missing->len);
-		gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-installing-private-files");
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	}
-
-	/* now we have the okay to copy the files, do so */
-	ret = TRUE;
-	for (i=0; i<array->len; i++) {
-		data = (const gchar *) g_ptr_array_index (array, i);
-
-		/* check we are not on FUSE */
-		file = g_file_new_for_path (data);
-		native = g_file_is_native (file);
-		g_object_unref (file);
-		if (!native) {
-			/* copy the file */
-			filename = gpk_dbus_task_install_package_files_copy_non_native (task, data, &error_local);
-			if (filename == NULL) {
-				*error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "failed to copy file %s: %s", data, error_local->message);
-				ret = FALSE;
-				break;
-			}
-
-			/* show progress */
-			gpk_modal_dialog_set_message (task->priv->dialog, filename);
-
-			/* swap data in array */
-			g_free (array->pdata[i]);
-			array->pdata[i] = g_strdup (filename);
-			g_free (filename);
-		}
-	}
-
-	/* did we fail to copy the files */
-	if (!ret) {
-		/* TRANSLATORS: title: tell the user we failed */
-		title = ngettext ("The file could not be copied",
-				  "The files could not be copied", array_missing->len);
-
-		/* show UI */
-		gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_message (task->priv->dialog, error_local->message);
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-		gpk_modal_dialog_run (task->priv->dialog);
-		*error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "files not copied");
-		ret = FALSE;
-		g_error_free (error_local);
-		goto out;
-	}
-out:
-	g_free (cache_path);
-	g_ptr_array_foreach (array_missing, (GFunc) g_free, NULL);
-	g_ptr_array_free (array_missing, TRUE);
-	return ret;
-}
-
-/**
  * gpk_dbus_task_install_package_files_verify:
  *
  * Allow the user to confirm the action
@@ -1636,7 +622,7 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 static gboolean
-gpk_dbus_task_install_package_files_verify (GpkDbusTask *task, GPtrArray *array, GError **error)
+gpk_dbus_task_install_package_files_verify (GpkDbusTask *dtask, GPtrArray *array, GError **error)
 {
 	GtkResponseType button;
 	const gchar *title;
@@ -1649,14 +635,14 @@ gpk_dbus_task_install_package_files_verify (GpkDbusTask *task, GPtrArray *array,
 	message = gpk_dbus_task_ptr_array_to_bullets (array, NULL);
 
 	/* show UI */
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	gpk_modal_dialog_set_message (task->priv->dialog, message);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_message (dtask->priv->dialog, message);
 	/* TRANSLATORS: title: installing local files */
-	gpk_modal_dialog_set_action (task->priv->dialog, _("Install"));
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-install-files");
-	gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	button = gpk_modal_dialog_run (task->priv->dialog);
+	gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-install-files");
+	gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+	button = gpk_modal_dialog_run (dtask->priv->dialog);
 	g_free (message);
 
 	/* did we click no or exit the window? */
@@ -1670,216 +656,37 @@ out:
 }
 
 /**
- * gpk_dbus_task_install_package_files_check_exists:
- *
- * Skip files that are not present
- *
- * Return value: %TRUE if the method succeeded
- **/
-static gboolean
-gpk_dbus_task_install_package_files_check_exists (GpkDbusTask *task, GPtrArray *array, GError **error)
-{
-	guint i;
-	const gchar *data;
-	gboolean ret;
-	GPtrArray *array_missing;
-	const gchar *message_part;
-	const gchar *title;
-	gchar *message;
-
-	array_missing = g_ptr_array_new ();
-
-	/* find missing */
-	for (i=0; i<array->len; i++) {
-		data = (const gchar *) g_ptr_array_index (array, i);
-		ret = g_file_test (data, G_FILE_TEST_EXISTS);
-		if (!ret)
-			g_ptr_array_add (array_missing, g_strdup (data));
-	}
-
-	/* warn, set error and quit */
-	ret = TRUE;
-	if (array_missing->len > 0) {
-		/* TRANSLATORS: title: we couldn't find the file -- very hard to get this */
-		title = ngettext ("File was not found!",
-				  "Files were not found!", array_missing->len);
-
-		/* TRANSLATORS: message: explain what went wrong */
-		message_part = ngettext ("The following file was not found:",
-					 "The following files were not found:", array_missing->len);
-		message = gpk_dbus_task_ptr_array_to_bullets (array_missing, message_part);
-
-		/* show UI */
-		gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_message (task->priv->dialog, message);
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-		gpk_modal_dialog_run (task->priv->dialog);
-
-		g_free (message);
-
-		ret = FALSE;
-		*error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "some files did not exist");
-		goto out;
-	}
-
-out:
-	g_ptr_array_foreach (array_missing, (GFunc) g_free, NULL);
-	g_ptr_array_free (array_missing, TRUE);
-	return ret;
-}
-
-/**
- * gpk_dbus_task_install_package_files_check_type_get_content_type:
- **/
-static gchar *
-gpk_dbus_task_install_package_files_check_type_get_content_type (const gchar *filename, GError **error)
-{
-	GError *error_local = NULL;
-	GFile *file;
-	GFileInfo *info;
-	gchar *content_type = NULL;
-
-	/* get file info synchronously */
-	file = g_file_new_for_path (filename);
-	info = g_file_query_info (file, "standard::content-type", G_FILE_QUERY_INFO_NONE, NULL, &error_local);
-	if (info == NULL) {
-		*error = g_error_new (1, 0, "failed to get file attributes for %s: %s", filename, error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	/* get content type as string */
-	content_type = g_file_info_get_attribute_as_string (info, "standard::content-type");
-out:
-	if (info != NULL)
-		g_object_unref (info);
-	g_object_unref (file);
-	return content_type;
-}
-
-/**
- * gpk_dbus_task_install_package_files_check_type:
- *
- * Skip files that are not present
- *
- * Return value: %TRUE if the method succeeded
- **/
-static gboolean
-gpk_dbus_task_install_package_files_check_type (GpkDbusTask *task, GPtrArray *array, GError **error)
-{
-	guint i;
-	guint j;
-	const gchar *data;
-	gboolean ret = FALSE;
-	GPtrArray *array_unknown;
-	const gchar *message_part;
-	const gchar *title;
-	gchar *message;
-	gchar *content_type;
-	GError *error_local = NULL;
-	gchar **supported_types;
-
-	array_unknown = g_ptr_array_new ();
-
-	/* get mime types supported by the backend */
-	supported_types = pk_control_get_mime_types (task->priv->control, &error_local);
-	if (supported_types == NULL) {
-		*error = g_error_new (1, 0, "failed to get supported types for the backend: %s", error_local->message);
-		g_error_free (error_local);
-		goto out;
-	}
-
-	/* find invalid files */
-	for (i=0; i<array->len; i++) {
-		data = (const gchar *) g_ptr_array_index (array, i);
-
-		/* get content type for this file */
-		content_type = gpk_dbus_task_install_package_files_check_type_get_content_type (data, error);
-		if (content_type == NULL)
-			goto out;
-		egg_warning ("content_type=%s", content_type);
-
-		/* can we support this one? */
-		ret = FALSE;
-		for (j=0; supported_types[j] != NULL; j++) {
-			if (g_strcmp0 (supported_types[j], content_type) == 0) {
-				ret = TRUE;
-				break;
-			}
-		}
-		g_free (content_type);
-
-		/* we can't handle the content type :-( */
-		if (!ret)
-			g_ptr_array_add (array_unknown, g_strdup (data));
-	}
-
-	/* warn, set error and quit */
-	ret = TRUE;
-	if (array_unknown->len > 0) {
-		/* TRANSLATORS: title: we couldn't find the file -- very hard to get this */
-		title = ngettext ("File was not recognised!",
-				  "Files were not recognised!", array_unknown->len);
-
-		/* TRANSLATORS: message: the backend would not be able to handle the mime-type */
-		message_part = ngettext ("The following file is not recognised by the packaging system:",
-					 "The following files are not recognised by the packaging system:", array_unknown->len);
-		message = gpk_dbus_task_ptr_array_to_bullets (array_unknown, message_part);
-
-		/* show UI */
-		gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-		gpk_modal_dialog_set_title (task->priv->dialog, title);
-		gpk_modal_dialog_set_message (task->priv->dialog, message);
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-		gpk_modal_dialog_run (task->priv->dialog);
-
-		g_free (message);
-
-		ret = FALSE;
-		*error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "some files were not recognised");
-		goto out;
-	}
-
-out:
-	g_strfreev (supported_types);
-	g_ptr_array_foreach (array_unknown, (GFunc) g_free, NULL);
-	g_ptr_array_free (array_unknown, TRUE);
-	return ret;
-}
-
-/**
  * gpk_dbus_task_confirm_action:
  * @task: a valid #GpkDbusTask instance
  **/
 static gboolean
-gpk_dbus_task_confirm_action (GpkDbusTask *task, const gchar *title, const gchar *message, const gchar *action)
+gpk_dbus_task_confirm_action (GpkDbusTask *dtask, const gchar *title, const gchar *message, const gchar *action)
 {
 	GtkResponseType button;
 
 	/* check the user wanted to call this method */
-	if (!task->priv->show_confirm_search)
+	if (!dtask->priv->show_confirm_search)
 		return TRUE;
 
 	/* setup UI */
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
-	gpk_modal_dialog_set_action (task->priv->dialog, action);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
+	gpk_modal_dialog_set_action (dtask->priv->dialog, action);
 
 	/* set icon */
-	if (task->priv->parent_icon_name != NULL)
-		gpk_modal_dialog_set_image (task->priv->dialog, task->priv->parent_icon_name);
+	if (dtask->priv->parent_icon_name != NULL)
+		gpk_modal_dialog_set_image (dtask->priv->dialog, dtask->priv->parent_icon_name);
 	else
-		gpk_modal_dialog_set_image (task->priv->dialog, "emblem-system");
+		gpk_modal_dialog_set_image (dtask->priv->dialog, "emblem-system");
 
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	gpk_modal_dialog_set_message (task->priv->dialog, message);
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-application-confirm");
-	gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	button = gpk_modal_dialog_run (task->priv->dialog);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-application-confirm");
+	gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+	button = gpk_modal_dialog_run (dtask->priv->dialog);
 
 	/* close, we're going to fail the method */
 	if (button != GTK_RESPONSE_OK) {
-		gpk_modal_dialog_close (task->priv->dialog);
+		gpk_modal_dialog_close (dtask->priv->dialog);
 		return FALSE;
 	}
 
@@ -1887,183 +694,189 @@ gpk_dbus_task_confirm_action (GpkDbusTask *task, const gchar *title, const gchar
 }
 
 /**
- * gpk_dbus_task_is_installed:
+ * gpk_dbus_task_progress_cb:
  **/
-void
-gpk_dbus_task_is_installed (GpkDbusTask *task, const gchar *package_name)
+static void
+gpk_dbus_task_progress_cb (PkProgress *progress, PkProgressType type, GpkDbusTask *dtask)
 {
-	gboolean ret;
-	GError *error = NULL;
-	GError *error_local = NULL;
-	gchar **package_names = NULL;
-
-	task->priv->role = GPK_DBUS_TASK_ROLE_IS_INSTALLED;
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to reset: %s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	gboolean allow_cancel;
+	gint percentage;
+	guint remaining_time;
+	PkStatusEnum status;
+	gchar *package_id = NULL;
+	gchar *text;
 
-	/* get the package list for the installed packages */
-	package_names = g_strsplit (package_name, "|", 1);
-	egg_warning ("package_name=%s", package_name);
-	ret = pk_client_resolve (task->priv->client_primary, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_names, &error_local);
-	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to get installed status: %s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
+	/* optimise */
+	if (!dtask->priv->show_progress)
+		goto out;
+
+	g_object_get (progress,
+		      "allow-cancel", &allow_cancel,
+		      "percentage", &percentage,
+		      "remaining-time", &remaining_time,
+		      "status", &status,
+		      "package-id", &package_id,
+		      NULL);
+
+	if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
+		egg_debug ("_package");
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+		gpk_modal_dialog_set_percentage (dtask->priv->dialog, percentage);
+	} else if (type == PK_PROGRESS_TYPE_ALLOW_CANCEL) {
+		gpk_modal_dialog_set_allow_cancel (dtask->priv->dialog, allow_cancel);
+	} else if (type == PK_PROGRESS_TYPE_STATUS) {
+		gpk_dbus_task_set_status (dtask, status);
+
+		if (status == PK_STATUS_ENUM_FINISHED) {
+			/* stop spinning */
+			gpk_modal_dialog_set_percentage (dtask->priv->dialog, 100);
+		}
+	} else if (type == PK_PROGRESS_TYPE_REMAINING_TIME) {
+		gpk_modal_dialog_set_remaining (dtask->priv->dialog, remaining_time);
+	} else if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
+		text = gpk_package_id_format_twoline (package_id, NULL); //TODO: need summary
+		gpk_modal_dialog_set_message (dtask->priv->dialog, text);
+		g_free (text);
 	}
-
-	/* wait for async reply... */
 out:
-	g_strfreev (package_names);
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	g_free (package_id);
 }
 
 /**
- * gpk_dbus_task_search_file:
+ * gpk_dbus_task_is_installed_resolve_cb:
  **/
-void
-gpk_dbus_task_search_file (GpkDbusTask *task, const gchar *search_file)
+static void
+gpk_dbus_task_is_installed_resolve_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
 {
-	gboolean ret;
 	GError *error = NULL;
-	GError *error_local = NULL;
-
-	task->priv->role = GPK_DBUS_TASK_ROLE_SEARCH_FILE;
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to reset: %s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	gboolean ret;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
-
-	/* get the package list for the installed packages */
-	egg_warning ("package_name=%s", search_file);
-	ret = pk_client_search_file (task->priv->client_primary, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), search_file, &error_local);
-	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to get installed status: %s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-	/* wait for async reply... */
+	/* get results */
+	array = pk_results_get_package_array (results);
+	ret = (array->len > 0);
+	egg_debug ("doing async return");
+	dbus_g_method_return (dtask->priv->context, ret);
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_dbus_task_install_files:
+ * gpk_dbus_task_is_installed:
  **/
-static void
-gpk_dbus_task_install_files (GpkDbusTask *task)
+void
+gpk_dbus_task_is_installed (GpkDbusTask *dtask, const gchar *package_name)
 {
-	guint len;
-
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
-	len = g_strv_length (task->priv->files);
-	/* TRANSLATORS: title: installing a local file */
-	gpk_modal_dialog_set_title (task->priv->dialog, ngettext ("Install local file", "Install local files", len));
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
+	gchar **package_names = NULL;
 
-	gpk_dbus_task_install_package_files_internal (task, TRUE);
+	/* get the package list for the installed packages */
+	package_names = g_strsplit (package_name, "|", 1);
+	pk_client_resolve_async (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_names, NULL,
+				 (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				 (GAsyncReadyCallback) gpk_dbus_task_is_installed_resolve_cb, dtask);
+	g_strfreev (package_names);
 }
 
 /**
- * gpk_dbus_task_install_files_dep_check:
+ * gpk_dbus_task_search_file_search_file_cb:
  **/
 static void
-gpk_dbus_task_install_files_dep_check (GpkDbusTask *task)
+gpk_dbus_task_search_file_search_file_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
 {
-	gboolean ret;
 	GError *error = NULL;
-	GError *error_local = NULL;
-
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-	g_return_if_fail (task->priv->files != NULL);
-
-	/* are we dumb and can't check for depends? */
-	if (!pk_bitfield_contain (task->priv->roles, PK_ROLE_ENUM_SIMULATE_INSTALL_FILES)) {
-		egg_warning ("skipping depends check");
-		gpk_dbus_task_install_package_ids (task);
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+	gchar **split = NULL;
+	const PkItemPackage *item;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to search file: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* have we previously said we don't want to be shown the confirmation */
-	ret = gconf_client_get_bool (task->priv->gconf_client, GPK_CONF_SHOW_DEPENDS, NULL);
-	if (!ret) {
-		egg_warning ("we've said we don't want the dep dialog");
-		gpk_dbus_task_install_package_ids (task);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to search file: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-	/* optional */
-	if (!task->priv->show_confirm_deps) {
-		egg_warning ("skip confirm as not allowed to interact with user");
-		gpk_dbus_task_install_files (task);
+	/* get results */
+	array = pk_results_get_package_array (results);
+	if (array->len == 0) {
+		egg_warning ("no packages");
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to find any packages");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
-	/* TRANSLATORS: finding a list of packages that we would also need to download */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Finding other packages we require"));
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-finding-depends");
+	/* get first item */
+	item = g_ptr_array_index (array, 0);
+	split = pk_package_id_split (item->package_id);
 
-	/* setup the UI */
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this is an internal error, and should not be seen */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	egg_debug ("doing async return");
+	dbus_g_method_return (dtask->priv->context, (item->info == PK_INFO_ENUM_INSTALLED), split[PK_PACKAGE_ID_NAME]);
+out:
+	g_strfreev (split);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
 
-#if (PK_CHECK_VERSION(0,5,2))
-	/* find out if this would drag in other packages */
-	ret = pk_client_simulate_install_files (task->priv->client_primary, task->priv->files, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: error: could not get the extra package list when installing a package */
-		gpk_dbus_task_error_msg (task, _("Could not work out what packages would be also installed"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-#else
-	gpk_dbus_task_install_files (task);
-#endif
+/**
+ * gpk_dbus_task_search_file:
+ **/
+void
+gpk_dbus_task_search_file (GpkDbusTask *dtask, const gchar *search_file)
+{
+	gchar **values = NULL;
 
-	/* wait for async reply */
-out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	/* get the package list for the installed packages */
+	egg_debug ("package_name=%s", search_file);
+	values = g_strsplit (search_file, "&", -1);
+	pk_client_search_file_async (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), values, NULL,
+				     (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				     (GAsyncReadyCallback) gpk_dbus_task_search_file_search_file_cb, dtask);
+	g_strfreev (values);
 }
 
 /**
@@ -2078,58 +891,175 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_package_files (GpkDbusTask *task, gchar **files_rel)
+gpk_dbus_task_install_package_files (GpkDbusTask *dtask, gchar **files_rel)
 {
 	GError *error = NULL;
+	GError *error_dbus = NULL;
 	gboolean ret;
 	GPtrArray *array;
-//	const gchar *title;
+	guint len;
 
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (files_rel != NULL);
 
 	array = pk_strv_to_ptr_array (files_rel);
 
 	/* check the user wanted to call this method */
-	if (task->priv->show_confirm_search) {
-		ret = gpk_dbus_task_install_package_files_verify (task, array, &error);
+	if (dtask->priv->show_confirm_search) {
+		ret = gpk_dbus_task_install_package_files_verify (dtask, array, &error);
 		if (!ret) {
-			dbus_g_method_return_error (task->priv->context, error);
+			dbus_g_method_return_error (dtask->priv->context, error_dbus);
 			goto out;
 		}
 	}
 
-	/* check all files exist and are readable by the local user */
-	ret = gpk_dbus_task_install_package_files_check_exists (task, array, &error);
-	if (!ret) {
-		dbus_g_method_return_error (task->priv->context, error);
+	/* check for deps */
+	dtask->priv->files = pk_ptr_array_to_strv (array);
+
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+	len = g_strv_length (dtask->priv->files);
+	/* TRANSLATORS: title: installing a local file */
+	gpk_modal_dialog_set_title (dtask->priv->dialog, ngettext ("Install local file", "Install local files", len));
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+
+	/* install async */
+	pk_task_install_files_async (dtask->priv->task, dtask->priv->files, NULL, NULL, NULL,
+				     (GAsyncReadyCallback) gpk_dbus_task_install_files_cb, dtask);
+
+	/* wait for async reply */
+out:
+	g_ptr_array_unref (array);
+	if (error != NULL)
+		g_error_free (error);
+}
+
+/**
+ * gpk_dbus_task_install_package_names_resolve_cb:
+ **/
+static void
+gpk_dbus_task_install_package_names_resolve_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
+{
+	GError *error = NULL;
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+	const gchar *package_id = NULL;
+	gchar *title;
+	gchar *info_url;
+	PkItemPackage *item;
+	GtkResponseType button;
+	guint i;
+	gboolean already_installed = FALSE;
+
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* check all files can be handled by the backend */
-	ret = gpk_dbus_task_install_package_files_check_type (task, array, &error);
-	if (!ret) {
-		dbus_g_method_return_error (task->priv->context, error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-	/* check all files exist and are readable by the local user */
-	ret = gpk_dbus_task_install_package_files_native_check (task, array, &error);
-	if (!ret) {
-		dbus_g_method_return_error (task->priv->context, error);
+	/* found nothing? */
+	array = pk_results_get_package_array (results);
+	if (array->len == 0) {
+		if (!dtask->priv->show_warning) {
+			//FIXME: shows package_id in UI
+			/* TRANSLATORS: couldn't resolve name to package */
+			title = g_strdup_printf (_("Could not find packages"));
+			info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
+			/* only show the "more info" button if there is a valid link */
+			if (info_url != NULL)
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+			else
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+			/* TRANSLATORS: message: could not find */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("The packages could not be found in any software source"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-package-not-found");
+			/* TRANSLATORS: button: a link to the help file */
+			gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			button = gpk_modal_dialog_run (dtask->priv->dialog);
+			if (button == GTK_RESPONSE_OK)
+				gpk_gnome_open (info_url);
+			g_free (info_url);
+			g_free (title);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "no package found");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-	/* check for deps */
-	task->priv->files = pk_ptr_array_to_strv (array);
-	gpk_dbus_task_install_files_dep_check (task);
+	/* see what we've got already */
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->info == PK_INFO_ENUM_INSTALLED) {
+			already_installed = TRUE;
+		} else if (item->info == PK_INFO_ENUM_AVAILABLE) {
+			egg_debug ("package '%s' resolved", item->package_id);
+			package_id = item->package_id;
+			//TODO: we need to list these in a gpk-dbus_task-chooser
+		}
+	}
 
-	/* wait for async reply */
+	/* already installed? */
+	if (already_installed) {
+		if (dtask->priv->show_warning) {
+			//FIXME: shows package_id in UI
+			/* TRANSLATORS: title: package is already installed */
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install packages"));
+			/* TRANSLATORS: message: package is already installed */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("The package is already installed"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			gpk_modal_dialog_run (dtask->priv->dialog);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "package already found");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* got junk? */
+	if (package_id == NULL) {
+		if (dtask->priv->show_warning) {
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			/* TRANSLATORS: failed to install, shouldn't be shown */
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install package"));
+			/* TRANSLATORS: the search gave us the wrong result. internal error. barf. */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("Incorrect response from search"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			gpk_modal_dialog_run (dtask->priv->dialog);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "incorrect response from search");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* convert to data */
+	dtask->priv->package_ids = pk_package_array_to_strv (array);
+
+	/* install these packages with deps */
+	gpk_dbus_task_install_package_ids (dtask);
 out:
-	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-	g_ptr_array_free (array, TRUE);
-	if (error != NULL)
-		g_error_free (error);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -2143,24 +1073,21 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_package_names (GpkDbusTask *task, gchar **packages)
+gpk_dbus_task_install_package_names (GpkDbusTask *dtask, gchar **packages)
 {
 	gboolean ret;
-	GError *error = NULL;
-	GError *error_local = NULL;
+	GError *error_dbus = NULL;
 	gchar *message;
 	gchar *text;
 	guint len;
 	guint i;
 	GString *string;
 
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (packages != NULL);
 
-	task->priv->role = GPK_DBUS_TASK_ROLE_INSTALL_PACKAGE_NAMES;
-
 	/* optional */
-	if (!task->priv->show_confirm_install) {
+	if (!dtask->priv->show_confirm_install) {
 		egg_debug ("skip confirm as not allowed to interact with user");
 		goto skip_checks;
 	}
@@ -2188,65 +1115,157 @@ gpk_dbus_task_install_package_names (GpkDbusTask *task, gchar **packages)
 	g_free (text);
 
 	/* make title using application name */
-	if (task->priv->parent_title != NULL) {
+	if (dtask->priv->parent_title != NULL) {
 		/* TRANSLATORS: string is a program name, e.g. "Movie Player" */
-		text = g_strdup_printf (ngettext ("%s wants to install a package", "%s wants to install packages", len), task->priv->parent_title);
+		text = g_strdup_printf (ngettext ("%s wants to install a package", "%s wants to install packages", len), dtask->priv->parent_title);
 	} else {
 		/* TRANSLATORS: a random program which we can't get the name wants to do something */
 		text = g_strdup (ngettext ("A program wants to install a package", "A program wants to install packages", len));
 	}
 
 	/* TRANSLATORS: button: confirm to search for packages */
-	ret = gpk_dbus_task_confirm_action (task, text, message, _("Install"));
+	ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Install"));
 	g_free (text);
 	g_free (message);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 skip_checks:
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
 	/* TRANSLATORS: title, searching */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Searching for packages"));
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_WAIT);
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-finding-packages");
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this is an internal error, and should not be seen */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for packages"));
+	gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-finding-packages");
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present (dtask->priv->dialog);
+
+	/* find out if we can find a package */
+	pk_client_resolve_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1), packages, NULL,
+			         (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				 (GAsyncReadyCallback) gpk_dbus_task_install_package_names_resolve_cb, dtask);
+
+	/* wait for async reply */
+out:
+	return;
+}
+
+/**
+ * gpk_dbus_task_install_provide_files_search_file_cb:
+ **/
+static void
+gpk_dbus_task_install_provide_files_search_file_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+	GError *error = NULL;
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+	const gchar *package_id = NULL;
+	gchar *info_url;
+	PkItemPackage *item;
+	GtkResponseType button;
+	guint i;
+	gboolean already_installed = FALSE;
+	gchar *text;
+	gchar **split;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
 
-	/* find out if we can find a package */
-	ret = pk_client_resolve (task->priv->client_primary,
-				 pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH,
-							 PK_FILTER_ENUM_NEWEST, -1),
-				 packages, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: we failed to find the package, this shouldn't happen */
-		gpk_dbus_task_error_msg (task, _("Incorrect response from search"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
+	/* get results */
+	array = pk_results_get_package_array (results);
+	//FIXME: do something
+
+	/* found nothing? */
+	if (array->len == 0) {
+		if (dtask->priv->show_warning) {
+			info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
+			/* only show the "more info" button if there is a valid link */
+			if (info_url != NULL)
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+			else
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			/* TRANSLATORS: failed to fild the package for thefile */
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to find package"));
+			/* TRANSLATORS: nothing found */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("The file could not be found in any packages"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-package-not-found");
+			/* TRANSLATORS: button: show the user a button to get more help finding stuff */
+			gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			button = gpk_modal_dialog_run (dtask->priv->dialog);
+			if (button == GTK_RESPONSE_OK)
+				gpk_gnome_open (info_url);
+			g_free (info_url);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "no files found");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
-/*xxx*/
-	/* wait for async reply */
+
+	/* see what we've got already */
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->info == PK_INFO_ENUM_INSTALLED) {
+			already_installed = TRUE;
+			package_id = item->package_id;
+		} else if (item->info == PK_INFO_ENUM_AVAILABLE) {
+			egg_debug ("package '%s' resolved to:", item->package_id);
+			package_id = item->package_id;
+		}
+	}
+
+	/* already installed? */
+	if (already_installed) {
+		if (dtask->priv->show_warning) {
+			split = pk_package_id_split (package_id);
+			/* TRANSLATORS: we've already got a package that provides this file */
+			text = g_strdup_printf (_("The %s package already provides this file"), split[PK_PACKAGE_ID_NAME]);
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			/* TRANSLATORS: title */
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install file"));
+			gpk_modal_dialog_set_message (dtask->priv->dialog, text);
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			gpk_modal_dialog_run (dtask->priv->dialog);
+			g_free (text);
+			g_strfreev (split);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "already provided");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* convert to data */
+	dtask->priv->package_ids = pk_package_ids_from_id (package_id);
+
+	/* install these packages with deps */
+	gpk_dbus_task_install_package_ids (dtask);
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -2260,24 +1279,21 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_provide_files (GpkDbusTask *task, gchar **full_paths)
+gpk_dbus_task_install_provide_files (GpkDbusTask *dtask, gchar **full_paths)
 {
 	gboolean ret;
-	GError *error = NULL;
-	GError *error_local = NULL;
+	GError *error_dbus = NULL;
 	guint len;
 	guint i;
 	gchar *text;
 	gchar *message;
 	GString *string;
 
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (full_paths != NULL);
 
-	task->priv->role = GPK_DBUS_TASK_ROLE_INSTALL_PROVIDE_FILES;
-
 	/* optional */
-	if (!task->priv->show_confirm_search) {
+	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
 		goto skip_checks;
 	}
@@ -2304,131 +1320,44 @@ gpk_dbus_task_install_provide_files (GpkDbusTask *task, gchar **full_paths)
 				   ngettext ("Do you want to search for this file now?", "Do you want to search for these files now?", len));
 
 	/* make title using application name */
-	if (task->priv->parent_title != NULL) {
+	if (dtask->priv->parent_title != NULL) {
 		/* TRANSLATORS: string is a program name, e.g. "Movie Player" */
-		text = g_strdup_printf (ngettext ("%s wants to install a file", "%s wants to install files", len), task->priv->parent_title);
+		text = g_strdup_printf (ngettext ("%s wants to install a file", "%s wants to install files", len), dtask->priv->parent_title);
 	} else {
 		/* TRANSLATORS: a random program which we can't get the name wants to do something */
 		text = g_strdup (ngettext ("A program wants to install a file", "A program wants to install files", len));
 	}
 
 	/* TRANSLATORS: button: confirm to search for packages */
-	ret = gpk_dbus_task_confirm_action (task, text, message, _("Install"));
+	ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Install"));
 	g_free (text);
 	g_free (message);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 skip_checks:
 	/* TRANSLATORS: searching for the package that provides the file */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Searching for file"));
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_WAIT);
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this is an internal error, and should not be seen */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for file"));
+	gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
 
 	/* do search */
-	ret = pk_client_search_file (task->priv->client_primary,
-				     pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH,
-							     PK_FILTER_ENUM_NEWEST, -1),
-				     full_paths[0], &error_local);
-	if (!ret) {
-		/* TRANSLATORS: we failed to find the package, this shouldn't happen */
-		gpk_dbus_task_error_msg (task, _("Failed to search for file"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
+	pk_client_search_file_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1), full_paths, NULL,
+			             (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				     (GAsyncReadyCallback) gpk_dbus_task_install_provide_files_search_file_cb, dtask);
 
 	/* wait for async reply */
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
-}
-
-/**
- * gpk_dbus_task_install_gstreamer_codec_part:
- **/
-static PkPackageObj *
-gpk_dbus_task_install_gstreamer_codec_part (GpkDbusTask *task, const gchar *codec_name, const gchar *codec_desc, GError **error)
-{
-	PkPackageList *list = NULL;
-	gboolean ret;
-	PkPackageObj *new_obj = NULL;
-	const PkPackageObj *obj;
-	guint len;
-	gchar *title;
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, error);
-	if (!ret)
-		return NULL;
-
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
-
-	/* TRANSLATORS: title, searching for codecs */
-	title = g_strdup_printf (_("Searching for plugin: %s"), codec_name);
-	gpk_modal_dialog_set_message (task->priv->dialog, title);
-	g_free (title);
-
-	/* get codec packages, FIXME: synchronous! */
-	pk_client_set_synchronous (task->priv->client_primary, TRUE, NULL);
-	ret = pk_client_what_provides (task->priv->client_primary,
-				       pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED,
-							       PK_FILTER_ENUM_ARCH,
-							       PK_FILTER_ENUM_NEWEST, -1),
-				       PK_PROVIDES_ENUM_CODEC, codec_desc, error);
-	pk_client_set_synchronous (task->priv->client_primary, FALSE, NULL);
-	if (!ret)
-		return NULL;
-
-	list = pk_client_get_package_list (task->priv->client_primary);
-	len = pk_package_list_get_size (list);
-
-	/* found nothing? */
-	if (len == 0) {
-		*error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "failed to find: %s", codec_desc);
-		goto out;
-	}
-
-	/* gstreamer-ffmpeg and gstreamer-plugins-ugly both provide mp3 playback, choose one */
-	if (len > 1)
-		egg_warning ("choosing one of the provides as more than one match");
-
-	/* always use the first one */
-	obj = pk_package_list_get_obj (list, 0);
-	if (obj == NULL)
-		egg_error ("obj cannot be NULL");
-
-	/* copy the object */
-	new_obj = pk_package_obj_copy (obj);
-out:
-	if (list != NULL)
-		g_object_unref (list);
-	return new_obj;
+	return;
 }
 
 /**
  * gpk_dbus_task_install_gstreamer_resources_confirm:
  **/
 static gboolean
-gpk_dbus_task_install_gstreamer_resources_confirm (GpkDbusTask *task, gchar **codec_names)
+gpk_dbus_task_install_gstreamer_resources_confirm (GpkDbusTask *dtask, gchar **codec_names)
 {
 	guint i;
 	guint len;
@@ -2482,19 +1411,19 @@ gpk_dbus_task_install_gstreamer_resources_confirm (GpkDbusTask *task, gchar **co
 	message = g_string_free (string, FALSE);
 
 	/* make title using application name */
-	if (task->priv->parent_title != NULL) {
+	if (dtask->priv->parent_title != NULL) {
 		if (is_decoder && !is_encoder) {
 			/* TRANSLATORS: a program wants to decode something (unknown) -- string is a program name, e.g. "Movie Player" */
 			title = g_strdup_printf (ngettext ("%s requires an additional plugin to decode this file",
-							   "%s requires additional plugins to decode this file", len), task->priv->parent_title);
+							   "%s requires additional plugins to decode this file", len), dtask->priv->parent_title);
 		} else if (!is_decoder && is_encoder) {
 			/* TRANSLATORS: a program wants to encode something (unknown) -- string is a program name, e.g. "Movie Player" */
 			title = g_strdup_printf (ngettext ("%s requires an additional plugin to encode this file",
-							   "%s requires additional plugins to encode this file", len), task->priv->parent_title);
+							   "%s requires additional plugins to encode this file", len), dtask->priv->parent_title);
 		} else {
 			/* TRANSLATORS: a program wants to do something (unknown) -- string is a program name, e.g. "Movie Player" */
 			title = g_strdup_printf (ngettext ("%s requires an additional plugin for this operation",
-							   "%s requires additional plugins for this operation", len), task->priv->parent_title);
+							   "%s requires additional plugins for this operation", len), dtask->priv->parent_title);
 		}
 	} else {
 		if (is_decoder && !is_encoder) {
@@ -2513,7 +1442,7 @@ gpk_dbus_task_install_gstreamer_resources_confirm (GpkDbusTask *task, gchar **co
 	}
 
 	/* TRANSLATORS: button: confirm to search for packages */
-	ret = gpk_dbus_task_confirm_action (task, title, message, _("Search"));
+	ret = gpk_dbus_task_confirm_action (dtask, title, message, _("Search"));
 	g_free (title);
 	g_free (message);
 
@@ -2521,144 +1450,256 @@ gpk_dbus_task_install_gstreamer_resources_confirm (GpkDbusTask *task, gchar **co
 }
 
 /**
+ * gpk_dbus_task_codec_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_codec_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+	GError *error = NULL;
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GtkResponseType button;
+	gchar *info_url;
+	const gchar *title;
+	const gchar *message;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* get results */
+	array = pk_results_get_package_array (results);
+
+	/* found nothing? */
+	if (array->len == 0) {
+		if (dtask->priv->show_warning) {
+			info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_CODEC);
+			/* only show the "more info" button if there is a valid link */
+			if (info_url != NULL)
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+			else
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			/* TRANSLATORS: failed to search for codec */
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to search for plugin"));
+			/* TRANSLATORS: no software sources have the wanted codec */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("Could not find plugin in any configured software source"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-package-not-found");
+
+			/* TRANSLATORS: button text */
+			gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			button = gpk_modal_dialog_run (dtask->priv->dialog);
+			if (button == GTK_RESPONSE_OK)
+				gpk_gnome_open (info_url);
+			g_free (info_url);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "failed to find codec");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* optional */
+	if (!dtask->priv->show_confirm_deps) {
+		egg_debug ("skip confirm as not allowed to interact with user");
+		goto skip_checks2;
+	}
+
+	title = ngettext ("Install the following plugin", "Install the following plugins", array->len);
+	message = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", array->len);
+
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+	gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+	gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-information");
+	/* TRANSLATORS: button: install codecs */
+	gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+	gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+	button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+	/* close, we're going to fail the method */
+	if (button != GTK_RESPONSE_OK) {
+		gpk_modal_dialog_close (dtask->priv->dialog);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to download");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+skip_checks2:
+	/* install with deps */
+	dtask->priv->package_ids = pk_package_array_to_strv (array);
+	gpk_dbus_task_install_package_ids (dtask);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_dbus_task_install_gstreamer_resources:
  * @task: a valid #GpkDbusTask instance
  * @codecs: a codec_type such as <literal>application/text</literal>
  * @error: a %GError to put the error code and message in, or %NULL
  *
- * Install a application to handle a mime type
+ * Install a application to handle a gstreamer request
  *
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *task, gchar **codec_names)
+gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *dtask, gchar **codec_names)
 {
 	gboolean ret = TRUE;
-	GError *error = NULL;
-	GError *error_local = NULL;
-	guint i;
-	guint len;
-	PkPackageObj *obj_new;
-	gchar **parts;
-	GtkResponseType button;
-	gchar *info_url;
-	PkPackageList *list = NULL;
-	const gchar *title;
-	const gchar *message;
+	GError *error_dbus = NULL;
+	gchar **parts = NULL;
+	gchar *message = NULL;
 
 	/* check it's not session wide banned in gconf */
-	ret = gconf_client_get_bool (task->priv->gconf_client, GPK_CONF_ENABLE_CODEC_HELPER, NULL);
+	ret = gconf_client_get_bool (dtask->priv->gconf_client, GPK_CONF_ENABLE_CODEC_HELPER, NULL);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FORBIDDEN, "not enabled in GConf : %s", GPK_CONF_ENABLE_CODEC_HELPER);
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FORBIDDEN, "not enabled in GConf : %s", GPK_CONF_ENABLE_CODEC_HELPER);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 	/* optional */
-	if (!task->priv->show_confirm_search) {
+	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
 		goto skip_checks;
 	}
 
 	/* confirm */
-	ret = gpk_dbus_task_install_gstreamer_resources_confirm (task, codec_names);
+	ret = gpk_dbus_task_install_gstreamer_resources_confirm (dtask, codec_names);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 skip_checks:
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
 	/* TRANSLATORS: search for codec */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Searching for plugins"));
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_WAIT);
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-finding-packages");
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for plugins"));
+	gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-finding-packages");
 
 	/* setup the UI */
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present (dtask->priv->dialog);
 
-	/* save the objects to download in a list */
-	list = pk_package_list_new ();
+	/* get the request */
+	parts = g_strsplit (codec_names[0], "|", 2);
 
-	len = g_strv_length (codec_names);
-	for (i=0; i<len; i++) {
-		parts = g_strsplit (codec_names[i], "|", 2);
-		if (g_strv_length (parts) != 2) {
-			egg_warning ("invalid line '%s', expecting a | delimiter", codec_names[i]);
-			continue;
-		}
-		obj_new = gpk_dbus_task_install_gstreamer_codec_part (task, parts[0], parts[1], &error_local);
-		if (obj_new == NULL) {
-			if (task->priv->show_warning) {
-				info_url = gpk_vendor_get_not_found_url (task->priv->vendor, GPK_VENDOR_URL_TYPE_CODEC);
-				/* only show the "more info" button if there is a valid link */
-				if (info_url != NULL)
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
-				else
-					gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-				/* TRANSLATORS: failed to search for codec */
-				gpk_modal_dialog_set_title (task->priv->dialog, _("Failed to search for plugin"));
-				/* TRANSLATORS: no software sources have the wanted codec */
-				gpk_modal_dialog_set_message (task->priv->dialog, _("Could not find plugin in any configured software source"));
-				gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-package-not-found");
-
-				/* TRANSLATORS: button text */
-				gpk_modal_dialog_set_action (task->priv->dialog, _("More information"));
-				gpk_modal_dialog_present (task->priv->dialog);
-				button = gpk_modal_dialog_run (task->priv->dialog);
-				if (button == GTK_RESPONSE_OK)
-					gpk_gnome_open (info_url);
-				g_free (info_url);
-			}
-			error = g_error_new (GPK_DBUS_ERROR, error_local->code, "%s", error_local->message);
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
-		pk_obj_list_add (PK_OBJ_LIST(list), obj_new);
-		pk_package_obj_free (obj_new);
-		g_strfreev (parts);
-	}
+	/* TRANSLATORS: title, searching for codecs */
+	message = g_strdup_printf (_("Searching for plugin: %s"), parts[1]);
+	gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+
+	/* get codec packages */
+	pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+				       PK_PROVIDES_ENUM_CODEC, parts, NULL,
+			               (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				       (GAsyncReadyCallback) gpk_dbus_task_codec_what_provides_cb, dtask);
+out:
+	g_strfreev (parts);
+	g_free (message);
+}
 
-	/* optional */
-	if (!task->priv->show_confirm_deps) {
-		egg_debug ("skip confirm as not allowed to interact with user");
-		goto skip_checks2;
+/**
+ * gpk_dbus_task_mime_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_mime_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+	GError *error = NULL;
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+	gchar *info_url;
+	GtkResponseType button;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		/* TRANSLATORS: we failed to find the package, this shouldn't happen */
+		gpk_dbus_task_error_msg (dtask, _("Failed to search for provides"), error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
+		goto out;
 	}
 
-	title = ngettext ("Install the following plugin", "Install the following plugins", len);
-	message = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", len);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to resolve: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
 
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
-	gpk_modal_dialog_set_package_list (task->priv->dialog, list);
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	gpk_modal_dialog_set_message (task->priv->dialog, message);
-	gpk_modal_dialog_set_image (task->priv->dialog, "dialog-information");
-	/* TRANSLATORS: button: install codecs */
-	gpk_modal_dialog_set_action (task->priv->dialog, _("Install"));
-	gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	button = gpk_modal_dialog_run (task->priv->dialog);
+	/* get results */
+	array = pk_results_get_package_array (results);
 
-	/* close, we're going to fail the method */
-	if (button != GTK_RESPONSE_OK) {
-		gpk_modal_dialog_close (task->priv->dialog);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to download");
-		dbus_g_method_return_error (task->priv->context, error);
+	/* found nothing? */
+	if (array->len == 0) {
+		if (dtask->priv->show_warning) {
+			info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_MIME);
+			/* only show the "more info" button if there is a valid link */
+			if (info_url != NULL)
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+			else
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			/* TRANSLATORS: title */
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to find software"));
+			/* TRANSLATORS: nothing found in the software sources that helps */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("No new applications can be found to handle this type of file"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-package-not-found");
+			/* TRANSLATORS: button: show the user a button to get more help finding stuff */
+			gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			button = gpk_modal_dialog_run (dtask->priv->dialog);
+			if (button == GTK_RESPONSE_OK)
+				gpk_gnome_open (info_url);
+			g_free (info_url);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "nothing was found to handle mime type");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-skip_checks2:
-	/* install with deps */
-	task->priv->package_ids = pk_package_list_to_strv (list);
-	gpk_dbus_task_install_package_ids_dep_check (task);
+	/* populate a chooser */
+	gpk_helper_chooser_show (dtask->priv->helper_chooser, array);
+
+	egg_debug ("doing async return");
+	dbus_g_method_return (dtask->priv->context, TRUE);
 out:
-	if (list != NULL)
-		g_object_unref (list);
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -2672,30 +1713,27 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_mime_types (GpkDbusTask *task, gchar **mime_types)
+gpk_dbus_task_install_mime_types (GpkDbusTask *dtask, gchar **mime_types)
 {
 	gboolean ret;
-	GError *error = NULL;
-	GError *error_local = NULL;
+	GError *error_dbus = NULL;
 	guint len;
-	gchar *message;
-	gchar *text;
+	gchar *message = NULL;
+	gchar *text = NULL;
 
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (mime_types != NULL);
 
-	task->priv->role = GPK_DBUS_TASK_ROLE_INSTALL_MIME_TYPES;
-
 	/* check it's not session wide banned in gconf */
-	ret = gconf_client_get_bool (task->priv->gconf_client, GPK_CONF_ENABLE_MIME_TYPE_HELPER, NULL);
+	ret = gconf_client_get_bool (dtask->priv->gconf_client, GPK_CONF_ENABLE_MIME_TYPE_HELPER, NULL);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FORBIDDEN, "not enabled in GConf : %s", GPK_CONF_ENABLE_MIME_TYPE_HELPER);
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FORBIDDEN, "not enabled in GConf : %s", GPK_CONF_ENABLE_MIME_TYPE_HELPER);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 	/* optional */
-	if (!task->priv->show_confirm_search) {
+	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
 		goto skip_checks;
 	}
@@ -2712,68 +1750,42 @@ gpk_dbus_task_install_mime_types (GpkDbusTask *task, gchar **mime_types)
 	len = 1;
 
 	/* make title using application name */
-	if (task->priv->parent_title != NULL) {
+	if (dtask->priv->parent_title != NULL) {
 		/* TRANSLATORS: string is a program name, e.g. "Movie Player" */
-		text = g_strdup_printf (ngettext ("%s requires a new mime type", "%s requires new mime types", len), task->priv->parent_title);
+		text = g_strdup_printf (ngettext ("%s requires a new mime type", "%s requires new mime types", len), dtask->priv->parent_title);
 	} else {
 		/* TRANSLATORS: a random program which we can't get the name wants to do something */
 		text = g_strdup (ngettext ("A program requires a new mime type", "A program requires new mime types", len));
 	}
 
 	/* TRANSLATORS: button: confirm to search for packages */
-	ret = gpk_dbus_task_confirm_action (task, text, message, _("Search"));
-	g_free (text);
-	g_free (message);
+	ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Search"));
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 skip_checks:
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
 	/* TRANSLATORS: title: searching for mime type handlers */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Searching for file handlers"));
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_WAIT);
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-finding-packages");
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for file handlers"));
+	gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-finding-packages");
 
 	/* setup the UI */
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* reset */
-	ret = pk_client_reset (task->priv->client_primary, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: this is an internal error, and should not be seen */
-		gpk_dbus_task_error_msg (task, _("Failed to reset client"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present (dtask->priv->dialog);
 
 	/* action */
-	ret = pk_client_what_provides (task->priv->client_primary,
-				       pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED,
-							       PK_FILTER_ENUM_ARCH,
-							       PK_FILTER_ENUM_NEWEST, -1),
-				       PK_PROVIDES_ENUM_MIMETYPE, mime_types[0], &error_local);
-	if (!ret) {
-		/* TRANSLATORS: we failed to find the package, this shouldn't happen */
-		gpk_dbus_task_error_msg (task, _("Failed to search for provides"), error_local);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
+	pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+				       PK_PROVIDES_ENUM_MIMETYPE, mime_types, NULL,
+			               (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				       (GAsyncReadyCallback) gpk_dbus_task_mime_what_provides_cb, dtask);
 	/* wait for async reply */
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
+	g_free (text);
+	g_free (message);
 }
 
 /**
@@ -2827,7 +1839,7 @@ out:
  * gpk_dbus_task_font_tag_to_localised_name:
  **/
 static gchar *
-gpk_dbus_task_font_tag_to_localised_name (GpkDbusTask *task, const gchar *tag)
+gpk_dbus_task_font_tag_to_localised_name (GpkDbusTask *dtask, const gchar *tag)
 {
 	gchar *lang;
 	gchar *language = NULL;
@@ -2842,7 +1854,7 @@ gpk_dbus_task_font_tag_to_localised_name (GpkDbusTask *task, const gchar *tag)
 	}
 
 	/* convert to localisable name */
-	language = gpk_language_iso639_to_language (task->priv->language, lang);
+	language = gpk_language_iso639_to_language (dtask->priv->language, lang);
 	if (language == NULL) {
 		/* TRANSLATORS: we could not find en_US string for ISO639 code */
 		name = g_strdup_printf ("%s: %s", _("Language code not matched"), lang);
@@ -2860,6 +1872,113 @@ out:
 }
 
 /**
+ * gpk_dbus_task_fontconfig_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_fontconfig_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+	GError *error = NULL;
+	GError *error_dbus = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	PkItemErrorCode *error_item = NULL;
+	gchar *title;
+	gchar *info_url;
+	GtkResponseType button;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		/* TRANSLATORS: we failed to find the package, this shouldn't happen */
+//		gpk_dbus_task_error_msg (dtask, _("Failed to search for provides"), error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to search for provides: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		egg_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		/* TRANSLATORS: we failed to find the package, this shouldn't happen */
+//		gpk_dbus_task_error_msg (dtask, _("Failed to search for provides"), error_item->details);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "failed to search for provides: %s", error_item->details);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* get results */
+	array = pk_results_get_package_array (results);
+
+	/* found nothing? */
+	if (array->len == 0) {
+		if (dtask->priv->show_warning) {
+			info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_FONT);
+			/* TRANSLATORS: title: cannot find in sources */
+			title = ngettext ("Failed to find font", "Failed to find fonts", array->len);
+			/* only show the "more info" button if there is a valid link */
+			if (info_url != NULL)
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+			else
+				gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+			/* TRANSLATORS: message: tell the user we suck */
+			gpk_modal_dialog_set_message (dtask->priv->dialog, _("No new fonts can be found for this document"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-package-not-found");
+			/* TRANSLATORS: button: show the user a button to get more help finding stuff */
+			gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+			gpk_modal_dialog_present (dtask->priv->dialog);
+			button = gpk_modal_dialog_run (dtask->priv->dialog);
+			if (button == GTK_RESPONSE_OK)
+				gpk_gnome_open (info_url);
+			g_free (info_url);
+		}
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "failed to find font");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+	/* optional */
+	if (!dtask->priv->show_confirm_deps) {
+		egg_debug ("skip confirm as not allowed to interact with user");
+		goto skip_checks;
+	}
+
+	/* TRANSLATORS: title: show a list of fonts */
+	title = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", array->len);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+	gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_message (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-information");
+	/* TRANSLATORS: button: install a font */
+	gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+	gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+	button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+	/* close, we're going to fail the method */
+	if (button != GTK_RESPONSE_OK) {
+		gpk_modal_dialog_close (dtask->priv->dialog);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to download");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		goto out;
+	}
+
+skip_checks:
+	/* convert to list of package id's */
+	dtask->priv->package_ids = pk_package_array_to_strv (array);
+	gpk_dbus_task_install_package_ids (dtask);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_dbus_task_install_fontconfig_resources:
  * @task: a valid #GpkDbusTask instance
  * @fonts: font description such as <literal>lang:fr</literal>
@@ -2870,15 +1989,13 @@ out:
  * Return value: %TRUE if the method succeeded
  **/
 void
-gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *task, gchar **fonts)
+gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask, gchar **fonts)
 {
 	gboolean ret;
-	PkPackageList *list = NULL;
-	PkPackageList *list_tmp = NULL;
-	GtkResponseType button;
-	gchar *info_url;
-	GError *error = NULL;
-	GError *error_local = NULL;
+	GPtrArray *array = NULL;
+//	GtkResponseType button;
+//	gchar *info_url;
+	GError *error_dbus = NULL;
 	guint i;
 	guint len;
 	guint size;
@@ -2888,22 +2005,22 @@ gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *task, gchar **fonts)
 	const gchar *title_part;
 	GString *string;
 
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
+	g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
 	g_return_if_fail (fonts != NULL);
 
 	/* get number of fonts to install */
 	len = g_strv_length (fonts);
 
 	/* check it's not session wide banned in gconf */
-	ret = gconf_client_get_bool (task->priv->gconf_client, GPK_CONF_ENABLE_FONT_HELPER, NULL);
+	ret = gconf_client_get_bool (dtask->priv->gconf_client, GPK_CONF_ENABLE_FONT_HELPER, NULL);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FORBIDDEN, "not enabled in GConf : %s", GPK_CONF_ENABLE_FONT_HELPER);
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FORBIDDEN, "not enabled in GConf : %s", GPK_CONF_ENABLE_FONT_HELPER);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 	/* optional */
-	if (!task->priv->show_confirm_search) {
+	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
 		goto skip_checks;
 	}
@@ -2912,15 +2029,15 @@ gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *task, gchar **fonts)
 	for (i=0; i<len; i++) {
 		/* correct prefix */
 		if (!g_str_has_prefix (fonts[i], ":lang=")) {
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "not recognised prefix: '%s'", fonts[i]);
-			dbus_g_method_return_error (task->priv->context, error);
+			error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "not recognised prefix: '%s'", fonts[i]);
+			dbus_g_method_return_error (dtask->priv->context, error_dbus);
 			goto out;
 		}
 		/* no lang code */
 		size = strlen (fonts[i]);
 		if (size < 7 || size > 20) {
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "lang tag malformed: '%s'", fonts[i]);
-			dbus_g_method_return_error (task->priv->context, error);
+			error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "lang tag malformed: '%s'", fonts[i]);
+			dbus_g_method_return_error (dtask->priv->context, error_dbus);
 			goto out;
 		}
 	}
@@ -2929,12 +2046,12 @@ gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *task, gchar **fonts)
 
 	/* don't use a bullet for one item */
 	if (len == 1) {
-		text = gpk_dbus_task_font_tag_to_localised_name (task, fonts[0]);
+		text = gpk_dbus_task_font_tag_to_localised_name (dtask, fonts[0]);
 		g_string_append_printf (string, "%s\n", text);
 		g_free (text);
 	} else {
 		for (i=0; i<len; i++) {
-			text = gpk_dbus_task_font_tag_to_localised_name (task, fonts[i]);
+			text = gpk_dbus_task_font_tag_to_localised_name (dtask, fonts[i]);
 			g_string_append_printf (string, "â?¢ %s\n", text);
 			g_free (text);
 		}
@@ -2955,187 +2072,141 @@ gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *task, gchar **fonts)
 	g_free (text);
 
 	/* make title using application name */
-	if (task->priv->parent_title != NULL) {
+	if (dtask->priv->parent_title != NULL) {
 		/* TRANSLATORS: string is a program name, e.g. "Movie Player" */
-		text = g_strdup_printf (ngettext ("%s wants to install a font", "%s wants to install fonts", len), task->priv->parent_title);
+		text = g_strdup_printf (ngettext ("%s wants to install a font", "%s wants to install fonts", len), dtask->priv->parent_title);
 	} else {
 		/* TRANSLATORS: a random program which we can't get the name wants to do something */
 		text = g_strdup (ngettext ("A program wants to install a font", "A program wants to install fonts", len));
 	}
 
 	/* TRANSLATORS: button: confirm to search for packages */
-	ret = gpk_dbus_task_confirm_action (task, text, message, _("Search"));
+	ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Search"));
 	g_free (text);
 	g_free (message);
 	if (!ret) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to search");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 skip_checks:
 	/* TRANSLATORS: title to show when searching for font files */
 	title = ngettext ("Searching for font", "Searching for fonts", len);
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	gpk_modal_dialog_set_image_status (task->priv->dialog, PK_STATUS_ENUM_WAIT);
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-finding-packages");
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-finding-packages");
 
 	/* setup the UI */
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present (dtask->priv->dialog);
 
 	/* do each one */
-	list = pk_package_list_new ();
-	for (i=0; i<len; i++) {
+	pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+				       PK_PROVIDES_ENUM_FONT, fonts, NULL,
+			               (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				       (GAsyncReadyCallback) gpk_dbus_task_fontconfig_what_provides_cb, dtask);
+out:
+	if (array != NULL)
+		g_ptr_array_unref (array);
+}
 
-		/* reset */
-		ret = pk_client_reset (task->priv->client_primary, &error_local);
-		if (!ret) {
-			/* TRANSLATORS: this is an internal error, and should not be seen */
-			gpk_dbus_task_error_msg (task, _("Failed to reset client"), error_local);
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
-		}
+/**
+ * gpk_dbus_task_catalog_lookup_cb:
+ **/
+static void
+gpk_dbus_task_catalog_lookup_cb (GObject *object, GAsyncResult *res, GpkDbusTask *dtask)
+{
+	PkCatalog *catalog = PK_CATALOG (object);
+	GError *error = NULL;
+	GError *error_dbus = NULL;
+	GPtrArray *array = NULL;
+	GtkResponseType button;
 
-		/* set timeout */
-		pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
-
-		/* action: FIXME: synchronous */
-		pk_client_set_synchronous (task->priv->client_primary, TRUE, NULL);
-		ret = pk_client_what_provides (task->priv->client_primary,
-					       pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED,
-								       PK_FILTER_ENUM_ARCH,
-								       PK_FILTER_ENUM_NEWEST, -1),
-					       PK_PROVIDES_ENUM_FONT, fonts[i], &error_local);
-		pk_client_set_synchronous (task->priv->client_primary, FALSE, NULL);
-		if (!ret) {
-			/* TRANSLATORS: we failed to find the package, this shouldn't happen */
-			gpk_dbus_task_error_msg (task, _("Failed to search for provides"), error_local);
-			error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_INTERNAL_ERROR, "%s", error_local->message);
-			dbus_g_method_return_error (task->priv->context, error);
-			goto out;
+	/* get the results */
+	array = pk_catalog_lookup_finish (catalog, res, &error);
+	if (array == NULL) {
+		if (dtask->priv->show_warning) {
+			/* TRANSLATORS: title: we've already got all these packages installed */
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("Could not process catalog"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, NULL);
+			gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+			gpk_modal_dialog_run (dtask->priv->dialog);
 		}
-
-		/* add to main list */
-		list_tmp = pk_client_get_package_list (task->priv->client_primary);
-		pk_obj_list_add_list (PK_OBJ_LIST (list), PK_OBJ_LIST (list_tmp));
-		g_object_unref (list_tmp);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "failed to parse catalog: %s", error->message);
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
+		g_error_free (error);
+		goto out;
 	}
 
-	/* found nothing? */
-	len = pk_package_list_get_size (list);
-	if (len == 0) {
-		if (task->priv->show_warning) {
-			info_url = gpk_vendor_get_not_found_url (task->priv->vendor, GPK_VENDOR_URL_TYPE_FONT);
-			/* TRANSLATORS: title: cannot find in sources */
-			title = ngettext ("Failed to find font", "Failed to find fonts", len);
-			/* only show the "more info" button if there is a valid link */
-			if (info_url != NULL)
-				gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
-			else
-				gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-			gpk_modal_dialog_set_title (task->priv->dialog, title);
-			/* TRANSLATORS: message: tell the user we suck */
-			gpk_modal_dialog_set_message (task->priv->dialog, _("No new fonts can be found for this document"));
-			gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-package-not-found");
-			/* TRANSLATORS: button: show the user a button to get more help finding stuff */
-			gpk_modal_dialog_set_action (task->priv->dialog, _("More information"));
-			gpk_modal_dialog_present (task->priv->dialog);
-			button = gpk_modal_dialog_run (task->priv->dialog);
-			if (button == GTK_RESPONSE_OK)
-				gpk_gnome_open (info_url);
-			g_free (info_url);
+	/* nothing to do? */
+	if (array->len == 0) {
+		/* show UI */
+		if (dtask->priv->show_warning) {
+			/* TRANSLATORS: title: we've already got all these packages installed */
+			gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+			gpk_modal_dialog_set_title (dtask->priv->dialog, _("No packages need to be installed"));
+			gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-catalog-none-required");
+			gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+			gpk_modal_dialog_run (dtask->priv->dialog);
 		}
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_NO_PACKAGES_FOUND, "failed to find font");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "No packages need to be installed");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 	/* optional */
-	if (!task->priv->show_confirm_deps) {
+	if (!dtask->priv->show_confirm_deps) {
 		egg_debug ("skip confirm as not allowed to interact with user");
-		goto skip_checks2;
+		goto skip_checks;
 	}
 
-	/* TRANSLATORS: title: show a list of fonts */
-	title = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", len);
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
-	gpk_modal_dialog_set_package_list (task->priv->dialog, list);
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	gpk_modal_dialog_set_message (task->priv->dialog, title);
-	gpk_modal_dialog_set_image (task->priv->dialog, "dialog-information");
-	/* TRANSLATORS: button: install a font */
-	gpk_modal_dialog_set_action (task->priv->dialog, _("Install"));
-	gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	button = gpk_modal_dialog_run (task->priv->dialog);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+	/* TRANSLATORS: title: allow user to confirm */
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Install packages in catalog?"));
+	/* TRANSLATORS: display a list of packages to install */
+	gpk_modal_dialog_set_message (dtask->priv->dialog, _("The following packages are marked to be installed from the catalog:"));
+	gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-question");
+	gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+	/* TRANSLATORS: button: install packages in catalog */
+	gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+	gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+	button = gpk_modal_dialog_run (dtask->priv->dialog);
 
-	/* close, we're going to fail the method */
+	/* did we click no or exit the window? */
 	if (button != GTK_RESPONSE_OK) {
-		gpk_modal_dialog_close (task->priv->dialog);
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to download");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "Action was cancelled");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
-skip_checks2:
+skip_checks:
 	/* convert to list of package id's */
-	task->priv->package_ids = pk_package_list_to_strv (list);
-	gpk_dbus_task_install_package_ids_dep_check (task);
-
+	dtask->priv->package_ids = pk_package_array_to_strv (array);
+	gpk_dbus_task_install_package_ids (dtask);
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (error_local != NULL)
-		g_error_free (error_local);
-	if (list != NULL)
-		g_object_unref (list);
-}
-
-/**
- * gpk_dbus_task_catalog_progress_cb:
- **/
-static void
-gpk_dbus_task_catalog_progress_cb (PkCatalog *catalog, PkCatalogProgress mode, const gchar *text, GpkDbusTask *task)
-{
-	gchar *message = NULL;
-
-	g_return_if_fail (GPK_IS_DBUS_TASK (task));
-
-	if (mode == PK_CATALOG_PROGRESS_PACKAGES) {
-		/* TRANSLATORS: finding the package names for a catalog */
-		message = g_strdup_printf (_("Finding package name: %s"), text);
-	} else if (mode == PK_CATALOG_PROGRESS_FILES) {
-		/* TRANSLATORS: finding a package for a file for a catalog */
-		message = g_strdup_printf (_("Finding file name: %s"), text);
-	} else if (mode == PK_CATALOG_PROGRESS_PROVIDES) {
-		/* TRANSLATORS: finding a package which can provide a virtual provide */
-		message = g_strdup_printf (_("Finding a package to provide: %s"), text);
-	}
-	gpk_dbus_task_set_status (task, PK_STATUS_ENUM_QUERY);
-	gpk_modal_dialog_set_message (task->priv->dialog, message);
-	g_free (message);
+	if (array != NULL)
+		g_ptr_array_unref (array);
 }
 
 /**
  * gpk_dbus_task_install_catalogs:
  **/
 void
-gpk_dbus_task_install_catalogs (GpkDbusTask *task, gchar **filenames)
+gpk_dbus_task_install_catalogs (GpkDbusTask *dtask, gchar **filenames)
 {
-	GError *error = NULL;
+	GError *error_dbus = NULL;
 	GtkResponseType button;
-	gchar *message;
+	gchar *message = NULL;
 	const gchar *title;
-	PkPackageList *list = NULL;
-	PkCatalog *catalog;
 	guint len;
 
 	len = g_strv_length (filenames);
 
 	/* optional */
-	if (!task->priv->show_confirm_search) {
+	if (!dtask->priv->show_confirm_search) {
 		egg_debug ("skip confirm as not allowed to interact with user");
 		goto skip_checks;
 	}
@@ -3146,150 +2217,85 @@ gpk_dbus_task_install_catalogs (GpkDbusTask *task, gchar **filenames)
 	message = g_strjoinv ("\n", filenames);
 
 	/* show UI */
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
-	gpk_modal_dialog_set_title (task->priv->dialog, title);
-	gpk_modal_dialog_set_message (task->priv->dialog, message);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+	gpk_modal_dialog_set_message (dtask->priv->dialog, message);
 	/* TRANSLATORS: button: install catalog */
-	gpk_modal_dialog_set_action (task->priv->dialog, _("Install"));
-	gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-install-catalogs");
-	gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	button = gpk_modal_dialog_run (task->priv->dialog);
-	g_free (message);
+	gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+	gpk_modal_dialog_set_help_id (dtask->priv->dialog, "dialog-install-catalogs");
+	gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+	button = gpk_modal_dialog_run (dtask->priv->dialog);
 
 	/* did we click no or exit the window? */
 	if (button != GTK_RESPONSE_OK) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to install");
-		dbus_g_method_return_error (task->priv->context, error);
+		error_dbus = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "did not agree to install");
+		dbus_g_method_return_error (dtask->priv->context, error_dbus);
 		goto out;
 	}
 
 skip_checks:
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+	gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
 	/* TRANSLATORS: title: install package catalogs, that is, instructions for installing */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Install catalogs"));
-	gpk_dbus_task_set_status (task, PK_STATUS_ENUM_WAIT);
+	gpk_modal_dialog_set_title (dtask->priv->dialog, _("Install catalogs"));
+	gpk_dbus_task_set_status (dtask, PK_STATUS_ENUM_WAIT);
 
 	/* setup the UI */
-	if (task->priv->show_progress)
-		gpk_modal_dialog_present (task->priv->dialog);
-
-	/* get files to be installed */
-	catalog = pk_catalog_new ();
-	g_signal_connect (catalog, "progress", G_CALLBACK (gpk_dbus_task_catalog_progress_cb), task);
-	list = pk_catalog_process_files (catalog, filenames);
-	g_object_unref (catalog);
-
-	/* nothing to do? */
-	len = pk_package_list_get_size (list);
-	if (len == 0) {
-		/* show UI */
-		if (task->priv->show_warning) {
-			/* TRANSLATORS: title: we've already got all these packages installed */
-			gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
-			gpk_modal_dialog_set_title (task->priv->dialog, _("No packages need to be installed"));
-			gpk_modal_dialog_set_help_id (task->priv->dialog, "dialog-catalog-none-required");
-			gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-			gpk_modal_dialog_run (task->priv->dialog);
-		}
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_FAILED, "No packages need to be installed");
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-	/* optional */
-	if (!task->priv->show_confirm_deps) {
-		egg_debug ("skip confirm as not allowed to interact with user");
-		goto skip_checks2;
-	}
-
-	gpk_modal_dialog_setup (task->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
-	/* TRANSLATORS: title: allow user to confirm */
-	gpk_modal_dialog_set_title (task->priv->dialog, _("Install packages in catalog?"));
-	/* TRANSLATORS: display a list of packages to install */
-	gpk_modal_dialog_set_message (task->priv->dialog, _("The following packages are marked to be installed from the catalog:"));
-	gpk_modal_dialog_set_image (task->priv->dialog, "dialog-question");
-	gpk_modal_dialog_set_package_list (task->priv->dialog, list);
-	/* TRANSLATORS: button: install packages in catalog */
-	gpk_modal_dialog_set_action (task->priv->dialog, _("Install"));
-	gpk_modal_dialog_present_with_time (task->priv->dialog, task->priv->timestamp);
-	button = gpk_modal_dialog_run (task->priv->dialog);
-
-	/* did we click no or exit the window? */
-	if (button != GTK_RESPONSE_OK) {
-		error = g_error_new (GPK_DBUS_ERROR, GPK_DBUS_ERROR_CANCELLED, "Action was cancelled");
-		dbus_g_method_return_error (task->priv->context, error);
-		goto out;
-	}
-
-skip_checks2:
-	/* convert to list of package id's */
-	task->priv->package_ids = pk_package_list_to_strv (list);
-	gpk_dbus_task_install_package_ids_dep_check (task);
+	if (dtask->priv->show_progress)
+		gpk_modal_dialog_present (dtask->priv->dialog);
 
+	/* lookup catalog */
+	pk_catalog_lookup_async (dtask->priv->catalog, filenames[0], NULL,
+			 	 (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+				 (GAsyncReadyCallback) gpk_dbus_task_catalog_lookup_cb, dtask);
 out:
-	if (error != NULL)
-		g_error_free (error);
-	if (list != NULL)
-		g_object_unref (list);
+	g_free (message);
 }
 
 /**
  * gpk_dbus_task_get_package_for_exec:
  **/
 static gchar *
-gpk_dbus_task_get_package_for_exec (GpkDbusTask *task, const gchar *exec)
+gpk_dbus_task_get_package_for_exec (GpkDbusTask *dtask, const gchar *exec)
 {
 	gchar *package = NULL;
-	gboolean ret;
 	GError *error = NULL;
-	guint length;
-	PkPackageList *list = NULL;
-	const PkPackageObj *obj;
-
-	/* reset dbus_task */
-	ret = pk_client_reset (task->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* set timeout */
-	pk_client_set_timeout (task->priv->client_primary, task->priv->timeout, NULL);
+	GPtrArray *array = NULL;
+	const PkItemPackage *item;
+	PkResults *results = NULL;
+	gchar **values = NULL;
 
 	/* find the package name */
-	pk_client_set_synchronous (task->priv->client_primary, TRUE, NULL);
-	ret = pk_client_search_file (task->priv->client_primary, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), exec, &error);
-	pk_client_set_synchronous (task->priv->client_primary, FALSE, NULL);
-	if (!ret) {
+	values = g_strsplit (exec, "&", -1);
+	results = pk_client_search_file (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), values, NULL, NULL, NULL, &error);
+	if (results == NULL) {
 		egg_warning ("failed to search file: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
 	/* get the list of packages */
-	list = pk_client_get_package_list (task->priv->client_primary);
-	length = pk_package_list_get_size (list);
+	array = pk_results_get_package_array (results);
 
 	/* nothing found */
-	if (length == 0) {
+	if (array->len == 0) {
 		egg_debug ("cannot find installed package that provides : %s", exec);
 		goto out;
 	}
 
 	/* check we have one */
-	if (length != 1)
+	if (array->len != 1)
 		egg_warning ("not one return, using first");
 
 	/* copy name */
-	obj = pk_package_list_get_obj (list, 0);
-	package = g_strdup (obj->id->name);
+	item = g_ptr_array_index (array, 0);
+	package = g_strdup (item->package_id);
 	egg_debug ("got package %s", package);
-
 out:
-	/* use the exec name if we can't find an installed package */
-	if (list != NULL)
-		g_object_unref (list);
+	g_strfreev (values);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 	return package;
 }
 
@@ -3314,53 +2320,53 @@ gpk_dbus_task_path_is_trusted (const gchar *exec)
  * a translated name and icon.
  **/
 gboolean
-gpk_dbus_task_set_exec (GpkDbusTask *task, const gchar *exec)
+gpk_dbus_task_set_exec (GpkDbusTask *dtask, const gchar *exec)
 {
 	GpkX11 *x11;
 	gchar *package = NULL;
 
-	g_return_val_if_fail (GPK_IS_DBUS_TASK (task), FALSE);
+	g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
 
 	/* old values invalid */
-	g_free (task->priv->parent_title);
-	g_free (task->priv->parent_icon_name);
-	task->priv->parent_title = NULL;
-	task->priv->parent_icon_name = NULL;
+	g_free (dtask->priv->parent_title);
+	g_free (dtask->priv->parent_icon_name);
+	dtask->priv->parent_title = NULL;
+	dtask->priv->parent_icon_name = NULL;
 
 	/* is the binary trusted, i.e. can we probe it's window properties */
 	if (gpk_dbus_task_path_is_trusted (exec)) {
 		egg_debug ("using application window properties");
 		/* get from window properties */
 		x11 = gpk_x11_new ();
-		gpk_x11_set_window (x11, task->priv->parent_window);
-		task->priv->parent_title = gpk_x11_get_title (x11);
+		gpk_x11_set_window (x11, dtask->priv->parent_window);
+		dtask->priv->parent_title = gpk_x11_get_title (x11);
 		g_object_unref (x11);
 		goto out;
 	}
 
 	/* get from installed database */
-	package = gpk_dbus_task_get_package_for_exec (task, exec);
+	package = gpk_dbus_task_get_package_for_exec (dtask, exec);
 	egg_debug ("got package %s", package);
 
 	/* try to get from PkDesktop */
 	if (package != NULL) {
-		task->priv->parent_title = gpk_desktop_guess_localised_name (task->priv->desktop, package);
-		task->priv->parent_icon_name = gpk_desktop_guess_icon_name (task->priv->desktop, package);
+		dtask->priv->parent_title = gpk_desktop_guess_localised_name (dtask->priv->desktop, package);
+		dtask->priv->parent_icon_name = gpk_desktop_guess_icon_name (dtask->priv->desktop, package);
 		/* fallback to package name */
-		if (task->priv->parent_title == NULL) {
+		if (dtask->priv->parent_title == NULL) {
 			egg_debug ("did not get localised description for %s", package);
-			task->priv->parent_title = g_strdup (package);
+			dtask->priv->parent_title = g_strdup (package);
 		}
 	}
 
 	/* fallback to exec - eugh... */
-	if (task->priv->parent_title == NULL) {
+	if (dtask->priv->parent_title == NULL) {
 		egg_debug ("did not get package for %s, using exec basename", package);
-		task->priv->parent_title = g_path_get_basename (exec);
+		dtask->priv->parent_title = g_path_get_basename (exec);
 	}
 out:
 	g_free (package);
-	egg_debug ("got name=%s, icon=%s", task->priv->parent_title, task->priv->parent_icon_name);
+	egg_debug ("got name=%s, icon=%s", dtask->priv->parent_title, dtask->priv->parent_icon_name);
 	return TRUE;
 }
 
@@ -3381,31 +2387,29 @@ gpk_dbus_task_class_init (GpkDbusTaskClass *klass)
  * @task: a valid #GpkDbusTask instance
  **/
 static void
-gpk_dbus_task_init (GpkDbusTask *task)
+gpk_dbus_task_init (GpkDbusTask *dtask)
 {
 	gboolean ret;
 	GtkWindow *main_window;
 
-	task->priv = GPK_DBUS_TASK_GET_PRIVATE (task);
-
-	task->priv->package_ids = NULL;
-	task->priv->files = NULL;
-	task->priv->parent_window = NULL;
-	task->priv->parent_title = NULL;
-	task->priv->parent_icon_name = NULL;
-	task->priv->error_details = NULL;
-	task->priv->context = NULL;
-	task->priv->exit = PK_EXIT_ENUM_FAILED;
-	task->priv->show_confirm_search = TRUE;
-	task->priv->show_confirm_deps = TRUE;
-	task->priv->show_confirm_install = TRUE;
-	task->priv->show_progress = TRUE;
-	task->priv->show_finished = TRUE;
-	task->priv->show_warning = TRUE;
-	task->priv->timestamp = 0;
-	task->priv->timeout = -1;
-	task->priv->last_exit_code = PK_ERROR_ENUM_UNKNOWN;
-	task->priv->role = GPK_DBUS_TASK_ROLE_UNKNOWN;
+	dtask->priv = GPK_DBUS_TASK_GET_PRIVATE (dtask);
+
+	dtask->priv->package_ids = NULL;
+	dtask->priv->files = NULL;
+	dtask->priv->parent_window = NULL;
+	dtask->priv->parent_title = NULL;
+	dtask->priv->parent_icon_name = NULL;
+	dtask->priv->cached_error_code = NULL;
+	dtask->priv->context = NULL;
+	dtask->priv->cancellable = g_cancellable_new ();
+	dtask->priv->exit = PK_EXIT_ENUM_FAILED;
+	dtask->priv->show_confirm_search = TRUE;
+	dtask->priv->show_confirm_deps = TRUE;
+	dtask->priv->show_confirm_install = TRUE;
+	dtask->priv->show_progress = TRUE;
+	dtask->priv->show_finished = TRUE;
+	dtask->priv->show_warning = TRUE;
+	dtask->priv->timestamp = 0;
 
 	/* add application specific icons to search path */
 	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
@@ -3415,79 +2419,39 @@ gpk_dbus_task_init (GpkDbusTask *task)
 	if (!notify_is_initted ())
 		notify_init ("gpk-dbus_task");
 
-	task->priv->vendor = gpk_vendor_new ();
-	task->priv->dialog = gpk_modal_dialog_new ();
-	main_window = gpk_modal_dialog_get_window (task->priv->dialog);
-	gpk_modal_dialog_set_window_icon (task->priv->dialog, "pk-package-installed");
-	g_signal_connect (task->priv->dialog, "cancel",
-			  G_CALLBACK (gpk_dbus_task_button_cancel_cb), task);
-	g_signal_connect (task->priv->dialog, "close",
-			  G_CALLBACK (gpk_dbus_task_button_close_cb), task);
+	dtask->priv->vendor = gpk_vendor_new ();
+	dtask->priv->dialog = gpk_modal_dialog_new ();
+	main_window = gpk_modal_dialog_get_window (dtask->priv->dialog);
+	gpk_modal_dialog_set_window_icon (dtask->priv->dialog, "pk-package-installed");
+	g_signal_connect (dtask->priv->dialog, "cancel",
+			  G_CALLBACK (gpk_dbus_task_button_cancel_cb), dtask);
+	g_signal_connect (dtask->priv->dialog, "close",
+			  G_CALLBACK (gpk_dbus_task_button_close_cb), dtask);
 
 	/* helpers */
-	task->priv->helper_repo_signature = gpk_helper_repo_signature_new ();
-	g_signal_connect (task->priv->helper_repo_signature, "event", G_CALLBACK (gpk_dbus_task_repo_signature_event_cb), task);
-	gpk_helper_repo_signature_set_parent (task->priv->helper_repo_signature, main_window);
-
-	task->priv->helper_eula = gpk_helper_eula_new ();
-	g_signal_connect (task->priv->helper_eula, "event", G_CALLBACK (gpk_dbus_task_eula_event_cb), task);
-	gpk_helper_eula_set_parent (task->priv->helper_eula, main_window);
+	dtask->priv->helper_run = gpk_helper_run_new ();
+	gpk_helper_run_set_parent (dtask->priv->helper_run, main_window);
 
-	task->priv->helper_run = gpk_helper_run_new ();
-	gpk_helper_run_set_parent (task->priv->helper_run, main_window);
-
-#if (!PK_CHECK_VERSION(0,5,0))
-	task->priv->helper_untrusted = gpk_helper_untrusted_new ();
-	g_signal_connect (task->priv->helper_untrusted, "event", G_CALLBACK (gpk_dbus_task_untrusted_event_cb), task);
-	gpk_helper_untrusted_set_parent (task->priv->helper_untrusted, main_window);
-#endif
-
-	task->priv->helper_chooser = gpk_helper_chooser_new ();
-	g_signal_connect (task->priv->helper_chooser, "event", G_CALLBACK (gpk_dbus_task_chooser_event_cb), task);
-	gpk_helper_chooser_set_parent (task->priv->helper_chooser, main_window);
+	dtask->priv->helper_chooser = gpk_helper_chooser_new ();
+	g_signal_connect (dtask->priv->helper_chooser, "event", G_CALLBACK (gpk_dbus_task_chooser_event_cb), dtask);
+	gpk_helper_chooser_set_parent (dtask->priv->helper_chooser, main_window);
 
 	/* map ISO639 to language names */
-	task->priv->language = gpk_language_new ();
-	gpk_language_populate (task->priv->language, NULL);
+	dtask->priv->language = gpk_language_new ();
+	gpk_language_populate (dtask->priv->language, NULL);
 
 	/* use gconf for session settings */
-	task->priv->gconf_client = gconf_client_get_default ();
+	dtask->priv->gconf_client = gconf_client_get_default ();
 
 	/* get actions */
-	task->priv->control = pk_control_new ();
-	task->priv->roles = pk_control_get_actions (task->priv->control, NULL);
-
-	task->priv->client_primary = pk_client_new ();
-	pk_client_set_use_buffer (task->priv->client_primary, TRUE, NULL);
-	g_signal_connect (task->priv->client_primary, "finished",
-			  G_CALLBACK (gpk_dbus_task_finished_cb), task);
-	g_signal_connect (task->priv->client_primary, "progress-changed",
-			  G_CALLBACK (gpk_dbus_task_progress_changed_cb), task);
-	g_signal_connect (task->priv->client_primary, "status-changed",
-			  G_CALLBACK (gpk_dbus_task_status_changed_cb), task);
-	g_signal_connect (task->priv->client_primary, "error-code",
-			  G_CALLBACK (gpk_dbus_task_error_code_cb), task);
-	g_signal_connect (task->priv->client_primary, "package",
-			  G_CALLBACK (gpk_dbus_task_package_cb), task);
-	g_signal_connect (task->priv->client_primary, "allow-cancel",
-			  G_CALLBACK (gpk_dbus_task_allow_cancel_cb), task);
-	g_signal_connect (task->priv->client_primary, "repo-signature-required",
-			  G_CALLBACK (gpk_dbus_task_repo_signature_required_cb), task);
-	g_signal_connect (task->priv->client_primary, "eula-required",
-			  G_CALLBACK (gpk_dbus_task_eula_required_cb), task);
-
-	/* this is asynchronous, else we get into livelock */
-	task->priv->client_secondary = pk_client_new ();
-	g_signal_connect (task->priv->client_secondary, "finished",
-			  G_CALLBACK (gpk_dbus_task_finished_cb), task);
-	g_signal_connect (task->priv->client_secondary, "error-code",
-			  G_CALLBACK (gpk_dbus_task_error_code_cb), task);
-	g_signal_connect (task->priv->client_secondary, "status-changed",
-			  G_CALLBACK (gpk_dbus_task_status_changed_cb), task);
+	dtask->priv->control = pk_control_new ();
+	dtask->priv->task = PK_TASK(gpk_task_new ());
+	dtask->priv->roles = pk_control_get_properties (dtask->priv->control, NULL, NULL);
+	dtask->priv->catalog = pk_catalog_new ();
 
 	/* used for icons and translations */
-	task->priv->desktop = pk_desktop_new ();
-	ret = pk_desktop_open_database (task->priv->desktop, NULL);
+	dtask->priv->desktop = pk_desktop_new ();
+	ret = pk_desktop_open_database (dtask->priv->desktop, NULL);
 	if (!ret)
 		egg_warning ("failed to open desktop database");
 }
@@ -3499,33 +2463,30 @@ gpk_dbus_task_init (GpkDbusTask *task)
 static void
 gpk_dbus_task_finalize (GObject *object)
 {
-	GpkDbusTask *task;
+	GpkDbusTask *dtask;
 
 	g_return_if_fail (GPK_IS_DBUS_TASK (object));
 
-	task = GPK_DBUS_TASK (object);
-	g_return_if_fail (task->priv != NULL);
-
-	g_free (task->priv->parent_title);
-	g_free (task->priv->parent_icon_name);
-	g_free (task->priv->error_details);
-	g_strfreev (task->priv->files);
-	g_strfreev (task->priv->package_ids);
-	g_object_unref (task->priv->client_primary);
-	g_object_unref (task->priv->client_secondary);
-	g_object_unref (task->priv->control);
-	g_object_unref (task->priv->desktop);
-	g_object_unref (task->priv->gconf_client);
-	g_object_unref (task->priv->dialog);
-	g_object_unref (task->priv->vendor);
-	g_object_unref (task->priv->language);
-	g_object_unref (task->priv->helper_eula);
-	g_object_unref (task->priv->helper_run);
-#if (!PK_CHECK_VERSION(0,5,0))
-	g_object_unref (task->priv->helper_untrusted);
-#endif
-	g_object_unref (task->priv->helper_chooser);
-	g_object_unref (task->priv->helper_repo_signature);
+	dtask = GPK_DBUS_TASK (object);
+	g_return_if_fail (dtask->priv != NULL);
+
+	g_free (dtask->priv->parent_title);
+	g_free (dtask->priv->parent_icon_name);
+	if (dtask->priv->cached_error_code != NULL)
+		pk_item_error_code_unref (dtask->priv->cached_error_code);
+	g_strfreev (dtask->priv->files);
+	g_strfreev (dtask->priv->package_ids);
+	g_object_unref (PK_CLIENT(dtask->priv->task));
+	g_object_unref (dtask->priv->control);
+	g_object_unref (dtask->priv->desktop);
+	g_object_unref (dtask->priv->gconf_client);
+	g_object_unref (dtask->priv->dialog);
+	g_object_unref (dtask->priv->vendor);
+	g_object_unref (dtask->priv->language);
+	g_object_unref (dtask->priv->cancellable);
+	g_object_unref (dtask->priv->helper_run);
+	g_object_unref (dtask->priv->helper_chooser);
+	g_object_unref (dtask->priv->catalog);
 
 	G_OBJECT_CLASS (gpk_dbus_task_parent_class)->finalize (object);
 }
@@ -3540,9 +2501,9 @@ gpk_dbus_task_finalize (GObject *object)
 GpkDbusTask *
 gpk_dbus_task_new (void)
 {
-	GpkDbusTask *task;
-	task = g_object_new (GPK_TYPE_DBUS_TASK, NULL);
-	return GPK_DBUS_TASK (task);
+	GpkDbusTask *dtask;
+	dtask = g_object_new (GPK_TYPE_DBUS_TASK, NULL);
+	return GPK_DBUS_TASK (dtask);
 }
 
 /***************************************************************************
@@ -3555,7 +2516,7 @@ void
 gpk_dbus_task_test (gpointer data)
 {
 	EggTest *test = (EggTest *) data;
-	GpkDbusTask *task;
+	GpkDbusTask *dtask;
 	gchar *lang;
 	gchar *language;
 	gchar *package;
@@ -3570,11 +2531,11 @@ gpk_dbus_task_test (gpointer data)
 
 	/************************************************************/
 	egg_test_title (test, "get GpkDbusTask object");
-	task = gpk_dbus_task_new ();
-	if (task != NULL)
+	dtask = gpk_dbus_task_new ();
+	if (dtask != NULL)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, NULL);
+		egg_warning (NULL);
 
 	/************************************************************/
 	egg_test_title (test, "convert tag to lang");
@@ -3582,16 +2543,16 @@ gpk_dbus_task_test (gpointer data)
 	if (g_strcmp0 (lang, "mn") == 0)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, "lang '%s'", lang);
+		egg_warning ("lang '%s'", lang);
 	g_free (lang);
 
 	/************************************************************/
 	egg_test_title (test, "convert tag to language");
-	language = gpk_dbus_task_font_tag_to_localised_name (task, ":lang=mn");
+	language = gpk_dbus_task_font_tag_to_localised_name (dtask, ":lang=mn");
 	if (g_strcmp0 (language, "Mongolian") == 0)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, "language '%s'", language);
+		egg_warning ("language '%s'", language);
 	g_free (language);
 
 	/************************************************************/
@@ -3600,7 +2561,7 @@ gpk_dbus_task_test (gpointer data)
 	if (ret)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, "failed to identify trusted");
+		egg_warning ("failed to identify trusted");
 
 	/************************************************************/
 	egg_test_title (test, "test trusted path");
@@ -3608,31 +2569,31 @@ gpk_dbus_task_test (gpointer data)
 	if (!ret)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, "identify untrusted as trusted!");
+		egg_warning ("identify untrusted as trusted!");
 
 	/************************************************************/
 	egg_test_title (test, "get package for exec");
-	package = gpk_dbus_task_get_package_for_exec (task, "/usr/bin/totem");
+	package = gpk_dbus_task_get_package_for_exec (dtask, "/usr/bin/totem");
 	if (g_strcmp0 (package, "totem") == 0)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, "package '%s'", package);
+		egg_warning ("package '%s'", package);
 	g_free (package);
 
 	/************************************************************/
 	egg_test_title (test, "set exec");
-	ret = gpk_dbus_task_set_exec (task, "/usr/bin/totem");
+	ret = gpk_dbus_task_set_exec (dtask, "/usr/bin/totem");
 	if (ret)
 		egg_test_success (test, NULL);
 	else
-		egg_test_failed (test, "failed to set exec");
+		egg_warning ("failed to set exec");
 
 #if 0
 	/************************************************************/
 	egg_test_title (test, "install fonts (no UI)");
 	error = NULL;
-	gpk_dbus_task_set_interaction (task, GPK_CLIENT_INTERACT_NEVER);
-	ret = gpk_dbus_task_install_fontconfig_resources (task, (gchar**)fonts, &error);
+	gpk_dbus_task_set_interaction (dtask, GPK_CLIENT_INTERACT_NEVER);
+	ret = gpk_dbus_task_install_fontconfig_resources (dtask, (gchar**)fonts, &error);
 	if (ret)
 		egg_test_success (test, NULL);
 	else {
@@ -3644,8 +2605,8 @@ gpk_dbus_task_test (gpointer data)
 	/************************************************************/
 	egg_test_title (test, "install fonts (if found)");
 	error = NULL;
-	gpk_dbus_task_set_interaction (task, pk_bitfield_from_enums (GPK_CLIENT_INTERACT_CONFIRM_SEARCH, GPK_CLIENT_INTERACT_FINISHED, -1));
-	ret = gpk_dbus_task_install_fontconfig_resources (task, (gchar**)fonts, &error);
+	gpk_dbus_task_set_interaction (dtask, pk_bitfield_from_enums (GPK_CLIENT_INTERACT_CONFIRM_SEARCH, GPK_CLIENT_INTERACT_FINISHED, -1));
+	ret = gpk_dbus_task_install_fontconfig_resources (dtask, (gchar**)fonts, &error);
 	if (ret)
 		egg_test_success (test, NULL);
 	else {
@@ -3657,8 +2618,8 @@ gpk_dbus_task_test (gpointer data)
 	/************************************************************/
 	egg_test_title (test, "install fonts (always)");
 	error = NULL;
-	gpk_dbus_task_set_interaction (task, GPK_CLIENT_INTERACT_ALWAYS);
-	ret = gpk_dbus_task_install_fontconfig_resources (task, (gchar**)fonts, &error);
+	gpk_dbus_task_set_interaction (dtask, GPK_CLIENT_INTERACT_ALWAYS);
+	ret = gpk_dbus_task_install_fontconfig_resources (dtask, (gchar**)fonts, &error);
 	if (ret)
 		egg_test_success (test, NULL);
 	else {
diff --git a/src/gpk-dbus-task.h b/src/gpk-dbus-task.h
index 3c1576a..b631754 100644
--- a/src/gpk-dbus-task.h
+++ b/src/gpk-dbus-task.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 G_BEGIN_DECLS
 
@@ -86,37 +86,35 @@ GType		 gpk_dbus_task_error_get_type		(void);
 GpkDbusTask	*gpk_dbus_task_new			(void);
 
 /* methods that expect a DBusGMethodInvocation return */
-void		 gpk_dbus_task_is_installed		(GpkDbusTask	*task,
+void		 gpk_dbus_task_is_installed		(GpkDbusTask	*dtask,
 							 const gchar	*package_name);
-void		 gpk_dbus_task_search_file		(GpkDbusTask	*task,
+void		 gpk_dbus_task_search_file		(GpkDbusTask	*dtask,
 							 const gchar	*search_file);
-void		 gpk_dbus_task_install_package_files	(GpkDbusTask	*task,
+void		 gpk_dbus_task_install_package_files	(GpkDbusTask	*dtask,
 							 gchar		**files_rel);
-void		 gpk_dbus_task_install_provide_files	(GpkDbusTask	*task,
+void		 gpk_dbus_task_install_provide_files	(GpkDbusTask	*dtask,
 							 gchar		**full_paths);
-void		 gpk_dbus_task_install_mime_types	(GpkDbusTask	*task,
+void		 gpk_dbus_task_install_mime_types	(GpkDbusTask	*dtask,
 							 gchar		**mime_types);
-void		 gpk_dbus_task_install_gstreamer_resources (GpkDbusTask	*task,
+void		 gpk_dbus_task_install_gstreamer_resources (GpkDbusTask	*dtask,
 							 gchar		**codec_names);
-void		 gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *task,
+void		 gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask,
 							 gchar		**fonts);
-void		 gpk_dbus_task_install_package_names	(GpkDbusTask	*task,
+void		 gpk_dbus_task_install_package_names	(GpkDbusTask	*dtask,
 							 gchar		**packages);
-void		 gpk_dbus_task_install_catalogs		(GpkDbusTask	*task,
+void		 gpk_dbus_task_install_catalogs		(GpkDbusTask	*dtask,
 							 gchar		**filenames);
 
 /* set state */
-gboolean	 gpk_dbus_task_set_interaction		(GpkDbusTask	*task,
+gboolean	 gpk_dbus_task_set_interaction		(GpkDbusTask	*dtask,
 							 PkBitfield	 interact);
-gboolean	 gpk_dbus_task_set_timeout		(GpkDbusTask	*task,
-							 gint		 timeout);
-gboolean	 gpk_dbus_task_set_timestamp		(GpkDbusTask	*task,
+gboolean	 gpk_dbus_task_set_timestamp		(GpkDbusTask	*dtask,
 							 guint		 timeout);
-gboolean	 gpk_dbus_task_set_context		(GpkDbusTask	*task,
+gboolean	 gpk_dbus_task_set_context		(GpkDbusTask	*dtask,
 							 DBusGMethodInvocation *context);
-gboolean	 gpk_dbus_task_set_xid			(GpkDbusTask	*task,
+gboolean	 gpk_dbus_task_set_xid			(GpkDbusTask	*dtask,
 							 guint		 xid);
-gboolean	 gpk_dbus_task_set_exec			(GpkDbusTask	*task,
+gboolean	 gpk_dbus_task_set_exec			(GpkDbusTask	*dtask,
 							 const gchar	*exec);
 
 G_END_DECLS
diff --git a/src/gpk-dbus.c b/src/gpk-dbus.c
index b1f3130..7973a23 100644
--- a/src/gpk-dbus.c
+++ b/src/gpk-dbus.c
@@ -38,7 +38,7 @@
 #include <glib/gi18n.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <gconf/gconf-client.h>
 
 #include "egg-debug.h"
@@ -211,6 +211,13 @@ gpk_dbus_get_exec_for_sender (GpkDbus *dbus, const gchar *sender)
 		egg_warning ("failed to get cmdline: %s", error->message);
 		g_error_free (error);
 	}
+
+	/* if command line contains (deleted) the original binary is invalid */
+	if (g_strstr_len (cmdline, -1, "(deleted)") != NULL) {
+		g_free (cmdline);
+		cmdline = NULL;
+		goto out;
+	}
 out:
 	g_free (filename);
 	return cmdline;
@@ -329,10 +336,6 @@ gpk_dbus_create_task (GpkDbus *dbus, guint32 xid, const gchar *interaction, DBus
 	egg_debug ("interact=%i", (gint) interact);
 	gpk_dbus_task_set_interaction (task, interact);
 
-	/* set timeout */
-	egg_debug ("timeout=%i", timeout);
-	gpk_dbus_task_set_timeout (task, timeout);
-
 	/* set the parent window */
 	gpk_dbus_task_set_xid (task, xid);
 
@@ -492,7 +495,7 @@ gpk_dbus_init (GpkDbus *dbus)
 	dbus->priv = GPK_DBUS_GET_PRIVATE (dbus);
 	dbus->priv->timeout_tmp = -1;
 	dbus->priv->gconf_client = gconf_client_get_default ();
-	dbus->priv->array = g_ptr_array_new ();
+	dbus->priv->array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
 	dbus->priv->x11 = gpk_x11_new ();
 
 	/* find out PIDs on the session bus */
@@ -521,8 +524,7 @@ gpk_dbus_finalize (GObject *object)
 
 	dbus = GPK_DBUS (object);
 	g_return_if_fail (dbus->priv != NULL);
-	g_ptr_array_foreach (dbus->priv->array, (GFunc) g_object_unref, NULL);
-	g_ptr_array_free (dbus->priv->array, TRUE);
+	g_ptr_array_unref (dbus->priv->array);
 	g_object_unref (dbus->priv->gconf_client);
 	g_object_unref (dbus->priv->x11);
 	g_object_unref (dbus->priv->proxy_session_pid);
diff --git a/src/gpk-desktop.c b/src/gpk-desktop.c
index 4762fc2..c4fd549 100644
--- a/src/gpk-desktop.c
+++ b/src/gpk-desktop.c
@@ -24,7 +24,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <locale.h>
 #include <string.h>
 
@@ -267,10 +267,8 @@ gpk_desktop_guess_best_file (PkDesktop *desktop, const gchar *package)
 	best_file = g_strdup (g_ptr_array_index (array, max_index));
 	egg_debug ("using %s", best_file);
 out:
-	if (array != NULL) {
-		g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-		g_ptr_array_free (array, TRUE);
-	}
+	if (array != NULL)
+		g_ptr_array_unref (array);
 	return best_file;
 }
 
diff --git a/src/gpk-desktop.h b/src/gpk-desktop.h
index a660341..2e18b2e 100644
--- a/src/gpk-desktop.h
+++ b/src/gpk-desktop.h
@@ -23,7 +23,7 @@
 #define __GPK_DESKTOP_H
 
 #include <glib.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 G_BEGIN_DECLS
 
diff --git a/src/gpk-dialog.c b/src/gpk-dialog.c
index 4ccc4ce..a86e8f8 100644
--- a/src/gpk-dialog.c
+++ b/src/gpk-dialog.c
@@ -24,7 +24,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <gconf/gconf-client.h>
 
 #include "egg-debug.h"
@@ -51,20 +51,20 @@ gpk_dialog_package_id_name_join_locale (gchar **package_ids)
 	guint i;
 	guint length;
 	gchar *text;
-	PkPackageId *ident;
 	GPtrArray *array;
 	gchar **array_strv;
+	gchar **split;
 
 	length = g_strv_length (package_ids);
-	array = g_ptr_array_new ();
+	array = g_ptr_array_new_with_free_func (g_free);
 	for (i=0; i<length; i++) {
-		ident = pk_package_id_new_from_string (package_ids[i]);
-		if (ident == NULL) {
+		split = pk_package_id_split (package_ids[i]);
+		if (split == NULL) {
 			egg_warning ("failed to split %s", package_ids[i]);
 			continue;
 		}
-		g_ptr_array_add (array, g_strdup (ident->name));
-		pk_package_id_free (ident);
+		g_ptr_array_add (array, g_strdup (split[0]));
+		g_strfreev (split);
 	}
 	array_strv = pk_ptr_array_to_strv (array);
 	text = gpk_strv_join_locale (array_strv);
@@ -73,50 +73,47 @@ gpk_dialog_package_id_name_join_locale (gchar **package_ids)
 		/* TRANSLATORS: This is when we have over 5 items, and we're not interested in detail */
 		text = g_strdup (_("many packages"));
 	}
-	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-	g_ptr_array_free (array, TRUE);
+	g_ptr_array_unref (array);
 	return text;
 }
 
 /**
- * gpk_dialog_package_list_to_list_store:
+ * gpk_dialog_package_array_to_list_store:
  **/
 static GtkListStore *
-gpk_dialog_package_list_to_list_store (PkPackageList *list)
+gpk_dialog_package_array_to_list_store (GPtrArray *array)
 {
 	GtkListStore *store;
 	GtkTreeIter iter;
-	const PkPackageObj *obj;
+	const PkItemPackage *item;
 	PkDesktop *desktop;
 	const gchar *icon;
-	gchar *package_id;
 	gchar *text;
-	guint length;
 	guint i;
+	gchar **split;
 
 	desktop = pk_desktop_new ();
 	store = gtk_list_store_new (GPK_DIALOG_STORE_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
-	length = pk_package_list_get_size (list);
 
 	/* add each well */
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		text = gpk_package_id_format_twoline (obj->id, obj->summary);
-		package_id = pk_package_id_to_string (obj->id);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		text = gpk_package_id_format_twoline (item->package_id, item->summary);
 
 		/* get the icon */
-		icon = gpk_desktop_guess_icon_name (desktop, obj->id->name);
+		split = pk_package_id_split (item->package_id);
+		icon = gpk_desktop_guess_icon_name (desktop, split[0]);
 		if (icon == NULL)
-			icon = gpk_info_enum_to_icon_name (PK_INFO_ENUM_INSTALLED);
+			icon = gpk_info_enum_to_icon_name (item->info);
 
 		gtk_list_store_append (store, &iter);
 		gtk_list_store_set (store, &iter,
 				    GPK_DIALOG_STORE_IMAGE, icon,
-				    GPK_DIALOG_STORE_ID, package_id,
+				    GPK_DIALOG_STORE_ID, item->package_id,
 				    GPK_DIALOG_STORE_TEXT, text,
 				    -1);
+		g_strfreev (split);
 		g_free (text);
-		g_free (package_id);
 	}
 
 	g_object_unref (desktop);
@@ -170,16 +167,23 @@ gpk_dialog_widget_unrealize_unref_cb (GtkWidget *widget, GObject *obj)
  * gpk_dialog_embed_package_list_widget:
  **/
 gboolean
-gpk_dialog_embed_package_list_widget (GtkDialog *dialog, PkPackageList *list)
+gpk_dialog_embed_package_list_widget (GtkDialog *dialog, GPtrArray *array)
 {
 	GtkWidget *scroll;
 	GtkListStore *store;
 	GtkWidget *widget;
-	guint length;
 	const guint row_height = 48;
+	PkItemPackage *item;
+	guint i;
+
+	/* debug */
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		egg_debug ("add %s,%s", pk_info_enum_to_text (item->info), item->package_id);
+	}
 
 	/* convert to a store */
-	store = gpk_dialog_package_list_to_list_store (list);
+	store = gpk_dialog_package_array_to_list_store (array);
 
 	/* create a treeview to hold the store */
 	widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
@@ -196,11 +200,10 @@ gpk_dialog_embed_package_list_widget (GtkDialog *dialog, PkPackageList *list)
 	gtk_container_set_border_width (GTK_CONTAINER (scroll), 6);
 
 	/* only allow more space if there are a large number of items */
-	length = pk_package_list_get_size (list);
-	if (length > 5) {
+	if (array->len > 5) {
 		gtk_widget_set_size_request (GTK_WIDGET (scroll), -1, (row_height * 5) + 8);
-	} else if (length > 1) {
-		gtk_widget_set_size_request (GTK_WIDGET (scroll), -1, (row_height * length) + 8);
+	} else if (array->len > 1) {
+		gtk_widget_set_size_request (GTK_WIDGET (scroll), -1, (row_height * array->len) + 8);
 	}
 
 	/* add scrolled window */
diff --git a/src/gpk-dialog.h b/src/gpk-dialog.h
index 786bfc4..91e228b 100644
--- a/src/gpk-dialog.h
+++ b/src/gpk-dialog.h
@@ -24,12 +24,12 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 G_BEGIN_DECLS
 
 gboolean	 gpk_dialog_embed_package_list_widget	(GtkDialog	*dialog,
-							 PkPackageList	*list);
+							 GPtrArray	*array);
 gboolean	 gpk_dialog_embed_file_list_widget	(GtkDialog	*dialog,
 							 GPtrArray	*files);
 gboolean	 gpk_dialog_embed_do_not_show_widget	(GtkDialog	*dialog,
diff --git a/src/gpk-error.c b/src/gpk-error.c
index 069b6da..213c5a1 100644
--- a/src/gpk-error.c
+++ b/src/gpk-error.c
@@ -26,10 +26,9 @@
 #include <string.h>
 #include <unistd.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
-#include "egg-string.h"
 
 #include "gpk-common.h"
 #include "gpk-error.h"
@@ -75,7 +74,7 @@ gpk_error_dialog_modal_with_time (GtkWindow *window, const gchar *title, const g
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-error.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -115,7 +114,7 @@ gpk_error_dialog_modal_with_time (GtkWindow *window, const gchar *title, const g
 	gtk_label_set_markup (GTK_LABEL (widget), message);
 
 	/* show text in the expander */
-	if (egg_strzero (details)) {
+	if (details == NULL || details[0] == '\0') {
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "expander_details"));
 		gtk_widget_hide (widget);
 	} else {
diff --git a/src/gpk-firmware.c b/src/gpk-firmware.c
index a02b663..4d949ef 100644
--- a/src/gpk-firmware.c
+++ b/src/gpk-firmware.c
@@ -38,7 +38,7 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <libnotify/notify.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #ifdef GPK_BUILD_GUDEV
 #include <gudev/gudev.h>
 #endif
@@ -50,6 +50,7 @@
 #include "gpk-common.h"
 #include "gpk-error.h"
 #include "gpk-firmware.h"
+#include "gpk-task.h"
 
 static void     gpk_firmware_finalize	(GObject	  *object);
 
@@ -67,8 +68,8 @@ struct GpkFirmwarePrivate
 	GConfClient		*gconf_client;
 	GFileMonitor		*monitor;
 	GPtrArray		*array_requested;
-	PkClient		*client_primary;
-	PkPackageList		*packages_found;
+	PkTask			*task;
+	GPtrArray		*packages_found;
 	guint			 timeout_id;
 };
 
@@ -88,6 +89,9 @@ typedef struct {
 
 G_DEFINE_TYPE (GpkFirmware, gpk_firmware, G_TYPE_OBJECT)
 
+static void gpk_firmware_install_file (GpkFirmware *firmware);
+static void gpk_firmware_ignore_devices (GpkFirmware *firmware);
+
 /**
  * gpk_firmware_subsystem_can_replug:
  **/
@@ -169,38 +173,6 @@ gpk_firmware_request_free (GpkFirmwareRequest *req)
 	g_free (req);
 }
 
-/**
- * gpk_firmware_install_file:
- **/
-static gboolean
-gpk_firmware_install_file (GpkFirmware *firmware)
-{
-	gboolean ret;
-	GError *error = NULL;
-	gchar **package_ids;
-
-	/* install all of the firmware files */
-	package_ids = pk_package_list_to_strv (firmware->priv->packages_found);
-	ret = pk_client_reset (firmware->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to reset: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-#if PK_CHECK_VERSION(0,5,0)
-	ret = pk_client_install_packages (firmware->priv->client_primary, TRUE, package_ids, &error);
-#else
-	ret = pk_client_install_packages (firmware->priv->client_primary, package_ids, &error);
-#endif
-	if (!ret) {
-		egg_warning ("failed to install provide file: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	g_strfreev (package_ids);
-	return ret;
-}
 
 /**
  * gpk_firmware_rebind:
@@ -256,6 +228,213 @@ out:
 }
 
 /**
+ * gpk_firmware_libnotify_cb:
+ **/
+static void
+gpk_firmware_libnotify_cb (NotifyNotification *notification, gchar *action, gpointer data)
+{
+	GpkFirmware *firmware = GPK_FIRMWARE (data);
+	gboolean ret;
+	GError *error = NULL;
+
+	if (g_strcmp0 (action, "install-firmware") == 0) {
+		gpk_firmware_install_file (firmware);
+	} else if (g_strcmp0 (action, "ignore-devices") == 0) {
+		gpk_firmware_ignore_devices (firmware);
+	} else if (g_strcmp0 (action, "restart-now") == 0) {
+		ret = egg_console_kit_restart (firmware->priv->consolekit, &error);
+		if (!ret) {
+			egg_warning ("failed to reset: %s", error->message);
+			g_error_free (error);
+		}
+	} else {
+		egg_warning ("unknown action id: %s", action);
+	}
+}
+
+/**
+ * gpk_firmware_require_restart:
+ **/
+static void
+gpk_firmware_require_restart (GpkFirmware *firmware)
+{
+	const gchar *message;
+	gboolean can_restart = FALSE;
+	gboolean ret;
+	GError *error = NULL;
+	NotifyNotification *notification;
+
+	/* TRANSLATORS: we need to restart so the new hardware can re-request the firmware */
+	message = _("You will need to restart this computer before the hardware will work correctly.");
+
+	/* TRANSLATORS: title of libnotify bubble */
+	notification = notify_notification_new (_("Additional software was installed"), message, "help-browser", NULL);
+	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+
+	/* only show the restart button if we can restart */
+	egg_console_kit_can_restart (firmware->priv->consolekit, &can_restart, NULL);
+	if (can_restart) {
+		notify_notification_add_action (notification, "restart-now",
+						/* TRANSLATORS: button label */
+						_("Restart now"), gpk_firmware_libnotify_cb, firmware, NULL);
+	}
+
+	/* show the bubble */
+	ret = notify_notification_show (notification, &error);
+	if (!ret) {
+		egg_warning ("error: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+/**
+ * gpk_firmware_require_replug:
+ **/
+static void
+gpk_firmware_require_replug (GpkFirmware *firmware)
+{
+	const gchar *message;
+	gboolean ret;
+	GError *error = NULL;
+	NotifyNotification *notification;
+
+	/* TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware */
+	message = _("You will need to remove and then reinsert the hardware before it will work correctly.");
+
+	/* TRANSLATORS: title of libnotify bubble */
+	notification = notify_notification_new (_("Additional software was installed"), message, "help-browser", NULL);
+	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+
+	/* show the bubble */
+	ret = notify_notification_show (notification, &error);
+	if (!ret) {
+		egg_warning ("error: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+/**
+ * gpk_firmware_require_nothing:
+ **/
+static void
+gpk_firmware_require_nothing (GpkFirmware *firmware)
+{
+	const gchar *message;
+	gboolean ret;
+	GError *error = NULL;
+	NotifyNotification *notification;
+
+	/* TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware */
+	message = _("Your hardware has been set up and is now ready to use.");
+
+	/* TRANSLATORS: title of libnotify bubble */
+	notification = notify_notification_new (_("Additional software was installed"), message, "help-browser", NULL);
+	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+
+	/* show the bubble */
+	ret = notify_notification_show (notification, &error);
+	if (!ret) {
+		egg_warning ("error: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+/**
+ * gpk_firmware_install_packages_cb:
+ **/
+static void
+gpk_firmware_install_packages_cb (GObject *object, GAsyncResult *res, GpkFirmware *firmware)
+{
+	PkClient *client = PK_CLIENT (object);
+	GError *error = NULL;
+	PkResults *results = NULL;
+	GPtrArray *array = NULL;
+	gboolean restart = FALSE;
+	const GpkFirmwareRequest *req;
+	gboolean ret;
+	guint i;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to install file: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to install file: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		/* ignore some errors */
+		if (error_item->code != PK_ERROR_ENUM_PROCESS_KILL &&
+		    error_item->code != PK_ERROR_ENUM_TRANSACTION_CANCELLED &&
+		    error_item->code != PK_ERROR_ENUM_NOT_AUTHORIZED) {
+			gpk_error_dialog (gpk_error_enum_to_localised_text (error_item->code),
+					  gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		}
+		goto out;
+	}
+
+	/* go through all the requests, and find the worst type */
+	array = firmware->priv->array_requested;
+	for (i=0; i<array->len; i++) {
+		req = g_ptr_array_index (array, i);
+		ret = gpk_firmware_subsystem_can_replug (req->subsystem);
+		if (!ret) {
+			restart = TRUE;
+			break;
+		}
+	}
+
+	/* can we just rebind the device */
+	ret = g_file_test (GPK_FIRMWARE_DEVICE_REBIND_PROGRAM, G_FILE_TEST_EXISTS);
+	if (ret) {
+		ret = gpk_firmware_rebind (firmware);
+		if (ret) {
+			gpk_firmware_require_nothing (firmware);
+			goto out;
+		}
+	} else {
+		/* give the user the correct message */
+		if (restart)
+			gpk_firmware_require_restart (firmware);
+		else
+			gpk_firmware_require_replug (firmware);
+	}
+
+	/* clear array */
+	g_ptr_array_set_size (firmware->priv->array_requested, 0);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_firmware_install_file:
+ **/
+static void
+gpk_firmware_install_file (GpkFirmware *firmware)
+{
+	gchar **package_ids;
+
+	/* install all of the firmware files */
+	package_ids = pk_package_array_to_strv (firmware->priv->packages_found);
+	pk_client_install_packages_async (PK_CLIENT(firmware->priv->task), TRUE, package_ids, NULL, NULL, NULL,
+					  (GAsyncReadyCallback) gpk_firmware_install_packages_cb, firmware);
+	g_strfreev (package_ids);
+}
+
+/**
  * gpk_firmware_ignore_devices:
  **/
 static void
@@ -307,82 +486,77 @@ out:
 }
 
 /**
- * gpk_firmware_libnotify_cb:
- **/
-static void
-gpk_firmware_libnotify_cb (NotifyNotification *notification, gchar *action, gpointer data)
-{
-	GpkFirmware *firmware = GPK_FIRMWARE (data);
-	gboolean ret;
-	GError *error = NULL;
-
-	if (g_strcmp0 (action, "install-firmware") == 0) {
-		gpk_firmware_install_file (firmware);
-	} else if (g_strcmp0 (action, "ignore-devices") == 0) {
-		gpk_firmware_ignore_devices (firmware);
-	} else if (g_strcmp0 (action, "restart-now") == 0) {
-		ret = egg_console_kit_restart (firmware->priv->consolekit, &error);
-		if (!ret) {
-			egg_warning ("failed to reset: %s", error->message);
-			g_error_free (error);
-		}
-	} else {
-		egg_warning ("unknown action id: %s", action);
-	}
-}
-
-/**
  * gpk_firmware_check_available:
  * @firmware: This class instance
  * @filename: Firmware to search for
  **/
-static PkPackageObj *
+static PkItemPackage *
 gpk_firmware_check_available (GpkFirmware *firmware, const gchar *filename)
 {
-	gboolean ret;
 	guint length = 0;
-	PkPackageList *list = NULL;
+	GPtrArray *array = NULL;
 	GError *error = NULL;
-	PkPackageObj *obj = NULL;
+	PkItemPackage *item = NULL;
 	PkBitfield filter;
-
-	/* actually check we can provide the firmware */
-	ret = pk_client_reset (firmware->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to reset: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* say bodge */
-	pk_client_set_synchronous (firmware->priv->client_primary, TRUE, NULL);
+	PkResults *results;
+	gchar **values = NULL;
+	PkItemErrorCode *error_item = NULL;
 
 	/* search for newest not installed package */
 	filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_NEWEST, -1);
-	ret = pk_client_search_file (firmware->priv->client_primary, filter, filename, &error);
-
-	/* unsay bodge */
-	pk_client_set_synchronous (firmware->priv->client_primary, FALSE, NULL);
-
-	if (!ret) {
+	values = g_strsplit (filename, "&", -1);
+	results = pk_client_search_file (PK_CLIENT(firmware->priv->task), filter, values, NULL, NULL, NULL, &error);
+	if (results == NULL) {
 		egg_warning ("failed to search file %s: %s", filename, error->message);
 		g_error_free (error);
 		goto out;
 	}
 
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to search file: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
 	/* make sure we have one package */
-	list = pk_client_get_package_list (firmware->priv->client_primary);
-	length = pk_package_list_get_size (list);
-	if (length == 0)
+	array = pk_results_get_package_array (results);
+	if (array->len == 0)
 		egg_debug ("no package providing %s found", filename);
-	else if (length != 1)
+	else if (array->len != 1)
 		egg_warning ("not one package providing %s found (%i)", filename, length);
 	else
-		obj = pk_package_obj_copy (pk_package_list_get_obj (list, 0));
+		item = pk_item_package_ref (g_ptr_array_index (array, 0));
 out:
-	if (list != NULL)
-		g_object_unref (list);
-	return obj;
+	g_strfreev (values);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_object_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+	return item;
+}
+
+/**
+ * gpk_firmware_remove_duplicate:
+ **/
+static void
+gpk_firmware_remove_duplicate (GPtrArray *array)
+{
+	guint i, j;
+	const gchar *val;
+	const gchar *val_tmp;
+
+	/* remove each duplicate entry */
+	for (i=0; i<array->len; i++) {
+		val = g_ptr_array_index (array, i);
+		for (j=i+1; j<array->len; j++) {
+			val_tmp = g_ptr_array_index (array, j);
+			if (g_strcmp0 (val_tmp, val) == 0)
+				g_ptr_array_remove_index_fast (array, j);
+		}
+	}
 }
 
 /**
@@ -398,7 +572,7 @@ gpk_firmware_timeout_cb (gpointer data)
 	NotifyNotification *notification;
 	GPtrArray *array;
 	GError *error = NULL;
-	PkPackageObj *obj = NULL;
+	PkItemPackage *item = NULL;
 	const GpkFirmwareRequest *req;
 	gboolean has_data = FALSE;
 
@@ -410,23 +584,23 @@ gpk_firmware_timeout_cb (gpointer data)
 	for (i=0; i<array->len; i++) {
 		req = g_ptr_array_index (array, i);
 		/* save to new array if we found one package for this file */
-		obj = gpk_firmware_check_available (firmware, req->filename);
-		if (obj != NULL) {
-			pk_obj_list_add (PK_OBJ_LIST (firmware->priv->packages_found), obj);
-			pk_package_obj_free (obj);
+		item = gpk_firmware_check_available (firmware, req->filename);
+		if (item != NULL) {
+			g_ptr_array_add (firmware->priv->packages_found, item);
+			pk_item_package_unref (item);
 		}
 	}
 
 	/* nothing to do */
-	if (pk_package_list_get_size (firmware->priv->packages_found) == 0) {
+	if (firmware->priv->packages_found->len == 0) {
 		egg_debug ("no packages providing any of the missing firmware");
 		goto out;
 	}
 
 	/* check we don't want the same package more than once */
-	pk_obj_list_remove_duplicate (PK_OBJ_LIST (firmware->priv->packages_found));
+	gpk_firmware_remove_duplicate (firmware->priv->packages_found);
 
-	/* have we got any models to list */
+	/* have we got any models to array */
 	for (i=0; i<array->len; i++) {
 		req = g_ptr_array_index (array, i);
 		if (req->model != NULL) {
@@ -591,205 +765,6 @@ gpk_firmware_udev_text_decode (const gchar *data)
 }
 
 /**
- * gpk_firmware_error_code_cb:
- **/
-static void
-gpk_firmware_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *details, GpkFirmware *firmware)
-{
-	/* ignore some errors */
-	if (code == PK_ERROR_ENUM_PROCESS_KILL ||
-	    code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
-		egg_debug ("error ignored %s: %s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	/* ignore the ones we can handle */
-	if (pk_error_code_is_need_untrusted (code)) {
-		egg_debug ("error ignored as we're handling %s: %s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	/* ignore not authorised, which seems odd but this will happen if the user clicks cancel */
-	if (code == PK_ERROR_ENUM_NOT_AUTHORIZED) {
-		egg_debug ("auth failure '%s' ignored: %s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	gpk_error_dialog (gpk_error_enum_to_localised_text (code),
-			  gpk_error_enum_to_localised_message (code), details);
-}
-
-/**
- * gpk_firmware_primary_requeue:
- **/
-static gboolean
-gpk_firmware_primary_requeue (GpkFirmware *firmware)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	/* retry new action */
-	ret = pk_client_requeue (firmware->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("Failed to requeue: %s", error->message);
-		g_error_free (error);
-	}
-	return ret;
-}
-
-/**
- * gpk_firmware_require_restart:
- **/
-static void
-gpk_firmware_require_restart (GpkFirmware *firmware)
-{
-	const gchar *message;
-	gboolean can_restart = FALSE;
-	gboolean ret;
-	GError *error = NULL;
-	NotifyNotification *notification;
-
-	/* TRANSLATORS: we need to restart so the new hardware can re-request the firmware */
-	message = _("You will need to restart this computer before the hardware will work correctly.");
-
-	/* TRANSLATORS: title of libnotify bubble */
-	notification = notify_notification_new (_("Additional software was installed"), message, "help-browser", NULL);
-	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-
-	/* only show the restart button if we can restart */
-	egg_console_kit_can_restart (firmware->priv->consolekit, &can_restart, NULL);
-	if (can_restart) {
-		notify_notification_add_action (notification, "restart-now",
-						/* TRANSLATORS: button label */
-						_("Restart now"), gpk_firmware_libnotify_cb, firmware, NULL);
-	}
-
-	/* show the bubble */
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-}
-
-/**
- * gpk_firmware_require_replug:
- **/
-static void
-gpk_firmware_require_replug (GpkFirmware *firmware)
-{
-	const gchar *message;
-	gboolean ret;
-	GError *error = NULL;
-	NotifyNotification *notification;
-
-	/* TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware */
-	message = _("You will need to remove and then reinsert the hardware before it will work correctly.");
-
-	/* TRANSLATORS: title of libnotify bubble */
-	notification = notify_notification_new (_("Additional software was installed"), message, "help-browser", NULL);
-	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-
-	/* show the bubble */
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-}
-
-/**
- * gpk_firmware_require_nothing:
- **/
-static void
-gpk_firmware_require_nothing (GpkFirmware *firmware)
-{
-	const gchar *message;
-	gboolean ret;
-	GError *error = NULL;
-	NotifyNotification *notification;
-
-	/* TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware */
-	message = _("Your hardware has been set up and is now ready to use.");
-
-	/* TRANSLATORS: title of libnotify bubble */
-	notification = notify_notification_new (_("Additional software was installed"), message, "help-browser", NULL);
-	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-
-	/* show the bubble */
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-}
-
-/**
- * gpk_firmware_finished_cb:
- **/
-static void
-gpk_firmware_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkFirmware *firmware)
-{
-	PkRoleEnum role;
-	gboolean restart = FALSE;
-	const GpkFirmwareRequest *req;
-	GPtrArray *array;
-	gboolean ret;
-	guint i;
-
-	pk_client_get_role (client, &role, NULL, NULL);
-	egg_debug ("role: %s, exit: %s", pk_role_enum_to_text (role), pk_exit_enum_to_text (exit_enum));
-
-	/* need to handle retry with only_trusted=FALSE */
-	if (exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) {
-		egg_debug ("need to handle untrusted");
-		pk_client_set_only_trusted (client, FALSE);
-		gpk_firmware_primary_requeue (firmware);
-		return;
-	}
-
-	/* tell the user we installed okay */
-	if (exit_enum == PK_EXIT_ENUM_SUCCESS && role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
-
-		/* go through all the requests, and find the worst type */
-		array = firmware->priv->array_requested;
-		for (i=0; i<array->len; i++) {
-			req = g_ptr_array_index (array, i);
-			ret = gpk_firmware_subsystem_can_replug (req->subsystem);
-			if (!ret) {
-				restart = TRUE;
-				break;
-			}
-		}
-
-		/* can we just rebind the device */
-		ret = g_file_test (GPK_FIRMWARE_DEVICE_REBIND_PROGRAM, G_FILE_TEST_EXISTS);
-		if (ret) {
-			ret = gpk_firmware_rebind (firmware);
-			if (ret) {
-				gpk_firmware_require_nothing (firmware);
-				goto out;
-			}
-		} else {
-			/* give the user the correct message */
-			if (restart)
-				gpk_firmware_require_restart (firmware);
-			else
-				gpk_firmware_require_replug (firmware);
-		}
-
-		/* clear array */
-		g_ptr_array_foreach (firmware->priv->array_requested, (GFunc) gpk_firmware_request_free, NULL);
-		g_ptr_array_set_size (firmware->priv->array_requested, 0);
-	}
-out:
-	return;
-}
-
-/**
  * gpk_firmware_get_device:
  **/
 static gchar *
@@ -1023,17 +998,14 @@ gpk_firmware_init (GpkFirmware *firmware)
 
 	firmware->priv = GPK_FIRMWARE_GET_PRIVATE (firmware);
 	firmware->priv->timeout_id = 0;
-	firmware->priv->packages_found = pk_package_list_new ();
-	firmware->priv->array_requested = g_ptr_array_new ();
+	firmware->priv->packages_found = g_ptr_array_new_with_free_func ((GDestroyNotify) pk_item_package_unref);
+	firmware->priv->array_requested = g_ptr_array_new_with_free_func ((GDestroyNotify) gpk_firmware_request_free);
 	firmware->priv->gconf_client = gconf_client_get_default ();
 	firmware->priv->consolekit = egg_console_kit_new ();
-	firmware->priv->client_primary = pk_client_new ();
-	pk_client_set_use_buffer (firmware->priv->client_primary, TRUE, NULL);
-
-	g_signal_connect (firmware->priv->client_primary, "error-code",
-			  G_CALLBACK (gpk_firmware_error_code_cb), firmware);
-	g_signal_connect (firmware->priv->client_primary, "finished",
-			  G_CALLBACK (gpk_firmware_finished_cb), firmware);
+	firmware->priv->task = PK_TASK(gpk_task_new ());
+	g_object_set (firmware->priv->task,
+		      "background", TRUE,
+		      NULL);
 
 	/* setup watch for new hardware */
 	file = g_file_new_for_path (GPK_FIRMWARE_MISSING_DIR);
@@ -1070,10 +1042,9 @@ gpk_firmware_finalize (GObject *object)
 	firmware = GPK_FIRMWARE (object);
 
 	g_return_if_fail (firmware->priv != NULL);
-	g_ptr_array_foreach (firmware->priv->array_requested, (GFunc) gpk_firmware_request_free, NULL);
-	g_ptr_array_free (firmware->priv->array_requested, TRUE);
-	g_object_unref (firmware->priv->packages_found);
-	g_object_unref (firmware->priv->client_primary);
+	g_ptr_array_unref (firmware->priv->array_requested);
+	g_ptr_array_unref (firmware->priv->packages_found);
+	g_object_unref (PK_CLIENT(firmware->priv->task));
 	g_object_unref (firmware->priv->gconf_client);
 	g_object_unref (firmware->priv->consolekit);
 	if (firmware->priv->monitor != NULL)
diff --git a/src/gpk-hardware.c b/src/gpk-hardware.c
index dc26a66..2149562 100644
--- a/src/gpk-hardware.c
+++ b/src/gpk-hardware.c
@@ -39,13 +39,14 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
 
 #include "gpk-common.h"
 #include "gpk-hardware.h"
+#include "gpk-task.h"
 
 static void     gpk_hardware_finalize	(GObject	  *object);
 
@@ -57,6 +58,7 @@ static void     gpk_hardware_finalize	(GObject	  *object);
 
 struct GpkHardwarePrivate
 {
+	PkTask			*task;
 	GConfClient		*gconf_client;
 	DBusGConnection		*connection;
 	DBusGProxy		*proxy;
@@ -66,33 +68,48 @@ struct GpkHardwarePrivate
 
 G_DEFINE_TYPE (GpkHardware, gpk_hardware, G_TYPE_OBJECT)
 
+
 /**
- * gpk_hardware_install_package:
+ * gpk_hardware_install_packages_cb:
  **/
-static gboolean
-gpk_hardware_install_package (GpkHardware *hardware)
+static void
+gpk_hardware_install_packages_cb (GObject *object, GAsyncResult *res, GpkHardware *hardware)
 {
+	PkClient *client = PK_CLIENT (object);
 	GError *error = NULL;
-	PkClient *client = NULL;
-	gboolean ret;
-
-	client = pk_client_new ();
+	PkResults *results = NULL;
+	PkItemErrorCode *error_item = NULL;
 
-	/* FIXME: this needs to be async and connect up to the repo signature stuff */
-	pk_client_set_synchronous (client, TRUE, NULL);
-#if PK_CHECK_VERSION(0,5,0)
-	ret = pk_client_install_packages (client, TRUE, hardware->priv->package_ids, &error);
-#else
-	ret = pk_client_install_packages (client, hardware->priv->package_ids, &error);
-#endif
-	if (!ret) {
-		egg_warning ("failed to install package: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to install file: %s", error->message);
 		g_error_free (error);
-		error = NULL;
+		goto out;
 	}
 
-	g_object_unref (client);
-	return ret;
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to install file: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_hardware_install_package:
+ **/
+static void
+gpk_hardware_install_package (GpkHardware *hardware)
+{
+	/* FIXME: this needs to be async and connect up to the repo signature stuff */
+	pk_client_install_packages_async (PK_CLIENT(hardware->priv->task), TRUE, hardware->priv->package_ids, NULL, NULL, NULL,
+					  (GAsyncReadyCallback) gpk_hardware_install_packages_cb, hardware);
 }
 
 /**
@@ -114,50 +131,53 @@ gpk_hardware_libnotify_cb (NotifyNotification *notification, gchar *action, gpoi
 }
 
 /**
- * gpk_hardware_check_for_driver_available:
+ * gpk_hardware_what_provides_cb:
  **/
 static void
-gpk_hardware_check_for_driver_available (GpkHardware *hardware, const gchar *udi)
+gpk_hardware_what_provides_cb (GObject *object, GAsyncResult *res, GpkHardware *hardware)
 {
+	PkClient *client = PK_CLIENT (object);
+	GError *error = NULL;
+	PkResults *results = NULL;
 	gboolean ret;
-	guint length;
 	gchar *message = NULL;
 	gchar *body = NULL;
 	NotifyNotification *notification;
-	GError *error = NULL;
 	gchar *package = NULL;
-	PkPackageList *list = NULL;
-	const PkPackageObj *obj = NULL;
-	PkClient *client = NULL;
-
-	client = pk_client_new ();
-	pk_client_set_synchronous (client, TRUE, NULL);
-	pk_client_set_use_buffer (client, TRUE, NULL);
-	ret = pk_client_what_provides (client, pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED),
-				       PK_PROVIDES_ENUM_HARDWARE_DRIVER, udi, &error);
-	if (!ret) {
-		egg_warning ("Error calling pk_client_what_provides :%s", error->message);
+	GPtrArray *array = NULL;
+	const PkItemPackage *item = NULL;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get provides: %s", error->message);
 		g_error_free (error);
-		error = NULL;
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get provides: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 		goto out;
 	}
 
 	/* If there are no driver packages available just return */
-	list = pk_client_get_package_list (client);
-	length = pk_package_list_get_size (list);
-	if (length == 0) {
+	array = pk_results_get_package_array (results);
+	if (array->len == 0) {
 		egg_debug ("no drivers available");
 		goto out;
 	}
 
 	/* only install the first one? */
-	obj = pk_package_list_get_obj (list, 0);
-	package = gpk_package_id_format_oneline (obj->id, obj->summary);
+	item = g_ptr_array_index (array, 0);
+	package = gpk_package_id_format_oneline (item->package_id, item->summary);
 
-	/* save list */
+	/* save array */
 	if (hardware->priv->package_ids != NULL)
 		g_strfreev (hardware->priv->package_ids);
-	hardware->priv->package_ids = pk_package_list_to_strv (list);
+	hardware->priv->package_ids = pk_package_array_to_strv (array);
 
 	/* TODO: tell the user what hardware, NOT JUST A UDI */
 	/* TRANSLATORS: we can install an extra package so this hardware works, e.g. firmware */
@@ -178,14 +198,30 @@ gpk_hardware_check_for_driver_available (GpkHardware *hardware, const gchar *udi
 		egg_warning ("error: %s", error->message);
 		g_error_free (error);
 	}
-
 out:
 	g_free (package);
 	g_free (message);
 	g_free (body);
-	if (list != NULL)
-		g_object_unref (list);
-	g_object_unref (client);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_hardware_check_for_driver_available:
+ **/
+static void
+gpk_hardware_check_for_driver_available (GpkHardware *hardware, const gchar *udi)
+{
+	gchar **values = NULL;
+	values = g_strsplit (udi, "&", -1);
+	pk_client_what_provides_async (PK_CLIENT(hardware->priv->task), pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED),
+				       PK_PROVIDES_ENUM_HARDWARE_DRIVER, values, NULL, NULL, NULL,
+				       (GAsyncReadyCallback) gpk_hardware_what_provides_cb, hardware);
+	g_strfreev (values);
 }
 
 static gboolean
@@ -251,6 +287,10 @@ gpk_hardware_init (GpkHardware *hardware)
 		egg_debug ("hardware driver checking disabled in GConf");
 		return;
 	}
+	hardware->priv->task = PK_TASK(gpk_task_new ());
+	g_object_set (hardware->priv->task,
+		      "background", TRUE,
+		      NULL);
 
 	hardware->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
 	if (error != NULL) {
@@ -298,6 +338,7 @@ gpk_hardware_finalize (GObject *object)
 
 	g_return_if_fail (hardware->priv != NULL);
 	g_object_unref (hardware->priv->gconf_client);
+	g_object_unref (PK_CLIENT(hardware->priv->task));
 	g_strfreev (hardware->priv->package_ids);
 
 	G_OBJECT_CLASS (gpk_hardware_parent_class)->finalize (object);
diff --git a/src/gpk-helper-chooser.c b/src/gpk-helper-chooser.c
index 2edf1a3..655970c 100644
--- a/src/gpk-helper-chooser.c
+++ b/src/gpk-helper-chooser.c
@@ -23,7 +23,7 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "gpk-helper-chooser.h"
 #include "gpk-marshal.h"
@@ -159,41 +159,38 @@ pk_treeview_add_general_columns (GtkTreeView *treeview)
  * Return value: if we agreed
  **/
 gboolean
-gpk_helper_chooser_show (GpkHelperChooser *helper, PkPackageList *list)
+gpk_helper_chooser_show (GpkHelperChooser *helper, GPtrArray *list)
 {
 	GtkWidget *widget;
 	gchar *text;
 	const gchar *icon_name;
-	guint len;
 	guint i;
-	const PkPackageObj *obj;
-	gchar *package_id;
+	const PkItemPackage *item;
 	GtkTreeIter iter;
+	gchar **split;
 
 	g_return_val_if_fail (GPK_IS_HELPER_CHOOSER (helper), FALSE);
 	g_return_val_if_fail (list != NULL, FALSE);
 
 	/* see what we've got already */
-	len = pk_package_list_get_size (list);
-	for (i=0; i<len; i++) {
-		obj = pk_package_list_get_obj (list, i);
-		egg_debug ("package '%s' got:", obj->id->name);
+	for (i=0; i<list->len; i++) {
+		item = g_ptr_array_index (list, i);
+		egg_debug ("package '%s' got:", item->package_id);
 
 		/* put formatted text into treeview */
 		gtk_list_store_append (helper->priv->list_store, &iter);
-		text = gpk_package_id_format_twoline (obj->id, obj->summary);
+		text = gpk_package_id_format_twoline (item->package_id, item->summary);
 
 		/* get the icon */
-		icon_name = gpk_desktop_guess_icon_name (helper->priv->desktop, obj->id->name);
+		split = pk_package_id_split (item->package_id);
+		icon_name = gpk_desktop_guess_icon_name (helper->priv->desktop, split[PK_PACKAGE_ID_NAME]);
+		g_strfreev (split);
 		if (icon_name == NULL)
-			icon_name = gpk_info_enum_to_icon_name (obj->info);
+			icon_name = gpk_info_enum_to_icon_name (item->info);
 
-		package_id = pk_package_id_to_string (obj->id);
 		gtk_list_store_set (helper->priv->list_store, &iter,
 				    GPK_CHOOSER_COLUMN_TEXT, text,
-				    GPK_CHOOSER_COLUMN_ID, package_id, -1);
-		g_free (package_id);
-		package_id = NULL;
+				    GPK_CHOOSER_COLUMN_ID, item->package_id, -1);
 		gtk_list_store_set (helper->priv->list_store, &iter, GPK_CHOOSER_COLUMN_ICON, icon_name, -1);
 		g_free (text);
 	}
@@ -264,7 +261,7 @@ gpk_helper_chooser_init (GpkHelperChooser *helper)
 	/* get UI */
 	helper->priv->builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (helper->priv->builder, GPK_DATA "/gpk-log.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 	}
diff --git a/src/gpk-helper-chooser.h b/src/gpk-helper-chooser.h
index 2c108b5..a918036 100644
--- a/src/gpk-helper-chooser.h
+++ b/src/gpk-helper-chooser.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 G_BEGIN_DECLS
 
@@ -58,7 +58,7 @@ GpkHelperChooser	*gpk_helper_chooser_new		(void);
 gboolean	 gpk_helper_chooser_set_parent		(GpkHelperChooser	*helper,
 							 GtkWindow		*window);
 gboolean	 gpk_helper_chooser_show		(GpkHelperChooser	*helper,
-							 PkPackageList		*list);
+							 GPtrArray		*list);
 
 G_END_DECLS
 
diff --git a/src/gpk-helper-run.c b/src/gpk-helper-run.c
index e793df1..df7091d 100644
--- a/src/gpk-helper-run.c
+++ b/src/gpk-helper-run.c
@@ -23,7 +23,7 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "gpk-helper-run.h"
 #include "gpk-marshal.h"
@@ -201,7 +201,7 @@ pk_treeview_add_general_columns (GtkTreeView *treeview)
 static gboolean
 gpk_helper_run_add_desktop_file (GpkHelperRun *helper, const gchar *package_id, const gchar *filename)
 {
-	gboolean ret;
+	gboolean ret = FALSE;
 	gchar *icon = NULL;
 	gchar *text = NULL;
 	gchar *fulltext = NULL;
@@ -212,7 +212,6 @@ gpk_helper_run_add_desktop_file (GpkHelperRun *helper, const gchar *package_id,
 	gchar *menu_path = NULL;
 	GtkTreeIter iter;
 	GKeyFile *file = NULL;
-	PkPackageId *id;
 	gint weight;
 	gboolean hidden;
 
@@ -284,15 +283,13 @@ gpk_helper_run_add_desktop_file (GpkHelperRun *helper, const gchar *package_id,
 	/* put formatted text into treeview */
 	gtk_list_store_append (helper->priv->list_store, &iter);
 	joint = g_strdup_printf ("%s - %s", name, summary);
-	id = pk_package_id_new_from_string (package_id);
-	text = gpk_package_id_format_twoline (id, joint);
+	text = gpk_package_id_format_twoline (package_id, joint);
 	if (menu_path != NULL) {
 		/* TRANSLATORS: the path in the menu, e.g. Applications -> Games -> Dave */
 		fulltext = g_strdup_printf("%s\n\n<i>%s</i>", text, menu_path);
 		g_free (text);
 		text = fulltext;
 	}
-	pk_package_id_free (id);
 
 	gtk_list_store_set (helper->priv->list_store, &iter,
 			    GPK_CHOOSER_COLUMN_TEXT, fulltext,
@@ -347,8 +344,7 @@ gpk_helper_run_add_package_ids (GpkHelperRun *helper, gchar **package_ids)
 				if (ret)
 					added++;
 			}
-			g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-			g_ptr_array_free (array, TRUE);
+			g_ptr_array_unref (array);
 		}
 		g_strfreev (parts);
 	}
@@ -445,7 +441,7 @@ gpk_helper_run_init (GpkHelperRun *helper)
 	/* get UI */
 	helper->priv->builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (helper->priv->builder, GPK_DATA "/gpk-log.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 	}
diff --git a/src/gpk-inhibit.c b/src/gpk-inhibit.c
index 6f87ae2..2194a9a 100644
--- a/src/gpk-inhibit.c
+++ b/src/gpk-inhibit.c
@@ -35,7 +35,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <dbus/dbus-glib.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "gpk-inhibit.h"
diff --git a/src/gpk-install-catalog.c b/src/gpk-install-catalog.c
index ca5c2dc..d103391 100644
--- a/src/gpk-install-catalog.c
+++ b/src/gpk-install-catalog.c
@@ -25,7 +25,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <locale.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <dbus/dbus-glib.h>
 
 #include "egg-debug.h"
diff --git a/src/gpk-language.c b/src/gpk-language.c
index efd8347..66c1167 100644
--- a/src/gpk-language.c
+++ b/src/gpk-language.c
@@ -244,7 +244,7 @@ gpk_language_test (EggTest *test)
 
 	/************************************************************/
 	egg_test_title (test, "get data (missing)");
-	lang = gpk_language_iso639_to_language (language, "XxX");
+	lang = gpk_language_iso639_to_language (language, "notgoingtoexist");
 	if (lang == NULL)
 		egg_test_success (test, NULL);
 	else
diff --git a/src/gpk-log.c b/src/gpk-log.c
index e6880d5..f33eb80 100644
--- a/src/gpk-log.c
+++ b/src/gpk-log.c
@@ -25,30 +25,25 @@
 #include <glib/gi18n.h>
 
 #include <gtk/gtk.h>
-#include <math.h>
-#include <string.h>
-#include <dbus/dbus-glib.h>
 #include <locale.h>
 #include <sys/types.h>
 #include <pwd.h>
 
 #include <gconf/gconf-client.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <unique/unique.h>
 
 #include "egg-debug.h"
-#include "egg-string.h"
 
 #include "gpk-common.h"
 #include "gpk-gnome.h"
-#include "gpk-enum.h"
 
 static GtkBuilder *builder = NULL;
 static GtkListStore *list_store = NULL;
 static PkClient *client = NULL;
 static gchar *transaction_id = NULL;
 static gchar *filter = NULL;
-static PkObjList *transactions = NULL;
+static GPtrArray *transactions = NULL;
 static GtkTreePath *path_global = NULL;
 
 enum
@@ -193,7 +188,6 @@ gpk_log_get_type_line (gchar **array, PkInfoEnum info)
 	gchar *text;
 	gchar *whole;
 	gchar **sections;
-	PkPackageId *id;
 
 	string = g_string_new ("");
 	size = g_strv_length (array);
@@ -204,11 +198,9 @@ gpk_log_get_type_line (gchar **array, PkInfoEnum info)
 		sections = g_strsplit (array[i], "\t", 0);
 		info_local = pk_info_enum_from_text (sections[0]);
 		if (info_local == info) {
-			id = pk_package_id_new_from_string (sections[1]);
-			text = gpk_package_id_format_oneline (id, NULL);
+			text = gpk_package_id_format_oneline (sections[1], NULL);
 			g_string_append_printf (string, "%s, ", text);
 			g_free (text);
-			pk_package_id_free (id);
 		}
 		g_strfreev (sections);
 	}
@@ -387,18 +379,18 @@ gpk_log_message_received_cb (UniqueApp *app, UniqueCommand command, UniqueMessag
  * gpk_log_filter:
  **/
 static gboolean
-gpk_log_filter (const PkTransactionObj *obj)
+gpk_log_filter (const PkItemTransaction *item)
 {
 	gboolean ret = FALSE;
 	guint i;
 	guint length;
 	gchar **sections;
 	gchar **packages;
-	PkPackageId *id;
+	gchar **split;
 
 	/* only show transactions that succeeded */
-	if (!obj->succeeded) {
-		egg_debug ("tid %s did not succeed, so not adding", obj->tid);
+	if (!item->succeeded) {
+		egg_debug ("tid %s did not succeed, so not adding", item->tid);
 		return FALSE;
 	}
 
@@ -406,11 +398,11 @@ gpk_log_filter (const PkTransactionObj *obj)
 		return TRUE;
 
 	/* matches cmdline */
-	if (obj->cmdline != NULL && g_strrstr (obj->cmdline, filter) != NULL)
+	if (item->cmdline != NULL && g_strrstr (item->cmdline, filter) != NULL)
 		ret = TRUE;
 
 	/* look in all the data for the filter string */
-	packages = g_strsplit (obj->data, "\n", 0);
+	packages = g_strsplit (item->data, "\n", 0);
 	length = g_strv_length (packages);
 	for (i=0; i<length; i++) {
 		sections = g_strsplit (packages[i], "\t", 0);
@@ -420,15 +412,15 @@ gpk_log_filter (const PkTransactionObj *obj)
 			ret = TRUE;
 
 		/* check to see if package name, version or arch matches */
-		id = pk_package_id_new_from_string (sections[1]);
-		if (g_strrstr (id->name, filter) != NULL)
+		split = pk_package_id_split (sections[1]);
+		if (g_strrstr (split[0], filter) != NULL)
 			ret = TRUE;
-		if (id->version != NULL && g_strrstr (id->version, filter) != NULL)
+		if (split[1] != NULL && g_strrstr (split[1], filter) != NULL)
 			ret = TRUE;
-		if (id->arch != NULL && g_strrstr (id->arch, filter) != NULL)
+		if (split[2] != NULL && g_strrstr (split[2], filter) != NULL)
 			ret = TRUE;
 
-		pk_package_id_free (id);
+		g_strfreev (split);
 		g_strfreev (sections);
 
 		/* shortcut for speed */
@@ -442,10 +434,10 @@ gpk_log_filter (const PkTransactionObj *obj)
 }
 
 /**
- * gpk_log_add_obj
+ * gpk_log_add_item
  **/
 static void
-gpk_log_add_obj (const PkTransactionObj *obj)
+gpk_log_add_item (const PkItemTransaction *item)
 {
 	GtkTreeIter iter;
 	gchar *details;
@@ -461,15 +453,15 @@ gpk_log_add_obj (const PkTransactionObj *obj)
 	GtkTreeModel *model = gtk_tree_view_get_model (treeview);
 
 	/* put formatted text into treeview */
-	details = gpk_log_get_details_localised (obj->timespec, obj->data);
-	date = gpk_log_get_localised_date (obj->timespec);
+	details = gpk_log_get_details_localised (item->timespec, item->data);
+	date = gpk_log_get_localised_date (item->timespec);
 	date_part = g_strsplit (date, ", ", 2);
 
-	icon_name = gpk_role_enum_to_icon_name (obj->role);
-	role_text = gpk_role_enum_to_localised_past (obj->role);
+	icon_name = gpk_role_enum_to_icon_name (item->role);
+	role_text = gpk_role_enum_to_localised_past (item->role);
 
 	/* query real name */
-	pw = getpwuid(obj->uid);
+	pw = getpwuid(item->uid);
 	if (pw != NULL) {
 		if (pw->pw_gecos != NULL)
 			username = pw->pw_gecos;
@@ -478,29 +470,29 @@ gpk_log_add_obj (const PkTransactionObj *obj)
 	}
 
 	/* get nice name for tool name */
-	if (g_strcmp0 (obj->cmdline, "pkcon") == 0)
+	if (g_strcmp0 (item->cmdline, "pkcon") == 0)
 		/* TRANSLATORS: short name for pkcon */
 		tool = _("Command line client");
-	else if (g_strcmp0 (obj->cmdline, "gpk-application") == 0)
+	else if (g_strcmp0 (item->cmdline, "gpk-application") == 0)
 		/* TRANSLATORS: short name for gpk-update-viewer */
 		tool = _("Add/Remove Software");
-	else if (g_strcmp0 (obj->cmdline, "gpk-update-viewer") == 0)
+	else if (g_strcmp0 (item->cmdline, "gpk-update-viewer") == 0)
 		/* TRANSLATORS: short name for gpk-update-viewer */
 		tool = _("Update System");
-	else if (g_strcmp0 (obj->cmdline, "gpk-update-icon") == 0)
+	else if (g_strcmp0 (item->cmdline, "gpk-update-icon") == 0)
 		/* TRANSLATORS: short name for gpk-update-icon */
 		tool = _("Update Icon");
 	else
-		tool = obj->cmdline;
+		tool = item->cmdline;
 
-	gpk_log_model_get_iter (model, &iter, obj->tid);
+	gpk_log_model_get_iter (model, &iter, item->tid);
 	gtk_list_store_set (list_store, &iter,
 			    GPK_LOG_COLUMN_ICON, icon_name,
-			    GPK_LOG_COLUMN_TIMESPEC, obj->timespec,
+			    GPK_LOG_COLUMN_TIMESPEC, item->timespec,
 			    GPK_LOG_COLUMN_DATE, date_part[1],
 			    GPK_LOG_COLUMN_ROLE, role_text,
 			    GPK_LOG_COLUMN_DETAILS, details,
-			    GPK_LOG_COLUMN_ID, obj->tid,
+			    GPK_LOG_COLUMN_ID, item->tid,
 			    GPK_LOG_COLUMN_USER, username,
 			    GPK_LOG_COLUMN_TOOL, tool,
 			    GPK_LOG_COLUMN_ACTIVE, TRUE, -1);
@@ -523,7 +515,7 @@ gpk_log_refilter (void)
 {
 	guint i;
 	gboolean ret;
-	const PkTransactionObj *obj;
+	const PkItemTransaction *item;
 	GtkWidget *widget;
 	const gchar *package;
 	GtkTreeView *treeview;
@@ -533,7 +525,7 @@ gpk_log_refilter (void)
 	g_free (filter);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
 	package = gtk_entry_get_text (GTK_ENTRY(widget));
-	if (!egg_strzero (package))
+	if (package != NULL && package[0] != '\0')
 		filter = g_strdup (package);
 	else
 		filter = NULL;
@@ -547,10 +539,10 @@ gpk_log_refilter (void)
 
 	/* go through the list, adding and removing the items as required */
 	for (i=0; i<transactions->len; i++) {
-		obj = pk_obj_list_index (transactions, i);
-		ret = gpk_log_filter (obj);
+		item = g_ptr_array_index (transactions, i);
+		ret = gpk_log_filter (item);
 		if (ret)
-			gpk_log_add_obj (obj);
+			gpk_log_add_item (item);
 	}
 
 	/* remove the items that are not used */
@@ -558,38 +550,52 @@ gpk_log_refilter (void)
 }
 
 /**
- * gpk_log_refresh
+ * gpk_log_get_old_transactions_cb
  **/
-static gboolean
-gpk_log_refresh (void)
+static void
+gpk_log_get_old_transactions_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 {
-	gboolean ret;
+//	PkClient *client = PK_CLIENT (object);
 	GError *error = NULL;
+	PkResults *results = NULL;
+	PkItemErrorCode *error_item = NULL;
 
-	ret = pk_client_reset (client, &error);
-	if (!ret) {
-		egg_warning ("failed to reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get old transactions: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
-	ret = pk_client_get_old_transactions (client, 0, &error);
-	if (!ret) {
-		egg_warning ("failed to get list: %s", error->message);
-		g_error_free (error);
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get old transactions: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 		goto out;
 	}
 
 	/* get the list */
 	if (transactions != NULL)
-		g_object_unref (transactions);
-#if PK_CHECK_VERSION(0,5,0)
-	transactions = pk_client_get_transaction_list (client);
-#else
-	transactions = pk_client_get_cached_objects (client); /* removed in 0.5.x */
-#endif
+		g_ptr_array_unref (transactions);
+	transactions = pk_results_get_transaction_array (results);
 	gpk_log_refilter ();
 out:
-	return ret;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_log_refresh
+ **/
+static void
+gpk_log_refresh (void)
+{
+	/* get the list async */
+	pk_client_get_old_transactions_async (client, 0, NULL, NULL, NULL,
+					      (GAsyncReadyCallback) gpk_log_get_old_transactions_cb, NULL);
 }
 
 /**
@@ -659,7 +665,6 @@ main (int argc, char *argv[])
 
 	if (! g_thread_supported ())
 		g_thread_init (NULL);
-	dbus_g_thread_init ();
 	g_type_init ();
 
 	context = g_option_context_new (NULL);
@@ -691,13 +696,14 @@ main (int argc, char *argv[])
 					   GPK_DATA G_DIR_SEPARATOR_S "icons");
 
 	client = pk_client_new ();
-	pk_client_set_use_buffer (client, TRUE, NULL);
-	pk_client_set_synchronous (client, TRUE, NULL);
+	g_object_set (client,
+		      "background", FALSE,
+		      NULL);
 
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-log.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -726,6 +732,7 @@ main (int argc, char *argv[])
 	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_help_cb), NULL);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_refresh"));
 	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_refresh_cb), NULL);
+	gtk_widget_hide (widget);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_filter"));
 	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_filter_cb), NULL);
 
@@ -768,9 +775,6 @@ main (int argc, char *argv[])
 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
 					      GPK_LOG_COLUMN_TIMESPEC, GTK_SORT_DESCENDING);
 
-	/* get the update list */
-	gpk_log_refresh ();
-
 	/* show */
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_simple"));
 	gtk_widget_show (widget);
@@ -781,6 +785,9 @@ main (int argc, char *argv[])
 		gpk_window_set_parent_xid (GTK_WINDOW (widget), xid);
 	}
 
+	/* get the update list */
+	gpk_log_refresh ();
+
 	gtk_main ();
 
 out_build:
@@ -790,7 +797,7 @@ out_build:
 	g_free (transaction_id);
 	g_free (filter);
 	if (transactions != NULL)
-		g_object_unref (transactions);
+		g_ptr_array_unref (transactions);
 unique_out:
 	g_object_unref (unique_app);
 	return 0;
diff --git a/src/gpk-modal-dialog.c b/src/gpk-modal-dialog.c
index 4fe4802..89220bc 100644
--- a/src/gpk-modal-dialog.c
+++ b/src/gpk-modal-dialog.c
@@ -34,7 +34,7 @@
 #include <sys/wait.h>
 #include <fcntl.h>
 #include <glib/gi18n.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
@@ -390,11 +390,12 @@ gpk_modal_dialog_make_progressbar_pulse (GpkModalDialog *dialog)
  * gpk_modal_dialog_set_percentage:
  **/
 gboolean
-gpk_modal_dialog_set_percentage (GpkModalDialog *dialog, guint percentage)
+gpk_modal_dialog_set_percentage (GpkModalDialog *dialog, gint percentage)
 {
 	GtkProgressBar *progress_bar;
 
 	g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+	g_return_val_if_fail (percentage <= 100, FALSE);
 
 	egg_debug ("setting percentage: %u", percentage);
 
@@ -405,7 +406,7 @@ gpk_modal_dialog_set_percentage (GpkModalDialog *dialog, guint percentage)
 	}
 
 	/* either pulse or set percentage */
-	if (percentage == PK_CLIENT_PERCENTAGE_INVALID)
+	if (percentage < 0)
 		gpk_modal_dialog_make_progressbar_pulse (dialog);
 	else
 		gtk_progress_bar_set_fraction (progress_bar, (gfloat) percentage / 100.0);
@@ -629,56 +630,53 @@ gpk_modal_dialog_button_cancel_cb (GtkWidget *widget_button, GpkModalDialog *dia
  * gpk_modal_dialog_set_package_list:
  **/
 gboolean
-gpk_modal_dialog_set_package_list (GpkModalDialog *dialog, const PkPackageList *list)
+gpk_modal_dialog_set_package_list (GpkModalDialog *dialog, const GPtrArray *list)
 {
 	GtkTreeIter iter;
-	const PkPackageObj *obj;
+	const PkItemPackage *item;
 	PkDesktop *desktop;
 	gchar *icon;
-	gchar *package_id;
 	gchar *text;
-	guint length;
 	guint i;
 	GtkWidget *widget;
+	gchar **split;
 
 	gtk_list_store_clear (dialog->priv->store);
 
-	length = pk_package_list_get_size (list);
 	widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "scrolledwindow_packages"));
-	if (length > 5)
+	if (list->len > 5)
 		gtk_widget_set_size_request (widget, -1, 300);
-	else if (length > 1)
+	else if (list->len > 1)
 		gtk_widget_set_size_request (widget, -1, 150);
 
 	desktop = pk_desktop_new ();
-	length = pk_package_list_get_size (list);
 
 	/* add each well */
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
+	for (i=0; i<list->len; i++) {
+		item = g_ptr_array_index (list, i);
 
 		/* not installed, so ignore icon */
-		if (obj->info == PK_INFO_ENUM_DOWNLOADING ||
-		    obj->info == PK_INFO_ENUM_CLEANUP)
+		if (item->info == PK_INFO_ENUM_DOWNLOADING ||
+		    item->info == PK_INFO_ENUM_CLEANUP)
 			continue;
 
-		text = gpk_package_id_format_twoline (obj->id, obj->summary);
-		package_id = pk_package_id_to_string (obj->id);
+		text = gpk_package_id_format_twoline (item->package_id, item->summary);
 
 		/* get the icon */
-		icon = gpk_desktop_guess_icon_name (desktop, obj->id->name);
+		split = pk_package_id_split (item->package_id);
+		icon = gpk_desktop_guess_icon_name (desktop, split[0]);
 		if (icon == NULL)
 			icon = g_strdup (gpk_info_enum_to_icon_name (PK_INFO_ENUM_INSTALLED));
 
 		gtk_list_store_append (dialog->priv->store, &iter);
 		gtk_list_store_set (dialog->priv->store, &iter,
 				    GPK_MODAL_DIALOG_STORE_IMAGE, icon,
-				    GPK_MODAL_DIALOG_STORE_ID, package_id,
+				    GPK_MODAL_DIALOG_STORE_ID, item->package_id,
 				    GPK_MODAL_DIALOG_STORE_TEXT, text,
 				    -1);
+		g_strfreev (split);
 		g_free (icon);
 		g_free (text);
-		g_free (package_id);
 	}
 
 	g_object_unref (desktop);
@@ -804,7 +802,7 @@ gpk_modal_dialog_init (GpkModalDialog *dialog)
 	/* get UI */
 	dialog->priv->builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (dialog->priv->builder, GPK_DATA "/gpk-client.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -905,8 +903,8 @@ gpk_modal_dialog_test (EggTest *test)
 {
 	GtkResponseType button;
 	GpkModalDialog *dialog = NULL;
-	PkPackageList *list;
-	PkPackageId *id;
+	GPtrArray *array;
+	PkItemPackage *item;
 
 	if (!egg_test_start (test, "GpkModalDialog"))
 		return;
@@ -920,13 +918,13 @@ gpk_modal_dialog_test (EggTest *test)
 		egg_test_failed (test, NULL);
 
 	/* set some packages */
-	list = pk_package_list_new ();
-	id = pk_package_id_new_from_list ("totem", "0.0.1", "i386", "fedora-newkey");
-	pk_package_list_add (list, PK_INFO_ENUM_INSTALLED, id, "Totem is a music player for GNOME");
-	pk_package_list_add (list, PK_INFO_ENUM_AVAILABLE, id, "Amarok is a music player for KDE");
-	gpk_modal_dialog_set_package_list (dialog, list);
-	pk_package_id_free (id);
-	g_object_unref (list);
+	array = g_ptr_array_new_with_free_func ((GDestroyNotify) pk_item_package_unref);
+	item = pk_item_package_new (PK_INFO_ENUM_INSTALLED, "totem;001;i386;fedora", "Totem is a music player for GNOME");
+	g_ptr_array_add (array, item);
+	item = pk_item_package_new (PK_INFO_ENUM_AVAILABLE, "totem;001;i386;fedora", "Amarok is a music player for KDE");
+	g_ptr_array_add (array, item);
+	gpk_modal_dialog_set_package_list (dialog, array);
+	g_ptr_array_unref (array);
 
 	/************************************************************/
 	egg_test_title (test, "help button");
@@ -961,7 +959,7 @@ gpk_modal_dialog_test (EggTest *test)
 	gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
 	gpk_modal_dialog_set_title (dialog, "Refresh cache");
 	gpk_modal_dialog_set_image_status (dialog, PK_STATUS_ENUM_REFRESH_CACHE);
-	gpk_modal_dialog_set_percentage (dialog, 101);
+	gpk_modal_dialog_set_percentage (dialog, -1);
 	gpk_modal_dialog_present (dialog);
 	gpk_modal_dialog_run (dialog);
 	egg_test_success (test, NULL);
@@ -986,7 +984,7 @@ gpk_modal_dialog_test (EggTest *test)
 	gpk_modal_dialog_set_title (dialog, "Button press test");
 	gpk_modal_dialog_set_message (dialog, "Please press close");
 	gpk_modal_dialog_set_image_status (dialog, PK_STATUS_ENUM_INSTALL);
-	gpk_modal_dialog_set_percentage (dialog, 101);
+	gpk_modal_dialog_set_percentage (dialog, -1);
 	gpk_modal_dialog_present (dialog);
 	button = gpk_modal_dialog_run (dialog);
 	if (button == GTK_RESPONSE_CLOSE)
diff --git a/src/gpk-modal-dialog.h b/src/gpk-modal-dialog.h
index d907823..899c649 100644
--- a/src/gpk-modal-dialog.h
+++ b/src/gpk-modal-dialog.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 G_BEGIN_DECLS
 
@@ -94,7 +94,7 @@ gboolean	 gpk_modal_dialog_present		(GpkModalDialog		*dialog);
 gboolean	 gpk_modal_dialog_present_with_time	(GpkModalDialog		*dialog,
 							 guint32		 timestamp);
 gboolean	 gpk_modal_dialog_set_package_list	(GpkModalDialog		*dialog,
-							 const PkPackageList	*list);
+							 const GPtrArray	*list);
 gboolean	 gpk_modal_dialog_set_parent		(GpkModalDialog		*dialog,
 							 GdkWindow		*window);
 gboolean	 gpk_modal_dialog_set_window_icon	(GpkModalDialog		*dialog,
@@ -106,7 +106,7 @@ gboolean	 gpk_modal_dialog_set_message		(GpkModalDialog		*dialog,
 gboolean	 gpk_modal_dialog_set_action		(GpkModalDialog		*dialog,
 							 const gchar		*action);
 gboolean	 gpk_modal_dialog_set_percentage	(GpkModalDialog		*dialog,
-							 guint			 percentage);
+							 gint			 percentage);
 gboolean	 gpk_modal_dialog_set_remaining		(GpkModalDialog		*dialog,
 							 guint			 remaining);
 gboolean	 gpk_modal_dialog_set_image		(GpkModalDialog		*dialog,
diff --git a/src/gpk-prefs.c b/src/gpk-prefs.c
index 75c0f00..f18b615 100644
--- a/src/gpk-prefs.c
+++ b/src/gpk-prefs.c
@@ -31,7 +31,7 @@
 #include <string.h>
 #include <dbus/dbus-glib.h>
 #include <gconf/gconf-client.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <unique/unique.h>
 
 #include <gpk-common.h>
@@ -158,7 +158,6 @@ gpk_prefs_update_combo_changed (GtkWidget *widget, gpointer data)
 	const gchar *action;
 	GpkUpdateEnum update = GPK_UPDATE_ENUM_UNKNOWN;
 	GConfClient *client;
-	GtkWidget *notify_widget;
 
 	client = gconf_client_get_default ();
 	value = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
@@ -166,7 +165,6 @@ gpk_prefs_update_combo_changed (GtkWidget *widget, gpointer data)
 		egg_warning ("value NULL");
 		return;
 	}
-	notify_widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_notify_updates"));
 	if (strcmp (value, PK_UPDATE_ALL_TEXT) == 0) {
 		update = GPK_UPDATE_ENUM_ALL;
 	} else if (strcmp (value, PK_UPDATE_SECURITY_TEXT) == 0) {
@@ -361,14 +359,18 @@ gpk_prefs_message_received_cb (UniqueApp *app, UniqueCommand command, UniqueMess
 }
 
 /**
- * gpk_prefs_network_status_changed_cb:
+ * gpk_prefs_notify_network_state_cb:
  **/
 static void
-gpk_prefs_network_status_changed_cb (PkControl *control, PkNetworkEnum state, gpointer data)
+gpk_prefs_notify_network_state_cb (PkControl *control, GParamSpec *pspec, gpointer data)
 {
 	GtkWidget *widget;
+	PkNetworkEnum state;
 
 	/* only show label on mobile broadband */
+	g_object_get (control,
+		      "network-state", &state,
+		      NULL);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_mobile_broadband"));
 	if (state == PK_NETWORK_ENUM_MOBILE)
 		gtk_widget_show (widget);
@@ -377,6 +379,93 @@ gpk_prefs_network_status_changed_cb (PkControl *control, PkNetworkEnum state, gp
 }
 
 /**
+ * pk_prefs_get_properties_cb:
+ **/
+static void
+pk_prefs_get_properties_cb (GObject *object, GAsyncResult *res, GMainLoop *loop)
+{
+	GtkWidget *widget;
+	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
+	gboolean ret;
+	PkBitfield roles;
+
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
+	if (!ret) {
+		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
+		g_print ("%s: %s\n", _("Exiting as backend details could not be retrieved"), error->message);
+		g_error_free (error);
+		g_main_loop_quit (loop);
+		goto out;
+	}
+
+	/* get values */
+	g_object_get (control,
+		      "roles", &roles,
+		      NULL);
+
+	/* hide if not supported */
+	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DISTRO_UPGRADES)) {
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_upgrade"));
+		gtk_widget_hide (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_upgrade"));
+		gtk_widget_hide (widget);
+	}
+out:
+	return;
+}
+
+/**
+ * pk_prefs_get_network_state_cb:
+ **/
+static void
+pk_prefs_get_network_state_cb (GObject *object, GAsyncResult *res, GMainLoop *loop)
+{
+	GtkWidget *widget;
+	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
+	PkNetworkEnum state;
+
+	/* get the result */
+	state = pk_control_get_network_state_finish (control, res, &error);
+	if (state == PK_NETWORK_ENUM_UNKNOWN) {
+		egg_warning ("network status unknown: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* only show label on mobile broadband */
+	if (state == PK_NETWORK_ENUM_MOBILE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_mobile_broadband"));
+		gtk_widget_show (widget);
+	}
+out:
+	return;
+}
+
+/**
+ * gpk_prefs_close_cb:
+ **/
+static void
+gpk_prefs_close_cb (GtkWidget *widget, gpointer data)
+{
+	GMainLoop *loop = (GMainLoop *) data;
+	egg_debug ("emitting action-close");
+	g_main_loop_quit (loop);
+}
+
+/**
+ * gpk_prefs_delete_event_cb:
+ **/
+static gboolean
+gpk_prefs_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+	gpk_prefs_close_cb (widget, data);
+	return FALSE;
+}
+
+/**
  * main:
  **/
 int
@@ -387,13 +476,12 @@ main (int argc, char *argv[])
 	GOptionContext *context;
 	GtkWidget *main_window;
 	GtkWidget *widget;
-	PkBitfield roles;
 	PkControl *control;
 	UniqueApp *unique_app;
-	PkNetworkEnum state;
 	guint retval;
 	guint xid = 0;
 	GError *error = NULL;
+	GMainLoop *loop;
 
 	const GOptionEntry options[] = {
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
@@ -443,16 +531,15 @@ main (int argc, char *argv[])
 			  G_CALLBACK (gpk_prefs_message_received_cb), NULL);
 
 	/* get actions */
+	loop = g_main_loop_new (NULL, FALSE);
 	control = pk_control_new ();
-	g_signal_connect (control, "network-state-changed",
-			  G_CALLBACK (gpk_prefs_network_status_changed_cb), NULL);
-	roles = pk_control_get_actions (control, NULL);
-	state = pk_control_get_network_state (control, NULL);
+	g_signal_connect (control, "notify::network-state",
+			  G_CALLBACK (gpk_prefs_notify_network_state_cb), NULL);
 
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-prefs.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -463,38 +550,24 @@ main (int argc, char *argv[])
 	/* Hide window first so that the dialogue resizes itself without redrawing */
 	gtk_widget_hide (main_window);
 	gtk_window_set_icon_name (GTK_WINDOW (main_window), GPK_ICON_SOFTWARE_UPDATE_PREFS);
-
-	/* Get the main window quit */
-	g_signal_connect_swapped (main_window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
+	g_signal_connect (main_window, "delete_event",
+			  G_CALLBACK (gpk_prefs_delete_event_cb), loop);
 
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_mobile_broadband"));
 	gpk_prefs_notify_checkbutton_setup (widget, GPK_CONF_CONNECTION_USE_MOBILE);
 
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
-	g_signal_connect_swapped (widget, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+	g_signal_connect (widget, "clicked",
+			  G_CALLBACK (gpk_prefs_close_cb), loop);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_help"));
 	g_signal_connect (widget, "clicked",
 			  G_CALLBACK (pk_button_help_cb), NULL);
 
-	/* only show label on mobile broadband */
-	if (state == PK_NETWORK_ENUM_MOBILE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_mobile_broadband"));
-		gtk_widget_show (widget);
-	}
-
 	/* update the combo boxes */
 	gpk_prefs_update_freq_combo_setup ();
 	gpk_prefs_upgrade_freq_combo_setup ();
 	gpk_prefs_auto_update_combo_setup ();
 
-	/* hide if not supported */
-	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DISTRO_UPGRADES)) {
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_upgrade"));
-		gtk_widget_hide (widget);
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_upgrade"));
-		gtk_widget_hide (widget);
-	}
-
 	gtk_widget_show (main_window);
 
 	/* set the parent window if it is specified */
@@ -503,10 +576,15 @@ main (int argc, char *argv[])
 		gpk_window_set_parent_xid (GTK_WINDOW (main_window), xid);
 	}
 
+	/* get some data */
+	pk_control_get_properties_async (control, NULL, (GAsyncReadyCallback) pk_prefs_get_properties_cb, loop);
+	pk_control_get_network_state_async (control, NULL, (GAsyncReadyCallback) pk_prefs_get_network_state_cb, loop);
+
 	/* wait */
-	gtk_main ();
+	g_main_loop_run (loop);
 
 out_build:
+	g_main_loop_unref (loop);
 	g_object_unref (control);
 	g_object_unref (builder);
 unique_out:
diff --git a/src/gpk-repo.c b/src/gpk-repo.c
index 2cce71c..d37f8f6 100644
--- a/src/gpk-repo.c
+++ b/src/gpk-repo.c
@@ -21,20 +21,15 @@
 
 #include "config.h"
 
-#include <glib.h>
 #include <glib/gi18n.h>
 #include <locale.h>
 
 #include <gtk/gtk.h>
-#include <math.h>
-#include <string.h>
-#include <dbus/dbus-glib.h>
 #include <gconf/gconf-client.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <unique/unique.h>
 
 #include "egg-debug.h"
-#include "egg-string.h"
 
 #include "gpk-gnome.h"
 #include "gpk-common.h"
@@ -44,20 +39,12 @@
 
 static GtkBuilder *builder = NULL;
 static GtkListStore *list_store = NULL;
-static PkClient *client_query = NULL;
-#if PK_CHECK_VERSION(0,5,1)
-static PkClientPool *pool = NULL;
-#else
-static GPtrArray *client_array = NULL;
-#endif
+static PkClient *client = NULL;
 static PkBitfield roles;
 static GConfClient *gconf_client;
 static gboolean show_details;
 static GtkTreePath *path_global = NULL;
 static GtkWidget *image_animation = NULL;
-#if !PK_CHECK_VERSION(0,5,1)
-static PkStatusEnum status_last = PK_STATUS_ENUM_UNKNOWN;
-#endif
 static guint status_id = 0;
 
 enum {
@@ -69,10 +56,6 @@ enum {
 	REPO_COLUMN_LAST
 };
 
-#if !PK_CHECK_VERSION(0,5,1)
-static PkClient *gpk_repo_create_client (void);
-#endif
-
 /**
  * gpk_repo_find_iter_model_cb:
  **/
@@ -164,6 +147,113 @@ gpk_button_help_cb (GtkWidget *widget, gboolean  data)
 	gpk_gnome_help ("software-sources");
 }
 
+/**
+ * gpk_repo_status_changed_timeout_cb:
+ **/
+static gboolean
+gpk_repo_status_changed_timeout_cb (PkProgress *progress)
+{
+	const gchar *text;
+	GtkWidget *widget;
+	PkStatusEnum status;
+
+	/* get the last status */
+	g_object_get (progress,
+		      "status", &status,
+		      NULL);
+
+	/* set the text and show */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_animation_preview"));
+	gtk_widget_show (widget);
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_animation"));
+	text = gpk_status_enum_to_localised_text (status);
+	gtk_label_set_label (GTK_LABEL (widget), text);
+
+	/* set icon */
+	gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (image_animation), status, GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+	/* never repeat */
+	status_id = 0;
+	return FALSE;
+}
+
+/**
+ * gpk_repo_progress_cb:
+ **/
+static void
+gpk_repo_progress_cb (PkProgress *progress, PkProgressType type, gpointer user_data)
+{
+	PkStatusEnum status;
+	GtkWidget *widget;
+
+	if (type != PK_PROGRESS_TYPE_STATUS)
+		return;
+
+	/* get value */
+	g_object_get (progress,
+		      "status", &status,
+		      NULL);
+	egg_debug ("now %s", pk_status_enum_to_text (status));
+
+	if (status == PK_STATUS_ENUM_FINISHED) {
+		/* we've not yet shown, so don't bother */
+		if (status_id > 0) {
+			g_source_remove (status_id);
+			status_id = 0;
+		}
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_animation_preview"));
+		gtk_widget_hide (widget);
+		gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (image_animation), FALSE);
+		goto out;
+	}
+
+	/* already pending show */
+	if (status_id > 0)
+		goto out;
+
+	/* only show after some time in the transaction */
+	status_id = g_timeout_add (GPK_UI_STATUS_SHOW_DELAY, (GSourceFunc) gpk_repo_status_changed_timeout_cb, progress);
+out:
+	return;
+}
+
+/**
+ * gpk_repo_repo_enable_cb
+ **/
+static void
+gpk_repo_repo_enable_cb (GObject *object, GAsyncResult *res, gpointer user_data)
+{
+//	PkClient *client = PK_CLIENT (object);
+	GError *error = NULL;
+	PkResults *results = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get set repo: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to set repo: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_repo"));
+		/* TRANSLATORS: for one reason or another, we could not enable or disable a software source */
+		gpk_error_dialog_modal (window, _("Failed to change status"),
+					gpk_error_enum_to_localised_text (error_item->code), error_item->details);
+		goto out;
+	}
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
 static void
 gpk_misc_enabled_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data)
 {
@@ -171,15 +261,12 @@ gpk_misc_enabled_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer
 	GtkTreeIter iter;
 	GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
 	gboolean enabled;
-	gchar *repo_id;
-	gboolean ret;
-	GError *error = NULL;
-	PkClient *client;
+	gchar *repo_id = NULL;
 
 	/* do we have the capability? */
 	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_REPO_ENABLE) == FALSE) {
 		egg_debug ("can't change state");
-		return;
+		goto out;
 	}
 
 	/* get toggled iter */
@@ -191,26 +278,17 @@ gpk_misc_enabled_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer
 	/* do something with the value */
 	enabled ^= 1;
 
-	/* do this to the repo */
-	egg_debug ("setting %s to %i", repo_id, enabled);
-#if PK_CHECK_VERSION(0,5,1)
-	client = pk_client_pool_create (pool);
-#else
-	client = gpk_repo_create_client ();
-#endif
-	ret = pk_client_repo_enable (client, repo_id, enabled, &error);
-	if (!ret) {
-		egg_warning ("could not set repo enabled state: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	g_object_unref (client);
-
 	/* set new value */
 	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
 			    REPO_COLUMN_SENSITIVE, FALSE,
 			    -1);
 
+	/* set the repo */
+	egg_debug ("setting %s to %i", repo_id, enabled);
+	pk_client_repo_enable_async (client, repo_id, enabled, NULL,
+				     gpk_repo_progress_cb, NULL,
+				     gpk_repo_repo_enable_cb, NULL);
+
 out:
 	/* clean up */
 	g_free (repo_id);
@@ -218,32 +296,6 @@ out:
 }
 
 /**
- * gpk_repo_detail_cb:
- **/
-static void
-gpk_repo_detail_cb (PkClient *client, const gchar *repo_id,
-		    const gchar *description, gboolean enabled, gpointer data)
-{
-	GtkTreeIter iter;
-	GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_repo"));
-	GtkTreeModel *model = gtk_tree_view_get_model (treeview);
-
-	egg_debug ("repo = %s:%s:%i", repo_id, description, enabled);
-
-	gpk_repo_model_get_iter (model, &iter, repo_id);
-	gtk_list_store_set (list_store, &iter,
-			    REPO_COLUMN_ENABLED, enabled,
-			    REPO_COLUMN_TEXT, description,
-			    REPO_COLUMN_ID, repo_id,
-			    REPO_COLUMN_ACTIVE, TRUE,
-			    REPO_COLUMN_SENSITIVE, TRUE,
-			    -1);
-
-	/* sort after each entry, which is okay as there shouldn't be many */
-	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(list_store), REPO_COLUMN_TEXT, GTK_SORT_ASCENDING);
-}
-
-/**
  * gpk_treeview_add_columns:
  **/
 static void
@@ -294,99 +346,71 @@ gpk_repos_treeview_clicked_cb (GtkTreeSelection *selection, gpointer data)
 }
 
 /**
- * gpk_repo_finished_cb:
+ * gpk_repo_get_repo_list_cb
  **/
 static void
-gpk_repo_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpointer data)
+gpk_repo_get_repo_list_cb (GObject *object, GAsyncResult *res, gpointer user_data)
 {
+//	PkClient *client = PK_CLIENT (object);
+	GError *error = NULL;
+	PkResults *results = NULL;
+	PkItemErrorCode *error_item = NULL;
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
+	GtkWindow *window;
+	GPtrArray *array = NULL;
+	guint i;
+	const PkItemRepoDetail *item;
+	GtkTreeIter iter;
 
-	/* remove the items that are not used */
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_repo"));
-	model = gtk_tree_view_get_model (treeview);
-	gpk_repo_remove_nonactive (model);
-}
-
-/**
- * gpk_repo_status_changed_timeout_cb:
- **/
-static gboolean
-gpk_repo_status_changed_timeout_cb (PkClient *client)
-{
-	const gchar *text;
-	GtkWidget *widget;
-	PkStatusEnum status;
-
-#if PK_CHECK_VERSION(0,5,1)
-	/* get the last status */
-	g_object_get (client,
-		      "status", &status,
-		      NULL);
-#else
-	status = status_last;
-#endif
-
-	/* set the text and show */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_animation_preview"));
-	gtk_widget_show (widget);
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_animation"));
-	text = gpk_status_enum_to_localised_text (status);
-	gtk_label_set_label (GTK_LABEL (widget), text);
-
-	/* set icon */
-	gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (image_animation), status, GTK_ICON_SIZE_LARGE_TOOLBAR);
-
-	/* never repeat */
-	status_id = 0;
-	return FALSE;
-}
-
-/**
- * gpk_repo_status_changed_cb:
- **/
-static void
-gpk_repo_status_changed_cb (PkClient *client, PkStatusEnum status, gpointer data)
-{
-	GtkWidget *widget;
-
-	if (status == PK_STATUS_ENUM_FINISHED) {
-		/* we've not yet shown, so don't bother */
-		if (status_id > 0) {
-			g_source_remove (status_id);
-			status_id = 0;
-		}
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_animation_preview"));
-		gtk_widget_hide (widget);
-		gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (image_animation), FALSE);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get repo list: %s", error->message);
+		g_error_free (error);
 		goto out;
 	}
 
-	/* already pending show */
-	if (status_id > 0)
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get repo list: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_repo"));
+		/* TRANSLATORS: for one reason or another, we could not get the list of sources */
+		gpk_error_dialog_modal (window, _("Failed to get the list of sources"),
+					gpk_error_enum_to_localised_text (error_item->code), error_item->details);
 		goto out;
+	}
 
-	/* only show after some time in the transaction */
-	status_id = g_timeout_add (GPK_UI_STATUS_SHOW_DELAY, (GSourceFunc) gpk_repo_status_changed_timeout_cb, client);
-out:
-#if !PK_CHECK_VERSION(0,5,1)
-	/* save for the callback */
-	status_last = status;
-#endif
-	return;
-}
+	/* add repos */
+	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_repo"));
+	model = gtk_tree_view_get_model (treeview);
+	array = pk_results_get_repo_detail_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		egg_debug ("repo = %s:%s:%i", item->repo_id, item->description, item->enabled);
+		gpk_repo_model_get_iter (model, &iter, item->repo_id);
+		gtk_list_store_set (list_store, &iter,
+				    REPO_COLUMN_ENABLED, item->enabled,
+				    REPO_COLUMN_TEXT, item->description,
+				    REPO_COLUMN_ID, item->repo_id,
+				    REPO_COLUMN_ACTIVE, TRUE,
+				    REPO_COLUMN_SENSITIVE, TRUE,
+				    -1);
+	}
 
-/**
- * gpk_repo_error_code_cb:
- **/
-static void
-gpk_repo_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *details, gpointer data)
-{
-	GtkWindow *window;
-	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_repo"));
-	/* TRANSLATORS: for one reason or another, we could not enable or disable a software source */
-	gpk_error_dialog_modal (window, _("Failed to change status"),
-				gpk_error_enum_to_localised_text (code), details);
+	/* remove the items that are not now present */
+	gpk_repo_remove_nonactive (model);
+
+	/* sort */
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(list_store), REPO_COLUMN_TEXT, GTK_SORT_ASCENDING);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
@@ -395,8 +419,6 @@ gpk_repo_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *det
 static void
 gpk_repo_repo_list_refresh (void)
 {
-	gboolean ret;
-	GError *error = NULL;
 	PkBitfield filters;
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
@@ -407,21 +429,13 @@ gpk_repo_repo_list_refresh (void)
 	gpk_repo_mark_nonactive (model);
 
 	egg_debug ("refreshing list");
-	ret = pk_client_reset (client_query, &error);
-	if (!ret) {
-		egg_warning ("failed to reset client: %s", error->message);
-		g_error_free (error);
-		return;
-	}
 	if (!show_details)
 		filters = pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT);
 	else
 		filters = pk_bitfield_value (PK_FILTER_ENUM_NONE);
-	ret = pk_client_get_repo_list (client_query, filters, &error);
-	if (!ret) {
-		egg_warning ("failed to get repo list: %s", error->message);
-		g_error_free (error);
-	}
+	pk_client_get_repo_list_async (client, filters, NULL,
+				       gpk_repo_progress_cb, NULL,
+				       gpk_repo_get_repo_list_cb, NULL);
 }
 
 /**
@@ -458,43 +472,80 @@ gpk_repo_message_received_cb (UniqueApp *app, UniqueCommand command, UniqueMessa
 	}
 }
 
-#if !PK_CHECK_VERSION(0,5,1)
+
 /**
- * gpk_repo_destroy_cb:
+ * gpk_repo_get_properties_cb:
  **/
 static void
-gpk_repo_destroy_cb (PkClient *client, gpointer data)
+gpk_repo_get_properties_cb (GObject *object, GAsyncResult *res, GMainLoop *loop)
 {
+	GtkWidget *widget;
+	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
 	gboolean ret;
-	egg_debug ("client destroyed");
-	ret = g_ptr_array_remove (client_array, client);
-	if (!ret)
-		egg_warning ("failed to remove %p", client);
-	/* TODO: disconnect signals? */
-	g_object_unref (client);
+//	PkBitfield roles;
+
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
+	if (!ret) {
+		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
+		g_print ("%s: %s\n", _("Exiting as backend details could not be retrieved"), error->message);
+		g_error_free (error);
+		g_main_loop_quit (loop);
+		goto out;
+	}
+
+	/* get values */
+	g_object_get (control,
+		      "roles", &roles,
+		      NULL);
+
+	/* setup GUI */
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_REPO_LIST)) {
+		/* get the update list */
+		gpk_repo_repo_list_refresh ();
+	} else {
+		GtkTreeIter iter;
+		GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_repo"));
+		GtkTreeModel *model = gtk_tree_view_get_model (treeview);
+
+		gtk_list_store_append (GTK_LIST_STORE(model), &iter);
+		gtk_list_store_set (list_store, &iter,
+				    REPO_COLUMN_ENABLED, FALSE,
+				    REPO_COLUMN_TEXT, _("Getting software source list not supported by backend"),
+				    REPO_COLUMN_ACTIVE, FALSE,
+				    REPO_COLUMN_SENSITIVE, FALSE,
+				    -1);
+
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_repo"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_detail"));
+		gtk_widget_set_sensitive (widget, FALSE);
+	}
+out:
+	return;
 }
 
 /**
- * gpk_repo_create_client
+ * gpk_repo_close_cb:
  **/
-static PkClient *
-gpk_repo_create_client (void)
+static void
+gpk_repo_close_cb (GtkWidget *widget, gpointer data)
 {
-	PkClient *client;
-	client = pk_client_new ();
-	g_signal_connect (client, "repo-detail",
-			  G_CALLBACK (gpk_repo_detail_cb), NULL);
-	g_signal_connect (client, "status-changed",
-			  G_CALLBACK (gpk_repo_status_changed_cb), NULL);
-	g_signal_connect (client, "error-code",
-			  G_CALLBACK (gpk_repo_error_code_cb), NULL);
-	g_signal_connect (client, "destroy",
-			  G_CALLBACK (gpk_repo_destroy_cb), NULL);
-	g_ptr_array_add (client_array, client);
-	egg_debug ("added %p", client);
-	return g_object_ref (client);
+	GMainLoop *loop = (GMainLoop *) data;
+	egg_debug ("emitting action-close");
+	g_main_loop_quit (loop);
+}
+
+/**
+ * gpk_repo_delete_event_cb:
+ **/
+static gboolean
+gpk_repo_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+	gpk_repo_close_cb (widget, data);
+	return FALSE;
 }
-#endif
 
 /**
  * main:
@@ -514,6 +565,7 @@ main (int argc, char *argv[])
 	guint xid = 0;
 	gboolean ret;
 	GtkBox *box;
+	GMainLoop *loop;
 
 	const GOptionEntry options[] = {
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
@@ -532,7 +584,6 @@ main (int argc, char *argv[])
 
 	if (! g_thread_supported ())
 		g_thread_init (NULL);
-	dbus_g_thread_init ();
 	g_type_init ();
 
 	context = g_option_context_new (NULL);
@@ -565,37 +616,21 @@ main (int argc, char *argv[])
 
 	gconf_client = gconf_client_get_default ();
 
-	client_query = pk_client_new ();
-	g_signal_connect (client_query, "repo-detail",
-			  G_CALLBACK (gpk_repo_detail_cb), NULL);
-	g_signal_connect (client_query, "status-changed",
-			  G_CALLBACK (gpk_repo_status_changed_cb), NULL);
-	g_signal_connect (client_query, "finished",
-			  G_CALLBACK (gpk_repo_finished_cb), NULL);
-	g_signal_connect (client_query, "error-code",
-			  G_CALLBACK (gpk_repo_error_code_cb), NULL);
-
-#if PK_CHECK_VERSION(0,5,1)
-	pool = pk_client_pool_new ();
-	pk_client_pool_connect (pool, "repo-detail",
-				G_CALLBACK (gpk_repo_detail_cb), NULL);
-	pk_client_pool_connect (pool, "status-changed",
-				G_CALLBACK (gpk_repo_status_changed_cb), NULL);
-	pk_client_pool_connect (pool, "error-code",
-				G_CALLBACK (gpk_repo_error_code_cb), NULL);
-#else
-	client_array = g_ptr_array_new ();
-#endif
+	loop = g_main_loop_new (NULL, FALSE);
+
+	client = pk_client_new ();
+	g_object_set (client,
+		      "background", FALSE,
+		      NULL);
 
 	control = pk_control_new ();
 	g_signal_connect (control, "repo-list-changed",
 			  G_CALLBACK (gpk_repo_repo_list_changed_cb), NULL);
-	roles = pk_control_get_actions (control, NULL);
 
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-repo.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -610,10 +645,11 @@ main (int argc, char *argv[])
 
 	main_window = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_repo"));
 	gtk_window_set_icon_name (GTK_WINDOW (main_window), GPK_ICON_SOFTWARE_SOURCES);
-	g_signal_connect_swapped (main_window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
-
+	g_signal_connect (main_window, "delete_event",
+			  G_CALLBACK (gpk_repo_delete_event_cb), loop);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
-	g_signal_connect_swapped (widget, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+	g_signal_connect (widget, "clicked",
+			  G_CALLBACK (gpk_repo_close_cb), loop);
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_help"));
 	g_signal_connect (widget, "clicked",
 			  G_CALLBACK (gpk_button_help_cb), NULL);
@@ -657,33 +693,19 @@ main (int argc, char *argv[])
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
 	gtk_widget_grab_focus (widget);
 
-	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_REPO_LIST)) {
-		/* get the update list */
-		gpk_repo_repo_list_refresh ();
-	} else {
-		gpk_repo_detail_cb (client_query, "default",
-				   _("Getting software source list not supported by backend"), FALSE, NULL);
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_repo"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_detail"));
-		gtk_widget_set_sensitive (widget, FALSE);
-	}
+	/* get properties */
+	pk_control_get_properties_async (control, NULL, (GAsyncReadyCallback) gpk_repo_get_properties_cb, loop);
 
 	/* wait */
-	gtk_main ();
+	g_main_loop_run (loop);
 
 	g_object_unref (list_store);
 out_build:
 	g_object_unref (builder);
 	g_object_unref (gconf_client);
-	g_object_unref (client_query);
 	g_object_unref (control);
-#if PK_CHECK_VERSION(0,5,1)
-	g_object_unref (pool);
-#else
-	g_ptr_array_foreach (client_array, (GFunc) g_object_unref, NULL);
-	g_ptr_array_free (client_array, TRUE);
-#endif
+	g_object_unref (client);
+	g_main_loop_unref (loop);
 unique_out:
 	g_object_unref (unique_app);
 
diff --git a/src/gpk-self-test.c b/src/gpk-self-test.c
index bf38fa1..1d8d936 100644
--- a/src/gpk-self-test.c
+++ b/src/gpk-self-test.c
@@ -25,6 +25,7 @@
 #include "egg-debug.h"
 #include "gpk-common.h"
 #include "gpk-enum.h"
+#include "gpk-task.h"
 
 void egg_markdown_test (EggTest *test);
 void egg_string_test (EggTest *test);
@@ -56,6 +57,7 @@ main (int argc, char **argv)
 	gpk_error_test (test);
 //	gpk_client_test (test);
 	gpk_modal_dialog_test (test);
+	gpk_task_test (test);
 
 	return egg_test_finish (test);
 }
diff --git a/src/gpk-service-pack.c b/src/gpk-service-pack.c
index aac829e..dfbe7ba 100644
--- a/src/gpk-service-pack.c
+++ b/src/gpk-service-pack.c
@@ -21,17 +21,17 @@
 
 #include "config.h"
 
-#include <glib.h>
+//#include <glib.h>
 #include <glib/gi18n.h>
 #include <locale.h>
 
 #include <gtk/gtk.h>
-#include <math.h>
-#include <string.h>
+//#include <math.h>
+//#include <string.h>
 #include <sys/utsname.h>
-#include <dbus/dbus-glib.h>
+//#include <dbus/dbus-glib.h>
 #include <gconf/gconf-client.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <unique/unique.h>
 
 #include "egg-debug.h"
@@ -88,7 +88,7 @@ gpk_pack_get_default_filename (const gchar *directory)
 		filename = g_strdup_printf ("%s/%s-%s.servicepack", directory, package, distro_id);
 	} else if (action == GPK_ACTION_ENUM_COPY) {
 		nodename = pk_get_node_name ();
-		filename = g_strdup_printf ("%s/%s.package-list", directory, nodename);
+		filename = g_strdup_printf ("%s/%s.package-array", directory, nodename);
 	} else if (action == GPK_ACTION_ENUM_UPDATES) {
 		iso_time = pk_iso8601_present ();
 		/* don't include the time, just use the date prefix */
@@ -135,22 +135,6 @@ gpk_pack_widgets_activate (gboolean enable)
 }
 
 /**
- * gpk_pack_package_cb:
- **/
-static void
-gpk_pack_package_cb (PkServicePack *pack, const PkPackageObj *obj, gpointer data)
-{
-	GtkProgressBar *progress_bar;
-	gchar *text;
-
-	progress_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar_percentage"));
-	/* TRANSLATORS: This is the package name that is being downloaded */
-	text = g_strdup_printf ("%s: %s-%s.%s", _("Downloading"), obj->id->name, obj->id->version, obj->id->arch);
-	gtk_progress_bar_set_text (progress_bar, text);
-	g_free (text);
-}
-
-/**
  * gpk_pack_percentage_pulse_cb:
  **/
 static gboolean
@@ -189,74 +173,57 @@ gpk_pack_set_percentage (guint percentage)
 }
 
 /**
- * gpk_pack_percentage_cb:
- **/
-static void
-gpk_pack_percentage_cb (PkServicePack *pack, guint percentage, gpointer data)
-{
-	gpk_pack_set_percentage (percentage);
-}
-
-/**
- * gpk_pack_progress_changed_cb:
- **/
-static void
-gpk_pack_progress_changed_cb (PkClient *_client, guint percentage, guint subpercentage,
-			      guint elapsed, guint remaining, gpointer data)
-{
-	gpk_pack_set_percentage (percentage);
-}
-
-/**
  * gpk_pack_resolve_package_id:
  **/
 static gchar *
 gpk_pack_resolve_package_id (const gchar *package)
 {
-	PkPackageList *list = NULL;
+	GPtrArray *array = NULL;
 	gchar *package_id = NULL;
 	gchar **packages = NULL;
 	GError *error = NULL;
-	const PkPackageObj *obj;
-	gboolean ret = FALSE;
-	guint len;
+	const PkItemPackage *item;
+	PkResults *results;
+	PkItemErrorCode *error_item = NULL;
 
-	/* reset client */
-	ret = pk_client_reset (client, &error);
-	if (!ret) {
-		egg_warning ("could not reset client: %s", error->message);
+	/* get package array */
+	packages = g_strsplit (package, ";", 0);
+	results = pk_client_resolve (client, pk_bitfield_value (PK_FILTER_ENUM_NEWEST), packages, NULL, NULL, NULL, &error);
+	if (results == NULL) {
+		egg_warning ("failed to resolve: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	/* get package list */
-	packages = g_strsplit (package, ";", 0);
-	ret = pk_client_resolve (client, pk_bitfield_value (PK_FILTER_ENUM_NEWEST), packages, &error);
-	if (!ret) {
-		egg_warning ("failed to resolve: %s", error->message);
-		g_error_free (error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to resolve: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 		goto out;
 	}
 
 	/* get the deps */
-	list = pk_client_get_package_list (client);
-	len = pk_package_list_get_size (list);
+	array = pk_results_get_package_array (results);
 
 	/* no matches */
-	if (len == 0)
+	if (array->len == 0)
 		goto out;
 
 	/* display warning if not exactly one match */
-	if (len > 1)
+	if (array->len > 1)
 		egg_warning ("More than one possible package for '%s' found!", package);
 
 	/* convert to a text package id */
-	obj = pk_package_list_get_obj (list, 0);
-	package_id = pk_package_id_to_string (obj->id);
+	item = g_ptr_array_index (array, 0);
+	package_id = g_strdup (item->package_id);
 
 out:
-	if (list != NULL)
-		g_object_unref (list);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 	g_strfreev (packages);
 	return package_id;
 }
@@ -274,7 +241,7 @@ gpk_pack_resolve_package_ids (gchar **package, GError **error)
 	gchar *package_id;
 
 	length = g_strv_length (package);
-	array = g_ptr_array_new ();
+	array = g_ptr_array_new_with_free_func (g_free);
 
 	/* for each package, resolve to a package_id */
 	for (i=0; i<length; i++) {
@@ -309,56 +276,196 @@ gpk_pack_resolve_package_ids (gchar **package, GError **error)
 
 out:
 	/* free temp array */
-	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-	g_ptr_array_free (array, TRUE);
+	g_ptr_array_unref (array);
 	return package_ids;
 }
 
 /**
+ * gpk_pack_package_array_to_string:
+ **/
+static gchar *
+gpk_pack_package_array_to_string (GPtrArray *array)
+{
+	guint i;
+	const PkItemPackage *item;
+	GString *string;
+
+	string = g_string_new ("");
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		g_string_append_printf (string, "%s\t%s\t%s\n",
+					pk_info_enum_to_text (item->info),
+					item->package_id, item->summary);
+	}
+
+	/* remove trailing newline */
+	if (string->len != 0)
+		g_string_set_size (string, string->len-1);
+	return g_string_free (string, FALSE);
+}
+
+/**
  * gpk_pack_copy_package_lists:
  **/
 static gboolean
 gpk_pack_copy_package_lists (const gchar *filename, GError **error)
 {
 	gboolean ret = FALSE;
-	PkPackageList *list = NULL;
+	GPtrArray *array = NULL;
 	GError *error_local = NULL;
-
-	/* reset client */
-	ret = pk_client_reset (client, &error_local);
-	if (!ret) {
-		/* TRANSLATORS: internal error */
-		*error = g_error_new (1, 0, _("Could not reset client: %s"), error_local->message);
+	PkResults *results;
+	gchar *data = NULL;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get package array */
+	results = pk_client_get_packages (client, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), NULL, NULL, NULL, &error_local);
+	if (results == NULL) {
+		/* TRANSLATORS: cannot get package array */
+		*error = g_error_new (1, 0, _("Could not get array of installed packages: %s"), error_local->message);
 		g_error_free (error_local);
 		goto out;
 	}
 
-	/* get package list */
-	ret = pk_client_get_packages (client, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), &error_local);
-	if (!ret) {
-		/* TRANSLATORS: cannot get package list */
-		*error = g_error_new (1, 0, _("Could not get list of installed packages: %s"), error_local->message);
-		g_error_free (error_local);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get packages: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 		goto out;
 	}
 
 	/* get the deps */
-	list = pk_client_get_package_list (client);
+	array = pk_results_get_package_array (results);
 
-	/* write new file : FIXME: return a GError */
-	ret = pk_obj_list_to_file (PK_OBJ_LIST(list), filename);
+	/* convert to a file */
+	data = gpk_pack_package_array_to_string (array);
+	ret = g_file_set_contents (PK_SYSTEM_PACKAGE_LIST_FILENAME, data, -1, &error_local);
 	if (!ret) {
-		/* TRANSLATORS: we could not write to the destination directory for some reason */
-		*error = g_error_new (1, 0, _("Could not write package list"));
+		*error = g_error_new (1, 0, _("Could not save to file: %s"), error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 out:
-	if (list != NULL)
-		g_object_unref (list);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+	g_free (data);
 	return ret;
 }
 
 /**
+ * gpk_pack_ready_cb:
+ **/
+static void
+gpk_pack_ready_cb (GObject *object, GAsyncResult *res, gpointer userdata)
+{
+	GtkWidget *widget;
+	PkServicePack *pack = PK_SERVICE_PACK (object);
+	GError *error = NULL;
+	gboolean ret;
+
+	/* get the results */
+	ret = pk_service_pack_generic_finish (pack, res, &error);
+	if (!ret) {
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
+		/* TRANSLATORS: we could not create the pack file, generic error */
+		gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("Cannot create service pack"), error->message);
+		g_error_free (error);
+	}
+
+	/* stop the action */
+	gpk_pack_widgets_activate (TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "frame_progress"));
+	gtk_widget_hide (widget);
+	gpk_pack_set_percentage (100);
+
+	/* blank */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar_percentage"));
+	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget), "");
+}
+
+
+/**
+ * gpk_pack_progress_cb:
+ **/
+static void
+gpk_pack_progress_cb (PkProgress *progress, PkProgressType type, gpointer userdata)
+{
+	PkStatusEnum status;
+	gint percentage;
+	GtkProgressBar *progress_bar;
+	gchar *text;
+	gchar **split;
+	gchar *package_id;
+
+	g_object_get (progress,
+		      "status", &status,
+		      "percentage", &percentage,
+		      "package-id", &package_id,
+		      NULL);
+
+	if (type == PK_PROGRESS_TYPE_STATUS) {
+		egg_debug ("now %s", pk_status_enum_to_text (status));
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+		gpk_pack_set_percentage (percentage);
+	} else if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
+		progress_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar_percentage"));
+		split = pk_package_id_split (package_id);
+		/* TRANSLATORS: This is the package name that is being downloaded */
+		text = g_strdup_printf ("%s: %s-%s.%s",
+					_("Downloading"),
+					split[PK_PACKAGE_ID_NAME],
+					split[PK_PACKAGE_ID_VERSION],
+					split[PK_PACKAGE_ID_ARCH]);
+		gtk_progress_bar_set_text (progress_bar, text);
+		g_free (text);
+		g_strfreev (split);
+	}
+}
+
+/**
+ * gpk_pack_get_excludes_for_filename:
+ **/
+static gchar **
+gpk_pack_get_excludes_for_filename (const gchar *filename, GError **error)
+{
+	gboolean ret;
+	gchar *data = NULL;
+	gchar **split = NULL;
+	gchar **lines = NULL;
+	gchar **exclude_ids = NULL;
+	GPtrArray *array = NULL;
+	guint i;
+
+	/* get contents */
+	ret = g_file_get_contents (filename, &data, NULL, error);
+	if (!ret)
+		goto out;
+
+	/* split into lines */
+	array = g_ptr_array_new_with_free_func (g_free);
+	lines = g_strsplit (data, "\n", -1);
+	for (i=0; lines[i] != NULL; i++) {
+		/* split into sections */
+		split = g_strsplit (lines[i], "\t", -1);
+		if (g_strv_length (split) == 3)
+			g_ptr_array_add (array, g_strdup (split[1]));
+		g_strfreev (split);
+	}
+
+	/* convert to a string array */
+	exclude_ids = pk_ptr_array_to_strv (array);
+out:
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	g_free (data);
+	g_strfreev (lines);
+	return exclude_ids;
+}
+
+/**
  * gpk_pack_button_create_cb:
  **/
 static void
@@ -371,12 +478,13 @@ gpk_pack_button_create_cb (GtkWidget *widget2, gpointer data)
 	gchar *exclude = NULL;
 	gchar **packages = NULL;
 	gchar **package_ids = NULL;
+	gchar **exclude_ids = NULL;
 	PkServicePack *pack;
-	PkPackageList *list = NULL;
 	GError *error = NULL;
 	gboolean ret;
 	gboolean use_default = FALSE;
 	GtkProgressBar *progress_bar;
+	PkItemErrorCode *error_item = NULL;
 
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserbutton_directory"));
 	directory = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(widget));
@@ -389,19 +497,19 @@ gpk_pack_button_create_cb (GtkWidget *widget2, gpointer data)
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "frame_progress"));
 	gtk_widget_show (widget);
 
-	/* copy the system package list */
+	/* copy the system package array */
 	if (action == GPK_ACTION_ENUM_COPY) {
 		ret = gpk_pack_copy_package_lists (filename, &error);
 		if (!ret) {
 			widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
-			/* TRANSLATORS: Could not create package list */
-			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("Cannot copy system package list"), error->message);
+			/* TRANSLATORS: Could not create package array */
+			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("Cannot copy system package array"), error->message);
 			g_error_free (error);
 		}
 		goto out;
 	}
 
-	/* get the exclude list, and fall back to the system copy */
+	/* get the exclude array, and fall back to the system copy */
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserbutton_exclude"));
 	exclude = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(widget));
 	if (exclude == NULL) {
@@ -415,95 +523,82 @@ gpk_pack_button_create_cb (GtkWidget *widget2, gpointer data)
 		package = gtk_entry_get_text (GTK_ENTRY(widget));
 		if (egg_strzero (package)) {
 			widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
-			/* TRANSLATORS: Could not create package list */
+			/* TRANSLATORS: Could not create package array */
 			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("No package name selected"), NULL);
 			goto out;
 		}
-		/* split the package list with common delimiters */
+		/* split the package array with common delimiters */
 		packages = g_strsplit_set (package, ";, ", 0);
 		package_ids = gpk_pack_resolve_package_ids (packages, &error);
 		if (package_ids == NULL) {
 			widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
-			/* TRANSLATORS: Could not create package list */
+			/* TRANSLATORS: Could not create package array */
 			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), error->message, NULL);
 			g_error_free (error);
 			goto out;
 		}
 	}
 
-	/* if we're using the default list, and it doesn't exist, refresh and create it */
+	/* if we're using the default array, and it doesn't exist, refresh and create it */
 	if (use_default && !g_file_test (exclude, G_FILE_TEST_EXISTS)) {
-		/* reset client */
-		ret = pk_client_reset (client, &error);
-		if (!ret) {
-			widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
-			/* TRANSLATORS: we could not reset internal state */
-			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Refresh error"), _("Could not reset client"), error->message);
-			g_error_free (error);
-			goto out;
-		}
+		PkResults *results;
 
 		/* tell the user what we are doing */
 		progress_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar_percentage"));
 		/* TRANSLATORS: progressbar text */
-		gtk_progress_bar_set_text (progress_bar, _("Refreshing system package list"));
+		gtk_progress_bar_set_text (progress_bar, _("Refreshing system package array"));
 
-		/* refresh package list */
-		ret = pk_client_refresh_cache (client, TRUE, &error);
-		if (!ret) {
+		/* refresh package array */
+		results = pk_client_refresh_cache (client, TRUE, NULL, NULL, NULL, &error);
+		if (results == NULL) {
 			widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
 			/* TRANSLATORS: we could not reset internal state */
-			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Refresh error"), _("Could not refresh package list"), error->message);
+			gpk_error_dialog_modal (GTK_WINDOW (widget), _("Refresh error"), _("Could not refresh package array"), error->message);
 			g_error_free (error);
 			goto out;
 		}
+
+		/* check error code */
+		error_item = pk_results_get_error_code (results);
+		if (error_item != NULL) {
+			egg_warning ("failed to refresh cache: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+			goto out;
+		}
+
+		g_object_unref (results);
 	}
 
-	/* add the exclude list */
-	list = pk_package_list_new ();
-	ret = pk_obj_list_from_file (PK_OBJ_LIST(list), exclude);
-	if (!ret) {
+	/* add the exclude array */
+	exclude_ids = gpk_pack_get_excludes_for_filename (exclude, &error);
+	if (exclude_ids == NULL) {
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
-		/* TRANSLATORS: we could not read the file list for the destination computer */
-		gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("Cannot read destination package list"), NULL);
+		/* TRANSLATORS: we could not read the file array for the destination computer */
+		gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("Cannot read destination package array"), error->message);
+		g_error_free (error);
 		goto out;
 	}
 
 	/* create pack and set initial values */
 	pack = pk_service_pack_new ();
-	g_signal_connect (pack, "package", G_CALLBACK (gpk_pack_package_cb), pack);
-	g_signal_connect (pack, "percentage", G_CALLBACK (gpk_pack_percentage_cb), pack);
-	pk_service_pack_set_filename (pack, filename);
 	pk_service_pack_set_temp_directory (pack, NULL);
-	pk_service_pack_set_exclude_list (pack, list);
 
-	if (action == GPK_ACTION_ENUM_UPDATES)
-		ret = pk_service_pack_create_for_updates (pack, &error);
-	else if (action == GPK_ACTION_ENUM_PACKAGE)
-		ret = pk_service_pack_create_for_package_ids (pack, package_ids, &error);
-	if (!ret) {
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_pack"));
-		/* TRANSLATORS: we could not create the pack file, generic error */
-		gpk_error_dialog_modal (GTK_WINDOW (widget), _("Create error"), _("Cannot create service pack"), error->message);
-		g_error_free (error);
+	if (action == GPK_ACTION_ENUM_UPDATES) {
+		pk_service_pack_create_for_updates_async (pack, filename, exclude_ids, NULL,
+							  (PkProgressCallback) gpk_pack_progress_cb, NULL,
+							  (GAsyncReadyCallback) gpk_pack_ready_cb, NULL);
+	} else if (action == GPK_ACTION_ENUM_PACKAGE) {
+		pk_service_pack_create_for_package_ids_async (pack, filename, package_ids, exclude_ids, NULL,
+							      (PkProgressCallback) gpk_pack_progress_cb, NULL,
+							      (GAsyncReadyCallback) gpk_pack_ready_cb, NULL);
 	}
 	g_object_unref (pack);
 
 out:
-	/* stop the action */
-	gpk_pack_widgets_activate (TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "frame_progress"));
-	gtk_widget_hide (widget);
-	gpk_pack_set_percentage (100);
-
-	/* blank */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar_percentage"));
-	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget), "");
-
-	if (list != NULL)
-		g_object_unref (list);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
 	g_strfreev (packages);
 	g_strfreev (package_ids);
+	g_strfreev (exclude_ids);
 	g_free (directory);
 	g_free (exclude);
 }
@@ -578,14 +673,12 @@ main (int argc, char *argv[])
 	GtkWidget *widget;
 	GtkFileFilter *filter;
 	GtkEntryCompletion *completion;
-	PkBitfield roles;
-	PkControl *control = NULL;
 	UniqueApp *unique_app;
 	gboolean ret;
 	GConfClient *gconf_client = NULL;
 	gchar *option = NULL;
 	gchar *package = NULL;
-	gchar *with_list = NULL;
+	gchar *with_array = NULL;
 	gchar *output = NULL;
 	guint retval;
 	GError *error = NULL;
@@ -595,13 +688,13 @@ main (int argc, char *argv[])
 		  _("Show extra debugging information"), NULL },
 		{ "option", 'o', 0, G_OPTION_ARG_STRING, &option,
 		  /* TRANSLATORS: the constants should not be translated */
-		  _("Set the option, allowable values are 'list', 'updates' and 'package'"), NULL },
+		  _("Set the option, allowable values are 'array', 'updates' and 'package'"), NULL },
 		{ "package", 'p', 0, G_OPTION_ARG_STRING, &package,
 		  /* TRANSLATORS: this refers to the GtkTextEntry in gpk-service-pack */
 		  _("Add the package name to the text entry box"), NULL },
-		{ "with-list", 'p', 0, G_OPTION_ARG_STRING, &with_list,
-		  /* TRANSLATORS: this is the destination computer package list */
-		  _("Set the remote package list filename"), NULL },
+		{ "with-array", 'p', 0, G_OPTION_ARG_STRING, &with_array,
+		  /* TRANSLATORS: this is the destination computer package array */
+		  _("Set the remote package array filename"), NULL },
 		{ "output", 'p', 0, G_OPTION_ARG_STRING, &output,
 		  /* TRANSLATORS: this is the file output directory */
 		  _("Set the default output directory"), NULL },
@@ -616,7 +709,6 @@ main (int argc, char *argv[])
 
 	if (! g_thread_supported ())
 		g_thread_init (NULL);
-	dbus_g_thread_init ();
 	g_type_init ();
 
 	context = g_option_context_new (NULL);
@@ -639,19 +731,15 @@ main (int argc, char *argv[])
 	g_signal_connect (unique_app, "message-received",
 			  G_CALLBACK (gpk_pack_message_received_cb), NULL);
 
-	/* get actions */
-	control = pk_control_new ();
-	roles = pk_control_get_actions (control, NULL);
-
 	client = pk_client_new ();
-	pk_client_set_use_buffer (client, TRUE, NULL);
-	pk_client_set_synchronous (client, TRUE, NULL);
-	g_signal_connect (client, "progress-changed", G_CALLBACK (gpk_pack_progress_changed_cb), NULL);
+	g_object_set (client,
+		      "background", FALSE,
+		      NULL);
 
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-service-pack.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -669,8 +757,8 @@ main (int argc, char *argv[])
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserbutton_exclude"));
 	filter = gtk_file_filter_new ();
 	/* TRANSLATORS: file search type, lists of packages */
-	gtk_file_filter_set_name (filter, _("Package list files"));
-	gtk_file_filter_add_pattern (filter, "*.package-list");
+	gtk_file_filter_set_name (filter, _("Package array files"));
+	gtk_file_filter_add_pattern (filter, "*.package-array");
 	gtk_file_chooser_set_filter (GTK_FILE_CHOOSER(widget), filter);
 
 	widget = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserbutton_directory"));
@@ -710,7 +798,7 @@ main (int argc, char *argv[])
 
 	/* if command line arguments are set, then setup UI */
 	if (option != NULL) {
-		if (g_strcmp0 (option, "list") == 0) {
+		if (g_strcmp0 (option, "array") == 0) {
 			widget = GTK_WIDGET (gtk_builder_get_object (builder, "radiobutton_copy"));
 			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
 		} else if (g_strcmp0 (option, "updates") == 0) {
@@ -725,9 +813,9 @@ main (int argc, char *argv[])
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
 		gtk_entry_set_text (GTK_ENTRY(widget), package);
 	}
-	if (with_list != NULL) {
+	if (with_array != NULL) {
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserbutton_exclude"));
-		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), with_list);
+		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), with_array);
 	}
 	if (output != NULL) {
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "filechooserbutton_directory"));
@@ -745,13 +833,11 @@ out_unique:
 	g_object_unref (unique_app);
 	if (gconf_client != NULL)
 		g_object_unref (gconf_client);
-	if (control != NULL)
-		g_object_unref (control);
 	if (client != NULL)
 		g_object_unref (client);
 	g_free (option);
 	g_free (package);
-	g_free (with_list);
+	g_free (with_array);
 	g_free (output);
 
 	return 0;
diff --git a/src/gpk-update-icon.c b/src/gpk-update-icon.c
index 00ba9e5..2bde05f 100644
--- a/src/gpk-update-icon.c
+++ b/src/gpk-update-icon.c
@@ -31,7 +31,7 @@
 #include <gtk/gtk.h>
 #include <locale.h>
 #include <libnotify/notify.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-dbus-monitor.h"
@@ -141,8 +141,8 @@ main (int argc, char *argv[])
 
 	if (! g_thread_supported ())
 		g_thread_init (NULL);
-	dbus_g_thread_init ();
 	g_type_init ();
+	dbus_g_thread_init ();
 	notify_init ("gpk-update-icon");
 
 	/* TRANSLATORS: program name, a session wide daemon to watch for updates and changing system state */
diff --git a/src/gpk-update-viewer.c b/src/gpk-update-viewer.c
index 240dcbc..14c2f55 100644
--- a/src/gpk-update-viewer.c
+++ b/src/gpk-update-viewer.c
@@ -30,7 +30,7 @@
 #include <dbus/dbus-glib.h>
 
 #include <gconf/gconf-client.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 #include <libnotify/notify.h>
 #include <unique/unique.h>
 #include <canberra-gtk.h>
@@ -49,9 +49,7 @@
 #include "gpk-cell-renderer-restart.h"
 #include "gpk-cell-renderer-spinner.h"
 #include "gpk-enum.h"
-#include "gpk-helper-repo-signature.h"
-#include "gpk-helper-eula.h"
-#include "gpk-helper-deps-update.h"
+#include "gpk-task.h"
 
 #define GPK_UPDATE_VIEWER_AUTO_QUIT_TIMEOUT	10 /* seconds */
 #define GPK_UPDATE_VIEWER_AUTO_RESTART_TIMEOUT	60 /* seconds */
@@ -63,22 +61,19 @@
 static guint auto_shutdown_id = 0;
 static GMainLoop *loop = NULL;
 static GtkBuilder *builder = NULL;
-static GtkListStore *list_store_updates = NULL;
+static GtkListStore *array_store_updates = NULL;
 static GtkTextBuffer *text_buffer = NULL;
-static PkClient *client_primary = NULL;
-static PkClient *client_secondary = NULL;
+static PkTask *task = NULL;
 static PkControl *control = NULL;
-static PkPackageList *update_list = NULL;
-static GpkHelperRepoSignature *helper_repo_signature = NULL;
-static GpkHelperEula *helper_eula = NULL;
-static GpkHelperDepsUpdate *helper_deps_update = NULL;
+static GPtrArray *update_array = NULL;
 static EggMarkdown *markdown = NULL;
-static PkPackageId *package_id_last = NULL;
+static gchar *package_id_last = NULL;
 static PkRestartEnum restart_update = PK_RESTART_ENUM_NONE;
 static guint size_total = 0;
 static GConfClient *gconf_client = NULL;
 static gchar **install_package_ids = NULL;
 static EggConsoleKit *console = NULL;
+static GCancellable *cancellable = NULL;
 
 enum {
 	GPK_UPDATES_COLUMN_TEXT,
@@ -98,7 +93,7 @@ enum {
 	GPK_UPDATES_COLUMN_LAST
 };
 
-static gboolean gpk_update_viewer_get_new_update_list (void);
+static gboolean gpk_update_viewer_get_new_update_array (void);
 
 /**
  * gpk_update_viewer_logout:
@@ -166,76 +161,8 @@ gpk_update_viewer_button_help_cb (GtkWidget *widget, gpointer data)
 static void
 gpk_update_viewer_quit (void)
 {
-	gboolean ret;
-	gboolean allow_cancel = FALSE;
-	GError *error = NULL;
-	PkRoleEnum role;
-	PkStatusEnum status;
-	GtkWindow *window;
-	GtkWidget *dialog;
-	GtkResponseType response;
-
 	/* are we in a transaction */
-	ret = pk_client_get_role (client_primary, &role, NULL, &error);
-	if (!ret) {
-		egg_warning ("failed to get role: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	if (role == PK_ROLE_ENUM_UNKNOWN) {
-		egg_debug ("no role, so quitting");
-		goto out;
-	}
-	ret = pk_client_get_status (client_primary, &status, &error);
-	if (!ret) {
-		egg_warning ("failed to get status: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	if (status == PK_STATUS_ENUM_FINISHED) {
-		egg_debug ("status is finished, so quitting");
-		goto out;
-	}
-
-	/* can we easily cancel */
-	ret = pk_client_get_allow_cancel (client_primary, &allow_cancel, &error);
-	if (!ret) {
-		egg_warning ("failed to get allow cancel state: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* cancel the transaction */
-	if (allow_cancel) {
-		ret = pk_client_cancel (client_primary, &error);
-		if (!ret) {
-			egg_warning ("failed to cancel client: %s", error->message);
-			g_error_free (error);
-		}
-		goto out;
-	}
-
-	/* show modal dialog asking for confirmation */
-	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_MODAL,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL,
-					 "%s", _("Cannot cancel running task"));
-
-	/* TRANSLATORS: this is the button text when we check if it's okay to download */
-	gtk_dialog_add_button (GTK_DIALOG (dialog), "gtk-quit", GTK_RESPONSE_OK);
-
-	/* TRANSLATORS, user clicked the [x] when we cannot cancel what we are doing */
-	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
-						  "%s", _("There are tasks that cannot be cancelled."));
-
-	gtk_window_set_icon_name (GTK_WINDOW(dialog), GPK_ICON_SOFTWARE_INSTALLER);
-	response = gtk_dialog_run (GTK_DIALOG(dialog));
-	gtk_widget_destroy (dialog);
-
-	/* pressed cancel or [x] */
-	if (response != GTK_RESPONSE_OK)
-		return;
-out:
+	g_cancellable_cancel (cancellable);
 	g_main_loop_quit (loop);
 }
 
@@ -265,7 +192,7 @@ gpk_update_viewer_undisable_packages ()
 	/* set all the checkboxes sensitive */
 	valid = gtk_tree_model_get_iter_first (model, &iter);
 	while (valid) {
-		gtk_list_store_set (list_store_updates, &iter,
+		gtk_list_store_set (array_store_updates, &iter,
 				    GPK_UPDATES_COLUMN_SENSITIVE, TRUE,
 				    GPK_UPDATES_COLUMN_CLICKABLE, TRUE,
 				    -1);
@@ -274,231 +201,410 @@ gpk_update_viewer_undisable_packages ()
 }
 
 /**
- * gpk_update_viewer_button_check_connection:
+ * gpk_update_viewer_auto_shutdown:
+ **/
+static gboolean
+gpk_update_viewer_auto_shutdown (GtkDialog *dialog)
+{
+	gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
+	auto_shutdown_id = 0;
+	return FALSE;
+}
+
+/**
+ * gpk_update_viewer_check_restart:
  **/
 static gboolean
-gpk_update_viewer_button_check_connection (guint size)
+gpk_update_viewer_check_restart (PkRestartEnum restart)
 {
 	GtkWindow *window;
 	GtkWidget *dialog;
-	gboolean ret = TRUE;
-	gchar *text_size = NULL;
-	gchar *message = NULL;
+	gboolean ret = FALSE;
+	const gchar *title;
+	const gchar *message;
+	const gchar *button;
 	GtkResponseType response;
-	GError *error = NULL;
-	PkNetworkEnum state;
+	gboolean show_button = TRUE;
 
-	/* get network state */
-	state = pk_control_get_network_state (control, &error);
-	if (error != NULL) {
-		egg_warning ("failed to get network state: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
+	/* get the text */
+	title = gpk_restart_enum_to_localised_text (restart);
+	if (restart == PK_RESTART_ENUM_SYSTEM) {
+		/* TRANSLATORS: the message text for the restart */
+		message = _("Some of the updates that were installed require the computer to be restarted before the changes will be applied.");
+		/* TRANSLATORS: the button text for the restart */
+		button = _("Restart Computer");
 
-	/* not on wireless mobile */
-	if (state != PK_NETWORK_ENUM_MOBILE)
-		goto out;
+	} else if (restart == PK_RESTART_ENUM_SECURITY_SYSTEM) {
+		/* TRANSLATORS: the message text for the restart */
+		message = _("Some of the updates that were installed require the computer to be restarted to remain secure.");
+		/* TRANSLATORS: the button text for the restart */
+		button = _("Restart Computer");
 
-	/* not when small */
-	if (size < GPK_UPDATE_VIEWER_MOBILE_SMALL_SIZE)
-		goto out;
+	} else if (restart == PK_RESTART_ENUM_SESSION) {
+		/* TRANSLATORS: the message text for the logout */
+		message = _("Some of the updates that were installed require you to log out and back in before the changes will be applied.");
+		/* TRANSLATORS: the button text for the logout */
+		button = _("Log Out");
 
-	/* not when ignored */
-	ret = gconf_client_get_bool (gconf_client, GPK_CONF_UPDATE_VIEWER_MOBILE_BBAND, NULL);
-	if (!ret)
+	} else if (restart == PK_RESTART_ENUM_SECURITY_SESSION) {
+		/* TRANSLATORS: the message text for the logout */
+		message = _("Some of the updates that were installed require you to log out and back in to remain secure.");
+		/* TRANSLATORS: the button text for the logout */
+		button = _("Log Out");
+
+	} else {
+		egg_warning ("unknown restart enum");
 		goto out;
+	}
 
 	/* show modal dialog */
 	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
 	dialog = gtk_message_dialog_new (window, GTK_DIALOG_MODAL,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL,
-					 "%s", _("Detected wireless broadband connection"));
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+					 "%s", title);
 
-	/* TRANSLATORS: this is the button text when we check if it's okay to download */
-	gtk_dialog_add_button (GTK_DIALOG (dialog), _("Update anyway"), GTK_RESPONSE_OK);
-	text_size = g_format_size_for_display (size_total);
+	/* check to see if restart is possible */
+	if (restart == PK_RESTART_ENUM_SYSTEM ||
+	    restart == PK_RESTART_ENUM_SECURITY_SYSTEM) {
+		egg_console_kit_can_restart (console, &show_button, NULL);
+	}
 
-	/* TRANSLATORS, the %s is a size, e.g. 13.3Mb */
-	message = g_strdup_printf (_("Connectivity is being provided by wireless broadband, and it may be expensive to download %s."), text_size);
+	/* only show the button if we can do the action */
+	if (show_button)
+		gtk_dialog_add_button (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
 	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog), "%s", message);
-	gpk_dialog_embed_do_not_show_widget (GTK_DIALOG (dialog), GPK_CONF_UPDATE_VIEWER_MOBILE_BBAND);
 	gtk_window_set_icon_name (GTK_WINDOW(dialog), GPK_ICON_SOFTWARE_INSTALLER);
+
+	/* setup a callback so we autoclose */
+	auto_shutdown_id = g_timeout_add_seconds (GPK_UPDATE_VIEWER_AUTO_RESTART_TIMEOUT, (GSourceFunc) gpk_update_viewer_auto_shutdown, dialog);
+
 	response = gtk_dialog_run (GTK_DIALOG(dialog));
 	gtk_widget_destroy (dialog);
 
+	/* cancel */
 	if (response != GTK_RESPONSE_OK)
-		ret = FALSE;
+		goto out;
+
+	/* doing the action, return success */
+	ret = TRUE;
+
+	/* do the action */
+	if (restart == PK_RESTART_ENUM_SYSTEM)
+		gpk_update_viewer_shutdown ();
+	else if (restart == PK_RESTART_ENUM_SESSION)
+		gpk_update_viewer_logout ();
 out:
-	g_free (text_size);
-	g_free (message);
 	return ret;
 }
 
 /**
- * gpk_update_viewer_button_install_cb:
+ * gpk_update_viewer_check_blocked_packages:
  **/
 static void
-gpk_update_viewer_button_install_cb (GtkWidget *widget, gpointer data)
+gpk_update_viewer_check_blocked_packages (GPtrArray *array)
 {
+	guint i;
+	const PkItemPackage *item;
+	GString *string;
+	gboolean exists = FALSE;
+	gchar *text;
 	GtkWindow *window;
-	GtkTreeView *treeview;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-	GtkTreeSelection *selection;
-	gboolean ret;
-	gboolean valid;
-	gboolean update;
-	gboolean selected_any = FALSE;
-	gchar *package_id;
-	GError *error = NULL;
-	GPtrArray *array = NULL;
-	gchar **package_ids = NULL;
-	PkInfoEnum info;
-
-	/* check connection */
-	ret = gpk_update_viewer_button_check_connection (size_total);
-	if (!ret)
-		goto out;
 
-	/* hide the upgrade viewbox from now on */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_upgrade"));
-	gtk_widget_hide (widget);
+	string = g_string_new ("");
 
-	egg_debug ("Doing the package updates");
-	array = g_ptr_array_new ();
+	/* find any that are blocked */
+	for (i=0;i<array->len;i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->info == PK_INFO_ENUM_BLOCKED) {
+			text = gpk_package_id_format_oneline (item->package_id, item->summary);
+			g_string_append_printf (string, "%s\n", text);
+			g_free (text);
+			exists = TRUE;
+		}
+	}
 
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
-	model = gtk_tree_view_get_model (treeview);
+	/* trim off extra newlines */
+	if (string->len != 0)
+		g_string_set_size (string, string->len-1);
 
-	/* get the first iter in the list */
-	valid = gtk_tree_model_get_iter_first (model, &iter);
+	/* convert to a normal gchar */
+	text = g_string_free (string, FALSE);
 
-	/* find out how many we should update */
-	while (valid) {
-		gtk_tree_model_get (model, &iter,
-				    GPK_UPDATES_COLUMN_INFO, &info,
-				    GPK_UPDATES_COLUMN_SELECT, &update,
-				    GPK_UPDATES_COLUMN_ID, &package_id, -1);
+	/* nothing of interest */
+	if (!exists)
+		goto out;
 
-		/* set all the checkboxes insensitive */
-		gtk_list_store_set (list_store_updates, &iter,
-				    GPK_UPDATES_COLUMN_CLICKABLE, FALSE,
-				    GPK_UPDATES_COLUMN_SENSITIVE, FALSE, -1);
+	/* throw up dialog */
+	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+	/* TRANSLATORS: we failed to install all the updates we requested */
+	gpk_error_dialog_modal (window, _("Some updates were not installed"), text, NULL);
+out:
+	g_free (text);
+}
 
-		/* any selected? */
-		if (update)
-			selected_any = TRUE;
+/**
+ * gpk_update_viewer_update_packages_cb:
+ **/
+static void
+gpk_update_viewer_update_packages_cb (PkTask *_task, GAsyncResult *res, GMainLoop *_loop)
+{
+	PkResults *results;
+	GError *error = NULL;
+	GPtrArray *array = NULL;
+	PkItemPackage *item;
+	guint i;
+	GtkWidget *dialog;
+	GtkWidget *widget;
+	PkRestartEnum restart;
+	gchar *text;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
 
-		/* if selected, and not added previously because of deps */
-		if (update && info != PK_INFO_ENUM_AVAILABLE) {
-			g_ptr_array_add (array, package_id);
-		} else {
-			/* need to free the one in the array later */
-			g_free (package_id);
-		}
-		valid = gtk_tree_model_iter_next (model, &iter);
+	/* get the results */
+	results = pk_task_generic_finish (task, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to update packages: %s", error->message);
+		g_error_free (error);
+		goto out;
 	}
 
-	/* we have no checkboxes selected */
-	if (!selected_any) {
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to update packages: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
 		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: we clicked apply, but had no packages selected */
-					_("No updates selected"),
-					_("No updates are selected"), NULL);
-		return;
-	}
+		gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+					gpk_error_enum_to_localised_message (error_item->code), error_item->details);
 
-	/* disable button */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_install"));
-	gtk_widget_set_sensitive (widget, FALSE);
+		/* re-enable the package list */
+		gpk_update_viewer_undisable_packages ();
 
-	/* clear the selection */
-	selection = gtk_tree_view_get_selection (treeview);
-	gtk_tree_selection_unselect_all (selection);
+		/* allow clicking again */
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_install"));
+		gtk_widget_set_sensitive (widget, TRUE);
 
-	/* reset client */
-	ret = pk_client_reset (client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
 		goto out;
 	}
 
-	/* save for finished */
-	package_ids = pk_package_ids_from_array (array);
-	g_strfreev (install_package_ids);
-	install_package_ids = g_strdupv (package_ids);
+	/* TODO: failed sound */
+	/* play the sound, using sounds from the naming spec */
+	ca_context_play (ca_gtk_context_get (), 0,
+			 CA_PROP_EVENT_ID, "dialog-warning",
+			 /* TRANSLATORS: this is the application name for libcanberra */
+			 CA_PROP_APPLICATION_NAME, _("GNOME PackageKit Update Viewer"),
+			 /* TRANSLATORS: this is the sound description */
+			 CA_PROP_EVENT_DESCRIPTION, _("Failed to update"), NULL);
 
-	/* get packages that also have to be updated */
-#if PK_CHECK_VERSION(0,5,2)
-	ret = pk_client_simulate_update_packages (client_primary, package_ids, &error);
-#else
-	ret = pk_client_get_depends (client_primary, pk_bitfield_value (PK_FILTER_ENUM_NOT_INSTALLED), package_ids, TRUE, &error);
-#endif
-	if (!ret) {
-		egg_warning ("cannot get depends for updates: %s", error->message);
-		g_error_free (error);
-		goto out;
+	gpk_update_viewer_undisable_packages ();
+
+	/* get blocked data */
+	array = pk_results_get_package_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		egg_debug ("updated %s:%s", pk_info_enum_to_text (item->info), item->package_id);
+	}
+
+	/* TODO: use ca_gtk_context_get_for_screen to allow use of GDK_MULTIHEAD_SAFE */
+
+	/* play the sound, using sounds from the naming spec */
+	ca_context_play (ca_gtk_context_get (), 0,
+			 /* TODO: add a new sound to the spec */
+			 CA_PROP_EVENT_ID, "complete-download",
+			 /* TRANSLATORS: this is the application name for libcanberra */
+			 CA_PROP_APPLICATION_NAME, _("GNOME PackageKit Update Viewer"),
+			 /* TRANSLATORS: this is the sound description */
+			 CA_PROP_EVENT_DESCRIPTION, _("Updated successfully"), NULL);
+
+	/* get the worst restart case */
+	restart = pk_results_get_require_restart_worst (results);
+	if (restart > restart_update)
+		restart_update = restart;
+
+	/* check blocked */
+	array = pk_results_get_package_array (results);
+	gpk_update_viewer_check_blocked_packages (array);
+	g_ptr_array_unref (array);
+
+	/* check restart */
+	if (restart_update == PK_RESTART_ENUM_SYSTEM ||
+	    restart_update == PK_RESTART_ENUM_SESSION ||
+	    restart_update == PK_RESTART_ENUM_SECURITY_SESSION ||
+	    restart_update == PK_RESTART_ENUM_SECURITY_SYSTEM) {
+		gpk_update_viewer_check_restart (restart_update);
+		g_main_loop_quit (loop);
 	}
+
+	/* hide close button */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
+	gtk_widget_hide (widget);
+
+	/* show a new title */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_header_title"));
+	/* TRANSLATORS: completed all updates */
+	text = g_strdup_printf ("<big><b>%s</b></big>", _("All selected updates installed..."));
+	gtk_label_set_label (GTK_LABEL (widget), text);
+	g_free (text);
+
+	/* show modal dialog */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_updates"));
+	dialog = gtk_message_dialog_new (GTK_WINDOW (widget), GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
+					 /* TRANSLATORS: title: all updates installed okay */
+					 "%s", _("All selected updates installed"));
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
+						  "%s",
+						  /* TRANSLATORS: software updates installed okay */
+						  _("All selected updates were successfully installed."));
+	gtk_window_set_icon_name (GTK_WINDOW(dialog), GPK_ICON_SOFTWARE_INSTALLER);
+
+	/* setup a callback so we autoclose */
+	auto_shutdown_id = g_timeout_add_seconds (GPK_UPDATE_VIEWER_AUTO_RESTART_TIMEOUT, (GSourceFunc) gpk_update_viewer_auto_shutdown, dialog);
+
+	gtk_dialog_run (GTK_DIALOG(dialog));
+	gtk_widget_destroy (dialog);
+
+	/* quit after we successfully updated */
+	g_main_loop_quit (loop);
 out:
-	g_strfreev (package_ids);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
 
-	/* get rid of the array, and free the contents */
-	if (array != NULL) {
-		g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-		g_ptr_array_free (array, TRUE);
+
+static GSList *active_rows = NULL;
+static guint active_row_timeout = 0;
+
+/**
+ * gpk_update_viewer_compare_refs:
+ **/
+static gint
+gpk_update_viewer_compare_refs (GtkTreeRowReference *a, GtkTreeRowReference *b)
+{
+	GtkTreeModel *am, *bm;
+	GtkTreePath *ap, *bp;
+	gint res;
+
+	am = gtk_tree_row_reference_get_model (a);
+	bm = gtk_tree_row_reference_get_model (b);
+
+	res = 1;
+	if (am == bm) {
+		ap = gtk_tree_row_reference_get_path (a);
+		bp = gtk_tree_row_reference_get_path (b);
+
+		res = gtk_tree_path_compare (ap, bp);
+
+		gtk_tree_path_free (ap);
+		gtk_tree_path_free (bp);
 	}
+
+	return res;
 }
 
 /**
- * gpk_update_viewer_button_upgrade_cb:
+ * gpk_update_viewer_pulse_active_rows:
+ **/
+static gboolean
+gpk_update_viewer_pulse_active_rows (void)
+{
+	GSList *l;
+	GtkTreeRowReference *ref;
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	gint val;
+
+	for (l = active_rows; l; l = l->next) {
+		ref = l->data;
+		model = gtk_tree_row_reference_get_model (ref);
+		path = gtk_tree_row_reference_get_path (ref);
+		if (path) {
+			gtk_tree_model_get_iter (model, &iter, path);
+			gtk_tree_model_get (model, &iter, GPK_UPDATES_COLUMN_PULSE, &val, -1);
+			gtk_list_store_set (GTK_LIST_STORE (model), &iter, GPK_UPDATES_COLUMN_PULSE, val + 1, -1);
+			gtk_tree_path_free (path);
+		}
+	}
+
+	return TRUE;
+}
+
+/**
+ * gpk_update_viewer_add_active_row:
  **/
 static void
-gpk_update_viewer_button_upgrade_cb (GtkWidget *widget, gpointer data)
+gpk_update_viewer_add_active_row (GtkTreeModel *model, GtkTreePath *path)
 {
-	gboolean ret;
-	GError *error = NULL;
+	GtkTreeRowReference *ref;
 
-	ret = g_spawn_command_line_async ("/usr/share/PackageKit/pk-upgrade-distro.sh", NULL);
-	if (!ret) {
-		egg_warning ("Failure launching pk-upgrade-distro.sh: %s", error->message);
-		g_error_free (error);
+	if (!active_row_timeout) {
+		active_row_timeout = g_timeout_add (60, (GSourceFunc)gpk_update_viewer_pulse_active_rows, NULL);
 	}
+
+	ref = gtk_tree_row_reference_new (model, path);
+	active_rows = g_slist_prepend (active_rows, ref);
 }
 
 /**
- * gpk_update_viewer_button_delete_event_cb:
+ * gpk_update_viewer_remove_active_row:
  **/
-static gboolean
-gpk_update_viewer_button_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+static void
+gpk_update_viewer_remove_active_row (GtkTreeModel *model, GtkTreePath *path)
 {
-	gpk_update_viewer_quit ();
-	return TRUE;
+	GSList *link;
+	GtkTreeRowReference *ref;
+	GtkTreeIter iter;
+
+	gtk_tree_model_get_iter (model, &iter, path);
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter, GPK_UPDATES_COLUMN_PULSE, -1, -1);
+
+	ref = gtk_tree_row_reference_new (model, path);
+	link = g_slist_find_custom (active_rows, (gconstpointer)ref, (GCompareFunc)gpk_update_viewer_compare_refs);
+	gtk_tree_row_reference_free (ref);
+	g_assert (link);
+
+	active_rows = g_slist_remove_link (active_rows, link);
+	gtk_tree_row_reference_free (link->data);
+	g_slist_free (link);
+
+	if (active_rows == NULL) {
+		g_source_remove (active_row_timeout);
+		active_row_timeout = 0;
+	}
 }
 
 /**
  * gpk_update_viewer_find_iter_model_cb:
  **/
 static gboolean
-gpk_update_viewer_find_iter_model_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, const PkPackageId *id)
+gpk_update_viewer_find_iter_model_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, const gchar *package_id)
 {
-	gchar *id_tmp = NULL;
+	gchar *package_id_tmp = NULL;
 	GtkTreePath **_path = NULL;
-	PkPackageId *id_new;
 	gboolean ret = FALSE;
+	gchar **split;
+	gchar **split_tmp;
 
 	_path = (GtkTreePath **) g_object_get_data (G_OBJECT(model), "_path");
-	gtk_tree_model_get (model, iter, GPK_UPDATES_COLUMN_ID, &id_tmp, -1);
+	gtk_tree_model_get (model, iter,
+			    GPK_UPDATES_COLUMN_ID, &package_id_tmp,
+			    -1);
 
 	/* only match on the name */
-	id_new = pk_package_id_new_from_string (id_tmp);
-	if (g_strcmp0 (id_new->name, id->name) == 0) {
+	split = pk_package_id_split (package_id);
+	split_tmp = pk_package_id_split (package_id_tmp);
+	if (g_strcmp0 (split[PK_PACKAGE_ID_NAME], split_tmp[PK_PACKAGE_ID_NAME]) == 0) {
 		*_path = gtk_tree_path_copy (path);
 		ret = TRUE;
 	}
-	pk_package_id_free (id_new);
+	g_free (package_id_tmp);
+	g_strfreev (split);
+	g_strfreev (split_tmp);
 	return ret;
 }
 
@@ -506,121 +612,88 @@ gpk_update_viewer_find_iter_model_cb (GtkTreeModel *model, GtkTreePath *path, Gt
  * gpk_update_viewer_model_get_path:
  **/
 static GtkTreePath *
-gpk_update_viewer_model_get_path (GtkTreeModel *model, const PkPackageId *id)
+gpk_update_viewer_model_get_path (GtkTreeModel *model, const gchar *package_id)
 {
 	GtkTreePath *path = NULL;
+	g_return_val_if_fail (package_id != NULL, NULL);
 	g_object_set_data (G_OBJECT(model), "_path", (gpointer) &path);
-	gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) gpk_update_viewer_find_iter_model_cb, (gpointer) id);
+	gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) gpk_update_viewer_find_iter_model_cb, (gpointer) package_id);
 	g_object_steal_data (G_OBJECT(model), "_path");
 	return path;
 }
 
 /**
- * gpk_update_viewer_details_cb:
+ * gpk_update_viewer_progress_cb:
  **/
 static void
-gpk_update_viewer_details_cb (PkClient *client, const PkDetailsObj *obj, gpointer data)
+gpk_update_viewer_progress_cb (PkProgress *progress, PkProgressType type, GMainLoop *_loop)
 {
-	GtkTreeView *treeview;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-	GtkTreePath *path;
-
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
-	model = gtk_tree_view_get_model (treeview);
-
-	path = gpk_update_viewer_model_get_path (model, obj->id);
-	if (path == NULL) {
-		egg_debug ("not found ID for details");
-		return;
-	}
-
-	gtk_tree_model_get_iter (model, &iter, path);
-	gtk_tree_path_free (path);
-	gtk_list_store_set (list_store_updates, &iter,
-			    GPK_UPDATES_COLUMN_DETAILS_OBJ, (gpointer) pk_details_obj_copy (obj),
-			    GPK_UPDATES_COLUMN_SIZE, (gint)obj->size,
-			    GPK_UPDATES_COLUMN_SIZE_DISPLAY, (gint)obj->size,
-			    -1);
-	/* in cache */
-	if (obj->size == 0)
-		gtk_list_store_set (list_store_updates, &iter,
-				    GPK_UPDATES_COLUMN_STATUS, GPK_INFO_ENUM_DOWNLOADED, -1);
-}
-
-/**
- * gpk_update_viewer_is_update_info:
- **/
-static gboolean
-gpk_update_viewer_is_update_info (PkInfoEnum info)
-{
-	if (info == PK_INFO_ENUM_LOW)
-		return TRUE;
-	if (info == PK_INFO_ENUM_NORMAL)
-		return TRUE;
-	if (info == PK_INFO_ENUM_IMPORTANT)
-		return TRUE;
-	if (info == PK_INFO_ENUM_SECURITY)
-		return TRUE;
-	if (info == PK_INFO_ENUM_BUGFIX)
-		return TRUE;
-	if (info == PK_INFO_ENUM_ENHANCEMENT)
-		return TRUE;
-	return FALSE;
-}
-
-/**
- * gpk_update_viewer_package_cb:
- **/
-static void
-gpk_update_viewer_package_cb (PkClient *client, const PkPackageObj *obj, gpointer data)
-{
-	PkRoleEnum role;
-	PkInfoEnum info;
-	gchar *text = NULL;
+	gboolean allow_cancel;
 	gchar *package_id;
-	GtkTreeView *treeview;
-	GtkTreeIter iter;
-	GtkTreeModel *model;
-	GtkTreeViewColumn *column;
-	GtkTreePath *path;
-	gboolean selected;
-	gboolean scroll;
+	gchar *text;
+	gint percentage;
+	gint subpercentage;
+	GtkWidget *widget;
+	PkInfoEnum info = PK_INFO_ENUM_UNKNOWN;
+	PkRoleEnum role;
+	PkStatusEnum status;
 
-	pk_client_get_role (client, &role, NULL, NULL);
-	egg_debug ("role = %s, package = %s:%s:%s", pk_role_enum_to_text (role),
-		  pk_info_enum_to_text (obj->info), obj->id->name, obj->summary);
+	g_object_get (progress,
+		      "role", &role,
+		      "status", &status,
+		      "percentage", &percentage,
+		      "subpercentage", &subpercentage,
+		      "package-id", &package_id,
+		      "allow-cancel", &allow_cancel,
+		      NULL);
 
-	/* convert to string */
-	package_id = pk_package_id_to_string (obj->id);
+	if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
 
-	/* are we simulating to get deps? */
-#if PK_CHECK_VERSION(0,5,2)
-	if (role == PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES) {
-		egg_debug ("ignoring %s as we are simulating", package_id);
-		goto out;
-	}
-#else
-	if (role == PK_ROLE_ENUM_GET_DEPENDS) {
-		egg_debug ("ignoring %s as we are in the depends phase", package_id);
-		goto out;
-	}
-#endif
+		GtkTreeView *treeview;
+		GtkTreeIter iter;
+		GtkTreeModel *model;
+		GtkTreeViewColumn *column;
+		GtkTreePath *path;
+		gboolean scroll;
+
+		/* add the results, not the progress */
+		if (role == PK_ROLE_ENUM_GET_UPDATES)
+			return;
 
-	/* used for progress */
-	if (!gpk_update_viewer_is_update_info (obj->info)) {
-		pk_package_id_free (package_id_last);
-		package_id_last = pk_package_id_copy (obj->id);
+		/* used for progress */
+		g_free (package_id_last);
+		package_id_last = g_strdup (package_id);
 
 		/* find model */
 		treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
 		model = gtk_tree_view_get_model (treeview);
 
 		/* update icon */
-		path = gpk_update_viewer_model_get_path (model, obj->id);
+		path = gpk_update_viewer_model_get_path (model, package_id);
 		if (path == NULL) {
-			egg_debug ("not found ID for package");
-			goto out;
+			text = gpk_package_id_format_twoline (package_id, NULL); //TODO: summary
+			egg_debug ("adding: id=%s, text=%s", package_id, text);
+			gtk_list_store_append (array_store_updates, &iter);
+			gtk_list_store_set (array_store_updates, &iter,
+					    GPK_UPDATES_COLUMN_TEXT, text,
+					    GPK_UPDATES_COLUMN_ID, package_id,
+					    GPK_UPDATES_COLUMN_INFO, PK_INFO_ENUM_NORMAL, //TODO info
+					    GPK_UPDATES_COLUMN_SELECT, TRUE,
+					    GPK_UPDATES_COLUMN_SENSITIVE, FALSE,
+					    GPK_UPDATES_COLUMN_CLICKABLE, FALSE,
+					    GPK_UPDATES_COLUMN_RESTART, PK_RESTART_ENUM_NONE,
+					    GPK_UPDATES_COLUMN_STATUS, PK_INFO_ENUM_UNKNOWN,
+					    GPK_UPDATES_COLUMN_SIZE, 0,
+					    GPK_UPDATES_COLUMN_SIZE_DISPLAY, 0,
+					    GPK_UPDATES_COLUMN_PERCENTAGE, 0,
+					    GPK_UPDATES_COLUMN_PULSE, -1,
+					    -1);
+			g_free (text);
+			path = gpk_update_viewer_model_get_path (model, package_id);
+			if (path == NULL) {
+				egg_warning ("found no package %s", package_id);
+				goto out;
+			}
 		}
 
 		gtk_tree_model_get_iter (model, &iter, path);
@@ -633,86 +706,246 @@ gpk_update_viewer_package_cb (PkClient *client, const PkPackageObj *obj, gpointe
 		}
 
 		/* if the info is finished, change the status to past tense */
-		if (obj->info == PK_INFO_ENUM_FINISHED) {
+		if (info == PK_INFO_ENUM_FINISHED) {
 			gtk_tree_model_get (model, &iter,
 					    GPK_UPDATES_COLUMN_STATUS, &info, -1);
 			/* promote to past tense if present tense */
 			if (info < PK_INFO_ENUM_UNKNOWN)
 				info += PK_INFO_ENUM_UNKNOWN;
-		} else {
-			info = obj->info;
 		}
-		gtk_list_store_set (list_store_updates, &iter,
+		gtk_list_store_set (array_store_updates, &iter,
 				    GPK_UPDATES_COLUMN_STATUS, info, -1);
 
 		gtk_tree_path_free (path);
 
-		/* set package description */
-		//widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_package"));
-		//gtk_label_set_label (GTK_LABEL (widget), obj->summary);
+	} else if (type == PK_PROGRESS_TYPE_STATUS) {
 
-		goto out;
-	}
+		GdkWindow *window;
+		const gchar *title;
+		GdkDisplay *display;
+		GdkCursor *cursor;
 
-	/* add to list store */
-	text = gpk_package_id_format_twoline (obj->id, obj->summary);
-	selected = (obj->info != PK_INFO_ENUM_BLOCKED);
-	gtk_list_store_append (list_store_updates, &iter);
-	gtk_list_store_set (list_store_updates, &iter,
-			    GPK_UPDATES_COLUMN_TEXT, text,
-			    GPK_UPDATES_COLUMN_ID, package_id,
-			    GPK_UPDATES_COLUMN_INFO, obj->info,
-			    GPK_UPDATES_COLUMN_SELECT, selected,
-			    GPK_UPDATES_COLUMN_SENSITIVE, selected,
-			    GPK_UPDATES_COLUMN_CLICKABLE, selected,
-			    GPK_UPDATES_COLUMN_RESTART, PK_RESTART_ENUM_NONE,
-			    GPK_UPDATES_COLUMN_STATUS, PK_INFO_ENUM_UNKNOWN,
-			    GPK_UPDATES_COLUMN_SIZE, 0,
-			    GPK_UPDATES_COLUMN_SIZE_DISPLAY, 0,
-			    GPK_UPDATES_COLUMN_PERCENTAGE, 0,
-			    GPK_UPDATES_COLUMN_PULSE, -1,
-			    -1);
+		egg_debug ("status %s", pk_status_enum_to_text (status));
+
+		/* use correct status pane */
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_status"));
+		gtk_widget_show (widget);
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_info"));
+		gtk_widget_hide (widget);
+
+		/* set cursor back to normal */
+		window = gtk_widget_get_window (widget);
+		if (status == PK_STATUS_ENUM_FINISHED) {
+			gdk_window_set_cursor (window, NULL);
+		} else {
+			display = gdk_display_get_default ();
+			cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
+			gdk_window_set_cursor (window, cursor);
+			gdk_cursor_unref (cursor);
+		}
+
+		/* set status */
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_status"));
+		if (status == PK_STATUS_ENUM_FINISHED) {
+			gtk_label_set_label (GTK_LABEL (widget), "");
+			widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_progress"));
+			gtk_widget_hide (widget);
+
+			widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar_progress"));
+			gtk_widget_hide (widget);
+
+			widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
+			gtk_widget_set_sensitive (widget, TRUE);
+		} else {
+			if (status == PK_STATUS_ENUM_QUERY || status == PK_STATUS_ENUM_SETUP) {
+				/* TRANSLATORS: querying update array */
+				title = _("Getting the list of updates");
+			} else if (status == PK_STATUS_ENUM_WAIT) {
+				title = "";
+			} else {
+				title = gpk_status_enum_to_localised_text (status);
+			}
+			gtk_label_set_label (GTK_LABEL (widget), title);
+
+			/* set icon */
+			widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_progress"));
+			gtk_image_set_from_icon_name (GTK_IMAGE (widget), gpk_status_enum_to_icon_name (status), GTK_ICON_SIZE_BUTTON);
+			gtk_widget_show (widget);
+		}
+
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+
+		GtkTreeView *treeview;
+		GtkTreeModel *model;
+		GtkTreeIter iter;
+		GtkTreePath *path;
+		guint oldval;
+		guint size;
+		guint size_display;
+
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar_progress"));
+		gtk_widget_show (widget);
+		if (percentage != -1)
+			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget), (gfloat) percentage / 100.0);
+
+		treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
+		model = gtk_tree_view_get_model (treeview);
+
+		if (package_id_last == NULL) {
+			egg_debug ("no last package");
+			return;
+		}
+
+		path = gpk_update_viewer_model_get_path (model, package_id_last);
+		if (path == NULL) {
+			egg_debug ("not found ID for package");
+			return;
+		}
+
+		gtk_tree_model_get_iter (model, &iter, path);
+		gtk_tree_model_get (model, &iter,
+				    GPK_UPDATES_COLUMN_PERCENTAGE, &oldval,
+				    GPK_UPDATES_COLUMN_SIZE, &size,
+				    -1);
+		if ((oldval > 0 && oldval < 100) != (subpercentage > 0 && subpercentage < 100)) {
+			if (oldval > 0 && oldval < 100)
+				gpk_update_viewer_remove_active_row (model, path);
+			else
+				gpk_update_viewer_add_active_row (model, path);
+		}
+
+		size_display = size - ((size * subpercentage) / 100);
+		gtk_list_store_set (array_store_updates, &iter,
+				    GPK_UPDATES_COLUMN_PERCENTAGE, subpercentage,
+				    GPK_UPDATES_COLUMN_SIZE_DISPLAY, size_display,
+				    -1);
+
+		gtk_tree_path_free (path);
+
+	} else if (type == PK_PROGRESS_TYPE_ALLOW_CANCEL) {
+		widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
+		gtk_widget_set_sensitive (widget, allow_cancel);
+	}
 out:
 	g_free (package_id);
-	g_free (text);
 }
 
 /**
- * gpk_update_viewer_update_detail_cb:
+ * gpk_update_viewer_button_install_cb:
  **/
 static void
-gpk_update_viewer_update_detail_cb (PkClient *client, const PkUpdateDetailObj *obj, gpointer data)
+gpk_update_viewer_button_install_cb (GtkWidget *widget, gpointer data)
 {
+	GtkWindow *window;
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
-	GtkTreePath *path;
+	GtkTreeSelection *selection;
+	gboolean valid;
+	gboolean update;
+	gboolean selected_any = FALSE;
+	gchar *package_id;
+	GPtrArray *array = NULL;
+	gchar **package_ids = NULL;
+	PkInfoEnum info;
+
+	/* hide the upgrade viewbox from now on */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_upgrade"));
+	gtk_widget_hide (widget);
+
+	egg_debug ("Doing the package updates");
+	array = g_ptr_array_new ();
 
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
 	model = gtk_tree_view_get_model (treeview);
 
-	path = gpk_update_viewer_model_get_path (model, obj->id);
-	if (path == NULL) {
-		egg_warning ("not found ID for update detail");
+	/* get the first iter in the array */
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+
+	/* find out how many we should update */
+	while (valid) {
+		gtk_tree_model_get (model, &iter,
+				    GPK_UPDATES_COLUMN_INFO, &info,
+				    GPK_UPDATES_COLUMN_SELECT, &update,
+				    GPK_UPDATES_COLUMN_ID, &package_id, -1);
+
+		/* set all the checkboxes insensitive */
+		gtk_list_store_set (array_store_updates, &iter,
+				    GPK_UPDATES_COLUMN_CLICKABLE, FALSE,
+				    GPK_UPDATES_COLUMN_SENSITIVE, FALSE, -1);
+
+		/* any selected? */
+		if (update)
+			selected_any = TRUE;
+
+		/* if selected, and not added previously because of deps */
+		if (update && info != PK_INFO_ENUM_AVAILABLE) {
+			g_ptr_array_add (array, package_id);
+		} else {
+			/* need to free the one in the array later */
+			g_free (package_id);
+		}
+		valid = gtk_tree_model_iter_next (model, &iter);
+	}
+
+	/* we have no checkboxes selected */
+	if (!selected_any) {
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+		gpk_error_dialog_modal (window,
+					/* TRANSLATORS: we clicked apply, but had no packages selected */
+					_("No updates selected"),
+					_("No updates are selected"), NULL);
 		return;
 	}
 
-	gtk_tree_model_get_iter (model, &iter, path);
-	gtk_tree_path_free (path);
-	gtk_list_store_set (list_store_updates, &iter,
-			    GPK_UPDATES_COLUMN_UPDATE_DETAIL_OBJ, (gpointer) pk_update_detail_obj_copy (obj),
-			    GPK_UPDATES_COLUMN_RESTART, obj->restart, -1);
+	/* disable button */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_install"));
+	gtk_widget_set_sensitive (widget, FALSE);
+
+	/* clear the selection */
+	selection = gtk_tree_view_get_selection (treeview);
+	gtk_tree_selection_unselect_all (selection);
+
+	/* save for finished */
+	package_ids = pk_ptr_array_to_strv (array);
+	g_strfreev (install_package_ids);
+	install_package_ids = g_strdupv (package_ids);
+
+	/* get packages that also have to be updated */
+	pk_task_update_packages_async (task, package_ids, cancellable,
+				       (PkProgressCallback) gpk_update_viewer_progress_cb, NULL,
+				       (GAsyncReadyCallback) gpk_update_viewer_update_packages_cb, loop);
+	g_strfreev (package_ids);
+
+	/* get rid of the array, and free the contents */
+	if (array != NULL)
+		g_ptr_array_unref (array);
 }
 
 /**
- * gpk_update_viewer_auto_shutdown:
+ * gpk_update_viewer_button_upgrade_cb:
+ **/
+static void
+gpk_update_viewer_button_upgrade_cb (GtkWidget *widget, gpointer data)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	ret = g_spawn_command_line_async ("/usr/share/PackageKit/pk-upgrade-distro.sh", &error);
+	if (!ret) {
+		egg_warning ("Failure launching pk-upgrade-distro.sh: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+/**
+ * gpk_update_viewer_button_delete_event_cb:
  **/
 static gboolean
-gpk_update_viewer_auto_shutdown (GtkDialog *dialog)
+gpk_update_viewer_button_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
 {
-	gtk_dialog_response (dialog, GTK_RESPONSE_CANCEL);
-	auto_shutdown_id = 0;
-	return FALSE;
+	gpk_update_viewer_quit ();
+	return TRUE;
 }
 
 /**
@@ -774,7 +1007,7 @@ gpk_update_viewer_reconsider_info (GtkTreeModel *model)
 	gtk_button_set_label (GTK_BUTTON (widget), title);
 
 	/* no updates */
-	len = PK_OBJ_LIST(update_list)->len;
+	len = update_array->len;
 	if (len == 0) {
 		/* hide close button */
 		widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
@@ -872,69 +1105,6 @@ out:
 }
 
 /**
- * gpk_update_viewer_status_changed_cb:
- **/
-static void
-gpk_update_viewer_status_changed_cb (PkClient *client, PkStatusEnum status, gpointer data)
-{
-	GtkWidget *widget;
-	GdkWindow *window;
-	const gchar *text;
-	GdkDisplay *display;
-	GdkCursor *cursor;
-
-	egg_debug ("status %s", pk_status_enum_to_text (status));
-
-	/* use correct status pane */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_status"));
-	gtk_widget_show (widget);
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "hbox_info"));
-	gtk_widget_hide (widget);
-
-	/* set cursor back to normal */
-	window = gtk_widget_get_window (widget);
-	if (status == PK_STATUS_ENUM_FINISHED) {
-		gdk_window_set_cursor (window, NULL);
-	} else {
-		display = gdk_display_get_default ();
-		cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
-		gdk_window_set_cursor (window, cursor);
-		gdk_cursor_unref (cursor);
-	}
-
-	/* clear package */
-	if (status == PK_STATUS_ENUM_WAIT) {
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_package"));
-		gtk_label_set_label (GTK_LABEL (widget), "");
-	}
-
-	/* set status */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_status"));
-	if (status == PK_STATUS_ENUM_FINISHED) {
-		gtk_label_set_label (GTK_LABEL (widget), "");
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_progress"));
-		gtk_widget_hide (widget);
-		goto out;
-	}
-	if (status == PK_STATUS_ENUM_QUERY || status == PK_STATUS_ENUM_SETUP) {
-		/* TRANSLATORS: querying update list */
-		text = _("Getting the list of updates");
-	} else {
-		text = gpk_status_enum_to_localised_text (status);
-	}
-
-	/* set label */
-	gtk_label_set_label (GTK_LABEL (widget), text);
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "image_progress"));
-
-	/* set icon */
-	gtk_image_set_from_icon_name (GTK_IMAGE (widget), gpk_status_enum_to_icon_name (status), GTK_ICON_SIZE_BUTTON);
-	gtk_widget_show (widget);
-out:
-	return;
-}
-
-/**
  * gpk_update_viewer_treeview_update_toggled:
  **/
 static void
@@ -1205,7 +1375,7 @@ gpk_update_viewer_get_uris (const gchar *url_string)
 	guint length;
 	gint i;
 
-	array = g_ptr_array_new ();
+	array = g_ptr_array_new_with_free_func (g_free);
 
 	urls = g_strsplit (url_string, ";", 0);
 	length = g_strv_length (urls);
@@ -1227,7 +1397,7 @@ gpk_update_viewer_get_uris (const gchar *url_string)
  * gpk_update_viewer_populate_details:
  **/
 static void
-gpk_update_viewer_populate_details (const PkUpdateDetailObj *obj)
+gpk_update_viewer_populate_details (const PkItemUpdateDetail *item)
 {
 	GtkTreeView *treeview;
 	GtkTreeSelection *selection;
@@ -1279,9 +1449,9 @@ gpk_update_viewer_populate_details (const PkUpdateDetailObj *obj)
 	}
 
 	/* issued and updated */
-	if (obj->issued != NULL && obj->updated != NULL) {
-		issued = pk_iso8601_from_date (obj->issued);
-		updated = pk_iso8601_from_date (obj->updated);
+	if (item->issued != NULL && item->updated != NULL) {
+		issued = pk_iso8601_from_date (item->issued);
+		updated = pk_iso8601_from_date (item->updated);
 		/* TRANSLATORS: this is when the notification was issued and then updated*/
 		line = g_strdup_printf (_("This notification was issued on %s and last updated on %s."), issued, updated);
 		gtk_text_buffer_insert_with_tags_by_name (text_buffer, &iter, line, -1, "para", NULL);
@@ -1289,8 +1459,8 @@ gpk_update_viewer_populate_details (const PkUpdateDetailObj *obj)
 		g_free (issued);
 		g_free (updated);
 		g_free (line);
-	} else if (obj->issued != NULL) {
-		issued = pk_iso8601_from_date (obj->issued);
+	} else if (item->issued != NULL) {
+		issued = pk_iso8601_from_date (item->issued);
 		/* TRANSLATORS: this is when the update was issued */
 		line = g_strdup_printf (_("This notification was issued on %s."), issued);
 		gtk_text_buffer_insert_with_tags_by_name (text_buffer, &iter, line, -1, "para", NULL);
@@ -1300,9 +1470,9 @@ gpk_update_viewer_populate_details (const PkUpdateDetailObj *obj)
 	}
 
 	/* update text */
-	if (!egg_strzero (obj->update_text)) {
+	if (!egg_strzero (item->update_text)) {
 		/* convert the bullets */
-		line = egg_markdown_parse (markdown, obj->update_text);
+		line = egg_markdown_parse (markdown, item->update_text);
 		if (!egg_strzero (line)) {
 			gtk_text_buffer_insert_markup (text_buffer, &iter, line);
 			gtk_text_buffer_insert (text_buffer, &iter, "\n\n", -1);
@@ -1312,59 +1482,56 @@ gpk_update_viewer_populate_details (const PkUpdateDetailObj *obj)
 	}
 
 	/* add all the links */
-	if (!egg_strzero (obj->vendor_url)) {
-		array = gpk_update_viewer_get_uris (obj->vendor_url);
-		/* TRANSLATORS: this is a list of vendor URLs */
+	if (!egg_strzero (item->vendor_url)) {
+		array = gpk_update_viewer_get_uris (item->vendor_url);
+		/* TRANSLATORS: this is a array of vendor URLs */
 		title = ngettext ("For more information about this update please visit this website:",
 				  "For more information about this update please visit these websites:", array->len);
 		gpk_update_viewer_add_description_link_item (text_buffer, &iter, title, array);
-		g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-		g_ptr_array_free (array, TRUE);
+		g_ptr_array_unref (array);
 	}
-	if (!egg_strzero (obj->bugzilla_url)) {
-		array = gpk_update_viewer_get_uris (obj->bugzilla_url);
-		/* TRANSLATORS: this is a list of bugzilla URLs */
+	if (!egg_strzero (item->bugzilla_url)) {
+		array = gpk_update_viewer_get_uris (item->bugzilla_url);
+		/* TRANSLATORS: this is a array of bugzilla URLs */
 		title = ngettext ("For more information about bugs fixed by this update please visit this website:",
 				  "For more information about bugs fixed by this update please visit these websites:", array->len);
 		gpk_update_viewer_add_description_link_item (text_buffer, &iter, title, array);
-		g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-		g_ptr_array_free (array, TRUE);
+		g_ptr_array_unref (array);
 	}
-	if (!egg_strzero (obj->cve_url)) {
-		array = gpk_update_viewer_get_uris (obj->cve_url);
-		/* TRANSLATORS: this is a list of CVE (security) URLs */
+	if (!egg_strzero (item->cve_url)) {
+		array = gpk_update_viewer_get_uris (item->cve_url);
+		/* TRANSLATORS: this is a array of CVE (security) URLs */
 		title = ngettext ("For more information about this security update please visit this website:",
 				  "For more information about this security update please visit these websites:", array->len);
 		gpk_update_viewer_add_description_link_item (text_buffer, &iter, title, array);
-		g_ptr_array_foreach (array, (GFunc) g_free, NULL);
-		g_ptr_array_free (array, TRUE);
+		g_ptr_array_unref (array);
 	}
 
 	/* reboot */
-	if (obj->restart == PK_RESTART_ENUM_SYSTEM) {
+	if (item->restart == PK_RESTART_ENUM_SYSTEM) {
 		/* TRANSLATORS: reboot required */
 		gtk_text_buffer_insert_with_tags_by_name (text_buffer, &iter, _("The computer will have to be restarted after the update for the changes to take effect."), -1, "para", NULL);
 		gtk_text_buffer_insert (text_buffer, &iter, "\n", -1);
-	} else if (obj->restart == PK_RESTART_ENUM_SESSION) {
+	} else if (item->restart == PK_RESTART_ENUM_SESSION) {
 		/* TRANSLATORS: log out required */
 		gtk_text_buffer_insert_with_tags_by_name (text_buffer, &iter, _("You will need to log out and back in after the update for the changes to take effect."), -1, "para", NULL);
 		gtk_text_buffer_insert (text_buffer, &iter, "\n", -1);
 	}
 
 	/* state */
-	if (obj->state == PK_UPDATE_STATE_ENUM_UNSTABLE) {
+	if (item->state == PK_UPDATE_STATE_ENUM_UNSTABLE) {
 		/* TRANSLATORS: this is the stability status of the update */
 		gtk_text_buffer_insert_with_tags_by_name (text_buffer, &iter, _("The classifaction of this update is unstable which means it is not designed for production use."), -1, "para", NULL);
 		gtk_text_buffer_insert (text_buffer, &iter, "\n", -1);
-	} else if (obj->state == PK_UPDATE_STATE_ENUM_TESTING) {
+	} else if (item->state == PK_UPDATE_STATE_ENUM_TESTING) {
 		/* TRANSLATORS: this is the stability status of the update */
 		gtk_text_buffer_insert_with_tags_by_name (text_buffer, &iter, _("This is a test update, and is not designed for normal use. Please report any problems or regressions you encounter."), -1, "para", NULL);
 		gtk_text_buffer_insert (text_buffer, &iter, "\n", -1);
 	}
 
 	/* only show changelog if we didn't have any update text */
-	if (!update_text && !egg_strzero (obj->changelog)) {
-		line = egg_markdown_parse (markdown, obj->changelog);
+	if (!update_text && !egg_strzero (item->changelog)) {
+		line = egg_markdown_parse (markdown, item->changelog);
 		if (!egg_strzero (line)) {
 			/* TRANSLATORS: this is a ChangeLog */
 			line2 = g_strdup_printf ("%s\n%s\n", _("The developer logs will be shown as no description is available for this update:"), line);
@@ -1384,7 +1551,7 @@ gpk_packages_treeview_clicked_cb (GtkTreeSelection *selection, gpointer data)
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gchar *package_id;
-	PkUpdateDetailObj *obj = NULL;
+	PkItemUpdateDetail *item = NULL;
 
 	/* This will only work in single or browse selection mode! */
 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
@@ -1393,783 +1560,173 @@ gpk_packages_treeview_clicked_cb (GtkTreeSelection *selection, gpointer data)
 		gtk_text_buffer_set_text (text_buffer, _("Loading..."), -1);
 
 		gtk_tree_model_get (model, &iter,
-				    GPK_UPDATES_COLUMN_UPDATE_DETAIL_OBJ, &obj,
+				    GPK_UPDATES_COLUMN_UPDATE_DETAIL_OBJ, &item,
 				    GPK_UPDATES_COLUMN_ID, &package_id, -1);
-		egg_debug ("selected row is: %s, %p", package_id, obj);
+		egg_debug ("selected row is: %s, %p", package_id, item);
 		g_free (package_id);
-		if (obj != NULL)
-			gpk_update_viewer_populate_details (obj);
+		if (item != NULL)
+			gpk_update_viewer_populate_details (item);
 	} else {
 		egg_debug ("no row selected");
 	}
 }
 
 /**
- * gpk_update_viewer_check_blocked_packages:
+ * gpk_update_viewer_get_details_cb:
  **/
 static void
-gpk_update_viewer_check_blocked_packages (PkPackageList *list)
+gpk_update_viewer_get_details_cb (PkClient *client, GAsyncResult *res, GMainLoop *_loop)
 {
+	PkResults *results;
+	GError *error = NULL;
+	GPtrArray *array = NULL;
+	PkItemDetails *item;
 	guint i;
-	guint length;
-	const PkPackageObj *obj;
-	GString *string;
-	gboolean exists = FALSE;
-	gchar *text;
+	GtkWidget *widget;
+	GtkTreePath *path;
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
+	GtkTreeView *treeview;
+	GtkTreeIter iter;
+	PkItemErrorCode *error_item = NULL;
 	GtkWindow *window;
 
-	string = g_string_new ("");
-
-	/* find any that are blocked */
-	length = pk_package_list_get_size (list);
-	for (i=0;i<length;i++) {
-		obj = pk_package_list_get_obj (list, i);
-		if (obj->info == PK_INFO_ENUM_BLOCKED) {
-			text = gpk_package_id_format_oneline (obj->id, obj->summary);
-			g_string_append_printf (string, "%s\n", text);
-			g_free (text);
-			exists = TRUE;
-		}
-	}
-
-	/* trim off extra newlines */
-	if (string->len != 0)
-		g_string_set_size (string, string->len-1);
-
-	/* convert to a normal gchar */
-	text = g_string_free (string, FALSE);
-
-	/* nothing of interest */
-	if (!exists)
-		goto out;
-
-	/* throw up dialog */
-	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
-	/* TRANSLATORS: we failed to install all the updates we requested */
-	gpk_error_dialog_modal (window, _("Some updates were not installed"), text, NULL);
-out:
-	g_free (text);
-}
-
-/**
- * gpk_update_viewer_finished_get_details_cb:
- **/
-static gboolean
-gpk_update_viewer_finished_get_details_cb (PkPackageList *list)
-{
-	gboolean ret;
-	gchar **package_ids;
-	GError *error = NULL;
-	package_ids = pk_package_list_to_strv (list);
-
-	/* get the details of all the packages */
-	ret = pk_client_reset (client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get details: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
-	ret = pk_client_get_details (client_primary, package_ids, &error);
-	if (!ret) {
-		egg_error ("cannot get details: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	g_strfreev (package_ids);
-	g_object_unref (list);
-	return FALSE;
-}
-
-/**
- * gpk_update_viewer_finished_get_update_details_cb:
- **/
-static gboolean
-gpk_update_viewer_finished_get_update_details_cb (PkPackageList *list)
-{
-	gboolean ret;
-	gchar **package_ids;
-	GError *error = NULL;
-	package_ids = pk_package_list_to_strv (list);
-
-	/* get the details of all the packages */
-	ret = pk_client_reset (client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	ret = pk_client_get_update_detail (client_primary, package_ids, &error);
-	if (!ret) {
-		egg_error ("cannot get details: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	g_strfreev (package_ids);
-	g_object_unref (list);
-	return FALSE;
-}
 
-/**
- * gpk_update_viewer_finished_get_distro_upgrades_cb:
- **/
-static gboolean
-gpk_update_viewer_finished_get_distro_upgrades_cb (gpointer data)
-{
-	gboolean ret;
-	GError *error = NULL;
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get details: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 
-	/* get the details of all the packages */
-	ret = pk_client_reset (client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	ret = pk_client_get_distro_upgrades (client_primary, &error);
-	if (!ret) {
-		egg_error ("cannot get details: %s", error->message);
-		g_error_free (error);
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+		gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+					gpk_error_enum_to_localised_message (error_item->code), error_item->details);
 		goto out;
 	}
-out:
-	return FALSE;
-}
-
-/**
- * gpk_update_viewer_primary_requeue:
- **/
-static gboolean
-gpk_update_viewer_primary_requeue (gpointer data)
-{
-	gboolean ret;
-	GError *error = NULL;
-
-	/* retry new action */
-	ret = pk_client_requeue (client_primary, &error);
-	if (!ret) {
-		egg_warning ("Failed to requeue: %s", error->message);
-		g_error_free (error);
-	}
-	return ret;
-}
-
-/**
- * gpk_update_viewer_check_restart:
- **/
-static gboolean
-gpk_update_viewer_check_restart (PkRestartEnum restart)
-{
-	GtkWindow *window;
-	GtkWidget *dialog;
-	gboolean ret = FALSE;
-	const gchar *title;
-	const gchar *message;
-	const gchar *button;
-	GtkResponseType response;
-	gboolean show_button = TRUE;
-
-	/* get the text */
-	title = gpk_restart_enum_to_localised_text (restart);
-	if (restart == PK_RESTART_ENUM_SYSTEM) {
-		/* TRANSLATORS: the message text for the restart */
-		message = _("Some of the updates that were installed require the computer to be restarted before the changes will be applied.");
-		/* TRANSLATORS: the button text for the restart */
-		button = _("Restart Computer");
-
-	} else if (restart == PK_RESTART_ENUM_SECURITY_SYSTEM) {
-		/* TRANSLATORS: the message text for the restart */
-		message = _("Some of the updates that were installed require the computer to be restarted to remain secure.");
-		/* TRANSLATORS: the button text for the restart */
-		button = _("Restart Computer");
-
-	} else if (restart == PK_RESTART_ENUM_SESSION) {
-		/* TRANSLATORS: the message text for the logout */
-		message = _("Some of the updates that were installed require you to log out and back in before the changes will be applied.");
-		/* TRANSLATORS: the button text for the logout */
-		button = _("Log Out");
 
-	} else if (restart == PK_RESTART_ENUM_SECURITY_SESSION) {
-		/* TRANSLATORS: the message text for the logout */
-		message = _("Some of the updates that were installed require you to log out and back in to remain secure.");
-		/* TRANSLATORS: the button text for the logout */
-		button = _("Log Out");
+	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
+	model = gtk_tree_view_get_model (treeview);
 
-	} else {
-		egg_warning ("unknown restart enum");
-		goto out;
-	}
+	/* get data */
+	array = pk_results_get_details_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
 
-	/* show modal dialog */
-	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_MODAL,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
-					 "%s", title);
+		path = gpk_update_viewer_model_get_path (model, item->package_id);
+		if (path == NULL) {
+			egg_debug ("not found ID for details");
+			return;
+		}
 
-	/* check to see if restart is possible */
-	if (restart == PK_RESTART_ENUM_SYSTEM ||
-	    restart == PK_RESTART_ENUM_SECURITY_SYSTEM) {
-		egg_console_kit_can_restart (console, &show_button, NULL);
+		gtk_tree_model_get_iter (model, &iter, path);
+		gtk_tree_path_free (path);
+		gtk_list_store_set (array_store_updates, &iter,
+				    GPK_UPDATES_COLUMN_DETAILS_OBJ, (gpointer) pk_item_details_ref (item),
+				    GPK_UPDATES_COLUMN_SIZE, (gint)item->size,
+				    GPK_UPDATES_COLUMN_SIZE_DISPLAY, (gint)item->size,
+				    -1);
+		/* in cache */
+		if (item->size == 0)
+			gtk_list_store_set (array_store_updates, &iter,
+					    GPK_UPDATES_COLUMN_STATUS, GPK_INFO_ENUM_DOWNLOADED, -1);
 	}
 
-	/* only show the button if we can do the action */
-	if (show_button)
-		gtk_dialog_add_button (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
-	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog), "%s", message);
-	gtk_window_set_icon_name (GTK_WINDOW(dialog), GPK_ICON_SOFTWARE_INSTALLER);
-
-	/* setup a callback so we autoclose */
-	auto_shutdown_id = g_timeout_add_seconds (GPK_UPDATE_VIEWER_AUTO_RESTART_TIMEOUT, (GSourceFunc) gpk_update_viewer_auto_shutdown, dialog);
-
-	response = gtk_dialog_run (GTK_DIALOG(dialog));
-	gtk_widget_destroy (dialog);
-
-	/* cancel */
-	if (response != GTK_RESPONSE_OK)
-		goto out;
-
-	/* doing the action, return success */
-	ret = TRUE;
+	/* select the first entry in the updates array now we've got data */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_updates"));
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+	gtk_tree_selection_unselect_all (selection);
+	path = gtk_tree_path_new_first ();
+	gtk_tree_selection_select_path (selection, path);
+	gtk_tree_path_free (path);
 
-	/* do the action */
-	if (restart == PK_RESTART_ENUM_SYSTEM)
-		gpk_update_viewer_shutdown ();
-	else if (restart == PK_RESTART_ENUM_SESSION)
-		gpk_update_viewer_logout ();
+	/* set info */
+	gpk_update_viewer_reconsider_info (model);
 out:
-	return ret;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_update_viewer_deps_update_event_cb:
+ * gpk_update_viewer_get_update_detail_cb:
  **/
 static void
-gpk_update_viewer_deps_update_event_cb (GpkHelperDepsUpdate *helper, GtkResponseType type, PkPackageList *deps_list, gpointer data)
+gpk_update_viewer_get_update_detail_cb (PkClient *client, GAsyncResult *res, GMainLoop *_loop)
 {
-	gboolean ret;
+	PkResults *results;
 	GError *error = NULL;
+	GPtrArray *array = NULL;
+	PkItemUpdateDetail *item;
+	guint i;
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
-	gboolean valid;
 	GtkTreeIter iter;
-	gchar *package_id;
-	gchar *package_id_temp;
-	guint len;
-	guint i;
-	gboolean found;
-	gchar *text;
-	PkPackageId *id;
-	const PkPackageObj *obj;
-
-	/* get model */
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
-	model = gtk_tree_view_get_model (treeview);
-
-	if (type != GTK_RESPONSE_YES) {
-		/* clear selection */
-		gpk_update_viewer_reconsider_info (model);
-		gpk_update_viewer_undisable_packages ();
-		goto out;
-	}
-
-	/* need to select or add packages in deps_list */
-	len = PK_OBJ_LIST(deps_list)->len;
-	for (i=0; i<len; i++) {
-		obj = pk_package_list_get_obj (deps_list, i);
-		found = FALSE;
-
-		/* find it and select it */
-		valid = gtk_tree_model_get_iter_first (model, &iter);
-		while (valid && !found) {
-			gtk_tree_model_get (model, &iter, GPK_UPDATES_COLUMN_ID, &package_id_temp, -1);
-			id = pk_package_id_new_from_string (package_id_temp);
-
-			/* we found a match */
-			if (pk_package_id_equal (id, obj->id)) {
-				egg_debug ("selecting %s", id->name);
-				gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-						    GPK_UPDATES_COLUMN_SELECT, TRUE, -1);
-				found = TRUE;
-			}
-
-			g_free (package_id_temp);
-			pk_package_id_free (id);
-			valid = gtk_tree_model_iter_next (model, &iter);
-		}
-
-		/* not found, so add */
-		if (!found) {
-			package_id = pk_package_id_to_string (obj->id);
-			text = gpk_package_id_format_twoline (obj->id, obj->summary);
-			egg_debug ("adding: id=%s, text=%s", package_id, text);
-			gtk_list_store_append (list_store_updates, &iter);
-			gtk_list_store_set (list_store_updates, &iter,
-					    GPK_UPDATES_COLUMN_TEXT, text,
-					    GPK_UPDATES_COLUMN_ID, package_id,
-					    GPK_UPDATES_COLUMN_INFO, obj->info,
-					    GPK_UPDATES_COLUMN_SELECT, TRUE,
-					    GPK_UPDATES_COLUMN_SENSITIVE, FALSE,
-					    GPK_UPDATES_COLUMN_CLICKABLE, FALSE,
-					    GPK_UPDATES_COLUMN_RESTART, PK_RESTART_ENUM_NONE,
-					    GPK_UPDATES_COLUMN_STATUS, PK_INFO_ENUM_UNKNOWN,
-					    GPK_UPDATES_COLUMN_SIZE, 0,
-					    GPK_UPDATES_COLUMN_SIZE_DISPLAY, 0,
-					    GPK_UPDATES_COLUMN_PERCENTAGE, 0,
-					    GPK_UPDATES_COLUMN_PULSE, -1,
-					    -1);
-			g_free (text);
-			g_free (package_id);
-		}
-	}
-
-	/* if there are no entries selected, deselect the button */
-	gpk_update_viewer_reconsider_info (model);
+	GtkTreePath *path;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
 
-	/* reset client */
-	ret = pk_client_reset (client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get update details: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	/* actually install packages this time */
-#if PK_CHECK_VERSION(0,5,0)
-	ret = pk_client_update_packages (client_primary, TRUE, install_package_ids, &error);
-#else
-	ret = pk_client_update_packages (client_primary, install_package_ids, &error);
-#endif
-	if (!ret) {
-		egg_warning ("cannot install packages: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return;
-}
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get update details: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 
-/**
- * gpk_update_viewer_finished_cb:
- **/
-static void
-gpk_update_viewer_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpointer data)
-{
-	GtkWidget *widget;
-	GtkWidget *dialog;
-	GtkTreeView *treeview;
-	GtkTreePath *path;
-	GtkTreeModel *model;
-	GtkTreeSelection *selection;
-	PkBitfield roles;
-	PkRoleEnum role;
-	PkPackageList *list;
-	PkRestartEnum restart;
-	gchar *text;
-
-	pk_client_get_role (client, &role, NULL, NULL);
-	egg_debug ("role: %s, exit: %s", pk_role_enum_to_text (role), pk_exit_enum_to_text (exit));
-
-	/* clear package */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_package"));
-	gtk_label_set_label (GTK_LABEL (widget), "");
-
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar_progress"));
-	gtk_widget_hide (widget);
-
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
-	gtk_widget_set_sensitive (widget, TRUE);
-
-	/* need to handle retry with only_trusted=FALSE */
-	if (client == client_primary &&
-	    exit == PK_EXIT_ENUM_NEED_UNTRUSTED) {
-		egg_debug ("need to handle untrusted");
-		pk_client_set_only_trusted (client, FALSE);
-		gpk_update_viewer_primary_requeue (NULL);
-		return;
-	}
-
-	/* if secondary, ignore */
-	if (client == client_primary &&
-	    (exit == PK_EXIT_ENUM_KEY_REQUIRED ||
-	     exit == PK_EXIT_ENUM_EULA_REQUIRED)) {
-		egg_debug ("ignoring primary sig-required or eula");
-		return;
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+		gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+					gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		goto out;
 	}
 
-	/* get model */
+	/* get data */
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
 	model = gtk_tree_view_get_model (treeview);
-
-	/* clicked cancel on get updates screen */
-	if (role == PK_ROLE_ENUM_GET_UPDATES &&
-	    exit == PK_EXIT_ENUM_CANCELLED) {
-		g_main_loop_quit (loop);
-		return;
-	}
-
-	/* finished depends check, show any extras */
-#if PK_CHECK_VERSION(0,5,2)
-	if (exit == PK_EXIT_ENUM_SUCCESS && role == PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES) {
-#else
-	if (exit == PK_EXIT_ENUM_SUCCESS && role == PK_ROLE_ENUM_GET_DEPENDS) {
-#endif
-		/* show deps dialog */
-		list = pk_client_get_package_list (client);
-		gpk_helper_deps_update_show (helper_deps_update, list);
-		g_object_unref (list);
-	}
-
-	if (role == PK_ROLE_ENUM_GET_UPDATES) {
-		/* get the download sizes */
-		if (update_list != NULL)
-			g_object_unref (update_list);
-		update_list = pk_client_get_package_list (client_primary);
-
-		/* sort by name */
-		gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), GPK_UPDATES_COLUMN_ID, GTK_SORT_ASCENDING);
-
-		/* get the download sizes */
-		if (PK_OBJ_LIST(update_list)->len > 0)
-			g_idle_add ((GSourceFunc) gpk_update_viewer_finished_get_update_details_cb, g_object_ref (update_list));
-
-		/* set info */
-		gpk_update_viewer_reconsider_info (model);
-	}
-
-	if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
-		/* get the restarts */
-		g_idle_add ((GSourceFunc) gpk_update_viewer_finished_get_details_cb, g_object_ref (update_list));
-
-		/* are now able to do action */
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_install"));
-		gtk_widget_set_sensitive (widget, TRUE);
-
-		/* set info */
-		gpk_update_viewer_reconsider_info (model);
-	}
-
-	if (role == PK_ROLE_ENUM_GET_DETAILS) {
-
-		/* get the distro-upgrades if we support it */
-		roles = pk_control_get_actions (control, NULL);
-		if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DISTRO_UPGRADES))
-			g_idle_add ((GSourceFunc) gpk_update_viewer_finished_get_distro_upgrades_cb, NULL);
-
-		/* select the first entry in the updates list now we've got data */
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_updates"));
-		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
-		gtk_tree_selection_unselect_all (selection);
-		path = gtk_tree_path_new_first ();
-		gtk_tree_selection_select_path (selection, path);
-		gtk_tree_path_free (path);
-
-		/* set info */
-		gpk_update_viewer_reconsider_info (model);
-	}
-
-	if (role == PK_ROLE_ENUM_GET_DISTRO_UPGRADES) {
-		/* set info */
-		gpk_update_viewer_reconsider_info (model);
-	}
-
-	/* we've just agreed to auth or a EULA */
-	if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE ||
-	    role == PK_ROLE_ENUM_ACCEPT_EULA) {
-		if (exit == PK_EXIT_ENUM_SUCCESS)
-			gpk_update_viewer_primary_requeue (NULL);
-		else
-			gpk_update_viewer_undisable_packages ();
-	}
-
-	/* check if we need to display infomation about blocked packages */
-	if (exit == PK_EXIT_ENUM_SUCCESS &&
-	    (role == PK_ROLE_ENUM_UPDATE_SYSTEM ||
-	     role == PK_ROLE_ENUM_UPDATE_PACKAGES)) {
-
-		/* TODO: use ca_gtk_context_get_for_screen to allow use of GDK_MULTIHEAD_SAFE */
-
-		/* play the sound, using sounds from the naming spec */
-		ca_context_play (ca_gtk_context_get (), 0,
-				 /* TODO: add a new sound to the spec */
-				 CA_PROP_EVENT_ID, "complete-download",
-				 /* TRANSLATORS: this is the application name for libcanberra */
-				 CA_PROP_APPLICATION_NAME, _("GNOME PackageKit Update Viewer"),
-				 /* TRANSLATORS: this is the sound description */
-				 CA_PROP_EVENT_DESCRIPTION, _("Updated successfully"), NULL);
-
-		/* get the worst restart case */
-		restart = pk_client_get_require_restart (client_primary);
-		if (restart > restart_update)
-			restart_update = restart;
-
-		/* check blocked */
-		list = pk_client_get_package_list (client_primary);
-		gpk_update_viewer_check_blocked_packages (list);
-		g_object_unref (list);
-
-		/* check restart */
-		if (restart_update == PK_RESTART_ENUM_SYSTEM ||
-		    restart_update == PK_RESTART_ENUM_SESSION ||
-		    restart_update == PK_RESTART_ENUM_SECURITY_SESSION ||
-		    restart_update == PK_RESTART_ENUM_SECURITY_SYSTEM) {
-			gpk_update_viewer_check_restart (restart_update);
-			g_main_loop_quit (loop);
-		}
-
-		/* hide close button */
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
-		gtk_widget_hide (widget);
-
-		/* show a new title */
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_header_title"));
-		/* TRANSLATORS: completed all updates */
-		text = g_strdup_printf ("<big><b>%s</b></big>", _("All selected updates installed..."));
-		gtk_label_set_label (GTK_LABEL (widget), text);
-		g_free (text);
-
-		/* show modal dialog */
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_updates"));
-		dialog = gtk_message_dialog_new (GTK_WINDOW (widget), GTK_DIALOG_MODAL,
-						 GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
-						 /* TRANSLATORS: title: all updates installed okay */
-						 "%s", _("All selected updates installed"));
-		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog),
-							  "%s",
-							  /* TRANSLATORS: software updates installed okay */
-							  _("All selected updates were successfully installed."));
-		gtk_window_set_icon_name (GTK_WINDOW(dialog), GPK_ICON_SOFTWARE_INSTALLER);
-
-		/* setup a callback so we autoclose */
-		auto_shutdown_id = g_timeout_add_seconds (GPK_UPDATE_VIEWER_AUTO_RESTART_TIMEOUT, (GSourceFunc) gpk_update_viewer_auto_shutdown, dialog);
-
-		gtk_dialog_run (GTK_DIALOG(dialog));
-		gtk_widget_destroy (dialog);
-
-		/* quit after we successfully updated */
-		g_main_loop_quit (loop);
-	}
-
-	/* failed sound */
-	if (exit != PK_EXIT_ENUM_SUCCESS &&
-	    (role == PK_ROLE_ENUM_UPDATE_SYSTEM ||
-	     role == PK_ROLE_ENUM_UPDATE_PACKAGES)) {
-
-		/* play the sound, using sounds from the naming spec */
-		ca_context_play (ca_gtk_context_get (), 0,
-				 CA_PROP_EVENT_ID, "dialog-warning",
-				 /* TRANSLATORS: this is the application name for libcanberra */
-				 CA_PROP_APPLICATION_NAME, _("GNOME PackageKit Update Viewer"),
-				 /* TRANSLATORS: this is the sound description */
-				 CA_PROP_EVENT_DESCRIPTION, _("Failed to update"), NULL);
-	}
-
-	/* we pressed cancel */
-	if (exit != PK_EXIT_ENUM_SUCCESS) {
-		gpk_update_viewer_undisable_packages ();
-		widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_install"));
-		gtk_widget_set_sensitive (widget, TRUE);
-	}
-}
-
-static GSList *active_rows = NULL;
-static guint active_row_timeout = 0;
-
-/**
- * gpk_update_viewer_compare_refs:
- **/
-static gint
-gpk_update_viewer_compare_refs (GtkTreeRowReference *a, GtkTreeRowReference *b)
-{
-	GtkTreeModel *am, *bm;
-	GtkTreePath *ap, *bp;
-	gint res;
-
-	am = gtk_tree_row_reference_get_model (a);
-	bm = gtk_tree_row_reference_get_model (b);
-
-	res = 1;
-	if (am == bm) {
-		ap = gtk_tree_row_reference_get_path (a);
-		bp = gtk_tree_row_reference_get_path (b);
-
-		res = gtk_tree_path_compare (ap, bp);
-
-		gtk_tree_path_free (ap);
-		gtk_tree_path_free (bp);
-	}
-
-	return res;
-}
-
-/**
- * gpk_update_viewer_pulse_active_rows:
- **/
-static gboolean
-gpk_update_viewer_pulse_active_rows (void)
-{
-	GSList *l;
-	GtkTreeRowReference *ref;
-	GtkTreeModel *model;
-	GtkTreePath *path;
-	GtkTreeIter iter;
-	gint val;
-
-	for (l = active_rows; l; l = l->next) {
-		ref = l->data;
-		model = gtk_tree_row_reference_get_model (ref);
-		path = gtk_tree_row_reference_get_path (ref);
-		if (path) {
-			gtk_tree_model_get_iter (model, &iter, path);
-			gtk_tree_model_get (model, &iter, GPK_UPDATES_COLUMN_PULSE, &val, -1);
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter, GPK_UPDATES_COLUMN_PULSE, val + 1, -1);
-			gtk_tree_path_free (path);
+	array = pk_results_get_update_detail_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		path = gpk_update_viewer_model_get_path (model, item->package_id);
+		if (path == NULL) {
+			egg_warning ("not found ID for update detail");
+			continue;
 		}
-	}
 
-	return TRUE;
-}
-
-/**
- * gpk_update_viewer_add_active_row:
- **/
-static void
-gpk_update_viewer_add_active_row (GtkTreeModel *model, GtkTreePath *path)
-{
-	GtkTreeRowReference *ref;
-
-	if (!active_row_timeout) {
-		active_row_timeout = g_timeout_add (60, (GSourceFunc)gpk_update_viewer_pulse_active_rows, NULL);
-	}
-
-	ref = gtk_tree_row_reference_new (model, path);
-	active_rows = g_slist_prepend (active_rows, ref);
-}
-
-/**
- * gpk_update_viewer_remove_active_row:
- **/
-static void
-gpk_update_viewer_remove_active_row (GtkTreeModel *model, GtkTreePath *path)
-{
-	GSList *link;
-	GtkTreeRowReference *ref;
-	GtkTreeIter iter;
-
-	gtk_tree_model_get_iter (model, &iter, path);
-	gtk_list_store_set (GTK_LIST_STORE (model), &iter, GPK_UPDATES_COLUMN_PULSE, -1, -1);
-
-	ref = gtk_tree_row_reference_new (model, path);
-	link = g_slist_find_custom (active_rows, (gconstpointer)ref, (GCompareFunc)gpk_update_viewer_compare_refs);
-	gtk_tree_row_reference_free (ref);
-	g_assert (link);
-
-	active_rows = g_slist_remove_link (active_rows, link);
-	gtk_tree_row_reference_free (link->data);
-	g_slist_free (link);
-
-	if (active_rows == NULL) {
-		g_source_remove (active_row_timeout);
-		active_row_timeout = 0;
-	}
-}
-
-/**
- * gpk_update_viewer_progress_changed_cb:
- **/
-static void
-gpk_update_viewer_progress_changed_cb (PkClient *client, guint percentage, guint subpercentage,
-				       guint elapsed, guint remaining, gpointer data)
-{
-	GtkWidget *widget;
-	GtkTreeView *treeview;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-	GtkTreePath *path;
-	guint oldval;
-	guint size;
-	guint size_display;
-
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "progressbar_progress"));
-	gtk_widget_show (widget);
-	if (percentage != PK_CLIENT_PERCENTAGE_INVALID)
-		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget), (gfloat) percentage / 100.0);
-
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
-	model = gtk_tree_view_get_model (treeview);
-
-	if (package_id_last == NULL) {
-		egg_debug ("no last package");
-		return;
-	}
-
-	path = gpk_update_viewer_model_get_path (model, package_id_last);
-	if (path == NULL) {
-		egg_debug ("not found ID for package");
-		return;
-	}
-
-	gtk_tree_model_get_iter (model, &iter, path);
-	gtk_tree_model_get (model, &iter,
-			    GPK_UPDATES_COLUMN_PERCENTAGE, &oldval,
-			    GPK_UPDATES_COLUMN_SIZE, &size,
-			    -1);
-	if ((oldval > 0 && oldval < 100) != (subpercentage > 0 && subpercentage < 100)) {
-		if (oldval > 0 && oldval < 100)
-			gpk_update_viewer_remove_active_row (model, path);
-		else
-			gpk_update_viewer_add_active_row (model, path);
-	}
-
-	size_display = size - ((size * subpercentage) / 100);
-	gtk_list_store_set (list_store_updates, &iter,
-			    GPK_UPDATES_COLUMN_PERCENTAGE, subpercentage,
-			    GPK_UPDATES_COLUMN_SIZE_DISPLAY, size_display,
-			    -1);
-
-	gtk_tree_path_free (path);
-}
-
-/**
- * gpk_update_viewer_error_code_cb:
- **/
-static void
-gpk_update_viewer_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gchar *details, gpointer data)
-{
-	GtkWindow *window;
-
-	/* ignore some errors */
-	if (code == PK_ERROR_ENUM_PROCESS_KILL ||
-	    code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
-		egg_debug ("error ignored %s: %s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	/* ignore the ones we can handle */
-	if (code == PK_ERROR_ENUM_NO_LICENSE_AGREEMENT ||
-	    pk_error_code_is_need_untrusted (code)) {
-		egg_debug ("error ignored as we're handling %s: %s", pk_error_enum_to_text (code), details);
-		return;
-	}
-
-	/* ignore not authorised, which seems odd but this will happen if the user clicks cancel */
-	if (code == PK_ERROR_ENUM_NOT_AUTHORIZED) {
-		egg_debug ("auth failure '%s' ignored: %s", pk_error_enum_to_text (code), details);
-		return;
+		gtk_tree_model_get_iter (model, &iter, path);
+		gtk_tree_path_free (path);
+		gtk_list_store_set (array_store_updates, &iter,
+				    GPK_UPDATES_COLUMN_UPDATE_DETAIL_OBJ, (gpointer) pk_item_update_detail_ref (item),
+				    GPK_UPDATES_COLUMN_RESTART, item->restart, -1);
 	}
-
-	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
-	gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (code),
-				gpk_error_enum_to_localised_message (code), details);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_update_viewer_repo_list_changed_cb:
+ * gpk_update_viewer_repo_array_changed_cb:
  **/
 static void
-gpk_update_viewer_repo_list_changed_cb (PkClient *client, gpointer data)
+gpk_update_viewer_repo_array_changed_cb (PkClient *client, gpointer data)
 {
-	gpk_update_viewer_get_new_update_list ();
+	gpk_update_viewer_get_new_update_array ();
 }
 
 /**
@@ -2184,7 +1741,7 @@ gpk_update_viewer_detail_popup_menu_select_all (GtkWidget *menuitem, gpointer us
 	GtkTreeModel *model;
 	PkInfoEnum info;
 
-	/* get the first iter in the list */
+	/* get the first iter in the array */
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
 	while (valid) {
@@ -2212,7 +1769,7 @@ gpk_update_viewer_detail_popup_menu_select_security (GtkWidget *menuitem, gpoint
 	GtkTreeModel *model;
 	PkInfoEnum info;
 
-	/* get the first iter in the list */
+	/* get the first iter in the array */
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
 	while (valid) {
@@ -2238,7 +1795,7 @@ gpk_update_viewer_detail_popup_menu_select_none (GtkWidget *menuitem, gpointer u
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 
-	/* get the first iter in the list */
+	/* get the first iter in the array */
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
 	while (valid) {
@@ -2265,7 +1822,7 @@ gpk_update_viewer_get_checked_status (gboolean *all_checked, gboolean *none_chec
 	GtkTreeIter iter;
 	GtkTreeModel *model;
 
-	/* get the first iter in the list */
+	/* get the first iter in the array */
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
 	model = gtk_tree_view_get_model (treeview);
 	valid = gtk_tree_model_get_iter_first (model, &iter);
@@ -2399,193 +1956,166 @@ gpk_update_viewer_message_received_cb (UniqueApp *app, UniqueCommand command, Un
 }
 
 /**
- * gpk_update_viewer_get_new_update_list
+ * gpk_update_viewer_packages_to_ids:
  **/
-static gboolean
-gpk_update_viewer_get_new_update_list (void)
+static gchar **
+gpk_update_viewer_packages_to_ids (GPtrArray *array)
 {
-	gboolean ret;
-	GError *error = NULL;
-	GtkWidget *widget;
-	gchar *text = NULL;
-	PkBitfield filter = PK_FILTER_ENUM_NONE;
-
-	/* clear all widgets */
-	gtk_list_store_clear (list_store_updates);
-	gtk_text_buffer_set_text (text_buffer, "", -1);
-
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_header_title"));
-	/* TRANSLATORS: this is the header */
-	text = g_strdup_printf ("<big><b>%s</b></big>", _("Checking for updates..."));
-	gtk_label_set_label (GTK_LABEL (widget), text);
-
-	/* reset client */
-	ret = pk_client_reset (client_primary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* only show newest updates? */
-	ret = gconf_client_get_bool (gconf_client, GPK_CONF_UPDATE_VIEWER_ONLY_NEWEST, NULL);
-	if (ret) {
-		egg_warning ("only showing newest updates");
-		filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, -1);
-	}
+	guint i;
+	gchar **value;
+	PkItemPackage *item;
 
-	/* get new list */
-	ret = pk_client_get_updates (client_primary, filter, &error);
-	if (!ret) {
-		egg_warning ("Failed to get updates: %s", error->message);
-		g_error_free (error);
+	value = g_new0 (gchar *, array->len + 1);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		value[i] = g_strdup (item->package_id);
 	}
-out:
-	g_free (text);
-	return ret;
-}
-
-/**
- * gpk_update_viewer_allow_cancel_cb:
- **/
-static void
-gpk_update_viewer_allow_cancel_cb (PkClient *client, gboolean allow_cancel, gpointer data)
-{
-	GtkWidget *widget;
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_quit"));
-	gtk_widget_set_sensitive (widget, allow_cancel);
+	return value;
 }
 
 /**
- * gpk_update_viewer_eula_cb:
+ * gpk_update_viewer_get_updates_cb:
  **/
 static void
-gpk_update_viewer_eula_required_cb (PkClient *client, const gchar *eula_id, const gchar *package_id,
-				    const gchar *vendor_name, const gchar *license_agreement, gpointer data)
-{
-	/* use the helper */
-	gpk_helper_eula_show (helper_eula, eula_id, package_id, vendor_name, license_agreement);
-}
-
-/**
- * gpk_update_viewer_repo_signature_event_cb:
- **/
-static void
-gpk_update_viewer_repo_signature_event_cb (GpkHelperRepoSignature *_helper_repo_signature, GtkResponseType type, const gchar *key_id, const gchar *package_id, gpointer data)
+gpk_update_viewer_get_updates_cb (PkClient *client, GAsyncResult *res, GMainLoop *_loop)
 {
+	PkResults *results;
+	GError *error = NULL;
+	GPtrArray *array = NULL;
+	PkItemPackage *item;
+	gchar *text = NULL;
+	gboolean selected;
+	GtkTreeIter iter;
+	guint i;
+	gchar **package_ids;
 	GtkTreeView *treeview;
 	GtkTreeModel *model;
-	gboolean ret;
-	GError *error = NULL;
-
-	if (type != GTK_RESPONSE_YES) {
-		/* make sensitive again */
-		gpk_update_viewer_undisable_packages ();
-		goto out;
-	}
+	GtkWidget *widget;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
 
-	/* reset client */
-	ret = pk_client_reset (client_secondary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of updates: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
 
-	/* install signature */
-	ret = pk_client_install_signature (client_secondary, PK_SIGTYPE_ENUM_GPG, key_id, package_id, &error);
-	if (!ret) {
-		egg_warning ("cannot install signature: %s", error->message);
-		g_error_free (error);
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get updates: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
 
-		/* make sensitive again */
-		gpk_update_viewer_undisable_packages ();
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+		gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+					gpk_error_enum_to_localised_message (error_item->code), error_item->details);
 		goto out;
 	}
-out:
-	/* set state */
+
+	/* get data */
+	array = pk_results_get_package_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+
+		/* add to array store */
+		text = gpk_package_id_format_twoline (item->package_id, item->summary);
+		egg_debug ("adding: id=%s, text=%s", item->package_id, text);
+		selected = (item->info != PK_INFO_ENUM_BLOCKED);
+		gtk_list_store_append (array_store_updates, &iter);
+		gtk_list_store_set (array_store_updates, &iter,
+				    GPK_UPDATES_COLUMN_TEXT, text,
+				    GPK_UPDATES_COLUMN_ID, item->package_id,
+				    GPK_UPDATES_COLUMN_INFO, item->info,
+				    GPK_UPDATES_COLUMN_SELECT, selected,
+				    GPK_UPDATES_COLUMN_SENSITIVE, selected,
+				    GPK_UPDATES_COLUMN_CLICKABLE, selected,
+				    GPK_UPDATES_COLUMN_RESTART, PK_RESTART_ENUM_NONE,
+				    GPK_UPDATES_COLUMN_STATUS, PK_INFO_ENUM_UNKNOWN,
+				    GPK_UPDATES_COLUMN_SIZE, 0,
+				    GPK_UPDATES_COLUMN_SIZE_DISPLAY, 0,
+				    GPK_UPDATES_COLUMN_PERCENTAGE, 0,
+				    GPK_UPDATES_COLUMN_PULSE, -1,
+				    -1);
+		g_free (text);
+	}
+
+	/* get the download sizes */
+	if (update_array != NULL)
+		g_ptr_array_unref (update_array);
+	update_array = pk_results_get_package_array (results);
+
+	/* sort by name */
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
 	model = gtk_tree_view_get_model (treeview);
-	gpk_update_viewer_reconsider_info (model);
-}
+	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), GPK_UPDATES_COLUMN_ID, GTK_SORT_ASCENDING);
 
-/**
- * gpk_update_viewer_eula_event_cb:
- **/
-static void
-gpk_update_viewer_eula_event_cb (GpkHelperRepoSignature *_helper_eula, GtkResponseType type, const gchar *eula_id, gpointer data)
-{
-	GtkTreeView *treeview;
-	GtkTreeModel *model;
-	gboolean ret;
-	GError *error = NULL;
+	/* get the download sizes */
+	if (update_array->len > 0) {
+		package_ids = gpk_update_viewer_packages_to_ids (array);
 
-	if (type != GTK_RESPONSE_YES) {
-		/* make sensitive again */
-		gpk_update_viewer_undisable_packages ();
-		goto out;
-	}
+		/* get the details of all the packages */
+		pk_client_get_update_detail_async (PK_CLIENT(task), package_ids, cancellable,
+						   (PkProgressCallback) gpk_update_viewer_progress_cb, NULL,
+						   (GAsyncReadyCallback) gpk_update_viewer_get_update_detail_cb, loop);
 
-	/* reset client */
-	ret = pk_client_reset (client_secondary, &error);
-	if (!ret) {
-		egg_warning ("cannot reset client: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
+		/* get the details of all the packages */
+		pk_client_get_details_async (PK_CLIENT(task), package_ids, cancellable,
+					     (PkProgressCallback) gpk_update_viewer_progress_cb, NULL,
+					     (GAsyncReadyCallback) gpk_update_viewer_get_details_cb, loop);
 
-	/* install signature */
-	ret = pk_client_accept_eula (client_secondary, eula_id, &error);
-	if (!ret) {
-		egg_warning ("cannot accept eula: %s", error->message);
-		g_error_free (error);
-		/* make sensitive again */
-		gpk_update_viewer_undisable_packages ();
-		goto out;
+		g_strfreev (package_ids);
 	}
-out:
-	/* set state */
-	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
-	model = gtk_tree_view_get_model (treeview);
+
+	/* are now able to do action */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_install"));
+	gtk_widget_set_sensitive (widget, TRUE);
+
+	/* set info */
 	gpk_update_viewer_reconsider_info (model);
-}
 
-/**
- * gpk_update_viewer_repo_signature_required_cb:
- **/
-static void
-gpk_update_viewer_repo_signature_required_cb (PkClient *client, const gchar *package_id, const gchar *repository_name,
-					      const gchar *key_url, const gchar *key_userid, const gchar *key_id,
-					      const gchar *key_fingerprint, const gchar *key_timestamp,
-					      PkSigTypeEnum type, gpointer data)
-{
-	/* use the helper */
-	gpk_helper_repo_signature_show (helper_repo_signature, package_id, repository_name, key_url, key_userid, key_id, key_fingerprint, key_timestamp);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * pk_client_distro_upgrade_cb:
+ * gpk_update_viewer_get_new_update_array
  **/
-static void
-pk_client_distro_upgrade_cb (PkClient *client, const PkDistroUpgradeObj *obj, gpointer data)
+static gboolean
+gpk_update_viewer_get_new_update_array (void)
 {
-	gchar *text;
-	gchar *text_format;
+	gboolean ret;
 	GtkWidget *widget;
+	gchar *text = NULL;
+	PkBitfield filter = PK_FILTER_ENUM_NONE;
 
-	if (obj->state != PK_UPDATE_STATE_ENUM_STABLE)
-		return;
+	/* clear all widgets */
+	gtk_list_store_clear (array_store_updates);
+	gtk_text_buffer_set_text (text_buffer, "", -1);
 
-	/* only display last (newest) distro */
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_upgrade"));
-	/* TRANSLATORS: new distro available, e.g. F9 to F10 */
-	text = g_strdup_printf (_("New distribution upgrade release '%s' is available"), obj->summary);
-	text_format = g_strdup_printf ("<b>%s</b>", text);
-	gtk_label_set_label (GTK_LABEL (widget), text_format);
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_header_title"));
+	/* TRANSLATORS: this is the header */
+	text = g_strdup_printf ("<big><b>%s</b></big>", _("Checking for updates..."));
+	gtk_label_set_label (GTK_LABEL (widget), text);
+
+	/* only show newest updates? */
+	ret = gconf_client_get_bool (gconf_client, GPK_CONF_UPDATE_VIEWER_ONLY_NEWEST, NULL);
+	if (ret) {
+		egg_debug ("only showing newest updates");
+		filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NEWEST, -1);
+	}
+
+	/* get new array */
+	pk_client_get_updates_async (PK_CLIENT(task), filter, cancellable,
+				     (PkProgressCallback) gpk_update_viewer_progress_cb, NULL,
+				     (GAsyncReadyCallback) gpk_update_viewer_get_updates_cb, loop);
 	g_free (text);
-	g_free (text_format);
-	widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_upgrade"));
-	gtk_widget_show (widget);
+	return ret;
 }
 
 /**
@@ -2758,9 +2288,9 @@ gpk_update_viewer_textview_visibility_notify_event (GtkWidget *text_view, GdkEve
 static void
 gpk_update_viewer_updates_changed_cb (PkControl *_control, gpointer data)
 {
-	/* now try to get newest update list */
+	/* now try to get newest update array */
 	egg_debug ("updates changed");
-	gpk_update_viewer_get_new_update_list ();
+	gpk_update_viewer_get_new_update_array ();
 }
 
 /**
@@ -2805,6 +2335,197 @@ gpk_update_viewer_search_equal_func (GtkTreeModel *model, gint column, const gch
 }
 
 /**
+ * gpk_update_viewer_get_distro_upgrades_best:
+ **/
+static PkItemDistroUpgrade *
+gpk_update_viewer_get_distro_upgrades_best (GPtrArray *array)
+{
+	PkItemDistroUpgrade *item;
+	guint i;
+
+	/* find a stable update */
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		if (item->state == PK_UPDATE_STATE_ENUM_STABLE)
+			goto out;
+	}
+	item = NULL;
+out:
+	return item;
+}
+
+/**
+ * gpk_update_viewer_get_distro_upgrades_cb:
+ **/
+static void
+gpk_update_viewer_get_distro_upgrades_cb (PkClient *client, GAsyncResult *res, GMainLoop *_loop)
+{
+	PkResults *results;
+	GError *error = NULL;
+	GPtrArray *array = NULL;
+	PkItemDistroUpgrade *item;
+	gchar *text = NULL;
+	gchar *text_format = NULL;
+	GtkWidget *widget;
+	GtkTreeView *treeview;
+	GtkTreeModel *model;
+	PkItemErrorCode *error_item = NULL;
+	GtkWindow *window;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of distro upgrades: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get list of distro upgrades: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+
+		window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+		gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (error_item->code),
+					gpk_error_enum_to_localised_message (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_distro_upgrade_array (results);
+	item = gpk_update_viewer_get_distro_upgrades_best (array);
+	if (item == NULL)
+		goto out;
+
+	/* only display last (newest) distro */
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_upgrade"));
+	/* TRANSLATORS: new distro available, e.g. F9 to F10 */
+	text = g_strdup_printf (_("New distribution upgrade release '%s' is available"), item->summary);
+	text_format = g_strdup_printf ("<b>%s</b>", text);
+	gtk_label_set_label (GTK_LABEL (widget), text_format);
+
+	widget = GTK_WIDGET (gtk_builder_get_object (builder, "viewport_upgrade"));
+	gtk_widget_show (widget);
+
+	/* get model */
+	treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview_updates"));
+	model = gtk_tree_view_get_model (treeview);
+	gpk_update_viewer_reconsider_info (model);
+out:
+	g_free (text);
+	g_free (text_format);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_update_viewer_set_network_state:
+ **/
+static void
+gpk_update_viewer_set_network_state (PkNetworkEnum state)
+{
+	GtkWindow *window;
+	GtkWidget *dialog;
+	gboolean ret = TRUE;
+	gchar *text_size = NULL;
+	gchar *message = NULL;
+	guint size = 0; //TODO: FIXME
+
+	/* not on wireless mobile */
+	if (state != PK_NETWORK_ENUM_MOBILE)
+		goto out;
+
+	/* not when small */
+	if (size < GPK_UPDATE_VIEWER_MOBILE_SMALL_SIZE)
+		goto out;
+
+	/* not when ignored */
+	ret = gconf_client_get_bool (gconf_client, GPK_CONF_UPDATE_VIEWER_MOBILE_BBAND, NULL);
+	if (!ret)
+		goto out;
+
+	/* show modal dialog */
+	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_updates"));
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL,
+					 "%s", _("Detected wireless broadband connection"));
+
+	/* TRANSLATORS: this is the button text when we check if it's okay to download */
+	gtk_dialog_add_button (GTK_DIALOG (dialog), _("Update anyway"), GTK_RESPONSE_OK);
+	text_size = g_format_size_for_display (size_total);
+
+	/* TRANSLATORS, the %s is a size, e.g. 13.3Mb */
+	message = g_strdup_printf (_("Connectivity is being provided by wireless broadband, and it may be expensive to download %s."), text_size);
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(dialog), "%s", message);
+	gpk_dialog_embed_do_not_show_widget (GTK_DIALOG (dialog), GPK_CONF_UPDATE_VIEWER_MOBILE_BBAND);
+	gtk_window_set_icon_name (GTK_WINDOW(dialog), GPK_ICON_SOFTWARE_INSTALLER);
+	gtk_dialog_run (GTK_DIALOG(dialog));
+	gtk_widget_destroy (dialog);
+out:
+	g_free (text_size);
+	g_free (message);
+}
+
+/**
+ * gpk_update_viewer_get_properties_cb:
+ **/
+static void
+gpk_update_viewer_get_properties_cb (PkControl *_control, GAsyncResult *res, GMainLoop *_loop)
+{
+//	GtkWidget *widget;
+	GError *error = NULL;
+	gboolean ret;
+	PkBitfield roles;
+	PkNetworkEnum state;
+
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
+	if (!ret) {
+		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
+		g_print ("%s: %s\n", _("Exiting as backend details could not be retrieved"), error->message);
+		g_error_free (error);
+		g_main_loop_quit (loop);
+		goto out;
+	}
+
+	/* get values */
+	g_object_get (control,
+		      "roles", &roles,
+		      "network-state", &state,
+		      NULL);
+
+	gpk_update_viewer_set_network_state (state);
+
+	/* get the distro-upgrades if we support it */
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DISTRO_UPGRADES)) {
+		pk_client_get_distro_upgrades_async (PK_CLIENT(task), cancellable,
+						     (PkProgressCallback) gpk_update_viewer_progress_cb, NULL,
+						     (GAsyncReadyCallback) gpk_update_viewer_get_distro_upgrades_cb, loop);
+	}
+out:
+	return;
+}
+
+/**
+ * gpk_update_viewer_notify_network_state_cb:
+ **/
+static void
+gpk_update_viewer_notify_network_state_cb (PkControl *control_, GParamSpec *pspec, gpointer user_data)
+{
+	PkNetworkEnum state;
+
+	/* show icon? */
+	g_object_get (control,
+		      "network-state", &state,
+		      NULL);
+	gpk_update_viewer_set_network_state (state);
+}
+
+/**
  * main:
  **/
 int
@@ -2816,7 +2537,6 @@ main (int argc, char *argv[])
 	GtkWidget *main_window;
 	GtkWidget *widget;
 	GtkTreeSelection *selection;
-	PkBitfield roles;
 	gboolean ret;
 	guint retval;
 	GError *error = NULL;
@@ -2880,6 +2600,7 @@ main (int argc, char *argv[])
 
 	g_signal_connect (unique_app, "message-received", G_CALLBACK (gpk_update_viewer_message_received_cb), NULL);
 
+	cancellable = g_cancellable_new ();
 	markdown = egg_markdown_new ();
 	egg_markdown_set_output (markdown, EGG_MARKDOWN_OUTPUT_PANGO);
 	egg_markdown_set_escape (markdown, TRUE);
@@ -2887,50 +2608,25 @@ main (int argc, char *argv[])
 
 	control = pk_control_new ();
 	g_signal_connect (control, "repo-list-changed",
-			  G_CALLBACK (gpk_update_viewer_repo_list_changed_cb), NULL);
+			  G_CALLBACK (gpk_update_viewer_repo_array_changed_cb), NULL);
 	g_signal_connect (control, "updates-changed",
 			  G_CALLBACK (gpk_update_viewer_updates_changed_cb), NULL);
+	g_signal_connect (control, "notify::network-state",
+			  G_CALLBACK (gpk_update_viewer_notify_network_state_cb), NULL);
 
 	/* this is what we use mainly */
-	client_primary = pk_client_new ();
-	pk_client_set_use_buffer (client_primary, TRUE, NULL);
-	g_signal_connect (client_primary, "package",
-			  G_CALLBACK (gpk_update_viewer_package_cb), NULL);
-	g_signal_connect (client_primary, "details",
-			  G_CALLBACK (gpk_update_viewer_details_cb), NULL);
-	g_signal_connect (client_primary, "finished",
-			  G_CALLBACK (gpk_update_viewer_finished_cb), NULL);
-	g_signal_connect (client_primary, "progress-changed",
-			  G_CALLBACK (gpk_update_viewer_progress_changed_cb), NULL);
-	g_signal_connect (client_primary, "update-detail",
-			  G_CALLBACK (gpk_update_viewer_update_detail_cb), NULL);
-	g_signal_connect (client_primary, "status-changed",
-			  G_CALLBACK (gpk_update_viewer_status_changed_cb), NULL);
-	g_signal_connect (client_primary, "error-code",
-			  G_CALLBACK (gpk_update_viewer_error_code_cb), NULL);
-	g_signal_connect (client_primary, "allow-cancel",
-			  G_CALLBACK (gpk_update_viewer_allow_cancel_cb), NULL);
-	g_signal_connect (client_primary, "repo-signature-required",
-			  G_CALLBACK (gpk_update_viewer_repo_signature_required_cb), NULL);
-	g_signal_connect (client_primary, "eula-required",
-			  G_CALLBACK (gpk_update_viewer_eula_required_cb), NULL);
-	g_signal_connect (client_primary, "distro-upgrade",
-			  G_CALLBACK (pk_client_distro_upgrade_cb), NULL);
-
-	/* this is for auth and eula callbacks */
-	client_secondary = pk_client_new ();
-	g_signal_connect (client_secondary, "error-code",
-			  G_CALLBACK (gpk_update_viewer_error_code_cb), NULL);
-	g_signal_connect (client_secondary, "finished",
-			  G_CALLBACK (gpk_update_viewer_finished_cb), NULL);
-
-	/* get actions */
-	roles = pk_control_get_actions (control, NULL);
+	task = PK_TASK(gpk_task_new ());
+	g_object_set (task,
+		      "background", FALSE,
+		      NULL);
+
+	/* get properties */
+	pk_control_get_properties_async (control, NULL, (GAsyncReadyCallback) gpk_update_viewer_get_properties_cb, loop);
 
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-update-viewer.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -2940,21 +2636,8 @@ main (int argc, char *argv[])
 	g_signal_connect (main_window, "delete_event", G_CALLBACK (gpk_update_viewer_button_delete_event_cb), NULL);
 	gtk_window_set_icon_name (GTK_WINDOW (main_window), GPK_ICON_SOFTWARE_INSTALLER);
 
-	/* helpers */
-	helper_repo_signature = gpk_helper_repo_signature_new ();
-	g_signal_connect (helper_repo_signature, "event", G_CALLBACK (gpk_update_viewer_repo_signature_event_cb), NULL);
-	gpk_helper_repo_signature_set_parent (helper_repo_signature, GTK_WINDOW (main_window));
-
-	helper_eula = gpk_helper_eula_new ();
-	g_signal_connect (helper_eula, "event", G_CALLBACK (gpk_update_viewer_eula_event_cb), NULL);
-	gpk_helper_eula_set_parent (helper_eula, GTK_WINDOW (main_window));
-
-	helper_deps_update = gpk_helper_deps_update_new ();
-	g_signal_connect (helper_deps_update, "event", G_CALLBACK (gpk_update_viewer_deps_update_event_cb), NULL);
-	gpk_helper_deps_update_set_parent (helper_deps_update, GTK_WINDOW (main_window));
-
-	/* create list stores */
-	list_store_updates = gtk_list_store_new (GPK_UPDATES_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
+	/* create array stores */
+	array_store_updates = gtk_list_store_new (GPK_UPDATES_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
 						 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
 						 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
 						 G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_INT);
@@ -2987,7 +2670,7 @@ main (int argc, char *argv[])
 	gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (widget), gpk_update_viewer_search_equal_func, NULL, NULL);
 	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
 	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
-				 GTK_TREE_MODEL (list_store_updates));
+				 GTK_TREE_MODEL (array_store_updates));
 	gpk_update_viewer_treeview_add_columns_update (GTK_TREE_VIEW (widget));
 	g_signal_connect (widget, "popup-menu",
 			  G_CALLBACK (gpk_update_viewer_detail_popup_menu), NULL);
@@ -3058,44 +2741,30 @@ main (int argc, char *argv[])
 			  G_CALLBACK (gpk_update_viewer_vpaned_realized_cb), NULL);
 
 	/* coldplug */
-	gpk_update_viewer_get_new_update_list ();
+	gpk_update_viewer_get_new_update_array ();
 
 	/* wait */
 	loop = g_main_loop_new (NULL, FALSE);
 	g_main_loop_run (loop);
 
 	/* we might have visual stuff running, close it down */
-	ret = pk_client_cancel (client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_clear_error (&error);
-	}
-
-	/* we might have visual stuff running, close it down */
-	ret = pk_client_cancel (client_secondary, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_error_free (error);
-	}
+	g_cancellable_cancel (cancellable);
 
 	g_main_loop_unref (loop);
 
-	if (update_list != NULL)
-		g_object_unref (update_list);
+	if (update_array != NULL)
+		g_ptr_array_unref (update_array);
 
 	g_strfreev (install_package_ids);
-	g_object_unref (helper_eula);
-	g_object_unref (helper_repo_signature);
-	g_object_unref (helper_deps_update);
-	g_object_unref (list_store_updates);
+	g_object_unref (array_store_updates);
 	g_object_unref (text_buffer);
-	pk_package_id_free (package_id_last);
+	g_free (package_id_last);
 out_build:
 	g_object_unref (gconf_client);
 	g_object_unref (control);
 	g_object_unref (markdown);
-	g_object_unref (client_primary);
-	g_object_unref (client_secondary);
+	g_object_unref (cancellable);
+	g_object_unref (task);
 	g_object_unref (console);
 	g_object_unref (builder);
 unique_out:
diff --git a/src/gpk-watch.c b/src/gpk-watch.c
index 33ca950..adea7b1 100644
--- a/src/gpk-watch.c
+++ b/src/gpk-watch.c
@@ -37,19 +37,20 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 #include <libnotify/notify.h>
-#include <packagekit-glib/packagekit.h>
+#include <packagekit-glib2/packagekit.h>
 
 #include "egg-debug.h"
 #include "egg-string.h"
 #include "egg-console-kit.h"
 
 #include "gpk-common.h"
-#include "gpk-session.h"
+#include "gpk-enum.h"
 #include "gpk-error.h"
-#include "gpk-watch.h"
-#include "gpk-modal-dialog.h"
 #include "gpk-inhibit.h"
-#include "gpk-enum.h"
+#include "gpk-modal-dialog.h"
+#include "gpk-session.h"
+#include "gpk-task.h"
+#include "gpk-watch.h"
 
 static void     gpk_watch_finalize	(GObject       *object);
 
@@ -68,15 +69,17 @@ struct GpkWatchPrivate
 	NotifyNotification	*notification_cached_messages;
 	GpkInhibit		*inhibit;
 	GpkModalDialog		*dialog;
-	PkClient		*client_primary;
-	PkConnection		*pconnection;
-	PkTaskList		*tlist;
+	PkTask			*task;
+	PkTransactionList	*tlist;
 	PkRestartEnum		 restart;
 	GConfClient		*gconf_client;
 	guint			 set_proxy_timeout;
 	gchar			*error_details;
 	gboolean		 hide_warning;
 	EggConsoleKit		*console;
+	GCancellable		*cancellable;
+	GPtrArray		*array_progress;
+	gchar			*transaction_id;
 };
 
 typedef struct {
@@ -162,7 +165,7 @@ gpk_watch_get_restart_required_tooltip (GpkWatch *watch)
 		}
 
 		/* join */
-		text = g_strdup_printf ("%s\n%s", title, message);
+		text = g_strdup_printf ("%s%s", title, message);
 		goto out;
 	}
 
@@ -182,34 +185,33 @@ static gboolean
 gpk_watch_refresh_tooltip (GpkWatch *watch)
 {
 	guint i;
-	PkTaskListItem *item;
-	guint length;
+	PkProgress *progress;
 	guint len;
-	GString *status;
+	GString *string;
+	PkStatusEnum status;
 	const gchar *trailer;
-	const gchar *localised_status;
 	gchar *text;
+	GPtrArray *array;
 
 	g_return_val_if_fail (GPK_IS_WATCH (watch), FALSE);
 
-	status = g_string_new ("");
-	length = pk_task_list_get_size (watch->priv->tlist);
-	egg_debug ("refresh tooltip %i", length);
-	if (length == 0) {
+	string = g_string_new ("");
+	array = watch->priv->array_progress;
+	egg_debug ("refresh tooltip %i", array->len);
+	if (array->len == 0) {
 
 		/* any restart required? */
 		text = gpk_watch_get_restart_required_tooltip (watch);
-		if (text != NULL) {
-			g_string_append (status, text);
-		}
+		if (text != NULL)
+			g_string_append (string, text);
 		g_free (text);
 
 		/* do we have any cached messages to show? */
 		len = watch->priv->cached_messages->len;
 		if (len > 0) {
-			if (status->len > 0)
-				g_string_append_c (status, '\n');
-			g_string_append_printf (status, ngettext ("%i message from the package manager",
+			if (string->len > 0)
+				g_string_append_c (string, '\n');
+			g_string_append_printf (string, ngettext ("%i message from the package manager",
 								  "%i messages from the package manager", len), len);
 			goto out;
 		}
@@ -217,42 +219,31 @@ gpk_watch_refresh_tooltip (GpkWatch *watch)
 		egg_debug ("nothing to show");
 		goto out;
 	}
-	for (i=0; i<length; i++) {
-		item = pk_task_list_get_item (watch->priv->tlist, i);
-		if (item == NULL) {
-			egg_warning ("not found item %i", i);
-			break;
-		}
-		localised_status = gpk_status_enum_to_localised_text (item->status);
+
+	/* print all the running transactions */
+	for (i=0; i<array->len; i++) {
+		progress = g_ptr_array_index (array, i);
+		g_object_get (progress,
+			      "status", &status,
+			      NULL);
 
 		/* should we display the text */
-		if (item->role == PK_ROLE_ENUM_UPDATE_PACKAGES ||
-		    egg_strzero (item->text)) {
-			g_string_append_printf (status, "%s\n", localised_status);
-		} else {
-			/* display the package name, not the package_id */
-			g_string_append_printf (status, "%s: %s\n", localised_status, item->text);
-		}
+		g_string_append_printf (string, "%s\n", gpk_status_enum_to_localised_text (status));
 		/* don't fill the screen with a giant tooltip */
 		if (i > GPK_WATCH_MAXIMUM_TOOLTIP_LINES) {
 			/* TRANSLATORS: if the menu won't fit, inform the user there are a few more things waiting */
 			trailer = ngettext ("(%i more task)", "(%i more tasks)", i - GPK_WATCH_MAXIMUM_TOOLTIP_LINES);
-			g_string_append_printf (status, "%s\n", trailer);
+			g_string_append_printf (string, "%s\n", trailer);
 			break;
 		}
 	}
-	if (status->len == 0)
-		g_string_append (status, "Doing something...");
-	else
-		g_string_set_size (status, status->len-1);
 
+	/* remove trailing newline */
+	if (string->len > 0)
+		g_string_set_size (string, string->len-1);
 out:
-#if GTK_CHECK_VERSION(2,15,0)
-	gtk_status_icon_set_tooltip_text (watch->priv->status_icon, status->str);
-#else
-	gtk_status_icon_set_tooltip (watch->priv->status_icon, status->str);
-#endif
-	g_string_free (status, TRUE);
+	gtk_status_icon_set_tooltip_text (watch->priv->status_icon, string->str);
+	g_string_free (string, TRUE);
 	return TRUE;
 }
 
@@ -262,46 +253,44 @@ out:
 static PkBitfield
 gpk_watch_task_list_to_status_bitfield (GpkWatch *watch)
 {
-	gboolean ret;
 	gboolean active;
 	gboolean watch_active;
 	guint i;
-	guint length;
-	PkBitfield status = 0;
-	PkTaskListItem *item;
+	PkBitfield bitfield = 0;
+	PkStatusEnum status;
+	PkProgress *progress;
+	gchar *transaction_id;
+	GPtrArray *array;
 
-	g_return_val_if_fail (GPK_IS_WATCH (watch), PK_STATUS_ENUM_UNKNOWN);
+	g_return_val_if_fail (GPK_IS_WATCH (watch), 0);
 
 	/* shortcut */
-	length = pk_task_list_get_size (watch->priv->tlist);
-	if (length == 0)
+	array = watch->priv->array_progress;
+	if (array->len == 0)
 		goto out;
 
 	/* do we watch active transactions */
 	watch_active = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_WATCH_ACTIVE_TRANSACTIONS, NULL);
 
 	/* add each status to a list */
-	for (i=0; i<length; i++) {
-		item = pk_task_list_get_item (watch->priv->tlist, i);
-		if (item == NULL) {
-			egg_warning ("not found item %i", i);
-			break;
-		}
+	for (i=0; i<array->len; i++) {
+		progress = g_ptr_array_index (array, i);
 
 		/* only show an icon for this if the application isn't still on the bus */
-		ret = pk_client_is_caller_active (item->monitor, &active, NULL);
-
-		/* if we failed to get data, assume bad things happened */
-		if (!ret)
-			active = TRUE;
+		g_object_get (progress,
+			      "caller-active", &active,
+			      "status", &status,
+			      "transaction-id", &transaction_id,
+			      NULL);
 
 		/* add to bitfield calculation */
-		egg_debug ("%s %s (active:%i)", item->tid, pk_status_enum_to_text (item->status), active);
+		egg_debug ("%s %s (active:%i)", transaction_id, pk_status_enum_to_text (status), active);
 		if (!active || watch_active)
-			pk_bitfield_add (status, item->status);
+			pk_bitfield_add (bitfield, status);
+		g_free (transaction_id);
 	}
 out:
-	return status;
+	return bitfield;
 }
 
 /**
@@ -355,7 +344,7 @@ gpk_watch_refresh_icon (GpkWatch *watch)
 						      PK_STATUS_ENUM_REPACKAGING,
 						      PK_STATUS_ENUM_WAIT,
 						      PK_STATUS_ENUM_WAITING_FOR_LOCK,
-						      PK_STATUS_ENUM_FINISHED, -1);
+						      -1);
 	}
 
 	/* only set if in the list and not unknown */
@@ -390,18 +379,6 @@ out:
 }
 
 /**
- * gpk_watch_task_list_changed_cb:
- **/
-static void
-gpk_watch_task_list_changed_cb (PkTaskList *tlist, GpkWatch *watch)
-{
-	g_return_if_fail (GPK_IS_WATCH (watch));
-
-	gpk_watch_refresh_icon (watch);
-	gpk_watch_refresh_tooltip (watch);
-}
-
-/**
  * gpk_watch_libnotify_cb:
  **/
 static void
@@ -423,324 +400,6 @@ gpk_watch_libnotify_cb (NotifyNotification *notification, gchar *action, gpointe
 }
 
 /**
- * gpk_watch_task_list_finished_cb:
- **/
-static void
-gpk_watch_task_list_finished_cb (PkTaskList *tlist, PkClient *client, PkExitEnum exit_enum, guint runtime, GpkWatch *watch)
-{
-	guint i;
-	gboolean ret;
-	gboolean value;
-	PkRoleEnum role;
-	PkRestartEnum restart;
-	GError *error = NULL;
-	gchar *text = NULL;
-	gchar *message = NULL;
-	NotifyNotification *notification;
-#if PK_CHECK_VERSION(0,5,0)
-	guint j;
-	const PkRequireRestartObj *obj;
-	const PkRequireRestartObj *obj_tmp;
-	PkObjList *array;
-#else
-	PkPackageId *id;
-	const GPtrArray *array;
-#endif
-
-	g_return_if_fail (GPK_IS_WATCH (watch));
-
-	/* get the role */
-	ret = pk_client_get_role (client, &role, &text, NULL);
-	if (!ret) {
-		egg_warning ("cannot get role");
-		goto out;
-	}
-	egg_debug ("role=%s, text=%s", pk_role_enum_to_text (role), text);
-
-	/* is it worth processing? */
-	if (exit_enum != PK_EXIT_ENUM_SUCCESS) {
-		egg_debug ("not processing, as didn't complete okay");
-		goto out;
-	}
-
-	/* show an icon if the user needs to reboot */
-	if (role == PK_ROLE_ENUM_UPDATE_PACKAGES ||
-	    role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
-	    role == PK_ROLE_ENUM_UPDATE_SYSTEM) {
-		/* if more important than what we are already showing, then update the icon */
-		restart = pk_client_get_require_restart (client);
-		if (restart > watch->priv->restart) {
-#if PK_CHECK_VERSION(0,5,0)
-			/* list packages requiring this */
-			array = pk_client_get_require_restart_list (client);
-			if (array == NULL) {
-				egg_warning ("no data about restarts, perhaps not buffered");
-				goto no_data;
-			}
-			for (i=0; i<array->len; i++) {
-				obj = pk_obj_list_index (array, i);
-
-				/* is a lesser restart that what we have already */
-				if (obj->restart != restart)
-					continue;
-
-				/* is already in the list */
-				ret = FALSE;
-				for (j=0; j<array->len; j++) {
-					obj_tmp = pk_obj_list_index (array, j);
-					if (g_strcmp0 (obj_tmp->id->name, obj->id->name) == 0) {
-						ret = TRUE;
-						break;
-					}
-				}
-				if (ret)
-					continue;
-
-				/* add to list */
-				g_ptr_array_add (watch->priv->restart_package_names, g_strdup (obj->id->name));
-			}
-			g_object_unref (array);
-no_data:
-#else
-			/* list packages requiring this */
-			array = pk_client_get_require_restart_list (client);
-			for (i=0; i<array->len; i++) {
-				id = g_ptr_array_index (array, i);
-				g_ptr_array_add (watch->priv->restart_package_names, g_strdup (id->name));
-			}
-#endif
-			/* save new restart */
-			watch->priv->restart = restart;
-		}
-	}
-
-	/* is it worth showing a UI? */
-	if (runtime < 3000) {
-		egg_debug ("no notification, too quick");
-		goto out;
-	}
-
-	/* are we accepting notifications */
-	value = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_NOTIFY_COMPLETED, NULL);
-	if (!value) {
-		egg_debug ("not showing notification as prevented in gconf");
-		goto out;
-	}
-
-	/* is caller able to handle the messages itself? */
-	ret = pk_client_is_caller_active (client, &value, &error);
-	if (!ret) {
-		egg_warning ("could not get caller active status: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-	if (value) {
-		egg_debug ("not showing notification as caller is still present");
-		goto out;
-	}
-
-	if (role == PK_ROLE_ENUM_REMOVE_PACKAGES)
-		/* TRANSLATORS: This is the message in the libnotify body */
-		message = g_strdup_printf (_("Package '%s' has been removed"), text);
-	else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES)
-		/* TRANSLATORS: This is the message in the libnotify body */
-		message = g_strdup_printf (_("Package '%s' has been installed"), text);
-	else if (role == PK_ROLE_ENUM_UPDATE_SYSTEM)
-		/* TRANSLATORS: This is the message in the libnotify body */
-		message = g_strdup (_("System has been updated"));
-
-	/* nothing of interest */
-	if (message == NULL)
-		goto out;
-
-	/* TRANSLATORS: title: an action has finished, and we are showing the libnotify bubble */
-	notification = notify_notification_new (_("Task completed"), message, "help-browser", NULL);
-	notify_notification_set_timeout (notification, 5000);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-	notify_notification_add_action (notification, "do-not-show-notify-complete",
-					_("Do not show this again"), gpk_watch_libnotify_cb, watch, NULL);
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-
-out:
-	g_free (message);
-	g_free (text);
-}
-
-/**
- * gpk_watch_error_code_cb:
- **/
-static void
-gpk_watch_error_code_cb (PkTaskList *tlist, PkClient *client, PkErrorCodeEnum error_code, const gchar *details, GpkWatch *watch)
-{
-	gboolean ret;
-	GError *error = NULL;
-	const gchar *title;
-	gchar *title_prefix;
-	const gchar *message;
-	gboolean is_active;
-	gboolean value;
-	NotifyNotification *notification;
-
-	g_return_if_fail (GPK_IS_WATCH (watch));
-
-	title = gpk_error_enum_to_localised_text (error_code);
-
-	/* if the client dbus connection is still active */
-	pk_client_is_caller_active (client, &is_active, NULL);
-
-	/* do we ignore this error? */
-	if (is_active) {
-		egg_debug ("client active so leaving error %s\n%s", title, details);
-		return;
-	}
-
-	/* ignore some errors */
-	if (error_code == PK_ERROR_ENUM_NOT_SUPPORTED ||
-	    error_code == PK_ERROR_ENUM_NO_NETWORK ||
-	    error_code == PK_ERROR_ENUM_PROCESS_KILL ||
-	    error_code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
-		egg_debug ("error ignored %s\n%s", title, details);
-		return;
-	}
-
-	/* are we accepting notifications */
-	value = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_NOTIFY_ERROR, NULL);
-	if (!value) {
-		egg_debug ("not showing notification as prevented in gconf");
-		return;
-	}
-
-	/* we need to format this */
-	message = gpk_error_enum_to_localised_message (error_code);
-
-	/* save this globally */
-	g_free (watch->priv->error_details);
-	watch->priv->error_details = g_markup_escape_text (details, -1);
-
-	/* TRANSLATORS: Prefix to the title shown in the libnotify popup */
-	title_prefix = g_strdup_printf ("%s: %s", _("Package Manager"), title);
-
-	/* do the bubble */
-	notification = notify_notification_new (title_prefix, message, "help-browser", NULL);
-	notify_notification_set_timeout (notification, 15000);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-	notify_notification_add_action (notification, "show-error-details",
-					/* TRANSLATORS: This is a link in a libnotify bubble that shows the detailed error */
-					_("Show details"), gpk_watch_libnotify_cb, watch, NULL);
-
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-	g_free (title_prefix);
-}
-
-/**
- * gpk_watch_is_message_ignored:
- **/
-static gboolean
-gpk_watch_is_message_ignored (GpkWatch *watch, PkMessageEnum message)
-{
-	guint i;
-	gboolean ret = FALSE;
-	gchar *ignored_str;
-	gchar **ignored = NULL;
-	const gchar *message_str;
-
-	/* get from gconf */
-	ignored_str = gconf_client_get_string (watch->priv->gconf_client, GPK_CONF_IGNORED_MESSAGES, NULL);
-	if (ignored_str == NULL) {
-		egg_warning ("could not read ignored list");
-		goto out;
-	}
-
-	/* nothing in list, common case */
-	if (egg_strzero (ignored_str)) {
-		egg_debug ("nothing in ignored list");
-		goto out;
-	}
-
-	/* split using "," */
-	ignored = g_strsplit (ignored_str, ",", 0);
-
-	/* remove any ignored pattern matches */
-	message_str = pk_message_enum_to_text (message);
-	for (i=0; ignored[i] != NULL; i++) {
-		ret = g_pattern_match_simple (ignored[i], message_str);
-		if (ret) {
-			egg_debug ("match %s for %s, ignoring", ignored[i], message_str);
-			break;
-		}
-	}
-out:
-	g_free (ignored_str);
-	g_strfreev (ignored);
-	return ret;
-}
-
-/**
- * gpk_watch_message_cb:
- **/
-static void
-gpk_watch_message_cb (PkTaskList *tlist, PkClient *client, PkMessageEnum message, const gchar *details, GpkWatch *watch)
-{
-	gboolean ret;
-	GError *error = NULL;
-	gboolean value;
-	NotifyNotification *notification;
-	GpkWatchCachedMessage *cached_message;
-
-	g_return_if_fail (GPK_IS_WATCH (watch));
-
-	/* is ignored */
-	ret = gpk_watch_is_message_ignored (watch, message);
-	if (ret) {
-		egg_debug ("igoring message");
-		return;
-	}
-
-	/* add to list */
-	cached_message = g_new0 (GpkWatchCachedMessage, 1);
-	cached_message->type = message;
-	cached_message->tid = pk_client_get_tid (client);
-	cached_message->details = g_strdup (details);
-	g_ptr_array_add (watch->priv->cached_messages, cached_message);
-
-	/* close existing */
-	if (watch->priv->notification_cached_messages != NULL) {
-		ret = notify_notification_close (watch->priv->notification_cached_messages, &error);
-		if (!ret) {
-			egg_warning ("error: %s", error->message);
-			g_error_free (error);
-			error = NULL;
-		}
-	}
-
-	/* are we accepting notifications */
-	value = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_NOTIFY_MESSAGE, NULL);
-	if (!value) {
-		egg_debug ("not showing notification as prevented in gconf");
-		return;
-	}
-
-	/* do the bubble */
-	notification = notify_notification_new_with_status_icon (_("New package manager message"), NULL, "emblem-important", watch->priv->status_icon);
-	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
-	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
-	ret = notify_notification_show (notification, &error);
-	if (!ret) {
-		egg_warning ("error: %s", error->message);
-		g_error_free (error);
-	}
-	watch->priv->notification_cached_messages = notification;
-}
-
-/**
  * gpk_watch_about_dialog_url_cb:
  **/
 static void
@@ -804,8 +463,8 @@ gpk_watch_show_about_cb (GtkMenuItem *item, gpointer data)
 	if (!strcmp (translators, "translator-credits"))
 		translators = NULL;
 
-	license_trans = g_strconcat (_(license[0]), "\n\n", _(license[1]), "\n\n",
-				     _(license[2]), "\n\n", _(license[3]), "\n",  NULL);
+	license_trans = g_strconcat (_(license[0]), "", _(license[1]), "",
+				     _(license[2]), "", _(license[3]), "",  NULL);
 
 	gtk_about_dialog_set_url_hook (gpk_watch_about_dialog_url_cb, NULL, NULL);
 	gtk_about_dialog_set_email_hook (gpk_watch_about_dialog_url_cb, (gpointer) "mailto:";, NULL);
@@ -882,7 +541,7 @@ gpk_watch_menu_show_messages_cb (GtkMenuItem *item, gpointer data)
 	/* get UI */
 	builder = gtk_builder_new ();
 	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-repo.ui", &error);
-	if (error != NULL) {
+	if (retval == 0) {
 		egg_warning ("failed to load ui: %s", error->message);
 		g_error_free (error);
 		goto out_build;
@@ -963,7 +622,6 @@ gpk_watch_menu_show_messages_cb (GtkMenuItem *item, gpointer data)
 
 	gtk_widget_hide (main_window);
 
-	g_ptr_array_foreach (watch->priv->cached_messages, (GFunc) gpk_watch_cached_message_free, NULL);
 	g_ptr_array_set_size (watch->priv->cached_messages, 0);
 
 	g_object_unref (list_store);
@@ -976,43 +634,6 @@ out_build:
 }
 
 /**
- * gpk_watch_get_role_text:
- **/
-static gchar *
-gpk_watch_get_role_text (PkClient *client)
-{
-	const gchar *role_text;
-	gchar *message;
-	PkRoleEnum role;
-	GError *error = NULL;
-	gboolean ret;
-
-	/* get role and text */
-	ret = pk_client_get_role (client, &role, NULL, &error);
-	if (!ret) {
-		egg_warning ("failed to get role: %s", error->message);
-		g_error_free (error);
-		return NULL;
-	}
-
-	/* present tense localisation */
-	role_text = gpk_role_enum_to_localised_present (role);
-	message = g_strdup_printf ("%s", role_text);
-	return message;
-}
-
-/**
- * gpk_watch_progress_changed_cb:
- **/
-static void
-gpk_watch_progress_changed_cb (PkClient *client, guint percentage, guint subpercentage,
-				guint elapsed, guint remaining, GpkWatch *watch)
-{
-	gpk_modal_dialog_set_percentage (watch->priv->dialog, percentage);
-	gpk_modal_dialog_set_remaining (watch->priv->dialog, remaining);
-}
-
-/**
  * gpk_watch_set_status:
  **/
 static gboolean
@@ -1037,7 +658,7 @@ gpk_watch_set_status (GpkWatch *watch, PkStatusEnum status)
 
 	/* spin */
 	if (status == PK_STATUS_ENUM_WAIT)
-		gpk_modal_dialog_set_percentage (watch->priv->dialog, PK_CLIENT_PERCENTAGE_INVALID);
+		gpk_modal_dialog_set_percentage (watch->priv->dialog, -1);
 
 	/* do visual stuff when finished */
 	if (status == PK_STATUS_ENUM_FINISHED) {
@@ -1051,95 +672,75 @@ gpk_watch_set_status (GpkWatch *watch, PkStatusEnum status)
 }
 
 /**
- * gpk_watch_status_changed_cb:
+ * gpk_watch_lookup_progress_from_transaction_id:
  **/
-static void
-gpk_watch_status_changed_cb (PkClient *client, PkStatusEnum status, GpkWatch *watch)
+static PkProgress *
+gpk_watch_lookup_progress_from_transaction_id (GpkWatch *watch, const gchar *transaction_id)
 {
-	gpk_watch_set_status (watch, status);
-}
-
-/**
- * gpk_watch_package_cb:
- **/
-static void
-gpk_watch_package_cb (PkClient *client, const PkPackageObj *obj, GpkWatch *watch)
-{
-	gchar *text;
-	text = gpk_package_id_format_twoline (obj->id, obj->summary);
-	gpk_modal_dialog_set_message (watch->priv->dialog, text);
-	g_free (text);
+	GPtrArray *array;
+	guint i;
+	gchar *tid_tmp;
+	gboolean ret;
+	PkProgress *progress;
+
+	array = watch->priv->array_progress;
+	for (i=0; i<array->len; i++) {
+		progress = g_ptr_array_index (array, i);
+		g_object_get (progress,
+			      "transaction-id", &tid_tmp,
+			      NULL);
+		ret = (g_strcmp0 (transaction_id, tid_tmp) == 0);
+		g_free (tid_tmp);
+		if (ret)
+			goto out;
+	}
+	progress = NULL;
+out:
+	return progress;
 }
 
 /**
  * gpk_watch_monitor_tid:
  **/
 static gboolean
-gpk_watch_monitor_tid (GpkWatch *watch, const gchar *tid)
+gpk_watch_monitor_tid (GpkWatch *watch, const gchar *transaction_id)
 {
-	PkStatusEnum status;
-	gboolean ret;
 	gboolean allow_cancel;
-	gchar *text;
 	gchar *package_id = NULL;
+	gchar *text;
 	guint percentage;
-	guint subpercentage;
-	guint elapsed;
-	guint remaining;
-	GError *error = NULL;
+	guint remaining_time;
+	PkProgress *progress;
 	PkRoleEnum role;
+	PkStatusEnum status;
 
-	/* reset client */
-	ret = pk_client_reset (watch->priv->client_primary, &error);
-	if (!ret) {
-		egg_warning ("failed to reset client: %s", error->message);
-		g_error_free (error);
-		return FALSE;
-	}
+	g_free (watch->priv->transaction_id);
+	watch->priv->transaction_id = g_strdup (transaction_id);
 
-	ret = pk_client_set_tid (watch->priv->client_primary, tid, &error);
-	if (!ret) {
-		egg_warning ("could not set tid: %s", error->message);
-		g_error_free (error);
+	/* find progress */
+	progress = gpk_watch_lookup_progress_from_transaction_id (watch, transaction_id);
+	if (progress == NULL) {
+		egg_warning ("could not find: %s", transaction_id);
 		return FALSE;
 	}
 
-	/* fill in role */
-	text = gpk_watch_get_role_text (watch->priv->client_primary);
-	gpk_modal_dialog_set_title (watch->priv->dialog, text);
-	g_free (text);
-
 	/* coldplug */
-	ret = pk_client_get_status (watch->priv->client_primary, &status, NULL);
-	/* no such transaction? */
-	if (!ret) {
-		egg_warning ("could not get status");
-		return FALSE;
-	}
+	g_object_get (progress,
+		      "role", &role,
+		      "status", &status,
+		      "allow-cancel", &allow_cancel,
+		      "percentage", &percentage,
+		      "remaining-time", &remaining_time,
+		      "package-id", &package_id,
+		      NULL);
+
+	/* fill in role */
+	gpk_modal_dialog_set_title (watch->priv->dialog, gpk_role_enum_to_localised_present (role));
 
 	/* are we cancellable? */
-	pk_client_get_allow_cancel (watch->priv->client_primary, &allow_cancel, NULL);
 	gpk_modal_dialog_set_allow_cancel (watch->priv->dialog, allow_cancel);
-
-	/* coldplug */
-	ret = pk_client_get_progress (watch->priv->client_primary,
-				      &percentage, &subpercentage, &elapsed, &remaining, NULL);
-	if (ret) {
-		gpk_watch_progress_changed_cb (watch->priv->client_primary, percentage,
-						subpercentage, elapsed, remaining, watch);
-	} else {
-		egg_warning ("GetProgress failed");
-		gpk_watch_progress_changed_cb (watch->priv->client_primary,
-						PK_CLIENT_PERCENTAGE_INVALID,
-						PK_CLIENT_PERCENTAGE_INVALID, 0, 0, watch);
-	}
-
-	/* get the role */
-	ret = pk_client_get_role (watch->priv->client_primary, &role, NULL, &error);
-	if (!ret) {
-		egg_warning ("failed to get role: %s", error->message);
-		g_error_free (error);
-	}
+	gpk_modal_dialog_set_percentage (watch->priv->dialog, percentage);
+	gpk_modal_dialog_set_remaining (watch->priv->dialog, remaining_time);
 
 	/* setup the UI */
 	if (role == PK_ROLE_ENUM_SEARCH_NAME ||
@@ -1156,23 +757,12 @@ gpk_watch_monitor_tid (GpkWatch *watch, const gchar *tid)
 	gpk_watch_set_status (watch, status);
 
 	/* do the best we can, and get the last package */
-	ret = pk_client_get_package (watch->priv->client_primary, &package_id, NULL);
-	if (ret) {
-		PkPackageId *id;
-		PkPackageObj *obj;
-
-		id = pk_package_id_new_from_string (package_id);
-		if (id != NULL) {
-			obj = pk_package_obj_new (PK_INFO_ENUM_UNKNOWN, id, NULL);
-			egg_warning ("package_id=%s", package_id);
-			gpk_watch_package_cb (watch->priv->client_primary, obj, watch);
-			pk_package_obj_free (obj);
-		}
-		pk_package_id_free (id);
-	}
+	text = gpk_package_id_format_twoline (package_id, NULL);
+	gpk_modal_dialog_set_message (watch->priv->dialog, text);
 
 	gpk_modal_dialog_present (watch->priv->dialog);
-
+	g_free (package_id);
+	g_free (text);
 	return TRUE;
 }
 
@@ -1200,57 +790,56 @@ gpk_watch_menu_job_status_cb (GtkMenuItem *item, GpkWatch *watch)
 /**
  * gpk_watch_populate_menu_with_jobs:
  **/
-static guint
+static void
 gpk_watch_populate_menu_with_jobs (GpkWatch *watch, GtkMenu *menu)
 {
 	guint i;
-	PkTaskListItem *item;
+	PkProgress *progress;
 	GtkWidget *widget;
 	GtkWidget *image;
-	const gchar *localised_status;
-	const gchar *localised_role;
+	PkRoleEnum role;
+	PkStatusEnum status;
 	const gchar *icon_name;
 	gchar *text;
-	guint length;
+	gchar *transaction_id;
+	GPtrArray *array;
 
-	g_return_val_if_fail (GPK_IS_WATCH (watch), 0);
+	g_return_if_fail (GPK_IS_WATCH (watch));
 
-	length = pk_task_list_get_size (watch->priv->tlist);
-	if (length == 0)
+	array = watch->priv->array_progress;
+	if (array->len == 0)
 		goto out;
 
 	/* do a menu item for each job */
-	for (i=0; i<length; i++) {
-		item = pk_task_list_get_item (watch->priv->tlist, i);
-		if (item == NULL) {
-			egg_warning ("not found item %i", i);
-			break;
-		}
-		localised_role = gpk_role_enum_to_localised_present (item->role);
-		localised_status = gpk_status_enum_to_localised_text (item->status);
-
-		icon_name = gpk_status_enum_to_icon_name (item->status);
-		if (!egg_strzero (item->text) &&
-		    item->role != PK_ROLE_ENUM_UPDATE_PACKAGES)
-			text = g_strdup_printf ("%s %s (%s)", localised_role, item->text, localised_status);
-		else
-			text = g_strdup_printf ("%s (%s)", localised_role, localised_status);
+	for (i=0; i<array->len; i++) {
+		progress = g_ptr_array_index (array, i);
+		g_object_get (progress,
+			      "role", &role,
+			      "status", &status,
+			      "transaction-id", &transaction_id,
+			      NULL);
+
+		icon_name = gpk_status_enum_to_icon_name (status);
+		text = g_strdup_printf ("%s (%s)",
+					gpk_role_enum_to_localised_present (role),
+					gpk_status_enum_to_localised_text (status));
 
 		/* add a job */
 		widget = gtk_image_menu_item_new_with_mnemonic (text);
 
 		/* we need the job ID so we know what transaction to show */
-		g_object_set_data (G_OBJECT (widget), "tid", (gpointer) item->tid);
+		g_object_set_data_full (G_OBJECT (widget), "tid", g_strdup (transaction_id), g_free);
 
 		image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
 		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), image);
 		g_signal_connect (G_OBJECT (widget), "activate",
 				  G_CALLBACK (gpk_watch_menu_job_status_cb), watch);
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget);
+		g_free (transaction_id);
 		g_free (text);
 	}
 out:
-	return length;
+	return;
 }
 
 /**
@@ -1321,7 +910,7 @@ gpk_watch_activate_status_cb (GtkStatusIcon *status_icon, GpkWatch *watch)
 	egg_debug ("icon left clicked");
 
 	/* add jobs as drop down */
-	len = gpk_watch_populate_menu_with_jobs (watch, menu);
+	gpk_watch_populate_menu_with_jobs (watch, menu);
 
 	/* any messages to show? */
 	len = watch->priv->cached_messages->len;
@@ -1383,21 +972,6 @@ gpk_watch_activate_status_cb (GtkStatusIcon *status_icon, GpkWatch *watch)
 }
 
 /**
- * gpk_watch_locked_cb:
- **/
-static void
-gpk_watch_locked_cb (PkClient *client, gboolean is_locked, GpkWatch *watch)
-{
-	g_return_if_fail (GPK_IS_WATCH (watch));
-
-	egg_debug ("setting locked %i, doing g-p-m (un)inhibit", is_locked);
-	if (is_locked)
-		gpk_inhibit_create (watch->priv->inhibit);
-	else
-		gpk_inhibit_remove (watch->priv->inhibit);
-}
-
-/**
  * gpk_watch_get_proxy_ftp:
  * Return value: server.lan:8080
  **/
@@ -1515,6 +1089,28 @@ out:
 }
 
 /**
+ * gpk_watch_set_proxy_cb:
+ **/
+static void
+gpk_watch_set_proxy_cb (GObject *object, GAsyncResult *res, GpkWatch *watch)
+{
+	PkControl *control = PK_CONTROL (object);
+	GError *error = NULL;
+	gboolean ret;
+
+	/* we can run again */
+	watch->priv->set_proxy_timeout = 0;
+
+	/* get the result */
+	ret = pk_control_set_proxy_finish (control, res, &error);
+	if (!ret) {
+		egg_warning ("failed to set proxies: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+}
+
+/**
  * gpk_watch_set_proxies_ratelimit:
  **/
 static gboolean
@@ -1522,10 +1118,6 @@ gpk_watch_set_proxies_ratelimit (GpkWatch *watch)
 {
 	gchar *proxy_http;
 	gchar *proxy_ftp;
-	gboolean ret;
-	GError *error = NULL;
-
-	g_return_val_if_fail (GPK_IS_WATCH (watch), FALSE);
 
 	/* debug so we can catch polling */
 	egg_debug ("polling check");
@@ -1534,17 +1126,10 @@ gpk_watch_set_proxies_ratelimit (GpkWatch *watch)
 	proxy_ftp = gpk_watch_get_proxy_ftp (watch);
 
 	egg_debug ("set proxy_http=%s, proxy_ftp=%s", proxy_http, proxy_ftp);
-	ret = pk_control_set_proxy (watch->priv->control, proxy_http, proxy_ftp, &error);
-	if (!ret) {
-		egg_warning ("setting proxy failed: %s", error->message);
-		g_error_free (error);
-	}
-
+	pk_control_set_proxy_async (watch->priv->control, proxy_http, proxy_ftp, watch->priv->cancellable,
+				    (GAsyncReadyCallback) gpk_watch_set_proxy_cb, watch);
 	g_free (proxy_http);
 	g_free (proxy_ftp);
-
-	/* we can run again */
-	watch->priv->set_proxy_timeout = 0;
 	return FALSE;
 }
 
@@ -1577,73 +1162,531 @@ gpk_watch_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *
 }
 
 /**
- * gpk_watch_allow_cancel_cb:
+ * gpk_watch_button_close_cb:
  **/
 static void
-gpk_watch_allow_cancel_cb (PkClient *client, gboolean allow_cancel, GpkWatch *watch)
+gpk_watch_button_close_cb (GtkWidget *widget, GpkWatch *watch)
 {
-	gpk_modal_dialog_set_allow_cancel (watch->priv->dialog, allow_cancel);
+	/* close, don't abort */
+	gpk_modal_dialog_close (watch->priv->dialog);
+}
+
+/**
+ * gpk_watch_button_cancel_cb:
+ **/
+static void
+gpk_watch_button_cancel_cb (GtkWidget *widget, GpkWatch *watch)
+{
+	/* we might have a transaction running */
+	g_cancellable_cancel (watch->priv->cancellable);
+}
+
+/**
+ * gpk_watch_set_connected:
+ **/
+static void
+gpk_watch_set_connected (GpkWatch *watch, gboolean connected)
+{
+	if (!connected) {
+		gtk_status_icon_set_visible (watch->priv->status_icon, FALSE);
+		return;
+	}
+
+	/* daemon has just appeared */
+	egg_debug ("dameon has just appeared");
+	gpk_watch_refresh_icon (watch);
+	gpk_watch_refresh_tooltip (watch);
+	gpk_watch_set_proxies (watch);
+}
+
+/**
+ * gpk_watch_notify_connected_cb:
+ **/
+static void
+gpk_watch_notify_connected_cb (PkControl *control, GParamSpec *pspec, GpkWatch *watch)
+{
+	gboolean connected;
+	g_object_get (control, "connected", &connected, NULL);
+	gpk_watch_set_connected (watch, connected);
 }
 
 /**
- * gpk_watch_finished_cb:
+ * gpk_watch_notify_locked_cb:
  **/
 static void
-gpk_watch_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkWatch *watch)
+gpk_watch_notify_locked_cb (PkControl *control, GParamSpec *pspec, GpkWatch *watch)
+{
+	gboolean locked;
+	g_object_get (control, "locked", &locked, NULL);
+	if (locked)
+		gpk_inhibit_create (watch->priv->inhibit);
+	else
+		gpk_inhibit_remove (watch->priv->inhibit);
+}
+
+/**
+ * gpk_watch_is_message_ignored:
+ **/
+static gboolean
+gpk_watch_is_message_ignored (GpkWatch *watch, PkMessageEnum message)
 {
+	guint i;
+	gboolean ret = FALSE;
+	gchar *ignored_str;
+	gchar **ignored = NULL;
+	const gchar *message_str;
+
+	/* get from gconf */
+	ignored_str = gconf_client_get_string (watch->priv->gconf_client, GPK_CONF_IGNORED_MESSAGES, NULL);
+	if (ignored_str == NULL) {
+		egg_warning ("could not read ignored list");
+		goto out;
+	}
+
+	/* nothing in list, common case */
+	if (egg_strzero (ignored_str)) {
+		egg_debug ("nothing in ignored list");
+		goto out;
+	}
+
+	/* split using "," */
+	ignored = g_strsplit (ignored_str, ",", 0);
+
+	/* remove any ignored pattern matches */
+	message_str = pk_message_enum_to_text (message);
+	for (i=0; ignored[i] != NULL; i++) {
+		ret = g_pattern_match_simple (ignored[i], message_str);
+		if (ret) {
+			egg_debug ("match %s for %s, ignoring", ignored[i], message_str);
+			break;
+		}
+	}
+out:
+	g_free (ignored_str);
+	g_strfreev (ignored);
+	return ret;
+}
+
+/**
+ * pk_watch_process_messages_cb:
+ **/
+static void
+pk_watch_process_messages_cb (PkItemMessage *item, GpkWatch *watch)
+{
+	gboolean ret;
+	GError *error = NULL;
+	gboolean value;
+	NotifyNotification *notification;
+	GpkWatchCachedMessage *cached_message;
+
 	g_return_if_fail (GPK_IS_WATCH (watch));
 
-	/* stop spinning */
-	gpk_modal_dialog_set_percentage (watch->priv->dialog, 100);
+	/* is ignored */
+	ret = gpk_watch_is_message_ignored (watch, item->type);
+	if (ret) {
+		egg_debug ("ignoring message");
+		return;
+	}
 
-	/* autoclose if success */
-	if (exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		gpk_modal_dialog_close (watch->priv->dialog);
+	/* add to list */
+	cached_message = g_new0 (GpkWatchCachedMessage, 1);
+	cached_message->type = item->type;
+	cached_message->tid = NULL;
+	cached_message->details = g_strdup (item->details);
+	g_ptr_array_add (watch->priv->cached_messages, cached_message);
+
+	/* close existing */
+	if (watch->priv->notification_cached_messages != NULL) {
+		ret = notify_notification_close (watch->priv->notification_cached_messages, &error);
+		if (!ret) {
+			egg_warning ("error: %s", error->message);
+			g_error_free (error);
+			error = NULL;
+		}
+	}
+
+	/* are we accepting notifications */
+	value = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_NOTIFY_MESSAGE, NULL);
+	if (!value) {
+		egg_debug ("not showing notification as prevented in gconf");
+		return;
+	}
+
+	/* do the bubble */
+	notification = notify_notification_new_with_status_icon (_("New package manager message"), NULL, "emblem-important", watch->priv->status_icon);
+	notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+	ret = notify_notification_show (notification, &error);
+	if (!ret) {
+		egg_warning ("error: %s", error->message);
+		g_error_free (error);
 	}
+	watch->priv->notification_cached_messages = notification;
 }
 
 /**
- * gpk_watch_button_close_cb:
+ * pk_watch_process_error_code:
  **/
 static void
-gpk_watch_button_close_cb (GtkWidget *widget, GpkWatch *watch)
+pk_watch_process_error_code (GpkWatch *watch, PkItemErrorCode *item)
 {
-	/* close, don't abort */
-	gpk_modal_dialog_close (watch->priv->dialog);
+	gboolean ret;
+	GError *error = NULL;
+	const gchar *title;
+	gchar *title_prefix = NULL;
+	const gchar *message;
+	gboolean value;
+	NotifyNotification *notification;
+
+	g_return_if_fail (GPK_IS_WATCH (watch));
+
+	title = gpk_error_enum_to_localised_text (item->code);
+
+	/* ignore some errors */
+	if (item->code == PK_ERROR_ENUM_NOT_SUPPORTED ||
+	    item->code == PK_ERROR_ENUM_NO_NETWORK ||
+	    item->code == PK_ERROR_ENUM_PROCESS_KILL ||
+	    item->code == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+		egg_debug ("error ignored %s%s", title, item->details);
+		goto out;
+	}
+
+	/* are we accepting notifications */
+	value = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_NOTIFY_ERROR, NULL);
+	if (!value) {
+		egg_debug ("not showing notification as prevented in gconf");
+		goto out;
+	}
+
+	/* we need to format this */
+	message = gpk_error_enum_to_localised_message (item->code);
+
+	/* save this globally */
+	g_free (watch->priv->error_details);
+	watch->priv->error_details = g_markup_escape_text (item->details, -1);
+
+	/* TRANSLATORS: Prefix to the title shown in the libnotify popup */
+	title_prefix = g_strdup_printf ("%s: %s", _("Package Manager"), title);
+
+	/* do the bubble */
+	notification = notify_notification_new (title_prefix, message, "help-browser", NULL);
+	notify_notification_set_timeout (notification, 15000);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+	notify_notification_add_action (notification, "show-error-details",
+					/* TRANSLATORS: This is a link in a libnotify bubble that shows the detailed error */
+					_("Show details"), gpk_watch_libnotify_cb, watch, NULL);
+
+	ret = notify_notification_show (notification, &error);
+	if (!ret) {
+		egg_warning ("error: %s", error->message);
+		g_error_free (error);
+	}
+out:
+	g_free (title_prefix);
 }
 
 /**
- * gpk_watch_button_cancel_cb:
+ * pk_watch_process_require_restart_cb:
  **/
 static void
-gpk_watch_button_cancel_cb (GtkWidget *widget, GpkWatch *watch)
+pk_watch_process_require_restart_cb (PkItemRequireRestart *item, GpkWatch *watch)
+{
+	GPtrArray *array = NULL;
+	GPtrArray *names = NULL;
+	const gchar *name;
+	gchar **split = NULL;
+	guint i;
+
+	/* if less important than what we are already showing */
+	if (item->restart <= watch->priv->restart)
+		goto out;
+
+	/* add name if not already in the list */
+	split = pk_package_id_split (item->package_id);
+	names = watch->priv->restart_package_names;
+	for (i=0; i<names->len; i++) {
+		name = g_ptr_array_index (names, i);
+		if (g_strcmp0 (name, split[PK_PACKAGE_ID_NAME]) == 0)
+			break;
+	}
+	if (i < names->len) {
+		/* add to list */
+		g_ptr_array_add (names, g_strdup (split[PK_PACKAGE_ID_NAME]));
+	}
+
+	/* save new restart */
+	watch->priv->restart = item->restart;
+out:
+	g_strfreev (split);
+	if (array != NULL)
+		g_object_unref (array);
+}
+
+/**
+ * gpk_watch_adopt_cb:
+ **/
+static void
+gpk_watch_adopt_cb (PkClient *client, GAsyncResult *res, GpkWatch *watch)
 {
+	const gchar *message = NULL;
+	gboolean caller_active;
 	gboolean ret;
+	gchar *transaction_id = NULL;
 	GError *error = NULL;
+	GPtrArray *array;
+	guint elapsed_time;
+	NotifyNotification *notification;
+	PkProgress *progress = NULL;
+	PkResults *results;
+	PkRoleEnum role;
+	PkItemErrorCode *error_item = NULL;
 
-	/* we might have a transaction running */
-	ret = pk_client_cancel (watch->priv->client_primary, &error);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to adopt: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* get data about the transaction */
+	g_object_get (results,
+		      "role", &role,
+		      "progress", &progress,
+		      NULL);
+
+	/* get data */
+	g_object_get (progress,
+		      "transaction-id", &transaction_id,
+		      "caller-active", &caller_active,
+		      "elapsed-time", &elapsed_time,
+		      NULL);
+
+	/* is not the watched transaction */
+	if (g_strcmp0 (transaction_id, watch->priv->transaction_id) != 0)
+		goto out;
+
+	/* stop spinning */
+	gpk_modal_dialog_set_percentage (watch->priv->dialog, 100);
+
+	/* autoclose if success */
+	error_item = pk_results_get_error_code (results);
+	if (error_item == NULL)
+		gpk_modal_dialog_close (watch->priv->dialog);
+
+	/* process messages */
+	if (error_item == NULL) {
+		array = pk_results_get_message_array (results);
+		g_ptr_array_foreach (array, (GFunc) pk_watch_process_messages_cb, watch);
+		g_ptr_array_unref (array);
+	}
+
+	/* only process errors if caller is no longer on the bus */
+	if (error_item != NULL && !caller_active)
+		pk_watch_process_error_code (watch, error_item);
+
+	/* process restarts */
+	if (role == PK_ROLE_ENUM_UPDATE_PACKAGES ||
+	    role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
+	    role == PK_ROLE_ENUM_UPDATE_SYSTEM) {
+		array = pk_results_get_require_restart_array (results);
+		g_ptr_array_foreach (array, (GFunc) pk_watch_process_require_restart_cb, watch);
+		g_ptr_array_unref (array);
+	}
+
+	/* are we accepting notifications */
+	ret = gconf_client_get_bool (watch->priv->gconf_client, GPK_CONF_NOTIFY_COMPLETED, NULL);
+	if (!ret) {
+		egg_debug ("not showing notification as prevented in gconf");
+		goto out;
+	}
+
+	/* is it worth showing a UI? */
+	if (elapsed_time < 3000) {
+		egg_debug ("no notification, too quick");
+		goto out;
+	}
+
+	/* is caller able to handle the messages itself? */
+	if (caller_active) {
+		egg_debug ("not showing notification as caller is still present");
+		goto out;
+	}
+
+	if (role == PK_ROLE_ENUM_REMOVE_PACKAGES)
+		/* TRANSLATORS: This is the message in the libnotify body */
+		message = _("Packages have been removed");
+	else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES)
+		/* TRANSLATORS: This is the message in the libnotify body */
+		message = _("Packages have been installed");
+	else if (role == PK_ROLE_ENUM_UPDATE_SYSTEM)
+		/* TRANSLATORS: This is the message in the libnotify body */
+		message = _("System has been updated");
+
+	/* nothing of interest */
+	if (message == NULL)
+		goto out;
+
+	/* TRANSLATORS: title: an action has finished, and we are showing the libnotify bubble */
+	notification = notify_notification_new (_("Task completed"), message, "help-browser", NULL);
+	notify_notification_set_timeout (notification, 5000);
+	notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+	notify_notification_add_action (notification, "do-not-show-notify-complete",
+					_("Do not show this again"), gpk_watch_libnotify_cb, watch, NULL);
+	ret = notify_notification_show (notification, &error);
 	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
+		egg_warning ("error: %s", error->message);
 		g_error_free (error);
 	}
+out:
+	g_free (transaction_id);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (progress != NULL)
+		g_object_unref (progress);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
- * gpk_watch_connection_changed_cb:
+ * gpk_watch_progress_cb:
  **/
 static void
-gpk_watch_connection_changed_cb (PkConnection *pconnection, gboolean connected, GpkWatch *watch)
+gpk_watch_progress_cb (PkProgress *progress, PkProgressType type, GpkWatch *watch)
 {
-	g_return_if_fail (GPK_IS_WATCH (watch));
-	egg_debug ("connected=%i", connected);
-	if (connected) {
+	PkStatusEnum status;
+	guint percentage;
+	gboolean allow_cancel;
+	gchar *package_id = NULL;
+	gchar *transaction_id = NULL;
+	GPtrArray *array;
+	guint i;
+	gboolean ret = FALSE;
+	PkProgress *progress_tmp;
+	guint remaining_time;
+	gchar *text = NULL;
+
+	/* add if not already in list */
+	array = watch->priv->array_progress;
+	for (i=0; i<array->len; i++) {
+		progress_tmp = g_ptr_array_index (array, i);
+		if (progress_tmp == progress)
+			ret = TRUE;
+	}
+	if (!ret) {
+		egg_debug ("adding progress %p", progress);
+		g_ptr_array_add (array, g_object_ref (progress));
+	}
+
+	/* get data */
+	g_object_get (progress,
+		      "status", &status,
+		      "percentage", &percentage,
+		      "allow-cancel", &allow_cancel,
+		      "package-id", &package_id,
+		      "remaining-time", &remaining_time,
+		      "transaction-id", &transaction_id,
+		      NULL);
+
+	/* refresh both */
+	if (type == PK_PROGRESS_TYPE_STATUS) {
 		gpk_watch_refresh_icon (watch);
 		gpk_watch_refresh_tooltip (watch);
-		gpk_watch_set_proxies (watch);
-	} else {
-		gtk_status_icon_set_visible (watch->priv->status_icon, FALSE);
 	}
+
+	/* is not the watched transaction */
+	if (g_strcmp0 (transaction_id, watch->priv->transaction_id) != 0)
+		goto out;
+
+	if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
+		text = gpk_package_id_format_twoline (package_id, NULL);
+		gpk_modal_dialog_set_message (watch->priv->dialog, text);
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+		gpk_modal_dialog_set_percentage (watch->priv->dialog, percentage);
+	} else if (type == PK_PROGRESS_TYPE_REMAINING_TIME) {
+		gpk_modal_dialog_set_remaining (watch->priv->dialog, remaining_time);
+	} else if (type == PK_PROGRESS_TYPE_ALLOW_CANCEL) {
+		gpk_modal_dialog_set_allow_cancel (watch->priv->dialog, allow_cancel);
+	} else if (type == PK_PROGRESS_TYPE_STATUS) {
+		gpk_watch_set_status (watch, status);
+	}
+out:
+	g_free (text);
+	g_free (package_id);
+	g_free (transaction_id);
+}
+
+/**
+ * gpk_watch_transaction_list_added_cb:
+ **/
+static void
+gpk_watch_transaction_list_added_cb (PkTransactionList *tlist, const gchar *transaction_id, GpkWatch *watch)
+{
+	PkProgress *progress;
+
+	/* find progress */
+	progress = gpk_watch_lookup_progress_from_transaction_id (watch, transaction_id);
+	if (progress != NULL) {
+		egg_warning ("already added: %s", transaction_id);
+		return;
+	}
+	egg_debug ("added: %s", transaction_id);
+	pk_client_adopt_async (PK_CLIENT(watch->priv->task), transaction_id, NULL,
+			       (PkProgressCallback) gpk_watch_progress_cb, watch,
+			       (GAsyncReadyCallback) gpk_watch_adopt_cb, watch);
+}
+
+/**
+ * gpk_watch_transaction_list_removed_cb:
+ **/
+static void
+gpk_watch_transaction_list_removed_cb (PkTransactionList *tlist, const gchar *transaction_id, GpkWatch *watch)
+{
+	PkProgress *progress;
+
+	/* find progress */
+	progress = gpk_watch_lookup_progress_from_transaction_id (watch, transaction_id);
+	if (progress == NULL) {
+		egg_warning ("could not find: %s", transaction_id);
+		return;
+	}
+	egg_debug ("removed: %s", transaction_id);
+	g_ptr_array_remove_fast (watch->priv->array_progress, progress);
+
+	/* refresh both */
+	gpk_watch_refresh_icon (watch);
+	gpk_watch_refresh_tooltip (watch);
+}
+
+/**
+ * gpk_check_update_get_properties_cb:
+ **/
+static void
+gpk_check_update_get_properties_cb (GObject *object, GAsyncResult *res, GpkWatch *watch)
+{
+	gboolean connected;
+	GError *error = NULL;
+	PkControl *control = PK_CONTROL(object);
+	gboolean ret;
+
+	/* get the result */
+	ret = pk_control_get_properties_finish (control, res, &error);
+	if (!ret) {
+		/* TRANSLATORS: backend is broken, and won't tell us what it supports */
+		egg_warning ("details could not be retrieved: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* get values */
+	g_object_get (control,
+		      "connected", &connected,
+		      NULL);
+
+	/* coldplug daemon */
+	gpk_watch_set_connected (watch, connected);
+out:
+	return;
 }
 
 /**
@@ -1656,29 +1699,22 @@ gpk_watch_init (GpkWatch *watch)
 	watch->priv = GPK_WATCH_GET_PRIVATE (watch);
 	watch->priv->error_details = NULL;
 	watch->priv->notification_cached_messages = NULL;
+	watch->priv->transaction_id = NULL;
 	watch->priv->restart = PK_RESTART_ENUM_NONE;
 	watch->priv->hide_warning = FALSE;
 	watch->priv->console = egg_console_kit_new ();
-
+	watch->priv->cancellable = g_cancellable_new ();
+	watch->priv->array_progress = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
 	watch->priv->gconf_client = gconf_client_get_default ();
 
 	watch->priv->status_icon = gtk_status_icon_new ();
 	watch->priv->set_proxy_timeout = 0;
-	watch->priv->cached_messages = g_ptr_array_new ();
-	watch->priv->restart_package_names = g_ptr_array_new ();
-
-	watch->priv->client_primary = pk_client_new ();
-	g_signal_connect (watch->priv->client_primary, "finished",
-			  G_CALLBACK (gpk_watch_finished_cb), watch);
-	g_signal_connect (watch->priv->client_primary, "progress-changed",
-			  G_CALLBACK (gpk_watch_progress_changed_cb), watch);
-	g_signal_connect (watch->priv->client_primary, "status-changed",
-			  G_CALLBACK (gpk_watch_status_changed_cb), watch);
-	g_signal_connect (watch->priv->client_primary, "package",
-			  G_CALLBACK (gpk_watch_package_cb), watch);
-	g_signal_connect (watch->priv->client_primary, "allow-cancel",
-			  G_CALLBACK (gpk_watch_allow_cancel_cb), watch);
-
+	watch->priv->cached_messages = g_ptr_array_new_with_free_func ((GDestroyNotify) gpk_watch_cached_message_free);
+	watch->priv->restart_package_names = g_ptr_array_new_with_free_func (g_free);
+	watch->priv->task = PK_TASK(gpk_task_new ());
+	g_object_set (watch->priv->task,
+		      "background", TRUE,
+		      NULL);
 	watch->priv->dialog = gpk_modal_dialog_new ();
 	gpk_modal_dialog_set_window_icon (watch->priv->dialog, "pk-package-installed");
 	g_signal_connect (watch->priv->dialog, "cancel",
@@ -1688,8 +1724,13 @@ gpk_watch_init (GpkWatch *watch)
 
 	/* we need to get ::locked */
 	watch->priv->control = pk_control_new ();
-	g_signal_connect (watch->priv->control, "locked",
-			  G_CALLBACK (gpk_watch_locked_cb), watch);
+	g_signal_connect (watch->priv->control, "notify::locked",
+			  G_CALLBACK (gpk_watch_notify_locked_cb), watch);
+	g_signal_connect (watch->priv->control, "notify::connected",
+			  G_CALLBACK (gpk_watch_notify_connected_cb), watch);
+
+	/* get properties */
+	pk_control_get_properties_async (watch->priv->control, NULL, (GAsyncReadyCallback) gpk_check_update_get_properties_cb, watch);
 
 	/* do session inhibit */
 	watch->priv->inhibit = gpk_inhibit_new ();
@@ -1700,23 +1741,11 @@ gpk_watch_init (GpkWatch *watch)
 	g_signal_connect_object (G_OBJECT (watch->priv->status_icon),
 				 "activate", G_CALLBACK (gpk_watch_activate_status_cb), watch, 0);
 
-	watch->priv->tlist = pk_task_list_new ();
-	g_signal_connect (watch->priv->tlist, "changed",
-			  G_CALLBACK (gpk_watch_task_list_changed_cb), watch);
-	g_signal_connect (watch->priv->tlist, "status-changed",
-			  G_CALLBACK (gpk_watch_task_list_changed_cb), watch);
-	g_signal_connect (watch->priv->tlist, "finished",
-			  G_CALLBACK (gpk_watch_task_list_finished_cb), watch);
-	g_signal_connect (watch->priv->tlist, "error-code",
-			  G_CALLBACK (gpk_watch_error_code_cb), watch);
-	g_signal_connect (watch->priv->tlist, "message",
-			  G_CALLBACK (gpk_watch_message_cb), watch);
-
-	watch->priv->pconnection = pk_connection_new ();
-	g_signal_connect (watch->priv->pconnection, "connection-changed",
-			  G_CALLBACK (gpk_watch_connection_changed_cb), watch);
-	if (pk_connection_valid (watch->priv->pconnection))
-		gpk_watch_connection_changed_cb (watch->priv->pconnection, TRUE, watch);
+	watch->priv->tlist = pk_transaction_list_new ();
+	g_signal_connect (watch->priv->tlist, "added",
+			  G_CALLBACK (gpk_watch_transaction_list_added_cb), watch);
+	g_signal_connect (watch->priv->tlist, "removed",
+			  G_CALLBACK (gpk_watch_transaction_list_removed_cb), watch);
 
 	/* watch proxy keys */
 	gconf_client_add_dir (watch->priv->gconf_client, GPK_WATCH_GCONF_PROXY_HTTP,
@@ -1751,24 +1780,20 @@ gpk_watch_finalize (GObject *object)
 	if (watch->priv->set_proxy_timeout != 0)
 		g_source_remove (watch->priv->set_proxy_timeout);
 
-	/* free cached messages */
-	g_ptr_array_foreach (watch->priv->cached_messages, (GFunc) gpk_watch_cached_message_free, NULL);
-	g_ptr_array_free (watch->priv->cached_messages, TRUE);
-
-	/* free cached restart names */
-	g_ptr_array_foreach (watch->priv->restart_package_names, (GFunc) g_free, NULL);
-	g_ptr_array_free (watch->priv->restart_package_names, TRUE);
-
 	g_free (watch->priv->error_details);
-	g_object_unref (watch->priv->status_icon);
-	g_object_unref (watch->priv->inhibit);
-	g_object_unref (watch->priv->tlist);
+	g_free (watch->priv->transaction_id);
+	g_object_unref (watch->priv->cancellable);
+	g_object_unref (PK_CLIENT(watch->priv->task));
+	g_object_unref (watch->priv->console);
 	g_object_unref (watch->priv->control);
-	g_object_unref (watch->priv->pconnection);
-	g_object_unref (watch->priv->gconf_client);
-	g_object_unref (watch->priv->client_primary);
 	g_object_unref (watch->priv->dialog);
-	g_object_unref (watch->priv->console);
+	g_object_unref (watch->priv->gconf_client);
+	g_object_unref (watch->priv->inhibit);
+	g_object_unref (watch->priv->status_icon);
+	g_object_unref (watch->priv->tlist);
+	g_ptr_array_unref (watch->priv->array_progress);
+	g_ptr_array_unref (watch->priv->cached_messages);
+	g_ptr_array_unref (watch->priv->restart_package_names);
 
 	G_OBJECT_CLASS (gpk_watch_parent_class)->finalize (object);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]