[PackageKit-commit] packagekit: Branch 'master' - 154 commits

Richard Hughes hughsient at kemper.freedesktop.org
Tue Jun 3 00:55:37 PDT 2008


 RELEASE                                              |   50 +
 backends/Makefile.am                                 |    8 
 backends/alpm/pk-backend-alpm.c                      |    4 
 backends/apt.deprecated/.gitignore                   |   10 
 backends/apt.deprecated/Makefile.am                  |   30 
 backends/apt.deprecated/helpers/.gitignore           |    1 
 backends/apt.deprecated/helpers/Makefile.am          |   29 
 backends/apt.deprecated/helpers/aptBackend.py        |  536 ++++++++++++++
 backends/apt.deprecated/helpers/get-depends.py       |   20 
 backends/apt.deprecated/helpers/get-details.py       |   18 
 backends/apt.deprecated/helpers/get-repo-list.py     |   20 
 backends/apt.deprecated/helpers/get-requires.py      |   20 
 backends/apt.deprecated/helpers/get-update-detail.py |   18 
 backends/apt.deprecated/helpers/get-updates.py       |   19 
 backends/apt.deprecated/helpers/install-files.py     |   21 
 backends/apt.deprecated/helpers/packagekit           |    1 
 backends/apt.deprecated/helpers/refresh-cache.py     |   17 
 backends/apt.deprecated/helpers/repo-enable.py       |   20 
 backends/apt.deprecated/helpers/resolve.py           |   20 
 backends/apt.deprecated/helpers/search-details.py    |   21 
 backends/apt.deprecated/helpers/search-file.py       |   21 
 backends/apt.deprecated/helpers/search-group.py      |   21 
 backends/apt.deprecated/helpers/search-name.py       |   21 
 backends/apt.deprecated/pk-apt-build-db.cpp          |  284 +++++++
 backends/apt.deprecated/pk-apt-build-db.h            |   30 
 backends/apt.deprecated/pk-apt-search-plain.c        |  106 ++
 backends/apt.deprecated/pk-apt-search-sqlite.cpp     |  135 +++
 backends/apt.deprecated/pk-apt-search.h              |   36 +
 backends/apt.deprecated/pk-backend-apt.c             |  268 +++++++
 backends/apt.deprecated/pk-sqlite-pkg-cache.cpp      |  215 ++++++
 backends/apt.deprecated/pk-sqlite-pkg-cache.h        |   42 +
 backends/apt/HACKING                                 |    5 
 backends/apt/Makefile.am                             |   41 -
 backends/apt/README                                  |   23 
 backends/apt/TODO                                    |   70 +
 backends/apt/aptDBUSBackend.py                       |  679 +++++++++++++++++++
 backends/apt/helpers/.gitignore                      |    1 
 backends/apt/helpers/Makefile.am                     |   29 
 backends/apt/helpers/aptBackend.py                   |  536 --------------
 backends/apt/helpers/get-depends.py                  |   20 
 backends/apt/helpers/get-details.py                  |   18 
 backends/apt/helpers/get-repo-list.py                |   20 
 backends/apt/helpers/get-requires.py                 |   20 
 backends/apt/helpers/get-update-detail.py            |   18 
 backends/apt/helpers/get-updates.py                  |   19 
 backends/apt/helpers/install-files.py                |   21 
 backends/apt/helpers/packagekit                      |    1 
 backends/apt/helpers/refresh-cache.py                |   17 
 backends/apt/helpers/repo-enable.py                  |   20 
 backends/apt/helpers/resolve.py                      |   20 
 backends/apt/helpers/search-details.py               |   21 
 backends/apt/helpers/search-file.py                  |   21 
 backends/apt/helpers/search-group.py                 |   21 
 backends/apt/helpers/search-name.py                  |   21 
 backends/apt/packagekit                              |    1 
 backends/apt/pk-apt-build-db.cpp                     |  284 -------
 backends/apt/pk-apt-build-db.h                       |   30 
 backends/apt/pk-apt-search-plain.c                   |  106 --
 backends/apt/pk-apt-search-sqlite.cpp                |  135 ---
 backends/apt/pk-apt-search.h                         |   36 -
 backends/apt/pk-backend-apt.c                        |  187 +----
 backends/apt/pk-sqlite-pkg-cache.cpp                 |  215 ------
 backends/apt/pk-sqlite-pkg-cache.h                   |   42 -
 backends/apt/profiler.py                             |   40 +
 backends/apt/test.py                                 |   98 ++
 backends/apt2/.gitignore                             |   10 
 backends/apt2/HACKING                                |    5 
 backends/apt2/Makefile.am                            |   25 
 backends/apt2/README                                 |   23 
 backends/apt2/TODO                                   |   70 -
 backends/apt2/aptDBUSBackend.py                      |  628 -----------------
 backends/apt2/packagekit                             |    1 
 backends/apt2/pk-backend-apt2.c                      |  204 -----
 backends/apt2/profiler.py                            |   40 -
 backends/apt2/test.py                                |   98 --
 backends/box/pk-backend-box.c                        |    2 
 backends/dummy/pk-backend-dummy.c                    |   26 
 backends/opkg/pk-backend-opkg.c                      |  171 +++-
 backends/poldek/pk-backend-poldek.c                  |  378 +++++++++-
 backends/test/pk-backend-test-dbus.c                 |    2 
 backends/test/pk-backend-test-spawn.c                |    2 
 backends/test/pk-backend-test-succeed.c              |    2 
 backends/urpmi/.gitignore                            |   14 
 backends/urpmi/Makefile.am                           |   11 
 backends/urpmi/helpers/.gitignore                    |    2 
 backends/urpmi/helpers/Makefile.am                   |   31 
 backends/urpmi/helpers/get-depends.pl                |   85 ++
 backends/urpmi/helpers/get-details.pl                |   48 +
 backends/urpmi/helpers/get-files.pl                  |   40 +
 backends/urpmi/helpers/get-packages.pl               |   53 +
 backends/urpmi/helpers/get-requires.pl               |   54 +
 backends/urpmi/helpers/get-update-detail.pl          |   88 ++
 backends/urpmi/helpers/get-updates.pl                |   46 +
 backends/urpmi/helpers/install-packages.pl           |   40 +
 backends/urpmi/helpers/perl_packagekit/Makefile.am   |   12 
 backends/urpmi/helpers/perl_packagekit/enums.pm      |  293 ++++++++
 backends/urpmi/helpers/perl_packagekit/prints.pm     |   95 ++
 backends/urpmi/helpers/refresh-cache.pl              |   33 
 backends/urpmi/helpers/remove-packages.pl            |   90 ++
 backends/urpmi/helpers/resolve.pl                    |   64 +
 backends/urpmi/helpers/search-details.pl             |   57 +
 backends/urpmi/helpers/search-file.pl                |   48 +
 backends/urpmi/helpers/search-group.pl               |   58 +
 backends/urpmi/helpers/search-name.pl                |   64 +
 backends/urpmi/helpers/update-packages.pl            |   50 +
 backends/urpmi/helpers/urpmi_backend/Makefile.am     |   15 
 backends/urpmi/helpers/urpmi_backend/actions.pm      |  297 ++++++++
 backends/urpmi/helpers/urpmi_backend/filters.pm      |   78 ++
 backends/urpmi/helpers/urpmi_backend/groups.pm       |  129 +++
 backends/urpmi/helpers/urpmi_backend/open_db.pm      |   48 +
 backends/urpmi/helpers/urpmi_backend/tools.pm        |  151 ++++
 backends/urpmi/pk-backend-urpmi.c                    |  355 +++++++++
 backends/yum/helpers/yumBackend.py                   |   47 -
 backends/yum2/helpers/testyum2.py                    |    2 
 backends/yum2/helpers/yumDBUSBackend.py              |  245 ++++--
 backends/zypp/pk-backend-zypp.cpp                    |   93 ++
 backends/zypp/zypp-utils.cpp                         |  132 +++
 backends/zypp/zypp-utils.h                           |   20 
 client/pk-console.c                                  |  257 +++++--
 client/pk-import-desktop.c                           |   23 
 client/pk-import-specspo.c                           |    8 
 configure.ac                                         |  151 ----
 contrib/PackageKit.spec.in                           |   11 
 contrib/gnome-packagekit.spec.in                     |    1 
 contrib/yum-packagekit/refresh-packagekit.py         |    2 
 data/tests/Makefile.am                               |    1 
 data/tests/pk-spawn-proxy.sh                         |   20 
 docs/html/index.html                                 |   20 
 docs/html/pk-authors.html                            |   46 -
 docs/html/pk-bugs.html                               |    4 
 docs/html/pk-download.html                           |    6 
 docs/html/pk-faq.html                                |  140 ++-
 docs/html/pk-help.html                               |   14 
 docs/html/pk-intro.html                              |    4 
 docs/html/pk-screenshots.html                        |   50 -
 docs/html/pk-using.html                              |    4 
 docs/spec/pk-concepts.xml                            |   14 
 docs/spec/pk-signals.xml                             |   14 
 etc/PackageKit.conf.in                               |   10 
 libpackagekit/Makefile.am                            |    3 
 libpackagekit/pk-client.c                            |  174 ++--
 libpackagekit/pk-client.h                            |    4 
 libpackagekit/pk-common.c                            |   90 ++
 libpackagekit/pk-common.h                            |    3 
 libpackagekit/pk-control.c                           |   37 +
 libpackagekit/pk-control.h                           |    3 
 libpackagekit/pk-enum.c                              |    5 
 libpackagekit/pk-enum.h                              |    7 
 libpackagekit/pk-extra.c                             |    2 
 libpackagekit/pk-package-item.c                      |  189 +++++
 libpackagekit/pk-package-item.h                      |   48 +
 libpackagekit/pk-package-list.c                      |   86 ++
 libpackagekit/pk-package-list.h                      |   20 
 libpackagekit/pk-polkit-client.c                     |    8 
 libpackagekit/pk-self-test.c                         |    2 
 libpackagekit/pk-task-list.c                         |    2 
 po/LINGUAS                                           |    1 
 po/de.po                                             |  146 ++--
 po/hu.po                                             |  311 ++++++++
 policy/org.freedesktop.packagekit.policy.in          |   12 
 python/packagekit/daemonBackend.py                   |   26 
 src/pk-backend-dbus.c                                |   52 +
 src/pk-backend-internal.h                            |    3 
 src/pk-backend-spawn.c                               |   48 +
 src/pk-backend.c                                     |  103 +-
 src/pk-backend.h                                     |   12 
 src/pk-engine.c                                      |   57 +
 src/pk-engine.h                                      |    7 
 src/pk-interface.xml                                 |    5 
 src/pk-network-unix.c                                |   10 
 src/pk-network.c                                     |   15 
 src/pk-security-polkit.c                             |    3 
 src/pk-security.h                                    |    3 
 src/pk-spawn.c                                       |   38 -
 src/pk-spawn.h                                       |    3 
 src/pk-transaction-db.c                              |    5 
 src/pk-transaction-list.c                            |   22 
 src/pk-transaction.c                                 |   21 
 tools/add-error-enum.sh                              |    2 
 tools/rpmbuild.sh                                    |   19 
 180 files changed, 8209 insertions(+), 3771 deletions(-)

New commits:
commit 1f1bce6b5a5efd2a9a836a208f1b041fab65029b
Merge: 168e74a... 09ec4e1...
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Jun 3 08:50:34 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit 09ec4e18e5df40b67ac79282d5c430a53e06ccb7
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Mon Jun 2 22:17:41 2008 +0200

    poldek: recognize and set correct PkInfoEnum for security updates

diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index 2691414..c205503 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -342,6 +342,9 @@ poldek_pkg_in_array_idx (const struct pkg *pkg, const tn_array *array, tn_fn_cmp
 static gboolean
 poldek_pkg_in_array (const struct pkg *pkg, const tn_array *array, tn_fn_cmp cmp_fn)
 {
+	if (array == NULL)
+		return FALSE;
+
 	if (poldek_pkg_in_array_idx (pkg, array, cmp_fn) == -1)
 		return FALSE;
 	else
@@ -527,6 +530,26 @@ poldek_pkg_set_installed (struct pkg *pkg, gboolean installed) {
 }
 
 /**
+ * poldek_get_security_updates:
+ **/
+static tn_array*
+poldek_get_security_updates (void)
+{
+	struct poclidek_rcmd *rcmd = NULL;
+	tn_array *pkgs = NULL;
+
+	rcmd = poclidek_rcmd_new (cctx, NULL);
+
+	poclidek_rcmd_execline (rcmd, "cd /all-avail; ls -S");
+
+	pkgs = poclidek_rcmd_get_packages (rcmd);
+
+	poclidek_rcmd_free (rcmd);
+
+	return pkgs;
+}
+
+/**
  * pld_group_to_enum:
  *
  * Converts PLD RPM group to PkGroupEnum.
@@ -667,6 +690,114 @@ poldek_get_installed_packages (void)
 	return arr;
 }
 
+static tn_array*
+poldek_pkg_get_cves_from_pld_changelog (struct pkg *pkg, time_t since)
+{
+	struct pkguinf	*inf = NULL;
+	const gchar	*ch;
+	gchar *chlog = NULL;
+	tn_array		*cves = NULL;
+
+	if ((inf = pkg_uinf (pkg)) == NULL)
+		return NULL;
+
+	if ((ch = pkguinf_get_changelog (inf, since))) {
+		chlog = g_strdup(ch);
+		if (g_strstr_len (chlog, 55 * sizeof (gchar), " poldek at pld-linux.org\n- see ")) { /* pkg is subpackage */
+			gchar *s, *e;
+
+			s = strchr (chlog, '\n');
+
+			s += 7; /* cut "\n- see " */
+
+			if ((e = strchr (s, '\''))) {
+				struct poclidek_rcmd *rcmd;
+				gchar *command;
+
+				*e = '\0'; /* now s is the name of package with changelog */
+
+				rcmd = poclidek_rcmd_new (cctx, NULL);
+
+				command = g_strdup_printf ("cd /all-avail; ls -q %s*", s);
+
+				/* release it */
+				g_free (chlog);
+				chlog = NULL;
+
+				if (poclidek_rcmd_execline (rcmd, command)) {
+					tn_array *pkgs;
+
+					pkgs = poclidek_rcmd_get_packages (rcmd);
+
+					if (pkgs) {
+						struct pkg *p = n_array_nth (pkgs, 0);
+						struct pkguinf *inf_parent = NULL;
+
+						if ((inf_parent = pkg_uinf (p))) {
+							if ((ch = pkguinf_get_changelog (inf_parent, since)))
+								chlog = g_strdup(ch);
+
+							pkguinf_free (inf_parent);
+						}
+					}
+					n_array_cfree (&pkgs);
+				}
+
+				poclidek_rcmd_free (rcmd);
+
+				g_free (command);
+			}
+		}
+	}
+
+	if (chlog && strlen (chlog) > 0) {
+		gchar *s=chlog;
+
+		cves = n_array_new (2, free, (tn_fn_cmp)strcmp);
+		while (1) {
+			gchar cve[14];
+			gboolean valid = TRUE;
+			gint i;
+
+			if ((s = strstr (s, "CVE-")) == NULL)
+				break;
+
+			if (strlen (s) < 13) /* CVE-XXXX-YYYY has 13 chars */
+				break;
+
+			for (i = 0; i < 14; i++) {
+				if (i == 13)
+					cve[i] = '\0';
+				else
+					cve[i] = *(s + i);
+			}
+
+			for (i = 4; i < 13; i++) {
+				if (i == 8) {
+					if (cve[i] != '-') {
+						valid = FALSE;
+						break;
+					}
+				} else if (g_ascii_isdigit (cve[i]) == FALSE) {
+					valid = FALSE;
+					break;
+				}
+			}
+
+			if (valid)
+				n_array_push (cves, g_strdup(cve));
+
+			s += 13;
+		}
+	}
+
+	pkguinf_free (inf);
+
+	g_free (chlog);
+
+	return cves;
+}
+
 static void
 do_newest (tn_array *pkgs)
 {
@@ -1731,7 +1862,7 @@ backend_get_update_detail_thread (PkBackend *backend)
 
 	if (poclidek_rcmd_execline (rcmd, command)) {
 		tn_array	*pkgs = NULL;
-		struct pkg	*pkg = NULL;
+		struct pkg	*pkg = NULL, *upkg = NULL;
 
 		pkgs = poclidek_rcmd_get_packages (rcmd);
 
@@ -1739,7 +1870,8 @@ backend_get_update_detail_thread (PkBackend *backend)
 		pkg = n_array_nth (pkgs, 0);
 
 		if (strcmp (pkg->name, pi->name) == 0) {
-			gchar	*evr, *update_id;
+			gchar	*evr, *update_id, *cve_url = NULL;
+			tn_array *cves = NULL;
 
 			evr = poldek_pkg_evr (pkg);
 			update_id = pk_package_id_build (pkg->name,
@@ -1747,18 +1879,43 @@ backend_get_update_detail_thread (PkBackend *backend)
 							 pkg_arch (pkg),
 							 "installed");
 
+			upkg = poldek_get_pkg_from_package_id (package_id);
+
+			if ((cves = poldek_pkg_get_cves_from_pld_changelog (upkg, pkg->btime))) {
+				GString	*string;
+				gint i;
+
+				string = g_string_new ("");
+
+				for (i = 0; i < n_array_size (cves); i++) {
+					gchar *cve = n_array_nth (cves, i);
+
+					g_string_append_printf (string,
+								"http://nvd.nist.gov/nvd.cfm?cvename=%s;%s",
+								cve, cve);
+
+					if ((i + 1) < n_array_size (cves))
+						g_string_append_printf (string, ";");
+				}
+
+				cve_url = g_string_free (string, FALSE);
+			}
+
 			pk_backend_update_detail (backend,
 						  package_id,
 						  update_id,
 						  "",
 						  "",
 						  "",
-						  "",
+						  cve_url ? cve_url : "",
 						  PK_RESTART_ENUM_NONE,
 						  "");
 
 			g_free (evr);
 			g_free (update_id);
+			g_free (cve_url);
+
+			n_array_cfree (&cves);
 		}
 
 		n_array_free (pkgs);
@@ -1807,6 +1964,7 @@ backend_get_updates_thread (PkBackend *backend)
 	if (rcmd) {
 		if (poclidek_rcmd_execline (rcmd, "cd /all-avail; ls -q -u")) {
 			tn_array	*pkgs = NULL;
+			tn_array	*secupgrades = NULL;
 			gint		i;
 
 			pkgs = poclidek_rcmd_get_packages (rcmd);
@@ -1814,6 +1972,8 @@ backend_get_updates_thread (PkBackend *backend)
 			/* GetUpdates returns only the newest packages */
 			do_newest (pkgs);
 
+			secupgrades = poldek_get_security_updates ();
+
 			for (i = 0; i < n_array_size (pkgs); i++) {
 				struct pkg	*pkg = n_array_nth (pkgs, i);
 
@@ -1823,9 +1983,12 @@ backend_get_updates_thread (PkBackend *backend)
 				/* mark held packages as blocked */
 				if (pkg->flags & PKG_HELD)
 					poldek_backend_package (backend, pkg, PK_INFO_ENUM_BLOCKED);
+				else if (poldek_pkg_in_array (pkg, secupgrades, (tn_fn_cmp)pkg_cmp_name_evr))
+					poldek_backend_package (backend, pkg, PK_INFO_ENUM_SECURITY);
 				else
 					poldek_backend_package (backend, pkg, PK_INFO_ENUM_NORMAL);
 			}
+			n_array_cfree (&secupgrades);
 			n_array_free (pkgs);
 		}
 	}
commit 168e74a5aa6673d4091ce50f59b0eb7dd0a243c8
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 17:59:40 2008 +0100

    trivial: add some more unit tests for PkClient, testing double resets

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 8fb82f1..3cb4343 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -3851,6 +3851,42 @@ libst_client (LibSelfTest *test)
 	pk_client_set_use_buffer (client, TRUE, NULL);
 
 	/************************************************************/
+	libst_title (test, "reset client #1");
+	ret = pk_client_reset (client, &error);
+	if (!ret) {
+		libst_failed (test, "failed to reset: %s", error->message);
+		g_error_free (error);
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "reset client #2");
+	ret = pk_client_reset (client, &error);
+	if (!ret) {
+		libst_failed (test, "failed to reset: %s", error->message);
+		g_error_free (error);
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "get updates");
+	ret = pk_client_get_updates (client, PK_FILTER_ENUM_NONE, &error);
+	if (!ret) {
+		libst_failed (test, "failed to reset: %s", error->message);
+		g_error_free (error);
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "reset client #2");
+	ret = pk_client_reset (client, &error);
+	if (!ret) {
+		libst_failed (test, "failed to reset: %s", error->message);
+		g_error_free (error);
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
 	libst_title (test, "search for power");
 	ret = pk_client_search_name (client, PK_FILTER_ENUM_NONE, "power", &error);
 	if (!ret) {
commit 9ced8313fb12f0f89ad6ced7c0fdc7241ff00d77
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 17:03:55 2008 +0100

    trivial: add some debugging so we know where a id is being set

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 67f41dc..8fb82f1 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -3063,6 +3063,7 @@ pk_client_set_tid (PkClient *client, const gchar *tid, GError **error)
 		return FALSE;
 	}
 	client->priv->tid = g_strdup (tid);
+	pk_debug ("set tid %s on %p", client->priv->tid, client);
 
 	dbus_g_proxy_add_signal (proxy, "Finished",
 				 G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
@@ -3501,9 +3502,8 @@ pk_client_reset (PkClient *client, GError **error)
 
 	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
 
-	if (client->priv->tid != NULL &&
-	    client->priv->is_finished != TRUE) {
-		pk_debug ("not exit status, will try to cancel");
+	if (client->priv->tid != NULL && !client->priv->is_finished) {
+		pk_debug ("not exit status, will try to cancel tid %s", client->priv->tid);
 		/* we try to cancel the running tranaction */
 		ret = pk_client_cancel (client, error);
 		if (!ret) {
commit a01a3a8ab14d208f287d4c84f463ce3e7ff2ac8d
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 16:57:31 2008 +0100

    bugfix: if we've finished the transaction, don't allow it to be cancelled --
    
    this is papering over a bug in GpkClient that we haven't yet found. It's a sane fix, but needs another pass

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 83c1c61..15faed3 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1161,6 +1161,12 @@ pk_transaction_cancel (PkTransaction *transaction, GError **error)
 		return TRUE;
 	}
 
+	/* if it's finished, cancelling will have no action */
+	if (transaction->priv->finished) {
+		pk_warning ("No point trying to cancel a finished transaction, ignoring");
+		return TRUE;
+	}
+
 	/* not implemented yet */
 	if (transaction->priv->backend->desc->cancel == NULL) {
 		pk_debug ("Not implemented yet: Cancel");
commit 484497661d39e3046e2d1137005d2f2692669244
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 16:56:12 2008 +0100

    trivial: add an additional unit test to try to pinpoint a pk_client_reset() bug.

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 61c26bd..67f41dc 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -3812,6 +3812,15 @@ libst_client (LibSelfTest *test)
 		libst_failed (test, NULL);
 	}
 
+	/************************************************************/
+	libst_title (test, "reset client, unused");
+	ret = pk_client_reset (client, NULL);
+	if (ret) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
 	/* check use after finalise */
 	g_signal_connect (client, "finished",
 			  G_CALLBACK (libst_client_finished_cb), test);
commit 386aa4f86c80dc0427a3f7d939504a78972cd1d5
Merge: 34d6b69... 2b2e3d7...
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Fri May 30 17:25:34 2008 +0200

    Merge branch 'master' of git+ssh://alk@git.packagekit.org/srv/git/PackageKit

commit 2b2e3d779fe0e9495cca8d608c94f62431cd0a51
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 15:22:25 2008 +0100

    bugfix: if the transaction has been queued but not run, and then it's canceled, just remove the transaction from the transaction list
    
    This fixes the problem where rapid scrolling in gpk-update-viewer causes a long list of transactions to be queued but not removed

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 6924fdc..61c26bd 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -914,10 +914,8 @@ pk_client_cancel (PkClient *client, GError **error)
 		return TRUE;
 	}
 
-	/* special case - if the tid is already finished, then cancel should
-	 * return TRUE as it's what we wanted */
-	if (pk_strequal (error_local->message, "cancelling a non-running transaction") ||
-	    g_str_has_suffix (error_local->message, " doesn't exist\n")) {
+	/* special case - if the tid is already finished, then cancel should return TRUE */
+	if (g_str_has_suffix (error_local->message, " doesn't exist\n")) {
 		pk_debug ("error ignored '%s' as we are trying to cancel", error_local->message);
 		g_error_free (error_local);
 		return TRUE;
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 1d9271a..83c1c61 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -71,6 +71,7 @@ struct PkTransactionPrivate
 	PkStatusEnum		 status;
 	gboolean		 finished;
 	gboolean		 running;
+	gboolean		 has_been_run;
 	gboolean		 allow_cancel;
 	gboolean		 emit_eula_required;
 	gboolean		 emit_signature_required;
@@ -798,6 +799,7 @@ pk_transaction_set_running (PkTransaction *transaction)
 
 	/* mark running */
 	transaction->priv->running = TRUE;
+	transaction->priv->has_been_run = TRUE;
 
 	/* set all possible arguments for backend */
 	pk_backend_set_bool (priv->backend, "force", priv->cached_force);
@@ -1152,11 +1154,11 @@ pk_transaction_cancel (PkTransaction *transaction, GError **error)
 	g_return_val_if_fail (transaction->priv->tid != NULL, FALSE);
 
 	pk_debug ("Cancel method called");
-	/* check to see if we are trying to cancel a non-running task */
-	if (!transaction->priv->running) {
-		g_set_error (error, PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NOT_RUNNING,
-			     "cancelling a non-running transaction");
-		return FALSE;
+
+	/* if it's never been run, just remove this transaction from the list */
+	if (!transaction->priv->has_been_run) {
+		pk_transaction_list_remove (transaction->priv->transaction_list, transaction);
+		return TRUE;
 	}
 
 	/* not implemented yet */
@@ -3011,6 +3013,7 @@ pk_transaction_init (PkTransaction *transaction)
 	transaction->priv = PK_TRANSACTION_GET_PRIVATE (transaction);
 	transaction->priv->finished = FALSE;
 	transaction->priv->running = FALSE;
+	transaction->priv->has_been_run = FALSE;
 	transaction->priv->allow_cancel = FALSE;
 	transaction->priv->emit_eula_required = FALSE;
 	transaction->priv->emit_signature_required = FALSE;
commit 34d6b6903817e4fee81c24c569cbfeba8aab2c89
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Fri May 30 15:52:38 2008 +0200

    bugfix: Another fix in get-details when xml_info_file doest not exists

diff --git a/backends/urpmi/helpers/get-details.pl b/backends/urpmi/helpers/get-details.pl
index 7ce0431..3207e9b 100755
--- a/backends/urpmi/helpers/get-details.pl
+++ b/backends/urpmi/helpers/get-details.pl
@@ -28,6 +28,12 @@ my $pkg = get_package_by_package_id($urpm, $ARGV[0]);
 my $medium = pkg2medium($pkg, $urpm);
 my $xml_info = 'info';
 my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, $xml_info, undef, undef);
+
+if(!$xml_info_file) {
+  pk_print_details(get_package_id($pkg), "N/A", $pkg->group, "N/A", "N/A", 0);
+  exit 0;
+}
+
 require urpm::xml_info;
 require urpm::xml_info_pkg;
 my $name = urpm_name($pkg);
@@ -38,5 +44,5 @@ my $description = $xml_info_pkgs{$name}{description};
 $description =~ s/\n/;/g;
 $description =~ s/\t/ /g;
 
-pk_print_details(get_package_id($pkg), "N/A", $pkg->group, $description, "N/A", $pkg->size);
+pk_print_details(get_package_id($pkg), "N/A", $pkg->group, ensure_utf8($description), "N/A", $pkg->size);
 
commit 36151f55f4a8c0847b326c841d4e47d4884a6fe8
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Fri May 30 15:37:06 2008 +0200

    Bugfix: Fix a bug when package description contains a tab

diff --git a/backends/urpmi/helpers/get-details.pl b/backends/urpmi/helpers/get-details.pl
index f39bd84..7ce0431 100755
--- a/backends/urpmi/helpers/get-details.pl
+++ b/backends/urpmi/helpers/get-details.pl
@@ -36,6 +36,7 @@ my %xml_info_pkgs;
 put_in_hash($xml_info_pkgs{$name} ||= {}, $nodes{$name});
 my $description = $xml_info_pkgs{$name}{description};
 $description =~ s/\n/;/g;
+$description =~ s/\t/ /g;
 
 pk_print_details(get_package_id($pkg), "N/A", $pkg->group, $description, "N/A", $pkg->size);
 
commit a1136859ea0e733ab3999d42f6fd60dc769f96dc
Author: Thomas Wood <thomas at openedhand.com>
Date:   Fri May 30 12:52:22 2008 +0100

    opkg: update to use new package corrupt error enum

diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 5949ff9..2d70108 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -138,7 +138,7 @@ handle_install_error (PkBackend *backend, int err)
 		pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL);
 		break;
 	case OPKG_MD5_ERROR:
-		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_CORRUPT, NULL);
 		break;
 	case OPKG_PACKAGE_NOT_AVAILABLE:
 		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
commit deeafa93a9088cd99fa0fea39feb2a5bde82bb02
Author: Thomas Wood <thomas at openedhand.com>
Date:   Fri May 30 12:31:45 2008 +0100

    Add a new error enum for corrupt packages

diff --git a/docs/spec/pk-concepts.xml b/docs/spec/pk-concepts.xml
index 0b75b10..51a165a 100644
--- a/docs/spec/pk-concepts.xml
+++ b/docs/spec/pk-concepts.xml
@@ -402,6 +402,13 @@
 	      signature is not valid in some way.
             </entry>
           </row>
+          <row>
+            <entry><literal>package-corrupt</literal></entry>
+            <entry>
+	      The downloaded package is corrupt.
+            </entry>
+          </row>
+
         </tbody>
       </tgroup>
     </informaltable>
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index c86b791..9dccdd0 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -152,6 +152,7 @@ static PkEnumMatch enum_error[] = {
 	{PK_ERROR_ENUM_REPO_NOT_AVAILABLE,	"repo-not-available"},
 	{PK_ERROR_ENUM_INVALID_PACKAGE_FILE,    "invalid-package-file"},
 	{PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED, "package-install-blocked"},
+	{PK_ERROR_ENUM_PACKAGE_CORRUPT,         "package-corrupt"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 0459bc7..4cc317e 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -256,6 +256,7 @@ typedef enum {
 	PK_ERROR_ENUM_REPO_NOT_AVAILABLE,
 	PK_ERROR_ENUM_INVALID_PACKAGE_FILE,
 	PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED,
+	PK_ERROR_ENUM_PACKAGE_CORRUPT,
 	PK_ERROR_ENUM_UNKNOWN
 } PkErrorCodeEnum;
 
commit ee89633768b89fcf30714c11a9610bfe3f4e3fff
Author: Thomas Wood <thomas at openedhand.com>
Date:   Fri May 30 11:04:10 2008 +0100

    opkg: update error checking for install and update methods

diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 7649bab..5949ff9 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -115,6 +115,39 @@ opkg_check_tag (opkg_package_t *pkg, gchar *tag)
 		return FALSE;
 }
 
+static void
+handle_install_error (PkBackend *backend, int err)
+{
+	switch (err)
+	{
+	case OPKG_NO_ERROR:
+		break;
+	case OPKG_PACKAGE_NOT_INSTALLED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
+		break;
+	case OPKG_PACKAGE_ALREADY_INSTALLED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL);
+		break;
+	case OPKG_GPG_ERROR:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, NULL);
+		break;
+	case OPKG_DOWNLOAD_FAILED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED, NULL);
+		break;
+	case OPKG_DEPENDENCIES_FAILED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL);
+		break;
+	case OPKG_MD5_ERROR:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
+		break;
+	case OPKG_PACKAGE_NOT_AVAILABLE:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
+		break;
+	default:
+		opkg_unknown_error (backend, err, "Update package");
+	}
+}
+
 /**
  * backend_initialize:
  */
@@ -387,22 +420,9 @@ backend_install_packages_thread (PkBackend *backend)
 		pi = pk_package_id_new_from_string (package_ids[0]);
 
 		err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend);
-		switch (err)
-		{
-		case OPKG_NO_ERROR:
-			break;
-		case OPKG_DEPENDANCIES_FAILED:
-			pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL);
-			break;
-		case OPKG_PACKAGE_ALREADY_INSTALLED:
-			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL);
-			break;
-		case OPKG_PACKAGE_NOT_AVAILABLE:
-			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
-			break;
-		default:
-			opkg_unknown_error (backend, err, "Install");
-		}
+		if (err)
+			handle_install_error (backend, err);
+
 		pk_package_id_free (pi);
 		if (err != 0)
 			break;
@@ -551,16 +571,9 @@ backend_update_package_thread (PkBackend *backend)
 	}
 
 	err = opkg_upgrade_package (opkg, pi->name, pk_opkg_progress_cb, backend);
-	switch (err)
-	{
-	case OPKG_NO_ERROR:
-		break;
-	case OPKG_PACKAGE_NOT_INSTALLED:
-		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
-		break;
-	default:
-		opkg_unknown_error (backend, err, "Update package");
-	}
+	if (err)
+		handle_install_error (backend, err);
+
 
 	pk_package_id_free (pi);
 	pk_backend_finished (backend);
diff --git a/configure.ac b/configure.ac
index 033ce17..7510b03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -411,7 +411,7 @@ if test x$enable_box = xyes; then
 fi
 
 if test x$enable_opkg = xyes; then
-	PKG_CHECK_MODULES(OPKG, libopkg = 0.1.4)
+	PKG_CHECK_MODULES(OPKG, libopkg = 0.1.5)
 	AC_SUBST(OPKG_CFLAGS)
 	AC_SUBST(OPKG_LIBS)
 fi
commit 9f363d3c6c78c6123282b48733978f5425e038b3
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 12:18:03 2008 +0100

    trivial: the error enum descriptions are now in pk-concepts.xml, not the introduction

diff --git a/tools/add-error-enum.sh b/tools/add-error-enum.sh
index f78c891..6521e69 100755
--- a/tools/add-error-enum.sh
+++ b/tools/add-error-enum.sh
@@ -7,5 +7,5 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
-$EDITOR docs/spec/pk-introduction.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/gpk-common.c
+$EDITOR docs/spec/pk-concepts.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/gpk-common.c
 
commit 6886b44c56ad8f6cf313777a680b5d6bbd20da9b
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 30 12:00:37 2008 +0100

    zypp: remove the localised text that crept into the backend

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index e05cee0..a971707 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -906,7 +906,7 @@ backend_update_system_thread (PkBackend *backend)
 	std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> ();
 	
 	if (_updating_self) {
-		pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, _("Package Management System updated - restart needed"));
+		pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, "Package Management System updated - restart needed");
 		_updating_self = FALSE;
 	}
 	else {
@@ -1525,7 +1525,7 @@ backend_update_packages_thread (PkBackend *backend)
 
 	if (_updating_self) {
 		pk_debug ("updating self and setting restart");
-		pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, _("Package Management System updated - restart needed"));
+		pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, "Package Management System updated - restart needed");
 		_updating_self = FALSE;
 	}
 	for (guint i = 0; i < g_strv_length (package_ids); i++) {
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index 69e612e..d81d0dd 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -445,7 +445,7 @@ zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key)
 	                        key.fingerprint ().c_str (),
         	                key.created ().asString ().c_str (),
                 	        PK_SIGTYPE_ENUM_GPG);
-		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Signature verification for Repository %s failed", _repoName);
 	}else{
 		ok = TRUE;
 	}
@@ -474,7 +474,7 @@ zypp_signature_required (PkBackend *backend, const std::string &file, const std:
 	                        "UNKNOWN",
         	                "UNKNOWN",
                 	        PK_SIGTYPE_ENUM_GPG);
-		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Signature verification for Repository %s failed", _repoName);
 	}else{
 		ok = TRUE;
 	}
@@ -503,7 +503,7 @@ zypp_signature_required (PkBackend *backend, const std::string &file)
                 	        "UNKNOWN",
                         	"UNKNOWN",
 	                        PK_SIGTYPE_ENUM_GPG);
-		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Signature verification for Repository %s failed", _repoName);
 	}else{
 		ok = TRUE;
 	}
commit 13760bdfff2cdfb8d47e29937082cb5456bd5698
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Fri May 30 12:58:52 2008 +0200

    Added update-packages method in urpmi backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index b7b0e9d..88f144e 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -20,6 +20,7 @@ dist_helper_DATA = 						\
 	search-details.pl						\
 	search-file.pl							\
 	resolve.pl									\
+	update-packages.pl					\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/update-packages.pl b/backends/urpmi/helpers/update-packages.pl
new file mode 100755
index 0000000..88274bc
--- /dev/null
+++ b/backends/urpmi/helpers/update-packages.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::select;
+use urpm::args;
+use urpmi_backend::tools;
+use urpmi_backend::open_db;
+use urpmi_backend::actions;
+
+# This script call only be called with one argument (the package id)
+exit if($#ARGV != 0);
+
+my @names;
+foreach(split(/\|/, $ARGV[0])) {
+  my @pkgid = split(/;/, $_);
+  push @names, $pkgid[0];
+}
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $db = open_rpm_db();
+$urpm->compute_installed_flags($db);
+
+my %requested;
+
+my @depslist = @{$urpm->{depslist}};
+my $pkg = undef;
+foreach my $depslistpkg (@depslist) {
+  foreach my $name (@names) {
+    if($depslistpkg->name =~ /^$name$/ && $depslistpkg->flag_upgrade) {
+      $requested{$depslistpkg->id} = 1;
+      goto tonext;
+    }
+  }
+  tonext:
+}
+
+perform_installation($urpm, \%requested);
+
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index c6dbe85..e7b56a7 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -295,6 +295,28 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_
 	g_free (filters_text);
 }
 
+/**
+ * pk_backend_update_packages:
+ */
+static void
+backend_update_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+
+	/* check network state */
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	pk_backend_spawn_helper (spawn, "update-packages.pl", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -326,7 +348,7 @@ PK_BACKEND_OPTIONS (
 	backend_search_group,			/* search_group */
 	backend_search_name,			/* search_name */
 	NULL,					/* service_pack */
-	NULL,		/* update_packages */
+	backend_update_packages,		/* update_packages */
 	NULL,			/* update_system */
 	NULL			/* what_provides */
 );
commit 85f0e199549b7b3421bf517bf0580742d5a66adb
Merge: 5d3c798... 616a8cf...
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Fri May 30 12:21:18 2008 +0200

    Merge branch 'master' of git+ssh://alk@git.packagekit.org/srv/git/PackageKit

commit 5d3c798f7b194cabcfcfcde353816fd45e5901cf
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Fri May 30 12:14:52 2008 +0200

    improvements: get-update-detail & get-updates of urpmi backend

diff --git a/backends/urpmi/helpers/get-update-detail.pl b/backends/urpmi/helpers/get-update-detail.pl
index 421bb95..69ea452 100755
--- a/backends/urpmi/helpers/get-update-detail.pl
+++ b/backends/urpmi/helpers/get-update-detail.pl
@@ -32,15 +32,13 @@ if(!$pkg) {
   exit;
 }
 
-my $pkg_upgrade = get_package_upgrade($urpm, $pkg);
-
 my %requested;
-$requested{$pkg_upgrade->id} = 1;
+$requested{$pkg->id} = 1;
 
 if(!find_installed_version($pkg)) {
   pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "The selected package isn't installed on your system");
 }
-elsif(!$pkg_upgrade) {
+elsif(package_version_is_installed($pkg)) {
   pk_print_error(PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, "The selected package is already at the latest version");
 }
 else {
@@ -53,16 +51,22 @@ else {
   my ($src, $binary) = partition { $_->arch eq 'src' } @to_install;
   @to_install = @$binary;
   my $updates_descr = urpm::get_updates_description($urpm);
-  my $updesc = $updates_descr->{URPM::pkg2media($urpm->{media}, $pkg_upgrade)->{name}}{$pkg_upgrade->name};
+  my $updesc = $updates_descr->{URPM::pkg2media($urpm->{media}, $pkg)->{name}}{$pkg->name};
   my $desc;
   if($updesc) {
     $desc = $updesc->{pre};
     $desc =~ s/\n/;/g;
   }
 
+  my @to_upgrade_pkids;
+  foreach(@to_install) {
+    my $pkid = get_installed_version_pkid($_);
+    push @to_upgrade_pkids, $pkid if $pkid;
+  }
+
   if($restart) {
     pk_print_update_detail(get_package_id($pkg),
-      join("^", map(get_package_id($_), @to_install)),
+      join("^", @to_upgrade_pkids),
       join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
@@ -72,7 +76,7 @@ else {
   }
   else {
     pk_print_update_detail(get_package_id($pkg),
-      join("^", map(get_package_id($_), @to_install)),
+      join("^", @to_upgrade_pkids),
       join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
diff --git a/backends/urpmi/helpers/get-updates.pl b/backends/urpmi/helpers/get-updates.pl
index f3ca6a3..02d574c 100755
--- a/backends/urpmi/helpers/get-updates.pl
+++ b/backends/urpmi/helpers/get-updates.pl
@@ -38,15 +38,7 @@ my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selecte
 my ($src, $binary) = partition { $_->arch eq 'src' } @to_install;
 @to_install = @$binary;
   
-my @to_upgrade;
 foreach(@to_install) {
-  my $installed = get_installed_version($urpm, $_);
-  if($installed) {
-    push @to_upgrade, $installed;
-  }
-}
-
-foreach(@to_upgrade) {
   # Fix me
   # Be default, we set to bugfix info type
   # Need to be implemented, see urpmq source.
diff --git a/backends/urpmi/helpers/urpmi_backend/tools.pm b/backends/urpmi/helpers/urpmi_backend/tools.pm
index 28f0828..e078134 100644
--- a/backends/urpmi/helpers/urpmi_backend/tools.pm
+++ b/backends/urpmi/helpers/urpmi_backend/tools.pm
@@ -20,6 +20,7 @@ our @EXPORT = qw(
   package_version_is_installed
   get_package_upgrade
   get_installed_version
+  get_installed_version_pkid
 );
 
 sub get_update_medias {
@@ -134,3 +135,17 @@ sub get_installed_version {
   }
   return;
 }
+
+sub get_installed_version_pkid {
+  my ($pkg) = @_;
+  my $pkgname = $pkg->name;
+  my $db = open_rpm_db();
+  my $installed_pkid;
+  $db->traverse(sub {
+      my ($pkg) = @_;
+      if($pkg->name =~ /^$pkgname$/) {
+        $installed_pkid = get_package_id($pkg);
+      }
+    });
+  return $installed_pkid;
+}
commit 616a8cf6fbae193084d95c52587e05813224ab5e
Author: Stefan Haas <shaas at suse.de>
Date:   Fri May 30 11:34:00 2008 +0200

    Duncan Mac-Vicar P <dmacvicar at suse.de>: fix transaction db path to use current dir when using --enable-local

diff --git a/src/pk-transaction-db.c b/src/pk-transaction-db.c
index 7aa183f..d42bc7a 100644
--- a/src/pk-transaction-db.c
+++ b/src/pk-transaction-db.c
@@ -46,7 +46,12 @@ static void     pk_transaction_db_init		(PkTransactionDb      *tdb);
 static void     pk_transaction_db_finalize	(GObject        *object);
 
 #define PK_TRANSACTION_DB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_TRANSACTION_DB, PkTransactionDbPrivate))
+
+#if PK_BUILD_LOCAL
+#define PK_TRANSACTION_DB_FILE		"./transactions.db"
+#else
 #define PK_TRANSACTION_DB_FILE		PK_DB_DIR "/transactions.db"
+#endif
 
 struct PkTransactionDbPrivate
 {
commit ec95c19f4235a842871afb95be82a39536f1f4a8
Author: Stefan Haas <shaas at suse.de>
Date:   Fri May 30 11:31:44 2008 +0200

    require libzypp 4.25.0

diff --git a/configure.ac b/configure.ac
index 8047013..033ce17 100644
--- a/configure.ac
+++ b/configure.ac
@@ -431,7 +431,7 @@ if test x$enable_poldek = xyes; then
 fi
 
 if test x$enable_zypp = xyes; then
-	PKG_CHECK_MODULES(ZYPP, libzypp >= 4.14.0)
+	PKG_CHECK_MODULES(ZYPP, libzypp >= 4.25.0)
 	AC_SUBST(ZYPP_CFLAGS)
 	AC_SUBST(ZYPP_LIBS)
 fi
commit 90884f93e580f333a1385972e83a4598f43384ef
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 19:21:07 2008 +0200

    bugfix: in get-update-detail & get-updates from urpmi backend

diff --git a/backends/urpmi/helpers/get-update-detail.pl b/backends/urpmi/helpers/get-update-detail.pl
index e870aa0..421bb95 100755
--- a/backends/urpmi/helpers/get-update-detail.pl
+++ b/backends/urpmi/helpers/get-update-detail.pl
@@ -32,22 +32,11 @@ if(!$pkg) {
   exit;
 }
 
-my %requested;
-$requested{$pkg->id} = 1;
-
-# my $result = urpm::select::search_packages($urpm, \%requested, [ $pkg_name ], 
-#   fuzzy => 0, 
-#   caseinsensitive => 0,
-#   all => 0);
-
-# if(!$result) {
-#   exit;
-# }
-
-my @requested_keys = keys %requested;
-my $pkg = @{$urpm->{depslist}}[pop @requested_keys];
 my $pkg_upgrade = get_package_upgrade($urpm, $pkg);
 
+my %requested;
+$requested{$pkg_upgrade->id} = 1;
+
 if(!find_installed_version($pkg)) {
   pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "The selected package isn't installed on your system");
 }
@@ -71,17 +60,9 @@ else {
     $desc =~ s/\n/;/g;
   }
 
-  my @to_upgrade;
-  foreach(@to_install) {
-    my $installed = get_installed_version($urpm, $_);
-    if($installed) {
-      push @to_upgrade, $installed;
-    }
-  }
-
   if($restart) {
     pk_print_update_detail(get_package_id($pkg),
-      join("^", map(get_package_id($_), @to_upgrade)),
+      join("^", map(get_package_id($_), @to_install)),
       join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
@@ -91,7 +72,7 @@ else {
   }
   else {
     pk_print_update_detail(get_package_id($pkg),
-      join("^", map(get_package_id($_), @to_upgrade)),
+      join("^", map(get_package_id($_), @to_install)),
       join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
diff --git a/backends/urpmi/helpers/get-updates.pl b/backends/urpmi/helpers/get-updates.pl
index 957126c..f3ca6a3 100755
--- a/backends/urpmi/helpers/get-updates.pl
+++ b/backends/urpmi/helpers/get-updates.pl
@@ -37,8 +37,16 @@ my @to_remove = urpm::select::removed_packages($urpm, $state);
 my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; 
 my ($src, $binary) = partition { $_->arch eq 'src' } @to_install;
 @to_install = @$binary;
-
+  
+my @to_upgrade;
 foreach(@to_install) {
+  my $installed = get_installed_version($urpm, $_);
+  if($installed) {
+    push @to_upgrade, $installed;
+  }
+}
+
+foreach(@to_upgrade) {
   # Fix me
   # Be default, we set to bugfix info type
   # Need to be implemented, see urpmq source.
commit b89b35182f73f3d19e282cf9182f549d22f9991b
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 18:59:05 2008 +0200

    Fix in get-update-detail of the urpmi backend

diff --git a/backends/urpmi/helpers/get-update-detail.pl b/backends/urpmi/helpers/get-update-detail.pl
index f2333c6..e870aa0 100755
--- a/backends/urpmi/helpers/get-update-detail.pl
+++ b/backends/urpmi/helpers/get-update-detail.pl
@@ -25,18 +25,24 @@ exit if($#ARGV != 0);
 my $urpm = urpm->new_parse_cmdline;
 urpm::media::configure($urpm);
 
-my ($pkg_name) = split(/;/, @ARGV[0]);
+my $pkg = get_package_by_package_id($urpm, @ARGV[0]);
+
+if(!$pkg) {
+  pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Requested package was not found");
+  exit;
+}
 
 my %requested;
+$requested{$pkg->id} = 1;
 
-my $result = urpm::select::search_packages($urpm, \%requested, [ $pkg_name ], 
-  fuzzy => 0, 
-  caseinsensitive => 0,
-  all => 0);
+# my $result = urpm::select::search_packages($urpm, \%requested, [ $pkg_name ], 
+#   fuzzy => 0, 
+#   caseinsensitive => 0,
+#   all => 0);
 
-if(!$result) {
-  exit;
-}
+# if(!$result) {
+#   exit;
+# }
 
 my @requested_keys = keys %requested;
 my $pkg = @{$urpm->{depslist}}[pop @requested_keys];
@@ -65,9 +71,17 @@ else {
     $desc =~ s/\n/;/g;
   }
 
+  my @to_upgrade;
+  foreach(@to_install) {
+    my $installed = get_installed_version($urpm, $_);
+    if($installed) {
+      push @to_upgrade, $installed;
+    }
+  }
+
   if($restart) {
     pk_print_update_detail(get_package_id($pkg),
-      join("^", map(get_package_id($_), @to_install)),
+      join("^", map(get_package_id($_), @to_upgrade)),
       join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
@@ -77,7 +91,7 @@ else {
   }
   else {
     pk_print_update_detail(get_package_id($pkg),
-      join("^", map(get_package_id($_), @to_install)),
+      join("^", map(get_package_id($_), @to_upgrade)),
       join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
diff --git a/backends/urpmi/helpers/urpmi_backend/tools.pm b/backends/urpmi/helpers/urpmi_backend/tools.pm
index f0d80ba..28f0828 100644
--- a/backends/urpmi/helpers/urpmi_backend/tools.pm
+++ b/backends/urpmi/helpers/urpmi_backend/tools.pm
@@ -19,6 +19,7 @@ our @EXPORT = qw(
   get_package_by_package_id
   package_version_is_installed
   get_package_upgrade
+  get_installed_version
 );
 
 sub get_update_medias {
@@ -101,6 +102,7 @@ sub get_package_by_package_id {
       return $_;
     }
   }
+  return;
 }
 
 sub package_version_is_installed {
@@ -120,3 +122,15 @@ sub get_package_upgrade {
     }
   }
 }
+
+sub get_installed_version {
+  my ($urpm, $pkg) = @_;
+  my @depslist = @{$urpm->{depslist}};
+  my $pkgname = $pkg->name;
+  foreach $_ (@depslist) {
+    if($_->name =~ /^$pkgname$/ && package_version_is_installed($_)) {
+      return $_;
+    }
+  }
+  return;
+}
commit aabd176732a72292bd45ee63ecadc7ab96a0115d
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 17:46:05 2008 +0200

    Added resolve method for urpmi backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index bea0a0e..b7b0e9d 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -19,6 +19,7 @@ dist_helper_DATA = 						\
 	get-requires.pl							\
 	search-details.pl						\
 	search-file.pl							\
+	resolve.pl									\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/resolve.pl b/backends/urpmi/helpers/resolve.pl
new file mode 100755
index 0000000..32e0866
--- /dev/null
+++ b/backends/urpmi/helpers/resolve.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpmi_backend::open_db;
+use urpmi_backend::tools;
+use urpmi_backend::filters;
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# Two arguments (filter and package name)
+exit if ($#ARGV != 1);
+my @filters = split(/;/, $ARGV[0]);
+my $search_term = $ARGV[1];
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my @names = ( $search_term );
+my %requested;
+my $result = urpm::select::search_packages($urpm, \%requested, \@names, 
+  fuzzy => 0, 
+  caseinsensitive => 0,
+  all => 0
+);
+
+if($result) {
+  my @requested_keys = keys %requested;
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+  my $pkg = @{$urpm->{depslist}}[$requested_keys[0]];
+
+  # We exit the script if found package does not match with
+  # specified filters
+  if(!filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+    exit;
+  }
+  if($pkg->version."-".$pkg->release eq find_installed_version($pkg)) {
+    if(grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+      exit;
+    }
+    pk_print_package(INFO_INSTALLED, get_package_id($pkg), $pkg->summary);
+  }
+  else {
+    if(grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+      exit;
+    }
+    pk_print_package(INFO_AVAILABLE, get_package_id($pkg), $pkg->summary);
+  }
+}
+else {
+  pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Can't find any package for the specified name");
+}
+
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 801be6d..c6dbe85 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -283,6 +283,18 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
 	g_free (filters_text);
 }
 
+/**
+ * pk_backend_resolve:
+ */
+static void
+backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "resolve.pl", filters_text, package_id, NULL);
+	g_free (filters_text);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -307,7 +319,7 @@ PK_BACKEND_OPTIONS (
 	backend_remove_packages,		/* remove_packages */
 	NULL,			/* repo_enable */
 	NULL,			/* repo_set_data */
-	NULL,			/* resolve */
+	backend_resolve,			/* resolve */
 	NULL,					/* rollback */
 	backend_search_details,			/* search_details */
 	backend_search_file,			/* search_file */
commit b86be4209f8e1f35731b9301b16ed240b1dcb2d9
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 16:49:19 2008 +0200

    pk-faq.html updated for urpmi backend

diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index 8415138..3e37cc1 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -90,7 +90,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -105,7 +105,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -135,7 +135,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -150,7 +150,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -165,7 +165,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -180,7 +180,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -195,7 +195,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -225,7 +225,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -255,7 +255,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -270,7 +270,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -285,7 +285,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -300,7 +300,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -315,7 +315,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -420,7 +420,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[good]"/></td><!-- zypp -->
@@ -454,7 +454,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -469,7 +469,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -484,7 +484,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
commit be3f50a70a06a56a78773e52a673d61dbecf70bf
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 29 15:39:06 2008 +0100

    add info about the urpmi backend

diff --git a/docs/html/pk-authors.html b/docs/html/pk-authors.html
index 607a7a4..7aa298b 100644
--- a/docs/html/pk-authors.html
+++ b/docs/html/pk-authors.html
@@ -262,6 +262,22 @@
  </td>
 </tr>
 
+<tr>
+ <td>
+  <img src="img/author-unknown.png" alt=""/><!-- image should be 120px wide -->
+ </td>
+ <td>
+  <h2>Aurelien Lefebvre</h2>
+  <p>
+   Aurelien works for <a href="http://www.mandriva.org">Mandriva</a>.
+   He works on the urpmi backend of PackageKit.
+  </p>
+  <p>
+   <b>Responsible for: urpmi backend</b>
+  </p>
+ </td>
+</tr>
+
 </table>
 
 <p>Back to the <a href="index.html">main page</a></p>
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index 371e67a..8415138 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -60,6 +60,7 @@
 <td><center>pisi</center></td>
 <td><center>poldek</center></td>
 <td><center>smart</center></td>
+<td><center>urpmi</center></td>
 <td><center>yum</center></td>
 <td><center>yum2</center></td>
 <td><center>zypp</center></td>
@@ -74,6 +75,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -88,6 +90,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -102,6 +105,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -116,6 +120,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -130,6 +135,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -144,6 +150,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -158,6 +165,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -172,6 +180,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -186,6 +195,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -200,6 +210,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -214,6 +225,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -228,6 +240,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -242,6 +255,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -256,6 +270,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -270,6 +285,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -284,6 +300,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -298,6 +315,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -312,6 +330,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -326,6 +345,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -340,6 +360,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -354,6 +375,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -368,6 +390,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -382,6 +405,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -396,6 +420,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[good]"/></td><!-- zypp -->
@@ -414,6 +439,7 @@
 <td><center>pisi</center></td>
 <td><center>poldek</center></td>
 <td><center>smart</center></td>
+<td><center>urpmi</center></td>
 <td><center>yum</center></td>
 <td><center>yum2</center></td>
 <td><center>zypp</center></td>
@@ -428,6 +454,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- zypp -->
@@ -442,6 +469,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -456,6 +484,7 @@
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -470,6 +499,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
@@ -483,6 +513,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
@@ -497,6 +528,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
@@ -511,6 +543,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
@@ -525,6 +558,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- urpmi -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
commit d928f775d89cdf64bfb42d89f9d28103e2800818
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 29 15:30:30 2008 +0100

    yum: improve the 'Missing Dependency:' detailed output a smidgin

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 7515fcd..d70d8dc 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1062,8 +1062,11 @@ class PackageKitYumBackend(PackageKitBaseBackend):
 
     def _format_msgs(self,msgs):
         if isinstance(msgs,basestring):
-            msgs = msgs.split('\n')
-        return ";".join(msgs)
+             msgs = msgs.split('\n')
+        text = ";".join(msgs)
+        text = text.replace("Missing Dependency: ","")
+        text = text.replace(" (installed)","")
+        return text
 
     def _runYumTransaction(self,removedeps=None):
         '''
commit 1df6fe0baa4ad97fb4cc35b350f063b78a59d52a
Merge: 5131838... ce95d2c...
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 16:31:22 2008 +0200

    Merge branch 'master' of git+ssh://alk@git.packagekit.org/srv/git/PackageKit

commit 5131838fcec02a5bcfcb41806a815bce5a092941
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 16:29:24 2008 +0200

    Added search-file method in urpmi backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 2d0e2bc..bea0a0e 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -18,6 +18,7 @@ dist_helper_DATA = 						\
 	get-packages.pl							\
 	get-requires.pl							\
 	search-details.pl						\
+	search-file.pl							\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/search-file.pl b/backends/urpmi/helpers/search-file.pl
new file mode 100755
index 0000000..03d348e
--- /dev/null
+++ b/backends/urpmi/helpers/search-file.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+
+use urpmi_backend::actions;
+use urpmi_backend::filters;
+use urpmi_backend::tools;
+use perl_packagekit::prints;
+use perl_packagekit::enums;
+
+# Two arguments (filter and search term)
+exit if ($#ARGV != 1);
+my @filters = split(/;/, $ARGV[0]);
+my $search_term = $ARGV[1];
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my %requested;
+
+pk_print_status(PK_STATUS_ENUM_QUERY);
+
+perform_file_search($urpm, \%requested, $search_term, fuzzy => 1);
+
+foreach(keys %requested) {
+  my $p = @{$urpm->{depslist}}[$_];
+  if(filter($p, \@filters, { FILTER_INSTALLED => 1, FILTER_DEVELOPMENT=> 1, FILTER_GUI => 1})) {
+    my $version = find_installed_version($p);
+    if($version eq $p->version."-".$p->release) {
+      pk_print_package(INFO_INSTALLED, get_package_id($p), ensure_utf8($p->summary));
+    }
+    else {
+      pk_print_package(INFO_AVAILABLE, get_package_id($p), ensure_utf8($p->summary));
+    }
+  }
+}
+
+pk_print_status(PK_STATUS_ENUM_FINISHED);
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 96c7149..801be6d 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -271,6 +271,18 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
 	g_free (filters_text);
 }
 
+/**
+ * pk_backend_search_file:
+ */
+static void
+backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "search-file.pl", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -298,7 +310,7 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* resolve */
 	NULL,					/* rollback */
 	backend_search_details,			/* search_details */
-	NULL,			/* search_file */
+	backend_search_file,			/* search_file */
 	backend_search_group,			/* search_group */
 	backend_search_name,			/* search_name */
 	NULL,					/* service_pack */
commit a9dfd5e17cadb131a939a1ada43636c0aa22aca6
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 16:09:46 2008 +0200

    Added search-details method for urpmi backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 251efb9..2d0e2bc 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -17,6 +17,7 @@ dist_helper_DATA = 						\
 	search-group.pl							\
 	get-packages.pl							\
 	get-requires.pl							\
+	search-details.pl						\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/search-details.pl b/backends/urpmi/helpers/search-details.pl
new file mode 100755
index 0000000..3081abe
--- /dev/null
+++ b/backends/urpmi/helpers/search-details.pl
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::args;
+
+use urpmi_backend::open_db;
+use urpmi_backend::tools;
+use urpmi_backend::filters;
+
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# Two arguments (filterand search term)
+exit if ($#ARGV != 1);
+my @filters = split(/;/, $ARGV[0]);
+my $search_term = $ARGV[1];
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $db = open_rpm_db();
+$urpm->compute_installed_flags($db);
+
+# Here we display installed packages
+if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+  $db->traverse(sub {
+      my ($pkg) = @_;
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        if($pkg->name =~ /$search_term/ || $pkg->summary =~ /$search_term/ || $pkg->url =~ /$search_term/) {
+          pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary));
+        }
+      }
+    });
+}
+
+# Here are package which can be installed
+if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+  foreach my $pkg(@{$urpm->{depslist}}) {
+    if($pkg->flag_upgrade) {
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        if($pkg->name =~ /$search_term/ || $pkg->summary =~ /$search_term/ || $pkg->url =~ /$search_term/) {
+          pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary));
+        }
+      }
+    }  
+  }
+}
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 7a5c6a6..96c7149 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -259,6 +259,18 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, const gchar *pac
 	g_free (filters_text);
 }
 
+/**
+ * pk_backend_search_details:
+ */
+static void
+backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "search-details.pl", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -285,7 +297,7 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* repo_set_data */
 	NULL,			/* resolve */
 	NULL,					/* rollback */
-	NULL,			/* search_details */
+	backend_search_details,			/* search_details */
 	NULL,			/* search_file */
 	backend_search_group,			/* search_group */
 	backend_search_name,			/* search_name */
commit ce95d2cc6fbc565eae548cdcdb67607a6f6a6c4c
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 29 14:48:07 2008 +0100

    bugfix: don't ignore ::Finished() if we warn the user

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 37ed024..f0f245f 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1484,8 +1484,7 @@ pk_backend_finished (PkBackend *backend)
 	     backend->priv->role == PK_ROLE_ENUM_REMOVE_PACKAGES ||
 	     backend->priv->role == PK_ROLE_ENUM_UPDATE_PACKAGES)) {
 		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
-				    "Backends need to send a Package() for this role!");
-		return FALSE;
+				    "Backends should send a Package() for this role!");
 	}
 
 	/* if we set an error code notifier, clear */
commit cf0658aaeb638590a534fa09b1ae6d2ab64f77a9
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 15:49:23 2008 +0200

    Added get-requires method for urpmi backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 724c65a..251efb9 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -16,6 +16,7 @@ dist_helper_DATA = 						\
 	remove-packages.pl					\
 	search-group.pl							\
 	get-packages.pl							\
+	get-requires.pl							\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/get-requires.pl b/backends/urpmi/helpers/get-requires.pl
new file mode 100755
index 0000000..0012b2a
--- /dev/null
+++ b/backends/urpmi/helpers/get-requires.pl
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpm::select;
+use urpmi_backend::tools;
+use urpmi_backend::actions;
+use urpmi_backend::filters;
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# 3 arguments
+# (filter, packageid, and recursive option)
+exit if($#ARGV != 2);
+
+my @filters = split(/;/, $ARGV[0]);
+my $pkgid = $ARGV[1];
+my $recursive_option = 0;
+$recursive_option = 1 if($ARGV[2] eq "yes");
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $pkg = get_package_by_package_id($urpm, $pkgid);
+if(!$pkg) {
+  pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Requested package wasn't found");
+  exit;
+}
+# print "Checking requires of the package : ", urpm_name($pkg), "\n";
+pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
+my @requires = perform_requires_search($urpm, $pkg, $recursive_option);
+
+foreach(@requires) {
+  if(filter($_, \@filters, { FILTER_GUI => 1, FILTER_DEVELOPMENT => 1 })) {
+    if(package_version_is_installed($_)) {
+      !grep(/^${\FILTER_NOT_INSTALLED}$/, @filters) and pk_print_package(INFO_INSTALLED, get_package_id($_), $_->summary);
+    }
+    else {
+      !grep(/^${\FILTER_INSTALLED}$/, @filters) and pk_print_package(INFO_AVAILABLE, get_package_id($_), $_->summary);
+    }
+  }
+}
+pk_print_status(PK_STATUS_ENUM_FINISHED);
+
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 6fa0ebe..7a5c6a6 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -247,6 +247,18 @@ backend_get_packages (PkBackend *backend, PkFilterEnum filters)
 	g_free (filters_text);
 }
 
+/**
+ * backend_get_requires:
+ */
+static void
+backend_get_requires (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-requires.pl", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL);
+	g_free (filters_text);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -261,7 +273,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_files,			/* get_files */
 	backend_get_packages,			/* get_packages */
 	NULL,			/* get_repo_list */
-	NULL,			/* get_requires */
+	backend_get_requires,			/* get_requires */
 	backend_get_update_detail,		/* get_update_detail */
 	backend_get_updates,			/* get_updates */
 	NULL,			/* install_files */
commit 97bc7dfe83c49ed5a2b3d05718c8853beaefe950
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 15:32:39 2008 +0200

    Added get-packages method for urpmi backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 5fee661..724c65a 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -15,6 +15,7 @@ dist_helper_DATA = 						\
 	install-packages.pl					\
 	remove-packages.pl					\
 	search-group.pl							\
+	get-packages.pl							\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/get-packages.pl b/backends/urpmi/helpers/get-packages.pl
new file mode 100755
index 0000000..9e3e525
--- /dev/null
+++ b/backends/urpmi/helpers/get-packages.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::args;
+
+use urpmi_backend::open_db;
+use urpmi_backend::tools;
+use urpmi_backend::filters;
+
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# One argument (the filter)
+exit if ($#ARGV != 0);
+my @filters = split(/;/, $ARGV[0]);
+
+my $urpm = urpm->new_parse_cmdline;
+
+urpm::media::configure($urpm);
+
+my $db = open_rpm_db();
+$urpm->compute_installed_flags($db);
+
+# Here we display installed packages
+if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+  $db->traverse(sub {
+      my ($pkg) = @_;
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary));
+      }
+    });
+}
+
+# Here are package which can be installed
+if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+  foreach my $pkg(@{$urpm->{depslist}}) {
+    if($pkg->flag_upgrade) {
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary));
+      }
+    }  
+  }
+}
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 30093c2..6fa0ebe 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -235,6 +235,18 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
 	g_free (filters_text);
 }
 
+/**
+ * backend_get_packages:
+ */
+static void
+backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-packages.pl", filters_text, NULL);
+	g_free (filters_text);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -247,7 +259,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	backend_get_files,			/* get_files */
-	NULL,			/* get_packages */
+	backend_get_packages,			/* get_packages */
 	NULL,			/* get_repo_list */
 	NULL,			/* get_requires */
 	backend_get_update_detail,		/* get_update_detail */
commit db032465e89fafbcf30ebe3be591cbd82e223434
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 15:23:55 2008 +0200

    Added get_filters method in URPMI backend

diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index dbae6a8..30093c2 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -86,6 +86,17 @@ backend_get_groups (PkBackend *backend)
 }
 
 /**
+ * backend_get_filters:
+ */
+static PkFilterEnum
+backend_get_filters (PkBackend *backend)
+{
+	return (PK_FILTER_ENUM_GUI |
+		PK_FILTER_ENUM_INSTALLED |
+		PK_FILTER_ENUM_DEVELOPMENT);
+}
+
+/**
  * pk_backend_bool_to_text:
  */
 static const gchar *
@@ -231,7 +242,7 @@ PK_BACKEND_OPTIONS (
 	backend_initialize,			/* initalize */
 	backend_destroy,			/* destroy */
 	backend_get_groups,			/* get_groups */
-	NULL,			/* get_filters */
+	backend_get_filters,			/* get_filters */
 	NULL,				/* cancel */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
commit a3f46116a0b394d7bdbb72fc5741ce03ccfe389e
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 15:17:18 2008 +0200

    Added search-group method to URPMI backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index bd31cc5..5fee661 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -14,6 +14,7 @@ dist_helper_DATA = 						\
 	refresh-cache.pl						\
 	install-packages.pl					\
 	remove-packages.pl					\
+	search-group.pl							\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/search-group.pl b/backends/urpmi/helpers/search-group.pl
new file mode 100755
index 0000000..e5b7b92
--- /dev/null
+++ b/backends/urpmi/helpers/search-group.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::args;
+
+use urpmi_backend::open_db;
+use urpmi_backend::tools;
+use urpmi_backend::filters;
+use urpmi_backend::groups;
+
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# Two arguments (filter and packagekit group)
+exit if ($#ARGV != 1);
+my @filters = split(/;/, $ARGV[0]);
+my $pk_group = $ARGV[1];
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $db = open_rpm_db();
+$urpm->compute_installed_flags($db);
+
+# Here we display installed packages
+if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+  $db->traverse(sub {
+      my ($pkg) = @_;
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        if(package_belongs_to_pk_group($pkg, $pk_group)) {
+          pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary));
+        }
+      }
+    });
+}
+
+# Here are package which can be installed
+if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+  foreach my $pkg(@{$urpm->{depslist}}) {
+    if($pkg->flag_upgrade) {
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        if(package_belongs_to_pk_group($pkg, $pk_group)) {
+          pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary));
+        }
+      }
+    }  
+  }
+}
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 44447bc..dbae6a8 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -212,6 +212,18 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 	g_free (package_ids_temp);
 }
 
+/**
+ * pk_backend_search_group:
+ */
+static void
+backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "search-group.pl", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -240,7 +252,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* rollback */
 	NULL,			/* search_details */
 	NULL,			/* search_file */
-	NULL,			/* search_group */
+	backend_search_group,			/* search_group */
 	backend_search_name,			/* search_name */
 	NULL,					/* service_pack */
 	NULL,		/* update_packages */
commit 4736f90665d346197625cd5c8fb92385fc54600f
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 15:03:50 2008 +0200

    Added get-groups method in URPMI backend

diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index a4c1d4c..44447bc 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -49,6 +49,43 @@ backend_destroy (PkBackend *backend)
 }
 
 /**
+ * backend_get_groups:
+ */
+static PkGroupEnum
+backend_get_groups (PkBackend *backend)
+{
+  return(PK_GROUP_ENUM_UNKNOWN |
+  PK_GROUP_ENUM_ACCESSIBILITY |
+  PK_GROUP_ENUM_ACCESSORIES |
+  PK_GROUP_ENUM_EDUCATION |
+  PK_GROUP_ENUM_GAMES |
+  PK_GROUP_ENUM_GRAPHICS |
+  PK_GROUP_ENUM_INTERNET |
+  PK_GROUP_ENUM_OFFICE |
+  PK_GROUP_ENUM_OTHER |
+  PK_GROUP_ENUM_PROGRAMMING |
+  PK_GROUP_ENUM_MULTIMEDIA |
+  PK_GROUP_ENUM_SYSTEM |
+  PK_GROUP_ENUM_DESKTOP_GNOME |
+  PK_GROUP_ENUM_DESKTOP_KDE |
+  PK_GROUP_ENUM_DESKTOP_XFCE |
+  PK_GROUP_ENUM_DESKTOP_OTHER |
+  PK_GROUP_ENUM_PUBLISHING |
+  PK_GROUP_ENUM_SERVERS |
+  PK_GROUP_ENUM_FONTS |
+  PK_GROUP_ENUM_ADMIN_TOOLS |
+  PK_GROUP_ENUM_LEGACY |
+  PK_GROUP_ENUM_LOCALIZATION |
+  PK_GROUP_ENUM_VIRTUALIZATION |
+  PK_GROUP_ENUM_POWER_MANAGEMENT |
+  PK_GROUP_ENUM_SECURITY |
+  PK_GROUP_ENUM_COMMUNICATION |
+  PK_GROUP_ENUM_NETWORK |
+  PK_GROUP_ENUM_MAPS |
+  PK_GROUP_ENUM_REPOS);
+}
+
+/**
  * pk_backend_bool_to_text:
  */
 static const gchar *
@@ -181,7 +218,7 @@ PK_BACKEND_OPTIONS (
 	"Aurelien Lefebvre <alefebvre at mandriva.com>",	/* author */
 	backend_initialize,			/* initalize */
 	backend_destroy,			/* destroy */
-	NULL,			/* get_groups */
+	backend_get_groups,			/* get_groups */
 	NULL,			/* get_filters */
 	NULL,				/* cancel */
 	backend_get_depends,			/* get_depends */
commit 06c92f2cf0084a06787229025d96282ebad9d1c3
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 14:35:03 2008 +0200

    Added remove-packages method to URPMI backend

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 60d8641..bd31cc5 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -13,6 +13,7 @@ dist_helper_DATA = 						\
 	get-update-detail.pl				\
 	refresh-cache.pl						\
 	install-packages.pl					\
+	remove-packages.pl					\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/remove-packages.pl b/backends/urpmi/helpers/remove-packages.pl
new file mode 100755
index 0000000..3be38ea
--- /dev/null
+++ b/backends/urpmi/helpers/remove-packages.pl
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpm::select;
+use urpm::install;
+use urpmi_backend::tools;
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+my $notfound = 0;
+my @breaking_pkgs = ();
+my $allowdeps_option = 0;
+my @pkgid;
+my $state = {};
+my $notfound_callback = sub {
+  $notfound = 1;
+};
+
+# This script call only be called with two arguments (allow_deps (yes/no) and a package id)
+exit if($#ARGV != 1);
+
+my $urpm = urpm->new_parse_cmdline;
+my $urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => 1);
+urpm::media::configure($urpm);
+
+$allowdeps_option = 1 if($ARGV[0] eq "yes");
+
+my @pkg_ids = split(/\|/, pop @ARGV);
+my @names;
+foreach(@pkg_ids) {
+  my @pkg_id = (split(/;/, $_));
+  push @names, $pkg_id[0];
+}
+
+pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
+
+my @to_remove = urpm::select::find_packages_to_remove($urpm,
+  $state,
+  \@names,
+  callback_notfound => $notfound_callback,
+  callback_fuzzy => $notfound_callback,
+  callback_base => sub {
+    my $urpm = shift @_;
+    push @breaking_pkgs, @_;
+  }
+);
+
+if($notfound) {
+  # printf("Error: package %s not found\n", $pkgid[0]);
+  pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "Selected package isn't installed on your system");
+}
+elsif(@breaking_pkgs) {
+  # printf("Error: These packages will break your system = \n\t%s\n", join("\n\t", @breaking_pkgs));
+  pk_print_error(PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE, "Removing selected packages will break your system");
+}
+else {
+  # printf("It's ok, I will remove %s NOW !\n", $pkgid[0]);
+  # printf("To remove list = \n\t%s\n", join("\n\t", @to_remove));
+  if(!$allowdeps_option && $#to_remove > 1) {
+    pk_print_error(PK_ERROR_ENUM_TRANSACTION_ERROR, "Packages can't be removed because dependencies remove is forbidden");
+    # printf("I can't remove, because you don't allow deps remove :'(\n");
+  }
+  else {
+    # printf("Let's go for removing ...\n");
+    pk_print_status(PK_STATUS_ENUM_REMOVE);
+    urpm::install::install($urpm,
+      \@to_remove, {}, {},
+      callback_report_uninst => sub {
+        my @return = split(/ /, $_[0]);
+        # printf("Package\tRemoving\t%s\n", fullname_to_package_id($return[$#return]));
+        pk_print_package(INFO_REMOVING, fullname_to_package_id($return[$#return]), "");
+      }
+    );
+  }
+}
+
+$urpmi_lock->unlock;
+
+pk_print_status(PK_STATUS_ENUM_FINISHED);
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 2ff4ab2..a4c1d4c 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -161,6 +161,20 @@ backend_install_packages (PkBackend *backend, gchar **package_ids)
 	g_free (package_ids_temp);
 }
 
+/**
+ * pk_backend_remove_packages:
+ */
+static void
+backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+{
+	gchar *package_ids_temp;
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	pk_backend_spawn_helper (spawn, "remove-packages.pl", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -182,7 +196,7 @@ PK_BACKEND_OPTIONS (
 	backend_install_packages,		/* install_packages */
 	NULL,		/* install_signature */
 	backend_refresh_cache,			/* refresh_cache */
-	NULL,		/* remove_packages */
+	backend_remove_packages,		/* remove_packages */
 	NULL,			/* repo_enable */
 	NULL,			/* repo_set_data */
 	NULL,			/* resolve */
commit 9b5411dd3d416e935febd5fcbe209131e03522ad
Merge: bd10369... 7323e80...
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 11:15:54 2008 +0200

    Merge branch 'master' of git+ssh://alk@git.packagekit.org/srv/git/PackageKit

commit bd10369f6f5c365143cebe67522880ff9a6ba62c
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Thu May 29 11:15:21 2008 +0200

    * Fix in perform_installation method of the urpmi backend.

diff --git a/backends/urpmi/helpers/urpmi_backend/actions.pm b/backends/urpmi/helpers/urpmi_backend/actions.pm
index c2b563b..a01b893 100644
--- a/backends/urpmi/helpers/urpmi_backend/actions.pm
+++ b/backends/urpmi/helpers/urpmi_backend/actions.pm
@@ -111,9 +111,11 @@ sub perform_installation {
     if ($subtype eq 'start') {
       if ($type eq 'trans') {
         print "Preparing packages installation ...\n";
+	pk_print_status(PK_STATUS_ENUM_INSTALL);
       } 
       elsif (defined $pkg) {
         printf("Installing package %s ...\n", $pkg->name);
+	pk_print_package(INFO_INSTALLING, get_package_id($pkg), $pkg->summary);
       }
     } 
     elsif ($subtype eq 'progress') {
@@ -155,6 +157,7 @@ sub perform_installation {
       completed => sub {
         undef $lock;
         undef $rpm_lock;
+	pk_print_status(PK_STATUS_ENUM_FINISHED);
       },
       post_download => sub {
         # Fix me !
commit 7323e8044f5c0ae4f0e14c2db38492ecefbf5d76
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 28 18:52:05 2008 +0100

    add another couple of unit tests

diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c
index f0eb612..0be0e6e 100644
--- a/libpackagekit/pk-common.c
+++ b/libpackagekit/pk-common.c
@@ -879,6 +879,23 @@ libst_common (LibSelfTest *test)
 	}
 	g_free (text_safe);
 
+	/************************************************************/
+	libst_title (test, "pk_strequal same argument");
+	temp = "dave";
+	if (pk_strequal (temp, temp)) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "incorrect ret when both same");
+	}
+
+	/************************************************************/
+	libst_title (test, "pk_strequal both const");
+	if (pk_strequal ("dave", "dave")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "incorrect ret when both same");
+	}
+
 	/************************************************************
 	 ****************        build var args        **************
 	 ************************************************************/
commit 90cbe59e6e95e4cf880285353b331428c1a0d909
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 28 18:37:51 2008 +0100

    remove pk_client_package_buffer_get_size() and pk_client_package_buffer_get_item() to replace it with pk_client_get_package_list()

diff --git a/client/pk-console.c b/client/pk-console.c
index d1ee30f..ec93978 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -486,6 +486,7 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 	guint i;
 	guint length;
 	PkPackageItem *item;
+	PkPackageList *list;
 
 	/* have we passed a complete package_id? */
 	valid = pk_package_id_check (package);
@@ -507,7 +508,9 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 	}
 
 	/* get length of items found */
-	length = pk_client_package_buffer_get_size (client_task);
+	list = pk_client_get_package_list (client_task);
+	length = pk_package_list_get_size (list);
+	g_object_unref (list);
 
 	/* didn't resolve to anything, try to get a provide */
 	if (length == 0) {
@@ -523,8 +526,9 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 		}
 	}
 
-	/* get length of items found again (we might have has success) */
-	length = pk_client_package_buffer_get_size (client_task);
+	/* get length of items found again (we might have had success) */
+	list = pk_client_get_package_list (client_task);
+	length = pk_package_list_get_size (list);
 	if (length == 0) {
 		pk_warning (_("Could not find a package match"));
 		return NULL;
@@ -532,7 +536,7 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 
 	/* only found one, great! */
 	if (length == 1) {
-		item = pk_client_package_buffer_get_item (client_task, 0);
+		item = pk_package_list_get_item (list, 0);
 		return g_strdup (item->package_id);
 	}
 
@@ -542,14 +546,16 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 	}
 	g_print ("%s\n", _("There are multiple package matches"));
 	for (i=0; i<length; i++) {
-		item = pk_client_package_buffer_get_item (client_task, i);
+		item = pk_package_list_get_item (list, i);
 		g_print ("%i. %s\n", i+1, item->package_id);
 	}
 
 	/* find out what package the user wants to use */
 	i = pk_console_get_number (_("Please enter the package number: "), length);
-	item = pk_client_package_buffer_get_item (client_task, i-1);
+	item = pk_package_list_get_item (list, i-1);
 	pk_debug ("package_id = %s", item->package_id);
+	g_object_unref (list);
+
 	return g_strdup (item->package_id);
 }
 
@@ -720,6 +726,7 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 	GPtrArray *array;
 	gchar **package_ids = NULL;
 	PkPackageList *list;
+	PkPackageList *list_single;
 
 	array = g_ptr_array_new ();
 	list = pk_package_list_new ();
@@ -769,11 +776,13 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 		}
 
 		/* see how many packages there are */
-		size = pk_client_package_buffer_get_size (client_task);
+		list_single = pk_client_get_package_list (client_task);
+		size = pk_package_list_get_size (list_single);
 		for (j=0; j<size; j++) {
-			item = pk_client_package_buffer_get_item (client_task, j);
+			item = pk_package_list_get_item (list_single, j);
 			pk_package_list_add_item (list, item);
 		}
+		g_object_unref (list_single);
 	}
 
 	/* one of the get-requires failed */
diff --git a/client/pk-import-desktop.c b/client/pk-import-desktop.c
index f5be0a5..bfe364f 100644
--- a/client/pk-import-desktop.c
+++ b/client/pk-import-desktop.c
@@ -44,53 +44,58 @@ static gchar *
 pk_desktop_get_name_for_file (const gchar *filename)
 {
 	guint size;
-	gchar *name;
+	gchar *name = NULL;
 	PkPackageItem *item;
 	PkPackageId *pid;
 	gboolean ret;
 	GError *error = NULL;
+	PkPackageList *list = NULL;
 
 	/* use PK to find the correct package */
 	ret = pk_client_reset (client, &error);
 	if (!ret) {
 		pk_warning ("failed to reset client: %s", error->message);
 		g_error_free (error);
-		return NULL;
+		goto out;
 	}
 
 	ret = pk_client_search_file (client, PK_FILTER_ENUM_INSTALLED, filename, &error);
 	if (!ret) {
 		pk_warning ("failed to search file: %s", error->message);
 		g_error_free (error);
-		return NULL;
+		goto out;
 	}
 
 	/* check that we only matched one package */
-	size = pk_client_package_buffer_get_size (client);
+	list = pk_client_get_package_list (client);
+	size = pk_package_list_get_size (list);
 	if (size != 1) {
 		pk_warning ("not correct size, %i", size);
-		return NULL;
+		goto out;
 	}
 
 	/* get the item */
-	item = pk_client_package_buffer_get_item (client, 0);
+	item = pk_package_list_get_item (list, 0);
 	if (item == NULL) {
 		pk_error ("cannot get item");
-		return NULL;
+		goto out;
 	}
 
 	/* get the package name */
 	pid = pk_package_id_new_from_string (item->package_id);
 	if (pid == NULL) {
 		pk_error ("cannot allocate package id");
-		return NULL;
+		goto out;
 	}
 
 	/* strip the name */
 	name = g_strdup (pid->name);
 	pk_package_id_free (pid);
 
-	/* return a copy */
+out:
+	if (list != NULL) {
+		g_object_unref (list);
+	}
 	return name;
 }
 
diff --git a/client/pk-import-specspo.c b/client/pk-import-specspo.c
index cf14cc2..bffd45b 100644
--- a/client/pk-import-specspo.c
+++ b/client/pk-import-specspo.c
@@ -56,6 +56,7 @@ pk_import_specspo_get_summary (const gchar *name)
 	gboolean ret;
 	PkPackageItem *item;
 	GError *error = NULL;
+	PkPackageList *list;
 
 	ret = pk_client_reset (client, &error);
 	if (!ret) {
@@ -74,18 +75,21 @@ pk_import_specspo_get_summary (const gchar *name)
 	}
 
 	/* check that we only matched one package */
-	size = pk_client_package_buffer_get_size (client);
+	list = pk_client_get_package_list (client);
+	size = pk_package_list_get_size (list);
 	if (size != 1) {
 		pk_warning ("not correct size, %i", size);
 		return NULL;
 	}
 
 	/* get the item */
-	item = pk_client_package_buffer_get_item (client, 0);
+	item = pk_package_list_get_item (list, 0);
 	if (item == NULL) {
 		pk_error ("cannot get item");
+		g_object_unref (list);
 		return NULL;
 	}
+	g_object_unref (list);
 
 	return item->summary;
 }
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 8f7df68..6924fdc 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -275,7 +275,7 @@ pk_client_get_tid (PkClient *client)
  * If the package buffer is enabled then after the transaction has completed
  * then the package list can be retrieved in one go, rather than processing
  * each package request async.
- * If this is not set true explicitly, then pk_client_package_buffer_get_size
+ * If this is not set true explicitly, then pk_client_get_package_list
  * will always return zero items.
  *
  * This is not forced on as there may be significant overhead if the list
@@ -364,26 +364,7 @@ pk_client_get_require_restart (PkClient *client)
 }
 
 /**
- * pk_client_package_buffer_get_size:
- * @client: a valid #PkClient instance
- *
- * We do not provide access to the internal package list (as it could be being
- * updated) so provide a way to get access to the current size here.
- *
- * Return value: The size of the package buffer.
- **/
-guint
-pk_client_package_buffer_get_size (PkClient *client)
-{
-	g_return_val_if_fail (PK_IS_CLIENT (client), 0);
-	if (!client->priv->use_buffer) {
-		return 0;
-	}
-	return pk_package_list_get_size (client->priv->package_list);
-}
-
-/**
- * pk_client_package_buffer_get_item:
+ * pk_client_get_package_list:
  * @client: a valid #PkClient instance
  * @item: the item in the package buffer
  *
@@ -392,14 +373,17 @@ pk_client_package_buffer_get_size (PkClient *client)
  *
  * Return value: The #PkPackageItem or %NULL if not found or invalid
  **/
-PkPackageItem *
-pk_client_package_buffer_get_item (PkClient *client, guint item)
+PkPackageList *
+pk_client_get_package_list (PkClient *client)
 {
+	PkPackageList *list;
 	g_return_val_if_fail (PK_IS_CLIENT (client), NULL);
 	if (!client->priv->use_buffer) {
 		return NULL;
 	}
-	return pk_package_list_get_item (client->priv->package_list, item);
+	list = client->priv->package_list;
+	g_object_ref (list);
+	return list;
 }
 
 /**
@@ -3786,6 +3770,7 @@ libst_client (LibSelfTest *test)
 	guint size_new;
 	guint i;
 	gchar *file;
+	PkPackageList *list;
 
 	if (libst_start (test, "PkClient", CLASS_AUTO) == FALSE) {
 		return;
@@ -3867,7 +3852,9 @@ libst_client (LibSelfTest *test)
 	}
 
 	/* get size */
-	size = pk_client_package_buffer_get_size (client);
+	list = pk_client_get_package_list (client);
+	size = pk_package_list_get_size (list);
+	g_object_unref (list);
 	if (size == 0) {
 		libst_failed (test, "failed: to get any results");
 	}
@@ -3887,7 +3874,9 @@ libst_client (LibSelfTest *test)
 			g_error_free (error);
 		}
 		/* check we got the same results */
-		size_new = pk_client_package_buffer_get_size (client);
+		list = pk_client_get_package_list (client);
+		size_new = pk_package_list_get_size (list);
+		g_object_unref (list);
 		if (size != size_new) {
 			libst_failed (test, "old size %i, new size %", size, size_new);
 		}
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 2b1d1a2..6617159 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -346,9 +346,7 @@ gboolean	 pk_client_repo_set_data		(PkClient	*client,
 							 G_GNUC_WARN_UNUSED_RESULT;
 
 /* cached stuff */
-guint		 pk_client_package_buffer_get_size	(PkClient	*client);
-PkPackageItem	*pk_client_package_buffer_get_item	(PkClient	*client,
-							 guint		 item);
+PkPackageList	*pk_client_get_package_list		(PkClient	*client);
 PkRestartEnum	 pk_client_get_require_restart		(PkClient	*client);
 
 /* not job specific */
commit 9ba80097bb4aa9c6f8664729de542c4a3f90e33b
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 28 18:32:36 2008 +0100

    add pk_package_list_add_list() convenience function

diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index 212f36e..6bdb0d4 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -110,6 +110,30 @@ pk_package_list_add_item (PkPackageList *plist, PkPackageItem *item)
 }
 
 /**
+ * pk_package_list_add_list:
+ *
+ * Makes a deep copy of the list
+ **/
+gboolean
+pk_package_list_add_list (PkPackageList *plist, PkPackageList *list)
+{
+	guint i;
+	guint len;
+	PkPackageItem *item;
+
+	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE);
+	g_return_val_if_fail (PK_IS_PACKAGE_LIST (list), FALSE);
+
+	/* add list to plist */
+	len = pk_package_list_get_size (list);
+	for (i=0; i<len; i++) {
+		item = pk_package_list_get_item (list, i);
+		pk_package_list_add_item (plist, item);
+	}
+	return TRUE;
+}
+
+/**
  * pk_package_list_get_string:
  **/
 gchar *
diff --git a/libpackagekit/pk-package-list.h b/libpackagekit/pk-package-list.h
index 9734af4..83901ab 100644
--- a/libpackagekit/pk-package-list.h
+++ b/libpackagekit/pk-package-list.h
@@ -59,6 +59,8 @@ gboolean	 pk_package_list_add			(PkPackageList		*plist,
 							 const gchar		*summary);
 gboolean	 pk_package_list_add_item		(PkPackageList		*plist,
 							 PkPackageItem		*item);
+gboolean	 pk_package_list_add_list		(PkPackageList		*plist,
+							 PkPackageList		*list);
 gboolean	 pk_package_list_contains		(PkPackageList		*plist,
 							 const gchar		*package_id);
 gboolean	 pk_package_list_contains_item		(PkPackageList		*plist,
commit 2f853e279639d767b5905f506cf0073193208a64
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 28 17:41:41 2008 +0100

    don't print the file list as it's usually huge and fills the terminal

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index e2a8c67..8f7df68 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -566,16 +566,12 @@ pk_client_details_cb (DBusGProxy  *proxy,
  * pk_client_files_cb:
  */
 static void
-pk_client_files_cb (DBusGProxy  *proxy,
-		    const gchar *package_id,
-		    const gchar *filelist,
-		    PkClient    *client)
+pk_client_files_cb (DBusGProxy  *proxy, const gchar *package_id, const gchar *filelist, PkClient *client)
 {
 	g_return_if_fail (PK_IS_CLIENT (client));
 
-	pk_debug ("emit files %s, %s", package_id, filelist);
-	g_signal_emit (client , signals [PK_CLIENT_FILES], 0, package_id,
-		       filelist);
+	pk_debug ("emit files %s, <lots of files>", package_id);
+	g_signal_emit (client , signals [PK_CLIENT_FILES], 0, package_id, filelist);
 }
 
 /**
commit 2ef53f390884c854859e2b18d6c7f531eedd1197
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 18:26:54 2008 +0200

    * Added install-packages.pl in URPMI backend.

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 5a0f4ac..60d8641 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -12,6 +12,7 @@ dist_helper_DATA = 						\
 	get-updates.pl							\
 	get-update-detail.pl				\
 	refresh-cache.pl						\
+	install-packages.pl					\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/install-packages.pl b/backends/urpmi/helpers/install-packages.pl
new file mode 100755
index 0000000..c9cf6c8
--- /dev/null
+++ b/backends/urpmi/helpers/install-packages.pl
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::select;
+
+use urpmi_backend::actions;
+use urpmi_backend::tools;
+
+# One argument (package id)
+exit if($#ARGV != 0);
+
+my @pkg_ids = split(/\|/, pop @ARGV);
+my @names;
+foreach(@pkg_ids) {
+  my @pkg_id = (split(/;/, $_));
+  push @names, $pkg_id[0];
+}
+
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my %requested;
+
+urpm::select::search_packages($urpm, \%requested, \@names, 
+  fuzzy => 0, 
+  caseinsensitive => 0,
+  all => 0);
+
+perform_installation($urpm, \%requested);
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 0e6794f..2ff4ab2 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -140,6 +140,27 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
 	pk_backend_spawn_helper (spawn, "refresh-cache.pl", NULL);
 }
 
+/**
+ * backend_install_packages:
+ */
+static void
+backend_install_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/* check network state */
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	pk_backend_spawn_helper (spawn, "install-packages.pl", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -158,7 +179,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_update_detail,		/* get_update_detail */
 	backend_get_updates,			/* get_updates */
 	NULL,			/* install_files */
-	NULL,		/* install_packages */
+	backend_install_packages,		/* install_packages */
 	NULL,		/* install_signature */
 	backend_refresh_cache,			/* refresh_cache */
 	NULL,		/* remove_packages */
commit 01acbbc95e2dae05aa889e78e5f392214432ee3d
Merge: c22df72... 0ce1be0...
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 28 14:48:46 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit c22df72a4679c70c391413c0d0fccce71928cdcd
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 28 14:47:11 2008 +0100

    document the bodge seporator used for updates and obsoletes in the UpdateDetail callback

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 02036ec..5714e9f 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -187,6 +187,7 @@ backend_get_update_detail_timeout (gpointer data)
 					  "", PK_RESTART_ENUM_NONE, "Update to newest upstream source");
 	} else if (pk_strequal (_package_id, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed")) {
 		pk_backend_update_detail (backend, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;available",
+					  "kernel;2.6.22-0.104.rc3.git6.fc8;i386;installed^"
 					  "kernel;2.6.22-0.105.rc3.git7.fc8;i386;installed", "",
 					  "http://www.distro-update.org/page?moo;Bugfix release for kernel",
 					  "http://bgzilla.fd.org/result.php?#12344;Freedesktop Bugzilla #12344;"
diff --git a/docs/spec/pk-signals.xml b/docs/spec/pk-signals.xml
index a79e647..2970dda 100644
--- a/docs/spec/pk-signals.xml
+++ b/docs/spec/pk-signals.xml
@@ -360,11 +360,21 @@
           </row>
           <row>
             <entry><literal>updates</literal></entry>
-            <entry>A list of package_id's that are to be updated</entry>
+            <entry>
+              A list of package_id's that are to be updated, seporated by <literal>^</literal>.
+              This odd delimited was chosen as <literal>\t</literal> is already being used in the
+              spawned backends, and <literal>^</literal> is a banned character in a package_id.
+              This will change in 0.3.x where <literal>updates</literal> will be a proper string
+              array field.
+            </entry>
           </row>
           <row>
             <entry><literal>obsoletes</literal></entry>
-            <entry>A list of package_id's that are to be obsoletes</entry>
+            <entry>
+              A list of package_id's that are to be obsoleted, seporated by <literal>^</literal>
+              This will change in 0.3.x where <literal>obsoletes</literal> will be a proper string
+              array field.
+            </entry>
           </row>
           <row>
             <entry><literal>vendor_url</literal></entry>
commit 0ce1be0450929bcef5c51bedf63736e5ad446a1a
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 28 15:29:49 2008 +0200

    added source filter support

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 74e9c61..e05cee0 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -288,7 +288,9 @@ backend_get_filters (PkBackend *backend)
 	return (PkFilterEnum) (PK_FILTER_ENUM_INSTALLED |
 			PK_FILTER_ENUM_NOT_INSTALLED |
 			PK_FILTER_ENUM_ARCH |
-			PK_FILTER_ENUM_NOT_ARCH);
+			PK_FILTER_ENUM_NOT_ARCH |
+			PK_FILTER_ENUM_SOURCE |
+			PK_FILTER_ENUM_NOT_SOURCE);
 }
 
 static gboolean
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index 9301c19..69e612e 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -547,6 +547,12 @@ zypp_emit_packages_in_list (PkBackend *backend, std::vector<zypp::sat::Solvable>
 							system_and_package_are_x86 (*it))
 						print = FALSE;
 				}
+				if (i == PK_FILTER_ENUM_SOURCE && !(zypp::isKind<zypp::SrcPackage>(*it))) {
+					print = FALSE;
+				}
+				if (i == PK_FILTER_ENUM_NOT_SOURCE && zypp::isKind<zypp::SrcPackage>(*it)) {
+					print = FALSE;
+				}
 				//const gchar * myarch = zypp::ZConfig::defaultSystemArchitecture().asString().c_str();
 				//pk_debug ("my default arch is %s", myarch);
 			}
commit 7cc576fbd341d9a7e98f71cceb823e71ff644c6c
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 15:20:55 2008 +0200

    * Fix compilation error.

diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 0c4337e..0e6794f 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -160,7 +160,7 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* install_files */
 	NULL,		/* install_packages */
 	NULL,		/* install_signature */
-	NULL,			/* refresh_cache */
+	backend_refresh_cache,			/* refresh_cache */
 	NULL,		/* remove_packages */
 	NULL,			/* repo_enable */
 	NULL,			/* repo_set_data */
commit e62136945fdb55427c89e42dc7f9212f2a971fa1
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 28 15:17:12 2008 +0200

    make it build again

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index a1caa43..74e9c61 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1222,7 +1222,7 @@ backend_find_packages_thread (PkBackend *backend)
 	mode = pk_backend_get_uint (backend, "mode");
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	std::vector<zypp::sat::Solvable> *v = new std::vector<zypp::sat::Solvable>;
 	std::vector<zypp::sat::Solvable> *v2 = new std::vector<zypp::sat::Solvable>;
commit b00e433b0a4f8387f97b6b765087a4d80a46cdae
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 15:15:21 2008 +0200

    * Added refresh-cache.pl to URPMI backend.

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index fc751a5..5a0f4ac 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -11,6 +11,7 @@ dist_helper_DATA = 						\
 	get-files.pl								\
 	get-updates.pl							\
 	get-update-detail.pl				\
+	refresh-cache.pl						\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/refresh-cache.pl b/backends/urpmi/helpers/refresh-cache.pl
new file mode 100755
index 0000000..555a8b8
--- /dev/null
+++ b/backends/urpmi/helpers/refresh-cache.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::select;
+use urpm::args;
+use urpmi_backend::actions;
+
+# No arguments
+exit if($#ARGV != -1);
+
+#my $urpm = urpm->new_parse_cmdline;
+my $urpm = urpm->new_parse_cmdline;
+my $urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => 0);
+urpm::media::read_config($urpm);
+
+my @entries = map { $_->{name} } @{$urpm->{media}};
+ at entries == 0 and die N("nothing to update (use urpmi.addmedia to add a media)\n");
+
+my %options = ( all => 1 );
+
+my $ok = urpm::media::update_media($urpm, %options, 
+  quiet => 0);
+exit($ok ? 0 : 1);
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 6e55b20..0c4337e 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -124,6 +124,22 @@ backend_get_update_detail (PkBackend *backend, const gchar *package_id)
 	pk_backend_spawn_helper (spawn, "get-update-detail.pl", package_id, NULL);
 }
 
+/**
+ * backend_refresh_cache:
+ */
+static void
+backend_refresh_cache (PkBackend *backend, gboolean force)
+{
+	/* check network state */
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	pk_backend_spawn_helper (spawn, "refresh-cache.pl", NULL);
+}
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
commit 1de601f3556c80094cbf1f9f43113374c9257f54
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 28 15:10:22 2008 +0200

    added copyright stuff again

diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h
index 2955d98..d491f99 100644
--- a/backends/zypp/zypp-events.h
+++ b/backends/zypp/zypp-events.h
@@ -1,3 +1,27 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (c) 2007 Novell, Inc.
+ * Copyright (c) 2007 Boyd Timothy <btimothy at gmail.com>
+ * Copyright (c) 2007-2008 Stefan Haas <shaas at suse.de>
+ * Copyright (c) 2007-2008 Scott Reeves <sreeves at novell.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
 #ifndef _ZYPP_EVENTS_H_
 #define _ZYPP_EVENTS_H_
 
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index c8ebd3f..9301c19 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -1,3 +1,27 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (c) 2007 Novell, Inc.
+ * Copyright (c) 2007 Boyd Timothy <btimothy at gmail.com>
+ * Copyright (c) 2007-2008 Stefan Haas <shaas at suse.de>
+ * Copyright (c) 2007-2008 Scott Reeves <sreeves at novell.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
 #include <sstream>
 #include <stdlib.h>
 #include <glib.h>
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index d0361ea..4f785cf 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -1,3 +1,27 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (c) 2007 Novell, Inc.
+ * Copyright (c) 2007 Boyd Timothy <btimothy at gmail.com>
+ * Copyright (c) 2007-2008 Stefan Haas <shaas at suse.de>
+ * Copyright (c) 2007-2008 Scott Reeves <sreeves at novell.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
 #ifndef _ZYPP_UTILS_H_
 #define _ZYPP_UTILS_H_
 
commit 344b11c43aa7c272f3965da65ca7b9cae2d4906b
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 28 15:05:49 2008 +0200

    merged with distro-openSUSE branch

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index b684312..a1caa43 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -26,6 +26,7 @@
 #include <pk-debug.h>
 #include <string>
 #include <set>
+#include <glib/gi18n.h>
 
 #include <zypp/ZYppFactory.h>
 #include <zypp/ResObject.h>
@@ -95,6 +96,7 @@ backend_initialize (PkBackend *backend)
 	_eventDirectors [backend] = eventDirector;
 	std::vector<std::string> *signature = new std::vector<std::string> ();
 	_signatures [backend] = signature;
+	_updating_self = FALSE;
 }
 
 /**
@@ -402,7 +404,7 @@ backend_get_depends_thread (PkBackend *backend)
 			package_id_temp = pk_package_id_build (it->second.name ().c_str(),
 					it->second.edition ().asString ().c_str(),
 					it->second.arch ().c_str(),
-					it->second.repository ().name ().c_str());
+					it->second.repository ().alias ().c_str());
 
 			zypp::PoolItem item = zypp::ResPool::instance ().find (it->second);
 
@@ -569,6 +571,32 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
 	pk_backend_thread_create (backend, backend_refresh_cache_thread);
 }
 
+/* If a critical self update (see qualifying steps below) is available then only show/install that update first.
+ 1. there is a patch available with the <restart_suggested> tag set
+ 2. The patch contains the package "PackageKit" or "gnome-packagekit
+*/   
+/*static gboolean
+check_for_self_update (PkBackend *backend, std::set<zypp::PoolItem> *candidates)
+{
+	std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci;
+	for (ci = cb; ci != ce; ++ci) {
+		zypp::ResObject::constPtr res = ci->resolvable();
+		if (zypp::isKind<zypp::Patch>(res)) {
+			zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>(res);
+			//pk_debug ("restart_suggested is %d",(int)patch->restartSuggested());
+			if (patch->restartSuggested ()) {
+				if (!strcmp (PACKAGEKIT_RPM_NAME, res->satSolvable ().name ().c_str ()) ||
+						!strcmp (GNOME_PACKAGKEKIT_RPM_NAME, res->satSolvable ().name ().c_str ())) {
+					g_free (update_self_patch_name);
+					update_self_patch_name = zypp_build_package_id_from_resolvable (res->satSolvable ());
+					return TRUE;
+				}
+			}
+		}
+	}
+	return FALSE;
+}*/
+
 static gboolean
 backend_get_updates_thread (PkBackend *backend)
 {
@@ -585,12 +613,23 @@ backend_get_updates_thread (PkBackend *backend)
 	pk_backend_set_percentage (backend, 40);
 
 	// get all Packages and Patches for Update
-	std::set<zypp::PoolItem> *candidates = zypp_get_updates ();
-	std::set<zypp::PoolItem> *candidates2 = zypp_get_patches ();
+	std::set<zypp::PoolItem> *candidates = zypp_get_patches ();
+	std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> ();
+
+	if (!_updating_self) {
+		// exclude the patch-repository
+		std::string patchRepo;
+		if (!candidates->empty ()) {
+			patchRepo = candidates->begin ()->resolvable ()->repoInfo ().alias ();
+		}
+		
+		candidates2 = zypp_get_updates (patchRepo);
 
-	candidates->insert (candidates2->begin (), candidates2->end ());
+		candidates->insert (candidates2->begin (), candidates2->end ());
+	}
 
 	pk_backend_set_percentage (backend, 80);
+	
 	std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci;
 	for (ci = cb; ci != ce; ++ci) {
 		zypp::ResObject::constPtr res = ci->resolvable();
@@ -715,7 +754,7 @@ backend_install_files_thread (PkBackend *backend)
 		gboolean found = FALSE;
 
 		for (std::vector<zypp::sat::Solvable>::iterator it = solvables->begin (); it != solvables->end (); it ++) {
-		       if (it->repository ().name () == "PK_TMP_DIR") {
+		       if (it->repository ().alias () == "PK_TMP_DIR") {
 			       item = new zypp::PoolItem(*it);
 			       found = TRUE;
 			       break;
@@ -860,14 +899,28 @@ backend_update_system_thread (PkBackend *backend)
 	zypp::ResPool pool = zypp_build_pool (TRUE);
 	pk_backend_set_percentage (backend, 40);
 
-	// get all Packages for Update
-	std::set<zypp::PoolItem> *candidates =  zypp_get_updates ();
 	//get all Patches for Update
-	std::set<zypp::PoolItem> *candidates2 = zypp_get_patches ();
+	std::set<zypp::PoolItem> *candidates = zypp_get_patches ();
+	std::set<zypp::PoolItem> *candidates2 = new std::set<zypp::PoolItem> ();
+	
+	if (_updating_self) {
+		pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, _("Package Management System updated - restart needed"));
+		_updating_self = FALSE;
+	}
+	else {
+		//disabling patchrepo
+		std::string patchRepo;
+		if (!candidates->empty ()) {
+			patchRepo = candidates->begin ()->resolvable ()->repoInfo ().alias ();
+		}
+	
+		//get all Updates
+		candidates2 = zypp_get_updates (patchRepo);
 
-	//concatenate these sets
+		//concatenate these sets
 
-	candidates->insert (candidates->begin (), candidates->end ());
+		candidates->insert (candidates2->begin (), candidates2->end ());
+	}
 
 	pk_backend_set_percentage (backend, 80);
 	std::set<zypp::PoolItem>::iterator cb = candidates->begin (), ce = candidates->end (), ci;
@@ -1169,7 +1222,7 @@ backend_find_packages_thread (PkBackend *backend)
 	mode = pk_backend_get_uint (backend, "mode");
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
+	pk_backend_no_percentage_updates (backend);
 
 	std::vector<zypp::sat::Solvable> *v = new std::vector<zypp::sat::Solvable>;
 	std::vector<zypp::sat::Solvable> *v2 = new std::vector<zypp::sat::Solvable>;
@@ -1331,6 +1384,10 @@ backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
 		repo = manager.getRepositoryInfo (rid);
 		repo.setEnabled (enabled);
 		manager.modifyRepository (rid, repo);
+		if (!enabled) {
+			zypp::Repository repository = zypp::sat::Pool::instance ().reposFind (repo.alias ());
+			repository.eraseFromPool ();
+		}
 	} catch (const zypp::repo::RepoNotFoundException &ex) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, "Couldn't find the specified repository");
 		pk_backend_finished (backend);
@@ -1462,6 +1519,13 @@ backend_update_packages_thread (PkBackend *backend)
 	gchar **package_ids;
 	package_ids = pk_backend_get_strv (backend, "package_ids");
 
+	zypp_get_patches (); // make shure _updating_self is set
+
+	if (_updating_self) {
+		pk_debug ("updating self and setting restart");
+		pk_backend_require_restart (backend, PK_RESTART_ENUM_SESSION, _("Package Management System updated - restart needed"));
+		_updating_self = FALSE;
+	}
 	for (guint i = 0; i < g_strv_length (package_ids); i++) {
 		zypp::sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]);
 		zypp::PoolItem item = zypp::ResPool::instance ().find (solvable);
diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h
index d491f99..2955d98 100644
--- a/backends/zypp/zypp-events.h
+++ b/backends/zypp/zypp-events.h
@@ -1,27 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (c) 2007 Novell, Inc.
- * Copyright (c) 2007 Boyd Timothy <btimothy at gmail.com>
- * Copyright (c) 2007-2008 Stefan Haas <shaas at suse.de>
- * Copyright (c) 2007-2008 Scott Reeves <sreeves at novell.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
 #ifndef _ZYPP_EVENTS_H_
 #define _ZYPP_EVENTS_H_
 
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index a7bb282..c8ebd3f 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -1,31 +1,8 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (c) 2007 Novell, Inc.
- * Copyright (c) 2007 Boyd Timothy <btimothy at gmail.com>
- * Copyright (c) 2007-2008 Stefan Haas <shaas at suse.de>
- * Copyright (c) 2007-2008 Scott Reeves <sreeves at novell.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
 #include <sstream>
 #include <stdlib.h>
 #include <glib.h>
 #include <glib/gstdio.h>
+#include <glib/gi18n.h>
 #include <zypp/ZYpp.h>
 #include <zypp/ZYppFactory.h>
 #include <zypp/RepoManager.h>
@@ -55,6 +32,7 @@
 #include "zypp-utils.h"
 
 gchar * _repoName;
+gboolean _updating_self = FALSE;
 /**
  * Collect items, select best edition.  This is used to find the best
  * available or installed.  The name of the class is a bit misleading though ...
@@ -101,8 +79,8 @@ get_zypp ()
 }
 
 /**
- * Enable and rotate zypp logging
- */
+  * Enable and rotate zypp logging
+  */
 gboolean
 zypp_logging ()
 {
@@ -112,16 +90,16 @@ zypp_logging ()
 	if (g_file_test (file, G_FILE_TEST_EXISTS)) {
 		struct stat buffer;
 		g_stat (file, &buffer);
-		// if the file is bigger than 5 MB rotate
-		if ((guint)buffer.st_size > 5242880) {
+		// if the file is bigger than 10 MB rotate
+		if ((guint)buffer.st_size > 10485760) {
 			if (g_file_test (file_old, G_FILE_TEST_EXISTS))
 				g_remove (file_old);
 			g_rename (file, file_old);
 		}
 	}
- 
+
 	zypp::base::LogControl::instance ().logfile(file);
-		
+
 	g_free (file);
 	g_free (file_old);
 
@@ -150,13 +128,13 @@ zypp_build_pool (gboolean include_local)
 	zypp::ZYpp::Ptr zypp = get_zypp ();
 
 	if (include_local == TRUE) {
-                //FIXME have to wait for fix in zypp (repeated loading of target)
-                if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoName() ).solvablesEmpty ())
-                {
-		        // Add local resolvables
-		        zypp::Target_Ptr target = zypp->target ();
-		        target->load ();
-                }
+		//FIXME have to wait for fix in zypp (repeated loading of target)
+		if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoAlias() ).solvablesEmpty ())
+		{
+			// Add local resolvables
+			zypp::Target_Ptr target = zypp->target ();
+			target->load ();
+		}
 	}
 
 	// Add resolvables from enabled repos
@@ -193,16 +171,16 @@ zypp_build_pool (gboolean include_local)
 zypp::ResPool
 zypp_build_local_pool ()
 {
-        zypp::sat::Pool pool = zypp::sat::Pool::instance ();
+	zypp::sat::Pool pool = zypp::sat::Pool::instance ();
 	zypp::ZYpp::Ptr zypp = get_zypp ();
 
 	try {
 		for (zypp::detail::RepositoryIterator it = pool.reposBegin (); it != pool.reposEnd (); it++){
 			if (! it->isSystemRepo ())
-				pool.reposErase(it->name ());
+				pool.reposErase(it->alias ());
 		}
 		
-		if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoName() ).solvablesEmpty ())
+		if (zypp::sat::Pool::instance().reposFind( zypp::sat::Pool::systemRepoAlias() ).solvablesEmpty ())
                 {
 		        // Add local resolvables
 		        zypp::Target_Ptr target = zypp->target ();
@@ -401,7 +379,7 @@ zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable)
 	package_id = pk_package_id_build (resolvable.name ().c_str (),
 					  resolvable.edition ().asString ().c_str (),
 					  resolvable.arch ().asString ().c_str (),
-					  resolvable.repository (). name().c_str ());
+					  resolvable.repository (). alias().c_str ());
 
 	return package_id;
 }
@@ -437,13 +415,13 @@ zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key)
         	pk_backend_repo_signature_required (backend,
 				"dummy;0.0.1;i386;data",
 	                        _repoName,
-				info.baseUrlsBegin ()->asString ().c_str (),
-				key.name ().c_str (),
+        	                info.baseUrlsBegin ()->asString ().c_str (),
+                	        key.name ().c_str (),
                         	key.id ().c_str (),
 	                        key.fingerprint ().c_str (),
         	                key.created ().asString ().c_str (),
                 	        PK_SIGTYPE_ENUM_GPG);
-		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed");
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
 	}else{
 		ok = TRUE;
 	}
@@ -462,17 +440,17 @@ zypp_signature_required (PkBackend *backend, const std::string &file, const std:
 			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
 			return FALSE;
 		}
-
+		
 		pk_backend_repo_signature_required (backend,
 				"dummy;0.0.1;i386;data",
 	                        _repoName,
-				info.baseUrlsBegin ()->asString ().c_str (),
+        	                info.baseUrlsBegin ()->asString ().c_str (),
                 	        id.c_str (),
                         	id.c_str (),
 	                        "UNKNOWN",
         	                "UNKNOWN",
                 	        PK_SIGTYPE_ENUM_GPG);
-		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed");
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
 	}else{
 		ok = TRUE;
 	}
@@ -491,17 +469,17 @@ zypp_signature_required (PkBackend *backend, const std::string &file)
 			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
 			return FALSE;
 		}
-
+		
 		pk_backend_repo_signature_required (backend,
 				"dummy;0.0.1;i386;data",
 	                        _repoName,
-				info.baseUrlsBegin ()->asString ().c_str (),
+        	                info.baseUrlsBegin ()->asString ().c_str (),
 	                        "UNKNOWN",
         	                file.c_str (),
                 	        "UNKNOWN",
                         	"UNKNOWN",
 	                        PK_SIGTYPE_ENUM_GPG);
-		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, "Repo signature verification failed");
+		pk_backend_error_code (backend, PK_ERROR_ENUM_GPG_FAILURE, _("Signature verification for Repository %s failed"), _repoName);
 	}else{
 		ok = TRUE;
 	}
@@ -591,7 +569,7 @@ zypp_find_arch_update_item (const zypp::ResPool & pool, zypp::PoolItem item)
 }
 
 std::set<zypp::PoolItem> *
-zypp_get_updates ()
+zypp_get_updates (std::string repo)
 {
         std::set<zypp::PoolItem> *pks = new std::set<zypp::PoolItem> ();
         zypp::ResPool pool = zypp::ResPool::instance ();
@@ -606,7 +584,12 @@ zypp_get_updates ()
                 zypp::PoolItem candidate =  zypp_find_arch_update_item (pool, *it);
                 if (!candidate.resolvable ())
                         continue;
-                pks->insert (candidate);
+		if (repo.empty ()) {
+	                pks->insert (candidate);
+		}else{
+			if (candidate->repoInfo ().alias ().compare (repo) != 0)
+				pks->insert (candidate);
+		}
         }
 
         return pks;
@@ -616,6 +599,7 @@ std::set<zypp::PoolItem> *
 zypp_get_patches ()
 {
         std::set<zypp::PoolItem> *patches = new std::set<zypp::PoolItem> ();
+	_updating_self = FALSE;
 
         zypp::ZYpp::Ptr zypp;
         zypp = get_zypp ();
@@ -625,8 +609,18 @@ zypp_get_patches ()
         for (zypp::ResPoolProxy::const_iterator it = zypp->poolProxy ().byKindBegin<zypp::Patch>();
                         it != zypp->poolProxy ().byKindEnd<zypp::Patch>(); it ++) {
                 // check if patch is needed 
-                if((*it)->candidateObj ().isBroken())
+                if((*it)->candidateObj ().isBroken()) {
                         patches->insert ((*it)->candidateObj ());
+			zypp::Patch::constPtr patch = zypp::asKind<zypp::Patch>((*it)->candidateObj ().resolvable ());
+
+			// check if the patch updates libzypp or packageKit and show only this one
+			if (patch->restartSuggested ()) {
+				_updating_self = TRUE;
+				patches->clear ();
+				patches->insert ((*it)->candidateObj ());
+				break;
+			}
+		}
 
         }
 
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index e741e4e..d0361ea 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -1,27 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (c) 2007 Novell, Inc.
- * Copyright (c) 2007 Boyd Timothy <btimothy at gmail.com>
- * Copyright (c) 2007-2008 Stefan Haas <shaas at suse.de>
- * Copyright (c) 2007-2008 Scott Reeves <sreeves at novell.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
 #ifndef _ZYPP_UTILS_H_
 #define _ZYPP_UTILS_H_
 
@@ -62,6 +38,11 @@ typedef enum {
   */
 extern std::map<PkBackend *, std::vector<std::string> *> _signatures;
 
+/** Used to show/install only an update to ourself. This way if we find a critical bug
+  * in the way we update packages we will install the fix before any other updates.
+  */
+extern gboolean _updating_self;
+
 /** A string to store the last refreshed repo
   * this is needed for gpg-key handling stuff (UGLY HACK)
   * FIXME
@@ -71,8 +52,8 @@ extern gchar *_repoName;
 zypp::ZYpp::Ptr get_zypp ();
 
 /**
- * Enable and rotate logging
- */
+  * Enable and rotate logging
+  */
 gboolean zypp_logging ();
 
 gboolean zypp_is_changeable_media (const zypp::Url &url);
@@ -130,8 +111,8 @@ zypp::sat::Solvable zypp_get_package_by_id (const gchar *package_id);
 gchar * zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable);
 
 /**
- * Get the RepoInfo 
- */
+  * Get the RepoInfo 
+  */
 zypp::RepoInfo
 zypp_get_Repository (PkBackend *backend, const gchar *alias);
 
@@ -156,9 +137,9 @@ gboolean zypp_signature_required (PkBackend *backend, const std::string &file, c
 zypp::PoolItem zypp_find_arch_update_item (const zypp::ResPool & pool, zypp::PoolItem item);
 
 /**
-  * Returns a set of all packages the could be updated
+  * Returns a set of all packages the could be updated (you're able to exclude a repo)
   */
-std::set<zypp::PoolItem> * zypp_get_updates ();
+std::set<zypp::PoolItem> * zypp_get_updates (std::string repo);
 
 /**
   * Returns a set of all patches the could be installed
commit e1437afbe8e681027fc83e993666ddf360f86433
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 15:03:02 2008 +0200

    * Each elements of package id's list are displayed seperated with "^"

diff --git a/backends/urpmi/helpers/get-update-detail.pl b/backends/urpmi/helpers/get-update-detail.pl
index 6e32424..f2333c6 100755
--- a/backends/urpmi/helpers/get-update-detail.pl
+++ b/backends/urpmi/helpers/get-update-detail.pl
@@ -67,8 +67,8 @@ else {
 
   if($restart) {
     pk_print_update_detail(get_package_id($pkg),
-      join(" ", map(get_package_id($_), @to_install)),
-      join(" ", map(fullname_to_package_id($_), @to_remove)),
+      join("^", map(get_package_id($_), @to_install)),
+      join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
@@ -77,8 +77,8 @@ else {
   }
   else {
     pk_print_update_detail(get_package_id($pkg),
-      join(" ", map(get_package_id($_), @to_install)),
-      join(" ", map(fullname_to_package_id($_), @to_remove)),
+      join("^", map(get_package_id($_), @to_install)),
+      join("^", map(fullname_to_package_id($_), @to_remove)),
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
       "http://qa.mandriva.com",
commit 6fed870bdc1f8dfe4bfe92e92af6f337fc496705
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 14:23:42 2008 +0200

    * Fix compilation error.

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 6b16a18..fc751a5 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -10,7 +10,7 @@ dist_helper_DATA = 						\
 	get-depends.pl							\
 	get-files.pl								\
 	get-updates.pl							\
-	get-update-details.pl				\
+	get-update-detail.pl				\
 	$(NULL)
 
 install-data-hook:
commit 5d5777d73abb6b9969ffe5b9c6505050d1feb3b9
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 14:05:27 2008 +0200

    * Added get-update-detail.pl

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index a0de401..6b16a18 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -10,6 +10,7 @@ dist_helper_DATA = 						\
 	get-depends.pl							\
 	get-files.pl								\
 	get-updates.pl							\
+	get-update-details.pl				\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/get-update-detail.pl b/backends/urpmi/helpers/get-update-detail.pl
new file mode 100755
index 0000000..6e32424
--- /dev/null
+++ b/backends/urpmi/helpers/get-update-detail.pl
@@ -0,0 +1,89 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpm::select;
+use urpmi_backend::tools;
+use urpmi_backend::open_db;
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+use MDK::Common;
+
+# One argument (package id)
+exit if($#ARGV != 0);
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my ($pkg_name) = split(/;/, @ARGV[0]);
+
+my %requested;
+
+my $result = urpm::select::search_packages($urpm, \%requested, [ $pkg_name ], 
+  fuzzy => 0, 
+  caseinsensitive => 0,
+  all => 0);
+
+if(!$result) {
+  exit;
+}
+
+my @requested_keys = keys %requested;
+my $pkg = @{$urpm->{depslist}}[pop @requested_keys];
+my $pkg_upgrade = get_package_upgrade($urpm, $pkg);
+
+if(!find_installed_version($pkg)) {
+  pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "The selected package isn't installed on your system");
+}
+elsif(!$pkg_upgrade) {
+  pk_print_error(PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, "The selected package is already at the latest version");
+}
+else {
+  my $state = {};
+  my $restart = urpm::select::resolve_dependencies($urpm, $state, \%requested);
+  my %selected = %{$state->{selected}};
+  my @ask_unselect = urpm::select::unselected_packages($urpm, $state);
+  my @to_remove = urpm::select::removed_packages($urpm, $state);
+  my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; 
+  my ($src, $binary) = partition { $_->arch eq 'src' } @to_install;
+  @to_install = @$binary;
+  my $updates_descr = urpm::get_updates_description($urpm);
+  my $updesc = $updates_descr->{URPM::pkg2media($urpm->{media}, $pkg_upgrade)->{name}}{$pkg_upgrade->name};
+  my $desc;
+  if($updesc) {
+    $desc = $updesc->{pre};
+    $desc =~ s/\n/;/g;
+  }
+
+  if($restart) {
+    pk_print_update_detail(get_package_id($pkg),
+      join(" ", map(get_package_id($_), @to_install)),
+      join(" ", map(fullname_to_package_id($_), @to_remove)),
+      "http://qa.mandriva.com",
+      "http://qa.mandriva.com",
+      "http://qa.mandriva.com",
+      PK_RESTART_ENUM_SYSTEM,
+      $desc);
+  }
+  else {
+    pk_print_update_detail(get_package_id($pkg),
+      join(" ", map(get_package_id($_), @to_install)),
+      join(" ", map(fullname_to_package_id($_), @to_remove)),
+      "http://qa.mandriva.com",
+      "http://qa.mandriva.com",
+      "http://qa.mandriva.com",
+      PK_RESTART_ENUM_APPLICATION,
+      $desc);
+  }
+
+}
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index d7b4eae..6e55b20 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -115,6 +115,14 @@ backend_get_updates (PkBackend *backend, PkFilterEnum filters)
 	g_free (filters_text);
 }
 
+/**
+ * backend_get_update_detail:
+ */
+static void
+backend_get_update_detail (PkBackend *backend, const gchar *package_id)
+{
+	pk_backend_spawn_helper (spawn, "get-update-detail.pl", package_id, NULL);
+}
 
 
 PK_BACKEND_OPTIONS (
@@ -131,7 +139,7 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* get_packages */
 	NULL,			/* get_repo_list */
 	NULL,			/* get_requires */
-	NULL,		/* get_update_detail */
+	backend_get_update_detail,		/* get_update_detail */
 	backend_get_updates,			/* get_updates */
 	NULL,			/* install_files */
 	NULL,		/* install_packages */
commit 388b08d2e6bc4a90f97a5884c07a32375448cfdc
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 12:26:10 2008 +0200

    * Fix with get-updates parameters.

diff --git a/backends/urpmi/helpers/get-updates.pl b/backends/urpmi/helpers/get-updates.pl
index 5b72cc0..957126c 100755
--- a/backends/urpmi/helpers/get-updates.pl
+++ b/backends/urpmi/helpers/get-updates.pl
@@ -18,8 +18,10 @@ use urpmi_backend::tools;
 use perl_packagekit::enums;
 use perl_packagekit::prints;
 
-# No arguments authorized
-exit if($#ARGV != -1);
+# On argument (filter)
+exit if($#ARGV != 0);
+# Fix me
+# Filter are to be implemented.
 
 my $urpm = urpm->new_parse_cmdline;
 urpm::media::configure($urpm);
commit f959ee44016b8daad2a72f9dab16365a40d0055b
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 11:54:32 2008 +0200

    * Added get-updates method.

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index 4328aaf..a0de401 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -9,6 +9,7 @@ dist_helper_DATA = 						\
 	get-details.pl							\
 	get-depends.pl							\
 	get-files.pl								\
+	get-updates.pl							\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/get-updates.pl b/backends/urpmi/helpers/get-updates.pl
new file mode 100755
index 0000000..5b72cc0
--- /dev/null
+++ b/backends/urpmi/helpers/get-updates.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpm::select;
+use MDK::Common;
+use urpmi_backend::tools;
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# No arguments authorized
+exit if($#ARGV != -1);
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $state = {};
+my %requested;
+my $restart = urpm::select::resolve_dependencies($urpm, $state, \%requested,
+  auto_select => 1);
+
+my %selected = %{$state->{selected} || {}};
+my @ask_unselect = urpm::select::unselected_packages($urpm, $state);
+my @to_remove = urpm::select::removed_packages($urpm, $state);
+my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; 
+my ($src, $binary) = partition { $_->arch eq 'src' } @to_install;
+ at to_install = @$binary;
+
+foreach(@to_install) {
+  # Fix me
+  # Be default, we set to bugfix info type
+  # Need to be implemented, see urpmq source.
+  pk_print_package(INFO_BUGFIX, get_package_id($_), $_->summary);
+}
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index d8a241d..d7b4eae 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -103,6 +103,19 @@ backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *pack
 	g_free (filters_text);
 }
 
+/**
+ * backend_get_updates:
+ */
+static void
+backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-updates.pl", filters_text, NULL);
+	g_free (filters_text);
+}
+
+
 
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
@@ -119,7 +132,7 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* get_repo_list */
 	NULL,			/* get_requires */
 	NULL,		/* get_update_detail */
-	NULL,			/* get_updates */
+	backend_get_updates,			/* get_updates */
 	NULL,			/* install_files */
 	NULL,		/* install_packages */
 	NULL,		/* install_signature */
commit 405eda8acc7343cb2c6a3a140ba5b722c2594fdc
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 11:20:46 2008 +0200

    * 2nd par of last commit.

diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
index d459cb6..4328aaf 100644
--- a/backends/urpmi/helpers/Makefile.am
+++ b/backends/urpmi/helpers/Makefile.am
@@ -1,10 +1,14 @@
+SUBDIRS = perl_packagekit urpmi_backend
 
 helperdir = $(datadir)/PackageKit/helpers/urpmi
 
 NULL =
 
-dist_helper_DATA = 			\
-	search-name.pl			\
+dist_helper_DATA = 						\
+	search-name.pl							\
+	get-details.pl							\
+	get-depends.pl							\
+	get-files.pl								\
 	$(NULL)
 
 install-data-hook:
diff --git a/backends/urpmi/helpers/get-depends.pl b/backends/urpmi/helpers/get-depends.pl
index de01156..bf936c5 100755
--- a/backends/urpmi/helpers/get-depends.pl
+++ b/backends/urpmi/helpers/get-depends.pl
@@ -21,7 +21,7 @@ use urpmi_backend::tools;
 use perl_packagekit::enums;
 use perl_packagekit::prints;
 
-# Two arguments (filter and package name)
+# Two arguments (filter, package id)
 exit if($#ARGV != 2);
 
 my @filters = split(/;/, $ARGV[0]);
@@ -32,11 +32,10 @@ $recursive_option = 1 if($ARGV[2] eq "yes");
 # Only recursive option is supported
 # So, if user set no tu recursive option, 
 # backend will return error
-# Fix me : We force recursive option
-#if(!$recursive_option) {
-#  printf("Error\tnot-supported\tOnly recursive option to yes is supported\n");
-#  exit;
-#}
+if(!$recursive_option) {
+  printf("error\tnot-supported\tOnly recursive option to yes is supported\n");
+  exit;
+}
 
 pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
 
diff --git a/backends/urpmi/helpers/get-details.pl b/backends/urpmi/helpers/get-details.pl
index 56c99fe..f39bd84 100755
--- a/backends/urpmi/helpers/get-details.pl
+++ b/backends/urpmi/helpers/get-details.pl
@@ -17,8 +17,7 @@ use MDK::Common;
 
 use perl_packagekit::prints;
 
-# Only one argument authorized
-# (The Package ID)
+# One argument (package id)
 exit if($#ARGV != 0);
 
 my $urpm = urpm->new_parse_cmdline;
diff --git a/backends/urpmi/helpers/get-files.pl b/backends/urpmi/helpers/get-files.pl
index 2219415..74ae157 100755
--- a/backends/urpmi/helpers/get-files.pl
+++ b/backends/urpmi/helpers/get-files.pl
@@ -17,8 +17,7 @@ use MDK::Common;
 
 use perl_packagekit::prints;
 
-# Only one argument authorized
-# (The Package ID)
+# One argument (package id)
 exit if($#ARGV != 0);
 
 
diff --git a/backends/urpmi/helpers/search-name.pl b/backends/urpmi/helpers/search-name.pl
index f4d4c65..383921f 100755
--- a/backends/urpmi/helpers/search-name.pl
+++ b/backends/urpmi/helpers/search-name.pl
@@ -1,3 +1,64 @@
 #!/usr/bin/perl
 
-print "package\tinstalled\ttestpkg;3.1-1mdv2009.0;i586;mandriva\tHere is the summary\n";
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::media;
+use urpm::args;
+
+use urpmi_backend::open_db;
+use urpmi_backend::tools;
+use urpmi_backend::filters;
+
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# Two arguments (filter, search term)
+exit if ($#ARGV != 1);
+
+my @filters = split(/;/, $ARGV[0]);
+my $search_term = $ARGV[1];
+
+my $basename_option = FILTER_BASENAME;
+$basename_option = grep(/$basename_option/, @filters);
+
+my $urpm = urpm->new_parse_cmdline;
+
+urpm::media::configure($urpm);
+
+my $db = open_rpm_db();
+$urpm->compute_installed_flags($db);
+
+# Here we display installed packages
+if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+  $db->traverse(sub {
+      my ($pkg) = @_;
+      if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+        if( (!$basename_option && $pkg->name =~ /$search_term/)
+          || $pkg->name =~ /^$search_term$/ ) {
+          pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary));
+        }
+      }
+    });
+}
+
+# Here are packages which can be installed
+if(grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+  exit 0;
+}
+
+foreach my $pkg(@{$urpm->{depslist}}) {
+  if($pkg->flag_upgrade && filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+    if( (!$basename_option && $pkg->name =~ /$search_term/)
+      || $pkg->name =~ /^$search_term$/ ) {
+      pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary));
+    }
+  }
+}
diff --git a/backends/urpmi/helpers/urpmi_backend/actions.pm b/backends/urpmi/helpers/urpmi_backend/actions.pm
index f6033a0..c2b563b 100644
--- a/backends/urpmi/helpers/urpmi_backend/actions.pm
+++ b/backends/urpmi/helpers/urpmi_backend/actions.pm
@@ -27,11 +27,9 @@ sub perform_installation {
   my $restart;
   my $no_remove = 0;
 
-  pk_print_status(PK_STATUS_ENUM_WAIT);
-
   # Here we lock urpmi & rpm databases
-  # In third argument we can specified if the script must wait if urpmi or rpm
-  # databases are already locked
+  # In third argument we can specified if the script must wait until urpmi or rpm
+  # databases are locked
   my $lock = urpm::lock::urpmi_db($urpm, undef, wait => 0);
   my $rpm_lock = urpm::lock::rpm_db($urpm, 'exclusive');
 
@@ -116,14 +114,9 @@ sub perform_installation {
       } 
       elsif (defined $pkg) {
         printf("Installing package %s ...\n", $pkg->name);
-        # Need improvements, we can display package number, total number of packages to be installed, 
-        # and some others informations. See rpmdrake/pkg.pm source code for more information.
       }
     } 
     elsif ($subtype eq 'progress') {
-      # Progress bar ? 
-      # See Rpmdrake/pkg.pm for more information.
-      # $total, $amount/$total
       print "($type) Progress : total = ", $total, " ; amount/total = ", $amount/$total, " ; amount = ", $amount, "\n";
       if($type eq "inst") {
         pk_print_percentage($percentage + ($amount/$total)*(100/$nb_to_install));
@@ -159,26 +152,14 @@ sub perform_installation {
         my ($need_restart_formatted) = @_;
         print "$_\n" foreach values %$need_restart_formatted;
       },
-      message => sub {
-        my ($_title, $msg) = @_; # graphical title
-        print "message = ", $msg;
-        # What's this callback ? message ?
-        # Fix me : take a look on it.
-      },
       completed => sub {
         undef $lock;
         undef $rpm_lock;
       },
       post_download => sub {
+        # Fix me !
         # At this point, we need to refuse cancel action
-        # to the user (use of AllowCancel instruction of Packagekit)
       },
-      # I need to work more on main_loop callbacks in order to display
-      # personnal messages, and not using default urpmi display which is
-      # too ugly :s
-      # For help, look at the source code of Rpmdrake, and particulary see
-      # the file /usr/lib/perl5/vendor_perl/5.10.0/Rpmdrake/pkg.pm when 
-      # it calls the main_loop::run
     }
   );
 }
diff --git a/backends/urpmi/helpers/urpmi_backend/open_db.pm b/backends/urpmi/helpers/urpmi_backend/open_db.pm
index 956774e..795edc6 100644
--- a/backends/urpmi/helpers/urpmi_backend/open_db.pm
+++ b/backends/urpmi/helpers/urpmi_backend/open_db.pm
@@ -14,31 +14,13 @@ use Exporter;
 our @ISA = qw(Exporter);
 our @EXPORT = qw(fast_open_urpmi_db open_urpmi_db open_rpm_db);
 
-# do not pay the urpm::media::configure() heavy cost:
+# Note that most part of this perl module
+# is extracted from Rpmdrake
+
 sub fast_open_urpmi_db() {
     my $urpm = urpm->new;
     $urpm->get_global_options;
-    my $error_happened;
-    #$urpm->{options}{wait_lock} = $::rpmdrake_options{'wait-lock'};
-    #$urpm->{options}{'verify-rpm'} = !$::rpmdrake_options{'no-verify-rpm'} if defined $::rpmdrake_options{'no-verify-rpm'};
-    #$urpm->{options}{auto} = $::rpmdrake_options{auto} if defined $::rpmdrake_options{auto};
-    #urpm::set_files($urpm, $::rpmdrake_options{'urpmi-root'}[0]) if $::rpmdrake_options{'urpmi-root'}[0];
-    #urpm::args::set_root($urpm, $::rpmdrake_options{'rpm-root'}[0]) if $::rpmdrake_options{'rpm-root'}[0];
-
-    #$urpm::args::rpmdrake_options{justdb} = $::rpmdrake_options{justdb};
-
-    #$urpm->{fatal} = sub {
-    #    $error_happened = 1;
-    #    interactive_msg(N("Fatal error"),
-    #                     N("A fatal error occurred: %s.", $_[1]));
-    #};
-
     urpm::media::read_config($urpm);
-    # FIXME: seems uneeded with newer urpmi:
-    #if ($error_happened) {
-    #    touch('/etc/urpmi/urpmi.cfg');
-    #    exec('edit-urpm-sources.pl');
-    #}
     $urpm;
 }
 
@@ -61,23 +43,6 @@ sub get_inactive_backport_media {
 }
 
 sub open_rpm_db {
-#    my ($o_force) = @_;
-#    my $host;
-#    log::explanations("opening the RPM database");
-#    if ($::rpmdrake_options{parallel} && ((undef, $host) = @{$::rpmdrake_options{parallel}})) {
-#        state $done;
-#        my $dblocation = "/var/cache/urpmi/distantdb/$host";
-#        if (!$done || $o_force) {
-#            print "syncing db from $host to $dblocation...";
-#            mkdir_p "$dblocation/var/lib/rpm";
-#            system "rsync -Sauz -e ssh $host:/var/lib/rpm/ $dblocation/var/lib/rpm";
-#            $? == 0 or die "Couldn't sync db from $host to $dblocation";
-#            $done = 1;
-#            print "done.\n";
-#        }
-#        URPM::DB::open($dblocation) or die "Couldn't open RPM DB";
-#    } else {
-        URPM::DB::open() or die "Couldn't open RPM DB";
-#    }
+  URPM::DB::open() or die "Couldn't open RPM DB";
 }
 
diff --git a/backends/urpmi/helpers/urpmi_backend/tools.pm b/backends/urpmi/helpers/urpmi_backend/tools.pm
index 8492766..f0d80ba 100644
--- a/backends/urpmi/helpers/urpmi_backend/tools.pm
+++ b/backends/urpmi/helpers/urpmi_backend/tools.pm
@@ -21,8 +21,6 @@ our @EXPORT = qw(
   get_package_upgrade
 );
 
-# Note that all of these methods are extracted from the rpmdrake source code.
-
 sub get_update_medias {
   my ($urpm) = @_;
   grep { !$_->{ignore} && $_->{update} } @{$urpm->{media}};
@@ -50,7 +48,6 @@ sub urpm_name {
     "$name-$version-$release.$arch";
 }
 
-# from rpmtools, #37482:
 sub ensure_utf8 {
     my ($s) = @_;
     require Encode;
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 60501fa..d8a241d 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -48,6 +48,18 @@ backend_destroy (PkBackend *backend)
 	g_object_unref (spawn);
 }
 
+/**
+ * pk_backend_bool_to_text:
+ */
+static const gchar *
+pk_backend_bool_to_text (gboolean value)
+{
+	if (value == TRUE) {
+		return "yes";
+	}
+	return "no";
+}
+
 
 /**
  * pk_backend_search_name:
@@ -61,6 +73,37 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
 	g_free (filters_text);
 }
 
+/**
+ * backend_get_details:
+ */
+static void
+backend_get_details (PkBackend *backend, const gchar *package_id)
+{
+	pk_backend_spawn_helper (spawn, "get-details.pl", package_id, NULL);
+}
+
+/**
+ * backend_get_files:
+ */
+static void
+backend_get_files (PkBackend *backend, const gchar *package_id)
+{
+	pk_backend_spawn_helper (spawn, "get-files.pl", package_id, NULL);
+}
+
+/**
+ * backend_get_depends:
+ */
+static void
+backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-depends.pl", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL);
+	g_free (filters_text);
+}
+
+
 PK_BACKEND_OPTIONS (
 	"URPMI",					/* description */
 	"Aurelien Lefebvre <alefebvre at mandriva.com>",	/* author */
@@ -69,9 +112,9 @@ PK_BACKEND_OPTIONS (
 	NULL,			/* get_groups */
 	NULL,			/* get_filters */
 	NULL,				/* cancel */
-	NULL,			/* get_depends */
-	NULL,			/* get_details */
-	NULL,			/* get_files */
+	backend_get_depends,			/* get_depends */
+	backend_get_details,			/* get_details */
+	backend_get_files,			/* get_files */
 	NULL,			/* get_packages */
 	NULL,			/* get_repo_list */
 	NULL,			/* get_requires */
diff --git a/configure.ac b/configure.ac
index 5611aa8..8047013 100644
--- a/configure.ac
+++ b/configure.ac
@@ -474,6 +474,8 @@ backends/test/Makefile
 backends/test/helpers/Makefile
 backends/urpmi/Makefile
 backends/urpmi/helpers/Makefile
+backends/urpmi/helpers/perl_packagekit/Makefile
+backends/urpmi/helpers/urpmi_backend/Makefile
 backends/yum/Makefile
 backends/yum/helpers/Makefile
 backends/yum2/Makefile
commit 1a13394c8936782c8c8a042b2760162ff463b7bd
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Wed May 28 10:50:53 2008 +0200

    - Added perl_packagekit perl modules
    - Added urpmi_backend perm modules
    - Added some methods implementation
      * get-depends
      * get-details
      * get-files

diff --git a/backends/urpmi/helpers/get-depends.pl b/backends/urpmi/helpers/get-depends.pl
new file mode 100755
index 0000000..de01156
--- /dev/null
+++ b/backends/urpmi/helpers/get-depends.pl
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use URPM;
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpm::select;
+
+use urpmi_backend::open_db;
+use urpmi_backend::tools;
+
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+# Two arguments (filter and package name)
+exit if($#ARGV != 2);
+
+my @filters = split(/;/, $ARGV[0]);
+my @pkgid = split(/;/, $ARGV[1]);
+my $recursive_option = 0;
+$recursive_option = 1 if($ARGV[2] eq "yes");
+
+# Only recursive option is supported
+# So, if user set no tu recursive option, 
+# backend will return error
+# Fix me : We force recursive option
+#if(!$recursive_option) {
+#  printf("Error\tnot-supported\tOnly recursive option to yes is supported\n");
+#  exit;
+#}
+
+pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my %requested;
+my @names = (@pkgid[0]);
+my $results = urpm::select::search_packages($urpm, \%requested, \@names,
+  fuzzy => 0,
+  caseinsensitive => 0,
+  all => 0
+);
+
+exit if !$results;
+my @requested_keys = keys %requested;
+my $package_id = pop @requested_keys;
+
+my %resolv_request = ();
+%resolv_request->{$package_id} = 1;
+
+my $empty_db = new URPM;
+my $state = {};
+$urpm->resolve_requested($empty_db,
+  $state,
+  \%resolv_request,
+);
+
+my $db = open_rpm_db();
+$urpm->compute_installed_flags($db);
+
+my %selected = %{$state->{selected}};
+my @selected_keys = keys %selected;
+my @depslist = @{$urpm->{depslist}};
+
+foreach(sort {@depslist[$b]->flag_installed <=> @depslist[$a]->flag_installed} @selected_keys) {
+  my $pkg = @depslist[$_];
+  if($pkg->flag_installed) {
+    next if(grep(/^${\FILTER_NOT_INSTALLED}$/, @filters));
+    pk_print_package(INFO_INSTALLED, get_package_id($pkg), $pkg->summary);
+  }
+  else {
+    next if(grep(/^${\FILTER_INSTALLED}$/, @filters));
+    pk_print_package(INFO_AVAILABLE, get_package_id($pkg), $pkg->summary);
+  }
+}
+
diff --git a/backends/urpmi/helpers/get-details.pl b/backends/urpmi/helpers/get-details.pl
new file mode 100755
index 0000000..56c99fe
--- /dev/null
+++ b/backends/urpmi/helpers/get-details.pl
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpmi_backend::tools;
+use MDK::Common;
+
+use perl_packagekit::prints;
+
+# Only one argument authorized
+# (The Package ID)
+exit if($#ARGV != 0);
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $pkg = get_package_by_package_id($urpm, $ARGV[0]);
+
+my $medium = pkg2medium($pkg, $urpm);
+my $xml_info = 'info';
+my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, $xml_info, undef, undef);
+require urpm::xml_info;
+require urpm::xml_info_pkg;
+my $name = urpm_name($pkg);
+my %nodes = eval { urpm::xml_info::get_nodes($xml_info, $xml_info_file, [ $name ]) };
+my %xml_info_pkgs;
+put_in_hash($xml_info_pkgs{$name} ||= {}, $nodes{$name});
+my $description = $xml_info_pkgs{$name}{description};
+$description =~ s/\n/;/g;
+
+pk_print_details(get_package_id($pkg), "N/A", $pkg->group, $description, "N/A", $pkg->size);
+
diff --git a/backends/urpmi/helpers/get-files.pl b/backends/urpmi/helpers/get-files.pl
new file mode 100755
index 0000000..2219415
--- /dev/null
+++ b/backends/urpmi/helpers/get-files.pl
@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+
+use strict;
+
+use lib;
+use File::Basename;
+
+BEGIN {
+  push @INC, dirname($0);
+}
+
+use urpm;
+use urpm::args;
+use urpm::media;
+use urpmi_backend::tools;
+use MDK::Common;
+
+use perl_packagekit::prints;
+
+# Only one argument authorized
+# (The Package ID)
+exit if($#ARGV != 0);
+
+
+my $urpm = urpm->new_parse_cmdline;
+urpm::media::configure($urpm);
+
+my $pkg = get_package_by_package_id($urpm, $ARGV[0]);
+
+my $medium = pkg2medium($pkg, $urpm);
+my $xml_info = 'files';
+my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, $xml_info, undef, undef);
+require urpm::xml_info;
+require urpm::xml_info_pkg;
+my $name = urpm_name($pkg);
+my %nodes = eval { urpm::xml_info::get_nodes($xml_info, $xml_info_file, [ $name ]) };
+my %xml_info_pkgs;
+put_in_hash($xml_info_pkgs{$name} ||= {}, $nodes{$name});
+my @files = map { chomp_($_) } split("\n", $xml_info_pkgs{$name}{files});
+
+pk_print_files(get_package_id($pkg), join(';', @files));
diff --git a/backends/urpmi/helpers/perl_packagekit/Makefile.am b/backends/urpmi/helpers/perl_packagekit/Makefile.am
new file mode 100644
index 0000000..6ed63b5
--- /dev/null
+++ b/backends/urpmi/helpers/perl_packagekit/Makefile.am
@@ -0,0 +1,12 @@
+helperdir = $(datadir)/PackageKit/helpers/urpmi/perl_packagekit/
+
+NULL =
+
+dist_helper_DATA = 						\
+	enums.pm										\
+	prints.pm										\
+	$(NULL)
+
+clean-local :
+	rm -f *~
+
diff --git a/backends/urpmi/helpers/perl_packagekit/enums.pm b/backends/urpmi/helpers/perl_packagekit/enums.pm
new file mode 100644
index 0000000..8dbb4b0
--- /dev/null
+++ b/backends/urpmi/helpers/perl_packagekit/enums.pm
@@ -0,0 +1,293 @@
+package perl_packagekit::enums;
+
+use Exporter;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+  FILTER_BASENAME 
+  FILTER_DEVELOPMENT 
+  FILTER_FREE 
+  FILTER_GUI 
+  FILTER_INSTALLED 
+  FILTER_NEWEST 
+  FILTER_NONE 
+  FILTER_NOT_BASENAME 
+  FILTER_NOT_DEVELOPMENT 
+  FILTER_NOT_FREE 
+  FILTER_NOT_GUI 
+  FILTER_NOT_INSTALLED 
+  FILTER_NOT_NEWEST 
+  FILTER_NOT_SUPPORTED 
+  FILTER_NOT_VISIBLE 
+  FILTER_SUPPORTED 
+  FILTER_UNKNOWN 
+  FILTER_VISIBLE
+  
+  GROUP_ACCESSIBILITY 
+  GROUP_ACCESSORIES 
+  GROUP_ADMIN_TOOLS 
+  GROUP_COMMUNICATION 
+  GROUP_DESKTOP_GNOME 
+  GROUP_DESKTOP_KDE 
+  GROUP_DESKTOP_OTHER 
+  GROUP_DESKTOP_XFCE 
+  GROUP_EDUCATION 
+  GROUP_FONTS 
+  GROUP_GAMES 
+  GROUP_GRAPHICS 
+  GROUP_INTERNET 
+  GROUP_LEGACY 
+  GROUP_LOCALIZATION 
+  GROUP_MAPS 
+  GROUP_MULTIMEDIA 
+  GROUP_NETWORK 
+  GROUP_OFFICE 
+  GROUP_OTHER 
+  GROUP_POWER_MANAGEMENT 
+  GROUP_PROGRAMMING 
+  GROUP_PUBLISHING 
+  GROUP_REPOS 
+  GROUP_SECURITY 
+  GROUP_SERVERS 
+  GROUP_SYSTEM 
+  GROUP_UNKNOWN 
+  GROUP_VIRTUALIZATION 
+  
+  INFO_AVAILABLE 
+  INFO_BLOCKED 
+  INFO_BUGFIX 
+  INFO_CLEANUP 
+  INFO_DOWNLOADING 
+  INFO_ENHANCEMENT 
+  INFO_IMPORTANT 
+  INFO_INSTALLED 
+  INFO_INSTALLING 
+  INFO_LOW 
+  INFO_NORMAL 
+  INFO_OBSOLETING 
+  INFO_REMOVING 
+  INFO_SECURITY 
+  INFO_UNKNOWN 
+  INFO_UPDATING 
+
+  PK_ERROR_ENUM_UNKNOWN 
+  PK_ERROR_ENUM_OOM 
+  PK_ERROR_ENUM_NO_CACHE 
+  PK_ERROR_ENUM_NO_NETWORK 
+  PK_ERROR_ENUM_NOT_SUPPORTED 
+  PK_ERROR_ENUM_INTERNAL_ERROR 
+  PK_ERROR_ENUM_GPG_FAILURE 
+  PK_ERROR_ENUM_FILTER_INVALID 
+  PK_ERROR_ENUM_PACKAGE_ID_INVALID 
+  PK_ERROR_ENUM_TRANSACTION_ERROR 
+  PK_ERROR_ENUM_TRANSACTION_CANCELLED 
+  PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED 
+  PK_ERROR_ENUM_PACKAGE_NOT_FOUND 
+  PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED 
+  PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED 
+  PK_ERROR_ENUM_GROUP_NOT_FOUND 
+  PK_ERROR_ENUM_GROUP_LIST_INVALID 
+  PK_ERROR_ENUM_DEP_RESOLUTION_FAILED 
+  PK_ERROR_ENUM_CREATE_THREAD_FAILED 
+  PK_ERROR_ENUM_REPO_NOT_FOUND 
+  PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE 
+  PK_ERROR_ENUM_PROCESS_KILL 
+  PK_ERROR_ENUM_FAILED_INITIALIZATION 
+  PK_ERROR_ENUM_FAILED_FINALISE 
+  PK_ERROR_ENUM_FAILED_CONFIG_PARSING 
+  PK_ERROR_ENUM_CANNOT_CANCEL 
+  PK_ERROR_ENUM_CANNOT_GET_LOCK 
+  PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE 
+  PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG 
+  PK_ERROR_ENUM_LOCAL_INSTALL_FAILED 
+  PK_ERROR_ENUM_BAD_GPG_SIGNATURE 
+  PK_ERROR_ENUM_MISSING_GPG_SIGNATURE 
+  PK_ERROR_ENUM_CANNOT_INSTALL_SOURCE_PACKAGE 
+  PK_ERROR_ENUM_REPO_CONFIGURATION_ERROR 
+  PK_ERROR_ENUM_NO_LICENSE_AGREEMENT 
+  PK_ERROR_ENUM_FILE_CONFLICTS 
+  PK_ERROR_ENUM_REPO_NOT_AVAILABLE 
+  PK_ERROR_ENUM_INVALID_PACKAGE_FILE 
+  PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED 
+  
+  PK_RESTART_ENUM_UNKNOWN
+  PK_RESTART_ENUM_NONE
+  PK_RESTART_ENUM_SYSTEM
+  PK_RESTART_ENUM_SESSION
+  PK_RESTART_ENUM_APPLICATION
+  
+  PK_STATUS_ENUM_UNKNOWN 
+  PK_STATUS_ENUM_WAIT 
+  PK_STATUS_ENUM_SETUP 
+  PK_STATUS_ENUM_RUNNING 
+  PK_STATUS_ENUM_QUERY 
+  PK_STATUS_ENUM_INFO 
+  PK_STATUS_ENUM_REFRESH_CACHE 
+  PK_STATUS_ENUM_REMOVE 
+  PK_STATUS_ENUM_DOWNLOAD 
+  PK_STATUS_ENUM_INSTALL 
+  PK_STATUS_ENUM_UPDATE 
+  PK_STATUS_ENUM_CLEANUP 
+  PK_STATUS_ENUM_OBSOLETE 
+  PK_STATUS_ENUM_DEP_RESOLVE 
+  PK_STATUS_ENUM_SIG_CHECK 
+  PK_STATUS_ENUM_ROLLBACK 
+  PK_STATUS_ENUM_TEST_COMMIT 
+  PK_STATUS_ENUM_COMMIT 
+  PK_STATUS_ENUM_REQUEST 
+  PK_STATUS_ENUM_FINISHED 
+  PK_STATUS_ENUM_CANCEL 
+  PK_STATUS_ENUM_DOWNLOAD_REPOSITORY 
+  PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST 
+  PK_STATUS_ENUM_DOWNLOAD_FILELIST 
+  PK_STATUS_ENUM_DOWNLOAD_CHANGELOG 
+  PK_STATUS_ENUM_DOWNLOAD_GROUP 
+  PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO 
+
+  );
+
+use constant {
+  FILTER_BASENAME => "basename",
+  FILTER_DEVELOPMENT => "devel",
+  FILTER_FREE => "free",
+  FILTER_GUI => "gui",
+  FILTER_INSTALLED => "installed",
+  FILTER_NEWEST => "newest",
+  FILTER_NONE => "none",
+  FILTER_NOT_BASENAME => "~basename",
+  FILTER_NOT_DEVELOPMENT => "~devel",
+  FILTER_NOT_FREE => "~free",
+  FILTER_NOT_GUI => "~gui",
+  FILTER_NOT_INSTALLED => "~installed",
+  FILTER_NOT_NEWEST => "~newest",
+  FILTER_NOT_SUPPORTED => "~supported",
+  FILTER_NOT_VISIBLE => "~visible",
+  FILTER_SUPPORTED => "supported",
+  FILTER_UNKNOWN => "unknown",
+  FILTER_VISIBLE => "visible",
+
+  GROUP_ACCESSIBILITY => "accessibility",
+  GROUP_ACCESSORIES => "accessories",
+  GROUP_ADMIN_TOOLS => "admin-tools",
+  GROUP_COMMUNICATION => "communication",
+  GROUP_DESKTOP_GNOME => "desktop-gnome",
+  GROUP_DESKTOP_KDE => "desktop-kde",
+  GROUP_DESKTOP_OTHER => "desktop-other",
+  GROUP_DESKTOP_XFCE => "desktop-xfce",
+  GROUP_EDUCATION => "education",
+  GROUP_FONTS => "fonts",
+  GROUP_GAMES => "games",
+  GROUP_GRAPHICS => "graphics",
+  GROUP_INTERNET => "internet",
+  GROUP_LEGACY => "legacy",
+  GROUP_LOCALIZATION => "localization",
+  GROUP_MAPS => "maps",
+  GROUP_MULTIMEDIA => "multimedia",
+  GROUP_NETWORK => "network",
+  GROUP_OFFICE => "office",
+  GROUP_OTHER => "other",
+  GROUP_POWER_MANAGEMENT => "power-management",
+  GROUP_PROGRAMMING => "programming",
+  GROUP_PUBLISHING => "publishing",
+  GROUP_REPOS => "repos",
+  GROUP_SECURITY => "security",
+  GROUP_SERVERS => "servers",
+  GROUP_SYSTEM => "system",
+  GROUP_UNKNOWN => "unknown",
+  GROUP_VIRTUALIZATION => "virtualization",
+
+  INFO_AVAILABLE => "available",
+  INFO_BLOCKED => "blocked",
+  INFO_BUGFIX => "bugfix",
+  INFO_CLEANUP => "cleanup",
+  INFO_DOWNLOADING => "downloading",
+  INFO_ENHANCEMENT => "enhancement",
+  INFO_IMPORTANT => "important",
+  INFO_INSTALLED => "installed",
+  INFO_INSTALLING => "installing",
+  INFO_LOW => "low",
+  INFO_NORMAL => "normal",
+  INFO_OBSOLETING => "obsoleting",
+  INFO_REMOVING => "removing",
+  INFO_SECURITY => "security",
+  INFO_UNKNOWN => "unknown",
+  INFO_UPDATING => "updating",
+
+  PK_ERROR_ENUM_UNKNOWN => "unknown",
+  PK_ERROR_ENUM_OOM => "out-of-memory",
+  PK_ERROR_ENUM_NO_CACHE => "no-cache",
+  PK_ERROR_ENUM_NO_NETWORK => "no-network",
+  PK_ERROR_ENUM_NOT_SUPPORTED => "not-supported",
+  PK_ERROR_ENUM_INTERNAL_ERROR => "internal-error",
+  PK_ERROR_ENUM_GPG_FAILURE => "gpg-failure",
+  PK_ERROR_ENUM_FILTER_INVALID => "filter-invalid",
+  PK_ERROR_ENUM_PACKAGE_ID_INVALID => "package-id-invalid",
+  PK_ERROR_ENUM_TRANSACTION_ERROR => "transaction-error",
+  PK_ERROR_ENUM_TRANSACTION_CANCELLED => "transaction-cancelled",
+  PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED => "package-not-installed",
+  PK_ERROR_ENUM_PACKAGE_NOT_FOUND => "package-not-found",
+  PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED => "package-already-installed",
+  PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED => "package-download-failed",
+  PK_ERROR_ENUM_GROUP_NOT_FOUND => "group-not-found",
+  PK_ERROR_ENUM_GROUP_LIST_INVALID => "group-list-invalid",
+  PK_ERROR_ENUM_DEP_RESOLUTION_FAILED => "dep-resolution-failed",
+  PK_ERROR_ENUM_CREATE_THREAD_FAILED => "create-thread-failed",
+  PK_ERROR_ENUM_REPO_NOT_FOUND => "repo-not-found",
+  PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE => "cannot-remove-system-package",
+  PK_ERROR_ENUM_PROCESS_KILL => "process-kill",
+  PK_ERROR_ENUM_FAILED_INITIALIZATION => "failed-initialization",
+  PK_ERROR_ENUM_FAILED_FINALISE => "failed-finalise",
+  PK_ERROR_ENUM_FAILED_CONFIG_PARSING => "failed-config-parsing",
+  PK_ERROR_ENUM_CANNOT_CANCEL => "cannot-cancel",
+  PK_ERROR_ENUM_CANNOT_GET_LOCK => "cannot-get-lock",
+  PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE => "no-packages-to-update",
+  PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG => "cannot-write-repo-config",
+  PK_ERROR_ENUM_LOCAL_INSTALL_FAILED => "local-install-failed",
+  PK_ERROR_ENUM_BAD_GPG_SIGNATURE => "bad-gpg-signature",
+  PK_ERROR_ENUM_MISSING_GPG_SIGNATURE => "missing-gpg-signature",
+  PK_ERROR_ENUM_CANNOT_INSTALL_SOURCE_PACKAGE => "cannot-install-source-package",
+  PK_ERROR_ENUM_REPO_CONFIGURATION_ERROR => "repo-configuration-error",
+  PK_ERROR_ENUM_NO_LICENSE_AGREEMENT => "no-license-agreement",
+  PK_ERROR_ENUM_FILE_CONFLICTS => "file-conflicts",
+  PK_ERROR_ENUM_REPO_NOT_AVAILABLE => "repo-not-available",
+  PK_ERROR_ENUM_INVALID_PACKAGE_FILE => "invalid-package-file",
+  PK_ERROR_ENUM_PACKAGE_INSTALL_BLOCKED => "package-install-blocked",
+
+  PK_RESTART_ENUM_UNKNOWN => "unknown",
+  PK_RESTART_ENUM_NONE => "none",
+  PK_RESTART_ENUM_SYSTEM => "system",
+  PK_RESTART_ENUM_SESSION => "session",
+  PK_RESTART_ENUM_APPLICATION => "application",
+
+  PK_STATUS_ENUM_UNKNOWN => "unknown",
+  PK_STATUS_ENUM_WAIT => "wait",
+  PK_STATUS_ENUM_SETUP => "setup",
+  PK_STATUS_ENUM_RUNNING => "running",
+  PK_STATUS_ENUM_QUERY => "query",
+  PK_STATUS_ENUM_INFO => "info",
+  PK_STATUS_ENUM_REFRESH_CACHE => "refresh-cache",
+  PK_STATUS_ENUM_REMOVE => "remove",
+  PK_STATUS_ENUM_DOWNLOAD => "download",
+  PK_STATUS_ENUM_INSTALL => "install",
+  PK_STATUS_ENUM_UPDATE => "update",
+  PK_STATUS_ENUM_CLEANUP => "cleanup",
+  PK_STATUS_ENUM_OBSOLETE => "obsolete",
+  PK_STATUS_ENUM_DEP_RESOLVE => "dep-resolve",
+  PK_STATUS_ENUM_SIG_CHECK => "sig-check",
+  PK_STATUS_ENUM_ROLLBACK => "rollback",
+  PK_STATUS_ENUM_TEST_COMMIT => "test-commit",
+  PK_STATUS_ENUM_COMMIT => "commit",
+  PK_STATUS_ENUM_REQUEST => "request",
+  PK_STATUS_ENUM_FINISHED => "finished",
+  PK_STATUS_ENUM_CANCEL => "cancel",
+  PK_STATUS_ENUM_DOWNLOAD_REPOSITORY => "download-repository",
+  PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST => "download-package",
+  PK_STATUS_ENUM_DOWNLOAD_FILELIST => "download-filelist",
+  PK_STATUS_ENUM_DOWNLOAD_CHANGELOG => "download-changelog",
+  PK_STATUS_ENUM_DOWNLOAD_GROUP => "download-group",
+  PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO => "download-updateinfo",
+
+
+};
+
+1;
diff --git a/backends/urpmi/helpers/perl_packagekit/prints.pm b/backends/urpmi/helpers/perl_packagekit/prints.pm
new file mode 100644
index 0000000..7411ca9
--- /dev/null
+++ b/backends/urpmi/helpers/perl_packagekit/prints.pm
@@ -0,0 +1,95 @@
+package perl_packagekit::prints;
+
+use Exporter;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+  pk_print_package
+  pk_print_status
+  pk_print_details
+  pk_print_files
+  pk_print_update_detail
+  pk_print_require_restart
+  pk_print_error
+  pk_print_percentage
+  pk_print_sub_percentage
+  );
+
+sub pk_print_package {
+  # send 'package' signal
+  # @param info: the enumerated INFO_* string
+  # @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora
+  # @param summary: The package Summary
+  my ($info, $id, $summary) = @_;
+  printf("package\t%s\t%s\t%s\n", $info, $id, $summary);
+}
+
+sub pk_print_status {
+  # send 'status' signal
+  # @param state: STATUS_*
+  my ($status) = @_;
+  printf("status\t%s\n", $status);
+}
+
+sub pk_print_details {
+  # Send 'details' signal
+  # @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora
+  # @param license: The license of the package
+  # @param group: The enumerated group
+  # @param desc: The multi line package description
+  # @param url: The upstream project homepage
+  # @param bytes: The size of the package, in bytes
+  my ($id, $license, $group, $desc, $url, $bytes) = @_;
+  printf("details\t%s\t%s\t%s\t%s\t%s\t%ld\n", $id, $license, $group, $desc, $url, $bytes);
+}
+
+sub pk_print_files {
+  # Send 'files' signal
+  # @param file_list: List of the files in the package, separated by ';'
+  my ($id, $file_list) = @_;
+  printf("files\t%s\t%s\n", $id, $file_list);
+}
+    
+sub pk_print_update_detail {
+  # Send 'updatedetail' signal
+  # @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora
+  # @param updates:
+  # @param obsoletes:
+  # @param vendor_url:
+  # @param bugzilla_url:
+  # @param cve_url:
+  # @param restart:
+  # @param update_text:
+  my ($id, $updates, $obsoletes, $vendor_url, $bugzilla_url, $cve_url, $restart, $update_text) = @_;
+  printf("updatedetail\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $id, $updates, $obsoletes, $vendor_url, $bugzilla_url, $cve_url, $restart, $update_text);
+}
+    
+sub pk_print_require_restart {
+  # Send 'requirerestart' signal
+  # @param restart_type: RESTART_SYSTEM, RESTART_APPLICATION,RESTART_SESSION
+  # @param details: Optional details about the restart
+  my ($restart_type, $details) = @_;
+  printf("requirerestart\t%s\t%s\n", $restart_type, $details);
+}
+    
+sub pk_print_error {
+  # send 'error'
+  # @param err: Error Type ERROR_*
+  # @param description: Error description
+  # @param exit: exit application with rc=1, if true
+  my ($err, $description) = @_;
+  printf("error\t%s\t%s\n", $err, $description);
+  exit if($exit);
+}
+
+sub pk_print_percentage {
+  my ($percentage) = @_;
+  printf("percentage\t%i\n", $percentage);
+}
+
+sub pk_print_sub_percentage {
+  my ($sub_percentage) = @_;
+  printf("subpercentage\t%i\n", $sub_percentage);
+}
+
+1;
diff --git a/backends/urpmi/helpers/urpmi_backend/Makefile.am b/backends/urpmi/helpers/urpmi_backend/Makefile.am
new file mode 100644
index 0000000..3eb8280
--- /dev/null
+++ b/backends/urpmi/helpers/urpmi_backend/Makefile.am
@@ -0,0 +1,15 @@
+helperdir = $(datadir)/PackageKit/helpers/urpmi/urpmi_backend/
+
+NULL =
+
+dist_helper_DATA = 						\
+	actions.pm									\
+	filters.pm									\
+	groups.pm										\
+	open_db.pm									\
+	tools.pm										\
+	$(NULL)
+
+clean-local :
+	rm -f *~
+
diff --git a/backends/urpmi/helpers/urpmi_backend/actions.pm b/backends/urpmi/helpers/urpmi_backend/actions.pm
new file mode 100644
index 0000000..f6033a0
--- /dev/null
+++ b/backends/urpmi/helpers/urpmi_backend/actions.pm
@@ -0,0 +1,313 @@
+package urpmi_backend::actions;
+
+use strict;
+
+use urpm;
+use urpm::args;
+use urpm::msg;
+use urpm::main_loop;
+use urpm::lock;
+use urpmi_backend::tools;
+use urpmi_backend::open_db;
+use MDK::Common;
+use perl_packagekit::enums;
+use perl_packagekit::prints;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+  perform_installation 
+  perform_file_search 
+  perform_requires_search
+);
+
+sub perform_installation {
+  my ($urpm, $requested, %options) = @_;
+  my $state = {};
+  my $restart;
+  my $no_remove = 0;
+
+  pk_print_status(PK_STATUS_ENUM_WAIT);
+
+  # Here we lock urpmi & rpm databases
+  # In third argument we can specified if the script must wait if urpmi or rpm
+  # databases are already locked
+  my $lock = urpm::lock::urpmi_db($urpm, undef, wait => 0);
+  my $rpm_lock = urpm::lock::rpm_db($urpm, 'exclusive');
+
+  pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
+
+  $restart = urpm::select::resolve_dependencies($urpm, $state, $requested, auto_select => $options{auto_select});
+  my %selected = %{$state->{selected} || {}};
+
+  print "Dependencies = \n\t";
+  print join("\n\t", map(@{$urpm->{depslist}}[$_]->name, keys %selected)), "\n";
+
+  # Here we have packages which cannot be installed because of dependencies
+  my @unselected_uninstalled = @{$state->{unselected_uninstalled} || []};
+  if(@unselected_uninstalled) {
+    my $list = join "\n", map { $_->name . '-' . $_->version . '-' . $_->release  } @unselected_uninstalled;
+  }
+  # Fix me !
+  # Display warning (With pk enum?) which warning the user
+  # that the following packages can't be installed because they depend
+  # on packages that are older than the installed ones (copy/paste from
+  # the diplayed message in urpmi)
+
+  # Here we have packages which cannot be installed
+  my @ask_unselect = urpm::select::unselected_packages($urpm, $state);
+  if (@ask_unselect) {
+    my $list = urpm::select::translate_why_unselected($urpm, $state, @ask_unselect);
+  }
+  # Fix me !
+  # Display warning (With pk enum?) which warning the user
+  # that the following packages can't be installed (copy/paste from
+  # the diplayed message in urpmi)
+
+  my @ask_remove = urpm::select::removed_packages($urpm, $state);
+  if(@ask_remove) {
+    my $db = urpm::db_open_or_die($urpm, $urpm->{root});
+    urpm::select::find_removed_from_basesystem($urpm, $db, $state, sub {
+        my $urpm = shift @_;
+        foreach (@_) {
+          # Fix me 
+          # Someting like that. With a clean pk error enum.
+          # printf ("removing package %s will break your system", $_);
+        }
+        @_ and $no_remove = 1;
+      });
+    my $list = urpm::select::translate_why_removed($urpm, $state, @ask_remove);
+    if($no_remove) {
+      # Fix me
+      # Display message to prevent that the installation cannot continue because some
+      # packages has to be removed for others to be upgraded.
+      exit 0;
+    }
+    # Else, it's ok.
+    # Here we can display $list, which describe packages which has to be removed for
+    # others to be upgraded.
+    printf("Following package(s) will be removed for others to be upgraded:\n%s\n", $list);
+  }
+
+  # sorted by medium for format_selected_packages
+  my @to_install = @{$urpm->{depslist}}[sort { $a <=> $b } keys %{$state->{selected}}]; 
+  my ($src, $binary) = partition { $_->arch eq 'src' } @to_install;
+  # With packagekit, we will never install src packages.
+  @to_install = @$binary;
+
+  print "\@to_install debug : \n\t";
+  print join("\n\t", map(urpm_name($_), @to_install)), "\n";
+
+  my $nb_to_install = $#to_install + 1;
+  my $percentage = 0;
+
+  $urpm->{nb_install} = @to_install;
+  # For debug issue, we will display sizes
+  my ($size, $filesize) = $urpm->selected_size_filesize($state);
+  printf("%s of additional disk space will be used.\n", formatXiB($size));
+  printf("%s of packages will be retrieved.\n", formatXiB($filesize));
+
+  my $callback_inst = sub {
+    my ($urpm, $type, $id, $subtype, $amount, $total) = @_;
+    my $pkg = defined $id ? $urpm->{depslist}[$id] : undef;
+    if ($subtype eq 'start') {
+      if ($type eq 'trans') {
+        print "Preparing packages installation ...\n";
+      } 
+      elsif (defined $pkg) {
+        printf("Installing package %s ...\n", $pkg->name);
+        # Need improvements, we can display package number, total number of packages to be installed, 
+        # and some others informations. See rpmdrake/pkg.pm source code for more information.
+      }
+    } 
+    elsif ($subtype eq 'progress') {
+      # Progress bar ? 
+      # See Rpmdrake/pkg.pm for more information.
+      # $total, $amount/$total
+      print "($type) Progress : total = ", $total, " ; amount/total = ", $amount/$total, " ; amount = ", $amount, "\n";
+      if($type eq "inst") {
+        pk_print_percentage($percentage + ($amount/$total)*(100/$nb_to_install));
+        if(($amount/$total) == 1) {
+          $percentage = $percentage + ($amount/$total)*(100/$nb_to_install);
+        }
+      }
+    }
+  };
+
+  # Now, the script will call the urpmi main loop to make installation
+  my $exit_code = urpm::main_loop::run($urpm, $state, undef, \@ask_unselect, $requested, {
+      inst => $callback_inst,
+      trans => $callback_inst,
+      trans_log => sub {
+        my ($mode, $file, $percent, $total, $eta, $speed) = @_;
+        # Transfer log need to be improved.
+        if($mode eq "progress") {
+          pk_print_status(PK_STATUS_ENUM_DOWNLOAD);
+        }
+        print "Install current mode = ", $mode, "\n";
+      },
+      bad_signature => sub {
+        # Here we display a message (with PK enum) to warn the user
+        # about a bad signature, then we exit
+        exit 1;
+      },
+      ask_yes_or_no => sub {
+        # Return 1 = Return Yes
+        return 1;
+      },
+      need_restart => sub {
+        my ($need_restart_formatted) = @_;
+        print "$_\n" foreach values %$need_restart_formatted;
+      },
+      message => sub {
+        my ($_title, $msg) = @_; # graphical title
+        print "message = ", $msg;
+        # What's this callback ? message ?
+        # Fix me : take a look on it.
+      },
+      completed => sub {
+        undef $lock;
+        undef $rpm_lock;
+      },
+      post_download => sub {
+        # At this point, we need to refuse cancel action
+        # to the user (use of AllowCancel instruction of Packagekit)
+      },
+      # I need to work more on main_loop callbacks in order to display
+      # personnal messages, and not using default urpmi display which is
+      # too ugly :s
+      # For help, look at the source code of Rpmdrake, and particulary see
+      # the file /usr/lib/perl5/vendor_perl/5.10.0/Rpmdrake/pkg.pm when 
+      # it calls the main_loop::run
+    }
+  );
+}
+
+sub perform_file_search {
+  my ($urpm, $requested, $search_term, %options) = @_;
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+
+  my $xml_info = 'files';
+  my %result_hash;
+
+  # - For each medium, we browse the xml info file,
+  # while looking for files which matched with the
+  # search term given in argument. We store results 
+  # in a hash.
+  foreach my $medium (urpm::media::non_ignored_media($urpm)) {
+    my $xml_info_file = urpm::media::any_xml_info($urpm, $medium, ( "files", "summary" ), undef, undef);
+    $xml_info_file or next;
+    require urpm::xml_info;
+    require urpm::xml_info_pkg;
+    my $F = urpm::xml_info::open_lzma($xml_info_file);
+    my $fn;
+    local $_;
+    while (<$F>) {
+      if (m!^<!) {
+        ($fn) = /fn="(.*)"/;
+      } 
+      elsif ( (!$options{'fuzzy'} && $_ =~ /^$search_term$/)
+        || ($options{'fuzzy'} && $_ =~ /$search_term/) ) {
+        # Fix me : Replace with pk error enum.
+        # $fn or $urpm->{fatal}("fast algorithm is broken, please report a bug");
+        my $pkg = urpm::xml_info_pkg->new({ fn => $fn });
+        $result_hash{$pkg->name} = $pkg;
+      }
+    }
+  }
+
+  # - In order to get package summaries, we need to
+  # use the search package method from perl-URPM 
+  # which return Package type on which we can call
+  # methods to create the printing output.
+  # (It's about the same code as search-name.pl)
+  my @names = keys %result_hash;
+
+  urpm::select::search_packages($urpm, $requested, \@names, 
+    fuzzy => 0,
+    caseinsensitive => 0,
+    all => 0,);
+}
+
+sub perform_requires_search {
+
+  my ($urpm, $pkg, $recursive_option) = @_;
+
+  my (@properties, %requires, %properties, $dep);
+  my %requested;
+  urpm::select::search_packages($urpm, 
+    \%requested, [ $pkg->name ], 
+    use_provides => 0,
+    fuzzy => 0,
+    all => 0
+  );
+  @properties = keys %requested;
+  my $state = {};
+
+  foreach my $pkg (@{$urpm->{depslist}}) {
+    foreach ($pkg->requires_nosense) {
+      $requires{$_}{$pkg->id} = undef;
+    }
+  }
+
+  while (defined ($dep = shift @properties)) {
+    my $packages = $urpm->find_candidate_packages($dep);
+    foreach (values %$packages) {
+      my ($best_requested, $best);
+      foreach (@$_) {
+        if ($best_requested || exists $requested{$_->id}) {
+          if ($best_requested && $best_requested != $_) {
+            $_->compare_pkg($best_requested) > 0 and $best_requested = $_;
+          } else {
+            $best_requested = $_;
+          }
+        } elsif ($best && $best != $_) {
+          $_->compare_pkg($best) > 0 and $best = $_;
+        } else {
+          $best = $_;
+        }
+      }
+
+      my $pkg = $best_requested || $best or next;
+      exists $state->{selected}{$pkg->id} and next;
+      $state->{selected}{$pkg->id} = undef;
+
+      next if !$requested{$dep} && !$recursive_option;
+
+      #- for all provides of package, look up what is requiring them.
+      foreach ($pkg->provides) {
+        if (my ($n, $s) = /^([^\s\[]*)(?:\[\*\])?\[?([^\s\]]*\s*[^\s\]]*)/) {
+          if (my @l = grep { $_ ne $pkg->name } map { $_->name } $urpm->packages_providing($n)) {
+            #- If another package provides this requirement,
+            #- then don't bother finding stuff that needs it as it will be invalid
+            # $urpm->{log}(sprintf "skipping package(s) requiring %s via %s, since %s is also provided by %s", $pkg->name, $n, $n, join(' ', @l));
+            next;
+          }
+
+          foreach (map { $urpm->{depslist}[$_] }
+            grep { ! exists $state->{selected}{$_} && ! exists $properties{$_} }
+            keys %{$requires{$n} || {}}) {
+            if (grep { URPM::ranges_overlap("$n $s", $_) } $_->requires) {
+              push @properties, $_->id;
+              # $urpm->{debug} and $urpm->{debug}(sprintf "adding package %s (requires %s%s)", $_->name, $pkg->name, $n eq $pkg->name ? '' : " via $n");
+              $properties{$_->id} = undef;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  my @depslist = @{$urpm->{depslist}};
+  my @requires = ();
+  foreach(@depslist) {
+    my $pkgid = $_->id;
+    if(grep(/^$pkgid$/, keys %{$state->{selected}})) {
+      push @requires, $_;
+    }
+  }
+
+  @requires;
+
+}
diff --git a/backends/urpmi/helpers/urpmi_backend/filters.pm b/backends/urpmi/helpers/urpmi_backend/filters.pm
new file mode 100644
index 0000000..2c2f13a
--- /dev/null
+++ b/backends/urpmi/helpers/urpmi_backend/filters.pm
@@ -0,0 +1,78 @@
+package urpmi_backend::filters;
+
+use MDK::Common;
+use perl_packagekit::enums;
+use urpmi_backend::tools;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(filter);
+
+my @gui_pkgs = map { chomp; $_ } cat_('/usr/share/rpmdrake/gui.lst');
+
+sub filter {
+  my ($pkg, $filters, $enabled_filters) = @_;
+
+  my %e_filters = %{$enabled_filters};
+
+  foreach my $filter (@{$filters}) {
+    if($filter eq FILTER_INSTALLED || $filter eq FILTER_NOT_INSTALLED) {
+      if($e_filters{FILTER_INSTALLED}) {
+        return 0 if not filter_installed($pkg, $filter);
+      }
+    }
+    elsif($filter eq FILTER_DEVELOPMENT || $filter eq FILTER_NOT_DEVELOPMENT) {
+      if($e_filters{FILTER_DEVELOPMENT}) {
+        return 0 if not filter_devel($pkg, $filter);
+      }
+    }
+    elsif($filter eq FILTER_GUI || $filter eq FILTER_NOT_GUI) {
+      if($e_filters{FILTER_GUI}) {
+        return 0 if not filter_gui($pkg, $filter);
+      }
+    }
+  }
+  return 1;
+}
+
+sub filter_installed {
+  my ($pkg, $filter) = @_;
+  my $installed;
+  $installed = 1 if(find_installed_version($pkg));
+  if($filter eq FILTER_INSTALLED && $installed) {
+    return 1;
+  }
+  if($filter eq FILTER_NOT_INSTALLED && !$installed) {
+    return 1;
+  }
+  return 0;
+}
+
+sub filter_devel {
+  my ($pkg, $filter) = @_;
+  my $pkgname = $pkg->name;
+  my $devel = ($pkgname =~ /-devel$/);
+  if($filter eq FILTER_DEVELOPMENT && $devel) {
+    return 1;
+  }
+  if($filter eq FILTER_NOT_DEVELOPMENT && !$devel) {
+    return 1;
+  }
+  return 0;
+}
+
+sub filter_gui {
+  my ($pkg, $filter) = @_;
+  my $pkgname = $pkg->name;
+  my $gui = member($pkgname, @gui_pkgs);
+
+  if($filter eq FILTER_NOT_GUI && !$gui) {
+    return 1;
+  }
+  if($filter eq FILTER_GUI && $gui) {
+    return 1;
+  }
+  return 0;
+}
+
+1;
diff --git a/backends/urpmi/helpers/urpmi_backend/groups.pm b/backends/urpmi/helpers/urpmi_backend/groups.pm
new file mode 100644
index 0000000..d377ab2
--- /dev/null
+++ b/backends/urpmi/helpers/urpmi_backend/groups.pm
@@ -0,0 +1,129 @@
+package urpmi_backend::groups;
+
+use strict;
+
+use perl_packagekit::enums;
+use Exporter;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+  MDV_GROUPS
+  get_mdv_groups 
+  get_pk_group 
+  package_belongs_to_pk_group
+);
+
+use constant MDV_GROUPS => {
+    'Accessibility' => GROUP_ACCESSIBILITY,
+    'Archiving/Backup' => GROUP_OTHER,
+    'Archiving/Cd burning' => GROUP_MULTIMEDIA,
+    'Archiving/Compression' => GROUP_ACCESSORIES,
+    'Archiving/Other' => GROUP_OTHER,
+    'Books/Computer books' => GROUP_OTHER,
+    'Books/Faqs' => GROUP_OTHER,
+    'Books/Howtos' => GROUP_OTHER,
+    'Books/Literature' => GROUP_OTHER,
+    'Books/Other' => GROUP_OTHER,
+    'Communications' => GROUP_COMMUNICATION,
+    'Databases' => GROUP_PROGRAMMING,
+    'Development/C' => GROUP_PROGRAMMING,
+    'Development/C++' => GROUP_PROGRAMMING,
+    'Development/Databases' => GROUP_PROGRAMMING,
+    'Development/GNOME and GTK+' => GROUP_PROGRAMMING,
+    'Development/Java' => GROUP_PROGRAMMING,
+    'Development/KDE and Qt' => GROUP_PROGRAMMING,
+    'Development/Kernel' => GROUP_PROGRAMMING,
+    'Development/Other' => GROUP_PROGRAMMING,
+    'Development/Perl' => GROUP_PROGRAMMING,
+    'Development/PHP' => GROUP_PROGRAMMING,
+    'Development/Python' => GROUP_PROGRAMMING,
+    'Development/Ruby' => GROUP_PROGRAMMING,
+    'Development/X11' => GROUP_PROGRAMMING,
+    'Editors' => GROUP_ACCESSORIES,
+    'Education' => GROUP_EDUCATION,
+    'Emulators' => GROUP_VIRTUALIZATION,
+    'File tools' => GROUP_ACCESSORIES,
+    'Games/Adventure' => GROUP_GAMES,
+    'Games/Arcade' => GROUP_GAMES,
+    'Games/Boards' => GROUP_GAMES,
+    'Games/Cards' => GROUP_GAMES,
+    'Games/Other' => GROUP_GAMES,
+    'Games/Puzzles' => GROUP_GAMES,
+    'Games/Sports' => GROUP_GAMES,
+    'Games/Strategy' => GROUP_GAMES,
+    'Graphical desktop/Enlightenment' => GROUP_DESKTOP_OTHER,
+    'Graphical desktop/FVWM based' => GROUP_DESKTOP_OTHER,
+    'Graphical desktop/GNOME' => GROUP_DESKTOP_GNOME,
+    'Graphical desktop/Icewm' => GROUP_DESKTOP_OTHER,
+    'Graphical desktop/KDE' => GROUP_DESKTOP_KDE,
+    'Graphical desktop/Other' => GROUP_DESKTOP_OTHER,
+    'Graphical desktop/Sawfish' => GROUP_DESKTOP_OTHER,
+    'Graphical desktop/WindowMaker' => GROUP_DESKTOP_OTHER,
+    'Graphical desktop/Xfce' => GROUP_DESKTOP_XFCE,
+    'Graphics' => GROUP_GRAPHICS,
+    'Monitoring' => GROUP_NETWORK,
+    'Networking/Chat' => GROUP_INTERNET,
+    'Networking/File transfer' =>  GROUP_INTERNET,
+    'Networking/IRC' => GROUP_INTERNET,
+    'Networking/Instant messaging' => GROUP_INTERNET,
+    'Networking/Mail' => GROUP_INTERNET,
+    'Networking/News' => GROUP_INTERNET,
+    'Networking/Other' => GROUP_INTERNET,
+    'Networking/Remote access' => GROUP_INTERNET,
+    'Networking/WWW' => GROUP_INTERNET,
+    'Office' => GROUP_OFFICE,
+    'Publishing' => GROUP_PUBLISHING,
+    'Sciences/Astronomy' => GROUP_OTHER,
+    'Sciences/Biology' => GROUP_OTHER,
+    'Sciences/Chemistry' => GROUP_OTHER,
+    'Sciences/Computer science' => GROUP_OTHER,
+    'Sciences/Geosciences' => GROUP_OTHER,
+    'Sciences/Mathematics' => GROUP_OTHER,
+    'Sciences/Other' => GROUP_OTHER,
+    'Sciences/Physics' => GROUP_OTHER,
+    'Shells' => GROUP_SYSTEM,
+    'Sound' => GROUP_MULTIMEDIA,
+    'System/Base' => GROUP_SYSTEM,
+    'System/Cluster' => GROUP_SYSTEM,
+    'System/Configuration/Boot and Init' => GROUP_SYSTEM,
+    'System/Configuration/Hardware' => GROUP_SYSTEM,
+    'System/Configuration/Networking' => GROUP_SYSTEM,
+    'System/Configuration/Other' => GROUP_SYSTEM,
+    'System/Configuration/Packaging' => GROUP_SYSTEM,
+    'System/Configuration/Printing' => GROUP_SYSTEM,
+    'System/Fonts/Console' => GROUP_FONTS,
+    'System/Fonts/True type' => GROUP_FONTS,
+    'System/Fonts/Type1' => GROUP_FONTS,
+    'System/Fonts/X11 bitmap' => GROUP_FONTS,
+    'System/Internationalization' => GROUP_LOCALIZATION,
+    'System/Kernel and hardware' => GROUP_SYSTEM,
+    'System/Libraries' => GROUP_SYSTEM,
+    'System/Printing' => GROUP_SYSTEM,
+    'System/Servers' => GROUP_SYSTEM,
+    'System/X11' => GROUP_SYSTEM,
+    'Terminals' => GROUP_SYSTEM,
+    'Text tools' => GROUP_ACCESSORIES,
+    'Toys' => GROUP_GAMES,
+    'Video' => GROUP_MULTIMEDIA
+  };
+
+sub get_mdv_groups {
+  my ($pk_group) = @_;
+  my @groups = ();
+  foreach(keys %{(MDV_GROUPS)}) {
+    if(%{(MDV_GROUPS)}->{$_} eq $pk_group) {
+      push @groups, $_;
+    }
+  }
+  return @groups;
+}
+
+sub package_belongs_to_pk_group {
+  my ($pkg, $pk_group) = @_;
+  my @groups = get_mdv_groups($pk_group);
+  my $pkg_group = $pkg->group;
+  return grep(/$pkg_group/, @groups);
+}
+
+1;
+
diff --git a/backends/urpmi/helpers/urpmi_backend/open_db.pm b/backends/urpmi/helpers/urpmi_backend/open_db.pm
new file mode 100644
index 0000000..956774e
--- /dev/null
+++ b/backends/urpmi/helpers/urpmi_backend/open_db.pm
@@ -0,0 +1,83 @@
+package urpmi_backend::open_db;
+
+use strict;
+
+use MDK::Common;
+
+use urpm;
+use urpm::media;
+use urpm::select;
+
+use URPM;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(fast_open_urpmi_db open_urpmi_db open_rpm_db);
+
+# do not pay the urpm::media::configure() heavy cost:
+sub fast_open_urpmi_db() {
+    my $urpm = urpm->new;
+    $urpm->get_global_options;
+    my $error_happened;
+    #$urpm->{options}{wait_lock} = $::rpmdrake_options{'wait-lock'};
+    #$urpm->{options}{'verify-rpm'} = !$::rpmdrake_options{'no-verify-rpm'} if defined $::rpmdrake_options{'no-verify-rpm'};
+    #$urpm->{options}{auto} = $::rpmdrake_options{auto} if defined $::rpmdrake_options{auto};
+    #urpm::set_files($urpm, $::rpmdrake_options{'urpmi-root'}[0]) if $::rpmdrake_options{'urpmi-root'}[0];
+    #urpm::args::set_root($urpm, $::rpmdrake_options{'rpm-root'}[0]) if $::rpmdrake_options{'rpm-root'}[0];
+
+    #$urpm::args::rpmdrake_options{justdb} = $::rpmdrake_options{justdb};
+
+    #$urpm->{fatal} = sub {
+    #    $error_happened = 1;
+    #    interactive_msg(N("Fatal error"),
+    #                     N("A fatal error occurred: %s.", $_[1]));
+    #};
+
+    urpm::media::read_config($urpm);
+    # FIXME: seems uneeded with newer urpmi:
+    #if ($error_happened) {
+    #    touch('/etc/urpmi/urpmi.cfg');
+    #    exec('edit-urpm-sources.pl');
+    #}
+    $urpm;
+}
+
+sub open_urpmi_db {
+    my (%urpmi_options) = @_;
+    my $urpm = fast_open_urpmi_db();
+    my $media = ''; # See Rpmdrake source code for more information.
+
+    my $searchmedia = $urpmi_options{update} ? undef : join(',', get_inactive_backport_media($urpm));
+    $urpm->{lock} = urpm::lock::urpmi_db($urpm, undef, wait => $urpm->{options}{wait_lock});
+    my $previous = ''; # Same as $media above.
+    urpm::select::set_priority_upgrade_option($urpm, (ref $previous ? join(',', @$previous) : ()));
+    urpm::media::configure($urpm, media => $media, if_($searchmedia, searchmedia => $searchmedia), %urpmi_options);
+    $urpm;
+}
+
+sub get_inactive_backport_media {
+    my ($urpm) = @_;
+    map { $_->{name} } grep { $_->{ignore} && $_->{name} =~ /backport/i } @{$urpm->{media}};
+}
+
+sub open_rpm_db {
+#    my ($o_force) = @_;
+#    my $host;
+#    log::explanations("opening the RPM database");
+#    if ($::rpmdrake_options{parallel} && ((undef, $host) = @{$::rpmdrake_options{parallel}})) {
+#        state $done;
+#        my $dblocation = "/var/cache/urpmi/distantdb/$host";
+#        if (!$done || $o_force) {
+#            print "syncing db from $host to $dblocation...";
+#            mkdir_p "$dblocation/var/lib/rpm";
+#            system "rsync -Sauz -e ssh $host:/var/lib/rpm/ $dblocation/var/lib/rpm";
+#            $? == 0 or die "Couldn't sync db from $host to $dblocation";
+#            $done = 1;
+#            print "done.\n";
+#        }
+#        URPM::DB::open($dblocation) or die "Couldn't open RPM DB";
+#    } else {
+        URPM::DB::open() or die "Couldn't open RPM DB";
+#    }
+}
+
diff --git a/backends/urpmi/helpers/urpmi_backend/tools.pm b/backends/urpmi/helpers/urpmi_backend/tools.pm
new file mode 100644
index 0000000..8492766
--- /dev/null
+++ b/backends/urpmi/helpers/urpmi_backend/tools.pm
@@ -0,0 +1,125 @@
+package urpmi_backend::tools;
+
+use strict;
+
+use URPM;
+use urpmi_backend::open_db;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+  get_update_medias 
+  rpm_description 
+  urpm_name 
+  find_installed_version 
+  get_package_id 
+  ensure_utf8 
+  pkg2medium 
+  fullname_to_package_id
+  get_package_by_package_id
+  package_version_is_installed
+  get_package_upgrade
+);
+
+# Note that all of these methods are extracted from the rpmdrake source code.
+
+sub get_update_medias {
+  my ($urpm) = @_;
+  grep { !$_->{ignore} && $_->{update} } @{$urpm->{media}};
+}
+
+sub rpm_description {
+    my ($description) = @_;
+    ensure_utf8($description);
+    my ($t, $tmp);
+    foreach (split "\n", $description) {
+  s/^\s*//;
+        if (/^$/ || /^\s*(-|\*|\+|o)\s/) {
+            $t || $tmp and $t .= "$tmp\n";
+            $tmp = $_;
+        } else {
+            $tmp = ($tmp ? "$tmp " : ($t && "\n") . $tmp) . $_;
+        }
+    }
+    "$t$tmp\n";
+}
+
+sub urpm_name {
+    return '?-?-?.?' unless ref $_[0];
+    my ($name, $version, $release, $arch) = $_[0]->fullname;
+    "$name-$version-$release.$arch";
+}
+
+# from rpmtools, #37482:
+sub ensure_utf8 {
+    my ($s) = @_;
+    require Encode;
+    Encode::_utf8_on($s); #- this is done on the copy
+    if (!Encode::is_utf8($s, 1)) {
+        Encode::_utf8_off($_[0]);
+        Encode::from_to($_[0], 'iso-8859-15', 'utf8'); # most probable
+    }
+    Encode::_utf8_on($_[0]); #- now we know it is valid utf8
+    $_[0];
+}
+
+sub find_installed_version {
+  my ($p) = @_;
+  my @version;
+  URPM::DB::open()->traverse_tag('name', [ $p->name ], sub { push @version, $_[0]->version . '-' . $_[0]->release });
+  @version ? join(',', sort @version) : "";
+}
+
+sub get_package_id {
+  my ($pkg) = @_;
+  return $pkg->name.";".$pkg->version."-".$pkg->release.";".$pkg->arch.";mandriva";
+}
+
+sub pkg2medium {
+  my ($p, $urpm) = @_;
+  return if !ref $p;
+  return { name => N("None (installed)") } if !$p->id; # if installed
+  URPM::pkg2media($urpm->{media}, $p) || undef;
+}
+
+sub fullname_to_package_id {
+  # fullname, ie 'xeyes-1.0.1-5mdv2008.1.i586'
+  my ($pkg_string) = @_;
+  chomp($pkg_string);
+  $pkg_string =~ /^(.*)-([^-]*)-([^-]*)\.([^\.]*)$/;
+  my %pkg = (
+    name => $1,
+    version => $2,
+    release => $3,
+    arch => $4
+  );
+  return $pkg{name}.";".$pkg{version}."-".$pkg{release}.";".$pkg{arch}.";mandriva";
+}
+
+sub get_package_by_package_id {
+  my ($urpm, $package_id) = @_;
+  my @depslist = @{$urpm->{depslist}};
+  foreach(@depslist) {
+    if(get_package_id($_) eq $package_id) {
+      return $_;
+    }
+  }
+}
+
+sub package_version_is_installed {
+  my ($pkg) = @_;
+  return $pkg->version."-".$pkg->release eq find_installed_version($pkg);
+}
+
+sub get_package_upgrade {
+  my ($urpm, $pkg) = @_;
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+  my @depslist = @{$urpm->{depslist}};
+  my $pkgname = $pkg->name;
+  foreach(@depslist) {
+    if($_->name =~ /^$pkgname$/ && $_->flag_upgrade) {
+      return $_;
+    }
+  }
+}
commit fb4b62a31645d5f49cad044c252c3eb1fa802993
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue May 27 13:36:59 2008 +0100

    add some notes on howto do the release, as Robin is going to do the next one

diff --git a/RELEASE b/RELEASE
new file mode 100644
index 0000000..bd0cc2e
--- /dev/null
+++ b/RELEASE
@@ -0,0 +1,50 @@
+PackageKit Release Notes
+
+1. Write NEWS entries for PackageKit and gnome-packagekit in the same
+   format as usual. Ignore any trivial commits.
+
+$git-shortlog GNOME_PACKAGEKIT_0_2_1.. | grep -v trivial > NEWS.new
+
+2. Add download date to docs/html/pk-download.html, save file.
+
+3. Update library version if new ABI in configure.ac and change DEVELOPMENT_RELEASE if needed
+
+4. Commit changes in PackageKit git:
+
+$git commit -a -m "Release version 0.2.2"
+$git tag -a -f -m "Release 0.2.2" PACKAGEKIT_0_2_2
+$git push --tags
+$git push
+
+5. Commit changes in gnome-packagekit git:
+
+$git commit -a -m "Release version 0.2.2"
+$git-tag GNOME_PACKAGEKIT_0_2_2
+$git push --tags
+$git push
+
+6. Upload both tarballs to:
+
+$scp *.tar.gz packagekit.org/srv/www/html/releases/
+
+7. Do post release version bump in configure.ac
+
+8. Commit changes in both projects:
+
+$git commit -a -m "post release version bump"
+$git push
+
+9. Send an email to packagekit at lists.freedesktop.org
+
+=================================================
+Subject: PackageKit and gnome-packagekit 0.2.2 released!
+
+Today I released PackageKit and gnome-packagekit 0.2.2.
+
+PackageKit release notes: http://gitweb.freedesktop.org/?p=packagekit.git;a=blob;f=NEWS
+gnome-packagekit release notes: http://gitweb.freedesktop.org/?p=users/hughsient/gnome-packagekit.git;a=blob;f=NEWS
+
+Tarballs available here: http://people.freedesktop.org/~hughsient/releases/
+Thanks to all those who made this possible.
+=================================================
+
commit 3c0ca2ffccf56a093401969483d554dd1f6d5359
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue May 27 11:21:11 2008 +0200

    * Added skel for urpmi backend integration/implementation (Part 2)

diff --git a/backends/Makefile.am b/backends/Makefile.am
index a3c6fb1..20279b3 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -28,6 +28,10 @@ if BACKEND_TYPE_SMART
 SUBDIRS += smart
 endif
 
+if BACKEND_TYPE_URPMI
+SUBDIRS += urpmi
+endif
+
 if BACKEND_TYPE_YUM
 SUBDIRS += yum
 endif
diff --git a/configure.ac b/configure.ac
index 01e5867..5611aa8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -230,6 +230,7 @@ AC_ARG_ENABLE(opkg, AS_HELP_STRING([--enable-opkg],[use the OPKG backend]),enabl
 AC_ARG_ENABLE(pisi, AS_HELP_STRING([--enable-pisi],[use the PiSi backend]),enable_pisi=$enableval,enable_pisi=no)
 AC_ARG_ENABLE(poldek, AS_HELP_STRING([--enable-poldek],[use the poldek backend]),enable_poldek=$enableval,enable_poldek=no)
 AC_ARG_ENABLE(smart, AS_HELP_STRING([--enable-smart],[use the SMART backend]),enable_smart=$enableval,enable_smart=no)
+AC_ARG_ENABLE(urpmi, AS_HELP_STRING([--enable-urpmi],[use the URPMI backend]),enable_urpmi=$enableval,enable_urpmi=no)
 AC_ARG_ENABLE(yum, AS_HELP_STRING([--enable-yum],[use the YUM backend]),enable_yum=$enableval,enable_yum=no)
 AC_ARG_ENABLE(yum2, AS_HELP_STRING([--enable-yum2],[use the YUM DBUS backend]),enable_yum2=$enableval,enable_yum2=no)
 AC_ARG_ENABLE(zypp, AS_HELP_STRING([--enable-zypp],[use the Zypp backend]),enable_zypp=$enableval,enable_zypp=no)
@@ -244,6 +245,7 @@ AM_CONDITIONAL(BACKEND_TYPE_OPKG, [test x$enable_opkg = xyes], [using OPKG backe
 AM_CONDITIONAL(BACKEND_TYPE_PISI, [test x$enable_pisi = xyes], [using PiSi backend])
 AM_CONDITIONAL(BACKEND_TYPE_POLDEK, [test x$enable_poldek = xyes], [using poldek backend])
 AM_CONDITIONAL(BACKEND_TYPE_SMART, [test x$enable_smart = xyes], [using SMART backend])
+AM_CONDITIONAL(BACKEND_TYPE_URPMI, [test x$enable_urpmi = xyes], [using URPMI backend])
 AM_CONDITIONAL(BACKEND_TYPE_YUM, [test x$enable_yum = xyes], [using YUM backend])
 AM_CONDITIONAL(BACKEND_TYPE_YUM2, [test x$enable_yum2 = xyes], [using YUM DBUS backend])
 AM_CONDITIONAL(BACKEND_TYPE_ZYPP, [test x$enable_zypp = xyes], [using Zypp backend])
@@ -367,7 +369,7 @@ dnl ---------------------------------------------------------------------------
 AC_ARG_WITH([default_backend],
 	    AS_HELP_STRING([--with-default-backend=<option>],
 			   [Default backend to use
-                           alpm,apt,box,conary,dummy,smart,yum,pisi,zypp,opkg (dummy)]))
+                           alpm,apt,box,conary,dummy,smart,urpmi,yum,pisi,zypp,opkg (dummy)]))
 # default to a sane option for the installed tool
 if test x$with_default_backend = x; then
 	if test -f /usr/bin/yum ; then
@@ -386,6 +388,8 @@ if test x$with_default_backend = x; then
 		with_default_backend=pisi
 	elif test -f /usr/bin/poldek ; then
 		with_default_backend=poldek
+	elif test -f /usr/bin/urpmq ; then
+		with_default_backend=urpmi
 	elif test -f /usr/bin/zypper ; then
 		with_default_backend=zypp
 	else
@@ -468,6 +472,8 @@ backends/smart/Makefile
 backends/smart/helpers/Makefile
 backends/test/Makefile
 backends/test/helpers/Makefile
+backends/urpmi/Makefile
+backends/urpmi/helpers/Makefile
 backends/yum/Makefile
 backends/yum/helpers/Makefile
 backends/yum2/Makefile
@@ -522,6 +528,7 @@ echo "
         PiSi backend:              ${enable_pisi}
         poldek backend:            ${enable_poldek}
         SMART backend:             ${enable_smart}
+        URPMI backend:             ${enable_urpmi}
         YUM backend:               ${enable_yum}
         YUM2 backend:              ${enable_yum2}
         Zypp backend:              ${enable_zypp}
commit 889ed39ffb46ea4d37ac564f172cd32f5fea26ab
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue May 27 11:19:16 2008 +0200

    * Added skel for urpmi backend integration/implementation.

diff --git a/backends/urpmi/.gitignore b/backends/urpmi/.gitignore
new file mode 100644
index 0000000..996fb0d
--- /dev/null
+++ b/backends/urpmi/.gitignore
@@ -0,0 +1,14 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo
+*.loT
+*.o
+*~
+*.gcov
+*.gcda
+*.gcno
+*.out
+
diff --git a/backends/urpmi/Makefile.am b/backends/urpmi/Makefile.am
new file mode 100644
index 0000000..56743a1
--- /dev/null
+++ b/backends/urpmi/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = helpers
+plugindir = $(PK_PLUGIN_DIR)
+plugin_LTLIBRARIES = libpk_backend_urpmi.la
+libpk_backend_urpmi_la_SOURCES = pk-backend-urpmi.c
+libpk_backend_urpmi_la_LIBADD = $(PK_PLUGIN_LIBS)
+libpk_backend_urpmi_la_LDFLAGS = -module -avoid-version
+libpk_backend_urpmi_la_CFLAGS = $(PK_PLUGIN_CFLAGS)
+
+clean-local:
+	rm -f *.gcno
+
diff --git a/backends/urpmi/helpers/.gitignore b/backends/urpmi/helpers/.gitignore
new file mode 100644
index 0000000..2f78cf5
--- /dev/null
+++ b/backends/urpmi/helpers/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+
diff --git a/backends/urpmi/helpers/Makefile.am b/backends/urpmi/helpers/Makefile.am
new file mode 100644
index 0000000..d459cb6
--- /dev/null
+++ b/backends/urpmi/helpers/Makefile.am
@@ -0,0 +1,15 @@
+
+helperdir = $(datadir)/PackageKit/helpers/urpmi
+
+NULL =
+
+dist_helper_DATA = 			\
+	search-name.pl			\
+	$(NULL)
+
+install-data-hook:
+	chmod a+rx $(DESTDIR)$(helperdir)/*.pl
+
+clean-local :
+	rm -f *~
+
diff --git a/backends/urpmi/helpers/search-name.pl b/backends/urpmi/helpers/search-name.pl
new file mode 100755
index 0000000..f4d4c65
--- /dev/null
+++ b/backends/urpmi/helpers/search-name.pl
@@ -0,0 +1,3 @@
+#!/usr/bin/perl
+
+print "package\tinstalled\ttestpkg;3.1-1mdv2009.0;i586;mandriva\tHere is the summary\n";
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
new file mode 100644
index 0000000..60501fa
--- /dev/null
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <pk-backend.h>
+#include <pk-backend-spawn.h>
+#include <pk-package-ids.h>
+
+static PkBackendSpawn *spawn;
+
+/**
+ * backend_initialize:
+ * This should only be run once per backend load, i.e. not every transaction
+ */
+static void
+backend_initialize (PkBackend *backend)
+{
+	pk_debug ("FILTER: initialize");
+	spawn = pk_backend_spawn_new ();
+	pk_backend_spawn_set_name (spawn, "urpmi");
+}
+
+/**
+ * backend_destroy:
+ * This should only be run once per backend load, i.e. not every transaction
+ */
+static void
+backend_destroy (PkBackend *backend)
+{
+	pk_debug ("FILTER: destroy");
+	g_object_unref (spawn);
+}
+
+
+/**
+ * pk_backend_search_name:
+ */
+static void
+backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "search-name.pl", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+PK_BACKEND_OPTIONS (
+	"URPMI",					/* description */
+	"Aurelien Lefebvre <alefebvre at mandriva.com>",	/* author */
+	backend_initialize,			/* initalize */
+	backend_destroy,			/* destroy */
+	NULL,			/* get_groups */
+	NULL,			/* get_filters */
+	NULL,				/* cancel */
+	NULL,			/* get_depends */
+	NULL,			/* get_details */
+	NULL,			/* get_files */
+	NULL,			/* get_packages */
+	NULL,			/* get_repo_list */
+	NULL,			/* get_requires */
+	NULL,		/* get_update_detail */
+	NULL,			/* get_updates */
+	NULL,			/* install_files */
+	NULL,		/* install_packages */
+	NULL,		/* install_signature */
+	NULL,			/* refresh_cache */
+	NULL,		/* remove_packages */
+	NULL,			/* repo_enable */
+	NULL,			/* repo_set_data */
+	NULL,			/* resolve */
+	NULL,					/* rollback */
+	NULL,			/* search_details */
+	NULL,			/* search_file */
+	NULL,			/* search_group */
+	backend_search_name,			/* search_name */
+	NULL,					/* service_pack */
+	NULL,		/* update_packages */
+	NULL,			/* update_system */
+	NULL			/* what_provides */
+);
+
commit 288ba19ed645e62d1da27fb45d259cd23f557d97
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon May 26 17:34:58 2008 +0100

    PkClient: preventative fix as somebody pointed out that in theory we could do ::Finished and then Wait:: for very short transactions.

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 27a7634..e2a8c67 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -1022,7 +1022,7 @@ pk_client_get_updates (PkClient *client, PkFilterEnum filters, GError **error)
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1112,7 +1112,7 @@ pk_client_update_system (PkClient *client, GError **error)
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1167,7 +1167,7 @@ pk_client_search_name (PkClient *client, PkFilterEnum filters, const gchar *sear
 				 G_TYPE_STRING, search,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1223,7 +1223,7 @@ pk_client_search_details (PkClient *client, PkFilterEnum filters, const gchar *s
 				 G_TYPE_STRING, search,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1277,7 +1277,7 @@ pk_client_search_group (PkClient *client, PkFilterEnum filters, const gchar *sea
 				 G_TYPE_STRING, search,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1331,7 +1331,7 @@ pk_client_search_file (PkClient *client, PkFilterEnum filters, const gchar *sear
 				 G_TYPE_STRING, search,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1397,7 +1397,7 @@ pk_client_get_depends (PkClient *client, PkFilterEnum filters, const gchar *pack
 				 G_TYPE_BOOLEAN, recursive,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1448,7 +1448,7 @@ pk_client_get_packages (PkClient *client, PkFilterEnum filters, GError **error)
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1514,7 +1514,7 @@ pk_client_get_requires (PkClient *client, PkFilterEnum filters, const gchar *pac
 				 G_TYPE_BOOLEAN, recursive,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1579,7 +1579,7 @@ pk_client_what_provides (PkClient *client, PkFilterEnum filters, PkProvidesEnum
 				 G_TYPE_STRING, search,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1637,7 +1637,7 @@ pk_client_get_update_detail (PkClient *client, const gchar *package_id, GError *
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdateDetail", error,
 				 G_TYPE_STRING, package_id,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1686,7 +1686,7 @@ pk_client_rollback (PkClient *client, const gchar *transaction_id, GError **erro
 	ret = dbus_g_proxy_call (client->priv->proxy, "Rollback", error,
 				 G_TYPE_STRING, transaction_id,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1743,7 +1743,7 @@ pk_client_resolve (PkClient *client, PkFilterEnum filters, const gchar *package,
 				 G_TYPE_STRING, package,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1801,7 +1801,7 @@ pk_client_get_details (PkClient *client, const gchar *package_id, GError **error
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetDetails", error,
 				 G_TYPE_STRING, package_id,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1858,7 +1858,7 @@ pk_client_get_files (PkClient *client, const gchar *package_id, GError **error)
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetFiles", error,
 				 G_TYPE_STRING, package_id,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -1963,7 +1963,7 @@ pk_client_remove_packages (PkClient *client, gchar **package_ids, gboolean allow
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2048,7 +2048,7 @@ pk_client_refresh_cache (PkClient *client, gboolean force, GError **error)
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2142,7 +2142,7 @@ pk_client_install_packages (PkClient *client, gchar **package_ids, GError **erro
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2242,7 +2242,7 @@ pk_client_install_signature (PkClient *client, PkSigTypeEnum type, const gchar *
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2340,7 +2340,7 @@ pk_client_update_packages (PkClient *client, gchar **package_ids, GError **error
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2570,7 +2570,7 @@ pk_client_install_files (PkClient *client, gboolean trusted, gchar **files_rel,
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2622,7 +2622,7 @@ pk_client_get_repo_list (PkClient *client, PkFilterEnum filters, GError **error)
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	g_free (filter_text);
 	pk_client_error_fixup (error);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2703,7 +2703,7 @@ pk_client_accept_eula (PkClient *client, const gchar *eula_id, GError **error)
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2787,7 +2787,7 @@ pk_client_repo_enable (PkClient *client, const gchar *repo_id, gboolean enabled,
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2880,7 +2880,7 @@ pk_client_repo_set_data (PkClient *client, const gchar *repo_id, const gchar *pa
 		g_propagate_error (error, error_pk);
 	}
 
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 
@@ -2957,7 +2957,7 @@ pk_client_get_old_transactions (PkClient *client, guint number, GError **error)
 				 G_TYPE_UINT, number,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	pk_client_error_fixup (error);
-	if (ret) {
+	if (ret && !client->priv->is_finished) {
 		/* allow clients to respond in the status changed callback */
 		pk_client_change_status (client, PK_STATUS_ENUM_WAIT);
 	}
commit 448bbb37e16ea026b6c8eadf68a6cfea84b3d256
Author: Richard Hughes <richard at hughsie.com>
Date:   Sun May 25 16:42:47 2008 +0100

    trivial: improve a debugging statement output

diff --git a/libpackagekit/pk-task-list.c b/libpackagekit/pk-task-list.c
index 76ab022..3dc1db0 100644
--- a/libpackagekit/pk-task-list.c
+++ b/libpackagekit/pk-task-list.c
@@ -161,7 +161,7 @@ pk_task_list_status_changed_cb (PkClient *client, PkStatusEnum status, PkTaskLis
 	g_return_if_fail (PK_IS_TASK_LIST (tlist));
 
 	tid = pk_client_get_tid (client);
-	pk_debug ("tid %s is now %i", tid, status);
+	pk_debug ("tid %s is now %s", tid, pk_status_enum_to_text (status));
 
 	/* get correct item */
 	item = pk_task_list_find_existing_tid (tlist, tid);
commit 4be5f7b55960f19ebd4b49cc061f671e8dfb2090
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat May 24 16:30:34 2008 +0100

    trivial: fix a tiny-weenie memory leak if we get the array list when a task is finished and waiting to be cleaned up

diff --git a/src/pk-transaction-list.c b/src/pk-transaction-list.c
index 0921c7c..f325f94 100644
--- a/src/pk-transaction-list.c
+++ b/src/pk-transaction-list.c
@@ -89,7 +89,6 @@ pk_transaction_list_get_from_transaction (PkTransactionList *tlist, PkTransactio
 
 	/* find the runner with the transaction ID */
 	length = tlist->priv->array->len;
-	pk_debug ("length = %i", length);
 	for (i=0; i<length; i++) {
 		item = (PkTransactionItem *) g_ptr_array_index (tlist->priv->array, i);
 		if (item->transaction == transaction) {
@@ -352,28 +351,29 @@ gchar **
 pk_transaction_list_get_array (PkTransactionList *tlist)
 {
 	guint i;
-	guint count = 0;
 	guint length;
+	GPtrArray *parray;
 	gchar **array;
 	PkTransactionItem *item;
 
 	g_return_val_if_fail (PK_IS_TRANSACTION_LIST (tlist), NULL);
 
+	/* use a temp array, as not all are in progress */
+	parray = g_ptr_array_new ();
+
 	/* find all the transactions in progress */
 	length = tlist->priv->array->len;
-
-	/* create new strv list */
-	array = g_new0 (gchar *, length + 1);
-
-	pk_debug ("%i active transactions", length);
 	for (i=0; i<length; i++) {
 		item = (PkTransactionItem *) g_ptr_array_index (tlist->priv->array, i);
-		/* only return in the list if it worked */
-		if (item->committed && item->finished == FALSE) {
-			array[count] = g_strdup (item->tid);
-			count++;
+		/* only return in the list if its committed and not finished */
+		if (item->committed && !item->finished) {
+			g_ptr_array_add (parray, g_strdup (item->tid));
 		}
 	}
+	pk_debug ("%i transactions in list, %i active", length, parray->len);
+	array = pk_ptr_array_to_argv (parray);
+	g_ptr_array_free (parray, TRUE);
+
 	return array;
 }
 
commit 0635c99a3d0c3f84c8e949163c4e129d7779082e
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 15:38:16 2008 +0100

    trivial: use an epoch to trump fedora packages in the spec files

diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 4d4a7e3..61a67d1 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -10,6 +10,7 @@ Summary:   System daemon that is a DBUS abstraction layer for packages
 Name:      PackageKit
 Version:   #VERSION#
 Release:   0.#BUILD#%{?alphatag}%{?dist}
+Epoch:     1
 License:   GPLv2+
 Group:     System Environment/Libraries
 URL:       http://packagekit.freedesktop.org
@@ -17,8 +18,8 @@ Source0:   http://people.freedesktop.org/~hughsient/releases/%{name}-%{version}.
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 Requires: dbus >= %{dbus_version}
-Requires: PackageKit-libs = %{version}-%{release}
-Requires: yum-packagekit = %{version}-%{release}
+Requires: PackageKit-libs = %{epoch}:%{version}-%{release}
+Requires: yum-packagekit = %{epoch}:%{version}-%{release}
 Requires: yum >= 3.2.6
 
 BuildRequires: glib2-devel >= %{glib2_version}
@@ -69,7 +70,7 @@ will almost instantly update itself to reflect this.
 Summary: Libraries for accessing PackageKit
 Group: Development/Libraries
 Requires: dbus >= %{dbus_version}
-Requires: %{name} = %{version}-%{release}
+Requires: %{name} = %{epoch}:%{version}-%{release}
 
 %description libs
 Libraries for accessing PackageKit.
@@ -78,7 +79,7 @@ Libraries for accessing PackageKit.
 Summary: Cron job and related utilities for PackageKit
 Group: System Environment/Base
 Requires: cronie
-Requires: %{name} = %{version}-%{release}
+Requires: %{name} = %{epoch}:%{version}-%{release}
 
 %description cron
 Crontab and utilities for running PackageKit as a cron job.
@@ -86,7 +87,7 @@ Crontab and utilities for running PackageKit as a cron job.
 %package devel
 Summary: Libraries and headers for PackageKit
 Group: Development/Libraries
-Requires: %{name} = %{version}-%{release}
+Requires: %{name} = %{epoch}:%{version}-%{release}
 Requires: dbus-devel >= %{dbus_version}
 Requires: pkgconfig
 Requires: sqlite-devel
diff --git a/contrib/gnome-packagekit.spec.in b/contrib/gnome-packagekit.spec.in
index a97fc3b..ded7799 100644
--- a/contrib/gnome-packagekit.spec.in
+++ b/contrib/gnome-packagekit.spec.in
@@ -6,6 +6,7 @@ Summary:   GNOME PackageKit Client
 Name:      gnome-packagekit
 Version:   #VERSION#
 Release:   0.#BUILD#%{?alphatag}%{?dist}
+Epoch:     1
 License:   GPLv2+
 Group:     Applications/System
 URL:       http://www.packagekit.org
commit fad4eb0565ecfe1ec682905839119c24d6c7b577
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 15:27:37 2008 +0100

    add another convenience function, pk_strreplace()

diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c
index 4c5e8c5..f0eb612 100644
--- a/libpackagekit/pk-common.c
+++ b/libpackagekit/pk-common.c
@@ -613,6 +613,35 @@ pk_strpad_extra (const gchar *data, guint length, guint *extra)
 }
 
 /**
+ * pk_strreplace:
+ * @text: The input text to make safe
+ * @find: What to search for
+ * @replace: What to replace with
+ *
+ * Replaces chars in the text with a replacement.
+ * The %find and %replace variables to not have to be of the same length
+ *
+ * Return value: the new string (copied)
+ **/
+gchar *
+pk_strreplace (const gchar *text, const gchar *find, const gchar *replace)
+{
+	gchar **array;
+	gchar *retval;
+
+	/* common case, not found */
+	if (strstr (text, find) == NULL) {
+		return g_strdup (text);
+	}
+
+	/* split apart and rejoin with new delimiter */
+	array = g_strsplit (text, find, 0);
+	retval = g_strjoinv (replace, array);
+	g_strfreev (array);
+	return retval;
+}
+
+/**
  * pk_delay_yield:
  * @delay: the desired delay in seconds
  *
@@ -1283,6 +1312,48 @@ libst_common (LibSelfTest *test)
 	g_free (text_safe);
 
 	/************************************************************
+	 ****************         Replace          ******************
+	 ************************************************************/
+	libst_title (test, "replace start");
+	text_safe = pk_strreplace ("richard\nhughes", "r", "e");
+	if (pk_strequal (text_safe, "eichaed\nhughes")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "failed the replace '%s'", text_safe);
+	}
+	g_free (text_safe);
+
+	/************************************************************/
+	libst_title (test, "replace none");
+	text_safe = pk_strreplace ("richard\nhughes", "dave", "e");
+	if (pk_strequal (text_safe, "richard\nhughes")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "failed the replace '%s'", text_safe);
+	}
+	g_free (text_safe);
+
+	/************************************************************/
+	libst_title (test, "replace end");
+	text_safe = pk_strreplace ("richard\nhughes", "s", "e");
+	if (pk_strequal (text_safe, "richard\nhughee")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "failed the replace '%s'", text_safe);
+	}
+	g_free (text_safe);
+
+	/************************************************************/
+	libst_title (test, "replace unicode");
+	text_safe = pk_strreplace ("richard\n- hughes", "\n- ", "\n• ");
+	if (pk_strequal (text_safe, "richard\n• hughes")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "failed the replace '%s'", text_safe);
+	}
+	g_free (text_safe);
+
+	/************************************************************
 	 ****************         Padding          ******************
 	 ************************************************************/
 	libst_title (test, "pad smaller, no extra");
diff --git a/libpackagekit/pk-common.h b/libpackagekit/pk-common.h
index 9908ec2..9e5a05e 100644
--- a/libpackagekit/pk-common.h
+++ b/libpackagekit/pk-common.h
@@ -84,6 +84,9 @@ gchar		**pk_strsplit				(const gchar	*id,
 gchar		*pk_strbuild_va				(const gchar	*first_element,
 							 va_list	*args)
 							 G_GNUC_WARN_UNUSED_RESULT;
+gchar		*pk_strreplace				(const gchar	*text,
+							 const gchar	*find,
+							 const gchar	*replace);
 gchar		**pk_ptr_array_to_argv			(GPtrArray	*array)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		**pk_va_list_to_argv			(const gchar	*string_first,
commit 6da309f266b5bb72f95f2a0dabd1af50907bc217
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 15:11:02 2008 +0100

    dummy: add an multiline example

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 2df445e..02036ec 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -199,7 +199,11 @@ backend_get_update_detail_timeout (gpointer data)
 					  "http://www.distro-update.org/page?moo;Bugfix release for gtkhtml",
 					  "http://bgzilla.gnome.org/result.php?#9876;GNOME Bugzilla #9876",
 					  NULL,
-					  PK_RESTART_ENUM_SESSION, "Update to latest whizz bang version");
+					  PK_RESTART_ENUM_SESSION,
+					  "Update to latest whizz bang version\n"
+					  "* support this new thing\n"
+					  "* something else\n"
+					  "- and that new thing");
 	} else {
 		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON, "Got unexpected package_id '%s'", _package_id);
 	}
commit 15c1f31c5b9b532a6bda0f188b2392fb16df3754
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 15:10:50 2008 +0100

    newline is a valid char, else the update descriptions look bad

diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c
index 9d3cff7..4c5e8c5 100644
--- a/libpackagekit/pk-common.c
+++ b/libpackagekit/pk-common.c
@@ -246,7 +246,7 @@ pk_strsafe (const gchar *text)
 	}
 
 	/* rip out any insane characters */
-	delimiters = "\\\f\n\r\t\"'";
+	delimiters = "\\\f\r\t\"'";
 	text_safe = g_strdup (text);
 	g_strdelimit (text_safe, delimiters, ' ');
 	return text_safe;
commit dbc4ddb1df7c7195b9b2f26f366d4bac9d0cd026
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 12:45:55 2008 +0100

    change the download location to the packagekit.org server so other people can release code

diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 0cdc85c..d276a05 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -44,7 +44,7 @@ easier to install.
 <h2>Released Versions</h2>
 <p>
 Released versions are found on
-<a href="http://people.freedesktop.org/~hughsient/releases/">people.freedesktop.org</a>.
+<a href="http://www.packagekit.org/releases/">http://www.packagekit.org/releases/</a>.
 </p>
 <table>
 <tr><td><b>Version</b></td><td>&nbsp;&nbsp;</td><td><b>Date</b></td></tr>
commit ed3e70f6a98f1594ead8bed17e4b260247927181
Merge: f1786cd... 922a9bc...
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 12:05:31 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit f1786cd95d54040a0b15012f84da1b22d28b3d28
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 12:05:19 2008 +0100

    add a FAQ entry on 1-Click Install

diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index 5d997f6..5526117 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -22,6 +22,7 @@
 <h2>Table Of Contents</h2>
 <ul>
 <li><a href="#how-complete">How complete are the backends?</a></li>
+<li><a href="#1-click-install">Does PackageKit support 1-Click Install?</a></li>
 <li><a href="#run-as-root">When run as root, gpk-application and pkcon do not work!</a></li>
 <li><a href="#session-system">Why is there a session service and and a system service?</a></li>
 <li><a href="#session-methods">How do I use PackageKit in my application?</a></li>
@@ -566,6 +567,43 @@
 </table>
 
 <hr>
+<h3><a name="1-click-install">Does PackageKit support 1-Click Install?</a></h3>
+<p>
+No, as they are a potential security problem. The issues are as follows:
+</p>
+<ul>
+<li>
+That some developer creates a repository with a package with a higher package epoch, and then the
+distro releases a critical security package (with an updated version, but smaller epoch) and the
+package does not get upgraded, leaving the user vulnerable.
+</li>
+<li>
+The user installs some random repository, where the developer pushes a few svn packages.
+The developer gets bored, and stop produces updates, and then one of the old packages blocks
+on the distribution update, causing no further automatic system updates.
+</li>
+<li>
+There's no signing of 1-click-install files, so we can't actually be sure that they come from a
+reputable source.
+</li>
+<li>
+There's no localisation in the 1-click-files.
+For instance, if we only show a French language speaker a description of "remote exploit trojan"
+they are not going to understand the description.
+</li>
+</ul>
+<p>
+So what's the solution? Using a standard <code>$vendor-release.rpm</code> or <code>.deb</code>
+you can ship the standard repo or source with a signed GPG key.
+</p>
+<p>
+Quoting Sebastian Heinlein,
+<i>Allowing to easily add third party repositories and install third party software without a
+certification infrastructure is like opening the gates to hell.
+Most user just don't have got the technical understanding to handle this well.</i>
+</p>
+
+<hr>
 <h3><a name="run-as-root">When run as root, <code>gpk-application</code> and <code>pkcon</code> do not work!</a></h3>
 <p>
 GTK+ tools should not be run as the root user, <b>PERIOD</b>.
commit 922a9bcc039b3e34e6577f6324609b56f2e2422f
Merge: 92a4148... 4733bb7...
Author: Sebastian Heinlein <renate at debian.daheim>
Date:   Fri May 23 10:17:07 2008 +0100

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit 92a4148f6e15220243141f727399b026f27e5fef
Author: Sebastian Heinlein <renate at debian.daheim>
Date:   Fri May 23 10:04:46 2008 +0100

    APT: Replace the apt backend by the apt2 one, since the former one is
    outdated and not adapted to the api changes. But still keep the code in
    apt.deprecated

diff --git a/backends/Makefile.am b/backends/Makefile.am
index fcc8347..a3c6fb1 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -8,10 +8,6 @@ if BACKEND_TYPE_APT
 SUBDIRS += apt
 endif
 
-if BACKEND_TYPE_APT_DBUS
-SUBDIRS += apt2
-endif
-
 if BACKEND_TYPE_BOX
 SUBDIRS += box
 endif
diff --git a/backends/apt.deprecated/.gitignore b/backends/apt.deprecated/.gitignore
new file mode 100644
index 0000000..c851833
--- /dev/null
+++ b/backends/apt.deprecated/.gitignore
@@ -0,0 +1,10 @@
+.deps
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo
+*.loT
+*.o
+*~
+
diff --git a/backends/apt.deprecated/Makefile.am b/backends/apt.deprecated/Makefile.am
new file mode 100644
index 0000000..07b4131
--- /dev/null
+++ b/backends/apt.deprecated/Makefile.am
@@ -0,0 +1,30 @@
+NULL =
+
+SUBDIRS = helpers
+plugindir = $(PK_PLUGIN_DIR)
+plugin_LTLIBRARIES = libpk_backend_apt.la
+
+libpk_backend_apt_la_LIBADD = $(PK_PLUGIN_LIBS)
+libpk_backend_apt_la_LDFLAGS = -module -avoid-version $(APT_LIBS)
+libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS)
+libpk_backend_apt_la_CXXFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS) -DPK_DB_DIR=\""$(PK_DB_DIR)"\"
+
+libpk_backend_apt_la_SOURCES =				\
+	pk-backend-apt.c				\
+	pk-apt-search.h					\
+	$(NULL)
+
+if APT_SEARCH_PLAIN
+libpk_backend_apt_la_SOURCES +=				\
+	pk-apt-search-plain.c				\
+	$(NULL)
+endif
+
+if APT_SEARCH_SQLITE
+libpk_backend_apt_la_SOURCES +=				\
+	pk-sqlite-pkg-cache.h				\
+	pk-sqlite-pkg-cache.cpp				\
+	pk-apt-build-db.cpp				\
+	pk-apt-search-sqlite.cpp			\
+	$(NULL)
+endif
diff --git a/backends/apt.deprecated/helpers/.gitignore b/backends/apt.deprecated/helpers/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/backends/apt.deprecated/helpers/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/backends/apt.deprecated/helpers/Makefile.am b/backends/apt.deprecated/helpers/Makefile.am
new file mode 100644
index 0000000..0299df2
--- /dev/null
+++ b/backends/apt.deprecated/helpers/Makefile.am
@@ -0,0 +1,29 @@
+
+helperdir = $(datadir)/PackageKit/helpers/apt
+
+NULL =
+
+dist_helper_DATA = 			\
+	install-files.py		\
+	search-name.py			\
+	search-details.py		\
+	search-group.py			\
+	search-file.py			\
+	get-depends.py			\
+	get-details.py			\
+	get-repo-list.py		\
+	get-requires.py			\
+	get-update-detail.py		\
+	get-updates.py			\
+	refresh-cache.py		\
+	repo-enable.py			\
+	resolve.py			\
+	aptBackend.py			\
+	$(NULL)
+
+install-data-hook:
+	chmod a+rx $(DESTDIR)$(helperdir)/*.py
+
+clean-local :
+	rm -f *~
+
diff --git a/backends/apt.deprecated/helpers/aptBackend.py b/backends/apt.deprecated/helpers/aptBackend.py
new file mode 100644
index 0000000..e5f78ca
--- /dev/null
+++ b/backends/apt.deprecated/helpers/aptBackend.py
@@ -0,0 +1,536 @@
+#
+# vim: ts=4 et sts=4
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+# Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+import os
+import re
+
+from packagekit.backend import *
+import apt_pkg,apt_inst
+
+import warnings
+warnings.filterwarnings(action='ignore', category=FutureWarning)
+import apt
+from aptsources.distro import get_distro
+from aptsources.sourceslist import SourcesList
+from sets import Set
+from os.path import join,exists
+from urlparse import urlparse
+from apt.debfile import DebPackage
+from os import system
+
+class Package(apt.Package):
+    def __str__(self):
+        return "Package %s, version %s"%(self.name,self._version)
+
+    def _cmp_deps(self,deps, version):
+        for (v,c) in deps:
+            if not apt_pkg.CheckDep(version,c,v):
+                return False
+        return True
+
+    def __init__(self, backend, pkg, data="",version=[]):
+        apt.package.Package.__init__(self, pkg._cache, pkg._depcache,
+                                     pkg._records, pkg._list, pkg._pcache,
+                                     pkg._pkg)
+        self._version = version
+        self._data = data
+        self._backend = backend
+        wanted_ver = None
+        if self.installedVersion!=None and self._cmp_deps(version,self.installedVersion):
+            wanted_ver = self.installedVersion
+        elif self.installedVersion == None and version == []:
+            #self.markInstall(False,False)
+            wanted_ver = self.candidateVersion
+
+        for ver in pkg._pkg.VersionList:
+            #print "vers",dir(ver),version,ver
+            #print data
+            if (wanted_ver == None or wanted_ver == ver.VerStr) and self._cmp_deps(version,ver.VerStr):
+                f, index = ver.FileList.pop(0)
+                if self._data == "":
+                    if f.Origin=="" and f.Archive=="now":
+                        self._data = "local_install"
+                    elif f.Origin!="" or f.Archive!="":
+                        self._data = "%s/%s"%(f.Origin.replace("/","_"),f.Archive.replace("/","_"))
+                    else:
+                        self._data = "%s/unknown"%f.Site
+                self._version = ver.VerStr
+                break
+        else:
+            print "wanted",wanted_ver
+            for ver in pkg._pkg.VersionList:
+                print "vers",version,ver.VerStr
+            backend.error(ERROR_PACKAGE_NOT_FOUND, "Can't find version %s for %s"%(version,self.name))
+
+    def setVersion(self,version,compare="="):
+        if version!=None and (self.installedVersion == None or not apt_pkg.CheckDep(version,compare,self.installedVersion)):
+            self.markInstall(False,False)
+            if self.candidateVersion != version:
+                if self._data == "":
+                    for ver in pkg._pkg.VersionList:
+                        f, index = ver.FileList.pop(0)
+                        self._data = "%s/%s"%(f.Origin,f.Archive)
+                        if ver.VerStr == version:
+                            break
+
+                # FIXME: this is a nasty hack, assuming that the best way to resolve
+                # deps for non-default repos is by switching the default release.
+                # We really need a better resolver (but that's hard)
+                assert self._data!=""
+                origin = self._data[self._data.find("/")+1:]
+                print "origin",origin
+                name = self.name
+                apt_pkg.Config.Set("APT::Default-Release",origin)
+                if not self._backend._caches.has_key(origin):
+                    self._backend._caches[origin] = apt.Cache(PackageKitProgress(self))
+                    print "new cache for %s"%origin
+                self.__setParent(self._backend._caches[origin][name])
+                self.markInstall(False,False)
+                if not apt_pkg.CheckDep(self.candidateVersion,compare,version):
+                    self._backend.error(ERROR_PACKAGE_NOT_FOUND,
+                            "Unable to locate package version %s (only got %s) for %s"%(version,self.candidateVersion,name))
+                    return
+                self.markKeep()
+
+    @property
+    def group(self):
+        section = self.section.split('/')[-1].lower()
+        #if section in ():
+        #    return GROUP_ACCESSIBILITY
+        if section in ('utils',):
+            return "accessories"
+        #if section in ():
+        #    return GROUP_EDUCATION
+        if section in ('games',):
+            return "games"
+        if section in ('graphics',):
+            return "graphics"
+        if section in ('net', 'news', 'web', 'comm'):
+            return "internet"
+        if section in ('editors', 'tex'):
+            return "office"
+        if section in ('misc',):
+            return "other"
+        if section in ('devel', 'libdevel', 'interpreters', 'perl', 'python'):
+            return "programming"
+        if section in ('sound',):
+            return "multimedia"
+        if section in ('base', 'admin'):
+            return "system"
+        return "unknown"
+
+    @property
+    def isInstalled(self):
+        return super(self.__class__,self).isInstalled and self.installedVersion == self._version
+
+    @property
+    def isDevelopment(self):
+        name = self.name.lower()
+        section = self.section.split('/')[-1].lower()
+        return name.endswith('-dev') or name.endswith('-dbg') or \
+                section in ('devel', 'libdevel')
+
+    @property
+    def isGui(self):
+        section = self.section.split('/')[-1].lower()
+        return section in ('x11', 'gnome', 'kde')
+
+    _HYPHEN_PATTERN = re.compile(r'(\s|_)+')
+
+    def matchName(self, name):
+        needle = name.strip().lower()
+        haystack = self.name.lower()
+        needle = Package._HYPHEN_PATTERN.sub('-', needle)
+        haystack = Package._HYPHEN_PATTERN.sub('-', haystack)
+        if haystack.find(needle) >= 0:
+            return True
+        return False
+
+    def matchDetails(self, details):
+        if self.matchName(details):
+            return True
+        needle = details.strip().lower()
+        haystack = self.description.lower()
+        if haystack.find(needle) >= 0:
+            return True
+        return False
+
+    def matchGroup(self, name):
+        needle = name.strip().lower()
+        haystack = self.group
+        if haystack.startswith(needle):
+            return True
+        return False
+
+class PackageKitProgress(apt.progress.OpProgress, apt.progress.FetchProgress):
+    def __init__(self, backend):
+        self._backend = backend
+        apt.progress.OpProgress.__init__(self)
+        apt.progress.FetchProgress.__init__(self)
+
+    # OpProgress callbacks
+    def update(self, percent):
+        pass
+
+    def done(self):
+        pass
+
+    # FetchProgress callbacks
+    def pulse(self):
+        apt.progress.FetchProgress.pulse(self)
+        self._backend.percentage(self.percent)
+        return True
+
+    def stop(self):
+        self._backend.percentage(100)
+
+    def mediaChange(self, medium, drive):
+        # This probably should not be an error, but a Message.
+        self._backend.error(ERROR_UNKNOWN,
+                "Medium change needed")
+
+class PackageKitAptBackend(PackageKitBaseBackend):
+    def __init__(self, args):
+        PackageKitBaseBackend.__init__(self, args)
+        self.status(STATUS_SETUP)
+        self._caches  = {}
+        self._apt_cache = apt.Cache(PackageKitProgress(self))
+        default = apt_pkg.Config.Find("APT::Default-Release")
+        if default=="":
+            d = get_distro()
+            if d.id == "Debian":
+                default = "stable"
+            elif d.id == "Ubuntu":
+                default = "main"
+            else:
+                raise Exception,d.id
+
+        self._caches[default] = self._apt_cache
+
+
+    def search_name(self, filters, key):
+        '''
+        Implement the {backend}-search-name functionality
+        '''
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        for package in self._do_search(filters,
+                lambda pkg: pkg.matchName(key)):
+            self._emit_package(package)
+
+    def search_details(self, filters, key):
+        '''
+        Implement the {backend}-search-details functionality
+        '''
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        for package in self._do_search(filters,
+                lambda pkg: pkg.matchDetails(key)):
+            self._emit_package(package)
+
+    def search_group(self, filters, key):
+        '''
+        Implement the {backend}-search-group functionality
+        '''
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        for package in self._do_search(filters,
+                lambda pkg: pkg.matchGroup(key)):
+            self._emit_package(package)
+
+    def search_file(self, filters, key):
+        '''
+        Implement the {backend}-search-file functionality
+        '''
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        self.error(ERROR_NOT_SUPPORTED,
+                "This function is not implemented in this backend")
+
+    def refresh_cache(self):
+        '''
+        Implement the {backend}-refresh_cache functionality
+        '''
+        self.status(STATUS_REFRESH_CACHE)
+        try:
+            res = self._apt_cache.update(PackageKitProgress(self))
+        except Exception, error_message:
+             self.error(ERROR_UNKNOWN,
+                        "Failed to fetch the following items:\n%s" % error_message)
+        return res
+
+    def get_details(self, package):
+        '''
+        Implement the {backend}-get-details functionality
+        '''
+        self.status(STATUS_INFO)
+        name, version, arch, data = self.get_package_from_id(package)
+        pkg = Package(self, self._apt_cache[name])
+        description = re.sub('\s+', ' ', pkg.description).strip()
+        self.description(package, 'unknown', pkg.group, description,
+                         pkg.architecture, pkg.packageSize)
+
+    def resolve(self, name):
+        '''
+        Implement the {backend}-resolve functionality
+        '''
+        self.status(STATUS_INFO)
+        try:
+            pkg = Package(self,self._apt_cache[name])
+            self._emit_package(pkg)
+        except KeyError:
+            self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find a package called '%s'"%name)
+
+    def _do_deps(self,inp,deps,recursive):
+        inp.markInstall()
+        newkeys = []
+        for x in inp.candidateDependencies:
+            n = x.or_dependencies[0].name
+            if not deps.has_key(n):
+                deps[n] = []
+                newkeys.append(n)
+            deps[n].append((x.or_dependencies[0].version,x.or_dependencies[0].relation))
+        if recursive:
+            for n in newkeys:
+                try:
+                    deps = self._do_deps(Package(self,self._apt_cache[n],version=deps[n]),deps,recursive)
+                except KeyError: # FIXME: we're assuming this is a virtual package, which we can't cope with yet
+                    del deps[n]
+                    continue
+        return deps
+
+    def get_depends(self,filters,package, recursive):
+        '''
+        Implement the {backend}-get-depends functionality
+        '''
+        self.allow_cancel(True)
+        self.status(STATUS_INFO)
+        recursive = (recursive == "True")
+        name, version, arch, data = self.get_package_from_id(package)
+        pkg = Package(self,self._apt_cache[name],version=[(version,"=")],data=data)
+        pkg.setVersion(version)
+        deps = self._do_deps(pkg, {}, recursive)
+        for n in deps.keys():
+           self._emit_package(Package(self,self._apt_cache[n],version=deps[n]))
+
+    def _do_reqs(self,inp,pkgs,recursive):
+        extra = []
+        fails = []
+        for r in inp._pkg.RevDependsList:
+            ch = apt_pkg.CheckDep(inp._version,r.CompType,r.TargetVer)
+            v = (r.ParentPkg.Name,r.ParentVer.VerStr)
+            if not ch or v in fails:
+                #print "skip",r.TargetVer,r.CompType,r.ParentPkg.Name,r.ParentVer.VerStr
+                fails.append(v)
+                continue
+            p = Package(self,self._apt_cache[r.ParentPkg.Name],r.ParentVer.VerStr)
+            if v not in pkgs:
+                extra.append(p)
+                #print "new pkg",p
+                self._emit_package(p)
+            pkgs.add(v)
+        if recursive:
+            for e in extra:
+                pkgs = self._do_reqs(p, pkgs,recursive)
+        return pkgs
+
+    def get_requires(self,package,recursive):
+        '''
+        Implement the {backend}-get-requires functionality
+        '''
+        self.allow_cancel(True)
+        self.status(STATUS_INFO)
+        recursive = (recursive == "True")
+        name, version, arch, data = self.get_package_from_id(package)
+        pkg = Package(self,self._apt_cache[name], version=[(version,"=")], data=data)
+
+        pkgs = Set()
+        self._do_reqs(pkg,pkgs, recursive)
+
+    def _build_repo_list(self):
+        repo = {}
+
+        sources = SourcesList()
+        repo["__sources"] = sources
+
+        root = apt_pkg.Config.FindDir("Dir::State::Lists")
+        #print root
+        for entry in sources:
+            if entry.type!="":
+                url = entry.uri
+                #if entry.template!=None:
+                url +="/dists/"
+                url += entry.dist
+                url = url.replace("//dists","/dists")
+                #print url
+                path = join(root,"%s_Release"%(apt_pkg.URItoFileName(url)))
+                if not exists(path):
+                    #print path
+                    name = "%s/unknown"%urlparse(entry.uri)[1]
+                else:
+                    lines = file(path).readlines()
+                    origin = ""
+                    suite = ""
+                    for l in lines:
+                        if l.find("Origin: ")==0:
+                            origin = l.split(" ",1)[1].strip()
+                        elif l.find("Suite: ")==0:
+                            suite = l.split(" ",1)[1].strip()
+                    assert origin!="" and suite!=""
+                    name = "%s/%s"%(origin,suite)
+                if entry.type == "deb-src":
+                    name += "-src"
+
+                repo[name] = {"entry":entry}
+        return repo
+
+    def get_repo_list(self, filters):
+        '''
+        Implement the {backend}-get-repo-list functionality
+        '''
+        self.allow_interrupt(True)
+        self.status(STATUS_INFO)
+        repo = self._build_repo_list()
+        for e in repo.keys():
+            if e == "__sources":
+                continue
+            self.repo_detail(repo[e]["entry"].line.strip(),e,not repo[e]["entry"].disabled)
+
+    def repo_enable(self, repoid, enable):
+        '''
+        Implement the {backend}-repo-enable functionality
+        '''
+        enable = (enable == "True")
+        repo = self._build_repo_list()
+        if not repo.has_key(repoid):
+            self.error(ERROR_REPO_NOT_FOUND,"Couldn't find repo '%s'"%repoid)
+            return
+        r = repo[repoid]
+        if not r["entry"].disabled == enable: # already there
+            return
+        r["entry"].set_enabled(enable)
+        try:
+            repo["__sources"].save()
+        except IOError,e:
+            self.error(ERROR_UNKNOWN, "Problem while trying to save repo settings to %s: %s"%(e.filename,e.strerror))
+
+    def get_updates(self, filter):
+        self._apt_cache.upgrade(False)
+        for pkg in self._apt_cache.getChanges():
+            self._emit_package(Package(self, pkg))
+
+    def get_update_detail(self, package):
+        self.allow_cancel(True)
+        self.percentage(None)
+        self.status(STATUS_INFO)
+        name, version, arch, data = self.get_package_from_id(package)
+        update = ""
+        obsolete = ""
+        cve_url = ""
+        bz_url = ""
+        vendor_url = ""
+        reboot = "none"
+        desc = self._apt_cache[name].description
+        self.update_detail(package,update,obsolete,vendor_url,bz_url,cve_url,reboot,desc)
+
+
+    def install_files (self, inst_files):
+        '''
+        Implement the {backend}-install_files functionality
+        Install the package containing the inst_file file
+        '''
+        if not exists(inst_file):
+            self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find %s"%inst_file)
+            return
+        deb = DebPackage(inst_file)
+        deps = {}
+        for k in ["Depends","Recommends"]:
+            if not deb._sections.has_key(k):
+                continue
+            for items in apt_pkg.ParseDepends(deb[k]):
+                assert len(items) == 1,"Can't handle or deps properly yet"
+                (pkg,ver,comp) = items[0]
+                if not deps.has_key(pkg):
+                    deps[pkg] = []
+                deps[pkg].append((ver,comp))
+        for n in deps.keys():
+           p = Package(self,self._apt_cache[n],version=deps[n])
+           if not p.isInstalled:
+               p.markInstall()
+        assert self._apt_cache.getChanges()==[],"Don't handle install changes yet"
+        # FIXME: nasty hack. Need a better way in
+        ret = system("dpkg -i %s"%inst_file)
+        if ret!=0:
+            self.error(ERROR_UNKNOWN,"Can't install package")
+
+    ### Helpers ###
+    def _emit_package(self, package):
+        id = self.get_package_id(package.name,
+                package._version,
+                package.architecture,
+                package._data)
+        if package.isInstalled:
+            status = INFO_INSTALLED
+        else:
+            status = INFO_AVAILABLE
+        summary = package.summary
+        self.package(id, status, summary)
+
+    def _do_search(self, filters, condition):
+        filters = filters.split(';')
+        size = len(self._apt_cache)
+        percentage = 0
+        for i, pkg in enumerate(self._apt_cache):
+            new_percentage = i / float(size) * 100
+            if new_percentage - percentage >= 5:
+                percentage = new_percentage
+                self.percentage(percentage)
+            package = Package(self, pkg)
+            if package.installedVersion is None and \
+                    package.candidateVersion is None:
+                continue
+            if not condition(package):
+                continue
+                continue
+            vers = [x.VerStr for x in package._pkg.VersionList]
+            if package.installedVersion!=None:
+                i = package.installedVersion
+                if i in vers and vers[0]!=i:
+                    del vers[vers.index(i)]
+                    vers.insert(0,i)
+
+            for ver in vers:
+                p = Package(self, package, version=[[ver,"="]])
+                if self._do_filtering(p, filters):
+                    yield p
+        self.percentage(100)
+
+    def _do_filtering(self, package, filters):
+        if len(filters) == 0 or filters == ['none']:
+            return True
+        if (FILTER_INSTALLED in filters) and (not package.isInstalled):
+            return False
+        if (FILTER_NOT_INSTALLED in filters) and package.isInstalled:
+            return False
+        if (FILTER_GUI in filters) and (not package.isGui):
+            return False
+        if (FILTER_NOT_GUI in filters) and package.isGui:
+            return False
+        if (FILTER_DEVELOPMENT in filters) and (not package.isDevelopment):
+            return False
+        if (FILTER_NOT_DEVELOPMENT in filters) and package.isDevelopment:
+            return False
+        return True
+
diff --git a/backends/apt.deprecated/helpers/get-depends.py b/backends/apt.deprecated/helpers/get-depends.py
new file mode 100755
index 0000000..94dca4a
--- /dev/null
+++ b/backends/apt.deprecated/helpers/get-depends.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+filters=sys.argv[1]
+package=sys.argv[2]
+recursive = sys.argv[3]
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.get_depends(filters, package, recursive)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/get-details.py b/backends/apt.deprecated/helpers/get-details.py
new file mode 100755
index 0000000..a813640
--- /dev/null
+++ b/backends/apt.deprecated/helpers/get-details.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+from aptBackend import PackageKitAptBackend
+
+package = sys.argv[1]
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.get_details(package)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/get-repo-list.py b/backends/apt.deprecated/helpers/get-repo-list.py
new file mode 100755
index 0000000..5529f72
--- /dev/null
+++ b/backends/apt.deprecated/helpers/get-repo-list.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+filters = sys.argv[1]
+
+backend = PackageKitAptBackend(sys.argv[2:])
+backend.get_repo_list(filters)
+backend.unLock()
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/get-requires.py b/backends/apt.deprecated/helpers/get-requires.py
new file mode 100755
index 0000000..e581010
--- /dev/null
+++ b/backends/apt.deprecated/helpers/get-requires.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+package = sys.argv[1]
+recursive = sys.argv[2]
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.get_requires(package, recursive)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/get-update-detail.py b/backends/apt.deprecated/helpers/get-update-detail.py
new file mode 100755
index 0000000..5524d9a
--- /dev/null
+++ b/backends/apt.deprecated/helpers/get-update-detail.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2008 Michael Vogt <mvo at ubuntu.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+package=sys.argv[1]
+backend = PackageKitAptBackend(sys.argv[2:])
+backend.get_update_detail(package)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/get-updates.py b/backends/apt.deprecated/helpers/get-updates.py
new file mode 100755
index 0000000..4f45fbf
--- /dev/null
+++ b/backends/apt.deprecated/helpers/get-updates.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2008 Michael Vogt <mvo at ubuntu.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+from aptBackend import PackageKitAptBackend
+
+filter = sys.argv[1]
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.get_updates(filter)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/install-files.py b/backends/apt.deprecated/helpers/install-files.py
new file mode 100755
index 0000000..dfa024c
--- /dev/null
+++ b/backends/apt.deprecated/helpers/install-files.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+# Copyright (C) 2007 Red Hat Inc, Seth Vidal <skvidal at fedoraproject.org>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+
+trusted = sys.argv[1]
+files_to_inst = sys.argv[2:]
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.install_files(trusted, files_to_inst)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/packagekit b/backends/apt.deprecated/helpers/packagekit
new file mode 120000
index 0000000..8d22531
--- /dev/null
+++ b/backends/apt.deprecated/helpers/packagekit
@@ -0,0 +1 @@
+../../../python/packagekit
\ No newline at end of file
diff --git a/backends/apt.deprecated/helpers/refresh-cache.py b/backends/apt.deprecated/helpers/refresh-cache.py
new file mode 100755
index 0000000..881479d
--- /dev/null
+++ b/backends/apt.deprecated/helpers/refresh-cache.py
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+from aptBackend import PackageKitAptBackend
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.refresh_cache()
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/repo-enable.py b/backends/apt.deprecated/helpers/repo-enable.py
new file mode 100755
index 0000000..3cc36ae
--- /dev/null
+++ b/backends/apt.deprecated/helpers/repo-enable.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+repoid = sys.argv[1]
+state=sys.argv[2]
+backend = PackageKitAptBackend(sys.argv[2:])
+backend.repo_enable(repoid,state)
+backend.unLock()
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/resolve.py b/backends/apt.deprecated/helpers/resolve.py
new file mode 100755
index 0000000..aac34df
--- /dev/null
+++ b/backends/apt.deprecated/helpers/resolve.py
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+filters = sys.argv[1]
+name=sys.argv[2]
+backend = PackageKitAptBackend(sys.argv[2:])
+backend.resolve(name)
+backend.unLock()
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/search-details.py b/backends/apt.deprecated/helpers/search-details.py
new file mode 100755
index 0000000..d02f1b0
--- /dev/null
+++ b/backends/apt.deprecated/helpers/search-details.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+options = sys.argv[1]
+searchlist = sys.argv[2]
+
+from aptBackend import PackageKitAptBackend
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.search_details(options,searchlist)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/search-file.py b/backends/apt.deprecated/helpers/search-file.py
new file mode 100755
index 0000000..ec60319
--- /dev/null
+++ b/backends/apt.deprecated/helpers/search-file.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+options = sys.argv[1]
+searchlist = sys.argv[2]
+
+from aptBackend import PackageKitAptBackend
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.search_file(options,searchlist)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/search-group.py b/backends/apt.deprecated/helpers/search-group.py
new file mode 100755
index 0000000..f63ee80
--- /dev/null
+++ b/backends/apt.deprecated/helpers/search-group.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+options = sys.argv[1]
+searchlist = sys.argv[2]
+
+from aptBackend import PackageKitAptBackend
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.search_group(options,searchlist)
+sys.exit(0)
diff --git a/backends/apt.deprecated/helpers/search-name.py b/backends/apt.deprecated/helpers/search-name.py
new file mode 100755
index 0000000..9f73c89
--- /dev/null
+++ b/backends/apt.deprecated/helpers/search-name.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+options = sys.argv[1]
+searchlist = sys.argv[2]
+
+from aptBackend import PackageKitAptBackend
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.search_name(options,searchlist)
+sys.exit(0)
diff --git a/backends/apt.deprecated/pk-apt-build-db.cpp b/backends/apt.deprecated/pk-apt-build-db.cpp
new file mode 100644
index 0000000..885275d
--- /dev/null
+++ b/backends/apt.deprecated/pk-apt-build-db.cpp
@@ -0,0 +1,284 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+//#include "pk-backend-apt.h"
+#include <pk-backend.h>
+#include <apt-pkg/configuration.h>
+#include <sqlite3.h>
+
+typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
+
+void apt_build_db(PkBackend * backend, sqlite3 *db)
+{
+	GMatchInfo *match_info;
+	GError *error = NULL;
+	gchar *contents = NULL;
+	gchar *sdir;
+	const gchar *fname;
+	GRegex *origin, *suite;
+	GDir *dir;
+	GHashTable *releases;
+	int res;
+	sqlite3_stmt *package = NULL;
+
+	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
+
+	sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL);
+	dir = g_dir_open(sdir,0,&error);
+	if (error!=NULL)
+	{
+		pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir);
+		g_error_free(error);
+		goto search_task_cleanup;
+	}
+
+	origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+	suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+
+	releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
+	while ((fname = g_dir_read_name(dir))!=NULL)
+	{
+		gchar *temp, *parsed_name;
+		gchar** items = g_strsplit(fname,"_",-1);
+		guint len = g_strv_length(items);
+		if(len<=3) // minimum is <source>_<type>_<group>
+		{
+			g_strfreev(items);
+			continue;
+		}
+
+		/* warning: nasty hack with g_strjoinv */
+		temp = items[len-2];
+		items[len-2] = NULL;
+		parsed_name = g_strjoinv("_",items);
+		items[len-2] = temp;
+
+		if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0)
+		{
+			gchar * repo = NULL, *fullname;
+			fullname = g_build_filename(sdir,fname,NULL);
+			if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
+			{
+				pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
+				goto search_task_cleanup;
+			}
+			g_free(fullname);
+
+			g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info);
+			if (!g_match_info_matches(match_info))
+			{
+				pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname);
+				goto search_task_cleanup;
+			}
+			repo = g_match_info_fetch (match_info, 1);
+
+			g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info);
+			if (g_match_info_matches(match_info))
+			{
+				temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL);
+				g_free(repo);
+				repo = temp;
+			}
+
+			temp = parsed_name;
+			parsed_name = g_strconcat(temp,"_",items[len-2],NULL);
+			g_free(temp);
+
+			pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
+
+			g_hash_table_insert(releases, parsed_name, repo);
+			g_free(contents);
+			contents = NULL;
+		}
+		else
+			g_free(parsed_name);
+		g_strfreev(items);
+	}
+	g_dir_close(dir);
+
+	/* and then we need to do this again, but this time we're looking for the packages */
+	dir = g_dir_open(sdir,0,&error);
+	res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
+	if (res!=SQLITE_OK)
+		pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
+	else
+		pk_debug("insert prepare ok for %p",package);
+	while ((fname = g_dir_read_name(dir))!=NULL)
+	{
+		gchar** items = g_strsplit(fname,"_",-1);
+		guint len = g_strv_length(items);
+		if(len<=3) // minimum is <source>_<type>_<group>
+		{
+			g_strfreev(items);
+			continue;
+		}
+
+		if (g_ascii_strcasecmp(items[len-1],"Packages")==0)
+		{
+			const gchar *repo;
+			gchar *temp=NULL, *parsed_name=NULL;
+			gchar *fullname= NULL;
+			gchar *begin=NULL, *next=NULL, *description = NULL;
+			glong count = 0;
+			gboolean haspk = FALSE;
+
+			/* warning: nasty hack with g_strjoinv */
+			if (g_str_has_prefix(items[len-2],"binary-"))
+			{
+				temp = items[len-3];
+				items[len-3] = NULL;
+				parsed_name = g_strjoinv("_",items);
+				items[len-3] = temp;
+			}
+			else
+			{
+				temp = items[len-1];
+				items[len-1] = NULL;
+				parsed_name = g_strjoinv("_",items);
+				items[len-1] = temp;
+			}
+
+			pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
+
+			repo = (const gchar *)g_hash_table_lookup(releases,parsed_name);
+			if (repo == NULL)
+			{
+				pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name);
+				repo = g_strdup("unknown");
+				//g_assert(0);
+			}
+			else
+				pk_debug("repo for %s is %s",parsed_name,repo);
+			g_free(parsed_name);
+
+			fullname = g_build_filename(sdir,fname,NULL);
+			pk_debug("loading %s",fullname);
+			if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
+			{
+				pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
+				goto search_task_cleanup;
+			}
+			/*else
+				pk_debug("loaded");*/
+
+			res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_TRANSIENT);
+			if (res!=SQLITE_OK)
+				pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db));
+			/*else
+				pk_debug("repo bind ok");*/
+
+			res = sqlite3_exec(db,"begin",NULL,NULL,NULL);
+			g_assert(res == SQLITE_OK);
+
+			begin = contents;
+
+			while (true)
+			{
+				next = strstr(begin,"\n");
+				if (next!=NULL)
+				{
+					next[0] = '\0';
+					next++;
+				}
+
+				if (begin[0]=='\0')
+				{
+					if (haspk)
+					{
+						if (description!=NULL)
+						{
+							res=sqlite3_bind_text(package,FIELD_LONG,description,-1,SQLITE_TRANSIENT);
+							if (res!=SQLITE_OK)
+								pk_error("sqlite error during description bind: %s", sqlite3_errmsg(db));
+							g_free(description);
+							description = NULL;
+						}
+						res = sqlite3_step(package);
+						if (res!=SQLITE_DONE)
+							pk_error("sqlite error during step: %s", sqlite3_errmsg(db));
+						sqlite3_reset(package);
+						//pk_debug("added package");
+						haspk = FALSE;
+					}
+					//g_assert(0);
+				}
+				else if (begin[0]==' ')
+				{
+					if (description == NULL)
+						description = g_strdup(&begin[1]);
+					else
+					{
+						gchar *oldval = description;
+						description = g_strconcat(oldval, "\n",&begin[1],NULL);
+						g_free(oldval);
+					}
+				}
+				else
+				{
+					gchar *colon = strchr(begin,':');
+					g_assert(colon!=NULL);
+					colon[0] = '\0';
+					colon+=2;
+					/*if (strlen(colon)>3000)
+						pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/
+					//pk_debug("entry = '%s','%s'",begin,colon);
+					if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0)
+					{
+						res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC);
+						haspk = TRUE;
+						count++;
+						if (count%1000==0)
+							pk_debug("Package %ld (%s)",count,colon);
+					}
+					else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0)
+						res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC);
+					else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0)
+						res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC);
+					else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0)
+						res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC);
+					else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0)
+						res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC);
+					if (res!=SQLITE_OK)
+						pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db));
+				}
+				if (next == NULL)
+					break;
+				begin = next;
+			}
+			res = sqlite3_exec(db,"commit",NULL,NULL,NULL);
+			if (res!=SQLITE_OK)
+				pk_error("sqlite error during commit: %s", sqlite3_errmsg(db));
+			res = sqlite3_clear_bindings(package);
+			if (res!=SQLITE_OK)
+				pk_error("sqlite error during clear: %s", sqlite3_errmsg(db));
+			g_free(contents);
+			contents = NULL;
+		}
+	}
+	sqlite3_finalize(package);
+
+search_task_cleanup:
+	g_dir_close(dir);
+	g_free(sdir);
+	g_free(contents);
+}
+
diff --git a/backends/apt.deprecated/pk-apt-build-db.h b/backends/apt.deprecated/pk-apt-build-db.h
new file mode 100644
index 0000000..bb786a9
--- /dev/null
+++ b/backends/apt.deprecated/pk-apt-build-db.h
@@ -0,0 +1,30 @@
+#ifndef PK_APT_BUILD_DB
+#define PK_APT_BUILD_DB
+
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <sqlite3.h>
+#include <pk-backend.h>
+
+void apt_build_db(PkBackend * backend, sqlite3 *db);
+
+#endif
diff --git a/backends/apt.deprecated/pk-apt-search-plain.c b/backends/apt.deprecated/pk-apt-search-plain.c
new file mode 100644
index 0000000..5e5b4e5
--- /dev/null
+++ b/backends/apt.deprecated/pk-apt-search-plain.c
@@ -0,0 +1,106 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gmodule.h>
+#include <glib.h>
+#include <string.h>
+#include <pk-backend.h>
+#include <pk-backend-spawn.h>
+
+extern PkBackendSpawn *spawn;
+
+/**
+ * backend_get_groups:
+ */
+static PkGroupEnum
+backend_get_groups (PkBackend *backend)
+{
+	return (PK_GROUP_ENUM_ACCESSORIES |
+		PK_GROUP_ENUM_GAMES |
+		PK_GROUP_ENUM_GRAPHICS |
+		PK_GROUP_ENUM_INTERNET |
+		PK_GROUP_ENUM_OFFICE |
+		PK_GROUP_ENUM_OTHER |
+		PK_GROUP_ENUM_PROGRAMMING |
+		PK_GROUP_ENUM_MULTIMEDIA |
+		PK_GROUP_ENUM_SYSTEM);
+}
+
+/**
+ * backend_get_filters:
+ */
+static PkFilterEnum
+backend_get_filters (PkBackend *backend)
+{
+	return (PK_FILTER_ENUM_GUI |
+		PK_FILTER_ENUM_INSTALLED |
+		PK_FILTER_ENUM_DEVELOPMENT);
+}
+
+/**
+ * backend_get_details:
+ */
+
+void
+backend_get_details (PkBackend *backend, const gchar *package_id)
+{
+	pk_backend_spawn_helper (spawn, "get-details.py", package_id, NULL);
+}
+
+/**
+ * backend_search_details:
+ */
+
+void
+backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "search-details.py", filters_texts_text, search, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_search_name:
+ */
+void
+backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_search_group:
+ */
+void
+backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+{
+	gchar *filters_text;
+	pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+/* don't need to do any setup/finalize in the plain search mode */
+void backend_init_search(PkBackend *backend) {}
+void backend_finish_search(PkBackend *backend) {}
diff --git a/backends/apt.deprecated/pk-apt-search-sqlite.cpp b/backends/apt.deprecated/pk-apt-search-sqlite.cpp
new file mode 100644
index 0000000..98bdc7f
--- /dev/null
+++ b/backends/apt.deprecated/pk-apt-search-sqlite.cpp
@@ -0,0 +1,135 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gmodule.h>
+#include <glib.h>
+#include <string.h>
+#include <pk-backend.h>
+#include <pk-backend-spawn.h>
+#include "pk-sqlite-pkg-cache.h"
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/init.h>
+#include "pk-apt-build-db.h"
+
+static PkBackendSpawn *spawn;
+
+/**
+ * backend_get_groups:
+ */
+extern "C" PkGroupEnum
+backend_get_groups (PkBackend *backend)
+{
+	return (PK_GROUP_ENUM_ACCESSORIES |
+		PK_GROUP_ENUM_GAMES |
+		PK_GROUP_ENUM_GRAPHICS |
+		PK_GROUP_ENUM_INTERNET |
+		PK_GROUP_ENUM_OFFICE |
+		PK_GROUP_ENUM_OTHER |
+		PK_GROUP_ENUM_PROGRAMMING |
+		PK_GROUP_ENUM_MULTIMEDIA |
+		PK_GROUP_ENUM_SYSTEM);
+}
+
+/**
+ * backend_get_filters:
+ */
+extern "C" PkFilterEnum
+backend_get_filters (PkBackend *backend)
+{
+	return (PK_FILTER_ENUM_GUI |
+		PK_FILTER_ENUM_INSTALLED |
+		PK_FILTER_ENUM_DEVELOPMENT);
+}
+
+/**
+ * backend_get_details:
+ */
+
+extern "C" void
+backend_get_details (PkBackend *backend, const gchar *package_id)
+{
+	sqlite_get_details(backend,package_id);
+}
+
+/**
+ * backend_search_details:
+ */
+
+extern "C" void
+backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	sqlite_search_details(backend,filter,search);
+}
+
+/**
+ * backend_search_name:
+ */
+extern "C" void
+backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	sqlite_search_name(backend,filter,search);
+}
+
+/**
+ * backend_search_group:
+ */
+extern "C" void
+backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	pk_backend_set_allow_cancel (backend, TRUE);
+	pk_backend_spawn_helper (spawn, "search-group.py", filter, search, NULL);
+}
+
+static gboolean inited = FALSE;
+
+#define APT_DB PK_DB_DIR "/apt.db"
+
+extern "C" void backend_init_search(PkBackend *backend)
+{
+	if (!inited)
+	{
+		gchar *apt_fname = NULL;
+		if (pkgInitConfig(*_config) == false)
+			pk_debug("pkginitconfig was false");
+		if (pkgInitSystem(*_config, _system) == false)
+			pk_debug("pkginitsystem was false");
+
+		apt_fname = g_strconcat(
+				_config->Find("Dir").c_str(),
+				_config->Find("Dir::Cache").c_str(),
+				_config->Find("Dir::Cache::pkgcache").c_str(),
+				NULL);
+
+		//sqlite_set_installed_check(is_installed);
+		sqlite_init_cache(backend, APT_DB, apt_fname, apt_build_db);
+		g_free(apt_fname);
+
+		spawn = pk_backend_spawn_new ();
+		pk_backend_spawn_set_name (spawn, "apt-sqlite");
+
+		inited = TRUE;
+	}
+}
+
+extern "C" void backend_finish_search(PkBackend *backend)
+{
+	sqlite_finish_cache(backend);
+}
diff --git a/backends/apt.deprecated/pk-apt-search.h b/backends/apt.deprecated/pk-apt-search.h
new file mode 100644
index 0000000..e36e89f
--- /dev/null
+++ b/backends/apt.deprecated/pk-apt-search.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_APT_SEARCH_H
+#define __PK_APT_SEARCH_H
+
+#include <glib.h>
+#include <pk-backend.h>
+
+void backend_init_search(PkBackend *backend);
+void backend_finish_search(PkBackend *backend);
+
+void backend_get_details (PkBackend *backend, const gchar *package_id);
+void backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
+void backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
+void backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search);
+
+#endif
diff --git a/backends/apt.deprecated/pk-backend-apt.c b/backends/apt.deprecated/pk-backend-apt.c
new file mode 100644
index 0000000..f59cd88
--- /dev/null
+++ b/backends/apt.deprecated/pk-backend-apt.c
@@ -0,0 +1,268 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <gmodule.h>
+#include <glib.h>
+#include <string.h>
+#include <pk-backend.h>
+#include <pk-backend-spawn.h>
+#include <pk-package-ids.h>
+#include "pk-apt-search.h"
+#include "config.h"
+
+PkBackendSpawn *spawn;
+
+/**
+ * backend_initialize:
+ * This should only be run once per backend load, i.e. not every transaction
+ */
+static void
+backend_initialize (PkBackend *backend)
+{
+	pk_debug ("FILTER: initialize");
+	spawn = pk_backend_spawn_new ();
+	pk_backend_spawn_set_name (spawn, "apt");
+	backend_init_search (backend);
+}
+
+/**
+ * backend_destroy:
+ * This should only be run once per backend load, i.e. not every transaction
+ */
+static void
+backend_destroy (PkBackend *backend)
+{
+	pk_debug ("FILTER: destroy");
+	backend_finish_search (backend);
+	g_object_unref (spawn);
+}
+
+/**
+ * backend_get_groups:
+ */
+static PkGroupEnum
+backend_get_groups (PkBackend *backend)
+{
+	return (PK_GROUP_ENUM_ACCESSORIES |
+		PK_GROUP_ENUM_GAMES |
+		PK_GROUP_ENUM_GRAPHICS |
+		PK_GROUP_ENUM_INTERNET |
+		PK_GROUP_ENUM_OFFICE |
+		PK_GROUP_ENUM_OTHER |
+		PK_GROUP_ENUM_PROGRAMMING |
+		PK_GROUP_ENUM_MULTIMEDIA |
+		PK_GROUP_ENUM_SYSTEM);
+}
+
+/**
+ * backend_get_filters:
+ */
+static PkFilterEnum
+backend_get_filters (PkBackend *backend)
+{
+	return (PK_FILTER_ENUM_GUI |
+		PK_FILTER_ENUM_INSTALLED |
+		PK_FILTER_ENUM_DEVELOPMENT);
+}
+
+/**
+ * pk_backend_bool_to_text:
+ */
+static const gchar *
+pk_backend_bool_to_text (gboolean value)
+{
+	if (value == TRUE) {
+		return "yes";
+	}
+	return "no";
+}
+
+/**
+ * backend_get_depends:
+ */
+static void
+backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_get_updates:
+ */
+static void
+backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_get_update_detail:
+ */
+static void
+backend_get_update_detail (PkBackend *backend, const gchar *package_id)
+{
+	pk_backend_spawn_helper (spawn, "get-update-detail.py", package_id, NULL);
+}
+
+/**
+ * backend_install_packages:
+ */
+static void
+backend_install_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/* check network state */
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	pk_backend_spawn_helper (spawn, "install-packages.py", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_refresh_cache:
+ */
+static void
+backend_refresh_cache (PkBackend *backend, gboolean force)
+{
+	/* check network state */
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	pk_backend_spawn_helper (spawn, "refresh-cache.py", NULL);
+}
+
+/**
+ * pk_backend_remove_packages:
+ * 
+static void
+backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+{
+	gchar *package_ids_temp;
+	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	pk_backend_spawn_helper (spawn, "remove-packages.py", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL);
+	g_free (package_ids_temp);
+} */
+
+/**
+ * pk_backend_update_packages:
+ */
+static void
+backend_update_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/* check network state */
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
+	pk_backend_spawn_helper (spawn, "update-packages.py", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * pk_backend_update_system:
+ */
+static void
+backend_update_system (PkBackend *backend)
+{
+	pk_backend_spawn_helper (spawn, "update-system.py", NULL);
+}
+
+/**
+ * pk_backend_resolve:
+ */
+static void
+backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_id, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * pk_backend_get_repo_list:
+ */
+static void
+backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+{
+	gchar *filters_text;
+	filters_text = pk_filter_enums_to_text (filters);
+	pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL);
+	g_free (filters_text);
+}
+
+PK_BACKEND_OPTIONS (
+	"Apt (with " APT_SEARCH " searching)",				/* description */
+	"Ali Sabil <ali.sabil at gmail.com>; Tom Parker <palfrey at tevp.net>",	/* author */
+	backend_initialize,			/* initalize */
+	backend_destroy,			/* destroy */
+	backend_get_groups,			/* get_groups */
+	backend_get_filters,			/* get_filters */
+	NULL,					/* cancel */
+	backend_get_depends,			/* get_depends */
+	backend_get_details,			/* get_details */
+	NULL,					/* get_files */
+	NULL,					/* get_packages */
+	backend_get_repo_list,			/* get_repo_list */
+	NULL,					/* get_requires */
+	backend_get_update_detail,		/* get_update_detail */
+	backend_get_updates,			/* get_updates */
+	NULL,					/* install_files */
+	backend_install_packages,		/* install_packages */
+	NULL,					/* install_signature */
+	backend_refresh_cache,			/* refresh_cache */
+	NULL,					/* remove_packages */
+	NULL,					/* repo_enable */
+	NULL,					/* repo_set_data */
+	backend_resolve,			/* resolve */
+	NULL,					/* rollback */
+	backend_search_details,			/* search_details */
+	NULL,					/* search_file */
+	backend_search_group,			/* search_group */
+	backend_search_name,			/* search_name */
+	NULL,					/* service_pack */
+	backend_update_package,			/* update_package */
+	backend_update_system,			/* update_system */
+	NULL					/* what_provides */
+);
diff --git a/backends/apt.deprecated/pk-sqlite-pkg-cache.cpp b/backends/apt.deprecated/pk-sqlite-pkg-cache.cpp
new file mode 100644
index 0000000..1bf9a50
--- /dev/null
+++ b/backends/apt.deprecated/pk-sqlite-pkg-cache.cpp
@@ -0,0 +1,215 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include "pk-sqlite-pkg-cache.h"
+
+static sqlite3 *db = NULL;
+static PkBackend *backend;
+static gboolean(*is_installed) (const PkPackageId *) = NULL;
+
+void sqlite_set_installed_check(gboolean(*func) (const PkPackageId *))
+{
+	is_installed = func;
+}
+
+void
+sqlite_init_cache(PkBackend *backend, const char* dbname, const char *compare_fname, void (*build_db)(PkBackend *, sqlite3 *))
+{
+	int ret;
+	struct stat st;
+	time_t db_age;
+
+	ret = sqlite3_open (dbname, &db);
+	g_assert(ret == SQLITE_OK);
+	g_assert(db!=NULL);
+	ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
+	g_assert(ret == SQLITE_OK);
+
+	g_stat(dbname, &st);
+	db_age = st.st_mtime;
+	g_stat(compare_fname, &st);
+	if (db_age>=st.st_mtime)
+	{
+		ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL);
+		if (ret != SQLITE_ERROR)
+			return;
+		pk_debug("ages are %lu for db, and %lu for comparism",db_age,st.st_mtime);
+	}
+	ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it!
+	//g_assert(ret == SQLITE_OK);
+	pk_debug("wiped db");
+	ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
+	g_assert(ret == SQLITE_OK);
+
+	build_db(backend,db);
+
+	sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL);
+	sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL);
+}
+
+void sqlite_finish_cache(PkBackend *backend)
+{
+	sqlite3_close(db);
+}
+
+// sqlite_search_packages_thread
+static gboolean
+sqlite_search_packages_thread (PkBackend *backend)
+{
+	int res;
+	gchar *sel;
+	const gchar *search;
+
+	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
+	type = pk_backend_get_uint (backend, "type");
+	search = pk_backend_get_string (backend, "search");
+
+	pk_debug("finding %s", search);
+
+	sqlite3_stmt *package = NULL;
+	g_strdelimit(search," ",'%');
+
+	if (type == SEARCH_NAME)
+		sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",search);
+	else if (type == SEARCH_DETAILS)
+		sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%' or short_desc like '%%%s%%' or long_desc like '%%%s%%'",search, search, search);
+	else
+	{
+		pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Unknown search task type");
+		goto end_search_packages;
+	}
+
+	pk_debug("statement is '%s'",sel);
+	res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
+	g_free(sel);
+	if (res!=SQLITE_OK)
+		pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
+	res = sqlite3_step(package);
+	while (res == SQLITE_ROW)
+	{
+		PkPackageId *pid = pk_package_id_new_from_list((const gchar*)sqlite3_column_text(package,0),
+				(const gchar*)sqlite3_column_text(package,1),
+				(const gchar*)sqlite3_column_text(package,2),
+				(const gchar*)sqlite3_column_text(package,3));
+
+		gchar *cpid = pk_package_id_to_string(pid);
+		PkInfoEnum pie = PK_INFO_ENUM_UNKNOWN;
+
+		if (is_installed != NULL)
+			pie = is_installed(pid)?PK_INFO_ENUM_INSTALLED:PK_INFO_ENUM_AVAILABLE;
+
+		pk_backend_package(backend, pie, cpid, (const gchar*)sqlite3_column_text(package,4));
+
+		g_free(cpid);
+		pk_package_id_free(pid);
+
+		if (res==SQLITE_ROW)
+			res = sqlite3_step(package);
+	}
+	if (res!=SQLITE_DONE)
+	{
+		pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
+		g_assert(0);
+	}
+
+end_search_packages:
+	pk_backend_finished (backend);
+	return TRUE;
+}
+
+/**
+ * sqlite_search_details:
+ */
+void
+sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	pk_backend_set_uint (backend, "type", SEARCH_DETAILS);
+	pk_backend_thread_create (backend, sqlite_search_packages_thread);
+}
+
+/**
+ * sqlite_search_name:
+ */
+void
+sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+	pk_backend_set_uint (backend, "type", SEARCH_NAME);
+	pk_backend_thread_create (backend, sqlite_search_packages_thread);
+}
+
+// sqlite_get_details_thread
+static gboolean
+sqlite_get_details_thread (PkBackend *backend)
+{
+	PkPackageId *pi;
+	const gchar *package_id;
+	int res;
+
+	package_id = pk_backend_get_string (backend, "package_id");
+	pi = pk_package_id_new_from_string(package_id);
+	if (pi == NULL)
+	{
+		pk_backend_error_code(backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
+		pk_backend_finished(backend);
+		return;
+	}
+
+	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
+
+	pk_debug("finding %s", pi->name);
+
+	sqlite3_stmt *package = NULL;
+	gchar *sel = g_strdup_printf("select long_desc from packages where name = '%s' and version = '%s' and repo = '%s'",pi->name,pi->version,pi->data);
+	pk_debug("statement is '%s'",sel);
+	res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
+	g_free(sel);
+	if (res!=SQLITE_OK)
+		pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
+	res = sqlite3_step(package);
+	pk_backend_details(backend,pi->name, "unknown", PK_GROUP_ENUM_OTHER,(const gchar*)sqlite3_column_text(package,0),"",0);
+	res = sqlite3_step(package);
+	if (res==SQLITE_ROW)
+		pk_error("multiple matches for that package!");
+	if (res!=SQLITE_DONE)
+	{
+		pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
+		g_assert(0);
+	}
+
+	g_free(dt);
+
+	return TRUE;
+}
+
+/**
+ * sqlite_get_details:
+ */
+extern "C++" void
+sqlite_get_details (PkBackend *backend, const gchar *package_id)
+{
+	pk_backend_thread_create (backend, sqlite_get_details_thread);
+	return;
+}
+
diff --git a/backends/apt.deprecated/pk-sqlite-pkg-cache.h b/backends/apt.deprecated/pk-sqlite-pkg-cache.h
new file mode 100644
index 0000000..68fad42
--- /dev/null
+++ b/backends/apt.deprecated/pk-sqlite-pkg-cache.h
@@ -0,0 +1,42 @@
+#ifndef SQLITE_PKT_CACHE
+#define SQLITE_PKT_CACHE
+
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+typedef enum {
+	SEARCH_NAME = 1,
+	SEARCH_DETAILS,
+	SEARCH_FILE
+} SearchDepth;
+
+#include <pk-backend.h>
+#include <sqlite3.h>
+
+void sqlite_init_cache(PkBackend *backend, const char* dbname, const char* compare_fname, void (*build_db)(PkBackend *, sqlite3 *db));
+void sqlite_finish_cache(PkBackend *backend);
+
+void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
+void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
+void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func);
+void sqlite_get_details (PkBackend *backend, const gchar *package_id);
+
+#endif
diff --git a/backends/apt/HACKING b/backends/apt/HACKING
new file mode 100644
index 0000000..2b99c5d
--- /dev/null
+++ b/backends/apt/HACKING
@@ -0,0 +1,5 @@
+The backend can be tested by running it as root from the source code
+repository. Make sure to kill packagekitd before to force a reintializing
+of the cache:
+
+  killall packagekitd; python aptDBUSBackend.py 
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index 07b4131..e315ba9 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -1,30 +1,25 @@
-NULL =
+NULL = 
 
-SUBDIRS = helpers
 plugindir = $(PK_PLUGIN_DIR)
 plugin_LTLIBRARIES = libpk_backend_apt.la
-
+libpk_backend_apt_la_SOURCES = pk-backend-apt.c
 libpk_backend_apt_la_LIBADD = $(PK_PLUGIN_LIBS)
-libpk_backend_apt_la_LDFLAGS = -module -avoid-version $(APT_LIBS)
-libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS)
-libpk_backend_apt_la_CXXFLAGS = $(PK_PLUGIN_CFLAGS) $(APT_CFLAGS) -DPK_DB_DIR=\""$(PK_DB_DIR)"\"
+libpk_backend_apt_la_LDFLAGS = -module -avoid-version
+libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS)
+
+dbusinstancedir = $(LIBEXECDIR)
+dbusinstance_DATA =                                     \
+        aptDBUSBackend.py                               \
+        $(NULL)
+
+EXTRA_DIST =                                            \
+        $(dbusinstance_DATA)                            \
+        $(NULL)
 
-libpk_backend_apt_la_SOURCES =				\
-	pk-backend-apt.c				\
-	pk-apt-search.h					\
-	$(NULL)
+install-data-hook:
+	chmod a+rx $(DESTDIR)$(libexecdir)/*.py
 
-if APT_SEARCH_PLAIN
-libpk_backend_apt_la_SOURCES +=				\
-	pk-apt-search-plain.c				\
-	$(NULL)
-endif
+clean-local :
+	rm -f *~
+	rm -f *.pyc
 
-if APT_SEARCH_SQLITE
-libpk_backend_apt_la_SOURCES +=				\
-	pk-sqlite-pkg-cache.h				\
-	pk-sqlite-pkg-cache.cpp				\
-	pk-apt-build-db.cpp				\
-	pk-apt-search-sqlite.cpp			\
-	$(NULL)
-endif
diff --git a/backends/apt/README b/backends/apt/README
new file mode 100644
index 0000000..0a3da6e
--- /dev/null
+++ b/backends/apt/README
@@ -0,0 +1,23 @@
+The name of this backend is apt2.
+
+It supports apt which is mainly used by Debian and its derivates. In contrast to
+the backend called apt this one uses DBus for the communication with the 
+packagekit daemon. This allows to perform actions without having to reopen
+the cache for each one.
+
+To provide a tremendously fast search function a Xapian database is used.
+It is provided by Enrico Zini's apt-xapian-index. Debtags will be used to 
+enhance the quality of the search results further.
+
+A list of implemented functions are listed in the PackageKit FAQ:
+
+http://www.packagekit.org/pk-faq.html
+
+You can find packages for Ubuntu here:
+
+https://www.launchpad.net/~packagekit/+ppa
+
+Packages for Debian Unstable will be provided soon.
+
+Feel free to send comments or bug reports to the PackageKit mailing list
+or to the author.
diff --git a/backends/apt/TODO b/backends/apt/TODO
new file mode 100644
index 0000000..bee2f3d
--- /dev/null
+++ b/backends/apt/TODO
@@ -0,0 +1,70 @@
+ISSUES:
+
+ * Support delayed or hidden debconf questions
+
+Unresolved issues can be discussed at the following wiki page:
+http://wiki.debian.org/PackageKit
+
+
+TODO:
+
+ * Implement all open backend methods. A list of implemented backend methods 
+   can be found in PackageKit FAQ or in pk-backend-apt2.c.
+
+ * Blacklist packages requiring input on the terminal and try to change
+   the Debian policy in the long run. Way of automation?
+ 
+ * Allow to inject alternative apt.package.Package classes into the
+   cache to support PackageKit and distribution specific needs
+   (e.g. when is a package called free or supported)
+
+ * Allow to reinject debtags into the search results to get 
+   similar software which not matches on the search terms
+
+ * Index file list and add properties for package name and section to
+   the xapian database to also make use of it in search group and 
+   search name (do we want this?)
+
+ * Map Debian/Ubuntu sections to PackageKit groups:
+    - admin : System Administration 		=> admin-tools
+    - base : Base System 			=> system
+    - comm : Communication			=> communication
+    - devel : Development 			=> programming
+    - doc : Documentation			=> ???
+    - editors : Editors				=> accessoires
+    - electronics : Electronics			=> other
+    - embedded : Embedded Devices		=> system
+    - games : Games and Amusement 		=> games
+    - gnome : GNOME Desktop Environment		=> desktop-gnome
+    - graphics : Graphics			=> graphics
+    - hamradio : Amateur Radio			=> communication
+    - interpreters : Interpreted Computer L.	=> programming
+    - kde : KDE Desktop Environment		=> desktop-kde
+    - libdevel : Libraries - Development	=> programming
+    - libs : Libraries				=> system
+    - mail : Email				=> internet
+    - math : Mathematics			=> ??? science/education
+    - misc : Miscellaneous - Text Based		=> other
+    - net : Networkinga				=> network
+    - news : Newsgroup				=> internet
+    - oldlibs : Libraries - Old			=> legacy
+    - otherosfs : Cross Platform		=> system
+    - perl : Perl Programming Language		=> programming
+    - python : Python Programming Language	=> programming
+    - science : Science				=> ??? science/education
+    - shells : Shells				=> system
+    - sound : Multimedia			=> multimedia
+    - tex : TeX Authoring			=> publishing
+    - text : Word Processing			=> publishing
+    - utils : Utilities				=> accessoires
+    - web : World Wide Web			=> internet
+    - x11 : Miscellaneous  - Graphical		=> desktop-other
+    - unknown : Unknown				=> unknown
+    - alien : Converted From RPM by Alien"	=> unknown
+    - translations 				=> localization
+  The following could not be maped: science, documentation, electronics
+  Are there any derivates with additional sections?
+
+ * Fix the dbus policy. Should we require at_console for searching?
+ 
+DONE:
diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
new file mode 100755
index 0000000..22eb714
--- /dev/null
+++ b/backends/apt/aptDBUSBackend.py
@@ -0,0 +1,679 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+Provides an apt backend to PackageKit
+
+Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+Copyright (C) 2008 Sebastian Heinlein <glatzor at ubuntu.com>
+
+Licensed under the GNU General Public License Version 2
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+"""
+
+__author__  = "Sebastian Heinlein <devel at glatzor.de>"
+__state__   = "experimental"
+
+import os
+import pty
+import re
+import signal
+import time
+import threading
+import warnings
+
+import apt
+import apt_pkg
+import dbus
+import dbus.glib
+import dbus.service
+import dbus.mainloop.glib
+import gobject
+
+from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, async
+from packagekit.enums import *
+
+warnings.filterwarnings(action='ignore', category=FutureWarning)
+
+PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
+
+XAPIANDBPATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index")
+XAPIANDB = XAPIANDBPATH + "/index"
+XAPIANDBVALUES = XAPIANDBPATH + "/values"
+
+# Required for daemon mode
+os.putenv("PATH",
+          "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
+# Avoid questions from the maintainer scripts as far as possible
+os.putenv("DEBIAN_FRONTEND", "noninteractive")
+os.putenv("APT_LISTCHANGES_FRONTEND", "none")
+
+# Setup threading support
+gobject.threads_init()
+dbus.glib.threads_init()
+
+class PackageKitOpProgress(apt.progress.OpProgress):
+    '''
+    Handle the cache opening process
+    '''
+    def __init__(self, backend, prange=(0,100), progress=True):
+        self._backend = backend
+        apt.progress.OpProgress.__init__(self)
+        self.steps = []
+        for v in [0.12, 0.25, 0.50, 0.75, 1.00]:
+            s = prange[0] + (prange[1] - prange[0]) * v
+            self.steps.append(s)
+        self.pstart = float(prange[0])
+        self.pend = self.steps.pop(0)
+        self.pprev = None
+        self.show_progress = progress
+
+    # OpProgress callbacks
+    def update(self, percent):
+        progress = int(self.pstart + percent / 100 * (self.pend - self.pstart))
+        if self.show_progress == True and self.pprev < progress:
+            self._backend.PercentageChanged(progress)
+            self.pprev = progress
+
+    def done(self):
+        self.pstart = self.pend
+        try:
+            self.pend = self.steps.pop(0)
+        except:
+            pklog.warning("An additional step to open the cache is required")
+
+class PackageKitFetchProgress(apt.progress.FetchProgress):
+    '''
+    Handle the package download process
+    '''
+    def __init__(self, backend, prange=(0,100)):
+        self._backend = backend
+        apt.progress.FetchProgress.__init__(self)
+        self.pstart = prange[0]
+        self.pend = prange[1]
+        self.pprev = None
+
+    # FetchProgress callbacks
+    def pulse(self):
+        if self._backend._canceled.isSet():
+            return False
+        percent = ((self.currentBytes + self.currentItems)*100.0)/float(self.totalBytes+self.totalItems)
+        progress = int(self.pstart + percent/100 * (self.pend - self.pstart))
+        if self.pprev < progress:
+            self._backend.PercentageChanged(progress)
+            self.pprev = progress
+        apt.progress.FetchProgress.pulse(self)
+        return True
+
+    def start(self):
+        self._backend.StatusChanged(STATUS_DOWNLOAD)
+        self._backend.AllowCancel(True)
+
+    def stop(self):
+        self._backend.PercentageChanged(self.pend)
+        self._backend.AllowCancel(False)
+
+    def mediaChange(self, medium, drive):
+        #FIXME: use the Message method to notify the user
+        self._backend.error(ERROR_UNKNOWN,
+                            "Medium change needed")
+
+class PackageKitInstallProgress(apt.progress.InstallProgress):
+    '''
+    Handle the installation and removal process. Bits taken from
+    DistUpgradeViewNonInteractive.
+    '''
+    def __init__(self, backend, prange=(0,100)):
+        apt.progress.InstallProgress.__init__(self)
+        self._backend = backend
+        self.timeout = 900
+        self.pstart = prange[0]
+        self.pend = prange[1]
+        self.pprev = None
+
+    def statusChange(self, pkg, percent, status):
+        progress = self.pstart + percent/100 * (self.pend - self.pstart)
+        if self.pprev < progress:
+            self._backend.PercentageChanged(int(progress))
+            self.pprev = progress
+        pklog.debug("PM status: %s" % status)
+
+    def startUpdate(self):
+        self._backend.StatusChanged(STATUS_INSTALL)
+        self.last_activity = time.time()
+
+    def updateInterface(self):
+        pklog.debug("Updating interface")
+        apt.progress.InstallProgress.updateInterface(self)
+
+    def conffile(self, current, new):
+        pklog.critical("Config file prompt: '%s'" % current)
+
+def sigquit(signum, frame):
+    pklog.error("Was killed")
+    sys.exit(1)
+
+class PackageKitAptBackend(PackageKitBaseBackend):
+    '''
+    PackageKit backend for apt
+    '''
+    def __init__(self, bus_name, dbus_path):
+        pklog.info("Initializing APT backend")
+        signal.signal(signal.SIGQUIT, sigquit)
+        self._cache = None
+        self._canceled = threading.Event()
+        self._canceled.clear()
+        self._lock = threading.Lock()
+        # Check for xapian support
+        self._use_xapian = False
+        try:
+            import xapian
+        except ImportError:
+            pass
+        else:
+            if os.access(XAPIANDB, os.R_OK):
+                self._use_xapian = True
+        PackageKitBaseBackend.__init__(self, bus_name, dbus_path)
+
+    # Methods ( client -> engine -> backend )
+
+    def doInit(self):
+        pklog.info("Initializing cache")
+        self.StatusChanged(STATUS_SETUP)
+        self.AllowCancel(False)
+        self.NoPercentageUpdates()
+        self._open_cache(progress=False)
+
+    def doExit(self):
+        pass
+
+    @threaded
+    def doCancel(self):
+        pklog.info("Canceling current action")
+        self.StatusChanged(STATUS_CANCEL)
+        self._canceled.set()
+        self._canceled.wait()
+
+    @threaded
+    def doSearchName(self, filters, search):
+        '''
+        Implement the apt2-search-name functionality
+        '''
+        pklog.info("Searching for package name: %s" % search)
+        self.StatusChanged(STATUS_QUERY)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self.AllowCancel(True)
+
+        for pkg in self._cache:
+            if self._canceled.isSet():
+                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
+                               "The search was canceled")
+                self.Finished(EXIT_KILL)
+                self._canceled.clear()
+                return
+            elif search in pkg.name and self._is_package_visible(pkg, filters):
+                self._emit_package(pkg)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    def doSearchDetails(self, filters, search):
+        '''
+        Implement the apt2-search-details functionality
+        '''
+        pklog.info("Searching for package name: %s" % search)
+        self.StatusChanged(STATUS_QUERY)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self.AllowCancel(True)
+        results = []
+
+        if self._use_xapian == True:
+            search_flags = (xapian.QueryParser.FLAG_BOOLEAN |
+                            xapian.QueryParser.FLAG_PHRASE |
+                            xapian.QueryParser.FLAG_LOVEHATE |
+                            xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE)
+            pklog.debug("Performing xapian db based search")
+            db = xapian.Database(XAPIANDB)
+            parser = xapian.QueryParser()
+            query = parser.parse_query(unicode(search),
+                                       search_flags)
+            enquire = xapian.Enquire(db)
+            enquire.set_query(query)
+            matches = enquire.get_mset(0, 1000)
+            for r in  map(lambda m: m[xapian.MSET_DOCUMENT].get_data(),
+                          enquire.get_mset(0,1000)):
+                if self._cache.has_key(r):
+                    results.append(self._cache[r])
+        else:
+            pklog.debug("Performing apt cache based search")
+            for p in self._cache._dict.values():
+                if self._check_canceled("Search was canceled"): return
+                needle = search.strip().lower()
+                haystack = p.description.lower()
+                if p.name.find(needle) >= 0 or haystack.find(needle) >= 0:
+                    results.append(p)
+
+        for r in results:
+            if self._check_canceled("Search was canceled"): return
+            if self._is_package_visible(r, filters) == True:
+                self._emit_package(r)
+
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    @async
+    def doGetUpdates(self, filters):
+        '''
+        Implement the {backend}-get-update functionality
+        '''
+        #FIXME: Implment the basename filter
+        pklog.info("Get updates")
+        self.StatusChanged(STATUS_INFO)
+        self.AllowCancel(True)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self._cache.upgrade(False)
+        for pkg in self._cache.getChanges():
+            if self._canceled.isSet():
+                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
+                               "Calculating updates was canceled")
+                self.Finished(EXIT_KILL)
+                self._canceled.clear()
+                return
+            else:
+                self._emit_package(pkg)
+        self._open_cache(progress=False)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    def GetDetails(self, pkg_id):
+        '''
+        Implement the {backend}-get-details functionality
+        '''
+        pklog.info("Get details of %s" % pkg_id)
+        self.StatusChanged(STATUS_INFO)
+        self.NoPercentageUpdates()
+        self.AllowCancel(False)
+        self._check_init(progress=False)
+        name, version, arch, data = self.get_package_from_id(pkg_id)
+        if not self._cache.has_key(name):
+            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                           "Package %s isn't available" % name)
+            self.Finished(EXIT_FAILED)
+            return
+        pkg = self._cache[name]
+        #FIXME: should perhaps go to python-apt since we need this in
+        #       several applications
+        desc = pkg.description
+        # Skip the first line - it's a duplicate of the summary
+        i = desc.find('\n')
+        desc = desc[i+1:]
+        # do some regular expression magic on the description
+        # Add a newline before each bullet
+        p = re.compile(r'^(\s|\t)*(\*|0|-)',re.MULTILINE)
+        desc = p.sub(ur'\n\u2022', desc)
+        # replace all newlines by spaces
+        p = re.compile(r'\n', re.MULTILINE)
+        desc = p.sub(" ", desc)
+        # replace all multiple spaces by newlines
+        p = re.compile(r'\s\s+', re.MULTILINE)
+        desc = p.sub('\n', desc)
+        #FIXME: group and licence information missing
+        self.Details(pkg_id, 'unknown', 'unknown', desc,
+                         pkg.homepage, pkg.packageSize)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    @async
+    def doUpdateSystem(self):
+        '''
+        Implement the {backend}-update-system functionality
+        '''
+        pklog.info("Upgrading system")
+        self.StatusChanged(STATUS_UPDATE)
+        self.AllowCancel(False)
+        self.PercentageChanged(0)
+        self._check_init(prange=(0,5))
+        try:
+            self._cache.upgrade(distUpgrade=False)
+            self._cache.commit(PackageKitFetchProgress(self, prange=(5,50)),
+                               PackageKitInstallProgress(self, prange=(50,95)))
+        except apt.cache.FetchFailedException:
+            self._open_cache()
+            self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED, "Download failed")
+            self.Finished(EXIT_FAILED)
+            return
+        except apt.cache.FetchCancelledException:
+            self._open_cache(prange=(95,100))
+            self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled")
+            self.Finished(EXIT_KILL)
+            self._canceled.clear()
+            return
+        except:
+            self._open_cache(prange=(95,100))
+            self.ErrorCode(ERROR_UNKNOWN, "System update failed")
+            self.Finished(EXIT_FAILED)
+            return
+        self.PercentageChanged(100)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    @async
+    def doRemovePackages(self, ids, deps=True, auto=False):
+        '''
+        Implement the {backend}-remove functionality
+        '''
+        pklog.info("Removing package(s): id %s" % ids)
+        self.StatusChanged(STATUS_REMOVE)
+        self.AllowCancel(False)
+        self.PercentageChanged(0)
+        self._check_init(prange=(0,10))
+        pkgs=[]
+        for id in ids:
+            pkg = self._find_package_by_id(id)
+            if pkg == None:
+                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                               "Package %s isn't available" % id)
+                self.Finished(EXIT_FAILED)
+                return
+            if not pkg.isInstalled:
+                self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED,
+                               "Package %s isn't installed" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+            pkgs.append(pkg.name[:])
+            try:
+                pkg.markDelete()
+            except:
+                self._open_cache(prange=(90,99))
+                self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+        try:
+            self._cache.commit(PackageKitFetchProgress(self, prange=(10,10)),
+                               PackageKitInstallProgress(self, prange=(10,90)))
+        except:
+            self._open_cache(prange=(90,99))
+            self.ErrorCode(ERROR_UNKNOWN, "Removal failed")
+            self.Finished(EXIT_FAILED)
+            return
+        self._open_cache(prange=(90,99))
+        for p in pkgs:
+            if self._cache.has_key(p) and self._cache[p].isInstalled:
+                self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p)
+                self.Finished(EXIT_FAILED)
+                return
+        self.PercentageChanged(100)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    @async
+    def doInstallPackages(self, ids):
+        '''
+        Implement the {backend}-install functionality
+        '''
+        pklog.info("Installing package with id %s" % ids)
+        self.StatusChanged(STATUS_INSTALL)
+        self.AllowCancel(False)
+        self.PercentageChanged(0)
+        self._check_init(prange=(0,10))
+        pkgs=[]
+        for id in ids:
+            pkg = self._find_package_by_id(id)
+            if pkg == None:
+                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                               "Package %s isn't available" % id)
+                self.Finished(EXIT_FAILED)
+                return
+            if pkg.isInstalled:
+                self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
+                               "Package %s is already installed" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+            pkgs.append(pkg.name[:])
+            try:
+                pkg.markInstall()
+            except:
+                self._open_cache(prange=(90,100))
+                self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
+                                              "installation" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+        try:
+            self._cache.commit(PackageKitFetchProgress(self, prange=(10,50)),
+                               PackageKitInstallProgress(self, prange=(50,90)))
+        except:
+            self._open_cache(prange=(90,100))
+            self.ErrorCode(ERROR_UNKNOWN, "Installation failed")
+            self.Finished(EXIT_FAILED)
+            return
+        self._open_cache(prange=(90,100))
+        self.PercentageChanged(100)
+        pklog.debug("Checking success of operation")
+        for p in pkgs:
+            if not self._cache.has_key(p) or not self._cache[p].isInstalled:
+                self.ErrorCode(ERROR_UNKNOWN, "%s was not installed" % p)
+                self.Finished(EXIT_FAILED)
+                return
+        pklog.debug("Sending success signal")
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    @async
+    def doRefreshCache(self, force):
+        '''
+        Implement the {backend}-refresh_cache functionality
+        '''
+        pklog.info("Refresh cache")
+        self.StatusChanged(STATUS_REFRESH_CACHE)
+        self.last_action_time = time.time()
+        self.AllowCancel(False);
+        self.PercentageChanged(0)
+        self._check_init((0,10))
+        try:
+            self._cache.update(PackageKitFetchProgress(self, prange=(10,95)))
+        except apt.cache.FetchFailedException:
+            self.ErrorCode(ERROR_NO_NETWORK, "Download failed")
+            self.Finished(EXIT_FAILED)
+            return
+        except apt.cache.FetchCancelledException:
+            self._canceled.clear()
+            self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled")
+            self.Finished(EXIT_KILL)
+            return
+        except:
+            self._open_cache(prange=(95,100))
+            self.ErrorCode(ERROR_UNKNOWN, "Refreshing cache failed")
+            self.Finished(EXIT_FAILED)
+            return
+        self.PercentageChanged(100)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    def doGetPackages(self, filters):
+        '''
+        Implement the apt2-get-packages functionality
+        '''
+        pklog.info("Get all packages")
+        self.StatusChanged(STATUS_QUERY)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self.AllowCancel(True)
+
+        for pkg in self._cache:
+            if self._canceled.isSet():
+                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
+                               "The search was canceled")
+                self.Finished(EXIT_KILL)
+                self._canceled.clear()
+                return
+            elif self._is_package_visible(pkg, filters):
+                self._emit_package(pkg)
+        self.Finished(EXIT_SUCCESS)
+
+    @threaded
+    def doResolve(self, filters, name):
+        '''
+        Implement the apt2-resolve functionality
+        '''
+        pklog.info("Resolve")
+        self.StatusChanged(STATUS_QUERY)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self.AllowCancel(False)
+
+        #FIXME: Support candidates
+        if self._cache.has_key(name) and self.is_package_visible(pkg, filters):
+            self._emit_package(name)
+            self.Finished(EXIT_SUCCESS)
+        else:
+            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                           "Package name %s could not be resolved" % name)
+            self.Finished(EXIT_FAILED)
+
+    # Helpers
+
+    def _open_cache(self, prange=(0,100), progress=True):
+        '''
+        (Re)Open the APT cache
+        '''
+        pklog.debug("Open APT cache")
+        self.StatusChanged(STATUS_REFRESH_CACHE)
+        try:
+            self._cache = apt.Cache(PackageKitOpProgress(self, prange,
+                                                         progress))
+        except:
+            self.ErrorCode(ERROR_NO_CACHE, "Package cache could not be opened")
+            self.Finished(EXIT_FAILED)
+            self.Exit()
+            return
+        if self._cache._depcache.BrokenCount > 0:
+            self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+                           "Not all dependecies can be satisfied")
+            self.Finished(EXIT_FAILED)
+            self.Exit()
+            return
+
+    def _lock_cache(self):
+        '''
+        Lock the cache
+        '''
+        pklog.debug("Locking cache")
+        self._locked.acquire()
+
+    def _unlock_cache(self):
+        '''
+        Unlock the cache
+        '''
+        pklog.debug("Releasing cache")
+        self._locked.release()
+
+    def _check_init(self, prange=(0,10), progress=True):
+        '''
+        Check if the backend was initialized well and try to recover from
+        a broken setup
+        '''
+        pklog.debug("Check apt cache and xapian database")
+        if not isinstance(self._cache, apt.cache.Cache) or \
+           self._cache._depcache.BrokenCount > 0:
+            self._open_cache(prange, progress)
+
+    def _check_canceled(self, msg):
+        '''
+        Check if the current transaction was canceled. If so send the
+        corresponding error message and return True
+        '''
+        if self._canceled.isSet():
+             self.ErrorCode(ERROR_TRANSACTION_CANCELLED, msg)
+             self.Finished(EXIT_KILL)
+             self._canceled.clear()
+             return True
+        return False
+ 
+    def get_id_from_package(self, pkg, installed=False):
+        '''
+        Return the id of the installation candidate of a core
+        apt package. If installed is set to True the id of the currently
+        installed package will be returned.
+        '''
+        origin = ''
+        if installed == False and pkg.isInstalled:
+            pkgver = pkg.installedVersion
+        else:
+            pkgver = pkg.candidateVersion
+            if pkg.candidateOrigin:
+                origin = pkg.candidateOrigin[0].label
+        id = self._get_package_id(pkg.name, pkgver, pkg.architecture, origin)
+        return id
+
+    def _emit_package(self, pkg):
+        '''
+        Send the Package signal for a given apt package
+        '''
+        id = self.get_id_from_package(pkg)
+        if pkg.isInstalled:
+            status = INFO_INSTALLED
+        else:
+            status = INFO_AVAILABLE
+        summary = pkg.summary
+        self.Package(status, id, summary)
+
+    def _is_package_visible(self, pkg, filters):
+        '''
+        Return True if the package should be shown in the user interface
+        '''
+        #FIXME: Needs to be optmized
+        if filters == 'none':
+            return True
+        if FILTER_INSTALLED in filters and not pkg.isInstalled:
+            return False
+        if FILTER_NOT_INSTALLED in filters and pkg.isInstalled:
+            return False
+        if FILTER_GUI in filters and not self._package_has_gui(pkg):
+            return False
+        if FILTER_NOT_GUI in filters and self._package_has_gui(pkg):
+            return False
+        if FILTER_DEVELOPMENT in filters and not self._package_is_devel(pkg):
+            return False
+        if FILTER_NOT_DEVELOPMENT in filters and self._package_is_devel(pkg):
+            return False
+        return True
+
+    def _package_has_gui(self, pkg):
+        #FIXME: should go to a modified Package class
+        #FIXME: take application data into account. perhaps checking for
+        #       property in the xapian database
+        return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde']
+
+    def _package_is_devel(self, pkg):
+        #FIXME: should go to a modified Package class
+        return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \
+               pkg.section.split('/')[-1].lower() in ['devel', 'libdevel']
+
+    def _find_package_by_id(self, id):
+        '''
+        Return a package matching to the given package id
+        '''
+        # FIXME: Perform more checks
+        name, version, arch, data = self.get_package_from_id(id)
+        if self._cache.has_key(name):
+            return self._cache[name]
+        else:
+            return None
+
+
+def main():
+    loop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+    bus = dbus.SystemBus(mainloop=loop)
+    bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus=bus)
+    manager = PackageKitAptBackend(bus_name, PACKAGEKIT_DBUS_PATH)
+
+if __name__ == '__main__':
+    main()
+
+# vim: ts=4 et sts=4
diff --git a/backends/apt/helpers/.gitignore b/backends/apt/helpers/.gitignore
deleted file mode 100644
index 0d20b64..0000000
--- a/backends/apt/helpers/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.pyc
diff --git a/backends/apt/helpers/Makefile.am b/backends/apt/helpers/Makefile.am
deleted file mode 100644
index 0299df2..0000000
--- a/backends/apt/helpers/Makefile.am
+++ /dev/null
@@ -1,29 +0,0 @@
-
-helperdir = $(datadir)/PackageKit/helpers/apt
-
-NULL =
-
-dist_helper_DATA = 			\
-	install-files.py		\
-	search-name.py			\
-	search-details.py		\
-	search-group.py			\
-	search-file.py			\
-	get-depends.py			\
-	get-details.py			\
-	get-repo-list.py		\
-	get-requires.py			\
-	get-update-detail.py		\
-	get-updates.py			\
-	refresh-cache.py		\
-	repo-enable.py			\
-	resolve.py			\
-	aptBackend.py			\
-	$(NULL)
-
-install-data-hook:
-	chmod a+rx $(DESTDIR)$(helperdir)/*.py
-
-clean-local :
-	rm -f *~
-
diff --git a/backends/apt/helpers/aptBackend.py b/backends/apt/helpers/aptBackend.py
deleted file mode 100644
index e5f78ca..0000000
--- a/backends/apt/helpers/aptBackend.py
+++ /dev/null
@@ -1,536 +0,0 @@
-#
-# vim: ts=4 et sts=4
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-# Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-import os
-import re
-
-from packagekit.backend import *
-import apt_pkg,apt_inst
-
-import warnings
-warnings.filterwarnings(action='ignore', category=FutureWarning)
-import apt
-from aptsources.distro import get_distro
-from aptsources.sourceslist import SourcesList
-from sets import Set
-from os.path import join,exists
-from urlparse import urlparse
-from apt.debfile import DebPackage
-from os import system
-
-class Package(apt.Package):
-    def __str__(self):
-        return "Package %s, version %s"%(self.name,self._version)
-
-    def _cmp_deps(self,deps, version):
-        for (v,c) in deps:
-            if not apt_pkg.CheckDep(version,c,v):
-                return False
-        return True
-
-    def __init__(self, backend, pkg, data="",version=[]):
-        apt.package.Package.__init__(self, pkg._cache, pkg._depcache,
-                                     pkg._records, pkg._list, pkg._pcache,
-                                     pkg._pkg)
-        self._version = version
-        self._data = data
-        self._backend = backend
-        wanted_ver = None
-        if self.installedVersion!=None and self._cmp_deps(version,self.installedVersion):
-            wanted_ver = self.installedVersion
-        elif self.installedVersion == None and version == []:
-            #self.markInstall(False,False)
-            wanted_ver = self.candidateVersion
-
-        for ver in pkg._pkg.VersionList:
-            #print "vers",dir(ver),version,ver
-            #print data
-            if (wanted_ver == None or wanted_ver == ver.VerStr) and self._cmp_deps(version,ver.VerStr):
-                f, index = ver.FileList.pop(0)
-                if self._data == "":
-                    if f.Origin=="" and f.Archive=="now":
-                        self._data = "local_install"
-                    elif f.Origin!="" or f.Archive!="":
-                        self._data = "%s/%s"%(f.Origin.replace("/","_"),f.Archive.replace("/","_"))
-                    else:
-                        self._data = "%s/unknown"%f.Site
-                self._version = ver.VerStr
-                break
-        else:
-            print "wanted",wanted_ver
-            for ver in pkg._pkg.VersionList:
-                print "vers",version,ver.VerStr
-            backend.error(ERROR_PACKAGE_NOT_FOUND, "Can't find version %s for %s"%(version,self.name))
-
-    def setVersion(self,version,compare="="):
-        if version!=None and (self.installedVersion == None or not apt_pkg.CheckDep(version,compare,self.installedVersion)):
-            self.markInstall(False,False)
-            if self.candidateVersion != version:
-                if self._data == "":
-                    for ver in pkg._pkg.VersionList:
-                        f, index = ver.FileList.pop(0)
-                        self._data = "%s/%s"%(f.Origin,f.Archive)
-                        if ver.VerStr == version:
-                            break
-
-                # FIXME: this is a nasty hack, assuming that the best way to resolve
-                # deps for non-default repos is by switching the default release.
-                # We really need a better resolver (but that's hard)
-                assert self._data!=""
-                origin = self._data[self._data.find("/")+1:]
-                print "origin",origin
-                name = self.name
-                apt_pkg.Config.Set("APT::Default-Release",origin)
-                if not self._backend._caches.has_key(origin):
-                    self._backend._caches[origin] = apt.Cache(PackageKitProgress(self))
-                    print "new cache for %s"%origin
-                self.__setParent(self._backend._caches[origin][name])
-                self.markInstall(False,False)
-                if not apt_pkg.CheckDep(self.candidateVersion,compare,version):
-                    self._backend.error(ERROR_PACKAGE_NOT_FOUND,
-                            "Unable to locate package version %s (only got %s) for %s"%(version,self.candidateVersion,name))
-                    return
-                self.markKeep()
-
-    @property
-    def group(self):
-        section = self.section.split('/')[-1].lower()
-        #if section in ():
-        #    return GROUP_ACCESSIBILITY
-        if section in ('utils',):
-            return "accessories"
-        #if section in ():
-        #    return GROUP_EDUCATION
-        if section in ('games',):
-            return "games"
-        if section in ('graphics',):
-            return "graphics"
-        if section in ('net', 'news', 'web', 'comm'):
-            return "internet"
-        if section in ('editors', 'tex'):
-            return "office"
-        if section in ('misc',):
-            return "other"
-        if section in ('devel', 'libdevel', 'interpreters', 'perl', 'python'):
-            return "programming"
-        if section in ('sound',):
-            return "multimedia"
-        if section in ('base', 'admin'):
-            return "system"
-        return "unknown"
-
-    @property
-    def isInstalled(self):
-        return super(self.__class__,self).isInstalled and self.installedVersion == self._version
-
-    @property
-    def isDevelopment(self):
-        name = self.name.lower()
-        section = self.section.split('/')[-1].lower()
-        return name.endswith('-dev') or name.endswith('-dbg') or \
-                section in ('devel', 'libdevel')
-
-    @property
-    def isGui(self):
-        section = self.section.split('/')[-1].lower()
-        return section in ('x11', 'gnome', 'kde')
-
-    _HYPHEN_PATTERN = re.compile(r'(\s|_)+')
-
-    def matchName(self, name):
-        needle = name.strip().lower()
-        haystack = self.name.lower()
-        needle = Package._HYPHEN_PATTERN.sub('-', needle)
-        haystack = Package._HYPHEN_PATTERN.sub('-', haystack)
-        if haystack.find(needle) >= 0:
-            return True
-        return False
-
-    def matchDetails(self, details):
-        if self.matchName(details):
-            return True
-        needle = details.strip().lower()
-        haystack = self.description.lower()
-        if haystack.find(needle) >= 0:
-            return True
-        return False
-
-    def matchGroup(self, name):
-        needle = name.strip().lower()
-        haystack = self.group
-        if haystack.startswith(needle):
-            return True
-        return False
-
-class PackageKitProgress(apt.progress.OpProgress, apt.progress.FetchProgress):
-    def __init__(self, backend):
-        self._backend = backend
-        apt.progress.OpProgress.__init__(self)
-        apt.progress.FetchProgress.__init__(self)
-
-    # OpProgress callbacks
-    def update(self, percent):
-        pass
-
-    def done(self):
-        pass
-
-    # FetchProgress callbacks
-    def pulse(self):
-        apt.progress.FetchProgress.pulse(self)
-        self._backend.percentage(self.percent)
-        return True
-
-    def stop(self):
-        self._backend.percentage(100)
-
-    def mediaChange(self, medium, drive):
-        # This probably should not be an error, but a Message.
-        self._backend.error(ERROR_UNKNOWN,
-                "Medium change needed")
-
-class PackageKitAptBackend(PackageKitBaseBackend):
-    def __init__(self, args):
-        PackageKitBaseBackend.__init__(self, args)
-        self.status(STATUS_SETUP)
-        self._caches  = {}
-        self._apt_cache = apt.Cache(PackageKitProgress(self))
-        default = apt_pkg.Config.Find("APT::Default-Release")
-        if default=="":
-            d = get_distro()
-            if d.id == "Debian":
-                default = "stable"
-            elif d.id == "Ubuntu":
-                default = "main"
-            else:
-                raise Exception,d.id
-
-        self._caches[default] = self._apt_cache
-
-
-    def search_name(self, filters, key):
-        '''
-        Implement the {backend}-search-name functionality
-        '''
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        for package in self._do_search(filters,
-                lambda pkg: pkg.matchName(key)):
-            self._emit_package(package)
-
-    def search_details(self, filters, key):
-        '''
-        Implement the {backend}-search-details functionality
-        '''
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        for package in self._do_search(filters,
-                lambda pkg: pkg.matchDetails(key)):
-            self._emit_package(package)
-
-    def search_group(self, filters, key):
-        '''
-        Implement the {backend}-search-group functionality
-        '''
-        self.status(STATUS_INFO)
-        self.allow_cancel(True)
-        for package in self._do_search(filters,
-                lambda pkg: pkg.matchGroup(key)):
-            self._emit_package(package)
-
-    def search_file(self, filters, key):
-        '''
-        Implement the {backend}-search-file functionality
-        '''
-        self.allow_cancel(True)
-        self.percentage(None)
-
-        self.error(ERROR_NOT_SUPPORTED,
-                "This function is not implemented in this backend")
-
-    def refresh_cache(self):
-        '''
-        Implement the {backend}-refresh_cache functionality
-        '''
-        self.status(STATUS_REFRESH_CACHE)
-        try:
-            res = self._apt_cache.update(PackageKitProgress(self))
-        except Exception, error_message:
-             self.error(ERROR_UNKNOWN,
-                        "Failed to fetch the following items:\n%s" % error_message)
-        return res
-
-    def get_details(self, package):
-        '''
-        Implement the {backend}-get-details functionality
-        '''
-        self.status(STATUS_INFO)
-        name, version, arch, data = self.get_package_from_id(package)
-        pkg = Package(self, self._apt_cache[name])
-        description = re.sub('\s+', ' ', pkg.description).strip()
-        self.description(package, 'unknown', pkg.group, description,
-                         pkg.architecture, pkg.packageSize)
-
-    def resolve(self, name):
-        '''
-        Implement the {backend}-resolve functionality
-        '''
-        self.status(STATUS_INFO)
-        try:
-            pkg = Package(self,self._apt_cache[name])
-            self._emit_package(pkg)
-        except KeyError:
-            self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find a package called '%s'"%name)
-
-    def _do_deps(self,inp,deps,recursive):
-        inp.markInstall()
-        newkeys = []
-        for x in inp.candidateDependencies:
-            n = x.or_dependencies[0].name
-            if not deps.has_key(n):
-                deps[n] = []
-                newkeys.append(n)
-            deps[n].append((x.or_dependencies[0].version,x.or_dependencies[0].relation))
-        if recursive:
-            for n in newkeys:
-                try:
-                    deps = self._do_deps(Package(self,self._apt_cache[n],version=deps[n]),deps,recursive)
-                except KeyError: # FIXME: we're assuming this is a virtual package, which we can't cope with yet
-                    del deps[n]
-                    continue
-        return deps
-
-    def get_depends(self,filters,package, recursive):
-        '''
-        Implement the {backend}-get-depends functionality
-        '''
-        self.allow_cancel(True)
-        self.status(STATUS_INFO)
-        recursive = (recursive == "True")
-        name, version, arch, data = self.get_package_from_id(package)
-        pkg = Package(self,self._apt_cache[name],version=[(version,"=")],data=data)
-        pkg.setVersion(version)
-        deps = self._do_deps(pkg, {}, recursive)
-        for n in deps.keys():
-           self._emit_package(Package(self,self._apt_cache[n],version=deps[n]))
-
-    def _do_reqs(self,inp,pkgs,recursive):
-        extra = []
-        fails = []
-        for r in inp._pkg.RevDependsList:
-            ch = apt_pkg.CheckDep(inp._version,r.CompType,r.TargetVer)
-            v = (r.ParentPkg.Name,r.ParentVer.VerStr)
-            if not ch or v in fails:
-                #print "skip",r.TargetVer,r.CompType,r.ParentPkg.Name,r.ParentVer.VerStr
-                fails.append(v)
-                continue
-            p = Package(self,self._apt_cache[r.ParentPkg.Name],r.ParentVer.VerStr)
-            if v not in pkgs:
-                extra.append(p)
-                #print "new pkg",p
-                self._emit_package(p)
-            pkgs.add(v)
-        if recursive:
-            for e in extra:
-                pkgs = self._do_reqs(p, pkgs,recursive)
-        return pkgs
-
-    def get_requires(self,package,recursive):
-        '''
-        Implement the {backend}-get-requires functionality
-        '''
-        self.allow_cancel(True)
-        self.status(STATUS_INFO)
-        recursive = (recursive == "True")
-        name, version, arch, data = self.get_package_from_id(package)
-        pkg = Package(self,self._apt_cache[name], version=[(version,"=")], data=data)
-
-        pkgs = Set()
-        self._do_reqs(pkg,pkgs, recursive)
-
-    def _build_repo_list(self):
-        repo = {}
-
-        sources = SourcesList()
-        repo["__sources"] = sources
-
-        root = apt_pkg.Config.FindDir("Dir::State::Lists")
-        #print root
-        for entry in sources:
-            if entry.type!="":
-                url = entry.uri
-                #if entry.template!=None:
-                url +="/dists/"
-                url += entry.dist
-                url = url.replace("//dists","/dists")
-                #print url
-                path = join(root,"%s_Release"%(apt_pkg.URItoFileName(url)))
-                if not exists(path):
-                    #print path
-                    name = "%s/unknown"%urlparse(entry.uri)[1]
-                else:
-                    lines = file(path).readlines()
-                    origin = ""
-                    suite = ""
-                    for l in lines:
-                        if l.find("Origin: ")==0:
-                            origin = l.split(" ",1)[1].strip()
-                        elif l.find("Suite: ")==0:
-                            suite = l.split(" ",1)[1].strip()
-                    assert origin!="" and suite!=""
-                    name = "%s/%s"%(origin,suite)
-                if entry.type == "deb-src":
-                    name += "-src"
-
-                repo[name] = {"entry":entry}
-        return repo
-
-    def get_repo_list(self, filters):
-        '''
-        Implement the {backend}-get-repo-list functionality
-        '''
-        self.allow_interrupt(True)
-        self.status(STATUS_INFO)
-        repo = self._build_repo_list()
-        for e in repo.keys():
-            if e == "__sources":
-                continue
-            self.repo_detail(repo[e]["entry"].line.strip(),e,not repo[e]["entry"].disabled)
-
-    def repo_enable(self, repoid, enable):
-        '''
-        Implement the {backend}-repo-enable functionality
-        '''
-        enable = (enable == "True")
-        repo = self._build_repo_list()
-        if not repo.has_key(repoid):
-            self.error(ERROR_REPO_NOT_FOUND,"Couldn't find repo '%s'"%repoid)
-            return
-        r = repo[repoid]
-        if not r["entry"].disabled == enable: # already there
-            return
-        r["entry"].set_enabled(enable)
-        try:
-            repo["__sources"].save()
-        except IOError,e:
-            self.error(ERROR_UNKNOWN, "Problem while trying to save repo settings to %s: %s"%(e.filename,e.strerror))
-
-    def get_updates(self, filter):
-        self._apt_cache.upgrade(False)
-        for pkg in self._apt_cache.getChanges():
-            self._emit_package(Package(self, pkg))
-
-    def get_update_detail(self, package):
-        self.allow_cancel(True)
-        self.percentage(None)
-        self.status(STATUS_INFO)
-        name, version, arch, data = self.get_package_from_id(package)
-        update = ""
-        obsolete = ""
-        cve_url = ""
-        bz_url = ""
-        vendor_url = ""
-        reboot = "none"
-        desc = self._apt_cache[name].description
-        self.update_detail(package,update,obsolete,vendor_url,bz_url,cve_url,reboot,desc)
-
-
-    def install_files (self, inst_files):
-        '''
-        Implement the {backend}-install_files functionality
-        Install the package containing the inst_file file
-        '''
-        if not exists(inst_file):
-            self.error(ERROR_PACKAGE_NOT_FOUND,"Can't find %s"%inst_file)
-            return
-        deb = DebPackage(inst_file)
-        deps = {}
-        for k in ["Depends","Recommends"]:
-            if not deb._sections.has_key(k):
-                continue
-            for items in apt_pkg.ParseDepends(deb[k]):
-                assert len(items) == 1,"Can't handle or deps properly yet"
-                (pkg,ver,comp) = items[0]
-                if not deps.has_key(pkg):
-                    deps[pkg] = []
-                deps[pkg].append((ver,comp))
-        for n in deps.keys():
-           p = Package(self,self._apt_cache[n],version=deps[n])
-           if not p.isInstalled:
-               p.markInstall()
-        assert self._apt_cache.getChanges()==[],"Don't handle install changes yet"
-        # FIXME: nasty hack. Need a better way in
-        ret = system("dpkg -i %s"%inst_file)
-        if ret!=0:
-            self.error(ERROR_UNKNOWN,"Can't install package")
-
-    ### Helpers ###
-    def _emit_package(self, package):
-        id = self.get_package_id(package.name,
-                package._version,
-                package.architecture,
-                package._data)
-        if package.isInstalled:
-            status = INFO_INSTALLED
-        else:
-            status = INFO_AVAILABLE
-        summary = package.summary
-        self.package(id, status, summary)
-
-    def _do_search(self, filters, condition):
-        filters = filters.split(';')
-        size = len(self._apt_cache)
-        percentage = 0
-        for i, pkg in enumerate(self._apt_cache):
-            new_percentage = i / float(size) * 100
-            if new_percentage - percentage >= 5:
-                percentage = new_percentage
-                self.percentage(percentage)
-            package = Package(self, pkg)
-            if package.installedVersion is None and \
-                    package.candidateVersion is None:
-                continue
-            if not condition(package):
-                continue
-                continue
-            vers = [x.VerStr for x in package._pkg.VersionList]
-            if package.installedVersion!=None:
-                i = package.installedVersion
-                if i in vers and vers[0]!=i:
-                    del vers[vers.index(i)]
-                    vers.insert(0,i)
-
-            for ver in vers:
-                p = Package(self, package, version=[[ver,"="]])
-                if self._do_filtering(p, filters):
-                    yield p
-        self.percentage(100)
-
-    def _do_filtering(self, package, filters):
-        if len(filters) == 0 or filters == ['none']:
-            return True
-        if (FILTER_INSTALLED in filters) and (not package.isInstalled):
-            return False
-        if (FILTER_NOT_INSTALLED in filters) and package.isInstalled:
-            return False
-        if (FILTER_GUI in filters) and (not package.isGui):
-            return False
-        if (FILTER_NOT_GUI in filters) and package.isGui:
-            return False
-        if (FILTER_DEVELOPMENT in filters) and (not package.isDevelopment):
-            return False
-        if (FILTER_NOT_DEVELOPMENT in filters) and package.isDevelopment:
-            return False
-        return True
-
diff --git a/backends/apt/helpers/get-depends.py b/backends/apt/helpers/get-depends.py
deleted file mode 100755
index 94dca4a..0000000
--- a/backends/apt/helpers/get-depends.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-filters=sys.argv[1]
-package=sys.argv[2]
-recursive = sys.argv[3]
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.get_depends(filters, package, recursive)
-sys.exit(0)
diff --git a/backends/apt/helpers/get-details.py b/backends/apt/helpers/get-details.py
deleted file mode 100755
index a813640..0000000
--- a/backends/apt/helpers/get-details.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-from aptBackend import PackageKitAptBackend
-
-package = sys.argv[1]
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.get_details(package)
-sys.exit(0)
diff --git a/backends/apt/helpers/get-repo-list.py b/backends/apt/helpers/get-repo-list.py
deleted file mode 100755
index 5529f72..0000000
--- a/backends/apt/helpers/get-repo-list.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-filters = sys.argv[1]
-
-backend = PackageKitAptBackend(sys.argv[2:])
-backend.get_repo_list(filters)
-backend.unLock()
-sys.exit(0)
diff --git a/backends/apt/helpers/get-requires.py b/backends/apt/helpers/get-requires.py
deleted file mode 100755
index e581010..0000000
--- a/backends/apt/helpers/get-requires.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-package = sys.argv[1]
-recursive = sys.argv[2]
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.get_requires(package, recursive)
-sys.exit(0)
diff --git a/backends/apt/helpers/get-update-detail.py b/backends/apt/helpers/get-update-detail.py
deleted file mode 100755
index 5524d9a..0000000
--- a/backends/apt/helpers/get-update-detail.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2008 Michael Vogt <mvo at ubuntu.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-package=sys.argv[1]
-backend = PackageKitAptBackend(sys.argv[2:])
-backend.get_update_detail(package)
-sys.exit(0)
diff --git a/backends/apt/helpers/get-updates.py b/backends/apt/helpers/get-updates.py
deleted file mode 100755
index 4f45fbf..0000000
--- a/backends/apt/helpers/get-updates.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2008 Michael Vogt <mvo at ubuntu.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-from aptBackend import PackageKitAptBackend
-
-filter = sys.argv[1]
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.get_updates(filter)
-sys.exit(0)
diff --git a/backends/apt/helpers/install-files.py b/backends/apt/helpers/install-files.py
deleted file mode 100755
index dfa024c..0000000
--- a/backends/apt/helpers/install-files.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
-# Copyright (C) 2007 Red Hat Inc, Seth Vidal <skvidal at fedoraproject.org>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-
-trusted = sys.argv[1]
-files_to_inst = sys.argv[2:]
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.install_files(trusted, files_to_inst)
-sys.exit(0)
diff --git a/backends/apt/helpers/packagekit b/backends/apt/helpers/packagekit
deleted file mode 120000
index 8d22531..0000000
--- a/backends/apt/helpers/packagekit
+++ /dev/null
@@ -1 +0,0 @@
-../../../python/packagekit
\ No newline at end of file
diff --git a/backends/apt/helpers/refresh-cache.py b/backends/apt/helpers/refresh-cache.py
deleted file mode 100755
index 881479d..0000000
--- a/backends/apt/helpers/refresh-cache.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-from aptBackend import PackageKitAptBackend
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.refresh_cache()
-sys.exit(0)
diff --git a/backends/apt/helpers/repo-enable.py b/backends/apt/helpers/repo-enable.py
deleted file mode 100755
index 3cc36ae..0000000
--- a/backends/apt/helpers/repo-enable.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-repoid = sys.argv[1]
-state=sys.argv[2]
-backend = PackageKitAptBackend(sys.argv[2:])
-backend.repo_enable(repoid,state)
-backend.unLock()
-sys.exit(0)
diff --git a/backends/apt/helpers/resolve.py b/backends/apt/helpers/resolve.py
deleted file mode 100755
index aac34df..0000000
--- a/backends/apt/helpers/resolve.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-from aptBackend import PackageKitAptBackend
-filters = sys.argv[1]
-name=sys.argv[2]
-backend = PackageKitAptBackend(sys.argv[2:])
-backend.resolve(name)
-backend.unLock()
-sys.exit(0)
diff --git a/backends/apt/helpers/search-details.py b/backends/apt/helpers/search-details.py
deleted file mode 100755
index d02f1b0..0000000
--- a/backends/apt/helpers/search-details.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-options = sys.argv[1]
-searchlist = sys.argv[2]
-
-from aptBackend import PackageKitAptBackend
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.search_details(options,searchlist)
-sys.exit(0)
diff --git a/backends/apt/helpers/search-file.py b/backends/apt/helpers/search-file.py
deleted file mode 100755
index ec60319..0000000
--- a/backends/apt/helpers/search-file.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-options = sys.argv[1]
-searchlist = sys.argv[2]
-
-from aptBackend import PackageKitAptBackend
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.search_file(options,searchlist)
-sys.exit(0)
diff --git a/backends/apt/helpers/search-group.py b/backends/apt/helpers/search-group.py
deleted file mode 100755
index f63ee80..0000000
--- a/backends/apt/helpers/search-group.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-options = sys.argv[1]
-searchlist = sys.argv[2]
-
-from aptBackend import PackageKitAptBackend
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.search_group(options,searchlist)
-sys.exit(0)
diff --git a/backends/apt/helpers/search-name.py b/backends/apt/helpers/search-name.py
deleted file mode 100755
index 9f73c89..0000000
--- a/backends/apt/helpers/search-name.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-#
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-import sys
-
-options = sys.argv[1]
-searchlist = sys.argv[2]
-
-from aptBackend import PackageKitAptBackend
-
-backend = PackageKitAptBackend(sys.argv[1:])
-backend.search_name(options,searchlist)
-sys.exit(0)
diff --git a/backends/apt/packagekit b/backends/apt/packagekit
new file mode 120000
index 0000000..0b64032
--- /dev/null
+++ b/backends/apt/packagekit
@@ -0,0 +1 @@
+../../python/packagekit/
\ No newline at end of file
diff --git a/backends/apt/pk-apt-build-db.cpp b/backends/apt/pk-apt-build-db.cpp
deleted file mode 100644
index 885275d..0000000
--- a/backends/apt/pk-apt-build-db.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-//#include "pk-backend-apt.h"
-#include <pk-backend.h>
-#include <apt-pkg/configuration.h>
-#include <sqlite3.h>
-
-typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
-
-void apt_build_db(PkBackend * backend, sqlite3 *db)
-{
-	GMatchInfo *match_info;
-	GError *error = NULL;
-	gchar *contents = NULL;
-	gchar *sdir;
-	const gchar *fname;
-	GRegex *origin, *suite;
-	GDir *dir;
-	GHashTable *releases;
-	int res;
-	sqlite3_stmt *package = NULL;
-
-	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
-
-	sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL);
-	dir = g_dir_open(sdir,0,&error);
-	if (error!=NULL)
-	{
-		pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir);
-		g_error_free(error);
-		goto search_task_cleanup;
-	}
-
-	origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
-	suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
-
-	releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
-	while ((fname = g_dir_read_name(dir))!=NULL)
-	{
-		gchar *temp, *parsed_name;
-		gchar** items = g_strsplit(fname,"_",-1);
-		guint len = g_strv_length(items);
-		if(len<=3) // minimum is <source>_<type>_<group>
-		{
-			g_strfreev(items);
-			continue;
-		}
-
-		/* warning: nasty hack with g_strjoinv */
-		temp = items[len-2];
-		items[len-2] = NULL;
-		parsed_name = g_strjoinv("_",items);
-		items[len-2] = temp;
-
-		if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0)
-		{
-			gchar * repo = NULL, *fullname;
-			fullname = g_build_filename(sdir,fname,NULL);
-			if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
-			{
-				pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
-				goto search_task_cleanup;
-			}
-			g_free(fullname);
-
-			g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info);
-			if (!g_match_info_matches(match_info))
-			{
-				pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname);
-				goto search_task_cleanup;
-			}
-			repo = g_match_info_fetch (match_info, 1);
-
-			g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info);
-			if (g_match_info_matches(match_info))
-			{
-				temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL);
-				g_free(repo);
-				repo = temp;
-			}
-
-			temp = parsed_name;
-			parsed_name = g_strconcat(temp,"_",items[len-2],NULL);
-			g_free(temp);
-
-			pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
-
-			g_hash_table_insert(releases, parsed_name, repo);
-			g_free(contents);
-			contents = NULL;
-		}
-		else
-			g_free(parsed_name);
-		g_strfreev(items);
-	}
-	g_dir_close(dir);
-
-	/* and then we need to do this again, but this time we're looking for the packages */
-	dir = g_dir_open(sdir,0,&error);
-	res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
-	if (res!=SQLITE_OK)
-		pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
-	else
-		pk_debug("insert prepare ok for %p",package);
-	while ((fname = g_dir_read_name(dir))!=NULL)
-	{
-		gchar** items = g_strsplit(fname,"_",-1);
-		guint len = g_strv_length(items);
-		if(len<=3) // minimum is <source>_<type>_<group>
-		{
-			g_strfreev(items);
-			continue;
-		}
-
-		if (g_ascii_strcasecmp(items[len-1],"Packages")==0)
-		{
-			const gchar *repo;
-			gchar *temp=NULL, *parsed_name=NULL;
-			gchar *fullname= NULL;
-			gchar *begin=NULL, *next=NULL, *description = NULL;
-			glong count = 0;
-			gboolean haspk = FALSE;
-
-			/* warning: nasty hack with g_strjoinv */
-			if (g_str_has_prefix(items[len-2],"binary-"))
-			{
-				temp = items[len-3];
-				items[len-3] = NULL;
-				parsed_name = g_strjoinv("_",items);
-				items[len-3] = temp;
-			}
-			else
-			{
-				temp = items[len-1];
-				items[len-1] = NULL;
-				parsed_name = g_strjoinv("_",items);
-				items[len-1] = temp;
-			}
-
-			pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
-
-			repo = (const gchar *)g_hash_table_lookup(releases,parsed_name);
-			if (repo == NULL)
-			{
-				pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name);
-				repo = g_strdup("unknown");
-				//g_assert(0);
-			}
-			else
-				pk_debug("repo for %s is %s",parsed_name,repo);
-			g_free(parsed_name);
-
-			fullname = g_build_filename(sdir,fname,NULL);
-			pk_debug("loading %s",fullname);
-			if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
-			{
-				pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
-				goto search_task_cleanup;
-			}
-			/*else
-				pk_debug("loaded");*/
-
-			res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_TRANSIENT);
-			if (res!=SQLITE_OK)
-				pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db));
-			/*else
-				pk_debug("repo bind ok");*/
-
-			res = sqlite3_exec(db,"begin",NULL,NULL,NULL);
-			g_assert(res == SQLITE_OK);
-
-			begin = contents;
-
-			while (true)
-			{
-				next = strstr(begin,"\n");
-				if (next!=NULL)
-				{
-					next[0] = '\0';
-					next++;
-				}
-
-				if (begin[0]=='\0')
-				{
-					if (haspk)
-					{
-						if (description!=NULL)
-						{
-							res=sqlite3_bind_text(package,FIELD_LONG,description,-1,SQLITE_TRANSIENT);
-							if (res!=SQLITE_OK)
-								pk_error("sqlite error during description bind: %s", sqlite3_errmsg(db));
-							g_free(description);
-							description = NULL;
-						}
-						res = sqlite3_step(package);
-						if (res!=SQLITE_DONE)
-							pk_error("sqlite error during step: %s", sqlite3_errmsg(db));
-						sqlite3_reset(package);
-						//pk_debug("added package");
-						haspk = FALSE;
-					}
-					//g_assert(0);
-				}
-				else if (begin[0]==' ')
-				{
-					if (description == NULL)
-						description = g_strdup(&begin[1]);
-					else
-					{
-						gchar *oldval = description;
-						description = g_strconcat(oldval, "\n",&begin[1],NULL);
-						g_free(oldval);
-					}
-				}
-				else
-				{
-					gchar *colon = strchr(begin,':');
-					g_assert(colon!=NULL);
-					colon[0] = '\0';
-					colon+=2;
-					/*if (strlen(colon)>3000)
-						pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/
-					//pk_debug("entry = '%s','%s'",begin,colon);
-					if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0)
-					{
-						res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC);
-						haspk = TRUE;
-						count++;
-						if (count%1000==0)
-							pk_debug("Package %ld (%s)",count,colon);
-					}
-					else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0)
-						res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC);
-					else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0)
-						res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC);
-					else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0)
-						res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC);
-					else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0)
-						res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC);
-					if (res!=SQLITE_OK)
-						pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db));
-				}
-				if (next == NULL)
-					break;
-				begin = next;
-			}
-			res = sqlite3_exec(db,"commit",NULL,NULL,NULL);
-			if (res!=SQLITE_OK)
-				pk_error("sqlite error during commit: %s", sqlite3_errmsg(db));
-			res = sqlite3_clear_bindings(package);
-			if (res!=SQLITE_OK)
-				pk_error("sqlite error during clear: %s", sqlite3_errmsg(db));
-			g_free(contents);
-			contents = NULL;
-		}
-	}
-	sqlite3_finalize(package);
-
-search_task_cleanup:
-	g_dir_close(dir);
-	g_free(sdir);
-	g_free(contents);
-}
-
diff --git a/backends/apt/pk-apt-build-db.h b/backends/apt/pk-apt-build-db.h
deleted file mode 100644
index bb786a9..0000000
--- a/backends/apt/pk-apt-build-db.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef PK_APT_BUILD_DB
-#define PK_APT_BUILD_DB
-
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <sqlite3.h>
-#include <pk-backend.h>
-
-void apt_build_db(PkBackend * backend, sqlite3 *db);
-
-#endif
diff --git a/backends/apt/pk-apt-search-plain.c b/backends/apt/pk-apt-search-plain.c
deleted file mode 100644
index 5e5b4e5..0000000
--- a/backends/apt/pk-apt-search-plain.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <gmodule.h>
-#include <glib.h>
-#include <string.h>
-#include <pk-backend.h>
-#include <pk-backend-spawn.h>
-
-extern PkBackendSpawn *spawn;
-
-/**
- * backend_get_groups:
- */
-static PkGroupEnum
-backend_get_groups (PkBackend *backend)
-{
-	return (PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_SYSTEM);
-}
-
-/**
- * backend_get_filters:
- */
-static PkFilterEnum
-backend_get_filters (PkBackend *backend)
-{
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
-}
-
-/**
- * backend_get_details:
- */
-
-void
-backend_get_details (PkBackend *backend, const gchar *package_id)
-{
-	pk_backend_spawn_helper (spawn, "get-details.py", package_id, NULL);
-}
-
-/**
- * backend_search_details:
- */
-
-void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
-{
-	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
-	pk_backend_spawn_helper (spawn, "search-details.py", filters_texts_text, search, NULL);
-	g_free (filters_text);
-}
-
-/**
- * backend_search_name:
- */
-void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
-{
-	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
-	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
-	g_free (filters_text);
-}
-
-/**
- * backend_search_group:
- */
-void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
-{
-	gchar *filters_text;
-	pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL);
-	g_free (filters_text);
-}
-
-/* don't need to do any setup/finalize in the plain search mode */
-void backend_init_search(PkBackend *backend) {}
-void backend_finish_search(PkBackend *backend) {}
diff --git a/backends/apt/pk-apt-search-sqlite.cpp b/backends/apt/pk-apt-search-sqlite.cpp
deleted file mode 100644
index 98bdc7f..0000000
--- a/backends/apt/pk-apt-search-sqlite.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <gmodule.h>
-#include <glib.h>
-#include <string.h>
-#include <pk-backend.h>
-#include <pk-backend-spawn.h>
-#include "pk-sqlite-pkg-cache.h"
-#include <apt-pkg/configuration.h>
-#include <apt-pkg/init.h>
-#include "pk-apt-build-db.h"
-
-static PkBackendSpawn *spawn;
-
-/**
- * backend_get_groups:
- */
-extern "C" PkGroupEnum
-backend_get_groups (PkBackend *backend)
-{
-	return (PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_SYSTEM);
-}
-
-/**
- * backend_get_filters:
- */
-extern "C" PkFilterEnum
-backend_get_filters (PkBackend *backend)
-{
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
-}
-
-/**
- * backend_get_details:
- */
-
-extern "C" void
-backend_get_details (PkBackend *backend, const gchar *package_id)
-{
-	sqlite_get_details(backend,package_id);
-}
-
-/**
- * backend_search_details:
- */
-
-extern "C" void
-backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	sqlite_search_details(backend,filter,search);
-}
-
-/**
- * backend_search_name:
- */
-extern "C" void
-backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	sqlite_search_name(backend,filter,search);
-}
-
-/**
- * backend_search_group:
- */
-extern "C" void
-backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	pk_backend_set_allow_cancel (backend, TRUE);
-	pk_backend_spawn_helper (spawn, "search-group.py", filter, search, NULL);
-}
-
-static gboolean inited = FALSE;
-
-#define APT_DB PK_DB_DIR "/apt.db"
-
-extern "C" void backend_init_search(PkBackend *backend)
-{
-	if (!inited)
-	{
-		gchar *apt_fname = NULL;
-		if (pkgInitConfig(*_config) == false)
-			pk_debug("pkginitconfig was false");
-		if (pkgInitSystem(*_config, _system) == false)
-			pk_debug("pkginitsystem was false");
-
-		apt_fname = g_strconcat(
-				_config->Find("Dir").c_str(),
-				_config->Find("Dir::Cache").c_str(),
-				_config->Find("Dir::Cache::pkgcache").c_str(),
-				NULL);
-
-		//sqlite_set_installed_check(is_installed);
-		sqlite_init_cache(backend, APT_DB, apt_fname, apt_build_db);
-		g_free(apt_fname);
-
-		spawn = pk_backend_spawn_new ();
-		pk_backend_spawn_set_name (spawn, "apt-sqlite");
-
-		inited = TRUE;
-	}
-}
-
-extern "C" void backend_finish_search(PkBackend *backend)
-{
-	sqlite_finish_cache(backend);
-}
diff --git a/backends/apt/pk-apt-search.h b/backends/apt/pk-apt-search.h
deleted file mode 100644
index e36e89f..0000000
--- a/backends/apt/pk-apt-search.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PK_APT_SEARCH_H
-#define __PK_APT_SEARCH_H
-
-#include <glib.h>
-#include <pk-backend.h>
-
-void backend_init_search(PkBackend *backend);
-void backend_finish_search(PkBackend *backend);
-
-void backend_get_details (PkBackend *backend, const gchar *package_id);
-void backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
-void backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
-void backend_search_group (PkBackend *backend, const gchar *filter, const gchar *search);
-
-#endif
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index f59cd88..70836b2 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -20,16 +20,12 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#include <gmodule.h>
-#include <glib.h>
-#include <string.h>
 #include <pk-backend.h>
-#include <pk-backend-spawn.h>
-#include <pk-package-ids.h>
-#include "pk-apt-search.h"
-#include "config.h"
+#include <pk-backend-dbus.h>
 
-PkBackendSpawn *spawn;
+static PkBackendDbus *dbus;
+
+#define PK_DBUS_BACKEND_SERVICE_APT   "org.freedesktop.PackageKitAptBackend"
 
 /**
  * backend_initialize:
@@ -39,9 +35,8 @@ static void
 backend_initialize (PkBackend *backend)
 {
 	pk_debug ("FILTER: initialize");
-	spawn = pk_backend_spawn_new ();
-	pk_backend_spawn_set_name (spawn, "apt");
-	backend_init_search (backend);
+	dbus = pk_backend_dbus_new ();
+	pk_backend_dbus_set_name (dbus, PK_DBUS_BACKEND_SERVICE_APT);
 }
 
 /**
@@ -52,8 +47,8 @@ static void
 backend_destroy (PkBackend *backend)
 {
 	pk_debug ("FILTER: destroy");
-	backend_finish_search (backend);
-	g_object_unref (spawn);
+	pk_backend_dbus_kill (dbus);
+	g_object_unref (dbus);
 }
 
 /**
@@ -85,184 +80,144 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
- * pk_backend_bool_to_text:
+ * backend_get_updates:
  */
-static const gchar *
-pk_backend_bool_to_text (gboolean value)
+static void
+backend_get_updates (PkBackend *backend, PkFilterEnum filters)
 {
-	if (value == TRUE) {
-		return "yes";
-	}
-	return "no";
+	pk_backend_dbus_get_updates (dbus, filters);
 }
 
 /**
- * backend_get_depends:
- */
+ * backend_refresh_cache:
+ * */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, const gchar *package_id, gboolean recursive)
+backend_refresh_cache (PkBackend *backend, gboolean force)
 {
-	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
-	pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL);
-	g_free (filters_text);
+	// check network state
+	if (!pk_backend_is_online (backend)) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
+		pk_backend_finished (backend);
+		return;
+	}
+
+	pk_backend_dbus_refresh_cache(dbus, force);
 }
 
 /**
- * backend_get_updates:
- */
+ * pk_backend_update_system:
+ * */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_update_system (PkBackend *backend)
 {
-	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
-	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
-	g_free (filters_text);
+	pk_backend_dbus_update_system (dbus);
 }
 
 /**
- * backend_get_update_detail:
- */
+ * backend_install_packages
+ *  */
 static void
-backend_get_update_detail (PkBackend *backend, const gchar *package_id)
+backend_install_packages (PkBackend *backend, gchar **package_ids)
 {
-	pk_backend_spawn_helper (spawn, "get-update-detail.py", package_id, NULL);
+	pk_backend_dbus_install_packages (dbus, package_ids);
 }
 
 /**
- * backend_install_packages:
- */
+ * backend_remove_packages
+ *  */
 static void
-backend_install_packages (PkBackend *backend, gchar **package_ids)
+backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
 {
-	gchar *package_ids_temp;
-
-	/* check network state */
-	if (!pk_backend_is_online (backend)) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
-		pk_backend_finished (backend);
-		return;
-	}
-
-	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
-	pk_backend_spawn_helper (spawn, "install-packages.py", package_ids_temp, NULL);
-	g_free (package_ids_temp);
+	pk_backend_dbus_remove_packages (dbus, package_ids, allow_deps, autoremove);
 }
 
 /**
- * backend_refresh_cache:
- */
+ * backend_get_details:
+ *  */
 static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
+backend_get_details (PkBackend *backend, const gchar *package_id)
 {
-	/* check network state */
-	if (!pk_backend_is_online (backend)) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
-		pk_backend_finished (backend);
-		return;
-	}
-
-	pk_backend_spawn_helper (spawn, "refresh-cache.py", NULL);
+	pk_backend_dbus_get_details (dbus, package_id);
 }
 
 /**
- * pk_backend_remove_packages:
- * 
+ *  * pk_backend_search_details:
+ *   */
 static void
-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
+backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
 {
-	gchar *package_ids_temp;
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
-	pk_backend_spawn_helper (spawn, "remove-packages.py", pk_backend_bool_to_text (allow_deps), package_ids_temp, NULL);
-	g_free (package_ids_temp);
-} */
+	pk_backend_dbus_search_details (dbus, filters, search);
+}
 
 /**
- * pk_backend_update_packages:
- */
+ *  * pk_backend_search_name:
+ *   */
 static void
-backend_update_packages (PkBackend *backend, gchar **package_ids)
+backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
 {
-	gchar *package_ids_temp;
-
-	/* check network state */
-	if (!pk_backend_is_online (backend)) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
-		pk_backend_finished (backend);
-		return;
-	}
-
-	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
-	pk_backend_spawn_helper (spawn, "update-packages.py", package_ids_temp, NULL);
-	g_free (package_ids_temp);
+	pk_backend_dbus_search_name (dbus, filters, search);
 }
 
 /**
- * pk_backend_update_system:
- */
+ *  * pk_backend_cancel:
+ *   */
 static void
-backend_update_system (PkBackend *backend)
+backend_cancel (PkBackend *backend)
 {
-	pk_backend_spawn_helper (spawn, "update-system.py", NULL);
+	pk_backend_dbus_cancel (dbus);
 }
 
 /**
- * pk_backend_resolve:
- */
+ *  * pk_backend_resolve:
+ *   */
 static void
 backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id)
 {
-	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
-	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_id, NULL);
-	g_free (filters_text);
+	        pk_backend_dbus_resolve (dbus, filters, package_id);
 }
 
 /**
- * pk_backend_get_repo_list:
- */
+ *  * pk_backend_get_packages:
+ *   */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkFilterEnum filters)
 {
-	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
-	pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL);
-	g_free (filters_text);
+	        pk_backend_dbus_get_packages (dbus, filters);
 }
 
+
+
 PK_BACKEND_OPTIONS (
-	"Apt (with " APT_SEARCH " searching)",				/* description */
-	"Ali Sabil <ali.sabil at gmail.com>; Tom Parker <palfrey at tevp.net>",	/* author */
+	"Apt",					/* description */
+	"Ali Sabil <ali.sabil at gmail.com>; Tom Parker <palfrey at tevp.net>; Sebastian Heinlein <glatzor at ubuntu.com>",	/* author */
 	backend_initialize,			/* initalize */
 	backend_destroy,			/* destroy */
 	backend_get_groups,			/* get_groups */
 	backend_get_filters,			/* get_filters */
-	NULL,					/* cancel */
-	backend_get_depends,			/* get_depends */
+	backend_cancel,				/* cancel */
+	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_files */
-	NULL,					/* get_packages */
-	backend_get_repo_list,			/* get_repo_list */
+	backend_get_packages,			/* get_packages */
+	NULL,					/* get_repo_list */
 	NULL,					/* get_requires */
-	backend_get_update_detail,		/* get_update_detail */
+	NULL,					/* get_update_detail */
 	backend_get_updates,			/* get_updates */
 	NULL,					/* install_files */
 	backend_install_packages,		/* install_packages */
 	NULL,					/* install_signature */
 	backend_refresh_cache,			/* refresh_cache */
-	NULL,					/* remove_packages */
+	backend_remove_packages,		/* remove_packages */
 	NULL,					/* repo_enable */
 	NULL,					/* repo_set_data */
 	backend_resolve,			/* resolve */
 	NULL,					/* rollback */
 	backend_search_details,			/* search_details */
 	NULL,					/* search_file */
-	backend_search_group,			/* search_group */
+	NULL,					/* search_group */
 	backend_search_name,			/* search_name */
 	NULL,					/* service_pack */
-	backend_update_package,			/* update_package */
+	NULL,					/* update_packages */
 	backend_update_system,			/* update_system */
 	NULL					/* what_provides */
 );
diff --git a/backends/apt/pk-sqlite-pkg-cache.cpp b/backends/apt/pk-sqlite-pkg-cache.cpp
deleted file mode 100644
index 1bf9a50..0000000
--- a/backends/apt/pk-sqlite-pkg-cache.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include "pk-sqlite-pkg-cache.h"
-
-static sqlite3 *db = NULL;
-static PkBackend *backend;
-static gboolean(*is_installed) (const PkPackageId *) = NULL;
-
-void sqlite_set_installed_check(gboolean(*func) (const PkPackageId *))
-{
-	is_installed = func;
-}
-
-void
-sqlite_init_cache(PkBackend *backend, const char* dbname, const char *compare_fname, void (*build_db)(PkBackend *, sqlite3 *))
-{
-	int ret;
-	struct stat st;
-	time_t db_age;
-
-	ret = sqlite3_open (dbname, &db);
-	g_assert(ret == SQLITE_OK);
-	g_assert(db!=NULL);
-	ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
-	g_assert(ret == SQLITE_OK);
-
-	g_stat(dbname, &st);
-	db_age = st.st_mtime;
-	g_stat(compare_fname, &st);
-	if (db_age>=st.st_mtime)
-	{
-		ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL);
-		if (ret != SQLITE_ERROR)
-			return;
-		pk_debug("ages are %lu for db, and %lu for comparism",db_age,st.st_mtime);
-	}
-	ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it!
-	//g_assert(ret == SQLITE_OK);
-	pk_debug("wiped db");
-	ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
-	g_assert(ret == SQLITE_OK);
-
-	build_db(backend,db);
-
-	sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL);
-	sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL);
-}
-
-void sqlite_finish_cache(PkBackend *backend)
-{
-	sqlite3_close(db);
-}
-
-// sqlite_search_packages_thread
-static gboolean
-sqlite_search_packages_thread (PkBackend *backend)
-{
-	int res;
-	gchar *sel;
-	const gchar *search;
-
-	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
-	type = pk_backend_get_uint (backend, "type");
-	search = pk_backend_get_string (backend, "search");
-
-	pk_debug("finding %s", search);
-
-	sqlite3_stmt *package = NULL;
-	g_strdelimit(search," ",'%');
-
-	if (type == SEARCH_NAME)
-		sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",search);
-	else if (type == SEARCH_DETAILS)
-		sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%' or short_desc like '%%%s%%' or long_desc like '%%%s%%'",search, search, search);
-	else
-	{
-		pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Unknown search task type");
-		goto end_search_packages;
-	}
-
-	pk_debug("statement is '%s'",sel);
-	res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
-	g_free(sel);
-	if (res!=SQLITE_OK)
-		pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
-	res = sqlite3_step(package);
-	while (res == SQLITE_ROW)
-	{
-		PkPackageId *pid = pk_package_id_new_from_list((const gchar*)sqlite3_column_text(package,0),
-				(const gchar*)sqlite3_column_text(package,1),
-				(const gchar*)sqlite3_column_text(package,2),
-				(const gchar*)sqlite3_column_text(package,3));
-
-		gchar *cpid = pk_package_id_to_string(pid);
-		PkInfoEnum pie = PK_INFO_ENUM_UNKNOWN;
-
-		if (is_installed != NULL)
-			pie = is_installed(pid)?PK_INFO_ENUM_INSTALLED:PK_INFO_ENUM_AVAILABLE;
-
-		pk_backend_package(backend, pie, cpid, (const gchar*)sqlite3_column_text(package,4));
-
-		g_free(cpid);
-		pk_package_id_free(pid);
-
-		if (res==SQLITE_ROW)
-			res = sqlite3_step(package);
-	}
-	if (res!=SQLITE_DONE)
-	{
-		pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
-		g_assert(0);
-	}
-
-end_search_packages:
-	pk_backend_finished (backend);
-	return TRUE;
-}
-
-/**
- * sqlite_search_details:
- */
-void
-sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	pk_backend_set_uint (backend, "type", SEARCH_DETAILS);
-	pk_backend_thread_create (backend, sqlite_search_packages_thread);
-}
-
-/**
- * sqlite_search_name:
- */
-void
-sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
-{
-	pk_backend_set_uint (backend, "type", SEARCH_NAME);
-	pk_backend_thread_create (backend, sqlite_search_packages_thread);
-}
-
-// sqlite_get_details_thread
-static gboolean
-sqlite_get_details_thread (PkBackend *backend)
-{
-	PkPackageId *pi;
-	const gchar *package_id;
-	int res;
-
-	package_id = pk_backend_get_string (backend, "package_id");
-	pi = pk_package_id_new_from_string(package_id);
-	if (pi == NULL)
-	{
-		pk_backend_error_code(backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
-		pk_backend_finished(backend);
-		return;
-	}
-
-	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
-
-	pk_debug("finding %s", pi->name);
-
-	sqlite3_stmt *package = NULL;
-	gchar *sel = g_strdup_printf("select long_desc from packages where name = '%s' and version = '%s' and repo = '%s'",pi->name,pi->version,pi->data);
-	pk_debug("statement is '%s'",sel);
-	res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
-	g_free(sel);
-	if (res!=SQLITE_OK)
-		pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
-	res = sqlite3_step(package);
-	pk_backend_details(backend,pi->name, "unknown", PK_GROUP_ENUM_OTHER,(const gchar*)sqlite3_column_text(package,0),"",0);
-	res = sqlite3_step(package);
-	if (res==SQLITE_ROW)
-		pk_error("multiple matches for that package!");
-	if (res!=SQLITE_DONE)
-	{
-		pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
-		g_assert(0);
-	}
-
-	g_free(dt);
-
-	return TRUE;
-}
-
-/**
- * sqlite_get_details:
- */
-extern "C++" void
-sqlite_get_details (PkBackend *backend, const gchar *package_id)
-{
-	pk_backend_thread_create (backend, sqlite_get_details_thread);
-	return;
-}
-
diff --git a/backends/apt/pk-sqlite-pkg-cache.h b/backends/apt/pk-sqlite-pkg-cache.h
deleted file mode 100644
index 68fad42..0000000
--- a/backends/apt/pk-sqlite-pkg-cache.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef SQLITE_PKT_CACHE
-#define SQLITE_PKT_CACHE
-
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-typedef enum {
-	SEARCH_NAME = 1,
-	SEARCH_DETAILS,
-	SEARCH_FILE
-} SearchDepth;
-
-#include <pk-backend.h>
-#include <sqlite3.h>
-
-void sqlite_init_cache(PkBackend *backend, const char* dbname, const char* compare_fname, void (*build_db)(PkBackend *, sqlite3 *db));
-void sqlite_finish_cache(PkBackend *backend);
-
-void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
-void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
-void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func);
-void sqlite_get_details (PkBackend *backend, const gchar *package_id);
-
-#endif
diff --git a/backends/apt/profiler.py b/backends/apt/profiler.py
new file mode 100644
index 0000000..1b5d30f
--- /dev/null
+++ b/backends/apt/profiler.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Copyright (C) 2008
+#    Sebastian Heinlein <sebi at glatzor.de>
+
+"""
+Allows to start the apt2 backend in a profling mode
+"""
+
+__author__ = "Sebastian Heinlein <devel at glatzor.de>"
+
+
+import hotshot
+import sys
+
+from aptDBUSBackend import main
+
+if len(sys.argv) == 2:
+    profile = sys.argv[1]
+else:
+    profile = "profile"
+
+prof = hotshot.Profile(profile)
+print prof.runcall(main)
+prof.close()
diff --git a/backends/apt/test.py b/backends/apt/test.py
new file mode 100755
index 0000000..a1d5ffb
--- /dev/null
+++ b/backends/apt/test.py
@@ -0,0 +1,98 @@
+#!/usr/bin/python
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Copyright (C) 2007
+#    Tim Lauridsen <timlau at fedoraproject.org>
+
+import sys
+import dbus
+from packagekit.enums import *
+
+PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
+PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend'
+PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend'
+PKG_ID = 'xterm;232-1;i386;Debian'
+
+try:
+    bus = dbus.SystemBus()
+except dbus.DBusException, e:
+    print  "Unable to connect to dbus"
+    print "%s" %(e,)
+    sys.exit(1)
+
+try:
+    proxy = bus.get_object(PACKAGEKIT_DBUS_SERVICE, PACKAGEKIT_DBUS_PATH)
+    iface = dbus.Interface(proxy, PACKAGEKIT_DBUS_INTERFACE)
+    cmd = sys.argv[1]
+    if cmd == 'init' or cmd == 'all':
+        print "Testing Init()"
+        iface.Init()
+    if cmd == 'cancel':
+        print "Canceling"
+        iface.Cancel()
+    if cmd == 'get-updates' or cmd == 'all':
+        print "Testing GetUpdate()"
+        iface.GetUpdates()
+    if cmd == 'search-name' or cmd == 'all':
+        print "Testing SearchName(FILTER_NONE,'apt')"
+        iface.SearchName(FILTER_NONE,'apt')
+    if cmd == 'search-details' or cmd == 'all':
+        print "SearchDetails(FILTER_NONE,'dbus')"
+        iface.SearchDetails(FILTER_NONE,'dbus')
+    if cmd == 'search-group' or cmd == 'all':
+        print "Testing SearchGroup(FILTER_NONE,GROUP_GAMES)"
+        iface.SearchGroup(FILTER_NONE,GROUP_GAMES)
+    if cmd == 'search-file' or cmd == 'all':
+        print "Testing SearchFile(FILTER_NONE,'/usr/bin/yum')"
+        iface.SearchFile(FILTER_NONE,'/usr/bin/yum')
+    if cmd == 'get-requires' or cmd == 'all':
+        print "Testing GetRequires(PKG_ID,False)"
+        iface.GetRequires(PKG_ID,False)
+    if cmd == 'get-depends' or cmd == 'all':
+        print "Testing GetDepends(PKG_ID,False)"
+        iface.GetDepends(PKG_ID,False)
+    if cmd == 'refresh-cache' or cmd == 'all':
+        print "Testing RefreshCache()"
+        iface.RefreshCache()
+    if cmd == 'resolve' or cmd == 'all':
+        print "Testing Resolve(FILTER_NONE,'yum')"
+        iface.Resolve(FILTER_NONE,'yum')
+    if cmd == 'get-details' or cmd == 'all':
+        print "Testing GetDetails(PKG_ID)"
+        iface.GetDetails(PKG_ID)
+    if cmd == 'get-files' or cmd == 'all':
+        print "Testing GetFiles(PKG_ID)"
+        iface.GetFiles(PKG_ID)
+    if cmd == 'get-packages' or cmd == 'all':
+        print "Testing GetPackages(FILTER_INSTALLED,'no')"
+        iface.GetPackages(FILTER_INSTALLED,'no')
+    if cmd == 'get-repolist' or cmd == 'all':
+        print "Testing GetRepoList()"
+        iface.GetRepoList()
+    if cmd == 'get-updatedetail' or cmd == 'all':
+        print "Testing GetUpdateDetail(PKG_ID)"
+        iface.GetUpdateDetail(PKG_ID)
+    #print "Testing "
+    #iface.
+    if cmd == 'exit' or cmd == 'all':
+        print "Testing Exit()"
+        iface.Exit()
+    
+except dbus.DBusException, e:
+    print "Unable to send message on dbus"
+    print "%s" %(e,)
+    sys.exit(1)
diff --git a/backends/apt2/.gitignore b/backends/apt2/.gitignore
deleted file mode 100644
index c851833..0000000
--- a/backends/apt2/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-*.la
-*.lo
-*.loT
-*.o
-*~
-
diff --git a/backends/apt2/HACKING b/backends/apt2/HACKING
deleted file mode 100644
index 2b99c5d..0000000
--- a/backends/apt2/HACKING
+++ /dev/null
@@ -1,5 +0,0 @@
-The backend can be tested by running it as root from the source code
-repository. Make sure to kill packagekitd before to force a reintializing
-of the cache:
-
-  killall packagekitd; python aptDBUSBackend.py 
diff --git a/backends/apt2/Makefile.am b/backends/apt2/Makefile.am
deleted file mode 100644
index 91c0c46..0000000
--- a/backends/apt2/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-NULL = 
-
-plugindir = $(PK_PLUGIN_DIR)
-plugin_LTLIBRARIES = libpk_backend_apt2.la
-libpk_backend_apt2_la_SOURCES = pk-backend-apt2.c
-libpk_backend_apt2_la_LIBADD = $(PK_PLUGIN_LIBS)
-libpk_backend_apt2_la_LDFLAGS = -module -avoid-version
-libpk_backend_apt2_la_CFLAGS = $(PK_PLUGIN_CFLAGS)
-
-dbusinstancedir = $(LIBEXECDIR)
-dbusinstance_DATA =                                     \
-        aptDBUSBackend.py                               \
-        $(NULL)
-
-EXTRA_DIST =                                            \
-        $(dbusinstance_DATA)                            \
-        $(NULL)
-
-install-data-hook:
-	chmod a+rx $(DESTDIR)$(libexecdir)/*.py
-
-clean-local :
-	rm -f *~
-	rm -f *.pyc
-
diff --git a/backends/apt2/README b/backends/apt2/README
deleted file mode 100644
index 0a3da6e..0000000
--- a/backends/apt2/README
+++ /dev/null
@@ -1,23 +0,0 @@
-The name of this backend is apt2.
-
-It supports apt which is mainly used by Debian and its derivates. In contrast to
-the backend called apt this one uses DBus for the communication with the 
-packagekit daemon. This allows to perform actions without having to reopen
-the cache for each one.
-
-To provide a tremendously fast search function a Xapian database is used.
-It is provided by Enrico Zini's apt-xapian-index. Debtags will be used to 
-enhance the quality of the search results further.
-
-A list of implemented functions are listed in the PackageKit FAQ:
-
-http://www.packagekit.org/pk-faq.html
-
-You can find packages for Ubuntu here:
-
-https://www.launchpad.net/~packagekit/+ppa
-
-Packages for Debian Unstable will be provided soon.
-
-Feel free to send comments or bug reports to the PackageKit mailing list
-or to the author.
diff --git a/backends/apt2/TODO b/backends/apt2/TODO
deleted file mode 100644
index bee2f3d..0000000
--- a/backends/apt2/TODO
+++ /dev/null
@@ -1,70 +0,0 @@
-ISSUES:
-
- * Support delayed or hidden debconf questions
-
-Unresolved issues can be discussed at the following wiki page:
-http://wiki.debian.org/PackageKit
-
-
-TODO:
-
- * Implement all open backend methods. A list of implemented backend methods 
-   can be found in PackageKit FAQ or in pk-backend-apt2.c.
-
- * Blacklist packages requiring input on the terminal and try to change
-   the Debian policy in the long run. Way of automation?
- 
- * Allow to inject alternative apt.package.Package classes into the
-   cache to support PackageKit and distribution specific needs
-   (e.g. when is a package called free or supported)
-
- * Allow to reinject debtags into the search results to get 
-   similar software which not matches on the search terms
-
- * Index file list and add properties for package name and section to
-   the xapian database to also make use of it in search group and 
-   search name (do we want this?)
-
- * Map Debian/Ubuntu sections to PackageKit groups:
-    - admin : System Administration 		=> admin-tools
-    - base : Base System 			=> system
-    - comm : Communication			=> communication
-    - devel : Development 			=> programming
-    - doc : Documentation			=> ???
-    - editors : Editors				=> accessoires
-    - electronics : Electronics			=> other
-    - embedded : Embedded Devices		=> system
-    - games : Games and Amusement 		=> games
-    - gnome : GNOME Desktop Environment		=> desktop-gnome
-    - graphics : Graphics			=> graphics
-    - hamradio : Amateur Radio			=> communication
-    - interpreters : Interpreted Computer L.	=> programming
-    - kde : KDE Desktop Environment		=> desktop-kde
-    - libdevel : Libraries - Development	=> programming
-    - libs : Libraries				=> system
-    - mail : Email				=> internet
-    - math : Mathematics			=> ??? science/education
-    - misc : Miscellaneous - Text Based		=> other
-    - net : Networkinga				=> network
-    - news : Newsgroup				=> internet
-    - oldlibs : Libraries - Old			=> legacy
-    - otherosfs : Cross Platform		=> system
-    - perl : Perl Programming Language		=> programming
-    - python : Python Programming Language	=> programming
-    - science : Science				=> ??? science/education
-    - shells : Shells				=> system
-    - sound : Multimedia			=> multimedia
-    - tex : TeX Authoring			=> publishing
-    - text : Word Processing			=> publishing
-    - utils : Utilities				=> accessoires
-    - web : World Wide Web			=> internet
-    - x11 : Miscellaneous  - Graphical		=> desktop-other
-    - unknown : Unknown				=> unknown
-    - alien : Converted From RPM by Alien"	=> unknown
-    - translations 				=> localization
-  The following could not be maped: science, documentation, electronics
-  Are there any derivates with additional sections?
-
- * Fix the dbus policy. Should we require at_console for searching?
- 
-DONE:
diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
deleted file mode 100755
index 22eb714..0000000
--- a/backends/apt2/aptDBUSBackend.py
+++ /dev/null
@@ -1,679 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-Provides an apt backend to PackageKit
-
-Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
-Copyright (C) 2008 Sebastian Heinlein <glatzor at ubuntu.com>
-
-Licensed under the GNU General Public License Version 2
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-"""
-
-__author__  = "Sebastian Heinlein <devel at glatzor.de>"
-__state__   = "experimental"
-
-import os
-import pty
-import re
-import signal
-import time
-import threading
-import warnings
-
-import apt
-import apt_pkg
-import dbus
-import dbus.glib
-import dbus.service
-import dbus.mainloop.glib
-import gobject
-
-from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, async
-from packagekit.enums import *
-
-warnings.filterwarnings(action='ignore', category=FutureWarning)
-
-PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
-
-XAPIANDBPATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index")
-XAPIANDB = XAPIANDBPATH + "/index"
-XAPIANDBVALUES = XAPIANDBPATH + "/values"
-
-# Required for daemon mode
-os.putenv("PATH",
-          "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
-# Avoid questions from the maintainer scripts as far as possible
-os.putenv("DEBIAN_FRONTEND", "noninteractive")
-os.putenv("APT_LISTCHANGES_FRONTEND", "none")
-
-# Setup threading support
-gobject.threads_init()
-dbus.glib.threads_init()
-
-class PackageKitOpProgress(apt.progress.OpProgress):
-    '''
-    Handle the cache opening process
-    '''
-    def __init__(self, backend, prange=(0,100), progress=True):
-        self._backend = backend
-        apt.progress.OpProgress.__init__(self)
-        self.steps = []
-        for v in [0.12, 0.25, 0.50, 0.75, 1.00]:
-            s = prange[0] + (prange[1] - prange[0]) * v
-            self.steps.append(s)
-        self.pstart = float(prange[0])
-        self.pend = self.steps.pop(0)
-        self.pprev = None
-        self.show_progress = progress
-
-    # OpProgress callbacks
-    def update(self, percent):
-        progress = int(self.pstart + percent / 100 * (self.pend - self.pstart))
-        if self.show_progress == True and self.pprev < progress:
-            self._backend.PercentageChanged(progress)
-            self.pprev = progress
-
-    def done(self):
-        self.pstart = self.pend
-        try:
-            self.pend = self.steps.pop(0)
-        except:
-            pklog.warning("An additional step to open the cache is required")
-
-class PackageKitFetchProgress(apt.progress.FetchProgress):
-    '''
-    Handle the package download process
-    '''
-    def __init__(self, backend, prange=(0,100)):
-        self._backend = backend
-        apt.progress.FetchProgress.__init__(self)
-        self.pstart = prange[0]
-        self.pend = prange[1]
-        self.pprev = None
-
-    # FetchProgress callbacks
-    def pulse(self):
-        if self._backend._canceled.isSet():
-            return False
-        percent = ((self.currentBytes + self.currentItems)*100.0)/float(self.totalBytes+self.totalItems)
-        progress = int(self.pstart + percent/100 * (self.pend - self.pstart))
-        if self.pprev < progress:
-            self._backend.PercentageChanged(progress)
-            self.pprev = progress
-        apt.progress.FetchProgress.pulse(self)
-        return True
-
-    def start(self):
-        self._backend.StatusChanged(STATUS_DOWNLOAD)
-        self._backend.AllowCancel(True)
-
-    def stop(self):
-        self._backend.PercentageChanged(self.pend)
-        self._backend.AllowCancel(False)
-
-    def mediaChange(self, medium, drive):
-        #FIXME: use the Message method to notify the user
-        self._backend.error(ERROR_UNKNOWN,
-                            "Medium change needed")
-
-class PackageKitInstallProgress(apt.progress.InstallProgress):
-    '''
-    Handle the installation and removal process. Bits taken from
-    DistUpgradeViewNonInteractive.
-    '''
-    def __init__(self, backend, prange=(0,100)):
-        apt.progress.InstallProgress.__init__(self)
-        self._backend = backend
-        self.timeout = 900
-        self.pstart = prange[0]
-        self.pend = prange[1]
-        self.pprev = None
-
-    def statusChange(self, pkg, percent, status):
-        progress = self.pstart + percent/100 * (self.pend - self.pstart)
-        if self.pprev < progress:
-            self._backend.PercentageChanged(int(progress))
-            self.pprev = progress
-        pklog.debug("PM status: %s" % status)
-
-    def startUpdate(self):
-        self._backend.StatusChanged(STATUS_INSTALL)
-        self.last_activity = time.time()
-
-    def updateInterface(self):
-        pklog.debug("Updating interface")
-        apt.progress.InstallProgress.updateInterface(self)
-
-    def conffile(self, current, new):
-        pklog.critical("Config file prompt: '%s'" % current)
-
-def sigquit(signum, frame):
-    pklog.error("Was killed")
-    sys.exit(1)
-
-class PackageKitAptBackend(PackageKitBaseBackend):
-    '''
-    PackageKit backend for apt
-    '''
-    def __init__(self, bus_name, dbus_path):
-        pklog.info("Initializing APT backend")
-        signal.signal(signal.SIGQUIT, sigquit)
-        self._cache = None
-        self._canceled = threading.Event()
-        self._canceled.clear()
-        self._lock = threading.Lock()
-        # Check for xapian support
-        self._use_xapian = False
-        try:
-            import xapian
-        except ImportError:
-            pass
-        else:
-            if os.access(XAPIANDB, os.R_OK):
-                self._use_xapian = True
-        PackageKitBaseBackend.__init__(self, bus_name, dbus_path)
-
-    # Methods ( client -> engine -> backend )
-
-    def doInit(self):
-        pklog.info("Initializing cache")
-        self.StatusChanged(STATUS_SETUP)
-        self.AllowCancel(False)
-        self.NoPercentageUpdates()
-        self._open_cache(progress=False)
-
-    def doExit(self):
-        pass
-
-    @threaded
-    def doCancel(self):
-        pklog.info("Canceling current action")
-        self.StatusChanged(STATUS_CANCEL)
-        self._canceled.set()
-        self._canceled.wait()
-
-    @threaded
-    def doSearchName(self, filters, search):
-        '''
-        Implement the apt2-search-name functionality
-        '''
-        pklog.info("Searching for package name: %s" % search)
-        self.StatusChanged(STATUS_QUERY)
-        self.NoPercentageUpdates()
-        self._check_init(progress=False)
-        self.AllowCancel(True)
-
-        for pkg in self._cache:
-            if self._canceled.isSet():
-                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
-                               "The search was canceled")
-                self.Finished(EXIT_KILL)
-                self._canceled.clear()
-                return
-            elif search in pkg.name and self._is_package_visible(pkg, filters):
-                self._emit_package(pkg)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    def doSearchDetails(self, filters, search):
-        '''
-        Implement the apt2-search-details functionality
-        '''
-        pklog.info("Searching for package name: %s" % search)
-        self.StatusChanged(STATUS_QUERY)
-        self.NoPercentageUpdates()
-        self._check_init(progress=False)
-        self.AllowCancel(True)
-        results = []
-
-        if self._use_xapian == True:
-            search_flags = (xapian.QueryParser.FLAG_BOOLEAN |
-                            xapian.QueryParser.FLAG_PHRASE |
-                            xapian.QueryParser.FLAG_LOVEHATE |
-                            xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE)
-            pklog.debug("Performing xapian db based search")
-            db = xapian.Database(XAPIANDB)
-            parser = xapian.QueryParser()
-            query = parser.parse_query(unicode(search),
-                                       search_flags)
-            enquire = xapian.Enquire(db)
-            enquire.set_query(query)
-            matches = enquire.get_mset(0, 1000)
-            for r in  map(lambda m: m[xapian.MSET_DOCUMENT].get_data(),
-                          enquire.get_mset(0,1000)):
-                if self._cache.has_key(r):
-                    results.append(self._cache[r])
-        else:
-            pklog.debug("Performing apt cache based search")
-            for p in self._cache._dict.values():
-                if self._check_canceled("Search was canceled"): return
-                needle = search.strip().lower()
-                haystack = p.description.lower()
-                if p.name.find(needle) >= 0 or haystack.find(needle) >= 0:
-                    results.append(p)
-
-        for r in results:
-            if self._check_canceled("Search was canceled"): return
-            if self._is_package_visible(r, filters) == True:
-                self._emit_package(r)
-
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    @async
-    def doGetUpdates(self, filters):
-        '''
-        Implement the {backend}-get-update functionality
-        '''
-        #FIXME: Implment the basename filter
-        pklog.info("Get updates")
-        self.StatusChanged(STATUS_INFO)
-        self.AllowCancel(True)
-        self.NoPercentageUpdates()
-        self._check_init(progress=False)
-        self._cache.upgrade(False)
-        for pkg in self._cache.getChanges():
-            if self._canceled.isSet():
-                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
-                               "Calculating updates was canceled")
-                self.Finished(EXIT_KILL)
-                self._canceled.clear()
-                return
-            else:
-                self._emit_package(pkg)
-        self._open_cache(progress=False)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    def GetDetails(self, pkg_id):
-        '''
-        Implement the {backend}-get-details functionality
-        '''
-        pklog.info("Get details of %s" % pkg_id)
-        self.StatusChanged(STATUS_INFO)
-        self.NoPercentageUpdates()
-        self.AllowCancel(False)
-        self._check_init(progress=False)
-        name, version, arch, data = self.get_package_from_id(pkg_id)
-        if not self._cache.has_key(name):
-            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
-                           "Package %s isn't available" % name)
-            self.Finished(EXIT_FAILED)
-            return
-        pkg = self._cache[name]
-        #FIXME: should perhaps go to python-apt since we need this in
-        #       several applications
-        desc = pkg.description
-        # Skip the first line - it's a duplicate of the summary
-        i = desc.find('\n')
-        desc = desc[i+1:]
-        # do some regular expression magic on the description
-        # Add a newline before each bullet
-        p = re.compile(r'^(\s|\t)*(\*|0|-)',re.MULTILINE)
-        desc = p.sub(ur'\n\u2022', desc)
-        # replace all newlines by spaces
-        p = re.compile(r'\n', re.MULTILINE)
-        desc = p.sub(" ", desc)
-        # replace all multiple spaces by newlines
-        p = re.compile(r'\s\s+', re.MULTILINE)
-        desc = p.sub('\n', desc)
-        #FIXME: group and licence information missing
-        self.Details(pkg_id, 'unknown', 'unknown', desc,
-                         pkg.homepage, pkg.packageSize)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    @async
-    def doUpdateSystem(self):
-        '''
-        Implement the {backend}-update-system functionality
-        '''
-        pklog.info("Upgrading system")
-        self.StatusChanged(STATUS_UPDATE)
-        self.AllowCancel(False)
-        self.PercentageChanged(0)
-        self._check_init(prange=(0,5))
-        try:
-            self._cache.upgrade(distUpgrade=False)
-            self._cache.commit(PackageKitFetchProgress(self, prange=(5,50)),
-                               PackageKitInstallProgress(self, prange=(50,95)))
-        except apt.cache.FetchFailedException:
-            self._open_cache()
-            self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED, "Download failed")
-            self.Finished(EXIT_FAILED)
-            return
-        except apt.cache.FetchCancelledException:
-            self._open_cache(prange=(95,100))
-            self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled")
-            self.Finished(EXIT_KILL)
-            self._canceled.clear()
-            return
-        except:
-            self._open_cache(prange=(95,100))
-            self.ErrorCode(ERROR_UNKNOWN, "System update failed")
-            self.Finished(EXIT_FAILED)
-            return
-        self.PercentageChanged(100)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    @async
-    def doRemovePackages(self, ids, deps=True, auto=False):
-        '''
-        Implement the {backend}-remove functionality
-        '''
-        pklog.info("Removing package(s): id %s" % ids)
-        self.StatusChanged(STATUS_REMOVE)
-        self.AllowCancel(False)
-        self.PercentageChanged(0)
-        self._check_init(prange=(0,10))
-        pkgs=[]
-        for id in ids:
-            pkg = self._find_package_by_id(id)
-            if pkg == None:
-                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
-                               "Package %s isn't available" % id)
-                self.Finished(EXIT_FAILED)
-                return
-            if not pkg.isInstalled:
-                self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED,
-                               "Package %s isn't installed" % pkg.name)
-                self.Finished(EXIT_FAILED)
-                return
-            pkgs.append(pkg.name[:])
-            try:
-                pkg.markDelete()
-            except:
-                self._open_cache(prange=(90,99))
-                self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name)
-                self.Finished(EXIT_FAILED)
-                return
-        try:
-            self._cache.commit(PackageKitFetchProgress(self, prange=(10,10)),
-                               PackageKitInstallProgress(self, prange=(10,90)))
-        except:
-            self._open_cache(prange=(90,99))
-            self.ErrorCode(ERROR_UNKNOWN, "Removal failed")
-            self.Finished(EXIT_FAILED)
-            return
-        self._open_cache(prange=(90,99))
-        for p in pkgs:
-            if self._cache.has_key(p) and self._cache[p].isInstalled:
-                self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p)
-                self.Finished(EXIT_FAILED)
-                return
-        self.PercentageChanged(100)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    @async
-    def doInstallPackages(self, ids):
-        '''
-        Implement the {backend}-install functionality
-        '''
-        pklog.info("Installing package with id %s" % ids)
-        self.StatusChanged(STATUS_INSTALL)
-        self.AllowCancel(False)
-        self.PercentageChanged(0)
-        self._check_init(prange=(0,10))
-        pkgs=[]
-        for id in ids:
-            pkg = self._find_package_by_id(id)
-            if pkg == None:
-                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
-                               "Package %s isn't available" % id)
-                self.Finished(EXIT_FAILED)
-                return
-            if pkg.isInstalled:
-                self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
-                               "Package %s is already installed" % pkg.name)
-                self.Finished(EXIT_FAILED)
-                return
-            pkgs.append(pkg.name[:])
-            try:
-                pkg.markInstall()
-            except:
-                self._open_cache(prange=(90,100))
-                self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
-                                              "installation" % pkg.name)
-                self.Finished(EXIT_FAILED)
-                return
-        try:
-            self._cache.commit(PackageKitFetchProgress(self, prange=(10,50)),
-                               PackageKitInstallProgress(self, prange=(50,90)))
-        except:
-            self._open_cache(prange=(90,100))
-            self.ErrorCode(ERROR_UNKNOWN, "Installation failed")
-            self.Finished(EXIT_FAILED)
-            return
-        self._open_cache(prange=(90,100))
-        self.PercentageChanged(100)
-        pklog.debug("Checking success of operation")
-        for p in pkgs:
-            if not self._cache.has_key(p) or not self._cache[p].isInstalled:
-                self.ErrorCode(ERROR_UNKNOWN, "%s was not installed" % p)
-                self.Finished(EXIT_FAILED)
-                return
-        pklog.debug("Sending success signal")
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    @async
-    def doRefreshCache(self, force):
-        '''
-        Implement the {backend}-refresh_cache functionality
-        '''
-        pklog.info("Refresh cache")
-        self.StatusChanged(STATUS_REFRESH_CACHE)
-        self.last_action_time = time.time()
-        self.AllowCancel(False);
-        self.PercentageChanged(0)
-        self._check_init((0,10))
-        try:
-            self._cache.update(PackageKitFetchProgress(self, prange=(10,95)))
-        except apt.cache.FetchFailedException:
-            self.ErrorCode(ERROR_NO_NETWORK, "Download failed")
-            self.Finished(EXIT_FAILED)
-            return
-        except apt.cache.FetchCancelledException:
-            self._canceled.clear()
-            self.ErrorCode(ERROR_TRANSACTION_CANCELLED, "Download was canceled")
-            self.Finished(EXIT_KILL)
-            return
-        except:
-            self._open_cache(prange=(95,100))
-            self.ErrorCode(ERROR_UNKNOWN, "Refreshing cache failed")
-            self.Finished(EXIT_FAILED)
-            return
-        self.PercentageChanged(100)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    def doGetPackages(self, filters):
-        '''
-        Implement the apt2-get-packages functionality
-        '''
-        pklog.info("Get all packages")
-        self.StatusChanged(STATUS_QUERY)
-        self.NoPercentageUpdates()
-        self._check_init(progress=False)
-        self.AllowCancel(True)
-
-        for pkg in self._cache:
-            if self._canceled.isSet():
-                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
-                               "The search was canceled")
-                self.Finished(EXIT_KILL)
-                self._canceled.clear()
-                return
-            elif self._is_package_visible(pkg, filters):
-                self._emit_package(pkg)
-        self.Finished(EXIT_SUCCESS)
-
-    @threaded
-    def doResolve(self, filters, name):
-        '''
-        Implement the apt2-resolve functionality
-        '''
-        pklog.info("Resolve")
-        self.StatusChanged(STATUS_QUERY)
-        self.NoPercentageUpdates()
-        self._check_init(progress=False)
-        self.AllowCancel(False)
-
-        #FIXME: Support candidates
-        if self._cache.has_key(name) and self.is_package_visible(pkg, filters):
-            self._emit_package(name)
-            self.Finished(EXIT_SUCCESS)
-        else:
-            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
-                           "Package name %s could not be resolved" % name)
-            self.Finished(EXIT_FAILED)
-
-    # Helpers
-
-    def _open_cache(self, prange=(0,100), progress=True):
-        '''
-        (Re)Open the APT cache
-        '''
-        pklog.debug("Open APT cache")
-        self.StatusChanged(STATUS_REFRESH_CACHE)
-        try:
-            self._cache = apt.Cache(PackageKitOpProgress(self, prange,
-                                                         progress))
-        except:
-            self.ErrorCode(ERROR_NO_CACHE, "Package cache could not be opened")
-            self.Finished(EXIT_FAILED)
-            self.Exit()
-            return
-        if self._cache._depcache.BrokenCount > 0:
-            self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
-                           "Not all dependecies can be satisfied")
-            self.Finished(EXIT_FAILED)
-            self.Exit()
-            return
-
-    def _lock_cache(self):
-        '''
-        Lock the cache
-        '''
-        pklog.debug("Locking cache")
-        self._locked.acquire()
-
-    def _unlock_cache(self):
-        '''
-        Unlock the cache
-        '''
-        pklog.debug("Releasing cache")
-        self._locked.release()
-
-    def _check_init(self, prange=(0,10), progress=True):
-        '''
-        Check if the backend was initialized well and try to recover from
-        a broken setup
-        '''
-        pklog.debug("Check apt cache and xapian database")
-        if not isinstance(self._cache, apt.cache.Cache) or \
-           self._cache._depcache.BrokenCount > 0:
-            self._open_cache(prange, progress)
-
-    def _check_canceled(self, msg):
-        '''
-        Check if the current transaction was canceled. If so send the
-        corresponding error message and return True
-        '''
-        if self._canceled.isSet():
-             self.ErrorCode(ERROR_TRANSACTION_CANCELLED, msg)
-             self.Finished(EXIT_KILL)
-             self._canceled.clear()
-             return True
-        return False
- 
-    def get_id_from_package(self, pkg, installed=False):
-        '''
-        Return the id of the installation candidate of a core
-        apt package. If installed is set to True the id of the currently
-        installed package will be returned.
-        '''
-        origin = ''
-        if installed == False and pkg.isInstalled:
-            pkgver = pkg.installedVersion
-        else:
-            pkgver = pkg.candidateVersion
-            if pkg.candidateOrigin:
-                origin = pkg.candidateOrigin[0].label
-        id = self._get_package_id(pkg.name, pkgver, pkg.architecture, origin)
-        return id
-
-    def _emit_package(self, pkg):
-        '''
-        Send the Package signal for a given apt package
-        '''
-        id = self.get_id_from_package(pkg)
-        if pkg.isInstalled:
-            status = INFO_INSTALLED
-        else:
-            status = INFO_AVAILABLE
-        summary = pkg.summary
-        self.Package(status, id, summary)
-
-    def _is_package_visible(self, pkg, filters):
-        '''
-        Return True if the package should be shown in the user interface
-        '''
-        #FIXME: Needs to be optmized
-        if filters == 'none':
-            return True
-        if FILTER_INSTALLED in filters and not pkg.isInstalled:
-            return False
-        if FILTER_NOT_INSTALLED in filters and pkg.isInstalled:
-            return False
-        if FILTER_GUI in filters and not self._package_has_gui(pkg):
-            return False
-        if FILTER_NOT_GUI in filters and self._package_has_gui(pkg):
-            return False
-        if FILTER_DEVELOPMENT in filters and not self._package_is_devel(pkg):
-            return False
-        if FILTER_NOT_DEVELOPMENT in filters and self._package_is_devel(pkg):
-            return False
-        return True
-
-    def _package_has_gui(self, pkg):
-        #FIXME: should go to a modified Package class
-        #FIXME: take application data into account. perhaps checking for
-        #       property in the xapian database
-        return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde']
-
-    def _package_is_devel(self, pkg):
-        #FIXME: should go to a modified Package class
-        return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \
-               pkg.section.split('/')[-1].lower() in ['devel', 'libdevel']
-
-    def _find_package_by_id(self, id):
-        '''
-        Return a package matching to the given package id
-        '''
-        # FIXME: Perform more checks
-        name, version, arch, data = self.get_package_from_id(id)
-        if self._cache.has_key(name):
-            return self._cache[name]
-        else:
-            return None
-
-
-def main():
-    loop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-    bus = dbus.SystemBus(mainloop=loop)
-    bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus=bus)
-    manager = PackageKitAptBackend(bus_name, PACKAGEKIT_DBUS_PATH)
-
-if __name__ == '__main__':
-    main()
-
-# vim: ts=4 et sts=4
diff --git a/backends/apt2/packagekit b/backends/apt2/packagekit
deleted file mode 120000
index 0b64032..0000000
--- a/backends/apt2/packagekit
+++ /dev/null
@@ -1 +0,0 @@
-../../python/packagekit/
\ No newline at end of file
diff --git a/backends/apt2/pk-backend-apt2.c b/backends/apt2/pk-backend-apt2.c
deleted file mode 100644
index 70836b2..0000000
--- a/backends/apt2/pk-backend-apt2.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
- * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <pk-backend.h>
-#include <pk-backend-dbus.h>
-
-static PkBackendDbus *dbus;
-
-#define PK_DBUS_BACKEND_SERVICE_APT   "org.freedesktop.PackageKitAptBackend"
-
-/**
- * backend_initialize:
- * This should only be run once per backend load, i.e. not every transaction
- */
-static void
-backend_initialize (PkBackend *backend)
-{
-	pk_debug ("FILTER: initialize");
-	dbus = pk_backend_dbus_new ();
-	pk_backend_dbus_set_name (dbus, PK_DBUS_BACKEND_SERVICE_APT);
-}
-
-/**
- * backend_destroy:
- * This should only be run once per backend load, i.e. not every transaction
- */
-static void
-backend_destroy (PkBackend *backend)
-{
-	pk_debug ("FILTER: destroy");
-	pk_backend_dbus_kill (dbus);
-	g_object_unref (dbus);
-}
-
-/**
- * backend_get_groups:
- */
-static PkGroupEnum
-backend_get_groups (PkBackend *backend)
-{
-	return (PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_SYSTEM);
-}
-
-/**
- * backend_get_filters:
- */
-static PkFilterEnum
-backend_get_filters (PkBackend *backend)
-{
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
-}
-
-/**
- * backend_get_updates:
- */
-static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
-{
-	pk_backend_dbus_get_updates (dbus, filters);
-}
-
-/**
- * backend_refresh_cache:
- * */
-static void
-backend_refresh_cache (PkBackend *backend, gboolean force)
-{
-	// check network state
-	if (!pk_backend_is_online (backend)) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
-		pk_backend_finished (backend);
-		return;
-	}
-
-	pk_backend_dbus_refresh_cache(dbus, force);
-}
-
-/**
- * pk_backend_update_system:
- * */
-static void
-backend_update_system (PkBackend *backend)
-{
-	pk_backend_dbus_update_system (dbus);
-}
-
-/**
- * backend_install_packages
- *  */
-static void
-backend_install_packages (PkBackend *backend, gchar **package_ids)
-{
-	pk_backend_dbus_install_packages (dbus, package_ids);
-}
-
-/**
- * backend_remove_packages
- *  */
-static void
-backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
-{
-	pk_backend_dbus_remove_packages (dbus, package_ids, allow_deps, autoremove);
-}
-
-/**
- * backend_get_details:
- *  */
-static void
-backend_get_details (PkBackend *backend, const gchar *package_id)
-{
-	pk_backend_dbus_get_details (dbus, package_id);
-}
-
-/**
- *  * pk_backend_search_details:
- *   */
-static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
-{
-	pk_backend_dbus_search_details (dbus, filters, search);
-}
-
-/**
- *  * pk_backend_search_name:
- *   */
-static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
-{
-	pk_backend_dbus_search_name (dbus, filters, search);
-}
-
-/**
- *  * pk_backend_cancel:
- *   */
-static void
-backend_cancel (PkBackend *backend)
-{
-	pk_backend_dbus_cancel (dbus);
-}
-
-/**
- *  * pk_backend_resolve:
- *   */
-static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id)
-{
-	        pk_backend_dbus_resolve (dbus, filters, package_id);
-}
-
-/**
- *  * pk_backend_get_packages:
- *   */
-static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
-{
-	        pk_backend_dbus_get_packages (dbus, filters);
-}
-
-
-
-PK_BACKEND_OPTIONS (
-	"Apt",					/* description */
-	"Ali Sabil <ali.sabil at gmail.com>; Tom Parker <palfrey at tevp.net>; Sebastian Heinlein <glatzor at ubuntu.com>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	backend_get_groups,			/* get_groups */
-	backend_get_filters,			/* get_filters */
-	backend_cancel,				/* cancel */
-	NULL,					/* get_depends */
-	backend_get_details,			/* get_details */
-	NULL,					/* get_files */
-	backend_get_packages,			/* get_packages */
-	NULL,					/* get_repo_list */
-	NULL,					/* get_requires */
-	NULL,					/* get_update_detail */
-	backend_get_updates,			/* get_updates */
-	NULL,					/* install_files */
-	backend_install_packages,		/* install_packages */
-	NULL,					/* install_signature */
-	backend_refresh_cache,			/* refresh_cache */
-	backend_remove_packages,		/* remove_packages */
-	NULL,					/* repo_enable */
-	NULL,					/* repo_set_data */
-	backend_resolve,			/* resolve */
-	NULL,					/* rollback */
-	backend_search_details,			/* search_details */
-	NULL,					/* search_file */
-	NULL,					/* search_group */
-	backend_search_name,			/* search_name */
-	NULL,					/* service_pack */
-	NULL,					/* update_packages */
-	backend_update_system,			/* update_system */
-	NULL					/* what_provides */
-);
diff --git a/backends/apt2/profiler.py b/backends/apt2/profiler.py
deleted file mode 100644
index 1b5d30f..0000000
--- a/backends/apt2/profiler.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# Copyright (C) 2008
-#    Sebastian Heinlein <sebi at glatzor.de>
-
-"""
-Allows to start the apt2 backend in a profling mode
-"""
-
-__author__ = "Sebastian Heinlein <devel at glatzor.de>"
-
-
-import hotshot
-import sys
-
-from aptDBUSBackend import main
-
-if len(sys.argv) == 2:
-    profile = sys.argv[1]
-else:
-    profile = "profile"
-
-prof = hotshot.Profile(profile)
-print prof.runcall(main)
-prof.close()
diff --git a/backends/apt2/test.py b/backends/apt2/test.py
deleted file mode 100755
index a1d5ffb..0000000
--- a/backends/apt2/test.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/python
-# Licensed under the GNU General Public License Version 2
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# Copyright (C) 2007
-#    Tim Lauridsen <timlau at fedoraproject.org>
-
-import sys
-import dbus
-from packagekit.enums import *
-
-PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
-PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend'
-PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend'
-PKG_ID = 'xterm;232-1;i386;Debian'
-
-try:
-    bus = dbus.SystemBus()
-except dbus.DBusException, e:
-    print  "Unable to connect to dbus"
-    print "%s" %(e,)
-    sys.exit(1)
-
-try:
-    proxy = bus.get_object(PACKAGEKIT_DBUS_SERVICE, PACKAGEKIT_DBUS_PATH)
-    iface = dbus.Interface(proxy, PACKAGEKIT_DBUS_INTERFACE)
-    cmd = sys.argv[1]
-    if cmd == 'init' or cmd == 'all':
-        print "Testing Init()"
-        iface.Init()
-    if cmd == 'cancel':
-        print "Canceling"
-        iface.Cancel()
-    if cmd == 'get-updates' or cmd == 'all':
-        print "Testing GetUpdate()"
-        iface.GetUpdates()
-    if cmd == 'search-name' or cmd == 'all':
-        print "Testing SearchName(FILTER_NONE,'apt')"
-        iface.SearchName(FILTER_NONE,'apt')
-    if cmd == 'search-details' or cmd == 'all':
-        print "SearchDetails(FILTER_NONE,'dbus')"
-        iface.SearchDetails(FILTER_NONE,'dbus')
-    if cmd == 'search-group' or cmd == 'all':
-        print "Testing SearchGroup(FILTER_NONE,GROUP_GAMES)"
-        iface.SearchGroup(FILTER_NONE,GROUP_GAMES)
-    if cmd == 'search-file' or cmd == 'all':
-        print "Testing SearchFile(FILTER_NONE,'/usr/bin/yum')"
-        iface.SearchFile(FILTER_NONE,'/usr/bin/yum')
-    if cmd == 'get-requires' or cmd == 'all':
-        print "Testing GetRequires(PKG_ID,False)"
-        iface.GetRequires(PKG_ID,False)
-    if cmd == 'get-depends' or cmd == 'all':
-        print "Testing GetDepends(PKG_ID,False)"
-        iface.GetDepends(PKG_ID,False)
-    if cmd == 'refresh-cache' or cmd == 'all':
-        print "Testing RefreshCache()"
-        iface.RefreshCache()
-    if cmd == 'resolve' or cmd == 'all':
-        print "Testing Resolve(FILTER_NONE,'yum')"
-        iface.Resolve(FILTER_NONE,'yum')
-    if cmd == 'get-details' or cmd == 'all':
-        print "Testing GetDetails(PKG_ID)"
-        iface.GetDetails(PKG_ID)
-    if cmd == 'get-files' or cmd == 'all':
-        print "Testing GetFiles(PKG_ID)"
-        iface.GetFiles(PKG_ID)
-    if cmd == 'get-packages' or cmd == 'all':
-        print "Testing GetPackages(FILTER_INSTALLED,'no')"
-        iface.GetPackages(FILTER_INSTALLED,'no')
-    if cmd == 'get-repolist' or cmd == 'all':
-        print "Testing GetRepoList()"
-        iface.GetRepoList()
-    if cmd == 'get-updatedetail' or cmd == 'all':
-        print "Testing GetUpdateDetail(PKG_ID)"
-        iface.GetUpdateDetail(PKG_ID)
-    #print "Testing "
-    #iface.
-    if cmd == 'exit' or cmd == 'all':
-        print "Testing Exit()"
-        iface.Exit()
-    
-except dbus.DBusException, e:
-    print "Unable to send message on dbus"
-    print "%s" %(e,)
-    sys.exit(1)
diff --git a/configure.ac b/configure.ac
index f614d2b..01e5867 100644
--- a/configure.ac
+++ b/configure.ac
@@ -223,7 +223,6 @@ AC_ARG_ENABLE(gprof, AS_HELP_STRING([--enable-gprof],[compile with gprof support
 # backends
 AC_ARG_ENABLE(alpm, AS_HELP_STRING([--enable-alpm],[use the ALPM backend]),enable_alpm=$enableval,enable_alpm=no)
 AC_ARG_ENABLE(apt, AS_HELP_STRING([--enable-apt],[use the APT backend]),enable_apt=$enableval,enable_apt=no)
-AC_ARG_ENABLE(apt2, AS_HELP_STRING([--enable-apt2],[use the DBus based APT backend]),enable_apt2=$enableval,enable_apt2=no)
 AC_ARG_ENABLE(box, AS_HELP_STRING([--enable-box],[use the BOX backend]),enable_box=$enableval,enable_box=no)
 AC_ARG_ENABLE(conary, AS_HELP_STRING([--enable-conary],[use the CONARY backend]),enable_conary=$enableval,enable_conary=no)
 AC_ARG_ENABLE(dummy, AS_HELP_STRING([--enable-dummy],[use the dummy backend]),enable_dummy=$enableval,enable_dummy=yes)
@@ -238,7 +237,6 @@ AC_ARG_ENABLE(zypp, AS_HELP_STRING([--enable-zypp],[use the Zypp backend]),enabl
 # export to Makefile.am's
 AM_CONDITIONAL(BACKEND_TYPE_ALPM, [test x$enable_alpm = xyes], [using ALPM backend])
 AM_CONDITIONAL(BACKEND_TYPE_APT, [test x$enable_apt = xyes], [using APT backend])
-AM_CONDITIONAL(BACKEND_TYPE_APT_DBUS, [test x$enable_apt2 = xyes], [using DBus based APT backend])
 AM_CONDITIONAL(BACKEND_TYPE_BOX, [test x$enable_box = xyes], [using BOX backend])
 AM_CONDITIONAL(BACKEND_TYPE_CONARY, [test x$enable_conary = xyes], [using CONARY backend])
 AM_CONDITIONAL(BACKEND_TYPE_DUMMY, [test x$enable_dummy = xyes], [using dummy backend])
@@ -369,7 +367,7 @@ dnl ---------------------------------------------------------------------------
 AC_ARG_WITH([default_backend],
 	    AS_HELP_STRING([--with-default-backend=<option>],
 			   [Default backend to use
-                           alpm,apt,apt2,box,conary,dummy,smart,yum,pisi,zypp,opkg (dummy)]))
+                           alpm,apt,box,conary,dummy,smart,yum,pisi,zypp,opkg (dummy)]))
 # default to a sane option for the installed tool
 if test x$with_default_backend = x; then
 	if test -f /usr/bin/yum ; then
@@ -398,134 +396,8 @@ fi
 AC_DEFINE_UNQUOTED(DEFAULT_BACKEND, "$with_default_backend", [default backend prefix])
 AC_SUBST(DEFAULT_BACKEND, "$with_default_backend")
 
-AC_DEFUN([APT_BACKEND],
-[
-  if test "$APT_PKG_TYPE" == "" ; then
-	   AC_LANG_PUSH(C++)
-		_libaptpkg_save_cppflags=$CPPFLAGS
-	   CPPFLAGS="$APT_CFLAGS $CPPFLAGS"
-	   _APT_save_libs=$LIBS
-	   LIBS="$APT_LIBS $LIBS"
-
-	   AC_MSG_CHECKING([for apt support for $1 packages])
-		AC_RUN_IFELSE(AC_LANG_PROGRAM([
-		#include <apt-pkg/configuration.h>
-		#include <apt-pkg/pkgsystem.h>
-		#include <apt-pkg/init.h>
-		#include <stdio.h>
-	   ],[
-		if (pkgInitConfig(*_config) == false)
-		{
-			fprintf(stderr,"pkginitconfig was false");
-			return -1;
-		}
-		if (pkgInitSystem(*_config, _system) == false)
-		{
-			fprintf(stderr,"pkginitsystem was false");
-			return -1;
-		}
-		if (_system->ArchiveSupported("$1"))
-			return 0;
-		else
-			return 1;
-		]),[
-			APT_PKG_TYPE=$1
-			AC_MSG_RESULT([yes])
-			AC_DEFINE(APT_PKG_$2,1,[apt-pkg support files of type $1])
-		],)
-		AC_LANG_POP(C++)
-	   CPPFLAGS=$_libaptpkg_save_cppflags
-	   LIBS=$_libaptpkg_save_libs
-	   unset _libaptpkg_save_cppflags
-	   unset _libaptpkg_save_libs
- 	fi
-])
-
 if test x$enable_apt = xyes; then
 	PY_CHECK_MOD([apt_pkg],,,AC_MSG_ERROR([Apt backend needs python-apt]))
-
-	AC_ARG_WITH([apt_search],
-	    AS_HELP_STRING([--with-apt-search=<option>],
-			   [Apt search type to use - plain,sqlite (plain)]))
-
-	if test x$with_apt_search = x; then
-		with_apt_search=plain
-	fi
-    AC_MSG_NOTICE([using $with_apt_search for apt searching])
-	AC_DEFINE_UNQUOTED(APT_SEARCH, "$with_apt_search", [apt search type])
-	AC_SUBST(APT_SEARCH, $with_apt_search)
-	AM_CONDITIONAL(APT_SEARCH_PLAIN, [test x$with_apt_search = xplain], [using plain apt search])
-	AM_CONDITIONAL(APT_SEARCH_SQLITE, [test x$with_apt_search = xsqlite], [using sqlite apt search])
-
-   AC_ARG_WITH(libapt-pkg-lib,
-	 AC_HELP_STRING([--with-libapt-pkg-lib=DIR],[look for the libapt-pkg library in DIR]),
-	 [_libaptpkg_with_lib=$withval],[_libaptpkg_with_lib=no])
-  	if test "$_libaptpkg_with_lib" == "no" ; then
-		APT_LIBS="-lapt-pkg"
-	else
-		APT_LIBS="-L$withval -lapt-pkg"
-	fi
-
-   AC_ARG_WITH(libapt-pkg-includes,
-	 AC_HELP_STRING([--with-libapt-pkg-includes=DIR],[look for the libapt-pkg includes in DIR]),
-	 [_libaptpkg_with_inc=$withval],[_libaptpkg_with_inc=no])
-  	if test "$_libaptpkg_with_inc" == "no" ; then
-		APT_CFLAGS="-I/usr/include/apt-pkg"
-	else
-		APT_CFLAGS="-I$withval"
-	fi
-
-	AC_CACHE_CHECK([whether libapt-pkg is usable],
-	   [libaptpkg_usable],
-	   [
-	   _libaptpkg_save_cppflags=$CPPFLAGS
-	   CPPFLAGS="$APT_CFLAGS $CPPFLAGS"
-	   _APT_save_libs=$LIBS
-	   LIBS="$APT_LIBS $LIBS"
-
-	   AC_LANG_PUSH(C++)
-	   AC_LINK_IFELSE(AC_LANG_PROGRAM([
-		#include <apt-pkg/configuration.h>
-	   	#include <apt-pkg/pkgsystem.h>
-	   	#include <apt-pkg/init.h>
-		#include <stdio.h>
-	   ],[
-		if (pkgInitConfig(*_config) == false)
-		{
-			fprintf(stderr,"pkginitconfig was false");
-			return -1;
-		}
-		if (pkgInitSystem(*_config, _system) == false)
-		{
-			fprintf(stderr,"pkginitsystem was false");
-			return -1;
-		}
-		return 0;
-]),libaptpkg_usable=yes,AC_MSG_ERROR([libapt-pkg not found]))
-
-	   CPPFLAGS=$_libaptpkg_save_cppflags
-	   LIBS=$_libaptpkg_save_libs
-	   unset _libaptpkg_save_cppflags
-	   unset _libaptpkg_save_libs
-	   ])
-	AC_LANG_POP(C++)
-
-	APT_BACKEND(deb,DEB)
-	APT_BACKEND(rpm,RPM)
-  	if test "$APT_PKG_TYPE" == "" ; then
-		AC_MSG_ERROR([Couldn't find support for any type of packages that we know about for Apt!])
-	fi
-
-	AC_SUBST(APT_CFLAGS)
-	AC_SUBST(APT_LIBS)
-	AC_SUBST(APT_PKG_TYPE)
-else
-	AM_CONDITIONAL(APT_SEARCH_PLAIN, [false])
-	AM_CONDITIONAL(APT_SEARCH_SQLITE, [false])
-fi
-
-if test x$enable_apt2 = xyes; then
-	PY_CHECK_MOD([apt_pkg],,,AC_MSG_ERROR([Apt backend needs python-apt]))
 fi
 
 if test x$enable_box = xyes; then
@@ -568,11 +440,6 @@ AC_SUBST(PK_PLUGIN_DIR, "\$(libdir)/packagekit-backend")
 AC_SUBST(PK_PLUGIN_CFLAGS, "-I\$(top_srcdir)/src -I\$(top_srcdir)/libpackagekit $GLIB_CFLAGS $DBUS_CFLAGS $GMODULE_CFLAGS")
 AC_SUBST(PK_PLUGIN_LIBS, "$GLIB_LIBS $DBUS_LIBS $GMODULE_LIBS")
 
-if test x$with_default_backend = xapt; then
-	# now we've done the conditionals, rename for searching backend
-	with_default_backend="apt (with $with_apt_search searching)"
-fi
-
 dnl ---------------------------------------------------------------------------
 dnl - Makefiles, etc.
 dnl ---------------------------------------------------------------------------
@@ -592,8 +459,6 @@ contrib/yum-packagekit/Makefile
 backends/Makefile
 backends/alpm/Makefile
 backends/apt/Makefile
-backends/apt/helpers/Makefile
-backends/apt2/Makefile
 backends/box/Makefile
 backends/conary/Makefile
 backends/conary/helpers/Makefile
@@ -650,7 +515,6 @@ echo "
         Backends:
         ALPM backend:              ${enable_alpm}
         APT backend:               ${enable_apt}
-        APT DBus backend:          ${enable_apt2}
         BOX backend:               ${enable_box}
         CONARY backend:            ${enable_conary}
         dummy backend:             ${enable_dummy}
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index 5d997f6..a58cc15 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -52,7 +52,6 @@
 <tr>
 <td width="150px">&nbsp;</td>
 <td><center>apt</center></td>
-<td><center>apt2</center></td>
 <td><center>alpm</center></td>
 <td><center>box</center></td>
 <td><center>conary</center></td>
@@ -66,8 +65,7 @@
 </tr>
 <tr>
 <td><b>Resolve</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -82,7 +80,6 @@
 <tr>
 <td><b>RefreshCache</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -96,8 +93,7 @@
 </tr>
 <tr>
 <td><b>GetUpdates</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -111,8 +107,7 @@
 </tr>
 <tr>
 <td><b>UpdateSystem</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -127,7 +122,6 @@
 <tr>
 <td><b>SearchName</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -142,7 +136,6 @@
 <tr>
 <td><b>SearchDetails</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -157,7 +150,6 @@
 <tr>
 <td><b>SearchFile</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -172,7 +164,6 @@
 <tr>
 <td><b>SearchGroup</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -186,8 +177,7 @@
 </tr>
 <tr>
 <td><b>InstallPackages</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -202,7 +192,6 @@
 <tr>
 <td><b>InstallFiles</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -216,8 +205,7 @@
 </tr>
 <tr>
 <td><b>RemovePackages</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -232,7 +220,6 @@
 <tr>
 <td><b>UpdatePackage</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -247,7 +234,6 @@
 <tr>
 <td><b>GetDepends</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -262,7 +248,6 @@
 <tr>
 <td><b>GetRequires</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -277,7 +262,6 @@
 <tr>
 <td><b>GetDetails</b></td>
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -292,7 +276,6 @@
 <tr>
 <td><b>GetFiles</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -307,7 +290,6 @@
 <tr>
 <td><b>GetUpdateDetail</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -322,7 +304,6 @@
 <tr>
 <td><b>GetRepoList</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -337,7 +318,6 @@
 <tr>
 <td><b>RepoEnable</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -352,7 +332,6 @@
 <tr>
 <td><b>RepoSetData</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -367,7 +346,6 @@
 <tr>
 <td><b>Cancel</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -382,7 +360,6 @@
 <tr>
 <td><b>ServicePack</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -397,7 +374,6 @@
 <tr>
 <td><b>WhatProvides</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -411,8 +387,7 @@
 </tr>
 <tr>
 <td><b>GetPackages</b></td>
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -431,7 +406,6 @@
 <tr>
 <td width="150px">&nbsp;</td>
 <td><center>apt</center></td>
-<td><center>apt2</center></td>
 <td><center>alpm</center></td>
 <td><center>box</center></td>
 <td><center>conary</center></td>
@@ -446,7 +420,6 @@
 <tr>
 <td><b>Installed</b></td>
 <td><img src="img/status-good.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
@@ -461,7 +434,6 @@
 <tr>
 <td><b>Development</b></td>
 <td><img src="img/status-good.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -476,7 +448,6 @@
 <tr>
 <td><b>GUI</b></td>
 <td><img src="img/status-good.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-good.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -491,7 +462,6 @@
 <tr>
 <td><b>Free</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -506,7 +476,6 @@
 <tr>
 <td><b>Visible</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -521,7 +490,6 @@
 <tr>
 <td><b>Supported</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -536,7 +504,6 @@
 <tr>
 <td><b>Newest</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
@@ -551,7 +518,6 @@
 <tr>
 <td><b>Arch</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
commit 76ee76ae98a799c9675301bde7ac38d079edccb4
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 09:19:02 2008 +0100

    trivial: remove private file

diff --git a/tools/rpmbuild.sh b/tools/rpmbuild.sh
deleted file mode 100755
index ebbd8f7..0000000
--- a/tools/rpmbuild.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-# Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
-#
-# Licensed under the GNU General Public License Version 2
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-sudo echo "Build!"
-#autobuild.sh all PolicyKit
-#sudo auto_refresh_from_repo.sh
-#autobuild.sh all PolicyKit-gnome
-#sudo auto_refresh_from_repo.sh
-autobuild.sh all PackageKit force
-sudo auto_refresh_from_repo.sh
-autobuild.sh all gnome-packagekit force
-sudo auto_refresh_from_repo.sh
-
commit 4733bb703176002ff3877fd42b4a3418701ff39d
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 23 09:13:06 2008 +0100

    ref and unref the PkClient in pk_client_finished_cb() in case we do unref in ::finished and try to access free'd memory
    
    See https://bugzilla.novell.com/show_bug.cgi?id=390929 for the full explanation -- thanks go to Hans Petter Jansson

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 100ad3c..27a7634 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -412,6 +412,10 @@ pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime,
 
 	g_return_if_fail (PK_IS_CLIENT (client));
 
+	/* ref in case we unref the PkClient in ::finished --
+	 * see https://bugzilla.novell.com/show_bug.cgi?id=390929 for rationale */
+	g_object_ref (client);
+
 	exit = pk_exit_enum_from_text (exit_text);
 	pk_debug ("emit finished %s, %i", exit_text, runtime);
 
@@ -420,16 +424,13 @@ pk_client_finished_cb (DBusGProxy *proxy, const gchar *exit_text, guint runtime,
 
 	g_signal_emit (client, signals [PK_CLIENT_FINISHED], 0, exit, runtime);
 
-	/* check we are still valid */
-	if (!PK_IS_CLIENT (client)) {
-		pk_debug ("client was g_object_unref'd in finalise, object no longer valid");
-		return;
-	}
-
 	/* exit our private loop */
 	if (client->priv->synchronous) {
 		g_main_loop_quit (client->priv->loop);
 	}
+
+	/* unref what we previously ref'd */
+	g_object_unref (client);
 }
 
 /**
commit 0d7734d037e96dae8a89ad7c304a4558ec4df21c
Merge: febdc36... 7455581...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Thu May 22 23:19:12 2008 -0400

    Merge branch 'master' of git+ssh://rnorwood@git.packagekit.org/srv/git/PackageKit

commit febdc36c953886ca1afbcee442515b25e3deed94
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Thu May 22 23:18:55 2008 -0400

    Add Qhull license per http://fedoraproject.org/wiki/Licensing?action=diff&rev2=134&rev1=133

diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 563deb4..c86b791 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -418,6 +418,7 @@ static PkEnumMatch enum_free_licenses[] = {
 	{PK_LICENSE_ENUM_VOSTROM,		"VOSTROM"},
 	{PK_LICENSE_ENUM_XEROX,                 "Xerox License"},
 	{PK_LICENSE_ENUM_RICEBSD,               "RiceBSD"},
+	{PK_LICENSE_ENUM_QHULL,                 "Qhull"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 9e08217..0459bc7 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -494,6 +494,7 @@ typedef enum {
 	PK_LICENSE_ENUM_VOSTROM,
 	PK_LICENSE_ENUM_XEROX,
 	PK_LICENSE_ENUM_RICEBSD,
+	PK_LICENSE_ENUM_QHULL,
 	PK_LICENSE_ENUM_UNKNOWN
 } PkLicenseEnum;
 
commit 74555810b00c96fa11dbd089af1854559fb18c0d
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Fri May 23 00:51:13 2008 +0200

    poldek: implement GetGroups. Now user can search group.

diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index cf1776f..2691414 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -58,6 +58,31 @@ enum {
 };
 
 typedef struct {
+	PkGroupEnum	group;
+	const gchar	*regex;
+} PLDGroupRegex;
+
+static PLDGroupRegex group_perlre[] = {
+	{PK_GROUP_ENUM_ACCESSORIES, "/.*Archiving\\|.*Dictionaries/"},
+	{PK_GROUP_ENUM_ADMIN_TOOLS, "/.*Databases.*\\|.*Admin/"},
+	{PK_GROUP_ENUM_COMMUNICATION, "/.*Communications/"},
+	{PK_GROUP_ENUM_EDUCATION, "/.*Engineering\\|.*Math\\|.*Science/"},
+	{PK_GROUP_ENUM_FONTS, "/Fonts/"},
+	{PK_GROUP_ENUM_GAMES, "/.*Games.*/"},
+	{PK_GROUP_ENUM_GRAPHICS, "/.*Graphics/"},
+	{PK_GROUP_ENUM_LOCALIZATION, "/I18n/"},
+	{PK_GROUP_ENUM_MULTIMEDIA, "/.*Multimedia\\|.*Sound/"},
+	{PK_GROUP_ENUM_NETWORK, "/.*Networking.*\\|/.*Mail\\|.*News\\|.*WWW/"},
+	{PK_GROUP_ENUM_OFFICE, "/.*Editors.*\\|.*Spreadsheets/"},
+	{PK_GROUP_ENUM_OTHER, "/^Applications$\\|.*Console\\|.*Emulators\\|.*File\\|.*Printing\\|.*Terminal\\|.*Text\\|Documentation\\|^Libraries.*\\|^Themes.*\\|^X11$\\|.*Amusements\\|^X11\\/Applications$\\|^X11\\/Libraries$\\|.*Window\\ Managers.*/"},
+	{PK_GROUP_ENUM_PROGRAMMING, "/.*Development.*/"},
+	{PK_GROUP_ENUM_PUBLISHING, "/.*Publishing.*/"},
+	{PK_GROUP_ENUM_SERVERS, "/Daemons\\|.*Servers/"},
+	{PK_GROUP_ENUM_SYSTEM, "/.*Shells\\|.*System\\|Base.*/"},
+	{0, NULL}
+};
+
+typedef struct {
 	gint		step; // current step
 
 	/* Numer of sources to update. It's used only by refresh cache,
@@ -502,6 +527,79 @@ poldek_pkg_set_installed (struct pkg *pkg, gboolean installed) {
 }
 
 /**
+ * pld_group_to_enum:
+ *
+ * Converts PLD RPM group to PkGroupEnum.
+ **/
+static PkGroupEnum
+pld_group_to_enum (const gchar *group)
+{
+	g_return_val_if_fail (group != NULL, PK_GROUP_ENUM_OTHER);
+
+	if (strstr (group, "Archiving") != NULL ||
+	    strstr (group, "Dictionaries") != NULL)
+		return PK_GROUP_ENUM_ACCESSORIES;
+	else if (strstr (group, "Databases") != NULL ||
+		 strstr (group, "Admin") != NULL)
+		return PK_GROUP_ENUM_ADMIN_TOOLS;
+	else if (strstr (group, "Communications") != NULL)
+		return PK_GROUP_ENUM_COMMUNICATION;
+	else if (strstr (group, "Engineering") != NULL ||
+		 strstr (group, "Math") != NULL	||
+		 strstr (group, "Science") != NULL)
+		return PK_GROUP_ENUM_EDUCATION;
+	else if (strcmp (group, "Fonts") == 0)
+		return PK_GROUP_ENUM_FONTS;
+	else if (strstr (group, "Games") != NULL)
+		return PK_GROUP_ENUM_GAMES;
+	else if (strstr (group, "Graphics") != NULL)
+		return PK_GROUP_ENUM_GRAPHICS;
+	else if (strcmp (group, "I18n") == 0)
+		return PK_GROUP_ENUM_LOCALIZATION;
+	else if (strstr (group, "Multimedia") != NULL ||
+		 strstr (group, "Sound") != NULL)
+		return PK_GROUP_ENUM_MULTIMEDIA;
+	else if (strstr (group, "Networking") != NULL ||
+		 strstr (group, "Mail") != NULL ||
+		 strstr (group, "News") != NULL ||
+		 strstr (group, "WWW") != NULL)
+		return PK_GROUP_ENUM_NETWORK;
+	else if (strstr (group, "Editors") != NULL ||
+		 strstr (group, "Spreadsheets") != NULL)
+		return PK_GROUP_ENUM_OFFICE;
+	else if (strstr (group, "Development") != NULL)
+		return PK_GROUP_ENUM_PROGRAMMING;
+	else if (strstr (group, "Publishing") != NULL)
+		return PK_GROUP_ENUM_PUBLISHING;
+	else if (strstr (group, "Daemons") != NULL ||
+		 strstr (group, "Servers") != NULL)
+		return PK_GROUP_ENUM_SERVERS;
+	else if (strstr (group, "Shells") != NULL ||
+		 strstr (group, "System") != NULL ||
+		 strstr (group, "Base") != NULL)
+		return PK_GROUP_ENUM_SYSTEM;
+	else
+		return PK_GROUP_ENUM_OTHER;
+}
+
+/**
+ * pld_group_get_regex_from_enum:
+ **/
+static const gchar*
+pld_group_get_regex_from_enum (PkGroupEnum value)
+{
+	gint i;
+
+	for (i = 0;; i++) {
+		if (group_perlre[i].regex == NULL)
+			return NULL;
+
+		if (group_perlre[i].group == value)
+			return group_perlre[i].regex;
+	}
+}
+
+/**
  * poldek_pkg_evr:
  */
 static gchar*
@@ -932,39 +1030,38 @@ search_package_thread (PkBackend *backend)
 	search = pk_backend_get_string (backend, "search");
 	filters = pk_backend_get_uint (backend, "filters");
 
-	switch (mode) {
-		/* GetPackages */
-		case SEARCH_ENUM_NONE:
-			search_cmd = g_strdup ("ls -q");
-			break;
-		/* SearchName */
-		case SEARCH_ENUM_NAME:
-			search_cmd = g_strdup_printf ("ls -q *%s*", search);
-			break;
-		/* SearchGroup */
-		case SEARCH_ENUM_GROUP:
-			search_cmd = g_strdup_printf ("search -qg *%s*", search);
-			break;
-		/* SearchDetails */
-		case SEARCH_ENUM_DETAILS:
-			search_cmd = g_strdup_printf ("search -dsq *%s*", search);
-			break;
-		/* SearchFile */
-		case SEARCH_ENUM_FILE:
-			search_cmd = g_strdup_printf ("search -qlf *%s*", search);
-			break;
-		/* WhatProvides */
-		case SEARCH_ENUM_PROVIDES:
-			provides = pk_backend_get_uint (backend, "provides");
-
-			if (provides == PK_PROVIDES_ENUM_ANY) {
-				search_cmd = g_strdup_printf ("search -qp %s", search);
-			} else if (provides == PK_PROVIDES_ENUM_MODALIAS) {
-			} else if (provides == PK_PROVIDES_ENUM_CODEC) {
-			} else if (provides == PK_PROVIDES_ENUM_MIMETYPE) {
-				search_cmd = g_strdup_printf ("search -qp mimetype(%s)", search);
-			}
-			break;
+	/* GetPackages*/
+	if (mode == SEARCH_ENUM_NONE) {
+		search_cmd = g_strdup ("ls -q");
+	/* SearchName */
+	} else if (mode == SEARCH_ENUM_NAME) {
+		search_cmd = g_strdup_printf ("ls -q *%s*", search);
+	/* SearchGroup */
+	} else if (mode == SEARCH_ENUM_GROUP) {
+		PkGroupEnum	group;
+		const gchar	*regex;
+
+		group = pk_group_enum_from_text (search);
+		regex = pld_group_get_regex_from_enum (group);
+
+		search_cmd = g_strdup_printf ("search -qg --perlre %s", regex);
+	/* SearchDetails */
+	} else if (mode == SEARCH_ENUM_DETAILS) {
+		search_cmd = g_strdup_printf ("search -dsq *%s*", search);
+	/* SearchFile */
+	} else if (mode == SEARCH_ENUM_FILE) {
+		search_cmd = g_strdup_printf ("search -qlf *%s*", search);
+	/* WhatProvides */
+	} else if (mode == SEARCH_ENUM_PROVIDES) {
+		provides = pk_backend_get_uint (backend, "provides");
+
+		if (provides == PK_PROVIDES_ENUM_ANY) {
+			search_cmd = g_strdup_printf ("search -qp %s", search);
+		} else if (provides == PK_PROVIDES_ENUM_MODALIAS) {
+		} else if (provides == PK_PROVIDES_ENUM_CODEC) {
+		} else if (provides == PK_PROVIDES_ENUM_MIMETYPE) {
+			search_cmd = g_strdup_printf ("search -qp mimetype(%s)", search);
+		}
 	}
 
 	if (cmd != NULL && search_cmd)
@@ -1318,6 +1415,30 @@ backend_destroy (PkBackend *backend)
 }
 
 /**
+ * backend_get_groups:
+ **/
+static PkGroupEnum
+backend_get_groups (PkBackend *backend)
+{
+	return (PK_GROUP_ENUM_ACCESSORIES |
+		PK_GROUP_ENUM_ADMIN_TOOLS |
+		PK_GROUP_ENUM_COMMUNICATION |
+		PK_GROUP_ENUM_EDUCATION |
+		PK_GROUP_ENUM_FONTS |
+		PK_GROUP_ENUM_GAMES |
+		PK_GROUP_ENUM_GRAPHICS |
+		PK_GROUP_ENUM_LOCALIZATION |
+		PK_GROUP_ENUM_MULTIMEDIA |
+		PK_GROUP_ENUM_NETWORK |
+		PK_GROUP_ENUM_OFFICE |
+		PK_GROUP_ENUM_OTHER |
+		PK_GROUP_ENUM_PROGRAMMING |
+		PK_GROUP_ENUM_PUBLISHING |
+		PK_GROUP_ENUM_SERVERS |
+		PK_GROUP_ENUM_SYSTEM);
+}
+
+/**
  * backend_get_filters:
  */
 static PkFilterEnum
@@ -1409,14 +1530,17 @@ backend_get_details_thread (PkBackend *backend)
 	if (pkg)
 	{
 		struct pkguinf	*pkgu = NULL;
+		PkGroupEnum	group;
 
 		pkgu = pkg_uinf (pkg);
 
+		group = pld_group_to_enum (pkg_group (pkg));
+
 		if (pkgu) {
 			pk_backend_details (backend,
 						package_id,
 						pkguinf_get (pkgu, PKGUINF_LICENSE),
-						PK_GROUP_ENUM_OTHER,
+						group,
 						pkguinf_get (pkgu, PKGUINF_DESCRIPTION),
 						pkguinf_get (pkgu, PKGUINF_URL),
 						pkg->size);
@@ -1425,7 +1549,7 @@ backend_get_details_thread (PkBackend *backend)
 			pk_backend_details (backend,
 						package_id,
 						"",
-						PK_GROUP_ENUM_OTHER,
+						group,
 						"",
 						"",
 						pkg->size);
@@ -2243,7 +2367,7 @@ PK_BACKEND_OPTIONS (
 	"Marcin Banasiak <megabajt at pld-linux.org>",	/* author */
 	backend_initalize,				/* initalize */
 	backend_destroy,				/* destroy */
-	NULL,						/* get_groups */
+	backend_get_groups,				/* get_groups */
 	backend_get_filters,				/* get_filters */
 	backend_get_cancel,				/* cancel */
 	backend_get_depends,				/* get_depends */
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index c8c0609..5d997f6 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -178,7 +178,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- opkg -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- pisi -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum2 -->
commit 47defbfb2e2c38514aa3060cc86067e0751f4144
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 22 18:21:46 2008 +0100

    yum: convert ';' chars in update description in to ',' to prevent a crash like in rh#447347

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index c2b5108..7515fcd 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1403,6 +1403,10 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                     typ = ref['type']
                     href = ref['href']
                     title = ref['title'] or ""
+
+                    # Description can sometimes have ';' in them, and we use that as the delimiter
+                    title = title.replace(";",",")
+
                     if href:
                         if typ in ('bugzilla','cve'):
                             urls[typ].append("%s;%s" % (href,title))
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index 6f769f6..a708a0c 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -1904,6 +1904,10 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 type_ = ref['type']
                 href = ref['href']
                 title = ref['title'] or ""
+
+                # Description can sometimes have ';' in them, and we use that as the delimiter
+                title = title.replace(";",",")
+
                 if href:
                     if type_ in ('bugzilla', 'cve'):
                         urls[type_].append("%s;%s" % (href, title))
commit 1ce2e0e3311307b47b4525e5c31f868a450a0506
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 22 17:23:31 2008 +0100

    trivial: remove some superflous debugging

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index dd2387b..100ad3c 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -491,7 +491,6 @@ pk_client_package_cb (DBusGProxy   *proxy,
 
 	/* cache */
 	if (client->priv->use_buffer || client->priv->synchronous) {
-		pk_debug ("adding to cache array package %i, %s, %s", info, package_id, summary);
 		pk_package_list_add (client->priv->package_list, info, package_id, summary);
 	}
 }
commit 786ba03e113b95f8a77cc4461bada0d84f03ae84
Merge: 2e0558c... f8816a3...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Thu May 22 11:00:13 2008 -0400

    Merge branch 'master' of git+ssh://rnorwood@git.packagekit.org/srv/git/PackageKit

commit 2e0558c96b4b067d7e4bd63e51fa06bc4ca3e992
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Thu May 22 10:57:45 2008 -0400

    We never want to show self.txt, since it contains '(x/y) packagename' instead of just 'packagename'.

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 9c57867..c2b5108 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1564,11 +1564,7 @@ class DownloadCallback(BaseMeter):
         '''
         Get the name of the package being downloaded
         '''
-        if self.text and type(self.text) == type(""):
-            name = self.text
-        else:
-            name = self.basename
-        return name
+        return self.basename
 
     def updateProgress(self,name,frac,fread,ftime):
         '''
commit f8816a36d238cb75e38edda0e265dcaee339faa1
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 22 12:07:13 2008 +0100

    trivial: remove extra debugging statement

diff --git a/client/pk-console.c b/client/pk-console.c
index 0420193..d1ee30f 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -76,7 +76,6 @@ pk_console_bar (guint subpercentage)
 		return;
 	}
 	if (!has_output_bar) {
-		pk_warning ("no bar");
 		return;
 	}
 	/* restore cursor */
commit 42b172f45229299a8f40c9eb23e863ea3ac0b24e
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Wed May 21 15:05:38 2008 -0400

    Add Rice BSD license per http://fedoraproject.org/wiki/Licensing?action=diff&rev2=133&rev1=132

diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 5743dcb..563deb4 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -417,6 +417,7 @@ static PkEnumMatch enum_free_licenses[] = {
 	{PK_LICENSE_ENUM_XANO,			"XANO"},
 	{PK_LICENSE_ENUM_VOSTROM,		"VOSTROM"},
 	{PK_LICENSE_ENUM_XEROX,                 "Xerox License"},
+	{PK_LICENSE_ENUM_RICEBSD,               "RiceBSD"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index e616b64..9e08217 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -493,6 +493,7 @@ typedef enum {
 	PK_LICENSE_ENUM_XANO,
 	PK_LICENSE_ENUM_VOSTROM,
 	PK_LICENSE_ENUM_XEROX,
+	PK_LICENSE_ENUM_RICEBSD,
 	PK_LICENSE_ENUM_UNKNOWN
 } PkLicenseEnum;
 
commit 814f2ee7d112cde40e13b31466fce934b474d93a
Author: Sebastian Heinlein <renate at debian.daheim>
Date:   Wed May 21 17:53:27 2008 +0100

    APT2: use the async wrapper from the daemonDBus instead of our own
    implementation

diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
index 0be9cb3..22eb714 100755
--- a/backends/apt2/aptDBUSBackend.py
+++ b/backends/apt2/aptDBUSBackend.py
@@ -34,7 +34,7 @@ import dbus.service
 import dbus.mainloop.glib
 import gobject
 
-from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded
+from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, async
 from packagekit.enums import *
 
 warnings.filterwarnings(action='ignore', category=FutureWarning)
@@ -161,27 +161,13 @@ class PackageKitAptBackend(PackageKitBaseBackend):
     '''
     PackageKit backend for apt
     '''
-
-    def locked(func):
-        '''
-        Decorator to run a method with a lock
-        '''
-        def wrapper(*args, **kwargs):
-            backend = args[0]
-            backend._lock_cache()
-            ret = func(*args, **kwargs)
-            backend._unlock_cache()
-            return ret
-        wrapper.__name__ = func.__name__
-        return wrapper
-
     def __init__(self, bus_name, dbus_path):
         pklog.info("Initializing APT backend")
         signal.signal(signal.SIGQUIT, sigquit)
         self._cache = None
         self._canceled = threading.Event()
         self._canceled.clear()
-        self._locked = threading.Lock()
+        self._lock = threading.Lock()
         # Check for xapian support
         self._use_xapian = False
         try:
@@ -280,7 +266,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.Finished(EXIT_SUCCESS)
 
     @threaded
-    @locked
+    @async
     def doGetUpdates(self, filters):
         '''
         Implement the {backend}-get-update functionality
@@ -343,7 +329,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.Finished(EXIT_SUCCESS)
 
     @threaded
-    @locked
+    @async
     def doUpdateSystem(self):
         '''
         Implement the {backend}-update-system functionality
@@ -377,7 +363,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.Finished(EXIT_SUCCESS)
 
     @threaded
-    @locked
+    @async
     def doRemovePackages(self, ids, deps=True, auto=False):
         '''
         Implement the {backend}-remove functionality
@@ -404,7 +390,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
             try:
                 pkg.markDelete()
             except:
-                self._open_cache(prange=(90,100))
+                self._open_cache(prange=(90,99))
                 self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name)
                 self.Finished(EXIT_FAILED)
                 return
@@ -412,21 +398,21 @@ class PackageKitAptBackend(PackageKitBaseBackend):
             self._cache.commit(PackageKitFetchProgress(self, prange=(10,10)),
                                PackageKitInstallProgress(self, prange=(10,90)))
         except:
-            self._open_cache(prange=(90,100))
+            self._open_cache(prange=(90,99))
             self.ErrorCode(ERROR_UNKNOWN, "Removal failed")
             self.Finished(EXIT_FAILED)
             return
-        self._open_cache(prange=(90,100))
-        self.PercentageChanged(100)
+        self._open_cache(prange=(90,99))
         for p in pkgs:
             if self._cache.has_key(p) and self._cache[p].isInstalled:
                 self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p)
                 self.Finished(EXIT_FAILED)
                 return
+        self.PercentageChanged(100)
         self.Finished(EXIT_SUCCESS)
 
     @threaded
-    @locked
+    @async
     def doInstallPackages(self, ids):
         '''
         Implement the {backend}-install functionality
@@ -478,7 +464,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.Finished(EXIT_SUCCESS)
 
     @threaded
-    @locked
+    @async
     def doRefreshCache(self, force):
         '''
         Implement the {backend}-refresh_cache functionality
commit c51fd190123cdc4e3bde5bd4df00c6ba8b4dfe3a
Author: Sebastian Heinlein <renate at debian.daheim>
Date:   Wed May 21 17:52:50 2008 +0100

    APT2: Fix doRemovePackages and doInstallPackages

diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
index 45e5ed3..0be9cb3 100755
--- a/backends/apt2/aptDBUSBackend.py
+++ b/backends/apt2/aptDBUSBackend.py
@@ -382,25 +382,33 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         '''
         Implement the {backend}-remove functionality
         '''
-        pklog.info("Removing package with id %s" % id)
+        pklog.info("Removing package(s): id %s" % ids)
         self.StatusChanged(STATUS_REMOVE)
         self.AllowCancel(False)
         self.PercentageChanged(0)
         self._check_init(prange=(0,10))
-        pkg = self._find_package_by_id(id)
-        if pkg == None:
-            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
-                           "Package %s isn't available" % pkg.name)
-            self.Finished(EXIT_FAILED)
-            return
-        if not pkg.isInstalled:
-            self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED,
-                           "Package %s isn't installed" % pkg.name)
-            self.Finished(EXIT_FAILED)
-            return
-        name = pkg.name[:]
+        pkgs=[]
+        for id in ids:
+            pkg = self._find_package_by_id(id)
+            if pkg == None:
+                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                               "Package %s isn't available" % id)
+                self.Finished(EXIT_FAILED)
+                return
+            if not pkg.isInstalled:
+                self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED,
+                               "Package %s isn't installed" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+            pkgs.append(pkg.name[:])
+            try:
+                pkg.markDelete()
+            except:
+                self._open_cache(prange=(90,100))
+                self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
         try:
-            pkg.markDelete()
             self._cache.commit(PackageKitFetchProgress(self, prange=(10,10)),
                                PackageKitInstallProgress(self, prange=(10,90)))
         except:
@@ -410,11 +418,12 @@ class PackageKitAptBackend(PackageKitBaseBackend):
             return
         self._open_cache(prange=(90,100))
         self.PercentageChanged(100)
-        if not self._cache.has_key(name) or not self._cache[name].isInstalled:
-            self.Finished(EXIT_SUCCESS)
-        else:
-            self.ErrorCode(ERROR_UNKNOWN, "Package is still installed")
-            self.Finished(EXIT_FAILED)
+        for p in pkgs:
+            if self._cache.has_key(p) and self._cache[p].isInstalled:
+                self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p)
+                self.Finished(EXIT_FAILED)
+                return
+        self.Finished(EXIT_SUCCESS)
 
     @threaded
     @locked
@@ -422,25 +431,34 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         '''
         Implement the {backend}-install functionality
         '''
-        pklog.info("Installing package with id %s" % id)
+        pklog.info("Installing package with id %s" % ids)
         self.StatusChanged(STATUS_INSTALL)
         self.AllowCancel(False)
         self.PercentageChanged(0)
         self._check_init(prange=(0,10))
-        pkg = self._find_package_by_id(id)
-        if pkg == None:
-            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
-                           "Package %s isn't available" % pkg.name)
-            self.Finished(EXIT_FAILED)
-            return
-        if pkg.isInstalled:
-            self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
-                           "Package %s is already installed" % pkg.name)
-            self.Finished(EXIT_FAILED)
-            return
-        name = pkg.name[:]
+        pkgs=[]
+        for id in ids:
+            pkg = self._find_package_by_id(id)
+            if pkg == None:
+                self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                               "Package %s isn't available" % id)
+                self.Finished(EXIT_FAILED)
+                return
+            if pkg.isInstalled:
+                self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
+                               "Package %s is already installed" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
+            pkgs.append(pkg.name[:])
+            try:
+                pkg.markInstall()
+            except:
+                self._open_cache(prange=(90,100))
+                self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
+                                              "installation" % pkg.name)
+                self.Finished(EXIT_FAILED)
+                return
         try:
-            pkg.markInstall()
             self._cache.commit(PackageKitFetchProgress(self, prange=(10,50)),
                                PackageKitInstallProgress(self, prange=(50,90)))
         except:
@@ -450,11 +468,14 @@ class PackageKitAptBackend(PackageKitBaseBackend):
             return
         self._open_cache(prange=(90,100))
         self.PercentageChanged(100)
-        if self._cache.has_key(name) and self._cache[name].isInstalled:
-            self.Finished(EXIT_SUCCESS)
-        else:
-            self.ErrorCode(ERROR_UNKNOWN, "Installation failed")
-            self.Finished(EXIT_FAILED)
+        pklog.debug("Checking success of operation")
+        for p in pkgs:
+            if not self._cache.has_key(p) or not self._cache[p].isInstalled:
+                self.ErrorCode(ERROR_UNKNOWN, "%s was not installed" % p)
+                self.Finished(EXIT_FAILED)
+                return
+        pklog.debug("Sending success signal")
+        self.Finished(EXIT_SUCCESS)
 
     @threaded
     @locked
commit c8f4138503b2eb4f1e10d357f52dadba7a323f10
Merge: 559aaae... c721fac...
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 21 16:17:31 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit 559aaae7c21b84c836f34dc39fc52b99112dd164
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 21 16:17:03 2008 +0100

    trivial: remove some debugging statements that cause a high load with lots of packages in the cache

diff --git a/libpackagekit/pk-extra.c b/libpackagekit/pk-extra.c
index 7f01a4c..d0f0776 100644
--- a/libpackagekit/pk-extra.c
+++ b/libpackagekit/pk-extra.c
@@ -130,7 +130,6 @@ pk_extra_populate_package_cache_callback (void *data, gint argc, gchar **argv, g
 	obj->icon_name = icon_name;
 	obj->exec = exec;
 	g_hash_table_insert (extra->priv->hash_package, (gpointer) package, (gpointer) obj);
-	pk_debug ("adding %s, %s", package, icon_name);
 out:
 	return 0;
 }
@@ -180,7 +179,6 @@ pk_extra_populate_locale_cache_callback (void *data, gint argc, gchar **argv, gc
 	obj = g_new (PkExtraLocaleObj, 1);
 	obj->summary = summary;
 	g_hash_table_insert (extra->priv->hash_locale, (gpointer) package, (gpointer) obj);
-	pk_debug ("adding %s, %s", package, summary);
 out:
 	return 0;
 }
commit c721facf89b8b12da5f2d7f2f888f3ed8b35cfef
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 21 15:57:33 2008 +0200

    fixed #BNC392435

diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index cc0d7e3..a7bb282 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -406,17 +406,39 @@ zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable)
 	return package_id;
 }
 
+zypp::RepoInfo
+zypp_get_Repository (PkBackend *backend, const gchar *alias)
+{
+	zypp::RepoInfo info;
+
+	try {
+		zypp::RepoManager manager;
+		info = manager.getRepositoryInfo (alias);
+	} catch (const zypp::repo::RepoNotFoundException &ex) {
+		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, ex.asUserString().c_str() );
+		return zypp::RepoInfo ();
+	}
+
+	return info;
+}
+
 gboolean
 zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key)
 {
 	gboolean ok = FALSE;
 
 	if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), key.id ()) == _signatures[backend]->end ()) {
+		zypp::RepoInfo info = zypp_get_Repository (backend, _repoName);
+		if (info.type () == zypp::repo::RepoType::NONE) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
+			return FALSE;
+		}
+
         	pk_backend_repo_signature_required (backend,
 				"dummy;0.0.1;i386;data",
 	                        _repoName,
-        	                key.path ().c_str (),
-                	        key.id ().c_str (),
+				info.baseUrlsBegin ()->asString ().c_str (),
+				key.name ().c_str (),
                         	key.id ().c_str (),
 	                        key.fingerprint ().c_str (),
         	                key.created ().asString ().c_str (),
@@ -435,10 +457,16 @@ zypp_signature_required (PkBackend *backend, const std::string &file, const std:
         gboolean ok = FALSE;
 	
 	if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), id) == _signatures[backend]->end ()) {
+		zypp::RepoInfo info = zypp_get_Repository (backend, _repoName);
+		if (info.type () == zypp::repo::RepoType::NONE) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
+			return FALSE;
+		}
+
 		pk_backend_repo_signature_required (backend,
 				"dummy;0.0.1;i386;data",
 	                        _repoName,
-        	                file.c_str (),
+				info.baseUrlsBegin ()->asString ().c_str (),
                 	        id.c_str (),
                         	id.c_str (),
 	                        "UNKNOWN",
@@ -458,10 +486,16 @@ zypp_signature_required (PkBackend *backend, const std::string &file)
 	gboolean ok = FALSE;
 
 	if (std::find (_signatures[backend]->begin (), _signatures[backend]->end (), file) == _signatures[backend]->end ()) {
-        	pk_backend_repo_signature_required (backend,
+        	zypp::RepoInfo info = zypp_get_Repository (backend, _repoName);
+		if (info.type () == zypp::repo::RepoType::NONE) {
+			pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Repository unknown");
+			return FALSE;
+		}
+
+		pk_backend_repo_signature_required (backend,
 				"dummy;0.0.1;i386;data",
 	                        _repoName,
-        	                file.c_str (),
+				info.baseUrlsBegin ()->asString ().c_str (),
 	                        "UNKNOWN",
         	                file.c_str (),
                 	        "UNKNOWN",
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index b3ba99d..e741e4e 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -130,6 +130,12 @@ zypp::sat::Solvable zypp_get_package_by_id (const gchar *package_id);
 gchar * zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable);
 
 /**
+ * Get the RepoInfo 
+ */
+zypp::RepoInfo
+zypp_get_Repository (PkBackend *backend, const gchar *alias);
+
+/**
   * Ask the User if it is OK to import an GPG-Key for a repo
   */
 gboolean zypp_signature_required (PkBackend *backend, const zypp::PublicKey &key);
commit a3feeafcbd9eb1c4cbdfde99d85006a82963590f
Merge: 905e692... 9cdeddf...
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 21 15:49:32 2008 +0200

    Merge branch 'master' of git+ssh://shaas@git.packagekit.org/srv/git/PackageKit

commit 905e692ebd3fee7ef378ec0f2d1930776ca1ed19
Author: Stefan Haas <shaas at suse.de>
Date:   Wed May 21 15:48:55 2008 +0200

    rotate logs #BNC390339

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 15c4b4f..b684312 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -47,7 +47,6 @@
 #include <zypp/target/rpm/RpmDb.h>
 #include <zypp/target/rpm/RpmHeader.h>
 #include <zypp/target/rpm/RpmException.h>
-#include <zypp/base/LogControl.h>
 #include <zypp/TmpPath.h>
 
 #include <zypp/sat/Solvable.h>
@@ -90,7 +89,7 @@ std::map<PkBackend *, std::vector<std::string> *> _signatures;
 static void
 backend_initialize (PkBackend *backend)
 {
-	zypp::base::LogControl::instance ().logfile("/var/log/pk_backend_zypp");
+	zypp_logging ();
 	pk_debug ("zypp_backend_initialize");
 	EventDirector *eventDirector = new EventDirector (backend);
 	_eventDirectors [backend] = eventDirector;
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index 2b848f0..cc0d7e3 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -25,6 +25,7 @@
 #include <sstream>
 #include <stdlib.h>
 #include <glib.h>
+#include <glib/gstdio.h>
 #include <zypp/ZYpp.h>
 #include <zypp/ZYppFactory.h>
 #include <zypp/RepoManager.h>
@@ -45,6 +46,7 @@
 #include <zypp/target/rpm/RpmDb.h>
 #include <zypp/target/rpm/RpmHeader.h>
 #include <zypp/target/rpm/librpmDb.h>
+#include <zypp/base/LogControl.h>
 
 #include <zypp/base/Logger.h>
 
@@ -98,6 +100,34 @@ get_zypp ()
 	return zypp;
 }
 
+/**
+ * Enable and rotate zypp logging
+ */
+gboolean
+zypp_logging ()
+{
+	gchar *file = g_strdup ("/var/log/pk_backend_zypp");
+	gchar *file_old = g_strdup ("/var/log/pk_backend_zypp-1");
+
+	if (g_file_test (file, G_FILE_TEST_EXISTS)) {
+		struct stat buffer;
+		g_stat (file, &buffer);
+		// if the file is bigger than 5 MB rotate
+		if ((guint)buffer.st_size > 5242880) {
+			if (g_file_test (file_old, G_FILE_TEST_EXISTS))
+				g_remove (file_old);
+			g_rename (file, file_old);
+		}
+	}
+ 
+	zypp::base::LogControl::instance ().logfile(file);
+		
+	g_free (file);
+	g_free (file_old);
+
+	return TRUE;
+}
+
 gboolean
 zypp_is_changeable_media (const zypp::Url &url)
 {
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index 9e3bad1..b3ba99d 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -70,6 +70,11 @@ extern gchar *_repoName;
 
 zypp::ZYpp::Ptr get_zypp ();
 
+/**
+ * Enable and rotate logging
+ */
+gboolean zypp_logging ();
+
 gboolean zypp_is_changeable_media (const zypp::Url &url);
 
 /**
commit 9cdeddfb807123283d6f03a9b663d5aef86b2fe7
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed May 21 15:32:42 2008 +0200

    Fix RemovePackages in the daemon backend

diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py
index f69b14f..9fd627a 100644
--- a/python/packagekit/daemonBackend.py
+++ b/python/packagekit/daemonBackend.py
@@ -658,8 +658,9 @@ class PackageKitBaseBackend(dbus.service.Object):
         '''
         Implement the {backend}-remove functionality
         '''
-        pklog.info("RemovePackages(%s, %s, %s)" % (package[0], allowdep, autoremove))
-        self.doRemovePackages(package, allowdep, autoremove)
+        pklog.info("RemovePackages(%s, %s, %s)" % (packages, allowdep,
+                                                   autoremove))
+        self.doRemovePackages(packages, allowdep, autoremove)
 
     def doRemovePackages(self, packages, allowdep, autoremove):
         '''
commit 244eb344d406c3644aaae9b175d2224e5ebf99fa
Author: Fabian Affolter <fabian at bernewireless.net>
Date:   Tue May 20 19:56:03 2008 +0000

    2008-05-20  Fabian Affolter <fabian at bernewireless.net> (via
    fab at fedoraproject.org)
    
      * po/de.po: Updated German translation

diff --git a/po/de.po b/po/de.po
index 33d30c1..6e8013e 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PackageKit\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-04-23 01:36+0000\n"
-"PO-Revision-Date: 2008-04-23 19:28+0100\n"
+"POT-Creation-Date: 2008-05-03 01:22+0000\n"
+"PO-Revision-Date: 2008-05-20 21:52+0100\n"
 "Last-Translator: Fabian Affolter <fab at fedoraproject.org>\n"
 "Language-Team: German <fedora-trans-de at redhat.com>\n"
 "MIME-Version: 1.0\n"
@@ -18,239 +18,239 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Language: German\n"
 
-#: ../client/pk-console.c:208
+#: ../client/pk-console.c:224
 msgid "Update detail"
 msgstr "Aktualisierungsdetails"
 
-#: ../client/pk-console.c:400
+#: ../client/pk-console.c:425
 msgid "A system restart is required"
 msgstr "Ein Systemneustart ist erforderlich"
 
-#: ../client/pk-console.c:402
+#: ../client/pk-console.c:427
 msgid "A logout and login is required"
 msgstr "Eine Neuanmeldung ist erforderlich"
 
-#: ../client/pk-console.c:404
+#: ../client/pk-console.c:429
 msgid "An application restart is required"
 msgstr "Ein Neustart der Anwendung ist erforderlich"
 
-#: ../client/pk-console.c:443
+#: ../client/pk-console.c:474
 #, c-format
 msgid "Please enter a number from 1 to %i: "
 msgstr "Bitte eine Zahl zwischen 1 und %i eingeben: "
 
-#: ../client/pk-console.c:493
+#: ../client/pk-console.c:524
 msgid "Could not find a package match"
 msgstr "Es konnte kein passendes Paket gefunden werden"
 
-#: ../client/pk-console.c:507
+#: ../client/pk-console.c:538
 msgid "There are multiple package matches"
 msgstr "Es wurden mehrere passende Paket gefunden"
 
 #. find out what package the user wants to use
-#: ../client/pk-console.c:514
+#: ../client/pk-console.c:545
 msgid "Please enter the package number: "
 msgstr "Bitte die Paketnummer eingeben: "
 
-#: ../client/pk-console.c:530
+#: ../client/pk-console.c:561
 msgid "Could not find a package with that name to install, or package already installed"
 msgstr "Es konnten weder installierte noch zu installierende Paket mit diesem Namen gefunden werden"
 
-#: ../client/pk-console.c:612
+#: ../client/pk-console.c:643
 msgid "Could not find a package with that name to remove"
 msgstr "Es konnte kein Paket mit diesem Namen zum Deinstallieren gefunden werden"
 
-#: ../client/pk-console.c:652
+#: ../client/pk-console.c:683
 msgid "The following packages have to be removed"
 msgstr "Die folgenden Paket werden entfernt"
 
 #. get user input
-#: ../client/pk-console.c:661
+#: ../client/pk-console.c:692
 msgid "Okay to remove additional packages?"
 msgstr "Die folgenden zusätzlichen Pakete entfernen?"
 
-#: ../client/pk-console.c:665
+#: ../client/pk-console.c:696
 msgid "Cancelled!"
 msgstr "Abgebrochen!"
 
-#: ../client/pk-console.c:687
+#: ../client/pk-console.c:718
 msgid "Could not find a package with that name to update"
 msgstr "Es konnte kein Paket mit diesem Namen zum Aktualisieren gefunden werden"
 
-#: ../client/pk-console.c:705
+#: ../client/pk-console.c:736
 msgid "Could not find what packages require this package"
 msgstr "Es konnte nicht rausgefunden werden, welche Pakete dieses Paket benötigen"
 
-#: ../client/pk-console.c:723
+#: ../client/pk-console.c:754
 msgid "Could not get dependencies for this package"
 msgstr "Die Abhängigkeiten für dieses Paket konnten nicht ermittelt werden"
 
-#: ../client/pk-console.c:741
-msgid "Could not find a description for this package"
-msgstr "Die Beschreibung für dieses Paket konnten nicht ermittelt werden"
+#: ../client/pk-console.c:772
+msgid "Could not find details for this package"
+msgstr "Die Details für dieses Paket konnten nicht gefunden werden"
 
-#: ../client/pk-console.c:759
+#: ../client/pk-console.c:790
 msgid "Could not find the files for this package"
 msgstr "Die Dateien für dieses Paket konnten nicht ermittelt werden"
 
-#: ../client/pk-console.c:819
+#: ../client/pk-console.c:870
 msgid "Package description"
 msgstr "Paketbeschreibung"
 
-#: ../client/pk-console.c:842
+#: ../client/pk-console.c:893
 msgid "Package files"
 msgstr "Paketinhalt"
 
-#: ../client/pk-console.c:850
+#: ../client/pk-console.c:901
 msgid "No files"
 msgstr "Keine Dateien"
 
 #. get user input
-#: ../client/pk-console.c:882
+#: ../client/pk-console.c:933
 msgid "Okay to import key?"
 msgstr "Soll der Schlüssel importiert werden?"
 
-#: ../client/pk-console.c:885
+#: ../client/pk-console.c:936
 msgid "Did not import key"
 msgstr "Den Schlüssel nicht importieren"
 
 #. get user input
-#: ../client/pk-console.c:925
+#: ../client/pk-console.c:976
 msgid "Do you agree?"
 msgstr "Sind Sie einverstanden?"
 
-#: ../client/pk-console.c:928
+#: ../client/pk-console.c:979
 msgid "Did not agree to licence, task will fail"
 msgstr "Lizenz wurde abgelehnt, Aufgabe wird fehlschlagen"
 
-#: ../client/pk-console.c:957
+#: ../client/pk-console.c:1008
 msgid "The daemon crashed mid-transaction!"
 msgstr "Der Dienst ist während der Verarbeitung abgestürzt!"
 
 #. header
-#: ../client/pk-console.c:1010
+#: ../client/pk-console.c:1061
 msgid "PackageKit Console Interface"
 msgstr "PackageKit-Konsolenschnittstelle"
 
-#: ../client/pk-console.c:1010
+#: ../client/pk-console.c:1061
 msgid "Subcommands:"
 msgstr "Unterbefehle:"
 
-#: ../client/pk-console.c:1114
-#: ../client/pk-monitor.c:100
+#: ../client/pk-console.c:1165
+#: ../client/pk-monitor.c:104
 #: ../src/pk-main.c:189
 msgid "Show extra debugging information"
 msgstr "Zusätzliche Debugging-Informationen anzeigen"
 
-#: ../client/pk-console.c:1116
-#: ../client/pk-monitor.c:102
+#: ../client/pk-console.c:1167
+#: ../client/pk-monitor.c:106
 msgid "Show the program version and exit"
 msgstr "Die Programmversion anzeigen und beenden"
 
-#: ../client/pk-console.c:1118
+#: ../client/pk-console.c:1169
 msgid "Set the filter, e.g. installed"
 msgstr "Setzt den Filter, z. B. installiert"
 
-#: ../client/pk-console.c:1120
+#: ../client/pk-console.c:1171
 msgid "Exit without waiting for actions to complete"
 msgstr "Beenden ohne auf das Ende der Aktionen zu warten"
 
-#: ../client/pk-console.c:1143
+#: ../client/pk-console.c:1194
 msgid "Could not connect to system DBUS."
 msgstr "Mit System-DBUS konnte nicht verbunden werden."
 
-#: ../client/pk-console.c:1231
+#: ../client/pk-console.c:1288
 msgid "You need to specify a search type"
 msgstr "Es muss eine Suchart angegeben werden"
 
-#: ../client/pk-console.c:1236
-#: ../client/pk-console.c:1243
-#: ../client/pk-console.c:1250
-#: ../client/pk-console.c:1257
-#: ../client/pk-console.c:1361
-#: ../client/pk-console.c:1368
-#: ../client/pk-console.c:1375
-#: ../client/pk-console.c:1382
+#: ../client/pk-console.c:1293
+#: ../client/pk-console.c:1300
+#: ../client/pk-console.c:1307
+#: ../client/pk-console.c:1314
+#: ../client/pk-console.c:1421
+#: ../client/pk-console.c:1428
+#: ../client/pk-console.c:1435
+#: ../client/pk-console.c:1442
 msgid "You need to specify a search term"
 msgstr "Es muss ein Suchausdruck angegeben werden"
 
-#: ../client/pk-console.c:1262
+#: ../client/pk-console.c:1319
 msgid "Invalid search type"
 msgstr "Ungültige Suchart"
 
-#: ../client/pk-console.c:1267
+#: ../client/pk-console.c:1324
 msgid "You need to specify a package or file to install"
 msgstr "Es muss ein Paket oder eine Datei zum Installieren angegeben werden"
 
-#: ../client/pk-console.c:1280
+#: ../client/pk-console.c:1339
 msgid "You need to specify a type, key_id and package_id"
 msgstr "Es muss ein Typ angegeben werden, key_id oder package_id"
 
-#: ../client/pk-console.c:1287
+#: ../client/pk-console.c:1346
 msgid "You need to specify a package to remove"
 msgstr "Es muss ein Paket zum Entfernen angegeben werden"
 
-#: ../client/pk-console.c:1294
+#: ../client/pk-console.c:1353
 msgid "You need to specify a eula-id"
 msgstr "Es muss eine eula-id angegeben werden"
 
-#: ../client/pk-console.c:1309
+#: ../client/pk-console.c:1369
 msgid "You need to specify a package name to resolve"
 msgstr "Es muss ein Paketname zum Auflösen angegeben werden"
 
-#: ../client/pk-console.c:1316
-#: ../client/pk-console.c:1323
+#: ../client/pk-console.c:1376
+#: ../client/pk-console.c:1383
 msgid "You need to specify a repo name"
 msgstr "Es muss ein Repository-Name angegeben werden"
 
-#: ../client/pk-console.c:1330
+#: ../client/pk-console.c:1390
 msgid "You need to specify a repo name/parameter and value"
 msgstr "Es muss ein Repository-Name/Argument und Wert angegeben werden"
 
-#: ../client/pk-console.c:1343
+#: ../client/pk-console.c:1403
 msgid "You need to specify a time term"
 msgstr "Es muss ein Zeitausdruck angegeben werden"
 
-#: ../client/pk-console.c:1348
+#: ../client/pk-console.c:1408
 msgid "You need to specify a correct role"
 msgstr "Es muss eine korrekte Rolle angegeben werden"
 
-#: ../client/pk-console.c:1353
+#: ../client/pk-console.c:1413
 msgid "Failed to get last time"
 msgstr "Die letzte Zeit konnte nicht abgefragt werden"
 
-#: ../client/pk-console.c:1389
-msgid "You need to specify a package to find the description for"
-msgstr "Es muss ein Paket angegeben werden zu dem die Beschreibung gefunden werden soll"
+#: ../client/pk-console.c:1449
+msgid "You need to specify a package to find the details for"
+msgstr "Es muss ein Paket angegeben werden zu dem die Details gefunden werden sollen"
 
-#: ../client/pk-console.c:1396
+#: ../client/pk-console.c:1456
 msgid "You need to specify a package to find the files for"
 msgstr "Es muss ein Paket angegeben werden zu dem die Dateien gefunden werden sollen"
 
-#: ../client/pk-console.c:1441
+#: ../client/pk-console.c:1503
 #, c-format
 msgid "Option '%s' not supported"
 msgstr "Option '%s' wird nicht unterstützt"
 
-#: ../client/pk-console.c:1452
+#: ../client/pk-console.c:1514
 msgid "Command failed"
 msgstr "Befehl fehlgeschlagen"
 
-#: ../client/pk-console.c:1456
+#: ../client/pk-console.c:1518
 msgid "You don't have the necessary privileges for this operation"
 msgstr "Es fehlen die benötigten Rechte für diese Operation"
 
-#: ../client/pk-monitor.c:113
+#: ../client/pk-monitor.c:117
 msgid "PackageKit Monitor"
 msgstr "PackageKit Monitor"
 
-#: ../client/pk-import-desktop.c:283
+#: ../client/pk-import-desktop.c:293
 #: ../client/pk-import-specspo.c:169
 #, c-format
 msgid "Could not open database: %s"
 msgstr "Datenbank konnte nicht geöffnet werden: %s"
 
-#: ../client/pk-import-desktop.c:284
+#: ../client/pk-import-desktop.c:294
 #: ../client/pk-import-specspo.c:170
 msgid "You probably need to run this program as the root user"
 msgstr "Das Programm muss möglicherweise als Benutzer root ausgeführt werden"
@@ -308,6 +308,12 @@ msgstr "Es konnte nicht zum System-Bus verbunden werden"
 msgid "Error trying to start: %s\n"
 msgstr "Fehler beim Versuch zu starten: %s\n"
 
+#~ msgid "Could not find a description for this package"
+#~ msgstr "Die Beschreibung für dieses Paket konnten nicht ermittelt werden"
+#~ msgid "You need to specify a package to find the description for"
+#~ msgstr ""
+#~ "Es muss ein Paket angegeben werden zu dem die Beschreibung gefunden "
+#~ "werden soll"
 #~ msgid "Accept EULA"
 #~ msgstr "EULA akzeptieren"
 #~ msgid "Authentication is required to accept a EULA"
commit 8121b43917242149efbeb6c0be4b94a4f6d20ba4
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue May 20 10:37:31 2008 -0400

    Convert fingerprint into hex.

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 2a0a8f9..9c57867 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1099,12 +1099,16 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                     self.error(ERROR_BAD_GPG_SIGNATURE,
                                "GPG key not imported, and no GPG information was found.")
                 id = self._pkg_to_id(keyData['po'])
+                fingerprint = keyData['fingerprint']
+                hex_fingerprint = "%02x" * len(fingerprint) % tuple(map(ord, fingerprint))
+                # Borrowed from http://mail.python.org/pipermail/python-list/2000-September/053490.html
+
                 self.repo_signature_required(id,
                                              keyData['po'].repoid,
                                              keyData['keyurl'].replace("file://",""),
                                              keyData['userid'],
                                              keyData['hexkeyid'],
-                                             keyData['fingerprint'](),
+                                             hex_fingerprint,
                                              time.ctime(keyData['timestamp']),
                                              'gpg')
                 self.error(ERROR_GPG_FAILURE,"GPG key %s required" % keyData['hexkeyid'])
commit 937578a47d13208444666859c16aac0d1eb2d55e
Merge: f70afd8... 53f05f8...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue May 20 09:40:02 2008 -0400

    Merge changes.

diff --cc backends/yum/helpers/yumBackend.py
index 41702a0,ee2ace6..2a0a8f9
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@@ -1095,13 -1101,12 +1101,12 @@@ class PackageKitYumBackend(PackageKitBa
- 
                  id = self._pkg_to_id(keyData['po'])
                  self.repo_signature_required(id,
                                               keyData['po'].repoid,
-                                              keyData['keyurl'],
+                                              keyData['keyurl'].replace("file://",""),
                                               keyData['userid'],
                                               keyData['hexkeyid'],
 -                                             keyData['fingerprint'],
 +                                             keyData['fingerprint'](),
-                                              keyData['timestamp'],
-                                              'GPG')
+                                              time.ctime(keyData['timestamp']),
+                                              'gpg')
                  self.error(ERROR_GPG_FAILURE,"GPG key %s required" % keyData['hexkeyid'])
              except yum.Errors.YumBaseError,ye:
                  message = self._format_msgs(ye.value)
commit f70afd8bf9afb7568f42cb122adddf550759edc5
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue May 20 09:37:39 2008 -0400

    keyData['fingerprint'] is a method, not a string.

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 5b2da8f..41702a0 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1099,7 +1099,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                                              keyData['keyurl'],
                                              keyData['userid'],
                                              keyData['hexkeyid'],
-                                             keyData['fingerprint'],
+                                             keyData['fingerprint'](),
                                              keyData['timestamp'],
                                              'GPG')
                 self.error(ERROR_GPG_FAILURE,"GPG key %s required" % keyData['hexkeyid'])
commit 53f05f88944c47122027c63838523874b9d9d6fb
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue May 20 14:12:48 2008 +0100

    yum2: some more GPG fixes

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 97fdd8d..ee2ace6 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -901,14 +901,16 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             if pkg and not inst:
                 repo = self.yumbase.repos.getRepo(pkg.repoid)
                 if not already_warned and not repo.gpgcheck:
-                    self.message(MESSAGE_WARNING,"The package %s was installed untrusted from %s." % (pkg.name, repo))
+                    self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
                     already_warned = True
                 txmbr = self.yumbase.install(name=pkg.name)
                 txmbrs.extend(txmbr)
+            if inst:
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package %s is already installed", pkg.name)
         if txmbrs:
             self._runYumTransaction()
         else:
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package is already installed")
+            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The packages failed to be installed")
 
     def _checkForNewer(self,po):
         pkgs = self.yumbase.pkgSack.returnNewestByName(name=po.name)
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index cde1557..6f769f6 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -823,15 +823,24 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         self.PercentageChanged(0)
         self.StatusChanged(STATUS_RUNNING)
 
-        pkg,inst = self._findPackage(package)
-        if pkg:
+        txmbrs = []
+        already_warned = False
+        for package in packages:
+            pkg,inst = self._findPackage(package)
+            if pkg and not inst:
+                repo = self.yumbase.repos.getRepo(pkg.repoid)
+                if not already_warned and not repo.gpgcheck:
+                    self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
+                    already_warned = True
+                txmbr = self.yumbase.install(name=pkg.name)
+                txmbrs.extend(txmbr)
             if inst:
                 self._unlock_yum()
-                self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,'Package already installed')
+                self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,"The package %s is already installed", pkg.name)
                 self.Finished(EXIT_FAILED)
                 return
+        if txmbrs:
             try:
-                txmbr = self.yumbase.install(name=pkg.name)
                 successful = self._runYumTransaction()
                 if not successful:
                     # _runYumTransaction unlocked yum, set the error code, and called Finished.
@@ -844,7 +853,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 return
         else:
             self._unlock_yum()
-            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,"Package was not found")
+            self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,"The packages failed to be installed")
             self.Finished(EXIT_FAILED)
             return
 
@@ -1761,7 +1770,9 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                                "GPG key not imported, but no GPG information received from Yum.")
                 self.Finished(EXIT_FAILED)
                 return False
-            self.RepoSignatureRequired(keyData['po'].repoid,
+            id = self._pkg_to_id(keyData['po'])
+            self.RepoSignatureRequired(id,
+                                       keyData['po'].repoid,
                                        keyData['keyurl'].replace("file://",""),
                                        keyData['userid'],
                                        keyData['hexkeyid'],
diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py
index 5253b39..f69b14f 100644
--- a/python/packagekit/daemonBackend.py
+++ b/python/packagekit/daemonBackend.py
@@ -325,13 +325,13 @@ class PackageKitBaseBackend(dbus.service.Object):
 
     @PKSignalHouseKeeper
     @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
-                         signature='sssssss')
-    def RepoSignatureRequired(self,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type):
+                         signature='ssssssss')
+    def RepoSignatureRequired(self,id,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type):
         '''
         send 'repo-signature-required' signal:
         '''
         pklog.info("RepoSignatureRequired (%s, %s, %s, %s, %s, %s, %s, %s)" %
-                   (repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type))
+                   (id,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,key_type))
 
 
 #
commit d9157745d3463656553fd2674472da5b268d6d61
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue May 20 13:49:44 2008 +0100

    yum: some various gpg fixes

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index b4bc7ff..97fdd8d 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1096,16 +1096,15 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 if not keyData:
                     self.error(ERROR_BAD_GPG_SIGNATURE,
                                "GPG key not imported, and no GPG information was found.")
-
                 id = self._pkg_to_id(keyData['po'])
                 self.repo_signature_required(id,
                                              keyData['po'].repoid,
-                                             keyData['keyurl'],
+                                             keyData['keyurl'].replace("file://",""),
                                              keyData['userid'],
                                              keyData['hexkeyid'],
                                              keyData['fingerprint'],
-                                             keyData['timestamp'],
-                                             'GPG')
+                                             time.ctime(keyData['timestamp']),
+                                             'gpg')
                 self.error(ERROR_GPG_FAILURE,"GPG key %s required" % keyData['hexkeyid'])
             except yum.Errors.YumBaseError,ye:
                 message = self._format_msgs(ye.value)
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index 29f5b03..cde1557 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -1762,12 +1762,12 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 self.Finished(EXIT_FAILED)
                 return False
             self.RepoSignatureRequired(keyData['po'].repoid,
-                                       keyData['keyurl'],
+                                       keyData['keyurl'].replace("file://",""),
                                        keyData['userid'],
                                        keyData['hexkeyid'],
                                        keyData['fingerprint'],
-                                       keyData['timestamp'],
-                                       SIGTYE_GPG)
+                                       time.ctime(keyData['timestamp']),
+                                       SIGTYPE_GPG)
             self._unlock_yum()
             self.ErrorCode(ERROR_GPG_FAILURE,"GPG key not imported.")
             self.Finished(EXIT_FAILED)
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index f9c9f12..2bd416d 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -316,8 +316,8 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		pk_backend_set_percentage (backend_spawn->priv->backend, PK_BACKEND_PERCENTAGE_INVALID);
 	} else if (pk_strequal (command, "repo-signature-required")) {
 
-		if (size != 9+99) {
-			pk_error ("invalid command '%s'", command);
+		if (size != 9) {
+			pk_warning ("invalid command '%s'", command);
 			ret = FALSE;
 			goto out;
 		}
commit be1715dc04f70a7e6a003a65efe82b6568fb646d
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue May 20 11:06:24 2008 +0100

    yum: correct the name of remove_packages as this won't have worked for a little while

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 5fc4b69..b4bc7ff 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -1114,7 +1114,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 else:
                     self.error(ERROR_TRANSACTION_ERROR,message)
 
-    def remove(self,allowdep,package):
+    def remove_packages(self,allowdep,package):
         '''
         Implement the {backend}-remove functionality
         Needed to be implemented in a sub class
commit 72a9d2e341ca900d6a9b0a0ab7d707aae79b7722
Merge: c22765e... 7ec8b35...
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon May 19 19:20:47 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit c22765e605f0ed044dab75af15944c953a765269
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon May 19 13:23:47 2008 +0100

    yum; only attempt to install .rpm files rather than all types of packages

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 5b2da8f..5fc4b69 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -927,6 +927,10 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             if inst_file.endswith('.src.rpm'):
                 self.error(ERROR_CANNOT_INSTALL_SOURCE_PACKAGE,'Backend will not install a src rpm file')
                 return
+        for inst_file in inst_files:
+            if not inst_file.endswith('.rpm'):
+                self.error(ERROR_INVALID_PACKAGE_FILE,'Only rpm packages are supported')
+                return
         self._check_init()
         self.allow_cancel(False);
         self.percentage(0)
commit 7ec8b3571f3388b913af664eda90211a837f8179
Merge: 3dcdb2d... 30f1ae7...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon May 19 14:18:22 2008 +0200

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

diff --cc backends/apt2/pk-backend-apt2.c
index 9c85206,4f78ec4..70836b2
--- a/backends/apt2/pk-backend-apt2.c
+++ b/backends/apt2/pk-backend-apt2.c
@@@ -203,14 -184,14 +203,14 @@@ PK_BACKEND_OPTIONS 
  	NULL,					/* get_requires */
  	NULL,					/* get_update_detail */
  	backend_get_updates,			/* get_updates */
- 	NULL,					/* install_file */
- 	backend_install_package,		/* install_package */
+ 	NULL,					/* install_files */
+ 	backend_install_packages,		/* install_packages */
  	NULL,					/* install_signature */
  	backend_refresh_cache,			/* refresh_cache */
- 	backend_remove_package,			/* remove_package */
+ 	backend_remove_packages,		/* remove_packages */
  	NULL,					/* repo_enable */
  	NULL,					/* repo_set_data */
 -	NULL,					/* resolve */
 +	backend_resolve,			/* resolve */
  	NULL,					/* rollback */
  	backend_search_details,			/* search_details */
  	NULL,					/* search_file */
commit 30f1ae766fa4bd9511fa8efb01cc6a50b844a104
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon May 19 13:14:36 2008 +0100

    only try to install local files if they are files, not files or folders

diff --git a/client/pk-console.c b/client/pk-console.c
index 5a05a8e..0420193 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -574,7 +574,8 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 	array_files = g_ptr_array_new ();
 	length = g_strv_length (packages);
 	for (i=2; i<length; i++) {
-		is_local = g_file_test (packages[i], G_FILE_TEST_EXISTS);
+		/* are we a local file */
+		is_local = g_file_test (packages[i], G_FILE_TEST_EXISTS & G_FILE_TEST_IS_REGULAR);
 		if (is_local) {
 			g_ptr_array_add (array_files, g_strdup (packages[i]));
 		} else {
commit e47724973b6a0dceecfa05c037beb089058c9c18
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon May 19 12:16:39 2008 +0100

    trivial: remove some unneeded debug statements

diff --git a/libpackagekit/pk-package-item.c b/libpackagekit/pk-package-item.c
index 87905dc..ff4bd4e 100644
--- a/libpackagekit/pk-package-item.c
+++ b/libpackagekit/pk-package-item.c
@@ -56,7 +56,6 @@ pk_package_item_new (PkInfoEnum info, const gchar *package_id, const gchar *summ
 
 	g_return_val_if_fail (package_id != NULL, FALSE);
 
-	pk_debug ("adding to cache item package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary);
 	item = g_new0 (PkPackageItem, 1);
 	item->info = info;
 	item->package_id = g_strdup (package_id);
diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index 5d95e1b..212f36e 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -77,7 +77,6 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package
 	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE);
 	g_return_val_if_fail (package_id != NULL, FALSE);
 
-	pk_debug ("adding to cache array package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary);
 	item = pk_package_item_new (info, package_id, summary);
 	g_ptr_array_add (plist->priv->array, item);
 
@@ -104,9 +103,6 @@ pk_package_list_add_item (PkPackageList *plist, PkPackageItem *item)
 		return FALSE;
 	}
 
-	pk_debug ("adding to cache array package %s, %s, %s",
-		  pk_info_enum_to_text (item->info), item->package_id, item->summary);
-
 	item_new = pk_package_item_copy (item);
 	g_ptr_array_add (plist->priv->array, item_new);
 
commit ada0ec9fdd13df10c17a5bb3be55aba57771b17a
Author: Peter Sulyok <sulyokpeti at gmail.com>
Date:   Sun May 18 22:23:17 2008 +0000

    2008-05-18  Peter Sulyok <sulyokpeti at gmail.com> (via peti at fedoraproject.org)
    
      * po/LINGUAS: hu added to LINGUAS

diff --git a/po/LINGUAS b/po/LINGUAS
index 6dbee0e..f87e6b3 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -5,6 +5,7 @@ es
 fi
 fr
 he
+hu
 it
 nl
 no_nb
commit b2277299db95abd26e252b7bc7a7923f3e3b1ee0
Merge: 3e6dba0... 8ce7db0...
Author: Peter Sulyok <sulyokpeti at gmail.com>
Date:   Sun May 18 22:11:26 2008 +0000

    Merge branch 'master' of git+ssh://transif@git.packagekit.org/srv/git/PackageKit

commit 3e6dba0f531f0a9b60e2c915488629753bb6121d
Author: Peter Sulyok <sulyokpeti at gmail.com>
Date:   Sun May 18 22:11:17 2008 +0000

    2008-05-18  Peter Sulyok <sulyokpeti at gmail.com> (via peti at fedoraproject.org)
    
      * po/hu.po: Initial Hungarian translation

diff --git a/po/hu.po b/po/hu.po
new file mode 100644
index 0000000..ea732d0
--- /dev/null
+++ b/po/hu.po
@@ -0,0 +1,311 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: packagekit\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-05-18 17:43+0000\n"
+"PO-Revision-Date: 2008-05-19 00:08+0100\n"
+"Last-Translator: Sulyok Péter <peti at fedoraproject.org>\n"
+"Language-Team: Hungarian <fedora-trans-hu at redhat.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1\n"
+"X-Poedit-Language: Hungarian\n"
+"X-Poedit-Country: HUNGARY\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: ../client/pk-console.c:224
+msgid "Update detail"
+msgstr "Frissítés részletező"
+
+#: ../client/pk-console.c:425
+msgid "A system restart is required"
+msgstr "Rendszer-újraindítás szükséges"
+
+#: ../client/pk-console.c:427
+msgid "A logout and login is required"
+msgstr "Kijelentkezés és bejelentkezés szükséges"
+
+#: ../client/pk-console.c:429
+msgid "An application restart is required"
+msgstr "Alkalmazás-újraindítás szükséges"
+
+#: ../client/pk-console.c:474
+#, c-format
+msgid "Please enter a number from 1 to %i: "
+msgstr "Kérem adjon meg egy számot 1-től %i-ig:"
+
+#: ../client/pk-console.c:524
+msgid "Could not find a package match"
+msgstr "Nincs megfelelő csomag"
+
+#: ../client/pk-console.c:538
+msgid "There are multiple package matches"
+msgstr "Több csomag illik"
+
+#. find out what package the user wants to use
+#: ../client/pk-console.c:545
+msgid "Please enter the package number: "
+msgstr "Kérem adja meg a csomagszámot:"
+
+#: ../client/pk-console.c:561
+msgid "Could not find a package with that name to install, or package already installed"
+msgstr "Nem lehetett csomagot találni azzal a névvel telepítésre, vagy márt telepített csomagot"
+
+#: ../client/pk-console.c:643
+msgid "Could not find a package with that name to remove"
+msgstr "Nem lehetett csomagot találni azzal a névvel törlésre"
+
+#: ../client/pk-console.c:683
+msgid "The following packages have to be removed"
+msgstr "A következő csomagokat kell eltávolítani"
+
+#. get user input
+#: ../client/pk-console.c:692
+msgid "Okay to remove additional packages?"
+msgstr "Eltávolíthatók további csomagok?"
+
+#: ../client/pk-console.c:696
+msgid "Cancelled!"
+msgstr "Megszakítva!"
+
+#: ../client/pk-console.c:718
+msgid "Could not find a package with that name to update"
+msgstr "Nem lehetett csomagot találni azzal a névvel frissítésre"
+
+#: ../client/pk-console.c:736
+msgid "Could not find what packages require this package"
+msgstr "Nem lehetett megtudni mely csomagok szükségesek"
+
+#: ../client/pk-console.c:754
+msgid "Could not get dependencies for this package"
+msgstr "Nem lehetett csomagfüggőséget megkapni e csomaghoz"
+
+#: ../client/pk-console.c:772
+msgid "Could not find details for this package"
+msgstr "Nem lehetett részletezőt találni e csomaghoz"
+
+#: ../client/pk-console.c:790
+msgid "Could not find the files for this package"
+msgstr "Nem lehetett fájlokat találni e csomaghoz"
+
+#: ../client/pk-console.c:870
+msgid "Package description"
+msgstr "Csomagleírás"
+
+#: ../client/pk-console.c:893
+msgid "Package files"
+msgstr "Csomagfájlok"
+
+#: ../client/pk-console.c:901
+msgid "No files"
+msgstr "Nincs fájl"
+
+#. get user input
+#: ../client/pk-console.c:933
+msgid "Okay to import key?"
+msgstr "Behozhatunk kulcsot?"
+
+#: ../client/pk-console.c:936
+msgid "Did not import key"
+msgstr "Nem hoztunk be kulcsot"
+
+#. get user input
+#: ../client/pk-console.c:976
+msgid "Do you agree?"
+msgstr "Egyetért?"
+
+#: ../client/pk-console.c:979
+msgid "Did not agree to licence, task will fail"
+msgstr "Nem egyezett meg az engedélyben, a munka elbukik"
+
+#: ../client/pk-console.c:1008
+msgid "The daemon crashed mid-transaction!"
+msgstr "A szolgáltatás összeomlott tranzakció közben!"
+
+#. header
+#: ../client/pk-console.c:1061
+msgid "PackageKit Console Interface"
+msgstr "PackageKit parancssori felület"
+
+#: ../client/pk-console.c:1061
+msgid "Subcommands:"
+msgstr "Részparancsok:"
+
+#: ../client/pk-console.c:1165
+#: ../client/pk-monitor.c:104
+#: ../src/pk-main.c:189
+msgid "Show extra debugging information"
+msgstr "Extra hibakereső adatok megjelenítése"
+
+#: ../client/pk-console.c:1167
+#: ../client/pk-monitor.c:106
+msgid "Show the program version and exit"
+msgstr "Programváltozat megmutatása és kilépés"
+
+#: ../client/pk-console.c:1169
+msgid "Set the filter, e.g. installed"
+msgstr "Szűrő beállítása, pl. telepítve"
+
+#: ../client/pk-console.c:1171
+msgid "Exit without waiting for actions to complete"
+msgstr "Kilépés cselekmény befejezésére várakozás nélkül"
+
+#: ../client/pk-console.c:1194
+msgid "Could not connect to system DBUS."
+msgstr "Nem lehetett kapcsolódni DBUS-hoz."
+
+#: ../client/pk-console.c:1288
+msgid "You need to specify a search type"
+msgstr "Meg kell adni a keresendő típust"
+
+#: ../client/pk-console.c:1293
+#: ../client/pk-console.c:1300
+#: ../client/pk-console.c:1307
+#: ../client/pk-console.c:1314
+#: ../client/pk-console.c:1421
+#: ../client/pk-console.c:1428
+#: ../client/pk-console.c:1435
+#: ../client/pk-console.c:1442
+msgid "You need to specify a search term"
+msgstr "Meg kell adni a keresendő kifejezést"
+
+#: ../client/pk-console.c:1319
+msgid "Invalid search type"
+msgstr "Érvénytelen típus"
+
+#: ../client/pk-console.c:1324
+msgid "You need to specify a package or file to install"
+msgstr "Meg kell adnia a telepítendő csomag  vagy fájl nevét"
+
+#: ../client/pk-console.c:1339
+msgid "You need to specify a type, key_id and package_id"
+msgstr "Meg kell adnia egy típust, kulcs azonosítót és csomag azonosítót"
+
+#: ../client/pk-console.c:1346
+msgid "You need to specify a package to remove"
+msgstr "Meg kell adnia egy eltávolítandó csomagot"
+
+#: ../client/pk-console.c:1353
+msgid "You need to specify a eula-id"
+msgstr "Meg kell adnia egy végfelhasználó azonosítót"
+
+#: ../client/pk-console.c:1369
+msgid "You need to specify a package name to resolve"
+msgstr "Meg kell adnia egy feloldandó csomagnevet"
+
+#: ../client/pk-console.c:1376
+#: ../client/pk-console.c:1383
+msgid "You need to specify a repo name"
+msgstr "Meg kell adnia egy tár nevét"
+
+#: ../client/pk-console.c:1390
+msgid "You need to specify a repo name/parameter and value"
+msgstr "Meg kell adnia egy tárnevet/paramétert és értéket"
+
+#: ../client/pk-console.c:1403
+msgid "You need to specify a time term"
+msgstr "Meg kell adnia egy időszakot"
+
+#: ../client/pk-console.c:1408
+msgid "You need to specify a correct role"
+msgstr "Meg kell adnia egy helyes szerepet"
+
+#: ../client/pk-console.c:1413
+msgid "Failed to get last time"
+msgstr "Nem sikerült megkapni az utolsó időt"
+
+#: ../client/pk-console.c:1449
+msgid "You need to specify a package to find the details for"
+msgstr "Meg kell adnia egy egy csomagot, amihez részletező keresendő"
+
+#: ../client/pk-console.c:1456
+msgid "You need to specify a package to find the files for"
+msgstr "Meg kell adnia egy csomagot, amihez fájlokat kell találni"
+
+#: ../client/pk-console.c:1503
+#, c-format
+msgid "Option '%s' not supported"
+msgstr "„%s” opció nem támogatott"
+
+#: ../client/pk-console.c:1514
+msgid "Command failed"
+msgstr "Parancs elbukott"
+
+#: ../client/pk-console.c:1518
+msgid "You don't have the necessary privileges for this operation"
+msgstr "Önnek nincs meg  szükséges jogosultsága e műveletre"
+
+#: ../client/pk-monitor.c:117
+msgid "PackageKit Monitor"
+msgstr "PackageKit figyelő"
+
+#: ../client/pk-import-desktop.c:293
+#: ../client/pk-import-specspo.c:169
+#, c-format
+msgid "Could not open database: %s"
+msgstr "Nem lehetett megnyitni %s adatbázist"
+
+#: ../client/pk-import-desktop.c:294
+#: ../client/pk-import-specspo.c:170
+msgid "You probably need to run this program as the root user"
+msgstr "E program valószínűleg rendszergazdaként futtatható"
+
+#: ../src/pk-main.c:83
+msgid "Startup failed due to security policies on this machine."
+msgstr "Indulás sikertelen a gép biztonsági szabályzata miatt."
+
+#: ../src/pk-main.c:84
+msgid "This can happen for two reasons:"
+msgstr "Két okból történet mehet:"
+
+#: ../src/pk-main.c:85
+msgid "The correct user is not launching the executable (usually root)"
+msgstr "A helyes használó nem indítja a futtathatót (rendszerint rendszergada)"
+
+#: ../src/pk-main.c:86
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system /etc/dbus-1/system.d directory"
+msgstr "Az org.freedesktop.PackageKit.conf a rendszert nem telepítették  a system /etc/dbus-1/system.d mappába"
+
+#: ../src/pk-main.c:185
+msgid "Packaging backend to use, e.g. dummy"
+msgstr "Használandó csomagoló háttér, pl. dummy"
+
+#: ../src/pk-main.c:187
+msgid "Daemonize and detach from the terminal"
+msgstr "Szolgálatatás és leválasztás terminálról"
+
+#: ../src/pk-main.c:191
+msgid "Disable the idle timer"
+msgstr "Tétlen időzítő kikapcsolása"
+
+#: ../src/pk-main.c:193
+msgid "Show version and exit"
+msgstr "Változat mutatása és kilépés"
+
+#: ../src/pk-main.c:195
+msgid "Exit after a small delay"
+msgstr "Kilépés rövid késleltetés után"
+
+#: ../src/pk-main.c:197
+msgid "Exit after the engine has loaded"
+msgstr "Kilépés a motor betöltése után"
+
+#: ../src/pk-main.c:207
+msgid "PackageKit service"
+msgstr "PackageKit szolgáltatás"
+
+#: ../src/pk-main.c:233
+msgid "Cannot connect to the system bus"
+msgstr "Nem lehetett csatlakozni a rendszerbuszhoz"
+
+#: ../src/pk-main.c:273
+#, c-format
+msgid "Error trying to start: %s\n"
+msgstr "Hiba %s indításakor\n"
+
commit 8ce7db0957db8a7702341cebd82de7dc14b7934a
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Sun May 18 00:08:25 2008 +0200

    poldek: implement WhatProvides

diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index fdc99d3..cf1776f 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -53,7 +53,8 @@ enum {
 	SEARCH_ENUM_NAME,
 	SEARCH_ENUM_GROUP,
 	SEARCH_ENUM_DETAILS,
-	SEARCH_ENUM_FILE
+	SEARCH_ENUM_FILE,
+	SEARCH_ENUM_PROVIDES
 };
 
 typedef struct {
@@ -916,7 +917,8 @@ poldek_pkg_is_gui (struct pkg *pkg)
 static gboolean
 search_package_thread (PkBackend *backend)
 {
-	PkFilterEnum filters;
+	PkFilterEnum		filters;
+	PkProvidesEnum		provides;
 	gchar			*search_cmd = NULL;
 	struct poclidek_rcmd	*cmd = NULL;
 	const gchar *search;
@@ -951,8 +953,17 @@ search_package_thread (PkBackend *backend)
 		case SEARCH_ENUM_FILE:
 			search_cmd = g_strdup_printf ("search -qlf *%s*", search);
 			break;
-		default:
-			/* Error */
+		/* WhatProvides */
+		case SEARCH_ENUM_PROVIDES:
+			provides = pk_backend_get_uint (backend, "provides");
+
+			if (provides == PK_PROVIDES_ENUM_ANY) {
+				search_cmd = g_strdup_printf ("search -qp %s", search);
+			} else if (provides == PK_PROVIDES_ENUM_MODALIAS) {
+			} else if (provides == PK_PROVIDES_ENUM_CODEC) {
+			} else if (provides == PK_PROVIDES_ENUM_MIMETYPE) {
+				search_cmd = g_strdup_printf ("search -qp mimetype(%s)", search);
+			}
 			break;
 	}
 
@@ -2213,6 +2224,20 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
 	pk_backend_finished (backend);
 }
 
+/**
+ * backend_what_provides:
+ **/
+static void
+backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+{
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
+	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
+	pb_error_clean ();
+
+	pk_backend_set_uint (backend, "mode", SEARCH_ENUM_PROVIDES);
+	pk_backend_thread_create (backend, search_package_thread);
+}
+
 PK_BACKEND_OPTIONS (
 	"poldek",					/* description */
 	"Marcin Banasiak <megabajt at pld-linux.org>",	/* author */
@@ -2245,6 +2270,6 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* service pack */
 	backend_update_packages,			/* update_packages */
 	backend_update_system,				/* update_system */
-	NULL						/* what_provides */
+	backend_what_provides				/* what_provides */
 );
 
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index efa8344..f21b842 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -403,7 +403,7 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- poldek -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- yum -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
commit 27572867172409841861266899ac664cc47d4eea
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Sat May 17 21:38:27 2008 +0200

    Fix typo that can confuse developers

diff --git a/src/pk-backend.h b/src/pk-backend.h
index fb17e3c..a7ba754 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -256,7 +256,7 @@ typedef struct {
 	void		(*update_system)		(PkBackend	*backend);
 	void		(*what_provides)		(PkBackend	*backend,
 							 PkFilterEnum	 filters,
-							 PkProvidesEnum provide,
+							 PkProvidesEnum	 provides,
 							 const gchar	*search);
 	gpointer	padding[10];
 } PkBackendDesc;
commit abedd13afa145b0f9a2d643deb69d2c495a6e782
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Sat May 17 21:30:55 2008 +0200

    Use pk_provides_enum_from_text for converting text into PkProvidesEnum

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 07ffdee..1d9271a 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -2871,7 +2871,7 @@ pk_transaction_what_provides (PkTransaction *transaction, const gchar *filter, c
 		return;
 	}
 
-	provides = pk_role_enum_from_text (type);
+	provides = pk_provides_enum_from_text (type);
 	if (provides == PK_PROVIDES_ENUM_UNKNOWN) {
 		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_PROVIDE,
 				     "provide type '%s' not found", type);
commit 5f5587e928dbb5cf8b1c8cc8fa2f656d97654ffd
Merge: 3f2f41b... d1e096c...
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 15:51:40 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit 3f2f41bd4923c795873f9d122401238853baaf3d
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 15:38:10 2008 +0100

    add pk_control_set_proxy so we can trivially set the proxy from client programs

diff --git a/etc/PackageKit.conf.in b/etc/PackageKit.conf.in
index 8f9bd57..7a48320 100644
--- a/etc/PackageKit.conf.in
+++ b/etc/PackageKit.conf.in
@@ -39,5 +39,5 @@ DefaultBackend=@defaultbackend@
 # They are in the format username:password at server:port
 #
 # ProxyHTTP=username:password at server.lan:8080
-# ProxyFTP=username:password at server.lan:21
+# ProxyFTP=server.lan:21
 
diff --git a/libpackagekit/pk-control.c b/libpackagekit/pk-control.c
index f2de5ae..5a54ccc 100644
--- a/libpackagekit/pk-control.c
+++ b/libpackagekit/pk-control.c
@@ -198,6 +198,43 @@ out:
 }
 
 /**
+ * pk_control_set_proxy:
+ * @control: a valid #PkControl instance
+ * @proxy_http: a HTTP proxy string such as "username:password at server.lan:8080"
+ * @proxy_ftp: a FTP proxy string such as "server.lan:8080"
+ *
+ * Set a proxy on the PK daemon
+ *
+ * Return value: if we set the proxy successfully
+ **/
+gboolean
+pk_control_set_proxy (PkControl *control, const gchar *proxy_http, const gchar *proxy_ftp)
+{
+	gboolean ret = FALSE;
+	GError *error = NULL;
+
+	g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN);
+
+	/* check to see if we have a valid proxy */
+	if (control->priv->proxy == NULL) {
+		pk_warning ("No proxy for manager");
+		goto out;
+	}
+	ret = dbus_g_proxy_call (control->priv->proxy, "SetProxy", &error,
+				 G_TYPE_STRING, proxy_http,
+				 G_TYPE_STRING, proxy_ftp,
+				 G_TYPE_INVALID,
+				 G_TYPE_INVALID);
+	if (!ret) {
+		/* abort as the DBUS method failed */
+		pk_warning ("SetProxy failed :%s", error->message);
+		g_error_free (error);
+	}
+out:
+	return ret;
+}
+
+/**
  * pk_control_get_groups:
  * @control: a valid #PkControl instance
  *
diff --git a/libpackagekit/pk-control.h b/libpackagekit/pk-control.h
index 63b30d3..c1b1be8 100644
--- a/libpackagekit/pk-control.h
+++ b/libpackagekit/pk-control.h
@@ -88,6 +88,9 @@ PkControl	*pk_control_new				(void);
 gboolean	 pk_control_allocate_transaction_id	(PkControl	*control,
 							 gchar		**tid,
 							 GError		**error);
+gboolean	 pk_control_set_proxy			(PkControl	*control,
+							 const gchar	*proxy_http,
+							 const gchar	*proxy_ftp);
 PkRoleEnum	 pk_control_get_actions			(PkControl	*control);
 PkFilterEnum	 pk_control_get_filters			(PkControl	*control);
 PkGroupEnum	 pk_control_get_groups			(PkControl	*control);
commit d1e096c3267c1c9492041382b954e9327bc8bbec
Author: Thomas Wood <thomas at openedhand.com>
Date:   Fri May 16 15:29:46 2008 +0100

    opkg: support multiple packages in install and remove

diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 2deccee..7649bab 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -373,44 +373,52 @@ static gboolean
 backend_install_packages_thread (PkBackend *backend)
 {
 	PkPackageId *pi;
-	gint err;
-	const gchar *package_id;
+	gint err, i;
+	gchar **package_ids;
 
-	package_id = pk_backend_get_string (backend, "pkid");
-	pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, package_id, NULL);
+	package_ids = pk_backend_get_strv (backend, "pkids");
 
-	pi = pk_package_id_new_from_string (package_id);
+	err = 0;
 
-	err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend);
-	switch (err)
+	for (i = 0; package_ids[i]; i++)
 	{
-	case OPKG_NO_ERROR:
-		break;
-	case OPKG_DEPENDANCIES_FAILED:
-		pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL);
-		break;
-	case OPKG_PACKAGE_ALREADY_INSTALLED:
-		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL);
-		break;
-	case OPKG_PACKAGE_NOT_AVAILABLE:
-		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
-		break;
-	default:
-		opkg_unknown_error (backend, err, "Install");
+		pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, package_ids[0], NULL);
+
+		pi = pk_package_id_new_from_string (package_ids[0]);
+
+		err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend);
+		switch (err)
+		{
+		case OPKG_NO_ERROR:
+			break;
+		case OPKG_DEPENDANCIES_FAILED:
+			pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL);
+			break;
+		case OPKG_PACKAGE_ALREADY_INSTALLED:
+			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL);
+			break;
+		case OPKG_PACKAGE_NOT_AVAILABLE:
+			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
+			break;
+		default:
+			opkg_unknown_error (backend, err, "Install");
+		}
+		pk_package_id_free (pi);
+		if (err != 0)
+			break;
 	}
 
-	pk_package_id_free (pi);
 	pk_backend_finished (backend);
 	return (err == 0);
 }
 
 static void
-backend_install_packages (PkBackend *backend, gchar **package_id)
+backend_install_packages (PkBackend *backend, gchar **package_ids)
 {
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
 
-	pk_backend_set_string (backend, "pkid", package_id[0]);
+	pk_backend_set_strv (backend, "pkids", package_ids);
 
 	pk_backend_thread_create (backend, backend_install_packages_thread);
 }
@@ -419,7 +427,7 @@ static gboolean
 backend_remove_packages_thread (PkBackend *backend)
 {
 	PkPackageId *pi;
-	gint err;
+	gint err, i;
 	gchar **package_ids;
 	gboolean allow_deps;
 	gboolean autoremove;
@@ -432,26 +440,34 @@ backend_remove_packages_thread (PkBackend *backend)
 	autoremove = GPOINTER_TO_INT (data[2]);
 	g_free (data);
 
-	pi = pk_package_id_new_from_string (package_ids[0]);
-	pk_backend_package (backend, PK_INFO_ENUM_REMOVING, package_ids[0], NULL);
-
 	opkg_set_option (opkg, "autoremove", &autoremove);
 	opkg_set_option (opkg, "force_removal_of_dependent_packages", &allow_deps);
 
-	err = opkg_remove_package (opkg, pi->name, pk_opkg_progress_cb, backend);
+	err = 0;
 
-	switch (err)
+	for (i = 0; package_ids[i]; i++)
 	{
-	case OPKG_NO_ERROR:
-		break;
-	case OPKG_PACKAGE_NOT_INSTALLED:
-		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
-		break;
-	default:
-		opkg_unknown_error (backend, err, "Remove");
+		pi = pk_package_id_new_from_string (package_ids[0]);
+		pk_backend_package (backend, PK_INFO_ENUM_REMOVING, package_ids[0], NULL);
+
+		err = opkg_remove_package (opkg, pi->name, pk_opkg_progress_cb, backend);
+
+		switch (err)
+		{
+		case OPKG_NO_ERROR:
+			break;
+		case OPKG_PACKAGE_NOT_INSTALLED:
+			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
+			break;
+		default:
+			opkg_unknown_error (backend, err, "Remove");
+		}
+		pk_package_id_free (pi);
+
+		if (err != 0)
+			break;
 	}
 
-	pk_package_id_free (pi);
 	pk_backend_finished (backend);
 	return (err == 0);
 }
commit 1c313503be920d16dee3b0813430841ba8f76a01
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 14:33:53 2008 +0100

    add a system method SetProxy() for setting the proxy from the session securely

diff --git a/policy/org.freedesktop.packagekit.policy.in b/policy/org.freedesktop.packagekit.policy.in
index 32efce7..4c4607d 100644
--- a/policy/org.freedesktop.packagekit.policy.in
+++ b/policy/org.freedesktop.packagekit.policy.in
@@ -133,5 +133,17 @@
       <allow_active>yes</allow_active>
     </defaults>
   </action>
+
+  <action id="org.freedesktop.packagekit.set-proxy">
+    <_description>Set network proxy</_description>
+    <_message>Authentication is required to set the network proxy used for downloading packages</_message>
+    <icon_name>applications-internet</icon_name>
+    <vendor_url>http://www.packagekit.org/pk-reference.html#methods-set-proxy</vendor_url>
+    <defaults>
+      <allow_inactive>no</allow_inactive>
+      <allow_active>yes</allow_active>
+    </defaults>
+  </action>
+
 </policyconfig>
 
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 028a0d0..14ecf41 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -154,6 +154,8 @@ pk_engine_error_get_type (void)
 		static const GEnumValue values[] =
 		{
 			ENUM_ENTRY (PK_ENGINE_ERROR_INVALID_STATE, "InvalidState"),
+			ENUM_ENTRY (PK_ENGINE_ERROR_REFUSED_BY_POLICY, "RefusedByPolicy"),
+			ENUM_ENTRY (PK_ENGINE_ERROR_CANNOT_SET_PROXY, "CannotSetProxy"),
 			{ 0, NULL, NULL }
 		};
 		etype = g_enum_register_static ("PkEngineError", values);
@@ -502,6 +504,47 @@ pk_engine_suggest_daemon_quit (PkEngine *engine, GError **error)
 }
 
 /**
+ * pk_engine_set_proxy:
+ **/
+void
+pk_engine_set_proxy (PkEngine *engine, const gchar *proxy_http, const gchar *proxy_ftp, DBusGMethodInvocation *context)
+{
+	gboolean ret;
+	GError *error;
+	gchar *sender = NULL;
+	gchar *error_detail = NULL;
+
+	g_return_if_fail (PK_IS_ENGINE (engine));
+
+	pk_debug ("SetProxy method called: %s, %s", proxy_http, proxy_ftp);
+
+	/* check if the action is allowed from this client - if not, set an error */
+	sender = dbus_g_method_get_sender (context);
+
+	/* use security model to get auth */
+	ret = pk_security_action_is_allowed (engine->priv->security, sender, FALSE, PK__ROLE_ENUM_SET_PROXY, &error_detail);
+	if (!ret) {
+		error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_REFUSED_BY_POLICY, "%s", error_detail);
+		dbus_g_method_return_error (context, error);
+		goto out;
+	}
+
+	/* try to set the new proxy */
+	ret = pk_backend_set_proxy (engine->priv->backend, proxy_http, proxy_ftp);
+	if (!ret) {
+		error = g_error_new (PK_ENGINE_ERROR, PK_ENGINE_ERROR_CANNOT_SET_PROXY, "%s", "setting the proxy failed");
+		dbus_g_method_return_error (context, error);
+		goto out;
+	}
+
+	/* all okay */
+	dbus_g_method_return (context);
+out:
+	g_free (sender);
+	g_free (error_detail);
+}
+
+/**
  * pk_engine_class_init:
  * @klass: The PkEngineClass
  **/
diff --git a/src/pk-engine.h b/src/pk-engine.h
index c59b1f3..668451f 100644
--- a/src/pk-engine.h
+++ b/src/pk-engine.h
@@ -57,9 +57,12 @@ typedef enum
 {
 	PK_ENGINE_ERROR_DENIED,
 	PK_ENGINE_ERROR_INVALID_STATE,
+	PK_ENGINE_ERROR_REFUSED_BY_POLICY,
+	PK_ENGINE_ERROR_CANNOT_SET_PROXY,
 	PK_ENGINE_ERROR_LAST
 } PkEngineError;
 
+
 GQuark		 pk_engine_error_quark			(void);
 GType		 pk_engine_error_get_type		(void) G_GNUC_CONST;
 GType		 pk_engine_get_type		  	(void) G_GNUC_CONST;
@@ -100,6 +103,10 @@ gboolean	 pk_engine_state_has_changed		(PkEngine	*engine,
 							 GError		**error);
 gboolean	 pk_engine_suggest_daemon_quit		(PkEngine	*engine,
 							 GError		**error);
+void		 pk_engine_set_proxy			(PkEngine	*engine,
+							 const gchar	*proxy_http,
+							 const gchar	*proxy_ftp,
+							 DBusGMethodInvocation *context);
 
 G_END_DECLS
 
diff --git a/src/pk-interface.xml b/src/pk-interface.xml
index e9e74e1..7290bbe 100644
--- a/src/pk-interface.xml
+++ b/src/pk-interface.xml
@@ -33,6 +33,11 @@
     <method name="GetNetworkState">
       <arg type="s" name="state" direction="out"/>
     </method>
+    <method name="SetProxy">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <arg type="s" name="proxy_http" direction="in"/>
+      <arg type="s" name="proxy_ftp" direction="in"/>
+    </method>
 
     <signal name="TransactionListChanged">
       <arg type="as" name="transactions" direction="out"/>
diff --git a/src/pk-security-polkit.c b/src/pk-security-polkit.c
index 9abf992..81332d0 100644
--- a/src/pk-security-polkit.c
+++ b/src/pk-security-polkit.c
@@ -128,6 +128,9 @@ pk_security_role_to_action (PkSecurity *security, gboolean trusted, PkRoleEnum r
 		policy = "org.freedesktop.packagekit.repo-change";
 	} else if (role == PK_ROLE_ENUM_REFRESH_CACHE) {
 		policy = "org.freedesktop.packagekit.refresh-cache";
+	/* PRIVATE: not actually roles */
+	} else if (role == PK__ROLE_ENUM_SET_PROXY) {
+		policy = "org.freedesktop.packagekit.refresh-cache";
 	}
 	return policy;
 }
diff --git a/src/pk-security.h b/src/pk-security.h
index 3432095..eb55932 100644
--- a/src/pk-security.h
+++ b/src/pk-security.h
@@ -34,6 +34,9 @@ G_BEGIN_DECLS
 #define PK_IS_SECURITY_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_SECURITY))
 #define PK_SECURITY_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_SECURITY, PkSecurityClass))
 
+/* FIXME: not actually a role */
+#define PK__ROLE_ENUM_SET_PROXY		1 << 31
+
 typedef struct PkSecurityPrivate PkSecurityPrivate;
 
 typedef struct
commit d9b8274b163941288c020a8ab70803ab9beb5d51
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 14:32:29 2008 +0100

    support RefusedByPolicy on the base interface too

diff --git a/libpackagekit/pk-polkit-client.c b/libpackagekit/pk-polkit-client.c
index dceb656..7308a29 100644
--- a/libpackagekit/pk-polkit-client.c
+++ b/libpackagekit/pk-polkit-client.c
@@ -54,9 +54,6 @@ static void     pk_polkit_client_finalize		(GObject           *object);
 #define POLKIT_DBUS_PATH		"/org/gnome/PolicyKit/Manager"
 #define POLKIT_DBUS_INTERFACE		"org.gnome.PolicyKit.Manager"
 
-/* we only support auth on the the transaction interface */
-#define	PK_ERROR_REFUSED_BY_POLICY	"org.freedesktop.PackageKit.Transaction.RefusedByPolicy"
-
 /**
  * PkPolkitClientPrivate:
  *
@@ -175,7 +172,10 @@ pk_polkit_client_error_denied_by_policy (GError *error)
 	/* check for specific error */
 	error_name = dbus_g_error_get_name (error);
 	pk_debug ("ERROR: %s: %s", error_name, error->message);
-	if (pk_strequal (error_name, PK_ERROR_REFUSED_BY_POLICY)) {
+	if (pk_strequal (error_name, "org.freedesktop.PackageKit.RefusedByPolicy")) {
+		return TRUE;
+	}
+	if (pk_strequal (error_name, "org.freedesktop.PackageKit.Transaction.RefusedByPolicy")) {
 		return TRUE;
 	}
 	return FALSE;
commit 4d6ed0eb4f02f8429aafad76b8690eed51c15ee2
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 13:19:09 2008 +0100

    actually check for NM before we try to use it in the networking code

diff --git a/src/pk-network.c b/src/pk-network.c
index 9656958..0ad839e 100644
--- a/src/pk-network.c
+++ b/src/pk-network.c
@@ -39,6 +39,7 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
+#include <libgbus.h>
 
 #include <glib/gi18n.h>
 
@@ -67,6 +68,7 @@ struct _PkNetworkPrivate
 	PkNetworkNm		*net_nm;
 	PkNetworkUnix		*net_unix;
 	PkConf			*conf;
+	LibGBus			*nm_bus;
 };
 
 enum {
@@ -154,6 +156,7 @@ pk_network_class_init (PkNetworkClass *klass)
 static void
 pk_network_init (PkNetwork *network)
 {
+	gboolean nm_alive;
 	network->priv = PK_NETWORK_GET_PRIVATE (network);
 	network->priv->conf = pk_conf_new ();
 	network->priv->net_nm = pk_network_nm_new ();
@@ -167,6 +170,17 @@ pk_network_init (PkNetwork *network)
 	network->priv->use_nm = pk_conf_get_bool (network->priv->conf, "UseNetworkManager");
 	network->priv->use_unix = pk_conf_get_bool (network->priv->conf, "UseNetworkHeuristic");
 
+	/* check if NM is on the bus */
+	network->priv->nm_bus = libgbus_new ();
+	libgbus_assign (network->priv->nm_bus, LIBGBUS_SYSTEM, "org.freedesktop.NetworkManager");
+	nm_alive = libgbus_is_connected (network->priv->nm_bus);
+
+	/* NetworkManager isn't up, so we can't use it */
+	if (network->priv->use_nm && !nm_alive) {
+		pk_warning ("UseNetworkManager true, but org.freedesktop.NetworkManager not up");
+		network->priv->use_nm = FALSE;
+	}
+
 #if !PK_BUILD_NETWORKMANAGER
 	/* check we can actually use the default */
 	if (network->priv->use_nm) {
@@ -190,6 +204,7 @@ pk_network_finalize (GObject *object)
 
 	g_return_if_fail (network->priv != NULL);
 	g_object_unref (network->priv->conf);
+	g_object_unref (network->priv->nm_bus);
 	g_object_unref (network->priv->net_nm);
 	g_object_unref (network->priv->net_unix);
 	G_OBJECT_CLASS (pk_network_parent_class)->finalize (object);
commit fd8edf9ef816564eb98e22b7854d71ba55424287
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 12:37:33 2008 +0100

    yum: backport the skip broken stuff from yum2 to improve the interaction a little

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 9aebf79..5b2da8f 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -801,6 +801,8 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         old_throttle = self.yumbase.conf.throttle
         self.yumbase.conf.throttle = "60%" # Set bandwidth throttle to 60%
                                            # to avoid taking all the system's bandwidth.
+        old_skip_broken = self.yumbase.conf.skip_broken
+        self.yumbase.conf.skip_broken = 1
 
         try:
             txmbr = self.yumbase.update() # Add all updates to Transaction
@@ -812,6 +814,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             self.error(ERROR_NO_PACKAGES_TO_UPDATE,"Nothing to do")
 
         self.yumbase.conf.throttle = old_throttle
+        self.yumbase.conf.skip_broken = old_skip_broken
 
     def refresh_cache(self):
         '''
commit 3cc0e9d8f4de82deb0cc0b5be6d3debfa313cea1
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri May 16 12:37:04 2008 +0100

    allow proxy_http and proxy_ftp to be NULL in the DBUS backend

diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index 7bf45c6..4c6837a 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -351,8 +351,6 @@ pk_backend_dbus_set_proxy (PkBackendDbus *backend_dbus, const gchar *proxy_http,
 
 	g_return_val_if_fail (PK_IS_BACKEND_DBUS (backend_dbus), FALSE);
 	g_return_val_if_fail (backend_dbus->priv->proxy != NULL, FALSE);
-	g_return_val_if_fail (proxy_http != NULL, FALSE);
-	g_return_val_if_fail (proxy_ftp != NULL, FALSE);
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
commit d56b003bc7221030a438599c88421582b2697a31
Author: S.Çağlar Onur <caglar at pardus.org.tr>
Date:   Fri May 16 02:44:17 2008 +0300

    Remove "nonzero MTU" check and skip "loopback" interface checking from pk_network_unix_get_network_state else PK always return PK_NETWORK_ENUM_OFFLINE for following routing table
    
    caglar at zangetsu ~ $ cat /proc/net/route
    Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT
    eth1    0000000A        00000000        0001    0       0       0       00FFFFFF        0       0       0
    lo      0000007F        0100007F        0003    0       0       0       000000FF        0       0       0
    eth1    00000000        0200000A        0003    0       0       0       00000000        0       0       0

diff --git a/src/pk-network-unix.c b/src/pk-network-unix.c
index 11c23a2..74b266c 100644
--- a/src/pk-network-unix.c
+++ b/src/pk-network-unix.c
@@ -138,6 +138,11 @@ pk_network_unix_get_network_state (PkNetworkUnix *network_unix)
 			continue;
 		}
 
+		/* is loopback? */
+		if (pk_strequal (sections[0], "lo")) {
+			continue;
+		}
+
 		/* is correct parameters? */
 		number_sections = g_strv_length (sections);
 		if (number_sections != 11) {
@@ -145,9 +150,8 @@ pk_network_unix_get_network_state (PkNetworkUnix *network_unix)
 			continue;
 		}
 
-		/* is MTU and gateway nonzero? */
-		if (!pk_strequal (sections[8], "0") &&
-		    !pk_strequal (sections[2], "00000000")) {
+		/* is gateway nonzero? */
+		if (!pk_strequal (sections[2], "00000000")) {
 			pk_debug ("interface %s is valid", sections[0]);
 			online = TRUE;
 		}
commit 8177fd102ea0e1443dde4da24745771589672a68
Author: S.Çağlar Onur <caglar at pardus.org.tr>
Date:   Fri May 16 01:47:15 2008 +0300

    Fix following compile warning;
    
    [...]
    pk-console.c:721: warning: 'package_ids' might be used uninitialized in this function
    pk-console.c:565: warning: 'package_id' might be used uninitialized in this function
    [...]

diff --git a/client/pk-console.c b/client/pk-console.c
index 2056264..5a05a8e 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -562,7 +562,7 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 {
 	gboolean ret = TRUE;
 	gboolean is_local;
-	gchar *package_id;
+	gchar *package_id = NULL;
 	gchar **package_ids = NULL;
 	gchar **files = NULL;
 	guint i;
@@ -718,7 +718,7 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 	guint length;
 	gboolean remove;
 	GPtrArray *array;
-	gchar **package_ids;
+	gchar **package_ids = NULL;
 	PkPackageList *list;
 
 	array = g_ptr_array_new ();
commit 4241a2e108566073204e5283b01ce0bb13cb5d9e
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 16:24:21 2008 +0100

    add the source filter

diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index f32238f..6935e66 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -5,7 +5,7 @@ NULL =
 
 TEST_FILES =						\
 	pk-spawn-test.sh				\
-	pk-spawn-test-proxy.sh				\
+	pk-spawn-proxy.sh				\
 	pk-spawn-test-sigquit.sh			\
 	pk-spawn-test-profiling.sh			\
 	$(NULL)
diff --git a/docs/html/pk-help.html b/docs/html/pk-help.html
index eeefa94..5bc7827 100644
--- a/docs/html/pk-help.html
+++ b/docs/html/pk-help.html
@@ -75,7 +75,6 @@ as for instructions!
 <li>Network proxy server support <i>(70%)</i></li>
 <li>Multiple package install and remove from pkcon <i>(80%)</i></li>
 <li>NetworkManager integration so we can detect GPRS (and modem) connections. <i>(10%)</i></li>
-<li>Filter for source packages. <i>(0%)</i></li>
 </ul>
 <p>
 <b>0.2.3</b> - To be released July 2008
diff --git a/docs/spec/pk-concepts.xml b/docs/spec/pk-concepts.xml
index 312c5a4..0b75b10 100644
--- a/docs/spec/pk-concepts.xml
+++ b/docs/spec/pk-concepts.xml
@@ -127,6 +127,13 @@
               This allows the used to choose non-native packages if a multi-lib policy is allowed.
             </entry>
           </row>
+          <row>
+            <entry><literal>source</literal> or <literal>~source</literal></entry>
+            <entry>
+              The source filter will only return source packages.
+              These are typically useful when rebuilding other packages.
+            </entry>
+          </row>
         </tbody>
       </tgroup>
     </informaltable>
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index b5b6ac3..5743dcb 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -193,6 +193,8 @@ static PkEnumMatch enum_filter[] = {
 	{PK_FILTER_ENUM_NOT_NEWEST,		"~newest"},
 	{PK_FILTER_ENUM_ARCH,			"arch"},
 	{PK_FILTER_ENUM_NOT_ARCH,		"~arch"},
+	{PK_FILTER_ENUM_SOURCE,			"source"},
+	{PK_FILTER_ENUM_NOT_SOURCE,		"~source"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 33e8a91..e616b64 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -182,7 +182,9 @@ typedef enum {
 	PK_FILTER_ENUM_NOT_NEWEST		= 1 << 15,
 	PK_FILTER_ENUM_ARCH			= 1 << 16,
 	PK_FILTER_ENUM_NOT_ARCH			= 1 << 17,
-	PK_FILTER_ENUM_UNKNOWN			= 1 << 18
+	PK_FILTER_ENUM_SOURCE			= 1 << 18,
+	PK_FILTER_ENUM_NOT_SOURCE		= 1 << 19,
+	PK_FILTER_ENUM_UNKNOWN			= 1 << 20
 } PkFilterEnum;
 
 /**
commit 035c60412da2a12ab78a7f164c579f94b0696c39
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 15:36:21 2008 +0100

    trivial: update help page

diff --git a/docs/html/pk-help.html b/docs/html/pk-help.html
index fa9d9cc..eeefa94 100644
--- a/docs/html/pk-help.html
+++ b/docs/html/pk-help.html
@@ -72,7 +72,8 @@ as for instructions!
 <b>0.2.2</b> - To be released June 2008
 </p>
 <ul>
-<li>Multiple package install and remove from pkcon <i>(0%)</i></li>
+<li>Network proxy server support <i>(70%)</i></li>
+<li>Multiple package install and remove from pkcon <i>(80%)</i></li>
 <li>NetworkManager integration so we can detect GPRS (and modem) connections. <i>(10%)</i></li>
 <li>Filter for source packages. <i>(0%)</i></li>
 </ul>
@@ -84,6 +85,12 @@ as for instructions!
 <li>Multiple package installs from gpk-application <i>(0%)</i></li>
 <li>Ignoring packages from the update viewer per-session <i>(10%)</i></li>
 </ul>
+<p>
+<b>0.3.0</b> - To be released December 2008
+</p>
+<ul>
+<li>More composite types <code>s</code> to <code>as</code> <i>(0%)</i></li>
+</ul>
 
 <p>Back to the <a href="index.html">main page</a></p>
 
commit 08eec7f60d97eaea0ce7630fc0ac4b8002599573
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 13:57:58 2008 +0100

    allow adding and removing multiple packages at one time with pkcon

diff --git a/client/pk-console.c b/client/pk-console.c
index f296ab8..2056264 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -50,7 +50,7 @@ static gboolean awaiting_space = FALSE;
 static gboolean trusted = TRUE;
 static guint timer_id = 0;
 static guint percentage_last = 0;
-static gchar *filename = NULL;
+static gchar **files_cache = NULL;
 static PkControl *control = NULL;
 static PkClient *client = NULL;
 static PkClient *client_task = NULL;
@@ -555,20 +555,93 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 }
 
 /**
- * pk_console_install_package:
+ * pk_console_install_stuff:
  **/
 static gboolean
-pk_console_install_package (PkClient *client, const gchar *package, GError **error)
+pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 {
-	gboolean ret;
+	gboolean ret = TRUE;
+	gboolean is_local;
 	gchar *package_id;
-	package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_NOT_INSTALLED, package, error);
-	if (package_id == NULL) {
-		g_print ("%s\n", _("Could not find a package with that name to install, or package already installed"));
-		return FALSE;
+	gchar **package_ids = NULL;
+	gchar **files = NULL;
+	guint i;
+	guint length;
+	GPtrArray *array_packages;
+	GPtrArray *array_files;
+
+	array_packages = g_ptr_array_new ();
+	array_files = g_ptr_array_new ();
+	length = g_strv_length (packages);
+	for (i=2; i<length; i++) {
+		is_local = g_file_test (packages[i], G_FILE_TEST_EXISTS);
+		if (is_local) {
+			g_ptr_array_add (array_files, g_strdup (packages[i]));
+		} else {
+			package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_NOT_INSTALLED, packages[i], error);
+			if (package_id == NULL) {
+				g_print ("%s\n", _("Could not find a package with that name to install, or package already installed"));
+				ret = FALSE;
+				break;
+			}
+			g_ptr_array_add (array_packages, package_id);
+		}
 	}
-	ret = pk_client_install_package (client, package_id, error);
-	g_free (package_id);
+
+	/* one of the resolves failed */
+	if (!ret) {
+		pk_warning ("resolve failed");
+		goto out;
+	}
+
+
+	/* any to process? */
+	if (array_packages->len > 0) {
+		/* convert to strv */
+		package_ids = pk_ptr_array_to_argv (array_packages);
+
+		/* reset */
+		ret = pk_client_reset (client, error);
+		if (!ret) {
+			pk_warning ("failed to reset");
+			goto out;
+		}
+
+		ret = pk_client_install_package (client, package_id, error);
+		if (!ret) {
+			pk_warning ("failed to install packages");
+			goto out;
+		}
+	}
+
+	/* any to process? */
+	if (array_files->len > 0) {
+		/* convert to strv */
+		files = pk_ptr_array_to_argv (array_files);
+
+		/* save for untrusted callback */
+		g_strfreev (files_cache);
+		files_cache = g_strdupv (files);
+
+		/* reset */
+		ret = pk_client_reset (client, error);
+		if (!ret) {
+			pk_warning ("failed to reset");
+			goto out;
+		}
+
+		ret = pk_client_install_files (client, trusted, files, error);
+		if (!ret) {
+			pk_warning ("failed to install files");
+			goto out;
+		}
+	}
+
+out:
+	g_strfreev (package_ids);
+	g_strfreev (files);
+	g_ptr_array_free (array_files, TRUE);
+	g_ptr_array_free (array_packages, TRUE);
 	return ret;
 }
 
@@ -576,16 +649,16 @@ pk_console_install_package (PkClient *client, const gchar *package, GError **err
  * pk_console_remove_only:
  **/
 static gboolean
-pk_console_remove_only (PkClient *client, const gchar *package_id, gboolean force, gboolean autoremove, GError **error)
+pk_console_remove_only (PkClient *client, gchar **package_ids, gboolean force, GError **error)
 {
 	gboolean ret;
 
-	pk_debug ("remove %s", package_id);
+	pk_debug ("remove+ %s", package_ids[0]);
 	ret = pk_client_reset (client, error);
 	if (!ret) {
 		return ret;
 	}
-	return pk_client_remove_package (client, package_id, force, autoremove, error);
+	return pk_client_remove_packages (client, package_ids, force, FALSE, error);
 }
 
 /**
@@ -631,64 +704,99 @@ pk_console_get_prompt (const gchar *question, gboolean defaultyes)
 }
 
 /**
- * pk_console_remove_package:
+ * pk_console_remove_packages:
  **/
 static gboolean
-pk_console_remove_package (PkClient *client, const gchar *package, GError **error)
+pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 {
 	gchar *package_id;
-	gboolean ret;
-	guint length;
+	gboolean ret = TRUE;
 	PkPackageItem *item;
 	PkPackageId *ident;
-	guint i;
+	guint i, j;
+	guint size;
+	guint length;
 	gboolean remove;
+	GPtrArray *array;
+	gchar **package_ids;
+	PkPackageList *list;
+
+	array = g_ptr_array_new ();
+	list = pk_package_list_new ();
+	length = g_strv_length (packages);
+	for (i=2; i<length; i++) {
+		package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_INSTALLED, packages[i], error);
+		if (package_id == NULL) {
+			g_print ("%s:%s\n", _("Could not find a package to remove"), packages[i]);
+			ret = FALSE;
+			break;
+		}
+		g_ptr_array_add (array, g_strdup (package_id));
+		pk_debug ("resolved to %s", package_id);
+		g_free (package_id);
+	}
 
-	package_id = pk_console_perhaps_resolve (client, PK_FILTER_ENUM_INSTALLED, package, error);
-	if (package_id == NULL) {
-		g_print ("%s\n", _("Could not find a package with that name to remove"));
-		return FALSE;
+	/* one of the resolves failed */
+	if (!ret) {
+		goto out;
 	}
 
+	/* convert to strv */
+	package_ids = pk_ptr_array_to_argv (array);
+
 	/* are we dumb and can't check for requires? */
 	if (!pk_enums_contain (roles, PK_ROLE_ENUM_GET_REQUIRES)) {
 		/* no, just try to remove it without deps */
-		ret = pk_console_remove_only (client, package_id, FALSE, FALSE, error);
-		g_free (package_id);
-		return ret;
+		ret = pk_console_remove_only (client, package_ids, FALSE, error);
+		goto out;
 	}
 
-	/* see if any packages require this one */
-	ret = pk_client_reset (client_task, error);
-	if (!ret) {
-		pk_warning ("failed to reset");
-		return FALSE;
+	/* get the requires packages for each package_id */
+	length = g_strv_length (package_ids);
+	for (i=0; i<length; i++) {
+		ret = pk_client_reset (client_task, error);
+		if (!ret) {
+			pk_warning ("failed to reset");
+			break;
+		}
+
+		pk_debug ("Getting installed requires for %s", package_ids[i]);
+		/* see if any packages require this one */
+		ret = pk_client_get_requires (client_task, PK_FILTER_ENUM_INSTALLED, package_ids[i], TRUE, error);
+		if (!ret) {
+			pk_warning ("failed to get requires");
+			break;
+		}
+
+		/* see how many packages there are */
+		size = pk_client_package_buffer_get_size (client_task);
+		for (j=0; j<size; j++) {
+			item = pk_client_package_buffer_get_item (client_task, j);
+			pk_package_list_add_item (list, item);
+		}
 	}
 
-	pk_debug ("Getting installed requires for %s", package_id);
-	ret = pk_client_get_requires (client_task, PK_FILTER_ENUM_INSTALLED, package_id, TRUE, error);
+	/* one of the get-requires failed */
 	if (!ret) {
-		return FALSE;
+		goto out;
 	}
 
-	/* see how many packages there are */
-	length = pk_client_package_buffer_get_size (client_task);
-
 	/* if there are no required packages, just do the remove */
+	length = pk_package_list_get_size (list);
 	if (length == 0) {
 		pk_debug ("no requires");
-		ret = pk_console_remove_only (client, package_id, FALSE, FALSE, error);
-		g_free (package_id);
-		return ret;
+		ret = pk_console_remove_only (client, package_ids, FALSE, error);
+		goto out;
 	}
 
+
 	/* present this to the user */
 	if (awaiting_space) {
 		g_print ("\n");
 	}
 	g_print ("%s:\n", _("The following packages have to be removed"));
 	for (i=0; i<length; i++) {
-		item = pk_client_package_buffer_get_item (client_task, i);
+		item = pk_package_list_get_item (list, i);
 		ident = pk_package_id_new_from_string (item->package_id);
 		g_print ("%i\t%s-%s\n", i, ident->name, ident->version);
 		pk_package_id_free (ident);
@@ -700,14 +808,17 @@ pk_console_remove_package (PkClient *client, const gchar *package, GError **erro
 	/* we chickened out */
 	if (remove == FALSE) {
 		g_print ("%s\n", _("Cancelled!"));
-		g_free (package_id);
-		return FALSE;
+		ret = FALSE;
+		goto out;
 	}
 
 	/* remove all the stuff */
-	ret = pk_console_remove_only (client, package_id, TRUE, FALSE, error);
-	g_free (package_id);
+	ret = pk_console_remove_only (client, package_ids, TRUE, error);
 
+out:
+	g_object_unref (list);
+	g_strfreev (package_ids);
+	g_ptr_array_free (array, TRUE);
 	return ret;
 }
 
@@ -846,7 +957,7 @@ pk_console_error_code_cb (PkClient *client, PkErrorCodeEnum error_code, const gc
 	    error_code == PK_ERROR_ENUM_MISSING_GPG_SIGNATURE && trusted) {
 		pk_debug ("need to try again with trusted FALSE");
 		trusted = FALSE;
-		ret = pk_client_install_file (client_install_files, trusted, filename, &error);
+		ret = pk_client_install_files (client_install_files, trusted, files_cache, &error);
 		/* we succeeded, so wait for the requeue */
 		if (!ret) {
 			pk_warning ("failed to install file second time: %s", error->message);
@@ -1159,7 +1270,6 @@ main (int argc, char *argv[])
 	const gchar *value = NULL;
 	const gchar *details = NULL;
 	const gchar *parameter = NULL;
-	PkRoleEnum roles;
 	PkGroupEnum groups;
 	gchar *text;
 	ret = FALSE;
@@ -1330,15 +1440,7 @@ main (int argc, char *argv[])
 			g_print (_("You need to specify a package or file to install"));
 			goto out;
 		}
-		/* is it a local file? */
-		ret = g_file_test (value, G_FILE_TEST_EXISTS);
-		if (ret) {
-			ret = pk_client_install_file (client, trusted, value, &error);
-			/* we need this for the untrusted try */
-			filename = g_strdup (value);
-		} else {
-			ret = pk_console_install_package (client, value, &error);
-		}
+		ret = pk_console_install_stuff (client, argv, &error);
 
 	} else if (strcmp (mode, "install-sig") == 0) {
 		if (value == NULL || details == NULL || parameter == NULL) {
@@ -1352,7 +1454,7 @@ main (int argc, char *argv[])
 			g_print (_("You need to specify a package to remove"));
 			goto out;
 		}
-		ret = pk_console_remove_package (client, value, &error);
+		ret = pk_console_remove_packages (client, argv, &error);
 
 	} else if (strcmp (mode, "accept-eula") == 0) {
 		if (value == NULL) {
@@ -1533,7 +1635,7 @@ out:
 	g_free (options_help);
 	g_free (filter);
 	g_free (summary);
-	g_free (filename);
+	g_strfreev (files_cache);
 	g_object_unref (control);
 	g_object_unref (client);
 	g_object_unref (client_task);
commit 9dfde1b81eed4e3bba0d1fe5c12ea73418d454d1
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 13:49:31 2008 +0100

    pkcon: make the get-actions, get-filters and get-groups output prettier

diff --git a/client/pk-console.c b/client/pk-console.c
index cd544bf..f296ab8 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -1471,9 +1471,9 @@ main (int argc, char *argv[])
 		ret = pk_client_get_packages (client, filters, &error);
 
 	} else if (strcmp (mode, "get-actions") == 0) {
-		roles = pk_control_get_actions (control);
 		text = pk_role_enums_to_text (roles);
-		g_print ("roles=%s\n", text);
+		g_strdelimit (text, ";", '\n');
+		g_print ("%s\n", text);
 		g_free (text);
 		maybe_sync = FALSE;
 		/* these can never fail */
@@ -1482,7 +1482,8 @@ main (int argc, char *argv[])
 	} else if (strcmp (mode, "get-filters") == 0) {
 		filters = pk_control_get_filters (control);
 		text = pk_filter_enums_to_text (filters);
-		g_print ("filters=%s\n", text);
+		g_strdelimit (text, ";", '\n');
+		g_print ("%s\n", text);
 		g_free (text);
 		maybe_sync = FALSE;
 		/* these can never fail */
@@ -1491,7 +1492,8 @@ main (int argc, char *argv[])
 	} else if (strcmp (mode, "get-groups") == 0) {
 		groups = pk_control_get_groups (control);
 		text = pk_group_enums_to_text (groups);
-		g_print ("groups=%s\n", text);
+		g_strdelimit (text, ";", '\n');
+		g_print ("%s\n", text);
 		g_free (text);
 		maybe_sync = FALSE;
 		/* these can never fail */
commit 80a634185e038681a8641d8c62f82bdac61ae8df
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 13:47:52 2008 +0100

    make sure we reset the resolve client before we try to reuse it

diff --git a/client/pk-console.c b/client/pk-console.c
index 8f69068..cd544bf 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -494,6 +494,12 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 		return g_strdup (package);
 	}
 
+	ret = pk_client_reset (client_task, error);
+	if (ret == FALSE) {
+		pk_warning ("failed to reset client task");
+		return NULL;
+	}
+
 	/* we need to resolve it */
 	ret = pk_client_resolve (client_task, filter, package, error);
 	if (ret == FALSE) {
commit 724c328d40acff42445531861e823516a219ac63
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 13:19:19 2008 +0100

    add support for http and ftp proxy servers in the daemon. This requires all backends DTRT:
    
    * For threaded backends you can do pk_backend_get_proxy_http() and pk_backend_get_proxy_ftp() if your backend supports either of these download methods.
    * For spawned backends you need to use the environment http_proxy and ftp_proxy variables.
    * for DBUS backends there is a method send called SetProxy() which can be used to setup proxy state. This is sent straight after Init() is called.
    
    The format of the proxy string is username:password at server:port -- it's not ideal but will cover 99% of the user base.

diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index d15dd6c..f32238f 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -5,6 +5,7 @@ NULL =
 
 TEST_FILES =						\
 	pk-spawn-test.sh				\
+	pk-spawn-test-proxy.sh				\
 	pk-spawn-test-sigquit.sh			\
 	pk-spawn-test-profiling.sh			\
 	$(NULL)
diff --git a/etc/PackageKit.conf.in b/etc/PackageKit.conf.in
index a6af99b..8f9bd57 100644
--- a/etc/PackageKit.conf.in
+++ b/etc/PackageKit.conf.in
@@ -31,3 +31,13 @@ ShutdownTimeout=300
 # default=@defaultbackend@
 DefaultBackend=@defaultbackend@
 
+# Proxy settings, uncomment as required
+#
+# NOTE: PackageKit does not use these settings, they are passed to backends.
+# Backends may ignore these values, or they may be updated from the session.
+#
+# They are in the format username:password at server:port
+#
+# ProxyHTTP=username:password at server.lan:8080
+# ProxyFTP=username:password at server.lan:21
+
diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py
index 3711f01..5253b39 100644
--- a/python/packagekit/daemonBackend.py
+++ b/python/packagekit/daemonBackend.py
@@ -789,6 +789,21 @@ class PackageKitBaseBackend(dbus.service.Object):
         self.Finished(EXIT_FAILED)
 
     @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
+                         in_signature='ss', out_signature='')
+    def SetProxy(self, proxy_http, proxy_ftp):
+        '''
+        Set the proxy
+        '''
+        pklog.info("SetProxy(%s, %s)" % (proxy_http, proxy_ftp))
+        self.doSetProxy(proxy_http, proxy_ftp)
+
+    def doSetProxy(self, proxy_http, proxy_ftp):
+        '''
+        Should be replaced in the corresponding backend sub class
+        '''
+        # do not use Finished() in this method
+
+    @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
                          in_signature='s', out_signature='')
     def InstallPublicKey(self, keyurl):
         '''
diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index 0a7d992..7bf45c6 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -341,6 +341,33 @@ pk_backend_dbus_remove_callbacks (PkBackendDbus *backend_dbus)
 }
 
 /**
+ * pk_backend_dbus_set_proxy:
+ **/
+static gboolean
+pk_backend_dbus_set_proxy (PkBackendDbus *backend_dbus, const gchar *proxy_http, const gchar *proxy_ftp)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	g_return_val_if_fail (PK_IS_BACKEND_DBUS (backend_dbus), FALSE);
+	g_return_val_if_fail (backend_dbus->priv->proxy != NULL, FALSE);
+	g_return_val_if_fail (proxy_http != NULL, FALSE);
+	g_return_val_if_fail (proxy_ftp != NULL, FALSE);
+
+	/* new sync method call */
+	pk_backend_dbus_time_reset (backend_dbus);
+	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "SetProxy", &error,
+				 G_TYPE_STRING, proxy_http,
+				 G_TYPE_STRING, proxy_ftp,
+				 G_TYPE_INVALID, G_TYPE_INVALID);
+	if (error != NULL) {
+		pk_warning ("%s", error->message);
+		g_error_free (error);
+	}
+	return ret;
+}
+
+/**
  * pk_backend_dbus_set_name:
  **/
 gboolean
@@ -450,6 +477,18 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service)
 		pk_backend_finished (backend_dbus->priv->backend);
 		g_error_free (error);
 	}
+
+	/* set the proxy */
+	if (ret) {
+		gchar *proxy_http;
+		gchar *proxy_ftp;
+		proxy_http = pk_backend_get_proxy_http (backend_dbus->priv->backend);
+		proxy_ftp = pk_backend_get_proxy_http (backend_dbus->priv->backend);
+		pk_backend_dbus_set_proxy (backend_dbus, proxy_http, proxy_ftp);
+		g_free (proxy_http);
+		g_free (proxy_ftp);
+	}
+
 	if (ret) {
 		pk_backend_dbus_time_check (backend_dbus);
 	}
diff --git a/src/pk-backend-internal.h b/src/pk-backend-internal.h
index 2213fed..2bffaff 100644
--- a/src/pk-backend-internal.h
+++ b/src/pk-backend-internal.h
@@ -59,6 +59,9 @@ gboolean	 pk_backend_reset			(PkBackend	*backend);
 gboolean	 pk_backend_set_name			(PkBackend	*backend,
 							 const gchar	*name)
 							 G_GNUC_WARN_UNUSED_RESULT;
+gboolean	 pk_backend_set_proxy			(PkBackend	*backend,
+							 const gchar	*proxy_http,
+							 const gchar	*proxy_ftp);
 gchar		*pk_backend_get_name			(PkBackend	*backend)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_backend_get_backend_detail		(PkBackend	*backend,
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 1d76109..f9c9f12 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -440,6 +440,44 @@ pk_backend_spawn_helper_new (PkBackendSpawn *backend_spawn)
 }
 
 /**
+ * pk_backend_spawn_get_envp:
+ *
+ * Return all the environment variables the script will need
+ **/
+static gchar **
+pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
+{
+	gchar **envp;
+	gchar *value;
+	gchar *line;
+	GPtrArray *array;
+
+	array = g_ptr_array_new ();
+
+	/* http_proxy */
+	value = pk_backend_get_proxy_http (backend_spawn->priv->backend);
+	if (!pk_strzero (value)) {
+		line = g_strdup_printf ("%s=%s", "http_proxy", value);
+		pk_debug ("setting evp '%s'", line);
+		g_ptr_array_add (array, line);
+	}
+	g_free (value);
+
+	/* ftp_proxy */
+	value = pk_backend_get_proxy_ftp (backend_spawn->priv->backend);
+	if (!pk_strzero (value)) {
+		line = g_strdup_printf ("%s=%s", "ftp_proxy", value);
+		pk_debug ("setting evp '%s'", line);
+		g_ptr_array_add (array, line);
+	}
+	g_free (value);
+
+	envp = pk_ptr_array_to_argv (array);
+	g_ptr_array_free (array, TRUE);
+	return envp;
+}
+
+/**
  * pk_backend_spawn_helper_va_list:
  **/
 static gboolean
@@ -448,6 +486,7 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 	gboolean ret;
 	gchar *filename;
 	gchar **argv;
+	gchar **envp;
 
 	g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE);
 
@@ -476,7 +515,8 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 	argv[0] = g_strdup (filename);
 
 	pk_backend_spawn_helper_new (backend_spawn);
-	ret = pk_spawn_argv (backend_spawn->priv->spawn, argv, NULL);
+	envp = pk_backend_spawn_get_envp (backend_spawn);
+	ret = pk_spawn_argv (backend_spawn->priv->spawn, argv, envp);
 	if (!ret) {
 		pk_backend_spawn_helper_delete (backend_spawn);
 		pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR,
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 3a30c4f..37ed024 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -78,6 +78,8 @@ struct _PkBackendPrivate
 	GHashTable		*eulas;
 	gchar			*name;
 	gchar			*c_tid;
+	gchar			*proxy_http;
+	gchar			*proxy_ftp;
 	gboolean		 locked;
 	gboolean		 set_error;
 	gboolean		 set_signature;
@@ -587,6 +589,44 @@ out:
 }
 
 /**
+ * pk_backend_set_proxy:
+ **/
+gboolean
+pk_backend_set_proxy (PkBackend	*backend, const gchar *proxy_http, const gchar *proxy_ftp)
+{
+	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
+	g_free (backend->priv->proxy_http);
+	g_free (backend->priv->proxy_ftp);
+	backend->priv->proxy_http = g_strdup (proxy_http);
+	backend->priv->proxy_ftp = g_strdup (proxy_ftp);
+	return TRUE;
+}
+
+/**
+ * pk_backend_get_proxy_http:
+ *
+ * Return value: proxy string in the form username:password at server:port
+ **/
+gchar *
+pk_backend_get_proxy_http (PkBackend *backend)
+{
+	g_return_val_if_fail (PK_IS_BACKEND (backend), NULL);
+	return g_strdup (backend->priv->proxy_http);
+}
+
+/**
+ * pk_backend_get_proxy_ftp:
+ *
+ * Return value: proxy string in the form username:password at server:port
+ **/
+gchar *
+pk_backend_get_proxy_ftp (PkBackend *backend)
+{
+	g_return_val_if_fail (PK_IS_BACKEND (backend), NULL);
+	return g_strdup (backend->priv->proxy_ftp);
+}
+
+/**
  * pk_backend_lock:
  *
  * Responsible for initialising the external backend object.
@@ -1670,6 +1710,8 @@ pk_backend_finalize (GObject *object)
 	pk_debug ("backend finalise");
 
 	pk_backend_reset (backend);
+	g_free (backend->priv->proxy_http);
+	g_free (backend->priv->proxy_ftp);
 	g_free (backend->priv->name);
 	g_free (backend->priv->c_tid);
 	g_object_unref (backend->priv->time);
@@ -1838,6 +1880,8 @@ pk_backend_init (PkBackend *backend)
 	backend->priv->handle = NULL;
 	backend->priv->name = NULL;
 	backend->priv->c_tid = NULL;
+	backend->priv->proxy_http = NULL;
+	backend->priv->proxy_ftp = NULL;
 	backend->priv->file_changed_func = NULL;
 	backend->priv->file_changed_data = NULL;
 	backend->priv->last_package = NULL;
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 3251a33..fb17e3c 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -72,6 +72,8 @@ gboolean	 pk_backend_get_progress		(PkBackend	*backend,
 							 guint		*elapsed,
 							 guint		*remaining);
 guint		 pk_backend_get_runtime			(PkBackend	*backend);
+gchar		*pk_backend_get_proxy_ftp		(PkBackend	*backend);
+gchar		*pk_backend_get_proxy_http		(PkBackend	*backend);
 
 /* signal helpers */
 gboolean	 pk_backend_finished			(PkBackend	*backend);
diff --git a/src/pk-engine.c b/src/pk-engine.c
index db81d36..028a0d0 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -101,6 +101,7 @@ struct PkEnginePrivate
 	PkNetwork		*network;
 	PkSecurity		*security;
 	PkNotify		*notify;
+	PkConf			*conf;
 	PkFileMonitor		*file_monitor;
 	PkRoleEnum		 actions;
 	PkGroupEnum		 groups;
@@ -579,10 +580,15 @@ pk_engine_init (PkEngine *engine)
 	DBusGConnection *connection;
 	gboolean ret;
 	gchar *filename;
+	gchar *proxy_http;
+	gchar *proxy_ftp;
 
 	engine->priv = PK_ENGINE_GET_PRIVATE (engine);
 	engine->priv->restart_schedule = FALSE;
 
+	/* use the config file */
+	engine->priv->conf = pk_conf_new ();
+
 	/* setup the backend backend */
 	engine->priv->backend = pk_backend_new ();
 	g_signal_connect (engine->priv->backend, "finished",
@@ -639,6 +645,13 @@ pk_engine_init (PkEngine *engine)
 			  G_CALLBACK (pk_engine_file_monitor_changed_cb), engine);
 	g_free (filename);
 
+	/* set the proxy */
+	proxy_http = pk_conf_get_string (engine->priv->conf, "ProxyHTTP");
+	proxy_ftp = pk_conf_get_string (engine->priv->conf, "ProxyFTP");
+	pk_backend_set_proxy (engine->priv->backend, proxy_http, proxy_ftp);
+	g_free (proxy_http);
+	g_free (proxy_ftp);
+
 	engine->priv->transaction_list = pk_transaction_list_new ();
 	g_signal_connect (engine->priv->transaction_list, "changed",
 			  G_CALLBACK (pk_engine_transaction_list_changed_cb), engine);
@@ -696,6 +709,7 @@ pk_engine_finalize (GObject *object)
 	g_object_unref (engine->priv->notify);
 	g_object_unref (engine->priv->backend);
 	g_object_unref (engine->priv->cache);
+	g_object_unref (engine->priv->conf);
 
 	G_OBJECT_CLASS (pk_engine_parent_class)->finalize (object);
 }
commit 12f8fc32ee8c1fefb8cdb89b1d06d4390e7ce1cf
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 12:45:02 2008 +0100

    allow passing environment parameters to pk_spawn_argv

diff --git a/data/tests/pk-spawn-proxy.sh b/data/tests/pk-spawn-proxy.sh
new file mode 100755
index 0000000..57774f1
--- /dev/null
+++ b/data/tests/pk-spawn-proxy.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+# Licensed under the GNU General Public License Version 2
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+if [ -z "${http_proxy}" ]; then
+	echo "no http proxy"
+	exit 1
+fi
+
+if [ -z "${ftp_proxy}" ]; then
+	echo "no ftp proxy"
+	exit 1
+fi
+
+echo -e "percentage\t100"
+
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 9c04e25..1d76109 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -476,7 +476,7 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 	argv[0] = g_strdup (filename);
 
 	pk_backend_spawn_helper_new (backend_spawn);
-	ret = pk_spawn_argv (backend_spawn->priv->spawn, argv);
+	ret = pk_spawn_argv (backend_spawn->priv->spawn, argv, NULL);
 	if (!ret) {
 		pk_backend_spawn_helper_delete (backend_spawn);
 		pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR,
diff --git a/src/pk-spawn.c b/src/pk-spawn.c
index 9b415b1..c4622f9 100644
--- a/src/pk-spawn.c
+++ b/src/pk-spawn.c
@@ -273,7 +273,7 @@ pk_spawn_kill (PkSpawn *spawn)
  *
  **/
 gboolean
-pk_spawn_argv (PkSpawn *spawn, gchar **argv)
+pk_spawn_argv (PkSpawn *spawn, gchar **argv, gchar **envp)
 {
 	gboolean ret;
 
@@ -284,7 +284,7 @@ pk_spawn_argv (PkSpawn *spawn, gchar **argv)
 	spawn->priv->finished = FALSE;
 
 	/* create spawned object for tracking */
-	ret = g_spawn_async_with_pipes (NULL, argv, NULL,
+	ret = g_spawn_async_with_pipes (NULL, argv, envp,
 				 G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
 				 NULL, NULL, &spawn->priv->child_pid,
 				 NULL, /* stdin */
@@ -484,6 +484,7 @@ libst_spawn (LibSelfTest *test)
 	gboolean ret;
 	gchar *path;
 	gchar **argv;
+	gchar **envp;
 
 	if (libst_start (test, "PkSpawn", CLASS_AUTO) == FALSE) {
 		return;
@@ -496,7 +497,7 @@ libst_spawn (LibSelfTest *test)
 	libst_title (test, "make sure return error for missing file");
 	mexit = BAD_EXIT;
 	argv = g_strsplit ("pk-spawn-test-xxx.sh", " ", 0);
-	ret = pk_spawn_argv (spawn, argv);
+	ret = pk_spawn_argv (spawn, argv, NULL);
 	g_strfreev (argv);
 	if (ret == FALSE) {
 		libst_success (test, "failed to run invalid file");
@@ -517,7 +518,7 @@ libst_spawn (LibSelfTest *test)
 	mexit = -1;
 	path = pk_test_get_data ("pk-spawn-test.sh");
 	argv = g_strsplit (path, " ", 0);
-	ret = pk_spawn_argv (spawn, argv);
+	ret = pk_spawn_argv (spawn, argv, NULL);
 	g_free (path);
 	g_strfreev (argv);
 	if (ret) {
@@ -558,11 +559,34 @@ libst_spawn (LibSelfTest *test)
 	new_spawn_object (test, &spawn);
 
 	/************************************************************/
+	libst_title (test, "make sure we set the proxy");
+	mexit = -1;
+	path = pk_test_get_data ("pk-spawn-proxy.sh");
+	argv = g_strsplit (path, " ", 0);
+	envp = g_strsplit ("http_proxy=username:password at server:port "
+			   "ftp_proxy=username:password at server:port", " ", 0);
+	ret = pk_spawn_argv (spawn, argv, envp);
+	g_free (path);
+	g_strfreev (argv);
+	if (ret) {
+		libst_success (test, "ran correct file");
+	} else {
+		libst_failed (test, "did not run helper");
+	}
+
+	/* wait for finished */
+	libst_loopwait (test, 10000);
+	libst_loopcheck (test);
+
+	/* get new object */
+	new_spawn_object (test, &spawn);
+
+	/************************************************************/
 	libst_title (test, "make sure run correct helper, and kill it");
 	mexit = BAD_EXIT;
 	path = pk_test_get_data ("pk-spawn-test.sh");
 	argv = g_strsplit (path, " ", 0);
-	ret = pk_spawn_argv (spawn, argv);
+	ret = pk_spawn_argv (spawn, argv, NULL);
 	g_free (path);
 	g_strfreev (argv);
 	if (ret) {
@@ -592,7 +616,7 @@ libst_spawn (LibSelfTest *test)
 	mexit = BAD_EXIT;
 	path = pk_test_get_data ("pk-spawn-test-sigquit.sh");
 	argv = g_strsplit (path, " ", 0);
-	ret = pk_spawn_argv (spawn, argv);
+	ret = pk_spawn_argv (spawn, argv, NULL);
 	g_free (path);
 	g_strfreev (argv);
 	if (ret) {
@@ -618,7 +642,7 @@ libst_spawn (LibSelfTest *test)
 	libst_title (test, "run lots of data for profiling");
 	path = pk_test_get_data ("pk-spawn-test-profiling.sh");
 	argv = g_strsplit (path, " ", 0);
-	ret = pk_spawn_argv (spawn, argv);
+	ret = pk_spawn_argv (spawn, argv, NULL);
 	g_free (path);
 	g_strfreev (argv);
 	if (ret) {
diff --git a/src/pk-spawn.h b/src/pk-spawn.h
index 1b20fef..0e58859 100644
--- a/src/pk-spawn.h
+++ b/src/pk-spawn.h
@@ -52,7 +52,8 @@ GType		 pk_spawn_get_type		  	(void) G_GNUC_CONST;
 PkSpawn		*pk_spawn_new				(void);
 
 gboolean	 pk_spawn_argv				(PkSpawn	*spawn,
-							 gchar		**argv)
+							 gchar		**argv,
+							 gchar		**envp)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_spawn_kill				(PkSpawn	*spawn);
 
commit 4c7c7b19ef4f87a59e5bf1d2d8201e6260c7c41a
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 10:48:19 2008 +0100

    add pk_package_list_add_item() and pk_package_list_contains_item()

diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index ec57f25..5d95e1b 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -85,6 +85,35 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package
 }
 
 /**
+ * pk_package_list_add_item:
+ *
+ * Makes a deep copy, and adds to the array
+ **/
+gboolean
+pk_package_list_add_item (PkPackageList *plist, PkPackageItem *item)
+{
+	gboolean ret;
+	PkPackageItem *item_new;
+
+	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE);
+	g_return_val_if_fail (item != NULL, FALSE);
+
+	ret = pk_package_list_contains_item (plist, item);
+	if (ret) {
+		pk_debug ("already added item");
+		return FALSE;
+	}
+
+	pk_debug ("adding to cache array package %s, %s, %s",
+		  pk_info_enum_to_text (item->info), item->package_id, item->summary);
+
+	item_new = pk_package_item_copy (item);
+	g_ptr_array_add (plist->priv->array, item_new);
+
+	return TRUE;
+}
+
+/**
  * pk_package_list_get_string:
  **/
 gchar *
@@ -182,6 +211,31 @@ pk_package_list_contains (PkPackageList *plist, const gchar *package_id)
 }
 
 /**
+ * pk_package_list_contains_item:
+ **/
+gboolean
+pk_package_list_contains_item (PkPackageList *plist, PkPackageItem *item)
+{
+	PkPackageItem *item_temp;
+	guint i;
+	guint length;
+	gboolean ret = FALSE;
+
+	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE);
+	g_return_val_if_fail (item != NULL, FALSE);
+
+	length = plist->priv->array->len;
+	for (i=0; i<length; i++) {
+		item_temp = g_ptr_array_index (plist->priv->array, i);
+		ret = pk_package_item_equal (item_temp, item);
+		if (ret) {
+			break;
+		}
+	}
+	return ret;
+}
+
+/**
  * pk_package_list_class_init:
  * @klass: The PkPackageListClass
  **/
diff --git a/libpackagekit/pk-package-list.h b/libpackagekit/pk-package-list.h
index 34e9ac8..9734af4 100644
--- a/libpackagekit/pk-package-list.h
+++ b/libpackagekit/pk-package-list.h
@@ -57,8 +57,12 @@ gboolean	 pk_package_list_add			(PkPackageList		*plist,
 							 PkInfoEnum		 info,
 							 const gchar		*package_id,
 							 const gchar		*summary);
+gboolean	 pk_package_list_add_item		(PkPackageList		*plist,
+							 PkPackageItem		*item);
 gboolean	 pk_package_list_contains		(PkPackageList		*plist,
 							 const gchar		*package_id);
+gboolean	 pk_package_list_contains_item		(PkPackageList		*plist,
+							 PkPackageItem		*item);
 gchar		*pk_package_list_get_string		(PkPackageList		*plist)
 							 G_GNUC_WARN_UNUSED_RESULT;
 guint		 pk_package_list_get_size		(PkPackageList		*plist);
commit 5d06323ea726c74b3a308374d89c4091569b172e
Author: Richard Hughes <richard at hughsie.com>
Date:   Thu May 15 09:22:35 2008 +0100

    don't use pk_backend_no_percentage_updates when we can just use pk_backend_set_percentage -- having two ways to do something just creates bugs...

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 3270e42..45e7a44 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -895,7 +895,7 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
 static gboolean
 backend_install_files_thread (PkBackend *backend)
 {
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	gchar **full_paths = pk_backend_get_strv (backend, "full_paths");
 
@@ -1050,7 +1050,7 @@ backend_install_packages (PkBackend *backend, gchar **package_ids)
 static gboolean
 backend_refresh_cache_thread (PkBackend *backend)
 {
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	if (alpm_trans_init (PM_TRANS_TYPE_SYNC, PM_TRANS_FLAG_NOSCRIPTLET, cb_trans_evt, cb_trans_conv, cb_trans_progress) != 0) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_TRANSACTION_ERROR, alpm_strerror (pm_errno));
diff --git a/backends/apt/pk-apt-build-db.cpp b/backends/apt/pk-apt-build-db.cpp
index d47c348..885275d 100644
--- a/backends/apt/pk-apt-build-db.cpp
+++ b/backends/apt/pk-apt-build-db.cpp
@@ -40,7 +40,7 @@ void apt_build_db(PkBackend * backend, sqlite3 *db)
 	sqlite3_stmt *package = NULL;
 
 	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates(backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL);
 	dir = g_dir_open(sdir,0,&error);
diff --git a/backends/apt/pk-sqlite-pkg-cache.cpp b/backends/apt/pk-sqlite-pkg-cache.cpp
index 770fcdf..1bf9a50 100644
--- a/backends/apt/pk-sqlite-pkg-cache.cpp
+++ b/backends/apt/pk-sqlite-pkg-cache.cpp
@@ -81,7 +81,7 @@ sqlite_search_packages_thread (PkBackend *backend)
 	const gchar *search;
 
 	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates(backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	type = pk_backend_get_uint (backend, "type");
 	search = pk_backend_get_string (backend, "search");
 
@@ -176,7 +176,7 @@ sqlite_get_details_thread (PkBackend *backend)
 	}
 
 	pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates(backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	pk_debug("finding %s", pi->name);
 
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index b7b8167..9263781 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -138,7 +138,7 @@ backend_find_packages_thread (PkBackend *backend)
 		filter_box = filter_box | PKG_SEARCH_DETAILS;
 	}
 
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	db = db_open();
 
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 9aa1a35..2df445e 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -254,7 +254,7 @@ static void
 backend_get_updates (PkBackend *backend, PkFilterEnum filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	/* check network state */
 	if (!pk_backend_is_online (backend)) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot check when offline");
@@ -537,7 +537,7 @@ backend_search_name_timeout (gpointer data)
 static void
 backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
 {
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	_signal_timeout = g_timeout_add (2000, backend_search_name_timeout, backend);
diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 7d09ace..2deccee 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -214,7 +214,7 @@ static void
 backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 
 	pk_backend_thread_create (backend, backend_refresh_cache_thread);
@@ -315,7 +315,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
 
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	params = g_new0 (SearchParams, 1);
 	params->filters = filters;
@@ -337,7 +337,7 @@ backend_search_description (PkBackend *backend, PkFilterEnum filters, const gcha
 
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	params = g_new0 (SearchParams, 1);
 	params->filters = filters;
@@ -356,7 +356,7 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
 
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	params = g_new0 (SearchParams, 1);
 	params->filters = filters;
@@ -407,7 +407,7 @@ backend_install_packages_thread (PkBackend *backend)
 static void
 backend_install_packages (PkBackend *backend, gchar **package_id)
 {
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
 
 	pk_backend_set_string (backend, "pkid", package_id[0]);
@@ -462,7 +462,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 	gpointer *params;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	/* params is a small array we can pack our thread parameters into */
 	params = g_new0 (gpointer, 2);
@@ -507,7 +507,7 @@ static void
 backend_update_system (PkBackend *backend)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	pk_backend_thread_create (backend, backend_update_system_thread);
 }
@@ -557,7 +557,7 @@ backend_update_packages (PkBackend *backend, gchar **package_ids)
 	gint i;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	for (i = 0; package_ids[i]; i++) {
 		pk_backend_set_string (backend, "pkgid", package_ids[i]);
@@ -599,7 +599,7 @@ static void
 backend_get_updates (PkBackend *backend, PkFilterEnum filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	pk_backend_thread_create (backend, backend_get_updates_thread);
 }
@@ -662,7 +662,7 @@ backend_get_details_thread (PkBackend *backend)
 static void
 backend_get_details (PkBackend *backend, const gchar *package_id)
 {
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_thread_create (backend, backend_get_details_thread);
 }
 
diff --git a/backends/test/pk-backend-test-dbus.c b/backends/test/pk-backend-test-dbus.c
index 5dfea32..76686dc 100644
--- a/backends/test/pk-backend-test-dbus.c
+++ b/backends/test/pk-backend-test-dbus.c
@@ -36,7 +36,7 @@ static void
 backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
 {
 	pk_backend_set_allow_cancel (backend, TRUE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_dbus_search_name (dbus, filters, search);
 }
 
diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c
index 2958c05..584f44c 100644
--- a/backends/test/pk-backend-test-spawn.c
+++ b/backends/test/pk-backend-test-spawn.c
@@ -35,7 +35,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
 {
 	gchar *filters_text;
 	pk_backend_set_allow_cancel (backend, TRUE);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	filters_text = pk_filter_enums_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.sh", filters_text, search, NULL);
 	g_free (filters_text);
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index 17cdc6e..c046c1d 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -236,7 +236,7 @@ backend_search_name_timeout (gpointer data)
 static void
 backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
 {
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	g_timeout_add (200000, backend_search_name_timeout, backend);
 }
 
diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 746da82..15c4b4f 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1170,7 +1170,7 @@ backend_find_packages_thread (PkBackend *backend)
 	mode = pk_backend_get_uint (backend, "mode");
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pk_backend_no_percentage_updates (backend);
+	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 
 	std::vector<zypp::sat::Solvable> *v = new std::vector<zypp::sat::Solvable>;
 	std::vector<zypp::sat::Solvable> *v2 = new std::vector<zypp::sat::Solvable>;
diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index b06e584..0a7d992 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -123,16 +123,6 @@ pk_backend_dbus_sub_percentage_changed_cb (DBusGProxy *proxy, guint sub_percenta
 }
 
 /**
- * pk_backend_dbus_no_percentage_updates_cb:
- **/
-static void
-pk_backend_dbus_no_percentage_updates_cb (DBusGProxy *proxy, PkBackendDbus *backend_dbus)
-{
-	pk_debug ("got signal");
-	pk_backend_no_percentage_updates (backend_dbus->priv->backend);
-}
-
-/**
  * pk_backend_dbus_package_cb:
  **/
 static void
@@ -325,8 +315,6 @@ pk_backend_dbus_remove_callbacks (PkBackendDbus *backend_dbus)
 					G_CALLBACK (pk_backend_dbus_percentage_changed_cb), backend_dbus);
 	dbus_g_proxy_disconnect_signal (proxy, "SubPercentageChanged",
 					G_CALLBACK (pk_backend_dbus_sub_percentage_changed_cb), backend_dbus);
-	dbus_g_proxy_disconnect_signal (proxy, "NoPercentageChanged",
-					G_CALLBACK (pk_backend_dbus_no_percentage_updates_cb), backend_dbus);
 	dbus_g_proxy_disconnect_signal (proxy, "Package",
 					G_CALLBACK (pk_backend_dbus_package_cb), backend_dbus);
 	dbus_g_proxy_disconnect_signal (proxy, "Details",
@@ -385,7 +373,6 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service)
 				 G_TYPE_UINT, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "SubPercentageChanged",
 				 G_TYPE_UINT, G_TYPE_INVALID);
-	dbus_g_proxy_add_signal (proxy, "NoPercentageChanged", G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "Package",
 				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 	dbus_g_proxy_add_signal (proxy, "Details",
@@ -424,8 +411,6 @@ pk_backend_dbus_set_name (PkBackendDbus *backend_dbus, const gchar *service)
 				     G_CALLBACK (pk_backend_dbus_percentage_changed_cb), backend_dbus, NULL);
 	dbus_g_proxy_connect_signal (proxy, "SubPercentageChanged",
 				     G_CALLBACK (pk_backend_dbus_sub_percentage_changed_cb), backend_dbus, NULL);
-	dbus_g_proxy_connect_signal (proxy, "NoPercentageChanged",
-				     G_CALLBACK (pk_backend_dbus_no_percentage_updates_cb), backend_dbus, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Package",
 				     G_CALLBACK (pk_backend_dbus_package_cb), backend_dbus, NULL);
 	dbus_g_proxy_connect_signal (proxy, "Details",
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index f9e8b68..9c04e25 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -313,7 +313,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_no_percentage_updates (backend_spawn->priv->backend);
+		pk_backend_set_percentage (backend_spawn->priv->backend, PK_BACKEND_PERCENTAGE_INVALID);
 	} else if (pk_strequal (command, "repo-signature-required")) {
 
 		if (size != 9+99) {
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 806bfab..3a30c4f 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -798,35 +798,6 @@ pk_backend_set_sub_percentage (PkBackend *backend, guint percentage)
 }
 
 /**
- * pk_backend_no_percentage_updates:
- **/
-gboolean
-pk_backend_no_percentage_updates (PkBackend *backend)
-{
-	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
-	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
-
-	/* have we already set an error? */
-	if (backend->priv->set_error) {
-		pk_warning ("already set error, cannot process");
-		return FALSE;
-	}
-
-	/* set the same twice? */
-	if (backend->priv->last_percentage == PK_BACKEND_PERCENTAGE_INVALID) {
-		pk_debug ("duplicate set of %i", PK_BACKEND_PERCENTAGE_INVALID);
-		return FALSE;
-	}
-
-	/* invalidate previous percentage */
-	backend->priv->last_percentage = PK_BACKEND_PERCENTAGE_INVALID;
-
-	/* emit the progress changed signal */
-	pk_backend_emit_progress_changed (backend);
-	return TRUE;
-}
-
-/**
  * pk_backend_set_status:
  **/
 gboolean
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 8f683a8..3251a33 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -58,7 +58,6 @@ gboolean	 pk_backend_set_sub_percentage		(PkBackend	*backend,
 							 guint		 percentage);
 gboolean	 pk_backend_set_exit_code		(PkBackend	*backend,
 							 PkExitEnum	 exit);
-gboolean	 pk_backend_no_percentage_updates	(PkBackend	*backend);
 gboolean	 pk_backend_set_transaction_data	(PkBackend	*backend,
 							 const gchar	*data);
 
commit 7f2fefc7e28b508d074e1ad786ca394f9f7a4f0d
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 18:03:53 2008 +0100

    allow setting 101 for backends for sub-percentages

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 3c356bd..9aa1a35 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -285,11 +285,16 @@ backend_install_timeout (gpointer data)
 		pk_backend_package (backend, PK_INFO_ENUM_INSTALLING,
 				    "gtkhtml2-devel;2.19.1-0.fc8;i386;fedora",
 				    "Devel files for gtkhtml");
+		/* this duplicate package should be ignored */
+		pk_backend_package (backend, PK_INFO_ENUM_INSTALLING,
+				    "gtkhtml2-devel;2.19.1-0.fc8;i386;fedora", NULL);
 		pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
 	}
 	if (_progress_percentage > 30 && _progress_percentage < 50) {
 		sub_percent = ((gfloat) (_progress_percentage - 30.0f) / 20.0f) * 100.0f;
 		pk_backend_set_sub_percentage (backend, sub_percent);
+	} else {
+		pk_backend_set_sub_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	}
 	_progress_percentage += 1;
 	pk_backend_set_percentage (backend, _progress_percentage);
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 1d25a05..806bfab 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -45,13 +45,6 @@
 #define PK_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_BACKEND, PkBackendPrivate))
 
 /**
- * PK_BACKEND_PERCENTAGE_INVALID:
- *
- * The unknown percentage value
- */
-#define PK_BACKEND_PERCENTAGE_INVALID		101
-
-/**
  * PK_BACKEND_PERCENTAGE_DEFAULT:
  *
  * The default percentage value, should never be emitted, but should be
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 95b7fa8..8f683a8 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -30,6 +30,13 @@
 
 G_BEGIN_DECLS
 
+/**
+ * PK_BACKEND_PERCENTAGE_INVALID:
+ *
+ * The unknown percentage value
+ */
+#define PK_BACKEND_PERCENTAGE_INVALID		101
+
 typedef struct _PkBackend PkBackend;
 
 /* set the state */
commit 5b9f70fda2471ffedad4e24bf2089e10ccb4b62d
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 18:00:37 2008 +0100

    ignore duplicate Package() calls from backends

diff --git a/src/pk-backend.c b/src/pk-backend.c
index 225c488..1d25a05 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -33,6 +33,7 @@
 #include <glib/gprintf.h>
 #include <pk-network.h>
 
+#include "pk-package-item.h"
 #include "pk-debug.h"
 #include "pk-common.h"
 #include "pk-marshal.h"
@@ -90,6 +91,7 @@ struct _PkBackendPrivate
 	gboolean		 set_eula;
 	gboolean		 has_sent_package;
 	PkNetwork		*network;
+	PkPackageItem		*last_package;
 	PkRoleEnum		 role; /* this never changes for the lifetime of a transaction */
 	PkStatusEnum		 status; /* this changes */
 	PkExitEnum		 exit;
@@ -901,11 +903,26 @@ gboolean
 pk_backend_package (PkBackend *backend, PkInfoEnum info, const gchar *package_id, const gchar *summary)
 {
 	gchar *summary_safe;
+	PkPackageItem *item;
+	gboolean ret;
 
 	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
 	g_return_val_if_fail (package_id != NULL, FALSE);
 	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
 
+	/* check against the old one */
+	item = pk_package_item_new (info, package_id, summary);
+	ret = pk_package_item_equal (item, backend->priv->last_package);
+	if (ret) {
+		pk_package_item_free (item);
+		pk_debug ("skipping duplicate %s", package_id);
+		return FALSE;
+	}
+	/* update the 'last' package */
+	pk_package_item_free (backend->priv->last_package);
+	backend->priv->last_package = pk_package_item_copy (item);
+	pk_package_item_free (item);
+
 	/* have we already set an error? */
 	if (backend->priv->set_error) {
 		pk_warning ("already set error, cannot process");
@@ -1818,6 +1835,7 @@ pk_backend_reset (PkBackend *backend)
 
 	/* TODO: need to wait for Finished() if running */
 
+	pk_package_item_free (backend->priv->last_package);
 	backend->priv->set_error = FALSE;
 	backend->priv->set_signature = FALSE;
 	backend->priv->set_eula = FALSE;
@@ -1825,6 +1843,7 @@ pk_backend_reset (PkBackend *backend)
 	backend->priv->finished = FALSE;
 	backend->priv->has_sent_package = FALSE;
 	backend->priv->thread = NULL;
+	backend->priv->last_package = NULL;
 	backend->priv->status = PK_STATUS_ENUM_UNKNOWN;
 	backend->priv->exit = PK_EXIT_ENUM_UNKNOWN;
 	backend->priv->role = PK_ROLE_ENUM_UNKNOWN;
@@ -1857,6 +1876,7 @@ pk_backend_init (PkBackend *backend)
 	backend->priv->c_tid = NULL;
 	backend->priv->file_changed_func = NULL;
 	backend->priv->file_changed_data = NULL;
+	backend->priv->last_package = NULL;
 	backend->priv->locked = FALSE;
 	backend->priv->signal_finished = 0;
 	backend->priv->signal_error_timeout = 0;
commit a79806ba57179630aa0828460053a6db07b345a2
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 17:54:50 2008 +0100

    add pk_package_item_copy() and allow freeing a NULL PkPackageItem without going boom

diff --git a/libpackagekit/pk-package-item.c b/libpackagekit/pk-package-item.c
index 7fe258d..87905dc 100644
--- a/libpackagekit/pk-package-item.c
+++ b/libpackagekit/pk-package-item.c
@@ -70,8 +70,9 @@ pk_package_item_new (PkInfoEnum info, const gchar *package_id, const gchar *summ
 gboolean
 pk_package_item_free (PkPackageItem *item)
 {
-	g_return_val_if_fail (item != NULL, FALSE);
-
+	if (item == NULL) {
+		return FALSE;
+	}
 	g_free (item->package_id);
 	g_free (item->summary);
 	g_free (item);
@@ -86,10 +87,25 @@ pk_package_item_free (PkPackageItem *item)
 gboolean
 pk_package_item_equal (PkPackageItem *item1, PkPackageItem *item2)
 {
+	if (item1 == NULL || item2 == NULL) {
+		return FALSE;
+	}
 	return (item1->info == item2->info &&
 		pk_strequal (item1->package_id, item2->package_id));
 }
 
+/**
+ * pk_package_item_copy:
+ *
+ * Copy a PkPackageItem
+ **/
+PkPackageItem *
+pk_package_item_copy (PkPackageItem *item)
+{
+	g_return_val_if_fail (item != NULL, NULL);
+	return pk_package_item_new (item->info, item->package_id, item->summary);
+}
+
 /***************************************************************************
  ***                          MAKE CHECK TESTS                           ***
  ***************************************************************************/
@@ -101,6 +117,7 @@ libst_package_item (LibSelfTest *test)
 {
 	PkPackageItem *item1;
 	PkPackageItem *item2;
+	PkPackageItem *item3;
 	gboolean ret;
 
 	if (libst_start (test, "PkPackageItem", CLASS_AUTO) == FALSE) {
@@ -126,8 +143,17 @@ libst_package_item (LibSelfTest *test)
 	}
 
 	/************************************************************/
+	libst_title (test, "copy entry");
+	item3 = pk_package_item_copy (item2);
+	if (item3 != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
 	libst_title (test, "check equal");
-	ret = pk_package_item_equal (item1, item2);
+	ret = pk_package_item_equal (item1, item3);
 	if (ret) {
 		libst_success (test, NULL);
 	} else {
@@ -135,6 +161,8 @@ libst_package_item (LibSelfTest *test)
 	}
 
 	pk_package_item_free (item2);
+	pk_package_item_free (item3);
+
 	/************************************************************/
 	libst_title (test, "add entry");
 	item2 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome-do;1.23;i386;data", "GNOME doo!");
diff --git a/libpackagekit/pk-package-item.h b/libpackagekit/pk-package-item.h
index 4ad188c..c41a6ea 100644
--- a/libpackagekit/pk-package-item.h
+++ b/libpackagekit/pk-package-item.h
@@ -40,6 +40,7 @@ PkPackageItem	*pk_package_item_new			(PkInfoEnum		 info,
 							 const gchar		*package_id,
 							 const gchar		*summary);
 gboolean	 pk_package_item_free			(PkPackageItem		*item);
+PkPackageItem	*pk_package_item_copy			(PkPackageItem		*item);
 gboolean	 pk_package_item_equal			(PkPackageItem		*item1,
 							 PkPackageItem		*item2);
 
commit 108c62a39fa705592684edd06622279d134a8506
Merge: a37e3d0... 4e77fbd...
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 17:27:58 2008 +0100

    Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit

commit a37e3d03312811bf85ef1783e08ab16b2541b52e
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 17:27:16 2008 +0100

    split up the PkPackageItem from PkPackageList so we can do an equal function

diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am
index 6b8c6b8..aeafe44 100644
--- a/libpackagekit/Makefile.am
+++ b/libpackagekit/Makefile.am
@@ -37,6 +37,7 @@ libpackagekit_include_HEADERS =					\
 	pk-connection.h						\
 	pk-package-id.h						\
 	pk-package-ids.h					\
+	pk-package-item.h					\
 	pk-package-list.h					\
 	pk-enum.h						\
 	pk-common.h						\
@@ -59,6 +60,8 @@ libpackagekit_la_SOURCES =					\
 	pk-package-id.h						\
 	pk-package-ids.c					\
 	pk-package-ids.h					\
+	pk-package-item.c					\
+	pk-package-item.h					\
 	pk-package-list.c					\
 	pk-package-list.h					\
 	pk-enum.h						\
diff --git a/libpackagekit/pk-package-item.c b/libpackagekit/pk-package-item.c
new file mode 100644
index 0000000..7fe258d
--- /dev/null
+++ b/libpackagekit/pk-package-item.c
@@ -0,0 +1,162 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:pk-package-item
+ * @short_description: A cached Package structure
+ *
+ * These provide a way to query and store a single package.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+
+#include "pk-debug.h"
+#include "pk-common.h"
+#include "pk-package-item.h"
+
+/**
+ * pk_package_item_new:
+ **/
+PkPackageItem *
+pk_package_item_new (PkInfoEnum info, const gchar *package_id, const gchar *summary)
+{
+	PkPackageItem *item;
+
+	g_return_val_if_fail (package_id != NULL, FALSE);
+
+	pk_debug ("adding to cache item package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary);
+	item = g_new0 (PkPackageItem, 1);
+	item->info = info;
+	item->package_id = g_strdup (package_id);
+	item->summary = g_strdup (summary);
+	return item;
+}
+
+/**
+ * pk_package_item_free:
+ **/
+gboolean
+pk_package_item_free (PkPackageItem *item)
+{
+	g_return_val_if_fail (item != NULL, FALSE);
+
+	g_free (item->package_id);
+	g_free (item->summary);
+	g_free (item);
+	return TRUE;
+}
+
+/**
+ * pk_package_item_equal:
+ *
+ * Only compares the package_id's and the info enum
+ **/
+gboolean
+pk_package_item_equal (PkPackageItem *item1, PkPackageItem *item2)
+{
+	return (item1->info == item2->info &&
+		pk_strequal (item1->package_id, item2->package_id));
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_package_item (LibSelfTest *test)
+{
+	PkPackageItem *item1;
+	PkPackageItem *item2;
+	gboolean ret;
+
+	if (libst_start (test, "PkPackageItem", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "add entry");
+	item1 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome;1.23;i386;data", "GNOME!");
+	if (item1 != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "add entry");
+	item2 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome;1.23;i386;data", "GNOME foo!");
+	if (item2 != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "check equal");
+	ret = pk_package_item_equal (item1, item2);
+	if (ret) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	pk_package_item_free (item2);
+	/************************************************************/
+	libst_title (test, "add entry");
+	item2 = pk_package_item_new (PK_INFO_ENUM_INSTALLED, "gnome-do;1.23;i386;data", "GNOME doo!");
+	if (item2 != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "check !equal");
+	ret = pk_package_item_equal (item1, item2);
+	if (!ret) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	pk_package_item_free (item1);
+	pk_package_item_free (item2);
+
+	libst_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-package-item.h b/libpackagekit/pk-package-item.h
new file mode 100644
index 0000000..4ad188c
--- /dev/null
+++ b/libpackagekit/pk-package-item.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_PACKAGE_ITEM_H
+#define __PK_PACKAGE_ITEM_H
+
+#include <glib-object.h>
+#include <pk-enum.h>
+
+/**
+ * PkPackageItem:
+ *
+ * A cached store for the complete Package object
+ */
+typedef struct {
+	PkInfoEnum		 info;
+	gchar			*package_id;
+	gchar			*summary;
+} PkPackageItem;
+
+PkPackageItem	*pk_package_item_new			(PkInfoEnum		 info,
+							 const gchar		*package_id,
+							 const gchar		*summary);
+gboolean	 pk_package_item_free			(PkPackageItem		*item);
+gboolean	 pk_package_item_equal			(PkPackageItem		*item1,
+							 PkPackageItem		*item2);
+
+#endif /* __PK_PACKAGE_ITEM_H */
+
diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index b0a1a71..ec57f25 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -45,6 +45,7 @@
 #include "pk-debug.h"
 #include "pk-common.h"
 #include "pk-package-id.h"
+#include "pk-package-item.h"
 #include "pk-package-list.h"
 
 static void     pk_package_list_class_init	(PkPackageListClass *klass);
@@ -77,10 +78,7 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package
 	g_return_val_if_fail (package_id != NULL, FALSE);
 
 	pk_debug ("adding to cache array package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary);
-	item = g_new0 (PkPackageItem, 1);
-	item->info = info;
-	item->package_id = g_strdup (package_id);
-	item->summary = g_strdup (summary);
+	item = pk_package_item_new (info, package_id, summary);
 	g_ptr_array_add (plist->priv->array, item);
 
 	return TRUE;
@@ -152,9 +150,7 @@ pk_package_list_clear (PkPackageList *plist)
 
 	while (plist->priv->array->len > 0) {
 		item = g_ptr_array_index (plist->priv->array, 0);
-		g_free (item->package_id);
-		g_free (item->summary);
-		g_free (item);
+		pk_package_item_free (item);
 		g_ptr_array_remove_index_fast (plist->priv->array, 0);
 	}
 	return TRUE;
diff --git a/libpackagekit/pk-package-list.h b/libpackagekit/pk-package-list.h
index 9178f77..34e9ac8 100644
--- a/libpackagekit/pk-package-list.h
+++ b/libpackagekit/pk-package-list.h
@@ -25,6 +25,8 @@
 #include <glib-object.h>
 #include <pk-enum.h>
 
+#include "pk-package-item.h"
+
 G_BEGIN_DECLS
 
 #define PK_TYPE_PACKAGE_LIST		(pk_package_list_get_type ())
@@ -49,18 +51,6 @@ struct _PkPackageListClass
 	GObjectClass	parent_class;
 };
 
-/**
- * PkPackageItem:
- *
- * A cached store for the complete Package object
- */
-typedef struct
-{
-	PkInfoEnum		 info;
-	gchar			*package_id;
-	gchar			*summary;
-} PkPackageItem;
-
 GType		 pk_package_list_get_type		(void) G_GNUC_CONST;
 PkPackageList	*pk_package_list_new			(void);
 gboolean	 pk_package_list_add			(PkPackageList		*plist,
diff --git a/libpackagekit/pk-self-test.c b/libpackagekit/pk-self-test.c
index 62e225b..bf151fb 100644
--- a/libpackagekit/pk-self-test.c
+++ b/libpackagekit/pk-self-test.c
@@ -29,6 +29,7 @@
 /* prototypes */
 void libst_package_id (LibSelfTest *test);
 void libst_package_ids (LibSelfTest *test);
+void libst_package_item (LibSelfTest *test);
 void libst_package_list (LibSelfTest *test);
 void libst_enum (LibSelfTest *test);
 void libst_common (LibSelfTest *test);
@@ -51,6 +52,7 @@ main (int argc, char **argv)
 	libst_common (&test);
 	libst_package_id (&test);
 	libst_package_ids (&test);
+	libst_package_item (&test);
 	libst_package_list (&test);
 	libst_enum (&test);
 	libst_extra (&test);
commit 4e77fbd845d6bab6f2cfb4a1ab6c9b2f70ee0611
Author: Thomas Wood <thomas at openedhand.com>
Date:   Wed May 14 16:52:51 2008 +0100

    opkg: send status and package signals during progress updates

diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 9e345b6..7d09ace 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -155,6 +155,38 @@ pk_opkg_progress_cb (opkg_t *opkg, const opkg_progress_data_t *pdata, void *data
 		return;
 
 	pk_backend_set_percentage (backend, pdata->percentage);
+	if (pdata->package)
+	{
+		gchar *uid;
+		opkg_package_t *pkg = pdata->package;
+		gint status = PK_INFO_ENUM_UNKNOWN;
+
+		uid = g_strdup_printf ("%s;%s;%s;",
+			pkg->name, pkg->version, pkg->architecture);
+
+		if (pdata->action == OPKG_DOWNLOAD)
+			status = PK_INFO_ENUM_DOWNLOADING;
+		else if (pdata->action == OPKG_INSTALL)
+			status = PK_INFO_ENUM_INSTALLING;
+		else if (pdata->action == OPKG_REMOVE)
+			status = PK_INFO_ENUM_REMOVING;
+
+		pk_backend_package (backend, status, uid, pkg->description);
+		g_free (uid);
+	}
+
+	switch (pdata->action)
+	{
+	case OPKG_DOWNLOAD:
+		pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD);
+		break;
+	case OPKG_INSTALL:
+		pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
+		break;
+	case OPKG_REMOVE:
+		pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE);
+		break;
+	}
 }
 
 static gboolean
commit 849226b9c3e93379fca67a00836e14e2ab3b5f67
Author: Thomas Wood <thomas at openedhand.com>
Date:   Wed May 14 16:09:46 2008 +0100

    opkg: support new error handling from libopkg

diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index ecc97be..9e345b6 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -163,8 +163,12 @@ backend_refresh_cache_thread (PkBackend *backend)
 	int ret;
 
 	ret = opkg_update_package_lists (opkg, pk_opkg_progress_cb, backend);
+
 	if (ret) {
-		opkg_unknown_error (backend, ret, "Refreshing cache");
+		if (ret == OPKG_DOWNLOAD_FAILED)
+			pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_AVAILABLE, NULL);
+		else
+			opkg_unknown_error (backend, ret, "Refreshing cache");
 	}
 	pk_backend_finished (backend);
 
@@ -346,8 +350,22 @@ backend_install_packages_thread (PkBackend *backend)
 	pi = pk_package_id_new_from_string (package_id);
 
 	err = opkg_install_package (opkg, pi->name, pk_opkg_progress_cb, backend);
-	if (err != 0)
+	switch (err)
+	{
+	case OPKG_NO_ERROR:
+		break;
+	case OPKG_DEPENDANCIES_FAILED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, NULL);
+		break;
+	case OPKG_PACKAGE_ALREADY_INSTALLED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED, NULL);
+		break;
+	case OPKG_PACKAGE_NOT_AVAILABLE:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
+		break;
+	default:
 		opkg_unknown_error (backend, err, "Install");
+	}
 
 	pk_package_id_free (pi);
 	pk_backend_finished (backend);
@@ -390,9 +408,16 @@ backend_remove_packages_thread (PkBackend *backend)
 
 	err = opkg_remove_package (opkg, pi->name, pk_opkg_progress_cb, backend);
 
-	/* TODO: improve error reporting */
-	if (err != 0)
+	switch (err)
+	{
+	case OPKG_NO_ERROR:
+		break;
+	case OPKG_PACKAGE_NOT_INSTALLED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
+		break;
+	default:
 		opkg_unknown_error (backend, err, "Remove");
+	}
 
 	pk_package_id_free (pi);
 	pk_backend_finished (backend);
@@ -478,8 +503,14 @@ backend_update_package_thread (PkBackend *backend)
 	}
 
 	err = opkg_upgrade_package (opkg, pi->name, pk_opkg_progress_cb, backend);
-
-	if (err != 0) {
+	switch (err)
+	{
+	case OPKG_NO_ERROR:
+		break;
+	case OPKG_PACKAGE_NOT_INSTALLED:
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
+		break;
+	default:
 		opkg_unknown_error (backend, err, "Update package");
 	}
 
@@ -572,19 +603,26 @@ backend_get_details_thread (PkBackend *backend)
 	if (pi == NULL)
 	{
 		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
-		pk_package_id_free (pi);
+		pk_backend_finished (backend);
 		return FALSE;
 	}
 
 
 	pkg = opkg_find_package (opkg, pi->name, pi->version, pi->arch, pi->data);
+	pk_package_id_free (pi);
+
+	if (!pkg)
+	{
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
+		pk_backend_finished (backend);
+		return FALSE;
+	}
 
 	newid = g_strdup_printf ("%s;%s;%s;%s", pkg->name, pkg->version, pkg->architecture, pkg->repository);
 
 	pk_backend_details (backend, newid, NULL, 0, pkg->description, pkg->url, pkg->size);
 
 	g_free (newid);
-	pk_package_id_free (pi);
 	pk_backend_finished (backend);
 	return TRUE;
 }
diff --git a/configure.ac b/configure.ac
index 9d734e1..f614d2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -535,7 +535,7 @@ if test x$enable_box = xyes; then
 fi
 
 if test x$enable_opkg = xyes; then
-	PKG_CHECK_MODULES(OPKG, libopkg = 0.1.3)
+	PKG_CHECK_MODULES(OPKG, libopkg = 0.1.4)
 	AC_SUBST(OPKG_CFLAGS)
 	AC_SUBST(OPKG_LIBS)
 fi
commit cb09e4042bf7cdb6847b052b5959d82fd22fad78
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 17:00:49 2008 +0100

    dummy: add subpercentage support into the dummy backend when installing packages

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 49d4e5a..3c356bd 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -268,6 +268,8 @@ static gboolean
 backend_install_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
+	guint sub_percent;
+
 	if (_progress_percentage == 100) {
 		pk_backend_finished (backend);
 		return FALSE;
@@ -285,7 +287,11 @@ backend_install_timeout (gpointer data)
 				    "Devel files for gtkhtml");
 		pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
 	}
-	_progress_percentage += 10;
+	if (_progress_percentage > 30 && _progress_percentage < 50) {
+		sub_percent = ((gfloat) (_progress_percentage - 30.0f) / 20.0f) * 100.0f;
+		pk_backend_set_sub_percentage (backend, sub_percent);
+	}
+	_progress_percentage += 1;
 	pk_backend_set_percentage (backend, _progress_percentage);
 	return TRUE;
 }
@@ -348,7 +354,7 @@ backend_install_packages (PkBackend *backend, gchar **package_ids)
 	pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
 			    "gtkhtml2;2.19.1-4.fc8;i386;fedora",
 			    "An HTML widget for GTK+ 2.0");
-	_signal_timeout = g_timeout_add (1000, backend_install_timeout, backend);
+	_signal_timeout = g_timeout_add (100, backend_install_timeout, backend);
 }
 
 /**
commit 06cba57a9ea2e85ca88b151284212f1277e31d0d
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 12:02:15 2008 +0100

    add another FAQ entry, about running the tools as the root user

diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index d4c0825..efa8344 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -22,6 +22,7 @@
 <h2>Table Of Contents</h2>
 <ul>
 <li><a href="#how-complete">How complete are the backends?</a></li>
+<li><a href="#run-as-root">When run as root, gpk-application and pkcon do not work!</a></li>
 <li><a href="#session-system">Why is there a session service and and a system service?</a></li>
 <li><a href="#session-methods">How do I use PackageKit in my application?</a></li>
 <li><a href="#rawhide-updates">Why don't I get update details with Fedora Rawhide?</a></li>
@@ -565,6 +566,19 @@
 </table>
 
 <hr>
+<h3><a name="run-as-root">When run as root, <code>gpk-application</code> and <code>pkcon</code> do not work!</a></h3>
+<p>
+GTK+ tools should not be run as the root user, <b>PERIOD</b>.
+Any GTK+ program run as the root user is a massive security hole -- GTK+ just isn't designed with
+this in mind.
+There are <b>numerous</b> attack vectors when running as root, and programs shouldn't do such
+insane and insecure things.
+</p>
+<p>
+Please see <a href="http://www.gtk.org/setuid.html">the GTK+ explanation</a> for more rationale.
+</p>
+
+<hr>
 <h3><a name="session-system">Why is there a session service <b>and</b> and a system service?</a></h3>
 <p>
 PackageKit runs a process <code>packagekitd</code> that is a daemon that runs per-system.
commit 3dcdb2d55ffe08e74c029418e04c465de4f5fcd5
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed May 14 11:36:48 2008 +0200

    APT2: Implement resolve. Update documentation accordingly.

diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
index cd23e36..8802ec3 100755
--- a/backends/apt2/aptDBUSBackend.py
+++ b/backends/apt2/aptDBUSBackend.py
@@ -509,6 +509,26 @@ class PackageKitAptBackend(PackageKitBaseBackend):
                 self._emit_package(pkg)
         self.Finished(EXIT_SUCCESS)
 
+    @threaded
+    def doResolve(self, filters, name):
+        '''
+        Implement the apt2-resolve functionality
+        '''
+        pklog.info("Resolve")
+        self.StatusChanged(STATUS_QUERY)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self.AllowCancel(False)
+
+        #FIXME: Support candidates
+        if self._cache.has_key(name) and self.is_package_visible(pkg, filters):
+            self._emit_package(name)
+            self.Finished(EXIT_SUCCESS)
+        else:
+            self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+                           "Package name %s could not be resolved" % name)
+            self.Finished(EXIT_FAILED)
+
     # Helpers
 
     def _open_cache(self, prange=(0,100), progress=True):
diff --git a/backends/apt2/pk-backend-apt2.c b/backends/apt2/pk-backend-apt2.c
index c075d43..9c85206 100644
--- a/backends/apt2/pk-backend-apt2.c
+++ b/backends/apt2/pk-backend-apt2.c
@@ -167,6 +167,25 @@ backend_cancel (PkBackend *backend)
 	pk_backend_dbus_cancel (dbus);
 }
 
+/**
+ *  * pk_backend_resolve:
+ *   */
+static void
+backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package_id)
+{
+	        pk_backend_dbus_resolve (dbus, filters, package_id);
+}
+
+/**
+ *  * pk_backend_get_packages:
+ *   */
+static void
+backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+{
+	        pk_backend_dbus_get_packages (dbus, filters);
+}
+
+
 
 PK_BACKEND_OPTIONS (
 	"Apt",					/* description */
@@ -179,7 +198,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_files */
-	NULL,					/* get_packages */
+	backend_get_packages,			/* get_packages */
 	NULL,					/* get_repo_list */
 	NULL,					/* get_requires */
 	NULL,					/* get_update_detail */
@@ -191,7 +210,7 @@ PK_BACKEND_OPTIONS (
 	backend_remove_package,			/* remove_package */
 	NULL,					/* repo_enable */
 	NULL,					/* repo_set_data */
-	NULL,					/* resolve */
+	backend_resolve,			/* resolve */
 	NULL,					/* rollback */
 	backend_search_details,			/* search_details */
 	NULL,					/* search_file */
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index e47c8de..6522279 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -66,7 +66,7 @@
 <tr>
 <td><b>Resolve</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- box -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- conary -->
commit fd795b75ac0dd690f37001879f49b95c7579ecfe
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed May 14 11:09:24 2008 +0200

    APT2: Update the FAQ to represent the GetPackages support

diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index e88a4e4..e47c8de 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -411,7 +411,7 @@
 <tr>
 <td><b>GetPackages</b></td>
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
-<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
+<td><img src="img/status-good.png" alt="[yes]"/></td><!-- apt2 -->
 <td><img src="img/status-good.png" alt="[yes]"/></td><!-- alpm -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
commit 2ead43b8b7630ace73e4cf824547bcdc2ccce0f3
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 09:16:07 2008 +0100

    Fix a backtrace when we try to use refresh-packagekit.py with an old daemon: catch all exceptions when we do StateHasChanged to fix rh#446331

diff --git a/contrib/yum-packagekit/refresh-packagekit.py b/contrib/yum-packagekit/refresh-packagekit.py
index 9c0bdf4..b440539 100644
--- a/contrib/yum-packagekit/refresh-packagekit.py
+++ b/contrib/yum-packagekit/refresh-packagekit.py
@@ -35,7 +35,7 @@ def posttrans_hook(conduit):
                                           '/org/freedesktop/PackageKit')
         packagekit_iface = dbus.Interface(packagekit_proxy, 'org.freedesktop.PackageKit')
         packagekit_iface.StateHasChanged('posttrans')
-    except dbus.DBusException, e:
+    except Exception, e:
         conduit.info(2, "Unable to send message to PackageKit")
         conduit.info(6, "%s" %(e,))
 
commit dea48cec137ce0feb04c79c78fe5d5006d4d65c1
Author: Richard Hughes <richard at hughsie.com>
Date:   Wed May 14 09:05:55 2008 +0100

    remove some [img] tags that have no value

diff --git a/docs/html/index.html b/docs/html/index.html
index 7270eb7..d60f825 100644
--- a/docs/html/index.html
+++ b/docs/html/index.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">PackageKit Main Page</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
@@ -20,10 +20,10 @@
 <table align="center" cellpadding="5px" border="0">
 
 <tr>
- <td align="center"><a href="pk-intro.html"><img src="img/large-accessories-text-editor.png" width="128" alt="[img]"/></a></td>
- <td align="center"><a href="pk-using.html"><img src="img/large-preferences-system.png" width="128" alt="[img]"/></a></td>
- <td align="center"><a href="pk-download.html"><img src="img/large-dialog-information.png" width="128" alt="[img]"/></a></td>
- <td align="center"><a href="pk-screenshots.html"><img src="img/large-emblem-photos.png" width="128" alt="[img]"/></a></td>
+ <td align="center"><a href="pk-intro.html"><img src="img/large-accessories-text-editor.png" width="128" alt=""/></a></td>
+ <td align="center"><a href="pk-using.html"><img src="img/large-preferences-system.png" width="128" alt=""/></a></td>
+ <td align="center"><a href="pk-download.html"><img src="img/large-dialog-information.png" width="128" alt=""/></a></td>
+ <td align="center"><a href="pk-screenshots.html"><img src="img/large-emblem-photos.png" width="128" alt=""/></a></td>
 </tr>
 <tr>
  <td><p class="indextitle"><a href="pk-intro.html" class="indextitle">What is<br/>PackageKit?</a></p></td>
@@ -32,10 +32,10 @@
  <td><p class="indextitle"><a href="pk-screenshots.html" class="indextitle">Screenshots</a></p></td>
 </tr>
 <tr>
- <td align="center"><a href="pk-authors.html"><img src="img/large-authors.png" width="128" alt="[img]"/></a></td>
- <td align="center"><a href="pk-bugs.html"><img src="img/large-applications-development.png" width="128" alt="[img]"/></a></td>
- <td align="center"><a href="pk-help.html"><img src="img/large-system-users.png" width="128" alt="[img]"/></a></td>
- <td align="center"><a href="pk-faq.html"><img src="img/large-help-browser.png" width="128" alt="[img]"/></a></td>
+ <td align="center"><a href="pk-authors.html"><img src="img/large-authors.png" width="128" alt=""/></a></td>
+ <td align="center"><a href="pk-bugs.html"><img src="img/large-applications-development.png" width="128" alt=""/></a></td>
+ <td align="center"><a href="pk-help.html"><img src="img/large-system-users.png" width="128" alt=""/></a></td>
+ <td align="center"><a href="pk-faq.html"><img src="img/large-help-browser.png" width="128" alt=""/></a></td>
 </tr>
 <tr>
  <td><p class="indextitle"><a href="pk-authors.html" class="indextitle">Who develops<br/>PackageKit?</a></p></td>
diff --git a/docs/html/pk-authors.html b/docs/html/pk-authors.html
index 08289ad..607a7a4 100644
--- a/docs/html/pk-authors.html
+++ b/docs/html/pk-authors.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">Who develops PackageKit?</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
@@ -22,7 +22,7 @@
 <table cellpadding="10">
 <tr>
  <td>
-  <img src="img/author-hughsie.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-hughsie.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Richard Hughes</h2>
@@ -48,7 +48,7 @@
 
 <tr>
  <td>
-  <img src="img/author-kenvandine.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-kenvandine.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Ken VanDine</h2>
@@ -66,7 +66,7 @@
 
 <tr>
  <td>
-  <img src="img/author-btimothy.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-btimothy.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Boyd Timothy</h2>
@@ -84,7 +84,7 @@
 
 <tr>
  <td>
-  <img src="img/author-rnorwood.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-rnorwood.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Robin Norwood</h2>
@@ -101,7 +101,7 @@
 
 <tr>
  <td>
-  <img src="img/author-tomparker.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-tomparker.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Tom Parker</h2>
@@ -118,7 +118,7 @@
 
 <tr>
  <td>
-  <img src="img/author-timlau.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-timlau.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Tim Lauridsen</h2>
@@ -139,7 +139,7 @@
 
 <tr>
  <td>
-  <img src="img/author-lmacken.png" alt="[img]"/>
+  <img src="img/author-lmacken.png" alt=""/>
  </td>
  <td>
   <h2>Luke Macken</h2>
@@ -154,7 +154,7 @@
 
 <tr>
  <td>
-  <img src="img/author-grzegorzdabrowski.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-grzegorzdabrowski.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Grzegorz DÄ…browski</h2>
@@ -173,7 +173,7 @@
 
 <tr>
  <td>
-  <img src="img/author-caglar.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-caglar.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>S.Çağlar Onur</h2>
@@ -195,7 +195,7 @@
 
 <tr>
  <td>
-  <img src="img/author-elliot.png" alt="[img]"/>
+  <img src="img/author-elliot.png" alt=""/>
  </td>
  <td>
   <h2>Elliot Peele</h2>
@@ -210,7 +210,7 @@
 
 <tr>
  <td>
-  <img src="img/author-jbowes.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-jbowes.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>James Bowes</h2>
@@ -227,7 +227,7 @@
 
 <tr>
  <td>
-  <img src="img/author-unknown.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-unknown.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Thomas Wood</h2>
@@ -247,7 +247,7 @@
 
 <tr>
  <td>
-  <img src="img/author-unknown.png" alt="[img]"/><!-- image should be 120px wide -->
+  <img src="img/author-unknown.png" alt=""/><!-- image should be 120px wide -->
  </td>
  <td>
   <h2>Scott Reeves</h2>
diff --git a/docs/html/pk-bugs.html b/docs/html/pk-bugs.html
index 89f7c48..2ee12ea 100644
--- a/docs/html/pk-bugs.html
+++ b/docs/html/pk-bugs.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">Reporting Bugs</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 6f796b8..0cdc85c 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">Where can I download it?</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index a25e2b7..d4c0825 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><center><img src="img/packagekit.png" alt="[img]"/></center></td>
+ <td><center><img src="img/packagekit.png" alt=""/></center></td>
  <td width="95%" valign="middle"><p class="title">Frequently Asked Questions</p></td>
- <td><center><img src="img/packagekit.png" alt="[img]"/></center></td>
+ <td><center><img src="img/packagekit.png" alt=""/></center></td>
 </tr>
 </table>
 
diff --git a/docs/html/pk-help.html b/docs/html/pk-help.html
index 5b44d50..fa9d9cc 100644
--- a/docs/html/pk-help.html
+++ b/docs/html/pk-help.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">How can I help?</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
diff --git a/docs/html/pk-intro.html b/docs/html/pk-intro.html
index c42be21..64f72fc 100644
--- a/docs/html/pk-intro.html
+++ b/docs/html/pk-intro.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">What is PackageKit?</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
diff --git a/docs/html/pk-screenshots.html b/docs/html/pk-screenshots.html
index 78bd01f..5c7d4fa 100644
--- a/docs/html/pk-screenshots.html
+++ b/docs/html/pk-screenshots.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><center><img src="img/packagekit.png" alt="[img]"/></center></td>
+ <td><center><img src="img/packagekit.png" alt=""/></center></td>
  <td width="95%" valign="middle"><p class="title">Screenshots</p></td>
- <td><center><img src="img/packagekit.png" alt="[img]"/></center></td>
+ <td><center><img src="img/packagekit.png" alt=""/></center></td>
 </tr>
 </table>
 
@@ -26,77 +26,77 @@
 
 <h1><a name="gnome">GNOME Screenshots</a></h1>
 
-<center><img src="img/gpk-application-search.png" alt="[img]"/></center>
+<center><img src="img/gpk-application-search.png" alt=""/></center>
 <p class="caption">Add/Remove Software search</p>
 
-<center><img src="img/gpk-application-groups.png" alt="[img]"/></center>
+<center><img src="img/gpk-application-groups.png" alt=""/></center>
 <p class="caption">Add/Remove Software groups</p>
 
-<center><img src="img/gpk-log.png" alt="[img]"/></center>
+<center><img src="img/gpk-log.png" alt=""/></center>
 <p class="caption">Transaction viewer</p>
 
-<center><img src="img/gpk-updates-overview.png" alt="[img]"/></center>
+<center><img src="img/gpk-updates-overview.png" alt=""/></center>
 <p class="caption">Update viewer overview</p>
 
-<center><img src="img/gpk-updates.png" alt="[img]"/></center>
+<center><img src="img/gpk-updates.png" alt=""/></center>
 <p class="caption">Update viewer</p>
 
-<center><img src="img/gpk-prefs.png" alt="[img]"/></center>
+<center><img src="img/gpk-prefs.png" alt=""/></center>
 <p class="caption">Auto update preferences</p>
 
-<center><img src="img/gpk-progress.png" alt="[img]"/></center>
+<center><img src="img/gpk-progress.png" alt=""/></center>
 <p class="caption">Progress dialog</p>
 
-<center><img src="img/gpk-added-deps.png" alt="[img]"/></center>
+<center><img src="img/gpk-added-deps.png" alt=""/></center>
 <p class="caption">Added check warning</p>
 
-<center><img src="img/gpk-eula.png" alt="[img]"/></center>
+<center><img src="img/gpk-eula.png" alt=""/></center>
 <p class="caption">EULA dialog</p>
 
-<center><img src="img/gpk-remove-confirm.png" alt="[img]"/></center>
+<center><img src="img/gpk-remove-confirm.png" alt=""/></center>
 <p class="caption">Remove check warning</p>
 
-<center><img src="img/gpk-repo-auth.png" alt="[img]"/></center>
+<center><img src="img/gpk-repo-auth.png" alt=""/></center>
 <p class="caption">Repository authentication</p>
 
-<center><img src="img/gpk-repo.png" alt="[img]"/></center>
+<center><img src="img/gpk-repo.png" alt=""/></center>
 <p class="caption">Repository viewer</p>
 
-<center><img src="img/gpk-backend-status.png" alt="[img]"/></center>
+<center><img src="img/gpk-backend-status.png" alt=""/></center>
 <p class="caption">PackageKit backend status</p>
 
-<center><img src="img/gpk-updates-warning.png" alt="[img]"/></center>
+<center><img src="img/gpk-updates-warning.png" alt=""/></center>
 <p class="caption">Libnotify updates warning</p>
 
-<center><img src="img/gpk-waiting.png" alt="[img]"/></center>
+<center><img src="img/gpk-waiting.png" alt=""/></center>
 <p class="caption">Tasks waiting</p>
 
-<center><img src="img/gpk-battery.png" alt="[img]"/></center>
+<center><img src="img/gpk-battery.png" alt=""/></center>
 <p class="caption">Intergration with gnome-power-manager</p>
 
-<center><img src="img/gpk-inhibit.png" alt="[img]"/></center>
+<center><img src="img/gpk-inhibit.png" alt=""/></center>
 <p class="caption">Inhibit with gnome-power-manager</p>
 
-<center><img src="img/gpk-require-restart.png" alt="[img]"/></center>
+<center><img src="img/gpk-require-restart.png" alt=""/></center>
 <p class="caption">We sometimes need to do a restart</p>
 
-<center><img src="img/gpk-auto-update.png" alt="[img]"/></center>
+<center><img src="img/gpk-auto-update.png" alt=""/></center>
 <p class="caption">Auto update install dialog</p>
 
 <h1><a name="kde">KDE Screenshots</a></h1>
 
-<center><img src="img/kpk-search.png" alt="[img]"/></center>
+<center><img src="img/kpk-search.png" alt=""/></center>
 <p class="caption">KPackageKit Searching</p>
 
-<center><img src="img/kpk-information.png" alt="[img]"/></center>
+<center><img src="img/kpk-information.png" alt=""/></center>
 <p class="caption">KPackageKit Package Information</p>
 
-<center><img src="img/pk-opensuse-updater.png" alt="[img]"/></center>
+<center><img src="img/pk-opensuse-updater.png" alt=""/></center>
 <p class="caption">OpenSuse Updater</p>
 
 <h1><a name="moko">OpenMoko Screenshots</a></h1>
 
-<center><img src="img/assassin.png" alt="[img]"/></center>
+<center><img src="img/assassin.png" alt=""/></center>
 <p class="caption">Assassin</p>
 
 <p>Back to the <a href="index.html">main page</a></p>
diff --git a/docs/html/pk-using.html b/docs/html/pk-using.html
index cc455c7..b2b028e 100644
--- a/docs/html/pk-using.html
+++ b/docs/html/pk-using.html
@@ -9,9 +9,9 @@
 
 <table align="center" class="title">
 <tr>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
  <td width="95%" valign="middle"><p class="title">How do I use PackageKit?</p></td>
- <td><img src="img/packagekit.png" alt="[img]"/></td>
+ <td><img src="img/packagekit.png" alt=""/></td>
 </tr>
 </table>
 
commit caf2dc0950a7ab829ae0c1bc2adf59ad82212d21
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue May 13 23:22:48 2008 -0400

    Fix exception name.

diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index 3b8a3e8..29f5b03 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -471,7 +471,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                             if self._do_extra_filtering(pkg, fltlist):
                                 package_list.append((pkg,INFO_AVAILABLE))
 
-        except yum.Errors.GroupError,e:
+        except yum.Errors.GroupsError,e:
             self._unlock_yum()
             self.ErrorCode(ERROR_GROUP_NOT_FOUND, str(e))
             self.Finished(EXIT_FAILED)
commit e6304955ee68785b2f0c063aa0fe80ba6886c5a2
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue May 13 23:22:37 2008 -0400

    Fix call to GetRepoList in yum2 tests.

diff --git a/backends/yum2/helpers/testyum2.py b/backends/yum2/helpers/testyum2.py
index cdec507..85b47f9 100755
--- a/backends/yum2/helpers/testyum2.py
+++ b/backends/yum2/helpers/testyum2.py
@@ -80,7 +80,7 @@ try:
         #iface.GetPackages(FILTER_INSTALLED,'no')
     if cmd == 'get-repolist' or cmd == 'all':
         print "Testing GetRepoList()"
-        iface.GetRepoList()
+        iface.GetRepoList("")
     if cmd == 'get-updatedetail' or cmd == 'all':
         print "Testing GetUpdateDetail(PKG_ID)"
         iface.GetUpdateDetail(PKG_ID)
commit 6af58c2eb3ac22b67a63f34023a4ee7a5dd51a72
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Mon May 12 13:28:14 2008 -0400

    Add some changes from yum backend.

diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index 9cfed94..3b8a3e8 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -434,7 +434,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         try:
             pkgGroupDict = self._buildGroupDict()
             fltlist = filters.split(';')
-            found = {}
+            installed_nevra = [] # yum returns packages as available even when installed
 
             if not FILTER_NOT_INSTALLED in fltlist:
                 # Check installed for group
@@ -450,21 +450,31 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                             group = groupMap[cg]           # use the pk group name, instead of yum 'category/group'
                     if group == key:
                         if self._do_extra_filtering(pkg, fltlist):
-                            self._show_package(pkg, INFO_INSTALLED)
+                            package_list.append((pkg,INFO_INSTALLED))
+                    installed_nevra.append(self._get_nevra(pkg))                        
+
             if not FILTER_INSTALLED in fltlist:
                 # Check available for group
                 for pkg in self.yumbase.pkgSack:
                     if self._cancel_check("Search cancelled."):
                         # _cancel_check() sets the error message, unlocks yum, and calls Finished()
                         return
-                    group = GROUP_OTHER
-                    if pkgGroupDict.has_key(pkg.name):
-                        cg = pkgGroupDict[pkg.name]
-                        if groupMap.has_key(cg):
-                            group = groupMap[cg]
-                    if group == key:
-                        if self._do_extra_filtering(pkg, fltlist):
-                            self._show_package(pkg, INFO_AVAILABLE)
+
+                    nevra = self._get_nevra(pkg)
+                    if nevra not in installed_nevra:
+                        group = GROUP_OTHER
+                        if pkgGroupDict.has_key(pkg.name):
+                            cg = pkgGroupDict[pkg.name]
+                            if groupMap.has_key(cg):
+                                group = groupMap[cg]
+                        if group == key:
+                            if self._do_extra_filtering(pkg, fltlist):
+                                package_list.append((pkg,INFO_AVAILABLE))
+
+        except yum.Errors.GroupError,e:
+            self._unlock_yum()
+            self.ErrorCode(ERROR_GROUP_NOT_FOUND, str(e))
+            self.Finished(EXIT_FAILED)
         except yum.Errors.RepoError,e:
             self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
@@ -473,6 +483,14 @@ class PackageKitYumBackend(PackageKitBaseBackend):
 
             return
 
+        # basename filter if specified
+        if FILTER_BASENAME in fltlist:
+            for (pkg,status) in self._basename_filter(package_list):
+                self._show_package(pkg,status)
+        else:
+            for (pkg,status) in package_list:
+                self._show_package(pkg,status)
+
         self._unlock_yum()
         self.Finished(EXIT_SUCCESS)
 
@@ -724,6 +742,11 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             #we might have a rounding error
             self.PercentageChanged(100)
 
+        except yum.Errors.RepoError,e:
+            self._unlock_yum()
+            self.ErrorCode(ERROR_REPO_CONFIGURATION_ERROR,str(e))
+            self.Finished(EXIT_FAILED)
+            self.Exit()
         except yum.Errors.YumBaseError, e:
             self._unlock_yum()
             # This should be a better-defined error, but I'm not sure
@@ -837,6 +860,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         Needed to be implemented in a sub class
         '''
         if inst_file.endswith('.src.rpm'):
+            self._unlock_yum()
             self.ErrorCode(ERROR_CANNOT_INSTALL_SOURCE_PACKAGE,'Backend will not install a src rpm file')
             self.Finished(EXIT_FAILED)
             return
@@ -1385,30 +1409,30 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             res = self.yumbase.searchGenerator(searchlist, [key])
             fltlist = filters.split(';')
 
-            available = []
-            count = 1
+            seen_nevra = [] # yum returns packages as available even when installed
+            pkg_list = [] # only do the second iteration on not installed pkgs
+            package_list = [] #we can't do emitting as found if we are post-processing
+
             for (pkg,values) in res:
                 if self._cancel_check("Search cancelled."):
                     return False
                 # are we installed?
                 if pkg.repo.id == 'installed':
-                    if FILTER_NOT_INSTALLED not in fltlist:
-                        if self._do_extra_filtering(pkg,fltlist):
-                            count+=1
-                            if count > 100:
-                                break
-                            self._show_package(pkg, INFO_INSTALLED)
+                    if self._do_extra_filtering(pkg,fltlist):
+                        package_list.append((pkg,INFO_INSTALLED))
+                        seen_nevra.append(self._get_nevra(pkg))
                 else:
-                    available.append(pkg)
+                    pkg_list.append(pkg)
 
-            # Now show available packages.
-            if FILTER_INSTALLED not in fltlist:
-                for pkg in available:
-                    if self._cancel_check("Search cancelled."):
-                        return False
-                    if self._do_extra_filtering(pkg,fltlist):
-                        self._show_package(pkg, INFO_AVAILABLE)
+            for pkg in pkg_list:
+                if self._cancel_check("Search cancelled."):
+                    return False
 
+                nevra = self._get_nevra(pkg)
+                if nevra not in seen_nevra:
+                    if self._do_extra_filtering(pkg,fltlist):
+                        package_list.append((pkg,INFO_AVAILABLE))
+                        seen_nevra.append(self._get_nevra(pkg))
         except yum.Errors.RepoError,e:
             self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
@@ -1417,13 +1441,22 @@ class PackageKitYumBackend(PackageKitBaseBackend):
 
             return False
 
+        # basename filter if specified
+        if FILTER_BASENAME in fltlist:
+            for (pkg,status) in self._basename_filter(package_list):
+                self._show_package(pkg,status)
+        else:
+            for (pkg,status) in package_list:
+                self._show_package(pkg,status)
+
         return True
 
     def _do_extra_filtering(self,pkg,filterList):
         ''' do extra filtering (gui,devel etc) '''
         for filter in filterList:
             if filter in (FILTER_INSTALLED, FILTER_NOT_INSTALLED):
-                continue
+                if not self._do_installed_filtering(filter,pkg):
+                    return False
             elif filter in (FILTER_GUI, FILTER_NOT_GUI):
                 if not self._do_gui_filtering(filter, pkg):
                     return False
@@ -1433,11 +1466,17 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             elif filter in (FILTER_FREE, FILTER_NOT_FREE):
                 if not self._do_free_filtering(filter, pkg):
                     return False
-            elif filter in (FILTER_BASENAME, FILTER_NOT_BASENAME):
-                if not self._do_basename_filtering(filter, pkg):
-                    return False
         return True
 
+    def _do_installed_filtering(self,flt,pkg):
+        isInstalled = False
+        if flt == FILTER_INSTALLED:
+            wantInstalled = True
+        else:
+            wantInstalled = False
+        isInstalled = pkg.repo.id == 'installed'
+        return isInstalled == wantInstalled
+
     def _do_gui_filtering(self,flt,pkg):
         isGUI = False
         if flt == FILTER_GUI:
@@ -1477,32 +1516,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
 
         return isFree == wantFree
 
-    def _do_basename_filtering(self,flt,pkg):
-        if flt == FILTER_BASENAME:
-            wantBase = True
-        else:
-            wantBase = False
-
-        isBase = self._check_basename(pkg)
-
-        return isBase == wantBase
 
-    def _check_basename(self, pkg):
-        '''
-        If a package does not have a source rpm (If that ever
-        happens), or it does have a source RPM, and the package's name
-        is the same as the source RPM's name, then we assume it is the
-        'base' package.
-        '''
-        basename = pkg.name
-
-        if pkg.sourcerpm:
-            basename = rpmUtils.miscutils.splitFilename(pkg.sourcerpm)[0]
-
-        if basename == pkg.name:
-            return True
-
-        return False
 
     def _is_development_repo(self, repo):
         if repo.endswith('-debuginfo'):
@@ -1576,28 +1590,41 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         '''
         find a package based on a package id (name;version;arch;repoid)
         '''
-        # Split up the id
-        (n,idver,a,d) = self.get_package_from_id(id)
-        # get e,v,r from package id version
-        e,v,r = self._getEVR(idver)
+        # is this an real id or just an name
+        if len(id.split(';')) > 1:
+            # Split up the id
+            (n,idver,a,d) = self.get_package_from_id(id)
+            # get e,v,r from package id version
+            e,v,r = self._getEVR(idver)
+        else:
+            n = id
+            e = v = r = a = None
         # search the rpmdb for the nevra
         pkgs = self.yumbase.rpmdb.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a)
-        # if the package is found, then return it
+        # if the package is found, then return it (do not have to match the repo_id)
         if len(pkgs) != 0:
             return pkgs[0],True
         # search the pkgSack for the nevra
-        pkgs = self.yumbase.pkgSack.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a)
-        # if the package is found, then return it
-        if len(pkgs) != 0:
-            return pkgs[0],False
-        else:
+        try:
+            pkgs = self.yumbase.pkgSack.searchNevra(name=n,epoch=e,ver=v,rel=r,arch=a)
+        except yum.Errors.RepoError,e:
+            self.error(ERROR_REPO_NOT_AVAILABLE,str(e))
+        # nothing found
+        if len(pkgs) == 0:
             return None,False
+        # one NEVRA in a single repo
+        if len(pkgs) == 1:
+            return pkgs[0],False
+        # we might have the same NEVRA in multiple repos, match by repo name
+        for pkg in pkgs:
+            if d == pkg.repoid:
+                return pkg,False
+        # repo id did not match
+        return None,False
 
     def _is_inst(self,pkg):
         return self.yumbase.rpmdb.installed(po=pkg)
 
-
-
     def _installable(self, pkg, ematch=False):
 
         """check if the package is reasonably installable, true/false"""
@@ -1764,6 +1791,57 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             return INFO_ENHANCEMENT
         else:
             return INFO_UNKNOWN
+    def _is_main_package(self,repo):
+        if repo.endswith('-debuginfo'):
+            return False
+        if repo.endswith('-devel'):
+            return False
+        if repo.endswith('-libs'):
+            return False
+        return True
+
+    def _basename_filter(self,package_list):
+        '''
+        Filter the list so that the number of packages are reduced.
+        This is done by only displaying gtk2 rather than gtk2-devel, gtk2-debuginfo, etc.
+        This imlementation is done by comparing the SRPM name, and if not falling back
+        to the first entry.
+        We have to fall back else we don't emit packages where the SRPM does not produce a
+        RPM with the same name, for instance, mono produces mono-core, mono-data and mono-winforms.
+        @package_list: a (pkg,status) list of packages
+        A new list is returned that has been filtered
+        '''
+        base_list = []
+        output_list = []
+        base_list_already_got = []
+
+        #find out the srpm name and add to a new array of compound data
+        for (pkg,status) in package_list:
+            if pkg.sourcerpm:
+                base = rpmUtils.miscutils.splitFilename(pkg.sourcerpm)[0]
+                base_list.append ((pkg,status,base,pkg.version));
+            else:
+                base_list.append ((pkg,status,'nosrpm',pkg.version));
+
+        #find all the packages that match thier basename name (done seporately so we get the "best" match)
+        for (pkg,status,base,version) in base_list:
+            if base == pkg.name and (base,version) not in base_list_already_got:
+                output_list.append((pkg,status))
+                base_list_already_got.append ((base,version))
+
+        #for all the ones not yet got, can we match against a non devel match?
+        for (pkg,status,base,version) in base_list:
+            if (base,version) not in base_list_already_got:
+                if self._is_main_package(pkg.name):
+                    output_list.append((pkg,status))
+                    base_list_already_got.append ((base,version))
+
+        #add the remainder of the packages, which should just be the single debuginfo's
+        for (pkg,status,base,version) in base_list:
+            if (base,version) not in base_list_already_got:
+                output_list.append((pkg,status))
+                base_list_already_got.append ((base,version))
+        return output_list
 
     def _get_obsoleted(self,name):
         obsoletes = self.yumbase.up.getObsoletesTuples( newest=1 )
commit 240c98e4a4df9b5c9af788330a8b9c21998b2659
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Mon May 12 13:05:31 2008 -0400

    Clean up a couple of error messages.

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index f76e27c..9aebf79 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -905,7 +905,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         if txmbrs:
             self._runYumTransaction()
         else:
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"This package could not be installed as it is already installed")
+            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,"The package is already installed")
 
     def _checkForNewer(self,po):
         pkgs = self.yumbase.pkgSack.returnNewestByName(name=po.name)
@@ -1003,7 +1003,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             return False
 
         if self._is_inst(po):
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED, "%s is already installed" % str(po))
+            self.error(ERROR_PACKAGE_ALREADY_INSTALLED, "The package %s is already installed" % str(po))
             return False
 
         if len(self.yumbase.conf.exclude) > 0:
commit 3d9353463e8b091ef486b704049e99784d49a54d
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed May 7 17:21:50 2008 +0200

    APT2: implement GetPackages

diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
index 8b69dd4..cd23e36 100755
--- a/backends/apt2/aptDBUSBackend.py
+++ b/backends/apt2/aptDBUSBackend.py
@@ -487,6 +487,28 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.PercentageChanged(100)
         self.Finished(EXIT_SUCCESS)
 
+    @threaded
+    def doGetPackages(self, filters):
+        '''
+        Implement the apt2-get-packages functionality
+        '''
+        pklog.info("Get all packages")
+        self.StatusChanged(STATUS_QUERY)
+        self.NoPercentageUpdates()
+        self._check_init(progress=False)
+        self.AllowCancel(True)
+
+        for pkg in self._cache:
+            if self._canceled.isSet():
+                self.ErrorCode(ERROR_TRANSACTION_CANCELLED,
+                               "The search was canceled")
+                self.Finished(EXIT_KILL)
+                self._canceled.clear()
+                return
+            elif self._is_package_visible(pkg, filters):
+                self._emit_package(pkg)
+        self.Finished(EXIT_SUCCESS)
+
     # Helpers
 
     def _open_cache(self, prange=(0,100), progress=True):
commit 1c398f55031e1ed2629cb81ed1c506fee424eace
Merge: cdc887c... c376670...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed May 7 13:47:41 2008 +0200

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit cdc887c1d61dad5e37ad1fd43414edb8ff57f438
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Tue Apr 8 11:16:02 2008 +0200

    APT-DBUS: do not segfault if xapian is not available. Perform a xapian test during initialisation

diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
index ce36696..01387ab 100755
--- a/backends/apt2/aptDBUSBackend.py
+++ b/backends/apt2/aptDBUSBackend.py
@@ -33,7 +33,6 @@ import dbus.glib
 import dbus.service
 import dbus.mainloop.glib
 import gobject
-import xapian
 
 from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded
 from packagekit.enums import *
@@ -45,10 +44,6 @@ PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
 XAPIANDBPATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index")
 XAPIANDB = XAPIANDBPATH + "/index"
 XAPIANDBVALUES = XAPIANDBPATH + "/values"
-DEFAULT_SEARCH_FLAGS = (xapian.QueryParser.FLAG_BOOLEAN |
-                        xapian.QueryParser.FLAG_PHRASE |
-                        xapian.QueryParser.FLAG_LOVEHATE |
-                        xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE)
 
 # Required for daemon mode
 os.putenv("PATH",
@@ -184,10 +179,18 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         pklog.info("Initializing APT backend")
         signal.signal(signal.SIGQUIT, sigquit)
         self._cache = None
-        self._xapian = None
         self._canceled = threading.Event()
         self._canceled.clear()
         self._locked = threading.Lock()
+        # Check for xapian support
+        self._use_xapian = False
+        try:
+            import xapian
+        except ImportError:
+            pass
+        else:
+            if os.access(XAPIANDB, os.R_OK):
+                self._use_xapian = True
         PackageKitBaseBackend.__init__(self, bus_name, dbus_path)
 
     # Methods ( client -> engine -> backend )
@@ -243,12 +246,16 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         self.AllowCancel(True)
         results = []
 
-        if os.access(XAPIANDB, os.R_OK):
+        if self._use_xapian == True:
+            search_flags = (xapian.QueryParser.FLAG_BOOLEAN |
+                            xapian.QueryParser.FLAG_PHRASE |
+                            xapian.QueryParser.FLAG_LOVEHATE |
+                            xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE)
             pklog.debug("Performing xapian db based search")
             db = xapian.Database(XAPIANDB)
             parser = xapian.QueryParser()
             query = parser.parse_query(unicode(search),
-                                       DEFAULT_SEARCH_FLAGS)
+                                       search_flags)
             enquire = xapian.Enquire(db)
             enquire.set_query(query)
             matches = enquire.get_mset(0, 1000)
commit eb566d7760280e353e666a62ff46f776a74cd9f4
Merge: 8b389ff... a90cd34...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Wed Apr 2 17:07:53 2008 +0200

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit 8b389ff97207bd7bed77d810bb3242850bd13817
Merge: 20d85e8... 1472b35...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Sat Mar 29 19:20:37 2008 +0100

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit 20d85e80d07bca65c549f14c0e3f916205f40dfd
Merge: 9513299... 52d8c92...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Mar 24 17:41:22 2008 +0100

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit 9513299f1f9865b856d8aa3329fa712780998e36
Merge: 8b653e4... b9833af...
Author: Sebastian Heinlein <sebi at glatzor.de>
Date:   Sun Mar 23 18:10:07 2008 +0100

    Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit

commit 8b653e4dc6662464f1ff80d7d7af8c1168f42b72
Author: Sebastian Heinlein <sebi at glatzor.de>
Date:   Sat Mar 22 15:48:07 2008 +0100

    APT-DUBS: Always perform a normal upgrade instead of dist-upgrade in doUpdateSystem. Clean up some fimxe statements.

diff --git a/backends/apt2/aptDBUSBackend.py b/backends/apt2/aptDBUSBackend.py
index bfc322b..ce36696 100755
--- a/backends/apt2/aptDBUSBackend.py
+++ b/backends/apt2/aptDBUSBackend.py
@@ -341,16 +341,13 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         '''
         Implement the {backend}-update-system functionality
         '''
-        #FIXME: Better exception and error handling
-        #FIXME: Distupgrade or Upgrade?
-        #FIXME: Handle progress in a more sane way
         pklog.info("Upgrading system")
         self.StatusChanged(STATUS_UPDATE)
         self.AllowCancel(False)
         self.PercentageChanged(0)
         self._check_init(prange=(0,5))
         try:
-            self._cache.upgrade(distUpgrade=True)
+            self._cache.upgrade(distUpgrade=False)
             self._cache.commit(PackageKitFetchProgress(self, prange=(5,50)),
                                PackageKitInstallProgress(self, prange=(50,95)))
         except apt.cache.FetchFailedException:
@@ -378,7 +375,6 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         '''
         Implement the {backend}-remove functionality
         '''
-        #FIXME: Handle progress in a more sane way
         pklog.info("Removing package with id %s" % id)
         self.StatusChanged(STATUS_REMOVE)
         self.AllowCancel(False)
@@ -419,7 +415,6 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         '''
         Implement the {backend}-install functionality
         '''
-        #FIXME: Handle progress in a more sane way
         pklog.info("Installing package with id %s" % id)
         self.StatusChanged(STATUS_INSTALL)
         self.AllowCancel(False)


More information about the PackageKit-commit mailing list