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

Richard Hughes hughsient at kemper.freedesktop.org
Tue Feb 9 12:06:51 PST 2010


 backends/entropy/TODO                        |   25 
 backends/entropy/entropyBackend.py           |  198 +++++-
 backends/entropy/pk-backend-entropy.c        |  118 +++
 backends/portage/pk-backend-portage.c        |   93 ++
 backends/portage/portageBackend.py           |   34 +
 contrib/PackageKit.spec.in                   |    3 
 lib/packagekit-glib2/Makefile.am             |    2 
 lib/packagekit-glib2/pk-category.c           |  170 +++++
 lib/packagekit-glib2/pk-category.h           |   17 
 lib/packagekit-qt/src/Makefile.am            |   47 +
 lib/packagekit-qt/src/client.cpp             |  136 ++--
 lib/packagekit-qt/src/client.h               |  380 +-----------
 lib/packagekit-qt/src/clientprivate.cpp      |    7 
 lib/packagekit-qt/src/clientprivate.h        |    5 
 lib/packagekit-qt/src/daemonproxy.cpp        |   18 
 lib/packagekit-qt/src/daemonproxy.h          |  202 ------
 lib/packagekit-qt/src/enum.cpp               |    9 
 lib/packagekit-qt/src/enum.h                 |  420 +++++++++++++
 lib/packagekit-qt/src/package.cpp            |   25 
 lib/packagekit-qt/src/package.h              |   16 
 lib/packagekit-qt/src/transaction.cpp        |   45 +
 lib/packagekit-qt/src/transaction.h          |  102 ---
 lib/packagekit-qt/src/transactionprivate.cpp |   22 
 lib/packagekit-qt/src/transactionprivate.h   |   10 
 lib/packagekit-qt/src/transactionproxy.cpp   |   19 
 lib/packagekit-qt/src/transactionproxy.h     |  412 -------------
 lib/packagekit-qt/src/util.cpp               |    8 
 lib/packagekit-qt/src/util.h                 |    2 
 lib/packagekit-qt/test/daemontest.cpp        |   16 
 lib/packagekit-qt/test/main.cpp              |    4 
 lib/packagekit-qt/test/transactiontest.cpp   |    8 
 po/hu.po                                     |  843 ++++++++++++++-------------
 src/pk-backend-internal.h                    |    1 
 src/pk-backend-spawn.c                       |  183 +++--
 src/pk-backend.c                             |   31 
 35 files changed, 1877 insertions(+), 1754 deletions(-)

New commits:
commit 76685bb09b671fe3cb99523a64da02a27531c632
Author: Adrien Bustany <madcat at mymadcat.com>
Date:   Tue Feb 9 16:20:52 2010 -0300

    PackageKit-Qt: Hopefully fix moc files generation

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index 271c4b6..1b05c4f 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -11,6 +11,16 @@ INCLUDES = \
 
 METASOURCES = AUTO
 
+MOCFILES =								\
+	client.moc							\
+	clientprivate.moc					\
+	daemonproxy.moc						\
+	transactionproxy.moc				\
+	transaction.moc						\
+	transactionprivate.moc				\
+	enum.moc							\
+	$(NULL)
+
 lib_LTLIBRARIES =						\
 	libpackagekit-qt.la					\
 	$(NULL)
@@ -75,14 +85,7 @@ clean-local:
 	rm -f $(CLEANFILES)
 
 EXTRA_DIST =							\
-	client.moc						\
-	clientprivate.moc					\
-	daemonproxy.moc						\
-	enum.moc						\
-	package.moc						\
-	transaction.moc						\
-	transactionprivate.moc					\
-	transactionproxy.moc					\
+	$(MOCFILES)							\
 	dbus_proxies.stamp                  \
 	daemonproxy.h						\
 	daemonproxy.cpp						\
@@ -98,7 +101,10 @@ MAINTAINERCLEANFILES =						\
 	daemonproxy.cpp							\
 	$(NULL)
 
-BUILT_SOURCES=dbus_proxies.stamp
+BUILT_SOURCES=								\
+	dbus_proxies.stamp						\
+	$(MOCFILES)								\
+	$(NULL)
 
 dbus_proxies.stamp: ${top_srcdir}/src/org.freedesktop.PackageKit.xml ${top_srcdir}/src/org.freedesktop.PackageKit.Transaction.xml
 	qdbusxml2cpp -c DaemonProxy -p daemonproxy -m -N ${top_srcdir}/src/org.freedesktop.PackageKit.xml
commit fd11637619930245541ce842284ea55067f5cb3a
Author: Adrien Bustany <madcat at mymadcat.com>
Date:   Tue Feb 9 15:23:54 2010 -0300

    Revert "pk-qt: fixed some small issues with makefiles"
    
    This reverts commit 3c3fd76a09a71b16c0bc05e3448fa6b784a4a241.
    
    Conflicts:
    
    	lib/packagekit-qt/src/Makefile.am

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index b8a22e9..271c4b6 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -78,6 +78,7 @@ EXTRA_DIST =							\
 	client.moc						\
 	clientprivate.moc					\
 	daemonproxy.moc						\
+	enum.moc						\
 	package.moc						\
 	transaction.moc						\
 	transactionprivate.moc					\
diff --git a/lib/packagekit-qt/src/enum.cpp b/lib/packagekit-qt/src/enum.cpp
new file mode 100644
index 0000000..989d2c2
--- /dev/null
+++ b/lib/packagekit-qt/src/enum.cpp
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the QPackageKit project
+ * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "enum.h"
+#include "enum.moc"
+
commit 44273daa7b23c093becd3e23233282e4dec02e25
Author: Adrien Bustany <madcat at mymadcat.com>
Date:   Tue Feb 9 15:14:12 2010 -0300

    PackageKit-Qt: Fix Makefile.am for generated files
    
    The switch to fully generated proxies introduced a bug where generated files
    wouldn't be shipped or updated correctly, breaking make distcheck.

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index 2467377..b8a22e9 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -48,6 +48,8 @@ libpackagekit_qt_la_SOURCES =					\
 	bitfield.h						\
 	bitfield.cpp						\
 	enum.h							\
+	enum.cpp							\
+	dbus_proxies.stamp				\
 	$(NULL)
 
 libpackagekit_qt_la_LIBADD =					\
@@ -81,6 +83,10 @@ EXTRA_DIST =							\
 	transactionprivate.moc					\
 	transactionproxy.moc					\
 	dbus_proxies.stamp                  \
+	daemonproxy.h						\
+	daemonproxy.cpp						\
+	transactionproxy.h					\
+	transactionproxy.cpp				\
 	$(NULL)
 
 MAINTAINERCLEANFILES =						\
@@ -96,3 +102,5 @@ BUILT_SOURCES=dbus_proxies.stamp
 dbus_proxies.stamp: ${top_srcdir}/src/org.freedesktop.PackageKit.xml ${top_srcdir}/src/org.freedesktop.PackageKit.Transaction.xml
 	qdbusxml2cpp -c DaemonProxy -p daemonproxy -m -N ${top_srcdir}/src/org.freedesktop.PackageKit.xml
 	qdbusxml2cpp -c TransactionProxy -p transactionproxy -m -N ${top_srcdir}/src/org.freedesktop.PackageKit.Transaction.xml
+	touch $@
+
commit 0d1713e7f9adc439921c0aac647a80c1e22c6d3e
Merge: 3c3fd76... 31f2130...
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Tue Feb 9 15:11:21 2010 -0200

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

commit 3c3fd76a09a71b16c0bc05e3448fa6b784a4a241
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Tue Feb 9 15:10:47 2010 -0200

    pk-qt: fixed some small issues with makefiles

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index 8b79557..2467377 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -48,7 +48,6 @@ libpackagekit_qt_la_SOURCES =					\
 	bitfield.h						\
 	bitfield.cpp						\
 	enum.h							\
-	enum.cpp							\
 	$(NULL)
 
 libpackagekit_qt_la_LIBADD =					\
@@ -77,7 +76,6 @@ EXTRA_DIST =							\
 	client.moc						\
 	clientprivate.moc					\
 	daemonproxy.moc						\
-	enum.moc						\
 	package.moc						\
 	transaction.moc						\
 	transactionprivate.moc					\
diff --git a/lib/packagekit-qt/src/enum.cpp b/lib/packagekit-qt/src/enum.cpp
deleted file mode 100644
index 989d2c2..0000000
--- a/lib/packagekit-qt/src/enum.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of the QPackageKit project
- * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "enum.h"
-#include "enum.moc"
-
commit 31f21308ec1d695d8ea9d73c3af0c65a07c9025d
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 16:01:51 2010 +0100

    entropy: implement EULA handling on pkgs install

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index f65eb03..c5b8866 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -63,7 +63,7 @@ from entropy.fetchers import UrlFetcher
 
 import entropy.tools
 
-PK_DEBUG = True
+PK_DEBUG = False
 
 class PackageKitEntropyMixin(object):
 
@@ -526,13 +526,17 @@ class PackageKitEntropyMixin(object):
         self.percentage(0)
         self.status(STATUS_DOWNLOAD)
 
-        """
-        # FIXME: need to have fixed backend API first
-
         # Before even starting the fetch
         # make sure that the user accepts their licenses
         # send license signal afterwards
         licenses = self._entropy.get_licenses_to_accept(run_queue)
+        if licenses:
+            # as per PackageKit specs
+            accepted_eulas = os.getenv("accepted_eulas", "").split(";")
+            for eula_id in accepted_eulas:
+                if eula_id in licenses:
+                    licenses.pop(eula_id)
+                    self._entropy.installed_repository().acceptLicense(eula_id)
 
         for eula_id, eula_pkgs in licenses.items():
             for pkg_id, repo_id in eula_pkgs:
@@ -542,8 +546,6 @@ class PackageKitEntropyMixin(object):
                 license_agreement = pkg_c_repo.retrieveLicenseText(eula_id)
                 self.eula_required(eula_id, pk_pkg, vendor_name,
                     license_agreement)
-                # TODO remove here
-                # self._entropy.installed_repository().acceptLicense(eula_id)
 
         if licenses:
             # bye bye, user will have to accept it and get here again
@@ -551,7 +553,6 @@ class PackageKitEntropyMixin(object):
                 "Following EULAs are not accepted: %s" % (
                     ' '.join(licenses.keys()),))
             return
-        """
 
         # used in case of errors
         match_map = {}
commit 92a84e44af215bc234d6c598afa5a2a954223baf
Merge: e2da1ce... 483bfd0...
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:51:43 2010 +0100

    Merge remote branch 'official/master'

commit e2da1ce18330721cdf53bae8c4b50bff908e30d4
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:50:10 2010 +0100

    portage: add basic simulate_* backend support (backend needs refactoring first)

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index d745750..61a5cb2 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -117,6 +117,49 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
+ * backend_get_roles:
+ */
+static PkBitfield
+backend_get_roles (PkBackend *backend)
+{
+    PkBitfield roles;
+    roles = pk_bitfield_from_enums (
+        PK_ROLE_ENUM_CANCEL,
+        PK_ROLE_ENUM_GET_DEPENDS,
+        PK_ROLE_ENUM_GET_DETAILS,
+        PK_ROLE_ENUM_GET_FILES,
+        PK_ROLE_ENUM_GET_REQUIRES,
+        PK_ROLE_ENUM_GET_PACKAGES,
+        //PK_ROLE_ENUM_WHAT_PROVIDES,
+        PK_ROLE_ENUM_GET_UPDATES,
+        PK_ROLE_ENUM_GET_UPDATE_DETAIL,
+        PK_ROLE_ENUM_INSTALL_PACKAGES,
+        //PK_ROLE_ENUM_INSTALL_FILES,
+        //PK_ROLE_ENUM_INSTALL_SIGNATURE,
+        PK_ROLE_ENUM_REFRESH_CACHE,
+        PK_ROLE_ENUM_REMOVE_PACKAGES,
+        //PK_ROLE_ENUM_DOWNLOAD_PACKAGES,
+        PK_ROLE_ENUM_RESOLVE,
+        PK_ROLE_ENUM_SEARCH_DETAILS,
+        PK_ROLE_ENUM_SEARCH_FILE,
+        PK_ROLE_ENUM_SEARCH_GROUP,
+        PK_ROLE_ENUM_SEARCH_NAME,
+        PK_ROLE_ENUM_UPDATE_PACKAGES,
+        PK_ROLE_ENUM_UPDATE_SYSTEM,
+        PK_ROLE_ENUM_GET_REPO_LIST,
+        PK_ROLE_ENUM_REPO_ENABLE,
+        //PK_ROLE_ENUM_REPO_SET_DATA,
+        //PK_ROLE_ENUM_GET_CATEGORIES,
+        //PK_ROLE_ENUM_SIMULATE_INSTALL_FILES,
+        PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES,
+        PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES,
+        PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES,
+        -1);
+
+    return roles;
+}
+
+/**
  * backend_cancel:
  */
 static void
@@ -391,7 +434,49 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, "foo", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+}
+
+/**
+ * backend_simulate_remove_packages:
+ */
+static void
+backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = pk_package_ids_to_string (package_ids);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-remove-packages", package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_update_packages:
+ */
+static void
+backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = pk_package_ids_to_string (package_ids);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-update-packages", package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_install_packages:
+ */
+static void
+backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = pk_package_ids_to_string (package_ids);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-install-packages", package_ids_temp, NULL);
+    g_free (package_ids_temp);
 }
 
 PK_BACKEND_OPTIONS (
@@ -401,7 +486,7 @@ PK_BACKEND_OPTIONS (
 	backend_destroy,			/* destroy */
 	backend_get_groups,			/* get_groups */
 	backend_get_filters,			/* get_filters */
-	NULL,					/* get_roles */
+	backend_get_roles,					/* get_roles */
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	NULL,					/* download_packages */
@@ -432,8 +517,8 @@ PK_BACKEND_OPTIONS (
 	backend_update_system,			/* update_system */
 	NULL,					/* what_provides */
 	NULL,					/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+    backend_simulate_install_packages,  /* simulate_install_packages */
+    backend_simulate_remove_packages,   /* simulate_remove_packages */
+    backend_simulate_update_packages    /* simulate_update_packages */
 );
 
diff --git a/backends/portage/portageBackend.py b/backends/portage/portageBackend.py
index c250abd..2ae8c64 100755
--- a/backends/portage/portageBackend.py
+++ b/backends/portage/portageBackend.py
@@ -1,4 +1,5 @@
 #!/usr/bin/python
+# -*- coding: utf-8 -*-
 # vim:set shiftwidth=4 tabstop=4 expandtab:
 #
 # Copyright (C) 2009 Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
@@ -1207,10 +1208,18 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
                 for cpv in cpv_updates[cp][slot]:
                     self.package(cpv, INFO_NORMAL)
 
+    def simulate_install_packages(self, pkgs):
+        return self._install_packages(False, pkgs, simulate=True)
+
     def install_packages(self, only_trusted, pkgs):
+        return self._install_packages(False, pkgs)
+
+    def _install_packages(self, only_trusted, pkgs, simulate=False):
         # NOTES:
         # can't install an already installed packages
         # even if it happens to be needed in Gentoo but probably not this API
+        # TODO: every merged pkg should emit self.package()
+        #       see around _emerge.Scheduler.Scheduler
 
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
@@ -1261,6 +1270,9 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
 
         self.status(STATUS_INSTALL)
 
+        if simulate:
+            return
+
         # get elog messages
         portage.elog.add_listener(self.elog_listener)
 
@@ -1318,6 +1330,14 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
             self.unblock_output()
 
     def remove_packages(self, allowdep, autoremove, pkgs):
+        return self._remove_packages(allowdep, autoremove, pkgs)
+
+    def simulate_remove_packages(self, pkgs):
+        return self._remove_packages(True, False, pkgs, simulate=True)
+
+    def _remove_packages(self, allowdep, autoremove, pkgs, simulate=False):
+        # TODO: every to-be-removed pkg should emit self.package()
+        #       see around _emerge.Scheduler.Scheduler
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
         self.percentage(None)
@@ -1395,6 +1415,9 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
                     operation="uninstall")
             packages.append(package)
 
+        if simulate:
+            return
+
         # need to define favorites to remove packages from world set
         favorites = []
         for p in packages:
@@ -1674,8 +1697,16 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
         self.percentage(100)
 
     def update_packages(self, only_trusted, pkgs):
+        return self._update_packages(only_trusted, pkgs)
+
+    def simulate_update_packages(self, pkgs):
+        return self._update_packages(False, pkgs, simulate=True)
+
+    def _update_packages(self, only_trusted, pkgs, simulate=False):
         # TODO: manage errors
         # TODO: manage config file updates
+        # TODO: every updated pkg should emit self.package()
+        #       see around _emerge.Scheduler.Scheduler
 
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
@@ -1721,6 +1752,9 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
 
         self.status(STATUS_INSTALL)
 
+        if simulate:
+            return
+
         # get elog messages
         portage.elog.add_listener(self.elog_listener)
 
commit 2a0c2d80ccb8a41d2c95e934a8ffc01b7783ff94
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:41:26 2010 +0100

    entropy: add simulate_* support

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index 06fe0e2..2fb9107 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -2,33 +2,10 @@ Entropy PackageKit backend developers' TODO:
 
     - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
         FILTER_DEVELOPMENT, FILTER_VISIBLE
-    - add get_mime_types, install_files, simulate_* support, repo_set_data
+    - add what_provides, repo_set_data
     - bind get_distro_upgrades to branch hop?
     - sys-apps/entropy is a syspkg
     - messages? how push output to stdout?
     - license dialog??
 
-What is currently implemented:
-    Y get-actions
-    Y get-groups
-    Y get-filters
-    Y get-transactions
-    Y get-time
-    Y search [name|details|group|file] [data]
-    Y install [packages]
-    Y remove [package]
-    Y update <package>
-    Y update-system
-    Y refresh
-    Y resolve [package]
-    Y get-updates
-    Y get-depends [package]
-    Y get-requires [package]
-    Y get-details [package]
-    Y get-files [package]
-    Y get-update-detail [package]
-    Y get-packages
-    Y repo-list
-    Y repo-enable [repo_id]
-    Y repo-disable [repo_id]
 
diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 8a47648..f65eb03 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -40,7 +40,7 @@ from packagekit.backend import PackageKitBaseBackend, \
     GROUP_MULTIMEDIA, GROUP_NETWORK, GROUP_OFFICE, GROUP_SCIENCE, \
     GROUP_SYSTEM, GROUP_SECURITY, GROUP_OTHER, GROUP_DESKTOP_XFCE, \
     GROUP_UNKNOWN, INFO_IMPORTANT, INFO_NORMAL, INFO_DOWNLOADING, \
-    INFO_INSTALLED, \
+    INFO_INSTALLED, INFO_REMOVING, INFO_INSTALLING, \
     INFO_AVAILABLE, get_package_id, split_package_id, MESSAGE_UNKNOWN, \
     MESSAGE_AUTOREMOVE_IGNORED, MESSAGE_CONFIG_FILES_CHANGED, STATUS_INFO, \
     MESSAGE_COULD_NOT_FIND_PACKAGE, MESSAGE_REPO_METADATA_DOWNLOAD_FAILED, \
@@ -51,6 +51,7 @@ from packagekit.backend import PackageKitBaseBackend, \
 from packagekit.package import PackagekitPackage
 
 sys.path.insert(0, '/usr/lib/entropy/libraries')
+from entropy.output import decolorize
 from entropy.i18n import _, _LOCALE
 from entropy.const import etpConst, const_convert_to_rawstring, \
     const_convert_to_unicode, const_get_stringtype
@@ -62,7 +63,7 @@ from entropy.fetchers import UrlFetcher
 
 import entropy.tools
 
-PK_DEBUG = False
+PK_DEBUG = True
 
 class PackageKitEntropyMixin(object):
 
@@ -367,7 +368,8 @@ class PackageKitEntropyMixin(object):
             cat_desc = cat_desc_data['en']
         return cat_desc
 
-    def _execute_etp_pkgs_remove(self, pkgs, allowdep, autoremove):
+    def _execute_etp_pkgs_remove(self, pkgs, allowdep, autoremove,
+        simulate = False):
         """
         Execute effective removal (including dep calculation).
 
@@ -387,6 +389,8 @@ class PackageKitEntropyMixin(object):
             it might download libneon as a dependency. When auto_remove
             is set to true, and you remove OpenOffice then libneon
             will also get removed automatically.
+        @keyword simulate: simulate removal if True
+        @type simulate: bool
         @type autoremove: bool
         """
 
@@ -436,6 +440,12 @@ class PackageKitEntropyMixin(object):
                 percent,))
 
             self.percentage(percent)
+            pkg_id, pkg_c_repo, pk_pkg = match_map.get(pkg_id)
+            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
+            self.package(pk_pkg, INFO_REMOVING, pkg_desc)
+
+            if simulate:
+                continue
 
             metaopts = {}
             metaopts['removeconfig'] = False
@@ -462,7 +472,7 @@ class PackageKitEntropyMixin(object):
             fetch_path = directory, calculate_deps = False)
 
     def _execute_etp_pkgs_install(self, pkgs, only_trusted, only_fetch = False,
-        fetch_path = None, calculate_deps = True):
+        fetch_path = None, calculate_deps = True, simulate = False):
         """
         Execute effective install (including dep calculation).
 
@@ -471,6 +481,15 @@ class PackageKitEntropyMixin(object):
         @type pkgs: list
         @param only_trusted: only accept trusted pkgs?
         @type only_trusted: bool
+        @keyword only_fetch: just fetch packages if True
+        @type only_fetch: bool
+        @keyword fetch_path: path where to store downloaded packages
+        @type fetch_path: string
+        @keyword calculate_deps: calculate package dependencies if true and
+            add them to queue
+        @type calculate_deps: bool
+        @keyword simulate: simulate actions if True
+        @type simulate: bool
         """
         self.percentage(0)
         self.status(STATUS_RUNNING)
@@ -556,6 +575,14 @@ class PackageKitEntropyMixin(object):
                 percent,))
 
             self.percentage(percent)
+
+            pkg_id, pkg_c_repo, pk_pkg = match_map.get(match)
+            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
+            self.package(pk_pkg, INFO_DOWNLOADING, pkg_desc)
+
+            if simulate:
+                continue
+
             metaopts = {
                 'dochecksum': True,
             }
@@ -568,11 +595,6 @@ class PackageKitEntropyMixin(object):
             obj = down_data.setdefault(myrepo, set())
             obj.add(entropy.tools.dep_getkey(package.pkgmeta['atom']))
 
-            pkg_id, pkg_c_repo, pk_pkg = match_map.get(match)
-            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
-            # show pkg
-            self.package(pk_pkg, INFO_DOWNLOADING, pkg_desc)
-
             x_rc = package.run()
             if x_rc != 0:
                 self.error(ERROR_PACKAGE_FAILED_TO_CONFIGURE,
@@ -586,7 +608,8 @@ class PackageKitEntropyMixin(object):
             del package
 
         # spawn UGC
-        self._etp_spawn_ugc(down_data)
+        if not simulate:
+            self._etp_spawn_ugc(down_data)
 
         self.percentage(100)
         if only_fetch:
@@ -606,6 +629,13 @@ class PackageKitEntropyMixin(object):
 
             self.percentage(percent)
 
+            pkg_id, pkg_c_repo, pk_pkg = match_map.get(match)
+            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
+            self.package(pk_pkg, INFO_INSTALLING, pkg_desc)
+
+            if simulate:
+                continue
+
             metaopts = {
                 'removeconfig': False,
             }
@@ -616,11 +646,6 @@ class PackageKitEntropyMixin(object):
                 metaopts['install_source'] = \
                     etpConst['install_sources']['automatic_dependency']
 
-            pkg_id, pkg_c_repo, pk_pkg = match_map.get(match)
-            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
-            # show pkg
-            self.package(pk_pkg, INFO_INSTALLING, pkg_desc)
-
             package = self._entropy.Package()
             package.prepare(match, "install", metaopts)
 
@@ -754,7 +779,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
     def _generic_message(self, message):
         # FIXME: this doesn't work, it seems there's no way to
         # print something to user while pkcon runs.
-        self.message(MESSAGE_UNKNOWN, message)
+        # self.message(MESSAGE_UNKNOWN, message)
+        self._log_message(__name__, "_generic_message:", decolorize(message))
 
     def _config_files_message(self):
         scandata = self._entropy.FileUpdates.scanfs(dcache = True,
@@ -1188,9 +1214,15 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self.percentage(100)
 
     def install_files(self, only_trusted, inst_files):
+        return self._install_files(only_trusted, inst_files)
 
-        self._log_message(__name__, "install_files: got", only_trusted, "and",
-            inst_files)
+    def simulate_install_files(self, inst_files):
+        return self._install_files(False, inst_files, simulate = True)
+
+    def _install_files(self, only_trusted, inst_files, simulate = False):
+
+        self._log_message(__name__, "install_files: got", only_trusted,
+            "and", inst_files, "and", simulate)
 
         self.allow_cancel(True)
         self.status(STATUS_RUNNING)
@@ -1231,12 +1263,12 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             pk_pkg = self._etp_to_id(pkg)
             pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-        self._execute_etp_pkgs_install(pkgs, only_trusted)
+        self._execute_etp_pkgs_install(pkgs, only_trusted, simulate = simulate)
 
-    def install_packages(self, only_trusted, pk_pkgs):
+    def _install_packages(self, only_trusted, pk_pkgs, simulate = False):
 
-        self._log_message(__name__, "install_packages: got %s and %s" % (
-            only_trusted, pk_pkgs,))
+        self._log_message(__name__, "install_packages: got", only_trusted,
+            "and", pk_pkgs, "and", simulate)
 
         self.status(STATUS_RUNNING)
         self.allow_cancel(True)
@@ -1250,7 +1282,13 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 continue
             pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-        self._execute_etp_pkgs_install(pkgs, only_trusted)
+        self._execute_etp_pkgs_install(pkgs, only_trusted, simulate = simulate)
+
+    def install_packages(self, only_trusted, pk_pkgs):
+        return self._install_packages(only_trusted, pk_pkgs)
+
+    def simulate_install_packages(self, pk_pkgs):
+        return self._install_packages(False, pk_pkgs, simulate = True)
 
     def download_packages(self, directory, pk_pkgs):
 
@@ -1303,6 +1341,12 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self.percentage(100)
 
     def remove_packages(self, allowdep, autoremove, pk_pkgs):
+        return self._remove_packages(allowdep, autoremove, pk_pkgs)
+
+    def simulate_remove_packages(self, pk_pkgs):
+        return self._remove_packages(True, False, pk_pkgs, simulate = True)
+
+    def _remove_packages(self, allowdep, autoremove, pk_pkgs, simulate = False):
 
         self._log_message(__name__, "remove_packages: got %s and %s and %s" % (
             allowdep, autoremove, pk_pkgs,))
@@ -1319,7 +1363,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 continue
             pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-        self._execute_etp_pkgs_remove(pkgs, allowdep, autoremove)
+        self._execute_etp_pkgs_remove(pkgs, allowdep, autoremove,
+            simulate = simulate)
 
     def repo_enable(self, repoid, enable):
 
@@ -1562,9 +1607,15 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self.percentage(100)
 
     def update_packages(self, only_trusted, pk_pkgs):
+        return self._update_packages(only_trusted, pk_pkgs)
+
+    def simulate_update_packages(self, pk_pkgs):
+        return self._update_packages(False, pk_pkgs, simulate = True)
 
-        self._log_message(__name__, "update_packages: got %s and %s" % (
-            only_trusted, pk_pkgs,))
+    def _update_packages(self, only_trusted, pk_pkgs, simulate = False):
+
+        self._log_message(__name__, "update_packages: got", only_trusted,
+            "and", pk_pkgs, "and", simulate)
 
         self.status(STATUS_RUNNING)
         self.allow_cancel(True)
@@ -1578,7 +1629,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 continue
             pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-        self._execute_etp_pkgs_install(pkgs, only_trusted)
+        self._execute_etp_pkgs_install(pkgs, only_trusted, simulate = simulate)
 
     def update_system(self, only_trusted):
 
diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 223420a..5bed57b 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -150,10 +150,10 @@ backend_get_roles (PkBackend *backend)
 		PK_ROLE_ENUM_REPO_ENABLE,
 		//PK_ROLE_ENUM_REPO_SET_DATA,
 		PK_ROLE_ENUM_GET_CATEGORIES,
-		//PK_ROLE_ENUM_SIMULATE_INSTALL_FILES,
-		//PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES,
-		//PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES,
-		//PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES,
+		PK_ROLE_ENUM_SIMULATE_INSTALL_FILES,
+		PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES,
+		PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES,
+		PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES,
 		-1);
 
 	return roles;
@@ -502,6 +502,62 @@ backend_update_system (PkBackend *backend, gboolean only_trusted)
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
+/**
+ * backend_simulate_remove_packages:
+ */
+static void
+backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = pk_package_ids_to_string (package_ids);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-remove-packages", package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_update_packages:
+ */
+static void
+backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = pk_package_ids_to_string (package_ids);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-update-packages", package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_install_packages:
+ */
+static void
+backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = pk_package_ids_to_string (package_ids);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-install-packages", package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_install_files:
+ */
+static void
+backend_simulate_install_files (PkBackend *backend, gchar **full_paths)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = g_strjoinv (PK_BACKEND_SPAWN_FILENAME_DELIM, full_paths);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "simulate-install-files", package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
 PK_BACKEND_OPTIONS (
 	"Entropy",				/* description */
 	"Fabio Erculiani (lxnay) <lxnay at sabayon.org>",	/* author */
@@ -539,9 +595,9 @@ PK_BACKEND_OPTIONS (
 	backend_update_packages,			/* update_packages */
 	backend_update_system,				/* update_system */
 	NULL,								/* what_provides */
-	NULL,								/* simulate_install_files */
-	NULL,								/* simulate_install_packages */
-	NULL,								/* simulate_remove_packages */
-	NULL								/* simulate_update_packages */
+	backend_simulate_install_files,	    /* simulate_install_files */
+	backend_simulate_install_packages,  /* simulate_install_packages */
+	backend_simulate_remove_packages,   /* simulate_remove_packages */
+	backend_simulate_update_packages    /* simulate_update_packages */
 );
 
commit 56660f059f825af81942e832ba7f5ca516dfe037
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:27:53 2010 +0100

    entropy: disable backend_what_provides by default

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 08c6219..223420a 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -194,7 +194,6 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 
 /**
  * backend_what_provides:
- */
 static void
 backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
 {
@@ -208,6 +207,7 @@ backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum pr
     g_free (filters_text);
     g_free (search);
 }
+ */
 
 /**
  * pk_backend_get_categories:
commit c5e483482fd6eb9b90e6764b761712faad363f5a
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:26:43 2010 +0100

    entropy: add stubby EntropyPackageKitBackend.what_provides()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index d7aca6b..8a47648 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -1607,6 +1607,23 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self._execute_etp_pkgs_install(pkgs, only_trusted)
 
+    def what_provides(self, filters, provides_type, values):
+
+        # FIXME: implement this
+        """
+        PROVIDES_ANY = "any"
+        PROVIDES_CODEC = "codec"
+        PROVIDES_FONT = "font"
+        PROVIDES_HARDWARE_DRIVER = "driver"
+        PROVIDES_MIMETYPE = "mimetype"
+        PROVIDES_MODALIAS = "modalias"
+        PROVIDES_POSTSCRIPT_DRIVER = "postscript-driver"
+        PROVIDES_UNKNOWN = "unknown"
+        """
+
+        self._log_message(__name__, "what_provides: got", filters,
+            "and", provides_type, "and", values)
+
 def main():
     backend = PackageKitEntropyBackend("")
     backend.dispatcher(sys.argv[1:])
commit 483bfd01027719fdbd1028faaf7496ebd5b60f06
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 9 14:19:08 2010 +0000

    Add the environment variable accecpted_eulas to the spawned processes

diff --git a/src/pk-backend-internal.h b/src/pk-backend-internal.h
index 9b5fa77..7452e6b 100644
--- a/src/pk-backend-internal.h
+++ b/src/pk-backend-internal.h
@@ -76,6 +76,7 @@ PkBitfield	 pk_backend_get_roles			(PkBackend	*backend);
 gchar		*pk_backend_get_mime_types		(PkBackend	*backend);
 gboolean	 pk_backend_is_implemented		(PkBackend	*backend,
 							 PkRoleEnum	 role);
+gchar		*pk_backend_get_accepted_eula_string	(PkBackend	*backend);
 void		pk_backend_cancel			(PkBackend	*backend);
 void		pk_backend_download_packages		(PkBackend	*backend,
 							 gchar		**package_ids,
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 87c3e16..19af668 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -611,6 +611,7 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	gchar *locale;
 	gchar *line;
 	gchar *uri;
+	gchar *eulas;
 	gchar *transaction_id;
 	guint i;
 	GPtrArray *array;
@@ -627,6 +628,13 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	line = g_strdup_printf ("%s=%s", "transaction_id", transaction_id);
 	g_ptr_array_add (array, line);
 
+	/* accepted eulas */
+	eulas = pk_backend_get_accepted_eula_string (priv->backend);
+	if (eulas != NULL){
+		line = g_strdup_printf ("%s=%s", "accepted_eulas", eulas);
+		g_ptr_array_add (array, line);
+	}
+
 	/* http_proxy */
 	proxy_http = pk_backend_get_proxy_http (priv->backend);
 	if (!egg_strzero (proxy_http)) {
@@ -682,6 +690,7 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	g_free (proxy_http);
 	g_free (proxy_ftp);
 	g_free (locale);
+	g_free (eulas);
 	g_free (transaction_id);
 	return envp;
 }
diff --git a/src/pk-backend.c b/src/pk-backend.c
index b508d94..5a8de06 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -2217,6 +2217,37 @@ pk_backend_is_eula_valid (PkBackend *backend, const gchar *eula_id)
 }
 
 /**
+ * pk_backend_is_eula_valid:
+ */
+gchar *
+pk_backend_get_accepted_eula_string (PkBackend *backend)
+{
+	GString *string;
+	gchar *result = NULL;
+	GList *keys = NULL;
+	GList *l;
+
+	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
+
+	/* optimise for the common case */
+	if (g_hash_table_size (backend->priv->eulas) == 0)
+		goto out;
+
+	/* create a string of the accepted EULAs */
+	string = g_string_new ("");
+	keys = g_hash_table_get_keys (backend->priv->eulas);
+	for (l=keys; l != NULL; l=l->next)
+		g_string_append_printf (string, "%s;", (const gchar *) l->data);
+
+	/* remove the trailing ';' */
+	g_string_set_size (string, string->len -1);
+	result = g_string_free (string, FALSE);
+out:
+	g_list_free (keys);
+	return result;
+}
+
+/**
  * pk_backend_watch_file:
  */
 gboolean
commit f6314d1e579314e746874629304302561b1bc259
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 9 14:18:38 2010 +0000

    Ensure that a malicious user can't make the backend exit by injecting a bogus EULA call into the transaction

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 17ca36c..87c3e16 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -612,6 +612,7 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	gchar *line;
 	gchar *uri;
 	gchar *transaction_id;
+	guint i;
 	GPtrArray *array;
 	gboolean ret;
 	PkHintEnum interactive;
@@ -631,7 +632,6 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	if (!egg_strzero (proxy_http)) {
 		uri = pk_backend_spawn_convert_uri (proxy_http);
 		line = g_strdup_printf ("%s=%s", "http_proxy", uri);
-		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
 		g_free (uri);
 	}
@@ -641,7 +641,6 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	if (!egg_strzero (proxy_ftp)) {
 		uri = pk_backend_spawn_convert_uri (proxy_ftp);
 		line = g_strdup_printf ("%s=%s", "ftp_proxy", uri);
-		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
 		g_free (uri);
 	}
@@ -650,20 +649,17 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	locale = pk_backend_get_locale (priv->backend);
 	if (!egg_strzero (locale)) {
 		line = g_strdup_printf ("%s=%s", "LANG", locale);
-		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
 	}
 
 	/* NETWORK */
 	ret = pk_backend_is_online (priv->backend);
 	line = g_strdup_printf ("%s=%s", "NETWORK", ret ? "TRUE" : "FALSE");
-	egg_debug ("setting evp '%s'", line);
 	g_ptr_array_add (array, line);
 
 	/* BACKGROUND */
 	ret = pk_backend_use_background (priv->backend);
 	line = g_strdup_printf ("%s=%s", "BACKGROUND", ret ? "TRUE" : "FALSE");
-	egg_debug ("setting evp '%s'", line);
 	g_ptr_array_add (array, line);
 
 	/* INTERACTIVE */
@@ -671,9 +667,15 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 		      "interactive", &interactive,
 		      NULL);
 	line = g_strdup_printf ("%s=%s", "INTERACTIVE", interactive ? "TRUE" : "FALSE");
-	egg_debug ("setting evp '%s'", line);
 	g_ptr_array_add (array, line);
 
+	/* ensure the malicious user can't inject anthing from the session */
+	for (i=0; i<array->len; i++) {
+		line = g_ptr_array_index (array, i);
+		g_strdelimit (line, "\\;{}[]()*?%\n\r\t", '_');
+		egg_debug ("setting evp '%s'", line);
+	}
+
 	envp = pk_ptr_array_to_strv (array);
 	g_ptr_array_unref (array);
 
commit 1d797872b05786a223511376ebd30270f70077d5
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:18:22 2010 +0100

    entropy: add what_provides C backend support (disabled for now)

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 8e61734..08c6219 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -193,6 +193,23 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
 }
 
 /**
+ * backend_what_provides:
+ */
+static void
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, gchar **values)
+{
+    gchar *filters_text;
+    gchar *search;
+    const gchar *provides_text;
+    provides_text = pk_provides_enum_to_string (provides);
+    filters_text = pk_filter_bitfield_to_string (filters);
+    search = g_strjoinv ("&", values);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "what-provides", filters_text, provides_text, search, NULL);
+    g_free (filters_text);
+    g_free (search);
+}
+
+/**
  * pk_backend_get_categories:
  */
 static void
commit b05161319a28a32f07a0d3bbf8fcc2010b6b8b8a
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 9 15:02:20 2010 +0100

    entropy: properly emit package() signals when installing/fetching

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 362a6cd..d7aca6b 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -575,7 +575,6 @@ class PackageKitEntropyMixin(object):
 
             x_rc = package.run()
             if x_rc != 0:
-                pk_pkg = match_map.get(match, (None, None, None))[2]
                 self.error(ERROR_PACKAGE_FAILED_TO_CONFIGURE,
                     "Cannot download package: %s" % (pk_pkg,))
                 return
@@ -617,12 +616,16 @@ class PackageKitEntropyMixin(object):
                 metaopts['install_source'] = \
                     etpConst['install_sources']['automatic_dependency']
 
+            pkg_id, pkg_c_repo, pk_pkg = match_map.get(match)
+            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
+            # show pkg
+            self.package(pk_pkg, INFO_INSTALLING, pkg_desc)
+
             package = self._entropy.Package()
             package.prepare(match, "install", metaopts)
 
             x_rc = package.run()
             if x_rc != 0:
-                pk_pkg = match_map.get(match, (None, None, None))[2]
                 self.error(ERROR_PACKAGE_FAILED_TO_INSTALL,
                     "Cannot install package: %s" % (pk_pkg,))
                 return
commit ea7214ae6af5ed424190e8ff143b05a71e68c52b
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 9 13:52:25 2010 +0000

    Add the environment variable transaction_id to the spawned processes

diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index ad5ac78..17ca36c 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -122,6 +122,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 	PkUpdateStateEnum update_state_enum;
 	PkMediaTypeEnum media_type_enum;
 	PkDistroUpgradeEnum distro_upgrade_enum;
+	PkBackendSpawnPrivate *priv = backend_spawn->priv;
 
 	g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE);
 
@@ -149,12 +150,12 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		info = pk_info_enum_from_string (sections[1]);
 		if (info == PK_INFO_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Info enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_package (backend_spawn->priv->backend, info, sections[2], sections[3]);
+		pk_backend_package (priv->backend, info, sections[2], sections[3]);
 	} else if (g_strcmp0 (command, "details") == 0) {
 		if (size != 7) {
 			egg_warning ("invalid command'%s', size %i", command, size);
@@ -173,7 +174,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		text = g_strdup (sections[4]);
 		/* convert ; to \n as we can't emit them on stdout */
 		g_strdelimit (text, ";", '\n');
-		pk_backend_details (backend_spawn->priv->backend, sections[1], sections[2],
+		pk_backend_details (priv->backend, sections[1], sections[2],
 					group, text, sections[5], package_size);
 		g_free (text);
 	} else if (g_strcmp0 (command, "finished") == 0) {
@@ -182,14 +183,14 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_finished (backend_spawn->priv->backend);
+		pk_backend_finished (priv->backend);
 	} else if (g_strcmp0 (command, "files") == 0) {
 		if (size != 3) {
 			egg_warning ("invalid command'%s', size %i", command, size);
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_files (backend_spawn->priv->backend, sections[1], sections[2]);
+		pk_backend_files (priv->backend, sections[1], sections[2]);
 	} else if (g_strcmp0 (command, "repo-detail") == 0) {
 		if (size != 4) {
 			egg_warning ("invalid command'%s', size %i", command, size);
@@ -197,9 +198,9 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			goto out;
 		}
 		if (g_strcmp0 (sections[3], "true") == 0) {
-			pk_backend_repo_detail (backend_spawn->priv->backend, sections[1], sections[2], TRUE);
+			pk_backend_repo_detail (priv->backend, sections[1], sections[2], TRUE);
 		} else if (g_strcmp0 (sections[3], "false") == 0) {
-			pk_backend_repo_detail (backend_spawn->priv->backend, sections[1], sections[2], FALSE);
+			pk_backend_repo_detail (priv->backend, sections[1], sections[2], FALSE);
 		} else {
 			egg_warning ("invalid qualifier '%s'", sections[3]);
 			ret = FALSE;
@@ -213,7 +214,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		restart = pk_restart_enum_from_string (sections[7]);
 		if (restart == PK_RESTART_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Restart enum not recognised, and hence ignored: '%s'", sections[7]);
 			ret = FALSE;
 			goto out;
@@ -222,7 +223,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		/* convert ; to \n as we can't emit them on stdout */
 		g_strdelimit (sections[8], ";", '\n');
 		g_strdelimit (sections[9], ";", '\n');
-		pk_backend_update_detail (backend_spawn->priv->backend, sections[1],
+		pk_backend_update_detail (priv->backend, sections[1],
 					  sections[2], sections[3], sections[4],
 					  sections[5], sections[6], restart, sections[8],
 					  sections[9], update_state_enum,
@@ -240,7 +241,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			egg_warning ("invalid percentage value %i", percentage);
 			ret = FALSE;
 		} else {
-			pk_backend_set_percentage (backend_spawn->priv->backend, percentage);
+			pk_backend_set_percentage (priv->backend, percentage);
 		}
 	} else if (g_strcmp0 (command, "subpercentage") == 0) {
 		if (size != 2) {
@@ -255,7 +256,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			egg_warning ("invalid subpercentage value %i", percentage);
 			ret = FALSE;
 		} else {
-			pk_backend_set_sub_percentage (backend_spawn->priv->backend, percentage);
+			pk_backend_set_sub_percentage (priv->backend, percentage);
 		}
 	} else if (g_strcmp0 (command, "error") == 0) {
 		if (size != 3) {
@@ -265,7 +266,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		error_enum = pk_error_enum_from_string (sections[1]);
 		if (error_enum == PK_ERROR_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Error enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -279,7 +280,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		/* convert % else we try to format them */
 		g_strdelimit (text, "%", '$');
 
-		pk_backend_error_code (backend_spawn->priv->backend, error_enum, text);
+		pk_backend_error_code (priv->backend, error_enum, text);
 		g_free (text);
 	} else if (g_strcmp0 (command, "requirerestart") == 0) {
 		if (size != 3) {
@@ -289,7 +290,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		restart_enum = pk_restart_enum_from_string (sections[1]);
 		if (restart_enum == PK_RESTART_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Restart enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -299,7 +300,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_require_restart (backend_spawn->priv->backend, restart_enum, sections[2]);
+		pk_backend_require_restart (priv->backend, restart_enum, sections[2]);
 	} else if (g_strcmp0 (command, "message") == 0) {
 		if (size != 3) {
 			egg_warning ("invalid command'%s', size %i", command, size);
@@ -308,7 +309,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		message_enum = pk_message_enum_from_string (sections[1]);
 		if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Message enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -316,7 +317,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		text = g_strdup (sections[2]);
 		/* convert ; to \n as we can't emit them on stdout */
 		g_strdelimit (text, ";", '\n');
-		pk_backend_message (backend_spawn->priv->backend, message_enum, text);
+		pk_backend_message (priv->backend, message_enum, text);
 		g_free (text);
 	} else if (g_strcmp0 (command, "change-transaction-data") == 0) {
 		if (size != 2) {
@@ -324,7 +325,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_set_transaction_data (backend_spawn->priv->backend, sections[1]);
+		pk_backend_set_transaction_data (priv->backend, sections[1]);
 	} else if (g_strcmp0 (command, "status") == 0) {
 		if (size != 2) {
 			egg_warning ("invalid command'%s', size %i", command, size);
@@ -333,12 +334,12 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		status_enum = pk_status_enum_from_string (sections[1]);
 		if (status_enum == PK_STATUS_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Status enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_set_status (backend_spawn->priv->backend, status_enum);
+		pk_backend_set_status (priv->backend, status_enum);
 	} else if (g_strcmp0 (command, "allow-cancel") == 0) {
 		if (size != 2) {
 			egg_warning ("invalid command'%s', size %i", command, size);
@@ -346,9 +347,9 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			goto out;
 		}
 		if (g_strcmp0 (sections[1], "true") == 0) {
-			pk_backend_set_allow_cancel (backend_spawn->priv->backend, TRUE);
+			pk_backend_set_allow_cancel (priv->backend, TRUE);
 		} else if (g_strcmp0 (sections[1], "false") == 0) {
-			pk_backend_set_allow_cancel (backend_spawn->priv->backend, FALSE);
+			pk_backend_set_allow_cancel (priv->backend, FALSE);
 		} else {
 			egg_warning ("invalid section '%s'", sections[1]);
 			ret = FALSE;
@@ -360,7 +361,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			ret = FALSE;
 			goto out;
 		}
-		pk_backend_set_percentage (backend_spawn->priv->backend, PK_BACKEND_PERCENTAGE_INVALID);
+		pk_backend_set_percentage (priv->backend, PK_BACKEND_PERCENTAGE_INVALID);
 	} else if (g_strcmp0 (command, "repo-signature-required") == 0) {
 
 		if (size != 9) {
@@ -371,26 +372,26 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 
 		sig_type = pk_sig_type_enum_from_string (sections[8]);
 		if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Sig enum not recognised, and hence ignored: '%s'", sections[8]);
 			ret = FALSE;
 			goto out;
 		}
 		if (egg_strzero (sections[1])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "package_id blank, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
 		if (egg_strzero (sections[2])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "repository name blank, and hence ignored: '%s'", sections[2]);
 			ret = FALSE;
 			goto out;
 		}
 
 		/* pass _all_ of the data */
-		ret = pk_backend_repo_signature_required (backend_spawn->priv->backend, sections[1],
+		ret = pk_backend_repo_signature_required (priv->backend, sections[1],
 							  sections[2], sections[3], sections[4],
 							  sections[5], sections[6], sections[7], sig_type);
 		goto out;
@@ -404,27 +405,27 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 
 		if (egg_strzero (sections[1])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "eula_id blank, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
 
 		if (egg_strzero (sections[2])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "package_id blank, and hence ignored: '%s'", sections[2]);
 			ret = FALSE;
 			goto out;
 		}
 
 		if (egg_strzero (sections[4])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "agreement name blank, and hence ignored: '%s'", sections[4]);
 			ret = FALSE;
 			goto out;
 		}
 
-		ret = pk_backend_eula_required (backend_spawn->priv->backend, sections[1], sections[2], sections[3], sections[4]);
+		ret = pk_backend_eula_required (priv->backend, sections[1], sections[2], sections[3], sections[4]);
 		goto out;
 
 	} else if (g_strcmp0 (command, "media-change-required") == 0) {
@@ -437,13 +438,13 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 
 		media_type_enum = pk_media_type_enum_from_string (sections[1]);
 		if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "media type enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
 
-		ret = pk_backend_media_change_required (backend_spawn->priv->backend, media_type_enum, sections[2], sections[3]);
+		ret = pk_backend_media_change_required (priv->backend, media_type_enum, sections[2], sections[3]);
 		goto out;
 	} else if (g_strcmp0 (command, "distro-upgrade") == 0) {
 
@@ -455,13 +456,13 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 
 		distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]);
 		if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
 
-		ret = pk_backend_distro_upgrade (backend_spawn->priv->backend, distro_upgrade_enum, sections[2], sections[3]);
+		ret = pk_backend_distro_upgrade (priv->backend, distro_upgrade_enum, sections[2], sections[3]);
 		goto out;
 	} else if (g_strcmp0 (command, "category") == 0) {
 
@@ -471,31 +472,31 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 			goto out;
 		}
 		if (g_strcmp0 (sections[1], sections[2]) == 0) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot be the same as parent_id");
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot be the same as parent_id");
 			ret = FALSE;
 			goto out;
 		}
 		if (egg_strzero (sections[2])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot not blank");
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "cat_id cannot not blank");
 			ret = FALSE;
 			goto out;
 		}
 		if (egg_strzero (sections[3])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "name cannot not blank");
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "name cannot not blank");
 			ret = FALSE;
 			goto out;
 		}
 		if (egg_strzero (sections[5])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "icon cannot not blank");
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "icon cannot not blank");
 			ret = FALSE;
 			goto out;
 		}
 		if (g_str_has_prefix (sections[5], "/")) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "icon '%s' should be a named icon, not a path", sections[5]);
+			pk_backend_message (priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR, "icon '%s' should be a named icon, not a path", sections[5]);
 			ret = FALSE;
 			goto out;
 		}
-		ret = pk_backend_category (backend_spawn->priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
+		ret = pk_backend_category (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
 		goto out;
 	} else {
 		egg_warning ("invalid command '%s'", command);
@@ -605,60 +606,68 @@ static gchar **
 pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 {
 	gchar **envp;
-	gchar *value;
+	gchar *proxy_http;
+	gchar *proxy_ftp;
+	gchar *locale;
 	gchar *line;
 	gchar *uri;
+	gchar *transaction_id;
 	GPtrArray *array;
 	gboolean ret;
 	PkHintEnum interactive;
+	PkBackendSpawnPrivate *priv = backend_spawn->priv;
 
 	array = g_ptr_array_new_with_free_func (g_free);
 
+	/* transaction_id */
+	g_object_get (priv->backend,
+		      "transaction-id", &transaction_id,
+		      NULL);
+	line = g_strdup_printf ("%s=%s", "transaction_id", transaction_id);
+	g_ptr_array_add (array, line);
+
 	/* http_proxy */
-	value = pk_backend_get_proxy_http (backend_spawn->priv->backend);
-	if (!egg_strzero (value)) {
-		uri = pk_backend_spawn_convert_uri (value);
+	proxy_http = pk_backend_get_proxy_http (priv->backend);
+	if (!egg_strzero (proxy_http)) {
+		uri = pk_backend_spawn_convert_uri (proxy_http);
 		line = g_strdup_printf ("%s=%s", "http_proxy", uri);
 		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
 		g_free (uri);
 	}
-	g_free (value);
 
 	/* ftp_proxy */
-	value = pk_backend_get_proxy_ftp (backend_spawn->priv->backend);
-	if (!egg_strzero (value)) {
-		uri = pk_backend_spawn_convert_uri (value);
+	proxy_ftp = pk_backend_get_proxy_ftp (priv->backend);
+	if (!egg_strzero (proxy_ftp)) {
+		uri = pk_backend_spawn_convert_uri (proxy_ftp);
 		line = g_strdup_printf ("%s=%s", "ftp_proxy", uri);
 		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
 		g_free (uri);
 	}
-	g_free (value);
 
 	/* LANG */
-	value = pk_backend_get_locale (backend_spawn->priv->backend);
-	if (!egg_strzero (value)) {
-		line = g_strdup_printf ("%s=%s", "LANG", value);
+	locale = pk_backend_get_locale (priv->backend);
+	if (!egg_strzero (locale)) {
+		line = g_strdup_printf ("%s=%s", "LANG", locale);
 		egg_debug ("setting evp '%s'", line);
 		g_ptr_array_add (array, line);
 	}
-	g_free (value);
 
 	/* NETWORK */
-	ret = pk_backend_is_online (backend_spawn->priv->backend);
+	ret = pk_backend_is_online (priv->backend);
 	line = g_strdup_printf ("%s=%s", "NETWORK", ret ? "TRUE" : "FALSE");
 	egg_debug ("setting evp '%s'", line);
 	g_ptr_array_add (array, line);
 
 	/* BACKGROUND */
-	ret = pk_backend_use_background (backend_spawn->priv->backend);
+	ret = pk_backend_use_background (priv->backend);
 	line = g_strdup_printf ("%s=%s", "BACKGROUND", ret ? "TRUE" : "FALSE");
 	egg_debug ("setting evp '%s'", line);
 	g_ptr_array_add (array, line);
 
 	/* INTERACTIVE */
-	g_object_get (backend_spawn->priv->backend,
+	g_object_get (priv->backend,
 		      "interactive", &interactive,
 		      NULL);
 	line = g_strdup_printf ("%s=%s", "INTERACTIVE", interactive ? "TRUE" : "FALSE");
@@ -667,6 +676,11 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 
 	envp = pk_ptr_array_to_strv (array);
 	g_ptr_array_unref (array);
+
+	g_free (proxy_http);
+	g_free (proxy_ftp);
+	g_free (locale);
+	g_free (transaction_id);
 	return envp;
 }
 
@@ -722,6 +736,7 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 	gchar **argv;
 	gchar **envp;
 	PkHintEnum background;
+	PkBackendSpawnPrivate *priv = backend_spawn->priv;
 #if PK_BUILD_LOCAL
 	const gchar *directory;
 #endif
@@ -737,7 +752,7 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 
 #if PK_BUILD_LOCAL
 	/* prefer the local version */
-	directory = backend_spawn->priv->name;
+	directory = priv->name;
 	if (g_str_has_prefix (directory, "test_"))
 		directory = "test";
 
@@ -750,10 +765,10 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 	if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE) {
 		egg_debug ("local helper not found '%s'", filename);
 		g_free (filename);
-		filename = g_build_filename (DATADIR, "PackageKit", "helpers", backend_spawn->priv->name, argv[0], NULL);
+		filename = g_build_filename (DATADIR, "PackageKit", "helpers", priv->name, argv[0], NULL);
 	}
 #else
-	filename = g_build_filename (DATADIR, "PackageKit", "helpers", backend_spawn->priv->name, argv[0], NULL);
+	filename = g_build_filename (DATADIR, "PackageKit", "helpers", priv->name, argv[0], NULL);
 #endif
 	egg_debug ("using spawn filename %s", filename);
 
@@ -762,20 +777,20 @@ pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, const gchar *exe
 	argv[0] = g_strdup (filename);
 
 	/* copy idle setting from backend to PkSpawn instance */
-	g_object_get (backend_spawn->priv->backend,
+	g_object_get (priv->backend,
 		      "background", &background,
 		      NULL);
-	g_object_set (backend_spawn->priv->spawn,
+	g_object_set (priv->spawn,
 		      "background", (background == PK_HINT_ENUM_TRUE),
 		      NULL);
 
-	backend_spawn->priv->finished = FALSE;
+	priv->finished = FALSE;
 	envp = pk_backend_spawn_get_envp (backend_spawn);
-	ret = pk_spawn_argv (backend_spawn->priv->spawn, argv, envp);
+	ret = pk_spawn_argv (priv->spawn, argv, envp);
 	if (!ret) {
-		pk_backend_error_code (backend_spawn->priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR,
+		pk_backend_error_code (priv->backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 				       "Spawn of helper '%s' failed", argv[0]);
-		pk_backend_finished (backend_spawn->priv->backend);
+		pk_backend_finished (priv->backend);
 	}
 	g_free (filename);
 	g_strfreev (argv);
@@ -844,24 +859,23 @@ static void
 pk_backend_spawn_finished_cb (PkBackend *backend, PkExitEnum exit_enum, PkBackendSpawn *backend_spawn)
 {
 	gint timeout;
-
-	g_return_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn));
+	PkBackendSpawnPrivate *priv = backend_spawn->priv;
 
 	/* we finished okay, so we don't need to emulate Finished() for a crashing script */
-	backend_spawn->priv->finished = TRUE;
+	priv->finished = TRUE;
 
-	if (backend_spawn->priv->kill_id > 0)
-		g_source_remove (backend_spawn->priv->kill_id);
+	if (priv->kill_id > 0)
+		g_source_remove (priv->kill_id);
 
 	/* get policy timeout */
-	timeout = pk_conf_get_int (backend_spawn->priv->conf, "BackendShutdownTimeout");
+	timeout = pk_conf_get_int (priv->conf, "BackendShutdownTimeout");
 	if (timeout == PK_CONF_VALUE_INT_MISSING) {
 		egg_warning ("using built in default value");
 		timeout = 5;
 	}
 
 	/* close down the dispatcher if it is still open after this much time */
-	backend_spawn->priv->kill_id = g_timeout_add_seconds (timeout, (GSourceFunc) pk_backend_spawn_exit_timeout_cb, backend_spawn);
+	priv->kill_id = g_timeout_add_seconds (timeout, (GSourceFunc) pk_backend_spawn_exit_timeout_cb, backend_spawn);
 }
 
 /**
commit b7c052dc64d50320afcdc60e67ccc29508f058c8
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 9 10:40:50 2010 +0000

    trivial: update the fedora spec file

diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 3578a48..28b01bb 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -374,7 +374,7 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %defattr(-,root,root,-)
 %doc README AUTHORS NEWS COPYING
 %{_libdir}/*packagekit-glib2.so.*
-%{_libdir}/girepositry-1.0/PackageKitGlib-1.0.typelib
+%{_libdir}/girepository-1.0/PackageKitGlib-1.0.typelib
 %{_datadir}/gir-1.0/PackageKitGlib-1.0.gir
 
 %files qt
@@ -452,4 +452,3 @@ update-mime-database %{_datadir}/mime &> /dev/null || :
 %changelog
 * #LONGDATE# Richard Hughes <richard at hughsie.com> #VERSION#-0.#BUILD##ALPHATAG#
 - Update from git
-
commit ac9baa270950422518c3125016b620ec3553d983
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 9 09:14:37 2010 +0000

    Install the introspection data to the correct location

diff --git a/lib/packagekit-glib2/Makefile.am b/lib/packagekit-glib2/Makefile.am
index ba211f1..0cbe0a6 100644
--- a/lib/packagekit-glib2/Makefile.am
+++ b/lib/packagekit-glib2/Makefile.am
@@ -250,7 +250,7 @@ INTROSPECTION_GIRS += PackageKitGlib-1.0.gir
 girdir = $(datadir)/gir-1.0
 dist_gir_DATA = $(INTROSPECTION_GIRS)
 
-typelibdir = $(libdir)/girepositry-1.0
+typelibdir = $(libdir)/girepository-1.0
 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
 
 CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
commit d78e57853283c8102eb592b54579df0416672905
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 9 09:11:39 2010 +0000

    trivial: add some getters and setters to PkCategory

diff --git a/lib/packagekit-glib2/pk-category.c b/lib/packagekit-glib2/pk-category.c
index f633969..82cd79f 100644
--- a/lib/packagekit-glib2/pk-category.c
+++ b/lib/packagekit-glib2/pk-category.c
@@ -65,6 +65,176 @@ enum {
 G_DEFINE_TYPE (PkCategory, pk_category, PK_TYPE_SOURCE)
 
 /**
+ * pk_category_get_parent_id:
+ * @category: The %PkCategory
+ *
+ * Gets the parent category id.
+ *
+ * Return value: the string value, or %NULL for unset.
+ *
+ * Since: 0.6.2
+ **/
+const gchar *
+pk_category_get_parent_id (PkCategory *category)
+{
+	g_return_val_if_fail (PK_IS_CATEGORY (category), NULL);
+	return category->priv->parent_id;
+}
+
+/**
+ * pk_category_set_parent_id:
+ * @category: The %PkCategory
+ * @parent_id: the new value
+ *
+ * Sets the parent category id.
+ *
+ * Since: 0.6.2
+ **/
+void
+pk_category_set_parent_id (PkCategory *category, const gchar *parent_id)
+{
+	g_return_if_fail (PK_IS_CATEGORY (category));
+	g_free (category->priv->parent_id);
+	category->priv->parent_id = g_strdup (parent_id);
+}
+
+/**
+ * pk_category_get_id:
+ * @category: The %PkCategory
+ *
+ * Gets the id specific to this category.
+ *
+ * Return value: the string value, or %NULL for unset.
+ *
+ * Since: 0.6.2
+ **/
+const gchar *
+pk_category_get_id (PkCategory *category)
+{
+	g_return_val_if_fail (PK_IS_CATEGORY (category), NULL);
+	return category->priv->cat_id;
+}
+
+/**
+ * pk_category_set_id:
+ * @category: The %PkCategory
+ * @cat_id: the new value
+ *
+ * Sets the id specific to this category.
+ *
+ * Since: 0.6.2
+ **/
+void
+pk_category_set_id (PkCategory *category, const gchar *cat_id)
+{
+	g_return_if_fail (PK_IS_CATEGORY (category));
+	g_free (category->priv->cat_id);
+	category->priv->cat_id = g_strdup (cat_id);
+}
+
+/**
+ * pk_category_get_name:
+ * @category: The %PkCategory
+ *
+ * Gets the name.
+ *
+ * Return value: the string value, or %NULL for unset.
+ *
+ * Since: 0.6.2
+ **/
+const gchar *
+pk_category_get_name (PkCategory *category)
+{
+	g_return_val_if_fail (PK_IS_CATEGORY (category), NULL);
+	return category->priv->name;
+}
+
+/**
+ * pk_category_set_name:
+ * @category: The %PkCategory
+ * @name: the new value
+ *
+ * Sets the name.
+ *
+ * Since: 0.6.2
+ **/
+void
+pk_category_set_name (PkCategory *category, const gchar *name)
+{
+	g_return_if_fail (PK_IS_CATEGORY (category));
+	g_free (category->priv->name);
+	category->priv->name = g_strdup (name);
+}
+
+/**
+ * pk_category_get_summary:
+ * @category: The %PkCategory
+ *
+ * Gets the summary.
+ *
+ * Return value: the string value, or %NULL for unset.
+ *
+ * Since: 0.6.2
+ **/
+const gchar *
+pk_category_get_summary (PkCategory *category)
+{
+	g_return_val_if_fail (PK_IS_CATEGORY (category), NULL);
+	return category->priv->summary;
+}
+
+/**
+ * pk_category_set_summary:
+ * @category: The %PkCategory
+ * @summary: the new value
+ *
+ * Sets the summary.
+ *
+ * Since: 0.6.2
+ **/
+void
+pk_category_set_summary (PkCategory *category, const gchar *summary)
+{
+	g_return_if_fail (PK_IS_CATEGORY (category));
+	g_free (category->priv->summary);
+	category->priv->summary = g_strdup (summary);
+}
+
+/**
+ * pk_category_get_icon:
+ * @category: The %PkCategory
+ *
+ * Gets the icon filename.
+ *
+ * Return value: the string value, or %NULL for unset.
+ *
+ * Since: 0.6.2
+ **/
+const gchar *
+pk_category_get_icon (PkCategory *category)
+{
+	g_return_val_if_fail (PK_IS_CATEGORY (category), NULL);
+	return category->priv->icon;
+}
+
+/**
+ * pk_category_set_icon:
+ * @category: The %PkCategory
+ * @icon: the new value
+ *
+ * Sets the icon filename.
+ *
+ * Since: 0.6.2
+ **/
+void
+pk_category_set_icon (PkCategory *category, const gchar *icon)
+{
+	g_return_if_fail (PK_IS_CATEGORY (category));
+	g_free (category->priv->icon);
+	category->priv->icon = g_strdup (icon);
+}
+
+/**
  * pk_category_get_property:
  **/
 static void
diff --git a/lib/packagekit-glib2/pk-category.h b/lib/packagekit-glib2/pk-category.h
index d099db4..3f90eb6 100644
--- a/lib/packagekit-glib2/pk-category.h
+++ b/lib/packagekit-glib2/pk-category.h
@@ -63,6 +63,23 @@ struct _PkCategoryClass
 GType		 pk_category_get_type		  	(void);
 PkCategory	*pk_category_new			(void);
 
+/* accessors */
+const gchar	*pk_category_get_parent_id		(PkCategory	*category);
+void		 pk_category_set_parent_id		(PkCategory	*category,
+							 const gchar	*parent_id);
+const gchar	*pk_category_get_id			(PkCategory	*category);
+void		 pk_category_set_id			(PkCategory	*category,
+							 const gchar	*cat_id);
+const gchar	*pk_category_get_name			(PkCategory	*category);
+void		 pk_category_set_name			(PkCategory	*category,
+							 const gchar	*name);
+const gchar	*pk_category_get_summary		(PkCategory	*category);
+void		 pk_category_set_summary		(PkCategory	*category,
+							 const gchar	*summary);
+const gchar	*pk_category_get_icon			(PkCategory	*category);
+void		 pk_category_set_icon			(PkCategory	*category,
+							 const gchar	*icon);
+
 G_END_DECLS
 
 #endif /* __PK_CATEGORY_H */
commit a072ed4b06a1c759c6076f83806f8713bbbcfb04
Author: Adrien Bustany <madcat at mymadcat.com>
Date:   Mon Feb 8 18:21:32 2010 -0300

    PackageKit-Qt: Fully automatize the proxy generation

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index bb569e3..8b79557 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -48,6 +48,7 @@ libpackagekit_qt_la_SOURCES =					\
 	bitfield.h						\
 	bitfield.cpp						\
 	enum.h							\
+	enum.cpp							\
 	$(NULL)
 
 libpackagekit_qt_la_LIBADD =					\
@@ -81,5 +82,19 @@ EXTRA_DIST =							\
 	transaction.moc						\
 	transactionprivate.moc					\
 	transactionproxy.moc					\
+	dbus_proxies.stamp                  \
 	$(NULL)
 
+MAINTAINERCLEANFILES =						\
+	dbus_proxies.stamp						\
+	transactionproxy.h						\
+	transactionproxy.cpp					\
+	daemonproxy.h							\
+	daemonproxy.cpp							\
+	$(NULL)
+
+BUILT_SOURCES=dbus_proxies.stamp
+
+dbus_proxies.stamp: ${top_srcdir}/src/org.freedesktop.PackageKit.xml ${top_srcdir}/src/org.freedesktop.PackageKit.Transaction.xml
+	qdbusxml2cpp -c DaemonProxy -p daemonproxy -m -N ${top_srcdir}/src/org.freedesktop.PackageKit.xml
+	qdbusxml2cpp -c TransactionProxy -p transactionproxy -m -N ${top_srcdir}/src/org.freedesktop.PackageKit.Transaction.xml
diff --git a/lib/packagekit-qt/src/client.cpp b/lib/packagekit-qt/src/client.cpp
index 4adb206..1ce765f 100644
--- a/lib/packagekit-qt/src/client.cpp
+++ b/lib/packagekit-qt/src/client.cpp
@@ -72,7 +72,7 @@ Client* Client::instance()
 Client::Client(QObject* parent) : QObject(parent), d_ptr(new ClientPrivate(this))
 {
 	Q_D(Client);
-	d->daemon = new DaemonProxy(PK_NAME, PK_PATH, QDBusConnection::systemBus(), this);
+	d->daemon = new ::DaemonProxy(PK_NAME, PK_PATH, QDBusConnection::systemBus(), this);
 
 	d->error = NoError;
 
diff --git a/lib/packagekit-qt/src/clientprivate.h b/lib/packagekit-qt/src/clientprivate.h
index f25470b..8b9f7a7 100644
--- a/lib/packagekit-qt/src/clientprivate.h
+++ b/lib/packagekit-qt/src/clientprivate.h
@@ -24,9 +24,10 @@
 #include <QtCore>
 #include "client.h"
 
+class DaemonProxy;
+
 namespace PackageKit {
 
-class DaemonProxy;
 class Transaction;
 
 class ClientPrivate : public QObject
@@ -36,7 +37,7 @@ class ClientPrivate : public QObject
 public:
 	~ClientPrivate();
 
-	DaemonProxy* daemon;
+	::DaemonProxy* daemon;
 	Client* c;
 
 	QStringList hints;
diff --git a/lib/packagekit-qt/src/daemonproxy.cpp b/lib/packagekit-qt/src/daemonproxy.cpp
deleted file mode 100644
index fa3298c..0000000
--- a/lib/packagekit-qt/src/daemonproxy.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "daemonproxy.h"
-
-/*
- * Implementation of interface class DaemonProxy
- */
-
-using namespace PackageKit;
-
-DaemonProxy::DaemonProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
-    : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
-{
-}
-
-DaemonProxy::~DaemonProxy()
-{
-}
-
-#include "daemonproxy.moc"
diff --git a/lib/packagekit-qt/src/daemonproxy.h b/lib/packagekit-qt/src/daemonproxy.h
deleted file mode 100644
index c6db4c2..0000000
--- a/lib/packagekit-qt/src/daemonproxy.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * This file was generated by qdbusxml2cpp version 0.7
- * Command line was: qdbusxml2cpp -c DaemonProxy -p daemonproxy.h ../../../src/org.freedesktop.PackageKit.xml -N
- *
- * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- *
- * This is an auto-generated file.
- * Do not edit! All changes made to it will be lost.
- */
-
-#ifndef DAEMONPROXY_H_1265392480
-#define DAEMONPROXY_H_1265392480
-
-#include <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtDBus/QtDBus>
-
-namespace PackageKit {
-
-/*
- * Proxy class for interface org.freedesktop.PackageKit
- */
-class DaemonProxy: public QDBusAbstractInterface
-{
-    Q_OBJECT
-public:
-    static inline const char *staticInterfaceName()
-    { return "org.freedesktop.PackageKit"; }
-
-public:
-    DaemonProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
-
-    ~DaemonProxy();
-
-    Q_PROPERTY(QString BackendAuthor READ backendAuthor)
-    inline QString backendAuthor() const
-    { return qvariant_cast< QString >(property("BackendAuthor")); }
-
-    Q_PROPERTY(QString BackendDescription READ backendDescription)
-    inline QString backendDescription() const
-    { return qvariant_cast< QString >(property("BackendDescription")); }
-
-    Q_PROPERTY(QString BackendName READ backendName)
-    inline QString backendName() const
-    { return qvariant_cast< QString >(property("BackendName")); }
-
-    Q_PROPERTY(QString DistroId READ distroId)
-    inline QString distroId() const
-    { return qvariant_cast< QString >(property("DistroId")); }
-
-    Q_PROPERTY(QString Filters READ filters)
-    inline QString filters() const
-    { return qvariant_cast< QString >(property("Filters")); }
-
-    Q_PROPERTY(QString Groups READ groups)
-    inline QString groups() const
-    { return qvariant_cast< QString >(property("Groups")); }
-
-    Q_PROPERTY(bool Locked READ locked)
-    inline bool locked() const
-    { return qvariant_cast< bool >(property("Locked")); }
-
-    Q_PROPERTY(QString MimeTypes READ mimeTypes)
-    inline QString mimeTypes() const
-    { return qvariant_cast< QString >(property("MimeTypes")); }
-
-    Q_PROPERTY(QString NetworkState READ networkState)
-    inline QString networkState() const
-    { return qvariant_cast< QString >(property("NetworkState")); }
-
-    Q_PROPERTY(QString Roles READ roles)
-    inline QString roles() const
-    { return qvariant_cast< QString >(property("Roles")); }
-
-    Q_PROPERTY(uint VersionMajor READ versionMajor)
-    inline uint versionMajor() const
-    { return qvariant_cast< uint >(property("VersionMajor")); }
-
-    Q_PROPERTY(uint VersionMicro READ versionMicro)
-    inline uint versionMicro() const
-    { return qvariant_cast< uint >(property("VersionMicro")); }
-
-    Q_PROPERTY(uint VersionMinor READ versionMinor)
-    inline uint versionMinor() const
-    { return qvariant_cast< uint >(property("VersionMinor")); }
-
-public Q_SLOTS: // METHODS
-    inline QDBusPendingReply<QString> CanAuthorize(const QString &action_id)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(action_id);
-        return asyncCallWithArgumentList(QLatin1String("CanAuthorize"), argumentList);
-    }
-
-    inline QDBusPendingReply<QString> GetDaemonState()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetDaemonState"), argumentList);
-    }
-
-    inline QDBusPendingReply<QString> GetTid()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetTid"), argumentList);
-    }
-
-    inline QDBusPendingReply<uint> GetTimeSinceAction(const QString &role)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(role);
-        return asyncCallWithArgumentList(QLatin1String("GetTimeSinceAction"), argumentList);
-    }
-
-    inline QDBusPendingReply<QStringList> GetTransactionList()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetTransactionList"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SetProxy(const QString &proxy_http, const QString &proxy_ftp)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(proxy_http) << qVariantFromValue(proxy_ftp);
-        return asyncCallWithArgumentList(QLatin1String("SetProxy"), argumentList);
-    }
-
-    inline QDBusPendingReply<> StateHasChanged(const QString &reason)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(reason);
-        return asyncCallWithArgumentList(QLatin1String("StateHasChanged"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SuggestDaemonQuit()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("SuggestDaemonQuit"), argumentList);
-    }
-
-Q_SIGNALS: // SIGNALS
-    void Changed();
-    void RepoListChanged();
-    void RestartSchedule();
-    void TransactionListChanged(const QStringList &transactions);
-    void UpdatesChanged();
-};
-
-} // namespace PackageKit
-#endif
-
diff --git a/lib/packagekit-qt/src/enum.cpp b/lib/packagekit-qt/src/enum.cpp
new file mode 100644
index 0000000..989d2c2
--- /dev/null
+++ b/lib/packagekit-qt/src/enum.cpp
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the QPackageKit project
+ * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "enum.h"
+#include "enum.moc"
+
diff --git a/lib/packagekit-qt/src/transactionprivate.h b/lib/packagekit-qt/src/transactionprivate.h
index 7131bae..1e1218f 100644
--- a/lib/packagekit-qt/src/transactionprivate.h
+++ b/lib/packagekit-qt/src/transactionprivate.h
@@ -25,10 +25,11 @@
 #include "enum.h"
 #include "client.h"
 
+class TransactionProxy;
+
 namespace PackageKit {
 
 class Transaction;
-class TransactionProxy;
 class Client;
 
 class TransactionPrivate : public QObject
@@ -39,7 +40,7 @@ public:
 	~TransactionPrivate();
 	QString tid;
 	Client* client;
-	TransactionProxy* p;
+	::TransactionProxy* p;
 	Transaction* t;
 
 	// Only used for old transactions
diff --git a/lib/packagekit-qt/src/transactionproxy.cpp b/lib/packagekit-qt/src/transactionproxy.cpp
deleted file mode 100644
index 734ac59..0000000
--- a/lib/packagekit-qt/src/transactionproxy.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "transactionproxy.h"
-
-/*
- * Implementation of interface class TransactionProxy
- */
-
-using namespace PackageKit;
-
-TransactionProxy::TransactionProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
-    : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
-{
-}
-
-TransactionProxy::~TransactionProxy()
-{
-}
-
-
-#include "transactionproxy.moc"
diff --git a/lib/packagekit-qt/src/transactionproxy.h b/lib/packagekit-qt/src/transactionproxy.h
deleted file mode 100644
index 2d16b38..0000000
--- a/lib/packagekit-qt/src/transactionproxy.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * This file was generated by qdbusxml2cpp version 0.7
- * Command line was: qdbusxml2cpp -c TransactionProxy -p transactionproxy.h ../../../src/org.freedesktop.PackageKit.Transaction.xml -N
- *
- * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- *
- * This is an auto-generated file.
- * Do not edit! All changes made to it will be lost.
- */
-
-#ifndef TRANSACTIONPROXY_H_1265392707
-#define TRANSACTIONPROXY_H_1265392707
-
-#include <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-#include <QtDBus/QtDBus>
-
-namespace PackageKit {
-/*
- * Proxy class for interface org.freedesktop.PackageKit.Transaction
- */
-class TransactionProxy: public QDBusAbstractInterface
-{
-    Q_OBJECT
-public:
-    static inline const char *staticInterfaceName()
-    { return "org.freedesktop.PackageKit.Transaction"; }
-
-public:
-    TransactionProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
-
-    ~TransactionProxy();
-
-    Q_PROPERTY(bool AllowCancel READ allowCancel)
-    inline bool allowCancel() const
-    { return qvariant_cast< bool >(property("AllowCancel")); }
-
-    Q_PROPERTY(bool CallerActive READ callerActive)
-    inline bool callerActive() const
-    { return qvariant_cast< bool >(property("CallerActive")); }
-
-    Q_PROPERTY(uint ElapsedTime READ elapsedTime)
-    inline uint elapsedTime() const
-    { return qvariant_cast< uint >(property("ElapsedTime")); }
-
-    Q_PROPERTY(QString LastPackage READ lastPackage)
-    inline QString lastPackage() const
-    { return qvariant_cast< QString >(property("LastPackage")); }
-
-    Q_PROPERTY(uint Percentage READ percentage)
-    inline uint percentage() const
-    { return qvariant_cast< uint >(property("Percentage")); }
-
-    Q_PROPERTY(uint RemainingTime READ remainingTime)
-    inline uint remainingTime() const
-    { return qvariant_cast< uint >(property("RemainingTime")); }
-
-    Q_PROPERTY(QString Role READ role)
-    inline QString role() const
-    { return qvariant_cast< QString >(property("Role")); }
-
-    Q_PROPERTY(uint Speed READ speed)
-    inline uint speed() const
-    { return qvariant_cast< uint >(property("Speed")); }
-
-    Q_PROPERTY(QString Status READ status)
-    inline QString status() const
-    { return qvariant_cast< QString >(property("Status")); }
-
-    Q_PROPERTY(uint Subpercentage READ subpercentage)
-    inline uint subpercentage() const
-    { return qvariant_cast< uint >(property("Subpercentage")); }
-
-    Q_PROPERTY(uint Uid READ uid)
-    inline uint uid() const
-    { return qvariant_cast< uint >(property("Uid")); }
-
-public Q_SLOTS: // METHODS
-    inline QDBusPendingReply<> AcceptEula(const QString &eula_id)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(eula_id);
-        return asyncCallWithArgumentList(QLatin1String("AcceptEula"), argumentList);
-    }
-
-    inline QDBusPendingReply<> Cancel()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("Cancel"), argumentList);
-    }
-
-    inline QDBusPendingReply<> DownloadPackages(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("DownloadPackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetCategories()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetCategories"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetDepends(const QString &filter, const QStringList &package_ids, bool recursive)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(package_ids) << qVariantFromValue(recursive);
-        return asyncCallWithArgumentList(QLatin1String("GetDepends"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetDetails(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("GetDetails"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetDistroUpgrades()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetDistroUpgrades"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetFiles(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("GetFiles"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetOldTransactions(uint number)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(number);
-        return asyncCallWithArgumentList(QLatin1String("GetOldTransactions"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetPackages(const QString &filter)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter);
-        return asyncCallWithArgumentList(QLatin1String("GetPackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetRepoList(const QString &filter)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter);
-        return asyncCallWithArgumentList(QLatin1String("GetRepoList"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetRequires(const QString &filter, const QStringList &package_ids, bool recursive)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(package_ids) << qVariantFromValue(recursive);
-        return asyncCallWithArgumentList(QLatin1String("GetRequires"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetUpdateDetail(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("GetUpdateDetail"), argumentList);
-    }
-
-    inline QDBusPendingReply<> GetUpdates(const QString &filter)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter);
-        return asyncCallWithArgumentList(QLatin1String("GetUpdates"), argumentList);
-    }
-
-    inline QDBusPendingReply<> InstallFiles(bool only_trusted, const QStringList &full_paths)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(only_trusted) << qVariantFromValue(full_paths);
-        return asyncCallWithArgumentList(QLatin1String("InstallFiles"), argumentList);
-    }
-
-    inline QDBusPendingReply<> InstallPackages(bool only_trusted, const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(only_trusted) << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("InstallPackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> InstallSignature(const QString &sig_type, const QString &key_id, const QString &package_id)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(sig_type) << qVariantFromValue(key_id) << qVariantFromValue(package_id);
-        return asyncCallWithArgumentList(QLatin1String("InstallSignature"), argumentList);
-    }
-
-    inline QDBusPendingReply<> RefreshCache(bool force)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(force);
-        return asyncCallWithArgumentList(QLatin1String("RefreshCache"), argumentList);
-    }
-
-    inline QDBusPendingReply<> RemovePackages(const QStringList &package_ids, bool allow_deps, bool autoremove)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids) << qVariantFromValue(allow_deps) << qVariantFromValue(autoremove);
-        return asyncCallWithArgumentList(QLatin1String("RemovePackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> RepoEnable(const QString &repo_id, bool enabled)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(repo_id) << qVariantFromValue(enabled);
-        return asyncCallWithArgumentList(QLatin1String("RepoEnable"), argumentList);
-    }
-
-    inline QDBusPendingReply<> RepoSetData(const QString &repo_id, const QString &parameter, const QString &value)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(repo_id) << qVariantFromValue(parameter) << qVariantFromValue(value);
-        return asyncCallWithArgumentList(QLatin1String("RepoSetData"), argumentList);
-    }
-
-    inline QDBusPendingReply<> Resolve(const QString &filter, const QStringList &packages)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(packages);
-        return asyncCallWithArgumentList(QLatin1String("Resolve"), argumentList);
-    }
-
-    inline QDBusPendingReply<> Rollback(const QString &transaction_id)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(transaction_id);
-        return asyncCallWithArgumentList(QLatin1String("Rollback"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SearchDetails(const QString &filter, const QStringList &values)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(values);
-        return asyncCallWithArgumentList(QLatin1String("SearchDetails"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SearchFiles(const QString &filter, const QStringList &values)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(values);
-        return asyncCallWithArgumentList(QLatin1String("SearchFiles"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SearchGroups(const QString &filter, const QStringList &values)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(values);
-        return asyncCallWithArgumentList(QLatin1String("SearchGroups"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SearchNames(const QString &filter, const QStringList &values)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(values);
-        return asyncCallWithArgumentList(QLatin1String("SearchNames"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SetHints(const QStringList &hints)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(hints);
-        return asyncCallWithArgumentList(QLatin1String("SetHints"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SetLocale(const QString &code)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(code);
-        return asyncCallWithArgumentList(QLatin1String("SetLocale"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SimulateInstallFiles(const QStringList &full_paths)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(full_paths);
-        return asyncCallWithArgumentList(QLatin1String("SimulateInstallFiles"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SimulateInstallPackages(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("SimulateInstallPackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SimulateRemovePackages(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("SimulateRemovePackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> SimulateUpdatePackages(const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("SimulateUpdatePackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> UpdatePackages(bool only_trusted, const QStringList &package_ids)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(only_trusted) << qVariantFromValue(package_ids);
-        return asyncCallWithArgumentList(QLatin1String("UpdatePackages"), argumentList);
-    }
-
-    inline QDBusPendingReply<> UpdateSystem(bool only_trusted)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(only_trusted);
-        return asyncCallWithArgumentList(QLatin1String("UpdateSystem"), argumentList);
-    }
-
-    inline QDBusPendingReply<> WhatProvides(const QString &filter, const QString &type, const QStringList &values)
-    {
-        QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(type) << qVariantFromValue(values);
-        return asyncCallWithArgumentList(QLatin1String("WhatProvides"), argumentList);
-    }
-
-Q_SIGNALS: // SIGNALS
-    void Category(const QString &parent_id, const QString &cat_id, const QString &name, const QString &summary, const QString &icon);
-    void Changed();
-    void Destroy();
-    void Details(const QString &package_id, const QString &license, const QString &group, const QString &detail, const QString &url, qulonglong size);
-    void DistroUpgrade(const QString &type, const QString &name, const QString &summary);
-    void ErrorCode(const QString &code, const QString &details);
-    void EulaRequired(const QString &eula_id, const QString &package_id, const QString &vendor_name, const QString &license_agreement);
-    void Files(const QString &package_id, const QString &file_list);
-    void Finished(const QString &exit, uint runtime);
-    void MediaChangeRequired(const QString &media_type, const QString &media_id, const QString &media_text);
-    void Message(const QString &type, const QString &details);
-    void Package(const QString &info, const QString &package_id, const QString &summary);
-    void RepoDetail(const QString &repo_id, const QString &description, bool enabled);
-    void RepoSignatureRequired(const QString &package_id, const QString &repository_name, const QString &key_url, const QString &key_userid, const QString &key_id, const QString &key_fingerprint, const QString &key_timestamp, const QString &type);
-    void RequireRestart(const QString &type, const QString &package_id);
-    void Transaction(const QString &old_tid, const QString &timespec, bool succeeded, const QString &role, uint duration, const QString &data, uint uid, const QString &cmdline);
-    void UpdateDetail(const QString &package_id, const QString &updates, const QString &obsoletes, const QString &vendor_url, const QString &bugzilla_url, const QString &cve_url, const QString &restart, const QString &update_text, const QString &changelog, const QString &state, const QString &issued, const QString &updated);
-};
-
-} // namespace PackageKit
-#endif
-
commit e1cbebd375f659fd61b1da650ac83fef8e8b3423
Author: Adrien Bustany <madcat at mymadcat.com>
Date:   Mon Feb 8 18:18:31 2010 -0300

    PackageKit-Qt: Port tests to current API

diff --git a/lib/packagekit-qt/test/daemontest.cpp b/lib/packagekit-qt/test/daemontest.cpp
index 810dd22..6eade57 100644
--- a/lib/packagekit-qt/test/daemontest.cpp
+++ b/lib/packagekit-qt/test/daemontest.cpp
@@ -10,31 +10,31 @@ DaemonTest::~DaemonTest()
 
 void DaemonTest::getActions()
 {
-	PackageKit::Client::Actions act = PackageKit::Client::instance()->getActions();
-	CPPUNIT_ASSERT(act & PackageKit::Client::ActionInstallPackages); // Not really a test, but if *that* fails, then things are going badly :)
+	PackageKit::Enum::Roles act = PackageKit::Client::instance()->actions();
+	CPPUNIT_ASSERT(act & PackageKit::Enum::RoleInstallPackages); // Not really a test, but if *that* fails, then things are going badly :)
 }
 
 void DaemonTest::getBackendDetail()
 {
-	PackageKit::Client::BackendDetail d = PackageKit::Client::instance()->getBackendDetail();
-	CPPUNIT_ASSERT(!d.name.isNull());
+	QString backendName = PackageKit::Client::instance()->backendName();
+	CPPUNIT_ASSERT(!backendName.isNull());
 }
 
 void DaemonTest::getFilters()
 {
-	PackageKit::Client::Filters f = PackageKit::Client::instance()->getFilters();
-	CPPUNIT_ASSERT(f & PackageKit::Client::FilterInstalled); // Not really a test, but if *that* fails, then things are going badly :)
+	PackageKit::Enum::Filters f = PackageKit::Client::instance()->filters();
+	CPPUNIT_ASSERT(f & PackageKit::Enum::FilterInstalled); // Not really a test, but if *that* fails, then things are going badly :)
 }
 
 void DaemonTest::getGroups()
 {
-	PackageKit::Client::Groups g = PackageKit::Client::instance()->getGroups();
+	PackageKit::Enum::Groups g = PackageKit::Client::instance()->groups();
 	CPPUNIT_ASSERT(g.size() != 1);
 }
 
 void DaemonTest::getTimeSinceAction()
 {
-	PackageKit::Client::instance()->getTimeSinceAction(PackageKit::Client::ActionInstallPackages);
+	PackageKit::Client::instance()->getTimeSinceAction(PackageKit::Enum::RoleInstallPackages);
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DaemonTest);
diff --git a/lib/packagekit-qt/test/main.cpp b/lib/packagekit-qt/test/main.cpp
index 8d31930..600c77c 100644
--- a/lib/packagekit-qt/test/main.cpp
+++ b/lib/packagekit-qt/test/main.cpp
@@ -9,8 +9,8 @@
 int main(int argc, char **argv)
 {
 	// Check that we are using the dummy backend for testing (I'm sometimes absent minded)
-	PackageKit::Client::BackendDetail d = PackageKit::Client::instance()->getBackendDetail();
-	if(d.name != "dummy") {
+	QString backendName = PackageKit::Client::instance()->backendName();
+	if(backendName != "dummy") {
 		qFatal("Please use the dummy backend for testing");
 	}
 
diff --git a/lib/packagekit-qt/test/transactiontest.cpp b/lib/packagekit-qt/test/transactiontest.cpp
index dddbbdf..9e5d746 100644
--- a/lib/packagekit-qt/test/transactiontest.cpp
+++ b/lib/packagekit-qt/test/transactiontest.cpp
@@ -15,7 +15,7 @@ TransactionTest::~TransactionTest()
 void TransactionTest::searchName()
 {
 	success = FALSE;
-	Transaction* t = PackageKit::Client::instance()->searchName("vim");
+	Transaction* t = PackageKit::Client::instance()->searchNames("vim");
 	qDebug() << "searchName";
 	QEventLoop el;
 	connect(t, SIGNAL(package(PackageKit::Package*)), this, SLOT(searchName_cb(PackageKit::Package*)));
@@ -44,13 +44,13 @@ void TransactionTest::resolveAndInstallAndRemove()
 	el.exec();
 	CPPUNIT_ASSERT_MESSAGE("resolve", success);
 
-	t = c->installPackage(FALSE, currentPackage);
+	t = c->installPackages(FALSE, currentPackage);
 	CPPUNIT_ASSERT_MESSAGE("installPackages", t != NULL);
 	qDebug() << "Installing";
 	connect(t, SIGNAL(finished(PackageKit::Transaction::ExitStatus, uint)), &el, SLOT(quit()));
 	el.exec();
 
-	t = c->removePackage(currentPackage, FALSE, FALSE);
+	t = c->removePackages(currentPackage, FALSE, FALSE);
 	CPPUNIT_ASSERT_MESSAGE("removePackages", t != NULL);
 	qDebug() << "Removing";
 	connect(t, SIGNAL(finished(PackageKit::Transaction::ExitStatus, uint)), &el, SLOT(quit()));
@@ -97,7 +97,7 @@ void TransactionTest::getRepos()
 	CPPUNIT_ASSERT_MESSAGE("getRepoList", success);
 
 	success = FALSE;
-	t = PackageKit::Client::instance()->getRepoList(PackageKit::Client::FilterNotDevelopment);
+	t = PackageKit::Client::instance()->getRepoList(PackageKit::Enum::FilterNotDevelopment);
 	CPPUNIT_ASSERT_MESSAGE("getRepoList (filtered)", t != NULL);
 	qDebug() << "Getting repos (filtered)";
 	connect(t, SIGNAL(finished(PackageKit::Transaction::ExitStatus, uint)), &el, SLOT(quit()));
commit 61f2a41c220cdab7dcbbcde2b3a7bf5e9fad4e55
Author: snicore <snicore at fedoraproject.org>
Date:   Mon Feb 8 20:04:45 2010 +0000

    Sending translation for Hungarian

diff --git a/po/hu.po b/po/hu.po
index a33b3ec..72459e5 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -7,304 +7,339 @@ msgid ""
 msgstr ""
 "Project-Id-Version: packagekit master\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-23 19:34+0000\n"
-"PO-Revision-Date: 2009-09-26 13:32+0200\n"
-"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
+"POT-Creation-Date: 2010-02-08 15:53+0000\n"
+"PO-Revision-Date: 2010-02-08 21:03+0100\n"
+"Last-Translator: Nikolas Slivka <snicore at gmail.com>\n"
 "Language-Team: Hungarian <gnome at fsf dot hu>\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"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Language: Hungarian\n"
 "X-Poedit-Country: HUNGARY\n"
 "X-Poedit-SourceCharset: utf-8\n"
 "X-Generator: KBabel 1.11.4\n"
 
 #. TRANSLATORS: this is an atomic transaction
-#: ../client/pk-console.c:142
+#. TRANSLATORS: the role is the point of the transaction, e.g. update-system
+#: ../client/pk-console.c:175
+#: ../client/pk-console.c:597
 msgid "Transaction"
 msgstr "Tranzakció"
 
 #. TRANSLATORS: this is the time the transaction was started in system timezone
-#: ../client/pk-console.c:144
+#: ../client/pk-console.c:177
 msgid "System time"
 msgstr "Rendszeridő"
 
 #. TRANSLATORS: this is if the transaction succeeded or not
-#: ../client/pk-console.c:146
+#: ../client/pk-console.c:179
 msgid "Succeeded"
 msgstr "Sikeres"
 
-#: ../client/pk-console.c:146
+#: ../client/pk-console.c:179
 msgid "True"
 msgstr "Igaz"
 
-#: ../client/pk-console.c:146
+#: ../client/pk-console.c:179
 msgid "False"
 msgstr "Hamis"
 
 #. TRANSLATORS: this is the transactions role, e.g. "update-system"
 #. TRANSLATORS: the trasaction role, e.g. update-system
-#: ../client/pk-console.c:148 ../src/pk-polkit-action-lookup.c:336
+#: ../client/pk-console.c:181
+#: ../src/pk-polkit-action-lookup.c:332
 msgid "Role"
 msgstr "Szerep"
 
 #. TRANSLATORS: this is The duration of the transaction
-#: ../client/pk-console.c:153
+#: ../client/pk-console.c:186
 msgid "Duration"
 msgstr "Időtartam"
 
-#: ../client/pk-console.c:153
+#: ../client/pk-console.c:186
 msgid "(seconds)"
 msgstr "(másodperc)"
 
 #. TRANSLATORS: this is The command line used to do the action
 #. TRANSLATORS: the command line of the thing that wants the authentication
-#: ../client/pk-console.c:157 ../src/pk-polkit-action-lookup.c:350
+#: ../client/pk-console.c:190
+#: ../src/pk-polkit-action-lookup.c:346
 msgid "Command line"
 msgstr "Parancssor"
 
 #. TRANSLATORS: this is the user ID of the user that started the action
-#: ../client/pk-console.c:159
+#: ../client/pk-console.c:192
 msgid "User ID"
 msgstr "Felhasználóazonosító"
 
 #. TRANSLATORS: this is the username, e.g. hughsie
-#: ../client/pk-console.c:166
+#: ../client/pk-console.c:199
 msgid "Username"
 msgstr "Felhasználónév"
 
 #. TRANSLATORS: this is the users real name, e.g. "Richard Hughes"
-#: ../client/pk-console.c:170
+#: ../client/pk-console.c:203
 msgid "Real name"
 msgstr "Valódi név"
 
-#: ../client/pk-console.c:178
+#: ../client/pk-console.c:211
 msgid "Affected packages:"
 msgstr "Érintett csomagok:"
 
-#: ../client/pk-console.c:180
+#: ../client/pk-console.c:213
 msgid "Affected packages: None"
 msgstr "Érintett csomagok: nincs"
 
 #. TRANSLATORS: this is the distro, e.g. Fedora 10
-#: ../client/pk-console.c:200
+#: ../client/pk-console.c:248
 msgid "Distribution"
 msgstr "Disztribúció"
 
 #. TRANSLATORS: this is type of update, stable or testing
-#: ../client/pk-console.c:202
+#: ../client/pk-console.c:250
 msgid "Type"
 msgstr "Típus"
 
 #. TRANSLATORS: this is any summary text describing the upgrade
 #. TRANSLATORS: this is the summary of the group
-#: ../client/pk-console.c:204 ../client/pk-console.c:225
+#: ../client/pk-console.c:252
+#: ../client/pk-console.c:291
 msgid "Summary"
 msgstr "Összegzés"
 
 #. TRANSLATORS: this is the group category name
-#: ../client/pk-console.c:214
+#: ../client/pk-console.c:280
 msgid "Category"
 msgstr "Kategória"
 
 #. TRANSLATORS: this is group identifier
-#: ../client/pk-console.c:216
+#: ../client/pk-console.c:282
 msgid "ID"
 msgstr "Azonosító"
 
 #. TRANSLATORS: this is the parent group
-#: ../client/pk-console.c:219
+#: ../client/pk-console.c:285
 msgid "Parent"
 msgstr "Szülő"
 
 #. TRANSLATORS: this is the name of the parent group
-#: ../client/pk-console.c:222
+#: ../client/pk-console.c:288
 msgid "Name"
 msgstr "Név"
 
 #. TRANSLATORS: this is preferred icon for the group
-#: ../client/pk-console.c:228
+#: ../client/pk-console.c:294
 msgid "Icon"
 msgstr "Ikon"
 
 #. TRANSLATORS: this is a header for the package that can be updated
-#: ../client/pk-console.c:242
+#: ../client/pk-console.c:340
 msgid "Details about the update:"
 msgstr "A frissítés részletei:"
 
 #. TRANSLATORS: details about the update, package name and version
+#. TRANSLATORS: the package that is being processed
 #. TRANSLATORS: the package that is not signed by a known key
 #. TRANSLATORS: the package name that was trying to be installed
 #. TRANSLATORS: title, the names of the packages that the method is processing
-#: ../client/pk-console.c:248 ../lib/packagekit-glib2/pk-task-text.c:105
-#: ../lib/packagekit-glib2/pk-task-text.c:172
-#: ../src/pk-polkit-action-lookup.c:361
+#: ../client/pk-console.c:346
+#: ../client/pk-console.c:616
+#: ../lib/packagekit-glib2/pk-task-text.c:126
+#: ../lib/packagekit-glib2/pk-task-text.c:208
+#: ../src/pk-polkit-action-lookup.c:357
 msgid "Package"
 msgid_plural "Packages"
 msgstr[0] "Csomag"
 msgstr[1] "Csomag"
 
 #. TRANSLATORS: details about the update, any packages that this update updates
-#: ../client/pk-console.c:251
+#: ../client/pk-console.c:349
 msgid "Updates"
 msgstr "Frissítések"
 
 #. TRANSLATORS: details about the update, any packages that this update obsoletes
-#: ../client/pk-console.c:255
+#: ../client/pk-console.c:353
 msgid "Obsoletes"
 msgstr "Elavult"
 
 #. TRANSLATORS: details about the update, the vendor URLs
 #. TRANSLATORS: the vendor (e.g. vmware) that is providing the EULA
-#: ../client/pk-console.c:259 ../lib/packagekit-glib2/pk-task-text.c:175
+#: ../client/pk-console.c:357
+#: ../lib/packagekit-glib2/pk-task-text.c:211
 msgid "Vendor"
 msgstr "Gyártó"
 
 #. TRANSLATORS: details about the update, the bugzilla URLs
-#: ../client/pk-console.c:263
+#: ../client/pk-console.c:361
 msgid "Bugzilla"
 msgstr "Bugzilla"
 
 #. TRANSLATORS: details about the update, the CVE URLs
-#: ../client/pk-console.c:267
+#: ../client/pk-console.c:365
 msgid "CVE"
 msgstr "CVE"
 
 #. TRANSLATORS: details about the update, if the package requires a restart
-#: ../client/pk-console.c:271
+#: ../client/pk-console.c:369
 msgid "Restart"
 msgstr "Újraindítás"
 
 #. TRANSLATORS: details about the update, any description of the update
-#: ../client/pk-console.c:275
+#: ../client/pk-console.c:373
 msgid "Update text"
 msgstr "Frissítési szöveg"
 
 #. TRANSLATORS: details about the update, the changelog for the package
-#: ../client/pk-console.c:279
+#: ../client/pk-console.c:377
 msgid "Changes"
 msgstr "Változások"
 
 #. TRANSLATORS: details about the update, the ongoing state of the update
-#: ../client/pk-console.c:283
+#: ../client/pk-console.c:381
 msgid "State"
 msgstr "Állapot"
 
 #. TRANSLATORS: details about the update, date the update was issued
-#: ../client/pk-console.c:288
+#: ../client/pk-console.c:385
 msgid "Issued"
 msgstr "Kiadva"
 
 #. TRANSLATORS: details about the update, date the update was updated
 #. TRANSLATORS: The action of the package, in past tense
-#: ../client/pk-console.c:293 ../lib/packagekit-glib2/pk-console-shared.c:498
+#: ../client/pk-console.c:389
+#: ../lib/packagekit-glib2/pk-console-shared.c:510
 msgid "Updated"
 msgstr "Frissítve"
 
 #. TRANSLATORS: if the repo is enabled
-#: ../client/pk-console.c:311
+#: ../client/pk-console.c:425
 msgid "Enabled"
 msgstr "Engedélyezve"
 
 #. TRANSLATORS: if the repo is disabled
-#: ../client/pk-console.c:314
+#: ../client/pk-console.c:428
 msgid "Disabled"
 msgstr "Tiltva"
 
 #. TRANSLATORS: a package requires the system to be restarted
-#: ../client/pk-console.c:336
+#: ../client/pk-console.c:460
 msgid "System restart required by:"
 msgstr "A rendszer újraindítását igényli:"
 
 #. TRANSLATORS: a package requires the session to be restarted
-#: ../client/pk-console.c:339
+#: ../client/pk-console.c:463
 msgid "Session restart required:"
 msgstr "A munkamenet újraindítását igényli:"
 
 #. TRANSLATORS: a package requires the system to be restarted due to a security update
-#: ../client/pk-console.c:342
+#: ../client/pk-console.c:466
 msgid "System restart (security) required by:"
 msgstr "A rendszer újraindítását (biztonsági okból) igényli:"
 
 #. TRANSLATORS: a package requires the session to be restarted due to a security update
-#: ../client/pk-console.c:345
+#: ../client/pk-console.c:469
 msgid "Session restart (security) required:"
 msgstr "A munkamenet újraindítását (biztonsági okból) igényli:"
 
 #. TRANSLATORS: a package requires the application to be restarted
-#: ../client/pk-console.c:348
+#: ../client/pk-console.c:472
 msgid "Application restart required by:"
 msgstr "Az alkalmazás újraindítását igényli:"
 
 #. TRANSLATORS: This a list of details about the package
-#: ../client/pk-console.c:365
+#: ../client/pk-console.c:507
 msgid "Package description"
 msgstr "Csomagleírás"
 
 #. TRANSLATORS: This a message (like a little note that may be of interest) from the transaction
-#: ../client/pk-console.c:383
+#: ../client/pk-console.c:538
 msgid "Message:"
 msgstr "Ãœzenet:"
 
 #. TRANSLATORS: This where the package has no files
-#: ../client/pk-console.c:397
+#: ../client/pk-console.c:559
 msgid "No files"
 msgstr "Nincsenek fájlok"
 
 #. TRANSLATORS: This a list files contained in the package
-#: ../client/pk-console.c:402
+#: ../client/pk-console.c:564
 msgid "Package files"
 msgstr "Csomag fájljai"
 
+#. TRANSLATORS: the percentage complete of the transaction
+#: ../client/pk-console.c:632
+msgid "Percentage"
+msgstr "Százalék"
+
+#. TRANSLATORS: the status of the transaction (e.g. downloading)
+#: ../client/pk-console.c:650
+msgid "Status"
+msgstr "Állapot"
+
+#. TRANSLATORS: the results from the transaction
+#: ../client/pk-console.c:679
+msgid "Results:"
+msgstr "Eredmények:"
+
 #. TRANSLATORS: we failed to get any results, which is pretty fatal in my book
-#: ../client/pk-console.c:474
+#: ../client/pk-console.c:686
 msgid "Fatal error"
 msgstr "Végzetes hiba"
 
 #. TRANSLATORS: the transaction failed in a way we could not expect
-#: ../client/pk-console.c:483
+#: ../client/pk-console.c:695
+#: ../contrib/command-not-found/pk-command-not-found.c:432
+#: ../contrib/command-not-found/pk-command-not-found.c:603
 msgid "The transaction failed"
 msgstr "A tranzakció meghiúsult"
 
+#. TRANSLATORS: print a message when there are no updates
+#: ../client/pk-console.c:726
+msgid "There are no updates available at this time."
+msgstr "Nincs elérhető frissítés"
+
 #. TRANSLATORS: a package needs to restart their system
-#: ../client/pk-console.c:551
+#: ../client/pk-console.c:814
 msgid "Please restart the computer to complete the update."
 msgstr "Indítsa újra a számítógépet a frissítés befejezéséhez."
 
 #. TRANSLATORS: a package needs to restart the session
-#: ../client/pk-console.c:554
+#: ../client/pk-console.c:817
 msgid "Please logout and login to complete the update."
 msgstr "Jelentkezzen ki, majd be a frissítés befejezéséhez."
 
 #. TRANSLATORS: a package needs to restart their system (due to security)
-#: ../client/pk-console.c:557
-msgid ""
-"Please restart the computer to complete the update as important security "
-"updates have been installed."
+#: ../client/pk-console.c:820
+msgid "Please restart the computer to complete the update as important security updates have been installed."
 msgstr "Indítsa újra a számítógépet a frissítés befejezéséhez, mivel fontos biztonsági frissítések kerültek telepítésre."
 
 #. TRANSLATORS: a package needs to restart the session (due to security)
-#: ../client/pk-console.c:560
-msgid ""
-"Please logout and login to complete the update as important security updates "
-"have been installed."
+#: ../client/pk-console.c:823
+msgid "Please logout and login to complete the update as important security updates have been installed."
 msgstr "Jelentkezzen ki, majd be a frissítés befejezéséhez, mivel fontos biztonsági frissítések kerültek telepítésre."
 
+#. TRANSLATORS: The user used 'pkcon install dave.rpm' rather than 'pkcon install-local dave.rpm'
+#: ../client/pk-console.c:849
+#, c-format
+msgid "Extected package name, actually got file. Try using 'pkcon install-local %s' instead."
+msgstr ""
+
 #. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:583
+#: ../client/pk-console.c:857
 #, c-format
 msgid "This tool could not find any available package: %s"
 msgstr "Az eszköz nem talál elérhető csomagokat: %s"
 
 #. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:611
+#: ../client/pk-console.c:885
 #, c-format
 msgid "This tool could not find the installed package: %s"
 msgstr "Az eszköz nem találja a telepített csomagot: %s"
 
 #. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:639 ../client/pk-console.c:667
+#: ../client/pk-console.c:913
+#: ../client/pk-console.c:941
 #, c-format
 msgid "This tool could not find the package: %s"
 msgstr "Az eszköz nem találja a csomagot: %s"
@@ -313,431 +348,448 @@ msgstr "Az eszköz nem találja a csomagot: %s"
 #. TRANSLATORS: There was an error getting the dependencies for the package. The detailed error follows
 #. TRANSLATORS: There was an error getting the details about the package. The detailed error follows
 #. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:695 ../client/pk-console.c:723
-#: ../client/pk-console.c:751 ../client/pk-console.c:779
-#: ../client/pk-console.c:807
+#: ../client/pk-console.c:969
+#: ../client/pk-console.c:997
+#: ../client/pk-console.c:1025
+#: ../client/pk-console.c:1053
+#: ../client/pk-console.c:1081
 #, c-format
 msgid "This tool could not find all the packages: %s"
 msgstr "Az eszköz nem találja az összes csomagot: %s"
 
 #. TRANSLATORS: This is when the daemon crashed, and we are up shit creek without a paddle
-#: ../client/pk-console.c:836
+#: ../client/pk-console.c:1110
 msgid "The daemon crashed mid-transaction!"
 msgstr "A démon tranzakció közben összeomlott!"
 
 #. TRANSLATORS: This is the header to the --help menu
-#: ../client/pk-console.c:870
+#: ../client/pk-console.c:1144
 msgid "PackageKit Console Interface"
 msgstr "PackageKit parancssori felület"
 
 #. these are commands we can use with pkcon
-#: ../client/pk-console.c:872
+#: ../client/pk-console.c:1146
 msgid "Subcommands:"
 msgstr "Részparancsok:"
 
 #. TRANSLATORS: we keep a database updated with the time that an action was last executed
-#: ../client/pk-console.c:951
+#: ../client/pk-console.c:1225
 msgid "Failed to get the time since this action was last completed"
 msgstr "A művelet utolsó végrehajtása óta eltelt idő lekérése meghiúsult"
 
-#. TRANSLATORS: command line argument, if we should show debugging information
-#. TRANSLATORS: if we should show debugging data
-#: ../client/pk-console.c:986 ../client/pk-generate-pack.c:222
-#: ../client/pk-monitor.c:275
-#: ../contrib/command-not-found/pk-command-not-found.c:614
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:511
-#: ../contrib/device-rebind/pk-device-rebind.c:293 ../src/pk-main.c:211
-msgid "Show extra debugging information"
-msgstr "Extra hibakeresési információk megjelenítése"
-
 #. TRANSLATORS: command line argument, just show the version string
-#: ../client/pk-console.c:989 ../client/pk-monitor.c:277
+#: ../client/pk-console.c:1261
+#: ../client/pk-monitor.c:306
 msgid "Show the program version and exit"
 msgstr "Programverzió kiírása és kilépés"
 
 #. TRANSLATORS: command line argument, use a filter to narrow down results
-#: ../client/pk-console.c:992
+#: ../client/pk-console.c:1264
 msgid "Set the filter, e.g. installed"
 msgstr "Szűrő beállítása, például: installed"
 
 #. TRANSLATORS: command line argument, work asynchronously
-#: ../client/pk-console.c:995
+#: ../client/pk-console.c:1267
 msgid "Exit without waiting for actions to complete"
 msgstr "Kilépés a műveletek befejezésének megvárása nélkül"
 
+#. command line argument, do we ask questions
+#: ../client/pk-console.c:1270
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:527
+msgid "Install the packages without asking for confirmation"
+msgstr "Telepíti a csomagokat megerősítés kérése nélkül"
+
+#. TRANSLATORS: command line argument, this command is not a priority
+#: ../client/pk-console.c:1273
+msgid "Run the command using idle network bandwidth and also using less power"
+msgstr "Parancsot használva kihasználatlan hálózati sávszélességet és kevesebb energiát is használ"
+
+#. TRANSLATORS: command line argument, just output without fancy formatting
+#: ../client/pk-console.c:1276
+msgid "Print to screen a machine readable output, rather than using animated widgets"
+msgstr ""
+
 #. TRANSLATORS: we failed to contact the daemon
-#: ../client/pk-console.c:1020
+#: ../client/pk-console.c:1298
 msgid "Failed to contact PackageKit"
 msgstr "A kapcsolatfelvétel a PackageKit démonnal meghiúsult."
 
 #. TRANSLATORS: The user specified an incorrect filter
-#: ../client/pk-console.c:1072
+#: ../client/pk-console.c:1356
 msgid "The filter specified was invalid"
 msgstr "A megadott szűrő érvénytelen"
 
 #. TRANSLATORS: a search type can be name, details, file, etc
-#: ../client/pk-console.c:1091
+#: ../client/pk-console.c:1375
 msgid "A search type is required, e.g. name"
 msgstr "Keresési típus szükséges, például: name"
 
 #. TRANSLATORS: the user needs to provide a search term
-#: ../client/pk-console.c:1098 ../client/pk-console.c:1110
-#: ../client/pk-console.c:1122 ../client/pk-console.c:1134
+#: ../client/pk-console.c:1382
+#: ../client/pk-console.c:1394
+#: ../client/pk-console.c:1406
+#: ../client/pk-console.c:1418
 msgid "A search term is required"
 msgstr "Keresőkifejezés szükséges"
 
 #. TRANSLATORS: the search type was provided, but invalid
-#: ../client/pk-console.c:1144
+#: ../client/pk-console.c:1428
 msgid "Invalid search type"
 msgstr "Érvénytelen keresési típus"
 
 #. TRANSLATORS: the user did not specify what they wanted to install
-#: ../client/pk-console.c:1150
+#: ../client/pk-console.c:1434
 msgid "A package name to install is required"
 msgstr "A telepítendő csomag neve szükséges"
 
 #. TRANSLATORS: the user did not specify what they wanted to install
-#: ../client/pk-console.c:1159
+#: ../client/pk-console.c:1443
 msgid "A filename to install is required"
 msgstr "A telepítendő fájl neve szükséges"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1171
+#: ../client/pk-console.c:1455
 msgid "A type, key_id and package_id are required"
 msgstr "A type, key_id és package_id értékek szükségesek"
 
 #. TRANSLATORS: the user did not specify what they wanted to remove
-#: ../client/pk-console.c:1182
+#: ../client/pk-console.c:1466
 msgid "A package name to remove is required"
 msgstr "Az eltávolítandó csomag neve szükséges"
 
 #. TRANSLATORS: the user did not specify anything about what to download or where
-#: ../client/pk-console.c:1191
+#: ../client/pk-console.c:1475
 msgid "A destination directory and the package names to download are required"
 msgstr "A célkönyvtár és a letöltendő csomagnevek szükségesek"
 
 #. TRANSLATORS: the directory does not exist, so we can't continue
-#: ../client/pk-console.c:1198
+#: ../client/pk-console.c:1482
 msgid "Directory not found"
 msgstr "A könyvtár nem található"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1207
+#: ../client/pk-console.c:1491
 msgid "A licence identifier (eula-id) is required"
 msgstr "Licencazonosító (eula-id) szükséges"
 
 #. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1218
+#: ../client/pk-console.c:1502
 msgid "A transaction identifier (tid) is required"
 msgstr "Tranzakcióazonosító (tid) szükséges"
 
 #. TRANSLATORS: The user did not specify a package name
-#: ../client/pk-console.c:1239
+#: ../client/pk-console.c:1523
 msgid "A package name to resolve is required"
 msgstr "Feloldandó csomagnév szükséges"
 
 #. TRANSLATORS: The user did not specify a repository (software source) name
-#: ../client/pk-console.c:1250 ../client/pk-console.c:1261
+#: ../client/pk-console.c:1534
+#: ../client/pk-console.c:1545
 msgid "A repository name is required"
 msgstr "Tárolónév szükséges"
 
 #. TRANSLATORS: The user didn't provide any data
-#: ../client/pk-console.c:1272
+#: ../client/pk-console.c:1556
 msgid "A repo name, parameter and value are required"
 msgstr "Tárolónév, paraméter és érték szükséges"
 
 #. TRANSLATORS: The user didn't specify what action to use
-#: ../client/pk-console.c:1289
+#: ../client/pk-console.c:1573
 msgid "An action, e.g. 'update-system' is required"
 msgstr "Művelet, például „update-system” szükséges"
 
 #. TRANSLATORS: The user specified an invalid action
-#: ../client/pk-console.c:1296
+#: ../client/pk-console.c:1580
 msgid "A correct role is required"
 msgstr "Megfelelő szerep szükséges"
 
 #. TRANSLATORS: The user did not provide a package name
 #. TRANSLATORS: This is when the user fails to supply the package name
-#: ../client/pk-console.c:1306 ../client/pk-console.c:1321
-#: ../client/pk-console.c:1330 ../client/pk-console.c:1350
-#: ../client/pk-console.c:1359 ../client/pk-generate-pack.c:285
+#: ../client/pk-console.c:1590
+#: ../client/pk-console.c:1605
+#: ../client/pk-console.c:1614
+#: ../client/pk-console.c:1634
+#: ../client/pk-console.c:1643
+#: ../client/pk-generate-pack.c:316
 msgid "A package name is required"
 msgstr "Csomagnév szükséges"
 
 #. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
-#: ../client/pk-console.c:1339
+#: ../client/pk-console.c:1623
 msgid "A package provide string is required"
 msgstr "A csomag által biztosított elemeket jelző karakterlánc szükséges"
 
 #. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:1419
+#: ../client/pk-console.c:1703
 #, c-format
 msgid "Option '%s' is not supported"
 msgstr "„%s” nevű kapcsoló nem támogatott"
 
 #. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:1429
+#: ../client/pk-console.c:1713
 msgid "Command failed"
 msgstr "A parancs meghiúsult"
 
 #. TRANSLATORS: we can exclude certain packages (glibc) when we know they'll exist on the target
-#: ../client/pk-generate-pack.c:225
+#: ../client/pk-generate-pack.c:255
 msgid "Set the file name of dependencies to be excluded"
 msgstr "Kihagyandó függőségek fájlnevének kihagyása"
 
 #. TRANSLATORS: the output location
-#: ../client/pk-generate-pack.c:228
+#: ../client/pk-generate-pack.c:258
 msgid "The output file or directory (the current directory is used if ommitted)"
 msgstr "A kimeneti fájl vagy könyvtár (alapértelmezésben az aktuális könyvtár)"
 
 #. TRANSLATORS: put a list of packages in the pack
-#: ../client/pk-generate-pack.c:231
+#: ../client/pk-generate-pack.c:261
 msgid "The package to be put into the service pack"
 msgstr "A szervizcsomagba helyezendő csomag"
 
 #. TRANSLATORS: put all pending updates in the pack
-#: ../client/pk-generate-pack.c:234
+#: ../client/pk-generate-pack.c:264
 msgid "Put all updates available in the service pack"
 msgstr "Minden elérhető frissítés szervizcsomagba helyezése"
 
 #. TRANSLATORS: This is when the user fails to supply the correct arguments
-#: ../client/pk-generate-pack.c:269
+#: ../client/pk-generate-pack.c:300
 msgid "Neither --package or --updates option selected."
 msgstr "A --package vagy --updates kapcsolók egyike sincs megadva."
 
 #. TRANSLATORS: This is when the user fails to supply just one argument
-#: ../client/pk-generate-pack.c:277
+#: ../client/pk-generate-pack.c:308
 msgid "Both options selected."
 msgstr "Mindkét kapcsoló kiválasztva."
 
 #. TRANSLATORS: This is when the user fails to supply the output
-#: ../client/pk-generate-pack.c:293
+#: ../client/pk-generate-pack.c:324
 msgid "A output directory or file name is required"
 msgstr "Kimeneti könyvtár vagy fájlnév szükséges"
 
 #. TRANSLATORS: This is when the dameon is not-installed/broken and fails to startup
-#: ../client/pk-generate-pack.c:311
+#: ../client/pk-generate-pack.c:342
 msgid "The dameon failed to startup"
 msgstr "A démon indítása meghiúsult"
 
 #. TRANSLATORS: This is when the backend doesn't have the capability to get-depends
 #. TRANSLATORS: This is when the backend doesn't have the capability to download
-#: ../client/pk-generate-pack.c:322 ../client/pk-generate-pack.c:328
+#: ../client/pk-generate-pack.c:353
+#: ../client/pk-generate-pack.c:359
 msgid "The package manager cannot perform this type of operation."
 msgstr "A csomagkezelő nem képes ezen művelettípus végrehajtására."
 
 #. TRANSLATORS: This is when the distro didn't include libarchive support into PK
-#: ../client/pk-generate-pack.c:335
-msgid ""
-"Service packs cannot be created as PackageKit was not built with libarchive "
-"support."
-msgstr ""
-"Szervízcsomagok nem készíthetőek, mivel a PackageKit libarchive támogatás "
-"nélkül került megépítésre."
+#: ../client/pk-generate-pack.c:366
+msgid "Service packs cannot be created as PackageKit was not built with libarchive support."
+msgstr "Szervízcsomagok nem készíthetőek, mivel a PackageKit libarchive támogatás nélkül került megépítésre."
 
 #. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
-#: ../client/pk-generate-pack.c:346
+#: ../client/pk-generate-pack.c:377
 msgid "If specifying a file, the service pack name must end with"
 msgstr "Fájl megadásakor a szervizcsomag nevének a következőre kell végződnie:"
 
 #. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:362
+#: ../client/pk-generate-pack.c:393
 msgid "A pack with the same name already exists, do you want to overwrite it?"
 msgstr "Már létezik ilyen nevű csomag, felülírja?"
 
 #. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:365
+#: ../client/pk-generate-pack.c:396
 msgid "The pack was not overwritten."
 msgstr "A csomag nem lett felülírva."
 
 #. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:378
+#: ../client/pk-generate-pack.c:409
 msgid "Failed to create directory:"
 msgstr "A könyvtár létrehozása meghiúsult:"
 
 #. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:390
+#: ../client/pk-generate-pack.c:421
 msgid "Failed to open package list."
 msgstr "A csomaglista megnyitása meghiúsult."
 
 #. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:399
+#: ../client/pk-generate-pack.c:430
 msgid "Finding package name."
 msgstr "Csomagnév keresése."
 
 #. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:403
+#: ../client/pk-generate-pack.c:434
 #, c-format
 msgid "Failed to find package '%s': %s"
 msgstr "A csomag („%s”) keresése meghiúsult: %s"
 
 #. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:411
+#: ../client/pk-generate-pack.c:442
 msgid "Creating service pack..."
 msgstr "Szervizcsomag létrehozása…"
 
 #. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:426
+#: ../client/pk-generate-pack.c:457
 #, c-format
 msgid "Service pack created '%s'"
 msgstr "A szervizcsomag létrehozva: „%s”"
 
 #. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:431
+#: ../client/pk-generate-pack.c:462
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "A szervizcsomag („%s”) létrehozása meghiúsult: %s"
 
-#: ../client/pk-monitor.c:205
+#: ../client/pk-monitor.c:236
 msgid "Failed to get daemon state"
 msgstr "A démon állapotának lekérése meghiúsult"
 
 #. TRANSLATORS: this is a program that monitors PackageKit
-#: ../client/pk-monitor.c:292
+#: ../client/pk-monitor.c:322
 msgid "PackageKit Monitor"
 msgstr "PackageKit-figyelő"
 
 #. TRANSLATORS: when we are getting data from the daemon
-#: ../contrib/browser-plugin/pk-plugin-install.c:491
+#: ../contrib/browser-plugin/pk-plugin-install.c:495
 msgid "Getting package information..."
 msgstr "Csomaginformációk lekérése…"
 
 #. TRANSLATORS: run an applicaiton
-#: ../contrib/browser-plugin/pk-plugin-install.c:497
+#: ../contrib/browser-plugin/pk-plugin-install.c:501
 #, c-format
 msgid "Run %s"
 msgstr "%s futtatása"
 
 #. TRANSLATORS: show the installed version of a package
-#: ../contrib/browser-plugin/pk-plugin-install.c:503
+#: ../contrib/browser-plugin/pk-plugin-install.c:507
 msgid "Installed version"
 msgstr "Telepített verzió"
 
 #. TRANSLATORS: run the application now
-#: ../contrib/browser-plugin/pk-plugin-install.c:511
+#: ../contrib/browser-plugin/pk-plugin-install.c:515
 #, c-format
 msgid "Run version %s now"
 msgstr "%s verzió futtatása most"
 
 #. TRANSLATORS: run the application now
-#: ../contrib/browser-plugin/pk-plugin-install.c:517
+#: ../contrib/browser-plugin/pk-plugin-install.c:521
 msgid "Run now"
 msgstr "Futtatás most"
 
 #. TRANSLATORS: update to a new version of the package
-#: ../contrib/browser-plugin/pk-plugin-install.c:523
+#: ../contrib/browser-plugin/pk-plugin-install.c:527
 #, c-format
 msgid "Update to version %s"
 msgstr "Frissítés %s verzióra"
 
 #. TRANSLATORS: To install a package
-#: ../contrib/browser-plugin/pk-plugin-install.c:529
+#: ../contrib/browser-plugin/pk-plugin-install.c:533
 #, c-format
 msgid "Install %s now"
 msgstr "%s telepítése most"
 
 #. TRANSLATORS: the version of the package
-#: ../contrib/browser-plugin/pk-plugin-install.c:532
+#: ../contrib/browser-plugin/pk-plugin-install.c:536
 msgid "Version"
 msgstr "Verzió"
 
 #. TRANSLATORS: noting found, so can't install
-#: ../contrib/browser-plugin/pk-plugin-install.c:537
+#: ../contrib/browser-plugin/pk-plugin-install.c:541
 msgid "No packages found for your system"
 msgstr "Nem találhatók csomagok a rendszeren"
 
 #. TRANSLATORS: package is being installed
-#: ../contrib/browser-plugin/pk-plugin-install.c:542
+#: ../contrib/browser-plugin/pk-plugin-install.c:546
 msgid "Installing..."
 msgstr "Telepítés…"
 
 #. TRANSLATORS: downloading repo data so we can search
-#: ../contrib/command-not-found/pk-command-not-found.c:358
+#: ../contrib/command-not-found/pk-command-not-found.c:365
 msgid "Downloading details about the software sources."
 msgstr "A szoftverforrásokkal kapcsolatos részletek letöltése."
 
 #. TRANSLATORS: downloading file lists so we can search
-#: ../contrib/command-not-found/pk-command-not-found.c:362
+#: ../contrib/command-not-found/pk-command-not-found.c:369
 msgid "Downloading filelists (this may take some time to complete)."
 msgstr "Fájllisták letöltése (ez eltarthat egy ideig)."
 
 #. TRANSLATORS: waiting for native lock
-#: ../contrib/command-not-found/pk-command-not-found.c:366
+#: ../contrib/command-not-found/pk-command-not-found.c:373
 msgid "Waiting for package manager lock."
 msgstr "Várakozás csomagkezelői zárra."
 
 #. TRANSLATORS: loading package cache so we can search
-#: ../contrib/command-not-found/pk-command-not-found.c:370
+#: ../contrib/command-not-found/pk-command-not-found.c:377
 msgid "Loading list of packages."
 msgstr "Csomaglista betöltése."
 
 #. TRANSLATORS: we failed to find the package, this shouldn't happen
-#: ../contrib/command-not-found/pk-command-not-found.c:444
+#: ../contrib/command-not-found/pk-command-not-found.c:423
 msgid "Failed to search for file"
 msgstr "A fájl keresése meghiúsult"
 
 #. TRANSLATORS: we failed to launch the executable, the error follows
-#: ../contrib/command-not-found/pk-command-not-found.c:570
+#: ../contrib/command-not-found/pk-command-not-found.c:566
 msgid "Failed to launch:"
 msgstr "Az indítás meghiúsult:"
 
+#. TRANSLATORS: we failed to install the package
+#: ../contrib/command-not-found/pk-command-not-found.c:594
+msgid "Failed to install packages"
+msgstr "Nem sikerült a csomagok telepítése"
+
 # fixme: valami szebb nevet...
 #. TRANSLATORS: tool that gets called when the command is not found
-#: ../contrib/command-not-found/pk-command-not-found.c:630
+#: ../contrib/command-not-found/pk-command-not-found.c:670
 msgid "PackageKit Command Not Found"
 msgstr "PackageKit parancskereső"
 
 #. TRANSLATORS: the prefix of all the output telling the user why it's not executing
-#: ../contrib/command-not-found/pk-command-not-found.c:658
+#: ../contrib/command-not-found/pk-command-not-found.c:699
 msgid "Command not found."
 msgstr "A parancs nem található."
 
 #. TRANSLATORS: tell the user what we think the command is
-#: ../contrib/command-not-found/pk-command-not-found.c:665
+#: ../contrib/command-not-found/pk-command-not-found.c:706
 msgid "Similar command is:"
 msgstr "Hasonló parancs:"
 
 #. TRANSLATORS: Ask the user if we should run the similar command
-#: ../contrib/command-not-found/pk-command-not-found.c:674
+#: ../contrib/command-not-found/pk-command-not-found.c:716
 msgid "Run similar command:"
 msgstr "Hasonló parancs futtatása:"
 
 #. TRANSLATORS: show the user a list of commands that they could have meant
 #. TRANSLATORS: show the user a list of commands we could run
-#: ../contrib/command-not-found/pk-command-not-found.c:686
-#: ../contrib/command-not-found/pk-command-not-found.c:695
+#: ../contrib/command-not-found/pk-command-not-found.c:730
+#: ../contrib/command-not-found/pk-command-not-found.c:739
 msgid "Similar commands are:"
 msgstr "Hasonló parancsok:"
 
 #. TRANSLATORS: ask the user to choose a file to run
-#: ../contrib/command-not-found/pk-command-not-found.c:702
+#: ../contrib/command-not-found/pk-command-not-found.c:746
 msgid "Please choose a command to run"
 msgstr "Válasszon egy futtatandó parancsot"
 
 #. TRANSLATORS: tell the user what package provides the command
-#: ../contrib/command-not-found/pk-command-not-found.c:721
+#: ../contrib/command-not-found/pk-command-not-found.c:764
 msgid "The package providing this file is:"
 msgstr "A fájlt biztosító csomag:"
 
 #. TRANSLATORS: as the user if we want to install a package to provide the command
-#: ../contrib/command-not-found/pk-command-not-found.c:726
+#: ../contrib/command-not-found/pk-command-not-found.c:769
 #, c-format
 msgid "Install package '%s' to provide command '%s'?"
 msgstr "Telepíti a(z) „%s” csomagot, amely a következő parancsot biztosítja: „%s”?"
 
 #. TRANSLATORS: Show the user a list of packages that provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:747
+#: ../contrib/command-not-found/pk-command-not-found.c:793
 msgid "Packages providing this file are:"
 msgstr "A fájlt biztosító csomagok:"
 
 #. TRANSLATORS: Show the user a list of packages that they can install to provide this command
-#: ../contrib/command-not-found/pk-command-not-found.c:756
+#: ../contrib/command-not-found/pk-command-not-found.c:803
 msgid "Suitable packages are:"
 msgstr "A megfelelő csomagok:"
 
 #. get selection
 #. TRANSLATORS: ask the user to choose a file to install
-#: ../contrib/command-not-found/pk-command-not-found.c:764
+#: ../contrib/command-not-found/pk-command-not-found.c:812
 msgid "Please choose a package to install"
 msgstr "Válasszon egy telepítendő csomagot"
 
@@ -753,270 +805,274 @@ msgid "Failed to find the package %s, or already installed: %s"
 msgstr "Nem található %s nevű csomag, vagy már telepítve van: %s"
 
 #. command line argument, simulate what would be done, but don't actually do it
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:514
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:518
 msgid "Don't actually install any packages, only simulate what would be installed"
 msgstr "Ne telepítsen semmilyen csomagot, csak szimulálja a telepítést"
 
 #. command line argument, do we skip packages that depend on the ones specified
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:517
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:521
 msgid "Do not install dependencies of the core packages"
 msgstr "Ne telepítse alapvető csomagok függőségeit"
 
 #. command line argument, do we operate quietly
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:520
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:524
 msgid "Do not display information or progress"
 msgstr "Ne jelenítsen meg információkat vagy előrehaladást"
 
 #. TRANSLATORS: tool that gets called when the command is not found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:535
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:542
 msgid "PackageKit Debuginfo Installer"
 msgstr "PackageKit Debuginfo Telepítő"
 
 #. TRANSLATORS: the use needs to specify a list of package names on the command line
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:550
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:556
 #, c-format
 msgid "ERROR: Specify package names to install."
 msgstr "Hiba: A telepítéshez adjon meg csomagneveket."
 
 #. TRANSLATORS: we are getting the list of repositories
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:579
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:592
 #, c-format
 msgid "Getting sources list"
 msgstr "Forráslista lekérése"
 
 #. TRANSLATORS: operation was not successful
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:589
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:664
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:748
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:792
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:859
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:903
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:602
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:677
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:761
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:805
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:872
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:916
 msgid "FAILED."
 msgstr "SIKERTELEN."
 
 #. TRANSLATORS: all completed 100%
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:604
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:644
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:679
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:763
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:807
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:874
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:918
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:617
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:657
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:692
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:776
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:820
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:887
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:931
 #, c-format
 msgid "OK."
 msgstr "OK."
 
 #. TRANSLATORS: tell the user what we found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:607
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:620
 #, c-format
 msgid "Found %i enabled and %i disabled sources."
 msgstr "Találtam %i engedélyezett és %i kiiktatott forrást."
 
 #. TRANSLATORS: we're finding repositories that match out pattern
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:614
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:627
 #, c-format
 msgid "Finding debugging sources"
 msgstr "Hibakeresési források keresése"
 
 #. TRANSLATORS: tell the user what we found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:647
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:660
 #, c-format
 msgid "Found %i disabled debuginfo repos."
 msgstr "%i kiiktatott debuginfo tárolót találtam."
 
 #. TRANSLATORS: we're now enabling all the debug sources we found
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:654
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:667
 #, c-format
 msgid "Enabling debugging sources"
 msgstr "Hibakeresési források engedélyezése"
 
 #. TRANSLATORS: tell the user how many we enabled
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:682
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:695
 #, c-format
 msgid "Enabled %i debugging sources."
 msgstr "%i hibakeresési forrás engedélyezve."
 
 #. TRANSLATORS: we're now finding packages that match in all the repos
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:689
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:702
 #, c-format
 msgid "Finding debugging packages"
 msgstr "Hibakeresési csomagok keresése"
 
 #. TRANSLATORS: we couldn't find the package name, non-fatal
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:701
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:714
 #, c-format
 msgid "Failed to find the package %s: %s"
 msgstr "A csomag („%s”) nem található: %s"
 
 #. TRANSLATORS: we couldn't find the debuginfo package name, non-fatal
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:724
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:737
 #, c-format
 msgid "Failed to find the debuginfo package %s: %s"
 msgstr "A hibakeresési csomag („%s”) nem található: %s"
 
 #. TRANSLATORS: no debuginfo packages could be found to be installed
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:752
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:765
 #, c-format
 msgid "Found no packages to install."
 msgstr "Telepítéshez nem találtam csomagokat."
 
 #. TRANSLATORS: tell the user we found some packages, and then list them
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:766
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:779
 #, c-format
 msgid "Found %i packages:"
 msgstr "%i csomagot találtam:"
 
 #. TRANSLATORS: tell the user we are searching for deps
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:782
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:795
 #, c-format
 msgid "Finding packages that depend on these packages"
 msgstr "Ezektől a csomagoktól függő csomagok keresése"
 
 #. TRANSLATORS: could not install, detailed error follows
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:795
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:808
 #, c-format
 msgid "Could not find dependant packages: %s"
 msgstr "Nem találhatók függő csomagok: %s"
 
 #. TRANSLATORS: tell the user we found some more packages
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:811
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:824
 #, c-format
 msgid "Found %i extra packages."
 msgstr "%i további csomag található."
 
 #. TRANSLATORS: tell the user we found some more packages
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:815
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:828
 #, c-format
 msgid "No extra packages required."
 msgstr "Nincs szükség további csomagokra."
 
 #. TRANSLATORS: tell the user we found some packages (and deps), and then list them
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:824
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:837
 #, c-format
 msgid "Found %i packages to install:"
 msgstr "%i telepítendő csomag található:"
 
 #. TRANSLATORS: simulate mode is a testing mode where we quit before the action
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:837
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:850
 #, c-format
 msgid "Not installing packages in simulate mode"
 msgstr "Nem telepít csomagokat szimulációs módban"
 
 #. TRANSLATORS: we are now installing the debuginfo packages we found earlier
 #. TRANSLATORS: transaction state, installing packages
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:849
-#: ../lib/packagekit-glib2/pk-console-shared.c:270
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:862
+#: ../lib/packagekit-glib2/pk-console-shared.c:282
 #, c-format
 msgid "Installing packages"
 msgstr "Csomagok telepítése"
 
 #. TRANSLATORS: could not install, detailed error follows
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:862
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:875
 #, c-format
 msgid "Could not install packages: %s"
 msgstr "Nem telepíthetők a csomagok: %s"
 
 #. TRANSLATORS: we are now disabling all debuginfo repos we previously enabled
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:894
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:907
 #, c-format
 msgid "Disabling sources previously enabled"
 msgstr "Korábban engedélyezett források kikapcsolása"
 
 #. TRANSLATORS: no debuginfo packages could be found to be installed, detailed error follows
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:906
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:919
 #, c-format
 msgid "Could not disable the debugging sources: %s"
 msgstr "Hibakeresési források kikapcsolása nem lehetséges: %s"
 
 #. TRANSLATORS: we disabled all the debugging repos that we enabled before
-#: ../contrib/debuginfo-install/pk-debuginfo-install.c:921
+#: ../contrib/debuginfo-install/pk-debuginfo-install.c:934
 #, c-format
 msgid "Disabled %i debugging sources."
 msgstr "Hibakeresési %i források kikapcsolva."
 
 #. TRANSLATORS: couldn't open device to write
-#: ../contrib/device-rebind/pk-device-rebind.c:61
+#: ../contrib/device-rebind/pk-device-rebind.c:62
 msgid "Failed to open file"
 msgstr "A fájl megnyitása meghiúsult"
 
 #. TRANSLATORS: could not write to the device
-#: ../contrib/device-rebind/pk-device-rebind.c:70
+#: ../contrib/device-rebind/pk-device-rebind.c:71
 msgid "Failed to write to the file"
 msgstr "A fájlba írás meghiúsult"
 
 #. TRANSLATORS: we failed to release the current driver
-#: ../contrib/device-rebind/pk-device-rebind.c:110
-#: ../contrib/device-rebind/pk-device-rebind.c:147
+#: ../contrib/device-rebind/pk-device-rebind.c:111
+#: ../contrib/device-rebind/pk-device-rebind.c:148
 msgid "Failed to write to device"
 msgstr "Az eszközre írás meghiúsult"
 
 #. TRANSLATORS: the device could not be found in sysfs
-#: ../contrib/device-rebind/pk-device-rebind.c:175
+#: ../contrib/device-rebind/pk-device-rebind.c:176
 msgid "Device could not be found"
 msgstr "Az eszköz nem található"
 
 #. TRANSLATORS: we failed to release the current driver
-#: ../contrib/device-rebind/pk-device-rebind.c:202
+#: ../contrib/device-rebind/pk-device-rebind.c:203
 msgid "Failed to unregister driver"
 msgstr "Az illesztő regisztrációjának megszüntetése meghiúsult"
 
 #. TRANSLATORS: we failed to bind the old driver
-#: ../contrib/device-rebind/pk-device-rebind.c:211
+#: ../contrib/device-rebind/pk-device-rebind.c:212
 msgid "Failed to register driver"
 msgstr "Az illesztő regisztrációja meghiúsult"
 
 #. TRANSLATORS: user did not specify a device sysfs path that exists
-#: ../contrib/device-rebind/pk-device-rebind.c:260
+#: ../contrib/device-rebind/pk-device-rebind.c:261
 msgid "Device path not found"
 msgstr "Az eszközútvonal nem található"
 
 #. TRANSLATORS: user did not specify a valid device sysfs path
-#: ../contrib/device-rebind/pk-device-rebind.c:268
+#: ../contrib/device-rebind/pk-device-rebind.c:269
 msgid "Incorrect device path specified"
 msgstr "Helytelen eszközútvonal lett megadva"
 
+#: ../contrib/device-rebind/pk-device-rebind.c:294
+msgid "Show extra debugging information"
+msgstr "Extra hibakeresési információk megjelenítése"
+
 #. command line argument, simulate what would be done, but don't actually do it
-#: ../contrib/device-rebind/pk-device-rebind.c:296
+#: ../contrib/device-rebind/pk-device-rebind.c:297
 msgid "Don't actually touch the hardware, only simulate what would be done"
 msgstr "Ne nyúljon ténylegesen a hardverhez, csak szimulálja"
 
 #. TRANSLATORS: command line option: a list of files to install
-#: ../contrib/device-rebind/pk-device-rebind.c:299
+#: ../contrib/device-rebind/pk-device-rebind.c:300
 msgid "Device paths"
 msgstr "Eszközútvonalak"
 
 #. TRANSLATORS: tool that gets called when the device needs reloading after installing firmware
-#: ../contrib/device-rebind/pk-device-rebind.c:314
+#: ../contrib/device-rebind/pk-device-rebind.c:315
 msgid "PackageKit Device Reloader"
 msgstr "PackageKit eszköz-újratöltő"
 
 #. TRANSLATORS: user did not specify a valid device sysfs path
-#: ../contrib/device-rebind/pk-device-rebind.c:322
+#: ../contrib/device-rebind/pk-device-rebind.c:323
 msgid "You need to specify at least one valid device path"
 msgstr "Legalább egy érvényes eszközútvonalat meg kell adnia"
 
 #. TRANSLATORS: user did not specify a valid device sysfs path
-#: ../contrib/device-rebind/pk-device-rebind.c:332
+#: ../contrib/device-rebind/pk-device-rebind.c:333
 msgid "This script can only be used by the root user"
 msgstr "Ezt a parancsfájlt csak rendszergazdai jogosultsággal lehet futtatni"
 
 #. TRANSLATORS: we're going to verify the path first
-#: ../contrib/device-rebind/pk-device-rebind.c:341
+#: ../contrib/device-rebind/pk-device-rebind.c:342
 msgid "Verifying device path"
 msgstr "Eszközútvonal ellenőrzése"
 
 #. TRANSLATORS: user did not specify a device sysfs path that exists
-#: ../contrib/device-rebind/pk-device-rebind.c:346
+#: ../contrib/device-rebind/pk-device-rebind.c:347
 msgid "Failed to verify device path"
 msgstr "Az eszközútvonal ellenőrzése meghiúsult"
 
 #. TRANSLATORS: we're going to try
-#: ../contrib/device-rebind/pk-device-rebind.c:360
+#: ../contrib/device-rebind/pk-device-rebind.c:361
 msgid "Attempting to rebind device"
 msgstr "Kísérlet az eszköz újratöltésére"
 
 #. TRANSLATORS: we failed to release the current driver
-#: ../contrib/device-rebind/pk-device-rebind.c:365
+#: ../contrib/device-rebind/pk-device-rebind.c:366
 msgid "Failed to rebind device"
 msgstr "Az eszköz újratöltése meghiúsult"
 
@@ -1032,604 +1088,604 @@ msgstr "PackageKit csomaglista"
 msgid "PackageKit Service Pack"
 msgstr "PackageKit szervizcsomag"
 
-#: ../lib/packagekit-glib2/pk-console-shared.c:55
+#: ../lib/packagekit-glib2/pk-console-shared.c:59
 #, c-format
 msgid "Please enter a number from 1 to %i: "
 msgstr "Adjon meg egy számot 1-től %i-ig: "
 
 #. TRANSLATORS: more than one package could be found that matched, to follow is a list of possible packages
-#: ../lib/packagekit-glib2/pk-console-shared.c:177
+#: ../lib/packagekit-glib2/pk-console-shared.c:183
 msgid "More than one package matches:"
 msgstr "Több csomag illeszkedik:"
 
 #. TRANSLATORS: This finds out which package in the list to use
-#: ../lib/packagekit-glib2/pk-console-shared.c:186
+#: ../lib/packagekit-glib2/pk-console-shared.c:196
 msgid "Please choose the correct package: "
 msgstr "Válassza ki a megfelelő csomagot: "
 
 #. TRANSLATORS: This is when the transaction status is not known
-#: ../lib/packagekit-glib2/pk-console-shared.c:238
+#: ../lib/packagekit-glib2/pk-console-shared.c:250
 msgid "Unknown state"
 msgstr "Ismeretlen állapot"
 
 #. TRANSLATORS: transaction state, the daemon is in the process of starting
-#: ../lib/packagekit-glib2/pk-console-shared.c:242
+#: ../lib/packagekit-glib2/pk-console-shared.c:254
 msgid "Starting"
 msgstr "Indul"
 
 #. TRANSLATORS: transaction state, the transaction is waiting for another to complete
-#: ../lib/packagekit-glib2/pk-console-shared.c:246
+#: ../lib/packagekit-glib2/pk-console-shared.c:258
 msgid "Waiting in queue"
 msgstr "Várakozik a sorban"
 
 #. TRANSLATORS: transaction state, just started
-#: ../lib/packagekit-glib2/pk-console-shared.c:250
+#: ../lib/packagekit-glib2/pk-console-shared.c:262
 msgid "Running"
 msgstr "Fut"
 
 #. TRANSLATORS: transaction state, is querying data
-#: ../lib/packagekit-glib2/pk-console-shared.c:254
+#: ../lib/packagekit-glib2/pk-console-shared.c:266
 msgid "Querying"
 msgstr "Lekérdezés"
 
 #. TRANSLATORS: transaction state, getting data from a server
-#: ../lib/packagekit-glib2/pk-console-shared.c:258
+#: ../lib/packagekit-glib2/pk-console-shared.c:270
 msgid "Getting information"
 msgstr "Információk lekérése"
 
 #. TRANSLATORS: transaction state, removing packages
-#: ../lib/packagekit-glib2/pk-console-shared.c:262
+#: ../lib/packagekit-glib2/pk-console-shared.c:274
 msgid "Removing packages"
 msgstr "Csomagok eltávolítása"
 
 #. TRANSLATORS: transaction state, downloading package files
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:266
-#: ../lib/packagekit-glib2/pk-console-shared.c:644
+#: ../lib/packagekit-glib2/pk-console-shared.c:278
+#: ../lib/packagekit-glib2/pk-console-shared.c:656
 msgid "Downloading packages"
 msgstr "Csomagok letöltése"
 
 #. TRANSLATORS: transaction state, refreshing internal lists
-#: ../lib/packagekit-glib2/pk-console-shared.c:274
+#: ../lib/packagekit-glib2/pk-console-shared.c:286
 msgid "Refreshing software list"
 msgstr "Szoftverlista frissítése"
 
 #. TRANSLATORS: transaction state, installing updates
-#: ../lib/packagekit-glib2/pk-console-shared.c:278
+#: ../lib/packagekit-glib2/pk-console-shared.c:290
 msgid "Installing updates"
 msgstr "Frissítések telepítése"
 
 #. TRANSLATORS: transaction state, removing old packages, and cleaning config files
-#: ../lib/packagekit-glib2/pk-console-shared.c:282
+#: ../lib/packagekit-glib2/pk-console-shared.c:294
 msgid "Cleaning up packages"
 msgstr "Csomagok tisztítása"
 
 #. TRANSLATORS: transaction state, obsoleting old packages
-#: ../lib/packagekit-glib2/pk-console-shared.c:286
+#: ../lib/packagekit-glib2/pk-console-shared.c:298
 msgid "Obsoleting packages"
 msgstr "Csomagok elavulttá tétele"
 
 #. TRANSLATORS: transaction state, checking the transaction before we do it
-#: ../lib/packagekit-glib2/pk-console-shared.c:290
+#: ../lib/packagekit-glib2/pk-console-shared.c:302
 msgid "Resolving dependencies"
 msgstr "Függőségek feloldása"
 
 #. TRANSLATORS: transaction state, checking if we have all the security keys for the operation
-#: ../lib/packagekit-glib2/pk-console-shared.c:294
+#: ../lib/packagekit-glib2/pk-console-shared.c:306
 msgid "Checking signatures"
 msgstr "Aláírások ellenőrzése"
 
 #. TRANSLATORS: transaction state, when we return to a previous system state
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:298
-#: ../lib/packagekit-glib2/pk-console-shared.c:604
+#: ../lib/packagekit-glib2/pk-console-shared.c:310
+#: ../lib/packagekit-glib2/pk-console-shared.c:616
 msgid "Rolling back"
 msgstr "Visszagörgetés"
 
 #. TRANSLATORS: transaction state, when we're doing a test transaction
-#: ../lib/packagekit-glib2/pk-console-shared.c:302
+#: ../lib/packagekit-glib2/pk-console-shared.c:314
 msgid "Testing changes"
 msgstr "Módosítások tesztelése"
 
 #. TRANSLATORS: transaction state, when we're writing to the system package database
-#: ../lib/packagekit-glib2/pk-console-shared.c:306
+#: ../lib/packagekit-glib2/pk-console-shared.c:318
 msgid "Committing changes"
 msgstr "Módosítások véglegesítése"
 
 #. TRANSLATORS: transaction state, requesting data from a server
-#: ../lib/packagekit-glib2/pk-console-shared.c:310
+#: ../lib/packagekit-glib2/pk-console-shared.c:322
 msgid "Requesting data"
 msgstr "Adatok lekérése"
 
 #. TRANSLATORS: transaction state, all done!
-#: ../lib/packagekit-glib2/pk-console-shared.c:314
+#: ../lib/packagekit-glib2/pk-console-shared.c:326
 msgid "Finished"
 msgstr "Befejeződött"
 
 #. TRANSLATORS: transaction state, in the process of cancelling
-#: ../lib/packagekit-glib2/pk-console-shared.c:318
+#: ../lib/packagekit-glib2/pk-console-shared.c:330
 msgid "Cancelling"
 msgstr "Megszakítás"
 
 #. TRANSLATORS: transaction state, downloading metadata
-#: ../lib/packagekit-glib2/pk-console-shared.c:322
+#: ../lib/packagekit-glib2/pk-console-shared.c:334
 msgid "Downloading repository information"
 msgstr "Tárolóinformációk letöltése"
 
 #. TRANSLATORS: transaction state, downloading metadata
-#: ../lib/packagekit-glib2/pk-console-shared.c:326
+#: ../lib/packagekit-glib2/pk-console-shared.c:338
 msgid "Downloading list of packages"
 msgstr "Csomaglista letöltése"
 
 #. TRANSLATORS: transaction state, downloading metadata
-#: ../lib/packagekit-glib2/pk-console-shared.c:330
+#: ../lib/packagekit-glib2/pk-console-shared.c:342
 msgid "Downloading file lists"
 msgstr "Fájllisták letöltése"
 
 #. TRANSLATORS: transaction state, downloading metadata
-#: ../lib/packagekit-glib2/pk-console-shared.c:334
+#: ../lib/packagekit-glib2/pk-console-shared.c:346
 msgid "Downloading lists of changes"
 msgstr "Változáslisták letöltése"
 
 #. TRANSLATORS: transaction state, downloading metadata
-#: ../lib/packagekit-glib2/pk-console-shared.c:338
+#: ../lib/packagekit-glib2/pk-console-shared.c:350
 msgid "Downloading groups"
 msgstr "Csoportok letöltése"
 
 #. TRANSLATORS: transaction state, downloading metadata
-#: ../lib/packagekit-glib2/pk-console-shared.c:342
+#: ../lib/packagekit-glib2/pk-console-shared.c:354
 msgid "Downloading update information"
 msgstr "Frissítési információk letöltése"
 
 #. TRANSLATORS: transaction state, repackaging delta files
-#: ../lib/packagekit-glib2/pk-console-shared.c:346
+#: ../lib/packagekit-glib2/pk-console-shared.c:358
 msgid "Repackaging files"
 msgstr "Fájlok újracsomagolása"
 
 #. TRANSLATORS: transaction state, loading databases
-#: ../lib/packagekit-glib2/pk-console-shared.c:350
+#: ../lib/packagekit-glib2/pk-console-shared.c:362
 msgid "Loading cache"
 msgstr "Gyorsítótár betöltése"
 
 #. TRANSLATORS: transaction state, scanning for running processes
-#: ../lib/packagekit-glib2/pk-console-shared.c:354
+#: ../lib/packagekit-glib2/pk-console-shared.c:366
 msgid "Scanning applications"
 msgstr "Alkalmazások vizsgálata"
 
 #. TRANSLATORS: transaction state, generating a list of packages installed on the system
-#: ../lib/packagekit-glib2/pk-console-shared.c:358
+#: ../lib/packagekit-glib2/pk-console-shared.c:370
 msgid "Generating package lists"
 msgstr "Csomaglisták előállítása"
 
 #. TRANSLATORS: transaction state, when we're waiting for the native tools to exit
-#: ../lib/packagekit-glib2/pk-console-shared.c:362
+#: ../lib/packagekit-glib2/pk-console-shared.c:374
 msgid "Waiting for package manager lock"
 msgstr "Várakozás a csomagkezelő zárolására"
 
 #. TRANSLATORS: transaction state, waiting for user to type in a password
-#: ../lib/packagekit-glib2/pk-console-shared.c:366
+#: ../lib/packagekit-glib2/pk-console-shared.c:378
 msgid "Waiting for authentication"
 msgstr "Várakozás hitelesítésre"
 
 #. TRANSLATORS: transaction state, we are updating the list of processes
-#: ../lib/packagekit-glib2/pk-console-shared.c:370
+#: ../lib/packagekit-glib2/pk-console-shared.c:382
 msgid "Updating running applications"
 msgstr "Futó alkalmazások frissítése"
 
 #. TRANSLATORS: transaction state, we are checking executable files currently in use
-#: ../lib/packagekit-glib2/pk-console-shared.c:374
+#: ../lib/packagekit-glib2/pk-console-shared.c:386
 msgid "Checking applications in use"
 msgstr "Használatban lévő alkalmazások keresése"
 
 #. TRANSLATORS: transaction state, we are checking for libraries currently in use
-#: ../lib/packagekit-glib2/pk-console-shared.c:378
+#: ../lib/packagekit-glib2/pk-console-shared.c:390
 msgid "Checking libraries in use"
 msgstr "Használatban lévő programkönyvtárak keresése"
 
 #. TRANSLATORS: transaction state, we are copying package files before or after the transaction
-#: ../lib/packagekit-glib2/pk-console-shared.c:382
+#: ../lib/packagekit-glib2/pk-console-shared.c:394
 msgid "Copying files"
 msgstr "Fájlok másolása"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:400
+#: ../lib/packagekit-glib2/pk-console-shared.c:412
 msgid "Trivial"
 msgstr "Triviális"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:404
+#: ../lib/packagekit-glib2/pk-console-shared.c:416
 msgid "Normal"
 msgstr "Normál"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:408
+#: ../lib/packagekit-glib2/pk-console-shared.c:420
 msgid "Important"
 msgstr "Fontos"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:412
+#: ../lib/packagekit-glib2/pk-console-shared.c:424
 msgid "Security"
 msgstr "Biztonsági"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:416
+#: ../lib/packagekit-glib2/pk-console-shared.c:428
 msgid "Bug fix "
 msgstr "Hibajavítás"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:420
+#: ../lib/packagekit-glib2/pk-console-shared.c:432
 msgid "Enhancement"
 msgstr "Bővítés"
 
 #. TRANSLATORS: The type of update
-#: ../lib/packagekit-glib2/pk-console-shared.c:424
+#: ../lib/packagekit-glib2/pk-console-shared.c:436
 msgid "Blocked"
 msgstr "Blokkolt"
 
 #. TRANSLATORS: The state of a package
 #. TRANSLATORS: The action of the package, in past tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:429
-#: ../lib/packagekit-glib2/pk-console-shared.c:502
+#: ../lib/packagekit-glib2/pk-console-shared.c:441
+#: ../lib/packagekit-glib2/pk-console-shared.c:514
 msgid "Installed"
 msgstr "Telepítve"
 
 #. TRANSLATORS: The state of a package, i.e. not installed
-#: ../lib/packagekit-glib2/pk-console-shared.c:434
+#: ../lib/packagekit-glib2/pk-console-shared.c:446
 msgid "Available"
 msgstr "Elérhető"
 
 #. TRANSLATORS: The action of the package, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:452
+#: ../lib/packagekit-glib2/pk-console-shared.c:464
 msgid "Downloading"
 msgstr "Letöltés"
 
 #. TRANSLATORS: The action of the package, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:456
+#: ../lib/packagekit-glib2/pk-console-shared.c:468
 msgid "Updating"
 msgstr "Frissítés"
 
 #. TRANSLATORS: The action of the package, in present tense
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:460
-#: ../lib/packagekit-glib2/pk-console-shared.c:580
+#: ../lib/packagekit-glib2/pk-console-shared.c:472
+#: ../lib/packagekit-glib2/pk-console-shared.c:592
 msgid "Installing"
 msgstr "Telepítés"
 
 #. TRANSLATORS: The action of the package, in present tense
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:464
-#: ../lib/packagekit-glib2/pk-console-shared.c:576
+#: ../lib/packagekit-glib2/pk-console-shared.c:476
+#: ../lib/packagekit-glib2/pk-console-shared.c:588
 msgid "Removing"
 msgstr "Eltávolítás"
 
 #. TRANSLATORS: The action of the package, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:468
+#: ../lib/packagekit-glib2/pk-console-shared.c:480
 msgid "Cleaning up"
 msgstr "Tisztítás"
 
 #. TRANSLATORS: The action of the package, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:472
+#: ../lib/packagekit-glib2/pk-console-shared.c:484
 msgid "Obsoleting"
 msgstr "Elavulttá tétel"
 
 #. TRANSLATORS: The action of the package, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:476
+#: ../lib/packagekit-glib2/pk-console-shared.c:488
 msgid "Reinstalling"
 msgstr "Újratelepítés"
 
 #. TRANSLATORS: The action of the package, in past tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:494
+#: ../lib/packagekit-glib2/pk-console-shared.c:506
 msgid "Downloaded"
 msgstr "Letöltve"
 
 #. TRANSLATORS: The action of the package, in past tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:506
+#: ../lib/packagekit-glib2/pk-console-shared.c:518
 msgid "Removed"
 msgstr "Eltávolítva"
 
 #. TRANSLATORS: The action of the package, in past tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:510
+#: ../lib/packagekit-glib2/pk-console-shared.c:522
 msgid "Cleaned up"
 msgstr "Megtisztítva"
 
 #. TRANSLATORS: The action of the package, in past tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:514
+#: ../lib/packagekit-glib2/pk-console-shared.c:526
 msgid "Obsoleted"
 msgstr "Elavulttá téve"
 
 #. TRANSLATORS: The action of the package, in past tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:518
+#: ../lib/packagekit-glib2/pk-console-shared.c:530
 msgid "Reinstalled"
 msgstr "Újratelepítve"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:536
+#: ../lib/packagekit-glib2/pk-console-shared.c:548
 msgid "Unknown role type"
 msgstr "Ismeretlen szereptípus"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:540
+#: ../lib/packagekit-glib2/pk-console-shared.c:552
 msgid "Getting dependencies"
 msgstr "Függőségek lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:544
+#: ../lib/packagekit-glib2/pk-console-shared.c:556
 msgid "Getting update details"
 msgstr "Frissítés részleteinek lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:548
+#: ../lib/packagekit-glib2/pk-console-shared.c:560
 msgid "Getting details"
 msgstr "Részletek lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:552
+#: ../lib/packagekit-glib2/pk-console-shared.c:564
 msgid "Getting requires"
 msgstr "Követelmények lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:556
+#: ../lib/packagekit-glib2/pk-console-shared.c:568
 msgid "Getting updates"
 msgstr "Frissítések lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:560
+#: ../lib/packagekit-glib2/pk-console-shared.c:572
 msgid "Searching by details"
 msgstr "Keresés részletek szerint"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:564
+#: ../lib/packagekit-glib2/pk-console-shared.c:576
 msgid "Searching by file"
 msgstr "Keresés fájl szerint"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:568
+#: ../lib/packagekit-glib2/pk-console-shared.c:580
 msgid "Searching groups"
 msgstr "Csoportok keresése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:572
+#: ../lib/packagekit-glib2/pk-console-shared.c:584
 msgid "Searching by name"
 msgstr "Keresés név szerint"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:584
+#: ../lib/packagekit-glib2/pk-console-shared.c:596
 msgid "Installing files"
 msgstr "Fájlok telepítése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:588
+#: ../lib/packagekit-glib2/pk-console-shared.c:600
 msgid "Refreshing cache"
 msgstr "Gyorsítótár frissítése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:592
+#: ../lib/packagekit-glib2/pk-console-shared.c:604
 msgid "Updating packages"
 msgstr "Csomagok frissítése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:596
+#: ../lib/packagekit-glib2/pk-console-shared.c:608
 msgid "Updating system"
 msgstr "Rendszer frissítése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:600
+#: ../lib/packagekit-glib2/pk-console-shared.c:612
 msgid "Canceling"
 msgstr "Megszakítás"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:608
+#: ../lib/packagekit-glib2/pk-console-shared.c:620
 msgid "Getting repositories"
 msgstr "Tárolók lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:612
+#: ../lib/packagekit-glib2/pk-console-shared.c:624
 msgid "Enabling repository"
 msgstr "Tároló engedélyezése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:616
+#: ../lib/packagekit-glib2/pk-console-shared.c:628
 msgid "Setting data"
 msgstr "Adatok beállítása"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:620
+#: ../lib/packagekit-glib2/pk-console-shared.c:632
 msgid "Resolving"
 msgstr "Feloldás"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:624
+#: ../lib/packagekit-glib2/pk-console-shared.c:636
 msgid "Getting file list"
 msgstr "Fájllista lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:628
+#: ../lib/packagekit-glib2/pk-console-shared.c:640
 msgid "Getting provides"
 msgstr "Biztosító csomagok lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:632
+#: ../lib/packagekit-glib2/pk-console-shared.c:644
 msgid "Installing signature"
 msgstr "Aláírás telepítése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:636
+#: ../lib/packagekit-glib2/pk-console-shared.c:648
 msgid "Getting packages"
 msgstr "Csomaglista lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:640
+#: ../lib/packagekit-glib2/pk-console-shared.c:652
 msgid "Accepting EULA"
 msgstr "EULA elfogadása"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:648
+#: ../lib/packagekit-glib2/pk-console-shared.c:660
 msgid "Getting upgrades"
 msgstr "Frissítések lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:652
+#: ../lib/packagekit-glib2/pk-console-shared.c:664
 msgid "Getting categories"
 msgstr "Kategóriák lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:656
+#: ../lib/packagekit-glib2/pk-console-shared.c:668
 msgid "Getting transactions"
 msgstr "Tranzakciók lekérése"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:660
-#: ../lib/packagekit-glib2/pk-console-shared.c:664
+#: ../lib/packagekit-glib2/pk-console-shared.c:672
+#: ../lib/packagekit-glib2/pk-console-shared.c:676
 msgid "Simulating install"
 msgstr "Telepítés szimulálása"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:668
+#: ../lib/packagekit-glib2/pk-console-shared.c:680
 msgid "Simulating remove"
 msgstr "Eltávolítás szimulálása"
 
 #. TRANSLATORS: The role of the transaction, in present tense
-#: ../lib/packagekit-glib2/pk-console-shared.c:672
+#: ../lib/packagekit-glib2/pk-console-shared.c:684
 msgid "Simulating update"
 msgstr "Frissítés szimulálása"
 
 #. TRANSLATORS: ask the user if they are comfortable installing insecure packages
-#: ../lib/packagekit-glib2/pk-task-text.c:64
+#: ../lib/packagekit-glib2/pk-task-text.c:69
 msgid "Do you want to allow installing of unsigned software?"
 msgstr "Engedélyezni kívánja aláíratlan szoftverek telepítését?"
 
 #. TRANSLATORS: tell the user we've not done anything
-#: ../lib/packagekit-glib2/pk-task-text.c:69
+#: ../lib/packagekit-glib2/pk-task-text.c:74
 msgid "The unsigned software will not be installed."
 msgstr "Az aláíratlan szoftverek nem kerülnek telepítésre."
 
 #. TRANSLATORS: the package repository is signed by a key that is not recognised
-#: ../lib/packagekit-glib2/pk-task-text.c:102
+#: ../lib/packagekit-glib2/pk-task-text.c:123
 msgid "Software source signature required"
 msgstr "Szoftverforrás-aláírás szükséges"
 
 #. TRANSLATORS: the package repository name
-#: ../lib/packagekit-glib2/pk-task-text.c:108
+#: ../lib/packagekit-glib2/pk-task-text.c:129
 msgid "Software source name"
 msgstr "Szoftverforrás neve"
 
 #. TRANSLATORS: the key URL
-#: ../lib/packagekit-glib2/pk-task-text.c:111
+#: ../lib/packagekit-glib2/pk-task-text.c:132
 msgid "Key URL"
 msgstr "Kulcs URL-címe"
 
 #. TRANSLATORS: the username of the key
-#: ../lib/packagekit-glib2/pk-task-text.c:114
+#: ../lib/packagekit-glib2/pk-task-text.c:135
 msgid "Key user"
 msgstr "Kulcs felhasználója"
 
 #. TRANSLATORS: the key ID, usually a few hex digits
-#: ../lib/packagekit-glib2/pk-task-text.c:117
+#: ../lib/packagekit-glib2/pk-task-text.c:138
 msgid "Key ID"
 msgstr "Kulcs azonosítója"
 
 #. TRANSLATORS: the key fingerprint, again, yet more hex
-#: ../lib/packagekit-glib2/pk-task-text.c:120
+#: ../lib/packagekit-glib2/pk-task-text.c:141
 msgid "Key fingerprint"
 msgstr "Kulcs ujjlenyomata"
 
 #. TRANSLATORS: the timestamp (a bit like a machine readable time)
-#: ../lib/packagekit-glib2/pk-task-text.c:123
+#: ../lib/packagekit-glib2/pk-task-text.c:144
 msgid "Key Timestamp"
 msgstr "Kulcs időbélyege"
 
 #. TRANSLATORS: ask the user if they want to import
-#: ../lib/packagekit-glib2/pk-task-text.c:129
+#: ../lib/packagekit-glib2/pk-task-text.c:157
 msgid "Do you accept this signature?"
 msgstr "Elfogadja ezt az aláírást?"
 
 #. TRANSLATORS: tell the user we've not done anything
-#: ../lib/packagekit-glib2/pk-task-text.c:134
+#: ../lib/packagekit-glib2/pk-task-text.c:162
 msgid "The signature was not accepted."
 msgstr "Az aláírást nem fogadta el."
 
 #. TRANSLATORS: this is another name for a software licence that has to be read before installing
-#: ../lib/packagekit-glib2/pk-task-text.c:169
+#: ../lib/packagekit-glib2/pk-task-text.c:205
 msgid "End user licence agreement required"
 msgstr "Végfelhasználói licencszerződés szükséges"
 
 #. TRANSLATORS: the EULA text itself (long and boring)
-#: ../lib/packagekit-glib2/pk-task-text.c:178
+#: ../lib/packagekit-glib2/pk-task-text.c:214
 msgid "Agreement"
 msgstr "Egyezmény"
 
 #. TRANSLATORS: ask the user if they've read and accepted the EULA
-#: ../lib/packagekit-glib2/pk-task-text.c:184
+#: ../lib/packagekit-glib2/pk-task-text.c:223
 msgid "Do you accept this agreement?"
 msgstr "Elfogadja ezt az egyezményt?"
 
 #. TRANSLATORS: tell the user we've not done anything
-#: ../lib/packagekit-glib2/pk-task-text.c:189
+#: ../lib/packagekit-glib2/pk-task-text.c:228
 msgid "The agreement was not accepted."
 msgstr "Az egyezményt nem fogadta el."
 
 #. TRANSLATORS: the user needs to change media inserted into the computer
-#: ../lib/packagekit-glib2/pk-task-text.c:219
+#: ../lib/packagekit-glib2/pk-task-text.c:267
 msgid "Media change required"
 msgstr "Adathordozó-csere szükséges"
 
 #. TRANSLATORS: the type, e.g. DVD, CD, etc
-#: ../lib/packagekit-glib2/pk-task-text.c:222
+#: ../lib/packagekit-glib2/pk-task-text.c:270
 msgid "Media type"
 msgstr "Adathordozó típusa"
 
 #. TRANSLATORS: the media label, usually like 'disk-1of3'
-#: ../lib/packagekit-glib2/pk-task-text.c:225
+#: ../lib/packagekit-glib2/pk-task-text.c:273
 msgid "Media label"
 msgstr "Adathordozó címkéje"
 
 #. TRANSLATORS: the media description, usually like 'Fedora 12 disk 5'
-#: ../lib/packagekit-glib2/pk-task-text.c:228
+#: ../lib/packagekit-glib2/pk-task-text.c:276
 msgid "Text"
 msgstr "Szöveg"
 
 #. TRANSLATORS: ask the user to insert the media
-#: ../lib/packagekit-glib2/pk-task-text.c:232
+#: ../lib/packagekit-glib2/pk-task-text.c:282
 msgid "Please insert the correct media"
 msgstr "Helyezze be a megfelelő adathordozót"
 
 #. TRANSLATORS: tell the user we've not done anything as they are lazy
-#: ../lib/packagekit-glib2/pk-task-text.c:237
+#: ../lib/packagekit-glib2/pk-task-text.c:287
 msgid "The correct media was not inserted."
 msgstr "Nincs behelyezve a megfelelő adathordozó."
 
 #. TRANSLATORS: When processing, we might have to remove other dependencies
-#: ../lib/packagekit-glib2/pk-task-text.c:252
+#: ../lib/packagekit-glib2/pk-task-text.c:302
 msgid "The following packages have to be removed:"
 msgstr "A következő csomagokat el kell távolítani:"
 
 #. TRANSLATORS: When processing, we might have to install other dependencies
-#: ../lib/packagekit-glib2/pk-task-text.c:257
+#: ../lib/packagekit-glib2/pk-task-text.c:307
 msgid "The following packages have to be installed:"
 msgstr "A következő csomagokat kell telepíteni:"
 
 #. TRANSLATORS: When processing, we might have to update other dependencies
-#: ../lib/packagekit-glib2/pk-task-text.c:262
+#: ../lib/packagekit-glib2/pk-task-text.c:312
 msgid "The following packages have to be updated:"
 msgstr "A következő csomagokat kell frissíteni:"
 
 #. TRANSLATORS: When processing, we might have to reinstall other dependencies
-#: ../lib/packagekit-glib2/pk-task-text.c:267
+#: ../lib/packagekit-glib2/pk-task-text.c:317
 msgid "The following packages have to be reinstalled:"
 msgstr "A következő csomagokat újra kell telepíteni:"
 
 #. TRANSLATORS: When processing, we might have to downgrade other dependencies
-#: ../lib/packagekit-glib2/pk-task-text.c:272
+#: ../lib/packagekit-glib2/pk-task-text.c:322
 msgid "The following packages have to be downgraded:"
 msgstr "A következő csomagokat vissza kell fejleszteni:"
 
 #. TRANSLATORS: ask the user if the proposed changes are okay
-#: ../lib/packagekit-glib2/pk-task-text.c:331
+#: ../lib/packagekit-glib2/pk-task-text.c:382
 msgid "Proceed with changes?"
 msgstr "Végrehajtja a módosításokat?"
 
 #. TRANSLATORS: tell the user we didn't do anything
-#: ../lib/packagekit-glib2/pk-task-text.c:336
+#: ../lib/packagekit-glib2/pk-task-text.c:387
 msgid "The transaction did not proceed."
 msgstr "A tranzakciót nem folytatta."
 
@@ -1656,12 +1712,8 @@ msgid "Authentication is required to change software source parameters"
 msgstr "Hitelesítés szükséges a szoftverforrás paramétereinek módosításához"
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:11
-msgid ""
-"Authentication is required to consider a key used for signing packages as "
-"trusted"
-msgstr ""
-"Hitelesítés szükséges a csomagok aláírásához használt kulcs megbízhatóvá "
-"nyilvánításához"
+msgid "Authentication is required to consider a key used for signing packages as trusted"
+msgstr "Hitelesítés szükséges a csomagok aláírásához használt kulcs megbízhatóvá nyilvánításához"
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:12
 msgid "Authentication is required to install a signed package"
@@ -1688,12 +1740,8 @@ msgid "Authentication is required to rollback a transaction"
 msgstr "Hitelesítés szükséges a tranzakció visszagörgetéséhez"
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:18
-msgid ""
-"Authentication is required to set the network proxy used for downloading "
-"packages"
-msgstr ""
-"Hitelesítés szükséges a csomagok letöltéséhez használt hálózati proxy "
-"beállításához"
+msgid "Authentication is required to set the network proxy used for downloading packages"
+msgstr "Hitelesítés szükséges a csomagok letöltéséhez használt hálózati proxy beállításához"
 
 #: ../policy/org.freedesktop.packagekit.policy.in.h:19
 msgid "Authentication is required to update packages"
@@ -1824,55 +1872,51 @@ msgstr "Nem a megfelelő felhasználó indítja a programot (rendszerint a rends
 
 #. TRANSLATORS: or we are installed in a prefix
 #: ../src/pk-main.c:93
-msgid ""
-"The org.freedesktop.PackageKit.conf file is not installed in the system "
-"directory:"
-msgstr ""
-"Az org.freedesktop.PackageKit.conf fájlt nincs a következő rendszermappába "
-"telepítve:"
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system directory:"
+msgstr "Az org.freedesktop.PackageKit.conf fájlt nincs a következő rendszermappába telepítve:"
 
 #. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
-#: ../src/pk-main.c:205
+#: ../src/pk-main.c:199
 msgid "Packaging backend to use, e.g. dummy"
 msgstr "Használandó csomagkezelő háttérprogram, például: dummy"
 
 #. TRANSLATORS: if we should run in the background
-#: ../src/pk-main.c:208
+#: ../src/pk-main.c:202
 msgid "Daemonize and detach from the terminal"
 msgstr "Démon módba váltás és leválasztás a terminálról"
 
 #. TRANSLATORS: if we should not monitor how long we are inactive for
-#: ../src/pk-main.c:214
+#: ../src/pk-main.c:205
 msgid "Disable the idle timer"
 msgstr "Üresjárati időzítő kikapcsolása"
 
 #. TRANSLATORS: show version
-#: ../src/pk-main.c:217
+#: ../src/pk-main.c:208
 msgid "Show version and exit"
 msgstr "Verziószám kiírása és kilépés"
 
 #. TRANSLATORS: exit after we've started up, used for user profiling
-#: ../src/pk-main.c:220
+#: ../src/pk-main.c:211
 msgid "Exit after a small delay"
 msgstr "Kilépés rövid késleltetés után"
 
 #. TRANSLATORS: exit straight away, used for automatic profiling
-#: ../src/pk-main.c:223
+#: ../src/pk-main.c:214
 msgid "Exit after the engine has loaded"
 msgstr "Kilépés az alrendszer betöltése után"
 
 #. TRANSLATORS: describing the service that is running
-#: ../src/pk-main.c:238
+#: ../src/pk-main.c:229
 msgid "PackageKit service"
 msgstr "PackageKit szolgáltatás"
 
 #. TRANSLATORS: fatal error, dbus is not running
-#: ../src/pk-main.c:275
+#: ../src/pk-main.c:266
 msgid "Cannot connect to the system bus"
 msgstr "Nem lehet csatlakozni a rendszerbuszhoz"
 
 #. TRANSLATORS: cannot register on system bus, unknown reason -- geeky error follows
-#: ../src/pk-main.c:334
+#: ../src/pk-main.c:317
 msgid "Error trying to start:"
 msgstr "Hiba az indításkor:"
 
@@ -1881,7 +1925,8 @@ msgid "To install debugging packages, extra sources need to be enabled"
 msgstr "Hibakeresési csomagok telepítéséhez, további külön források engedélyezésére"
 
 #. TRANSLATORS: is not GPG signed
-#: ../src/pk-polkit-action-lookup.c:171 ../src/pk-polkit-action-lookup.c:190
+#: ../src/pk-polkit-action-lookup.c:171
+#: ../src/pk-polkit-action-lookup.c:190
 msgid "The software is not from a trusted source."
 msgstr "A szoftver nem hiteles forrásból származik."
 
@@ -1901,18 +1946,44 @@ msgstr "Ne telepítse ezt a csomagot, hacsak nem biztos benne, hogy így biztons
 msgid "Do not install these packages unless you are sure it is safe to do so."
 msgstr "Ne telepítse ezeket a csomagokat, ha nem biztos benne, hogy ez biztonságos."
 
-#. TRANSLATORS: warn the user that all bets are off
-#: ../src/pk-polkit-action-lookup.c:202
-msgid "Malicious software can damage your computer or cause other harm."
-msgstr "Rosszindulatú szoftver problémát vagy meghibásodást okozhat."
-
 #. TRANSLATORS: too many packages to list each one
-#: ../src/pk-polkit-action-lookup.c:277
+#: ../src/pk-polkit-action-lookup.c:273
 msgid "Many packages"
 msgstr "Sok csomag"
 
 #. TRANSLATORS: if the transaction is forced to install only trusted packages
-#: ../src/pk-polkit-action-lookup.c:343
+#: ../src/pk-polkit-action-lookup.c:339
 msgid "Only trusted"
 msgstr "Csak hitelesítettet"
 
+#. TRANSLATORS: turn on all debugging
+#: ../src/egg-debug.c:388
+msgid "Show debugging information for all files"
+msgstr "Hibakeresési információk megjelenítése az összes fájlhoz"
+
+#. TRANSLATORS: a list of modules to debug
+#: ../src/egg-debug.c:459
+msgid "Debug these specific modules"
+msgstr ""
+
+#. TRANSLATORS: a list of functions to debug
+#: ../src/egg-debug.c:462
+msgid "Debug these specific functions"
+msgstr ""
+
+#. TRANSLATORS: save to a log
+#: ../src/egg-debug.c:465
+msgid "Log debugging data to a file"
+msgstr "Hibakeresés naplózása fájlba"
+
+#: ../src/egg-debug.c:469
+msgid "Debugging Options"
+msgstr "Hibakeresési lehetőségek"
+
+#: ../src/egg-debug.c:469
+msgid "Show debugging options"
+msgstr "Hibakeresési lehetőségek megjelenítése"
+
+#~ msgid "Malicious software can damage your computer or cause other harm."
+#~ msgstr "Rosszindulatú szoftver problémát vagy meghibásodást okozhat."
+
commit 9ff395dcfc4ffb16109db93990a75e8c5de033ca
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 8 20:15:32 2010 +0100

    entropy: implement PackageKitEntropyBackend.install_files()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 228af0a..362a6cd 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -53,7 +53,7 @@ from packagekit.package import PackagekitPackage
 sys.path.insert(0, '/usr/lib/entropy/libraries')
 from entropy.i18n import _, _LOCALE
 from entropy.const import etpConst, const_convert_to_rawstring, \
-    const_convert_to_unicode
+    const_convert_to_unicode, const_get_stringtype
 from entropy.client.interfaces import Client
 from entropy.core.settings.base import SystemSettings
 from entropy.misc import LogFile
@@ -89,8 +89,15 @@ class PackageKitEntropyMixin(object):
         Write log message to Entropy PackageKit log file.
         """
         if PK_DEBUG:
+            my_args = []
+            for arg in args:
+                if not isinstance(arg, const_get_stringtype()):
+                    my_args.append(repr(arg))
+                else:
+                    my_args.append(arg)
+
             self._entropy_log.write("%s: %s" % (source,
-                ' '.join([const_convert_to_unicode(x) for x in args]),)
+                ' '.join([const_convert_to_unicode(x) for x in my_args]),)
             )
 
     def _is_repository_enabled(self, repo_name):
@@ -1177,6 +1184,52 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
+    def install_files(self, only_trusted, inst_files):
+
+        self._log_message(__name__, "install_files: got", only_trusted, "and",
+            inst_files)
+
+        self.allow_cancel(True)
+        self.status(STATUS_RUNNING)
+
+        for etp_file in inst_files:
+            if not os.path.exists(etp_file):
+                self.error(ERROR_FILE_NOT_FOUND,
+                    "%s could not be found" % (etp_file,))
+                return
+
+            if not entropy.tools.is_entropy_package_file(etp_file):
+                self.error(ERROR_INVALID_PACKAGE_FILE,
+                    "Only Entropy files are supported")
+                return
+
+        pkg_ids = []
+        for etp_file in inst_files:
+            repo_id = os.path.basename(etp_file)
+            status, atomsfound = self._entropy.add_package_to_repos(etp_file)
+            if status != 0:
+                self.error(ERROR_INVALID_PACKAGE_FILE,
+                    "Error while trying to add %s repository" % (repo_id,))
+                return
+            for idpackage, atom in atomsfound:
+                pkg_ids.append((idpackage, repo_id))
+
+        self._log_message(__name__, "install_files: generated", pkg_ids)
+
+        pkgs = []
+        for pkg_id, repo_id in pkg_ids:
+            if pkg_id == -1: # wtf!?
+                self.error(ERROR_INVALID_PACKAGE_FILE,
+                    "Repo was added but package %s is not found" % (
+                        (pkg_id, repo_id),))
+                return
+            repo_db = self._entropy.open_repository(repo_id)
+            pkg = (pkg_id, repo_db)
+            pk_pkg = self._etp_to_id(pkg)
+            pkgs.append((pkg[0], pkg[1], pk_pkg,))
+
+        self._execute_etp_pkgs_install(pkgs, only_trusted)
+
     def install_packages(self, only_trusted, pk_pkgs):
 
         self._log_message(__name__, "install_packages: got %s and %s" % (
diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 2c294c0..8e61734 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -134,7 +134,7 @@ backend_get_roles (PkBackend *backend)
 		PK_ROLE_ENUM_GET_UPDATES,
 		PK_ROLE_ENUM_GET_UPDATE_DETAIL,
 		PK_ROLE_ENUM_INSTALL_PACKAGES,
-		//PK_ROLE_ENUM_INSTALL_FILES,
+		PK_ROLE_ENUM_INSTALL_FILES,
 		//PK_ROLE_ENUM_INSTALL_SIGNATURE,
 		PK_ROLE_ENUM_REFRESH_CACHE,
 		PK_ROLE_ENUM_REMOVE_PACKAGES,
@@ -293,6 +293,20 @@ backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **pac
 }
 
 /**
+ * backend_install_files:
+ */
+static void
+backend_install_files (PkBackend *backend, gboolean only_trusted, gchar **full_paths)
+{
+    gchar *package_ids_temp;
+
+    /* send the complete list as stdin */
+    package_ids_temp = g_strjoinv (PK_BACKEND_SPAWN_FILENAME_DELIM, full_paths);
+    pk_backend_spawn_helper (spawn, BACKEND_FILE, "install-files", pk_backend_bool_to_string (only_trusted), package_ids_temp, NULL);
+    g_free (package_ids_temp);
+}
+
+/**
  * backend_refresh_cache:
  */
 static void
@@ -492,7 +506,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_requires,				/* get_requires */
 	backend_get_update_detail,			/* get_update_detail */
 	backend_get_updates,				/* get_updates */
-	NULL,								/* install_files */
+	backend_install_files,				/* install_files */
 	backend_install_packages,			/* install_packages */
 	NULL,								/* install_signature */
 	backend_refresh_cache,				/* refresh_cache */
commit 6d830250970dbcc17696b8c7d5e4d5e745bcc565
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 8 19:40:02 2010 +0100

    entropy: add get_mime_types support in backend

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 775e12b..2c294c0 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -160,6 +160,15 @@ backend_get_roles (PkBackend *backend)
 }
 
 /**
+ * backend_get_mime_types:
+ */
+static gchar *
+backend_get_mime_types (PkBackend *backend)
+{
+    return g_strdup ("application/x-bzip-compressed-tar;application/x-tbz;application/x-tbz2");
+}
+
+/**
  * backend_cancel:
  */
 static void
@@ -470,7 +479,7 @@ PK_BACKEND_OPTIONS (
 	backend_get_groups,					/* get_groups */
 	backend_get_filters,				/* get_filters */
 	backend_get_roles,					/* get_roles */
-	NULL,								/* get_mime_types */
+	backend_get_mime_types,				/* get_mime_types */
 	backend_cancel,						/* cancel */
 	backend_download_packages,			/* download_packages */
 	backend_get_categories,				/* get_categories */
commit ac592ac66f0f6da2c4a86797af6012f381bd0188
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 8 19:30:13 2010 +0100

    entropy: temp disable EULA agreement checks

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index dcb7a64..228af0a 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -500,6 +500,9 @@ class PackageKitEntropyMixin(object):
         self.percentage(0)
         self.status(STATUS_DOWNLOAD)
 
+        """
+        # FIXME: need to have fixed backend API first
+
         # Before even starting the fetch
         # make sure that the user accepts their licenses
         # send license signal afterwards
@@ -513,7 +516,8 @@ class PackageKitEntropyMixin(object):
                 license_agreement = pkg_c_repo.retrieveLicenseText(eula_id)
                 self.eula_required(eula_id, pk_pkg, vendor_name,
                     license_agreement)
-                # FIXME remove here self._entropy.installed_repository().acceptLicense(eula_id)
+                # TODO remove here
+                # self._entropy.installed_repository().acceptLicense(eula_id)
 
         if licenses:
             # bye bye, user will have to accept it and get here again
@@ -521,6 +525,7 @@ class PackageKitEntropyMixin(object):
                 "Following EULAs are not accepted: %s" % (
                     ' '.join(licenses.keys()),))
             return
+        """
 
         # used in case of errors
         match_map = {}
commit b11b661a81df8b75b9712bb336e96eb08446f4f9
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 8 12:31:52 2010 +0000

    trivial: fix make distcheck

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index 3387ded..bb569e3 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -73,5 +73,13 @@ clean-local:
 	rm -f $(CLEANFILES)
 
 EXTRA_DIST =							\
+	client.moc						\
+	clientprivate.moc					\
+	daemonproxy.moc						\
+	enum.moc						\
+	package.moc						\
+	transaction.moc						\
+	transactionprivate.moc					\
+	transactionproxy.moc					\
 	$(NULL)
 
commit 849ba664683cf5942027a3937c18cab669ee9305
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Fri Feb 5 17:47:25 2010 -0200

    pk-qt: Moved all enums to Enum::class, and updated some

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index 28d6380..3387ded 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -48,7 +48,6 @@ libpackagekit_qt_la_SOURCES =					\
 	bitfield.h						\
 	bitfield.cpp						\
 	enum.h							\
-	enum.cpp						\
 	$(NULL)
 
 libpackagekit_qt_la_LIBADD =					\
diff --git a/lib/packagekit-qt/src/client.cpp b/lib/packagekit-qt/src/client.cpp
index ee0443e..4adb206 100644
--- a/lib/packagekit-qt/src/client.cpp
+++ b/lib/packagekit-qt/src/client.cpp
@@ -28,6 +28,7 @@
 #include "transaction.h"
 #include "transactionprivate.h"
 #include "transactionproxy.h"
+#include "package.h"
 #include "util.h"
 
 #define CREATE_NEW_TRANSACTION                      \
@@ -97,14 +98,14 @@ Client::~Client()
 {
 }
 
-Client::Actions Client::actions() const
+Enum::Roles Client::actions() const
 {
 	Q_D(const Client);
-	QStringList actions = d->daemon->roles().split(";");
+	QStringList roles = d->daemon->roles().split(";");
 
-	Actions flags;
-	foreach(const QString& action, actions) {
-		flags |= (Action) Util::enumFromString<Client>(action, "Action", "Action");
+	Enum::Roles flags;
+	foreach(const QString& role, roles) {
+		flags |= (Enum::Role) Util::enumFromString<Enum>(role, "Role", "Role");
 	}
 	return flags;
 }
@@ -127,7 +128,7 @@ QString Client::backendAuthor() const
 	return d->daemon->backendAuthor();
 }
 
-Client::Filters Client::filters() const
+Enum::Filters Client::filters() const
 {
 	Q_D(const Client);
 	QStringList filters = d->daemon->filters().split(";");
@@ -137,21 +138,21 @@ Client::Filters Client::filters() const
 		filters[filters.indexOf("none")] = "no-filter";
 	}
 
-	Filters flags;
+	Enum::Filters flags;
 	foreach(const QString& filter, filters) {
-		flags |= (Filter) Util::enumFromString<Client>(filter, "Filter", "Filter");
+		flags |= (Enum::Filter) Util::enumFromString<Enum>(filter, "Filter", "Filter");
 	}
 	return flags;
 }
 
-Client::Groups Client::groups() const
+Enum::Groups Client::groups() const
 {
 	Q_D(const Client);
 	QStringList groups = d->daemon->groups().split(";");
 
-	Groups flags;
+	Enum::Groups flags;
 	foreach(const QString& group, groups) {
-		flags.insert((Group) Util::enumFromString<Client>(group, "Group", "Group"));
+		flags.insert((Enum::Group) Util::enumFromString<Enum>(group, "Group", "Group"));
 	}
 	return flags;
 }
@@ -168,11 +169,11 @@ QStringList Client::mimeTypes() const
 	return d->daemon->mimeTypes().split(";");
 }
 
-Client::NetworkState Client::networkState() const
+Enum::Network Client::networkState() const
 {
 	Q_D(const Client);
 	QString state = d->daemon->networkState();
-	return (NetworkState) Util::enumFromString<Client>(state, "NetworkState", "Network");
+	return (Enum::Network) Util::enumFromString<Enum>(state, "Network", "Network");
 }
 
 QString Client::distroId() const
@@ -181,11 +182,18 @@ QString Client::distroId() const
 	return d->daemon->distroId();
 }
 
-uint Client::getTimeSinceAction(Action action) const
+Enum::Authorize Client::canAuthorize(const QString &actionId) const
 {
 	Q_D(const Client);
-	QString pkName = Util::enumToString<Client>(action, "Action", "Action");
-	return d->daemon->GetTimeSinceAction(pkName);
+	QString result = d->daemon->CanAuthorize(actionId);
+	return (Enum::Authorize) Util::enumFromString<Enum>(result, "Authorize", "Authorize");;
+}
+
+uint Client::getTimeSinceAction(Enum::Role role) const
+{
+	Q_D(const Client);
+	QString roleName = Util::enumToString<Enum>(role, "Role", "Role");
+	return d->daemon->GetTimeSinceAction(roleName);
 }
 
 QList<Transaction*> Client::getTransactions()
@@ -273,12 +281,12 @@ Transaction* Client::downloadPackages(Package* package)
 	return downloadPackages(QList<Package*>() << package);
 }
 
-Transaction* Client::getDepends(const QList<Package*>& packages, Filters filters, bool recursive)
+Transaction* Client::getDepends(const QList<Package*>& packages, Enum::Filters filters, bool recursive)
 {
 	RUN_TRANSACTION(GetDepends(Util::filtersToString(filters), Util::packageListToPids(packages), recursive))
 }
 
-Transaction* Client::getDepends(Package* package, Filters filters, bool recursive)
+Transaction* Client::getDepends(Package* package, Enum::Filters filters, bool recursive)
 {
 	return getDepends(QList<Package*>() << package, filters, recursive);
 }
@@ -319,22 +327,22 @@ Transaction* Client::getOldTransactions(uint number)
 	RUN_TRANSACTION(GetOldTransactions(number))
 }
 
-Transaction* Client::getPackages(Filters filters)
+Transaction* Client::getPackages(Enum::Filters filters)
 {
 	RUN_TRANSACTION(GetPackages(Util::filtersToString(filters)))
 }
 
-Transaction* Client::getRepoList(Filters filters)
+Transaction* Client::getRepoList(Enum::Filters filters)
 {
 	RUN_TRANSACTION(GetRepoList(Util::filtersToString(filters)))
 }
 
-Transaction* Client::getRequires(const QList<Package*>& packages, Filters filters, bool recursive)
+Transaction* Client::getRequires(const QList<Package*>& packages, Enum::Filters filters, bool recursive)
 {
 	RUN_TRANSACTION(GetRequires(Util::filtersToString(filters), Util::packageListToPids(packages), recursive))
 }
 
-Transaction* Client::getRequires(Package* package, Filters filters, bool recursive)
+Transaction* Client::getRequires(Package* package, Enum::Filters filters, bool recursive)
 {
 	return getRequires(QList<Package*>() << package, filters, recursive);
 }
@@ -349,7 +357,7 @@ Transaction* Client::getUpdateDetail(Package* package)
 	return getUpdateDetail(QList<Package*>() << package);
 }
 
-Transaction* Client::getUpdates(Filters filters)
+Transaction* Client::getUpdates(Enum::Filters filters)
 {
 	RUN_TRANSACTION(GetUpdates(Util::filtersToString(filters)))
 }
@@ -379,9 +387,9 @@ Transaction* Client::installPackages(bool only_trusted, Package* p)
 	return installPackages(only_trusted, QList<Package*>() << p);
 }
 
-Transaction* Client::installSignature(SignatureType type, const QString& key_id, Package* p)
+Transaction* Client::installSignature(Enum::SigType type, const QString& key_id, Package* p)
 {
-	RUN_TRANSACTION(InstallSignature(Util::enumToString<Client>(type, "SignatureType", "Signature"), key_id, p->id()))
+	RUN_TRANSACTION(InstallSignature(Util::enumToString<Enum>(type, "SigType", "Signature"), key_id, p->id()))
 }
 
 Transaction* Client::refreshCache(bool force)
@@ -409,12 +417,12 @@ Transaction* Client::repoSetData(const QString& repo_id, const QString& paramete
 	RUN_TRANSACTION(RepoSetData(repo_id, parameter, value))
 }
 
-Transaction* Client::resolve(const QStringList& packageNames, Filters filters)
+Transaction* Client::resolve(const QStringList& packageNames, Enum::Filters filters)
 {
 	RUN_TRANSACTION(Resolve(Util::filtersToString(filters), packageNames))
 }
 
-Transaction* Client::resolve(const QString& packageName, Filters filters)
+Transaction* Client::resolve(const QString& packageName, Enum::Filters filters)
 {
 	return resolve(QStringList() << packageName, filters);
 }
@@ -424,47 +432,47 @@ Transaction* Client::rollback(Transaction* oldtrans)
 	RUN_TRANSACTION(Rollback(oldtrans->tid()))
 }
 
-Transaction* Client::searchFiles(const QStringList& search, Filters filters)
+Transaction* Client::searchFiles(const QStringList& search, Enum::Filters filters)
 {
 	RUN_TRANSACTION(SearchFiles(Util::filtersToString(filters), search))
 }
 
-Transaction* Client::searchFiles(const QString& search, Filters filters)
+Transaction* Client::searchFiles(const QString& search, Enum::Filters filters)
 {
 	return searchFiles(QStringList() << search, filters);
 }
 
-Transaction* Client::searchDetails(const QStringList& search, Filters filters)
+Transaction* Client::searchDetails(const QStringList& search, Enum::Filters filters)
 {
 	RUN_TRANSACTION(SearchDetails(Util::filtersToString(filters), search))
 }
 
-Transaction* Client::searchDetails(const QString& search, Filters filters)
+Transaction* Client::searchDetails(const QString& search, Enum::Filters filters)
 {
 	return searchDetails(QStringList() << search, filters);
 }
 
-Transaction* Client::searchGroups(Client::Groups groups, Filters filters)
+Transaction* Client::searchGroups(Enum::Groups groups, Enum::Filters filters)
 {
 	QStringList groupsSL;
-	foreach (const Client::Group group, groups) {
-		groupsSL << Util::enumToString<Client>(group, "Group", "Group");
+	foreach (const Enum::Group group, groups) {
+		groupsSL << Util::enumToString<Enum>(group, "Group", "Group");
 	}
 
 	RUN_TRANSACTION(SearchGroups(Util::filtersToString(filters), groupsSL))
 }
 
-Transaction* Client::searchGroups(Client::Group group, Filters filters)
+Transaction* Client::searchGroups(Enum::Group group, Enum::Filters filters)
 {
-	return searchGroups(Groups() << group, filters);
+	return searchGroups(Enum::Groups() << group, filters);
 }
 
-Transaction* Client::searchNames(const QStringList& search, Filters filters)
+Transaction* Client::searchNames(const QStringList& search, Enum::Filters filters)
 {
 	RUN_TRANSACTION(SearchNames(Util::filtersToString(filters), search))
 }
 
-Transaction* Client::searchNames(const QString& search, Filters filters)
+Transaction* Client::searchNames(const QString& search, Enum::Filters filters)
 {
 	return searchNames(QStringList() << search, filters);
 }
@@ -546,12 +554,12 @@ Transaction* Client::updateSystem(bool only_trusted)
 	RUN_TRANSACTION(UpdateSystem(only_trusted))
 }
 
-Transaction* Client::whatProvides(ProvidesType type, const QStringList& search, Filters filters)
+Transaction* Client::whatProvides(Enum::Provides type, const QStringList& search, Enum::Filters filters)
 {
-	RUN_TRANSACTION(WhatProvides(Util::filtersToString(filters), Util::enumToString<Client>(type, "ProvidesType", "Provides"), search))
+	RUN_TRANSACTION(WhatProvides(Util::filtersToString(filters), Util::enumToString<Enum>(type, "Provides", "Provides"), search))
 }
 
-Transaction* Client::whatProvides(ProvidesType type, const QString& search, Filters filters)
+Transaction* Client::whatProvides(Enum::Provides type, const QString& search, Enum::Filters filters)
 {
 	return whatProvides(type, QStringList() << search, filters);
 }
diff --git a/lib/packagekit-qt/src/client.h b/lib/packagekit-qt/src/client.h
index be06b21..6e18e58 100644
--- a/lib/packagekit-qt/src/client.h
+++ b/lib/packagekit-qt/src/client.h
@@ -22,7 +22,7 @@
 #define CLIENT_H
 
 #include <QtCore>
-#include <bitfield.h>
+#include "enum.h"
 
 namespace PackageKit {
 
@@ -50,17 +50,6 @@ class Client : public QObject
 {
 
 	Q_OBJECT
-	Q_ENUMS(Action)
-	Q_ENUMS(Filter)
-	Q_ENUMS(Group)
-	Q_ENUMS(NetworkState)
-	Q_ENUMS(SignatureType)
-	Q_ENUMS(ProvidesType)
-	Q_ENUMS(ErrorType)
-	Q_ENUMS(MessageType)
-	Q_ENUMS(RestartType)
-	Q_ENUMS(UpdateState)
-	Q_ENUMS(DistroUpgradeType)
 
 public:
 	/**
@@ -79,54 +68,9 @@ public:
 	// Daemon functions
 
 	/**
-	 * Lists all the available actions
-	 * \sa getActions
-	 */
-	typedef enum {
-		UnknownAction,
-		ActionCancel,
-		ActionGetDepends,
-		ActionGetDetails,
-		ActionGetFiles,
-		ActionGetPackages,
-		ActionGetRepoList,
-		ActionGetRequires,
-		ActionGetUpdateDetail,
-		ActionGetUpdates,
-		ActionInstallFiles,
-		ActionInstallPackages,
-		ActionInstallSignature,
-		ActionRefreshCache,
-		ActionRemovePackages,
-		ActionRepoEnable,
-		ActionRepoSetData,
-		ActionResolve,
-		ActionRollback,
-		ActionSearchDetails,
-		ActionSearchFile,
-		ActionSearchGroup,
-		ActionSearchName,
-		ActionUpdatePackages,
-		ActionUpdateSystem,
-		ActionWhatProvides,
-		ActionAcceptEula,
-		ActionDownloadPackages,
-		ActionGetDistroUpgrades,
-		ActionGetCategories,
-		ActionGetOldTransactions,
-		ActionSimulateInstallFiles,
-		ActionSimulateInstallPackages,
-		ActionSimulateRemovePackages,
-		ActionSimulateUpdatePackages,
-		/* this always has to be at the end of the list */
-		LastAction
-	} Action;
-	typedef Bitfield Actions;
-
-	/**
 	 * Returns all the actions supported by the current backend
 	 */
-	Actions actions() const;
+	Enum::Roles actions() const;
 
 	/**
 	 * The backend name, e.g. "yum".
@@ -144,92 +88,14 @@ public:
 	QString backendAuthor() const;
 
 	/**
-	 * Describes the different filters
-	 */
-	typedef enum {
-		UnknownFilter		 = 0x0000001,
-		NoFilter		 = 0x0000002,
-		FilterInstalled		 = 0x0000004,
-		FilterNotInstalled	 = 0x0000008,
-		FilterDevelopment	 = 0x0000010,
-		FilterNotDevelopment	 = 0x0000020,
-		FilterGui		 = 0x0000040,
-		FilterNotGui		 = 0x0000080,
-		FilterFree		 = 0x0000100,
-		FilterNotFree		 = 0x0000200,
-		FilterVisible		 = 0x0000400,
-		FilterNotVisible	 = 0x0000800,
-		FilterSupported		 = 0x0001000,
-		FilterNotSupported	 = 0x0002000,
-		FilterBasename		 = 0x0004000,
-		FilterNotBasename	 = 0x0008000,
-		FilterNewest		 = 0x0010000,
-		FilterNotNewest		 = 0x0020000,
-		FilterArch		 = 0x0040000,
-		FilterNotArch		 = 0x0080000,
-		FilterSource		 = 0x0100000,
-		FilterNotSource		 = 0x0200000,
-		FilterCollections	 = 0x0400000,
-		FilterNotCollections	 = 0x0800000,
-		FilterApplication	 = 0x1000000,
-		FilterNotApplication	 = 0x2000000,
-		FilterLast		 = 0x4000000
-	} Filter;
-	Q_DECLARE_FLAGS(Filters, Filter)
-
-	/**
 	 * Returns the filters supported by the current backend
 	 */
-	Filters filters() const;
-
-	/**
-	 * Describes the different groups
-	 */
-	typedef enum {
-		UnknownGroup,
-		GroupAccessibility,
-		GroupAccessories,
-		GroupAdminTools,
-		GroupCommunication,
-		GroupDesktopGnome,
-		GroupDesktopKde,
-		GroupDesktopOther,
-		GroupDesktopXfce,
-		GroupEducation,
-		GroupFonts,
-		GroupGames,
-		GroupGraphics,
-		GroupInternet,
-		GroupLegacy,
-		GroupLocalization,
-		GroupMaps,
-		GroupMultimedia,
-		GroupNetwork,
-		GroupOffice,
-		GroupOther,
-		GroupPowerManagement,
-		GroupProgramming,
-		GroupPublishing,
-		GroupRepos,
-		GroupSecurity,
-		GroupServers,
-		GroupSystem,
-		GroupVirtualization,
-		GroupScience,
-		GroupDocumentation,
-		GroupElectronics,
-		GroupCollections,
-		GroupVendor,
-		GroupNewest,
-		/* this always has to be at the end of the list */
-		LastGroup
-	} Group;
-	typedef QSet<Group> Groups;
+	Enum::Filters filters() const;
 
 	/**
 	 * Returns the groups supported by the current backend
 	 */
-	Groups groups() const;
+	Enum::Groups groups() const;
 
 	/**
 	 * Set when the backend is locked and native tools would fail.
@@ -242,23 +108,9 @@ public:
 	QStringList mimeTypes() const;
 
 	/**
-	 * Describes the current network state
-	 */
-	typedef enum {
-		UnknownNetworkState,
-		NetworkOffline,
-		NetworkOnline,
-		NetworkWired,
-		NetworkWifi,
-		NetworkMobile,
-		/* this always has to be at the end of the list */
-		LastNetworkState
-	} NetworkState;
-
-	/**
 	 * Returns the current network state
 	 */
-	NetworkState networkState() const;
+	Enum::Network networkState() const;
 
 	/**
 	 * The distribution identifier in the
@@ -268,9 +120,17 @@ public:
 	QString distroId() const;
 
 	/**
+	 * Allows a client to find out if it would be allowed to authorize an action.
+	 * The action ID, e.g. org.freedesktop.packagekit.system-network-proxy-configure
+	 * specified in \p actionId
+	 * Returm might be either yes, no or interactive.
+	 */
+	Enum::Authorize canAuthorize(const QString &actionId) const;
+
+	/**
 	 * Returns the time (in seconds) since the specified \p action
 	 */
-	uint getTimeSinceAction(Action action) const;
+	uint getTimeSinceAction(Enum::Role action) const;
 
 	/**
 	 * Returns the list of current transactions
@@ -315,17 +175,6 @@ public:
 	 */
 	void suggestDaemonQuit();
 
-	// Other enums
-	/**
-	 * Describes a signature type
-	 */
-	typedef enum {
-		UnknownSignatureType,
-		SignatureGpg,
-		/* this always has to be at the end of the list */
-		LastSignatureType
-	} SignatureType;
-
 	/**
 	 * Describes a package signature
 	 * \li \c package is a pointer to the signed package
@@ -341,118 +190,10 @@ public:
 		QString keyId;
 		QString keyFingerprint;
 		QString keyTimestamp;
-		SignatureType type;
+		Enum::SigType type;
 	} SignatureInfo;
 
 	/**
-	 * Enum used to describe a "provides" request
-	 * \sa whatProvides
-	 */
-	typedef enum {
-		UnknownProvidesType,
-		ProvidesAny,
-		ProvidesModalias,
-		ProvidesCodec,
-		ProvidesMimetype,
-		ProvidesFont,
-		ProvidesHardwareDriver,
-		ProvidesPostscriptDriver,
-		/* this always has to be at the end of the list */
-		LastProvidesType
-	} ProvidesType;
-
-	/**
-	 * Lists the different types of error
-	 */
-	typedef enum {
-		UnknownErrorType,
-		ErrorOom,
-		ErrorNoNetwork,
-		ErrorNotSupported,
-		ErrorInternalError,
-		ErrorGpgFailure,
-		ErrorPackageIdInvalid,
-		ErrorPackageNotInstalled,
-		ErrorPackageNotFound,
-		ErrorPackageAlreadyInstalled,
-		ErrorPackageDownloadFailed,
-		ErrorGroupNotFound,
-		ErrorGroupListInvalid,
-		ErrorDepResolutionFailed,
-		ErrorFilterInvalid,
-		ErrorCreateThreadFailed,
-		ErrorTransactionError,
-		ErrorTransactionCancelled,
-		ErrorNoCache,
-		ErrorRepoNotFound,
-		ErrorCannotRemoveSystemPackage,
-		ErrorProcessKill,
-		ErrorFailedInitialization,
-		ErrorFailedFinalise,
-		ErrorFailedConfigParsing,
-		ErrorCannotCancel,
-		ErrorCannotGetLock,
-		ErrorNoPackagesToUpdate,
-		ErrorCannotWriteRepoConfig,
-		ErrorLocalInstallFailed,
-		ErrorBadGpgSignature,
-		ErrorMissingGpgSignature,
-		ErrorCannotInstallSourcePackage,
-		ErrorRepoConfigurationError,
-		ErrorNoLicenseAgreement,
-		ErrorFileConflicts,
-		ErrorPackageConflicts,
-		ErrorRepoNotAvailable,
-		ErrorInvalidPackageFile,
-		ErrorPackageInstallBlocked,
-		ErrorPackageCorrupt,
-		ErrorAllPackagesAlreadyInstalled,
-		ErrorFileNotFound,
-		ErrorNoMoreMirrorsToTry,
-		ErrorNoDistroUpgradeData,
-		ErrorIncompatibleArchitecture,
-		ErrorNoSpaceOnDevice,
-		ErrorMediaChangeRequired,
-		ErrorNotAuthorized,
-		ErrorUpdateNotFound,
-		ErrorCannotInstallRepoUnsigned,
-		ErrorCannotUpdateRepoUnsigned,
-		ErrorCannotGetFilelist,
-		ErrorCannotGetRequires,
-		ErrorCannotDisableRepository,
-		ErrorRestrictedDownload,
-		ErrorPackageFailedToConfigure,
-		ErrorPackageFailedToBuild,
-		ErrorPackageFailedToInstall,
-		ErrorPackageFailedToRemove,
-		/* this always has to be at the end of the list */
-		LastErrorType
-	} ErrorType;
-
-	/**
-	 * Describes a message's type
-	 */
-	typedef enum {
-		UnknownMessageType,
-		MessageBrokenMirror,
-		MessageConnectionRefused,
-		MessageParameterInvalid,
-		MessagePriorityInvalid,
-		MessageBackendError,
-		MessageDaemonError,
-		MessageCacheBeingRebuilt,
-		MessageUntrustedPackage,
-		MessageNewerPackageExists,
-		MessageCouldNotFindPackage,
-		MessageConfigFilesChanged,
-		MessagePackageAlreadyInstalled,
-		MessageAutoremoveIgnored,
-		MessageRepoMetadataDownloadFailed,
-		/* this always has to be at the end of the list */
-		LastMessageType
-	} MessageType;
-
-	/**
 	 * Describes an EULA
 	 * \li \c id is the EULA identifier
 	 * \li \c package is the package for which an EULA is required
@@ -467,44 +208,6 @@ public:
 	} EulaInfo;
 
 	/**
-	 * Describes a restart type
-	 */
-	typedef enum {
-		UnknownRestartType,
-		RestartNone,
-		RestartApplication,
-		RestartSession,
-		RestartSystem,
-		RestartSecuritySession,
-		RestartSecuritySystem,
-		/* this always has to be at the end of the list */
-		LastRestartType
-	} RestartType;
-
-	/**
-	 * Describes an update's state
-	 */
-	typedef enum {
-		UnknownUpdateState,
-		UpdateStable,
-		UpdateUnstable,
-		UpdateTesting,
-		/* this always has to be at the end of the list */
-		LastUpdateState
-	} UpdateState;
-
-	/**
-	 * Describes an distro upgrade state
-	 */
-	typedef enum {
-		UnknownDistroUpgrade,
-		DistroUpgradeStable,
-		DistroUpgradeUnstable,
-		/* this always has to be at the end of the list */
-		LastDistroUpgradeType
-	} DistroUpgradeType;
-
-	/**
 	 * Describes an error at the daemon level (for example, PackageKit crashes or is unreachable)
 	 *
 	 * \sa Client::error
@@ -551,10 +254,10 @@ public:
 		QString vendorUrl;
 		QString bugzillaUrl;
 		QString cveUrl;
-		RestartType restart;
+		Enum::Restart restart;
 		QString updateText;
 		QString changelog;
-		UpdateState state;
+		Enum::UpdateState state;
 		QDateTime issued;
 		QDateTime updated;
 	} UpdateInfo;
@@ -614,8 +317,8 @@ public:
 	 * \sa Transaction::package
 	 *
 	 */
-	Transaction* getDepends(const QList<Package*>& packages, Filters filters, bool recursive);
-	Transaction* getDepends(Package* package, Filters filters , bool recursive);
+	Transaction* getDepends(const QList<Package*>& packages, Enum::Filters filters, bool recursive);
+	Transaction* getDepends(Package* package, Enum::Filters filters , bool recursive);
 
 	/**
 	 * Gets more details about the given \p packages
@@ -645,12 +348,12 @@ public:
 	 *
 	 * \sa Transaction::package
 	 */
-	Transaction* getPackages(Filters filters = NoFilter);
+	Transaction* getPackages(Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * Gets the list of software repositories matching the given \p filters
 	 */
-	Transaction* getRepoList(Filters filter = NoFilter);
+	Transaction* getRepoList(Enum::Filters filter = Enum::NoFilter);
 
 	/**
 	 * \brief Searches for the packages requiring the given \p packages
@@ -658,8 +361,8 @@ public:
 	 * The search can be limited using the \p filters parameter. The recursive flag is used to tell
 	 * if the package manager should also search for the package requiring the resulting packages.
 	 */
-	Transaction* getRequires(const QList<Package*>& packages, Filters filters, bool recursive);
-	Transaction* getRequires(Package* package, Filters filters, bool recursive);
+	Transaction* getRequires(const QList<Package*>& packages, Enum::Filters filters, bool recursive);
+	Transaction* getRequires(Package* package, Enum::Filters filters, bool recursive);
 
 	/**
 	 * Retrieves more details about the update for the given \p packages
@@ -672,7 +375,7 @@ public:
 	 *
 	 * The \p filters parameters can be used to restrict the updates returned
 	 */
-	Transaction* getUpdates(Filters filters = NoFilter);
+	Transaction* getUpdates(Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * Retrieves the available distribution upgrades
@@ -700,7 +403,7 @@ public:
 	 *
 	 * \p type, \p key_id and \p p generally come from the Transaction::repoSignatureRequired
 	 */
-	Transaction* installSignature(SignatureType type, const QString& key_id, Package* p);
+	Transaction* installSignature(Enum::SigType type, const QString& key_id, Package* p);
 
 	/**
 	 * Refreshes the package manager's cache
@@ -732,8 +435,8 @@ public:
 	 *
 	 * The \p filters can be used to restrict the search
 	 */
-	Transaction* resolve(const QStringList& packageNames, Filters filters = NoFilter);
-	Transaction* resolve(const QString& packageName, Filters filters = NoFilter);
+	Transaction* resolve(const QStringList& packageNames, Enum::Filters filters = Enum::NoFilter);
+	Transaction* resolve(const QString& packageName, Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * Rolls back the given \p transactions
@@ -745,32 +448,32 @@ public:
 	 *
 	 * \p filters can be used to restrict the returned packages
 	 */
-	Transaction* searchFiles(const QStringList& search, Filters filters = NoFilter);
-	Transaction* searchFiles(const QString& search, Filters filters = NoFilter);
+	Transaction* searchFiles(const QStringList& search, Enum::Filters filters = Enum::NoFilter);
+	Transaction* searchFiles(const QString& search, Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * \brief Search in the packages details
 	 *
 	 * \p filters can be used to restrict the returned packages
 	 */
-	Transaction* searchDetails(const QStringList& search, Filters filters = NoFilter);
-	Transaction* searchDetails(const QString& search, Filters filters = NoFilter);
+	Transaction* searchDetails(const QStringList& search, Enum::Filters filters = Enum::NoFilter);
+	Transaction* searchDetails(const QString& search, Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * \brief Lists all the packages in the given \p group
 	 *
 	 * \p filters can be used to restrict the returned packages
 	 */
-	Transaction* searchGroups(Client::Groups group, Filters filters = NoFilter);
-	Transaction* searchGroups(Client::Group group, Filters filters = NoFilter);
+	Transaction* searchGroups(Enum::Groups group, Enum::Filters filters = Enum::NoFilter);
+	Transaction* searchGroups(Enum::Group group, Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * \brief Search in the packages names
 	 *
 	 * \p filters can be used to restrict the returned packages
 	 */
-	Transaction* searchNames(const QStringList& search, Filters filters = NoFilter);
-	Transaction* searchNames(const QString& search, Filters filters = NoFilter);
+	Transaction* searchNames(const QStringList& search, Enum::Filters filters = Enum::NoFilter);
+	Transaction* searchNames(const QString& search, Enum::Filters filters = Enum::NoFilter);
 
 	/**
 	 * \brief Tries to find a package name from a desktop file
@@ -838,8 +541,8 @@ public:
 	/**
 	 * Searchs for a package providing a file/a mimetype
 	 */
-	Transaction* whatProvides(ProvidesType type, const QStringList& search, Filters filters = NoFilter);
-	Transaction* whatProvides(ProvidesType type, const QString& search, Filters filters = NoFilter);
+	Transaction* whatProvides(Enum::Provides type, const QStringList& search, Enum::Filters filters = Enum::NoFilter);
+	Transaction* whatProvides(Enum::Provides type, const QString& search, Enum::Filters filters = Enum::NoFilter);
 
 Q_SIGNALS:
 	/**
@@ -889,7 +592,6 @@ private:
 
 	void destroyTransaction(const QString &tid);
 };
-Q_DECLARE_OPERATORS_FOR_FLAGS(Client::Filters)
 
 } // End namespace PackageKit
 
diff --git a/lib/packagekit-qt/src/clientprivate.cpp b/lib/packagekit-qt/src/clientprivate.cpp
index e96029c..179f5c8 100644
--- a/lib/packagekit-qt/src/clientprivate.cpp
+++ b/lib/packagekit-qt/src/clientprivate.cpp
@@ -85,7 +85,7 @@ void ClientPrivate::serviceOwnerChanged (const QString& name, const QString& old
 	c->error(error);
 
 	foreach(Transaction *t, runningTransactions) {
-		t->finished (Transaction::ExitFailed, 0);
+		t->finished (Enum::ExitFailed, 0);
 		t->d_ptr->destroy ();
 	}
 }
diff --git a/lib/packagekit-qt/src/enum.cpp b/lib/packagekit-qt/src/enum.cpp
deleted file mode 100644
index d9d08d8..0000000
--- a/lib/packagekit-qt/src/enum.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * This file is part of the QPackageKit project
- * Copyright (C) 2008 Adrien Bustany <madcat at mymadcat.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "enum.h"
-#include "util.h"
-
-using namespace PackageKit;
-
-Enum::Enum() : QObject(NULL)
-{
-}
diff --git a/lib/packagekit-qt/src/enum.h b/lib/packagekit-qt/src/enum.h
index 235e6bc..095e744 100644
--- a/lib/packagekit-qt/src/enum.h
+++ b/lib/packagekit-qt/src/enum.h
@@ -23,27 +23,363 @@
 #define ENUM_H
 
 #include <QtCore>
+#include "bitfield.h"
 
 namespace PackageKit {
 
 /**
- * \class Package package.h Package
+ * \class Enum enum.h Enum
  * \author Adrien Bustany <madcat at mymadcat.com>
  *
- * \brief Represents a software package
+ * \brief Represents a PackageKit's enums
  *
- * This class represents a software package.
+ * This class represents a PackageKit enums.
  *
- * \note All Package objects should be deleted by the user.
  */
 class Enum : public QObject
 {
 	Q_OBJECT
-	Q_ENUMS(PackageInfo)
+	Q_ENUMS(Role)
+	Q_ENUMS(Status)
+	Q_ENUMS(Exit)
+	Q_ENUMS(Network)
+	Q_ENUMS(Filter)
+	Q_ENUMS(Restart)
+	Q_ENUMS(Message)
+	Q_ENUMS(Error)
+	Q_ENUMS(Group)
+	Q_ENUMS(UpdateState)
+	Q_ENUMS(Info)
+	Q_ENUMS(DistroUpgrade)
+	Q_ENUMS(SigType)
+	Q_ENUMS(Provides)
 	Q_ENUMS(License)
-
+	Q_ENUMS(MediaType)
+	Q_ENUMS(Authorize)
 public:
 	/**
+	 * Lists all the available actions
+	 * \sa getActions
+	 */
+	typedef enum {
+		UnknownRole,
+		RoleCancel,
+		RoleGetDepends,
+		RoleGetDetails,
+		RoleGetFiles,
+		RoleGetPackages,
+		RoleGetRepoList,
+		RoleGetRequires,
+		RoleGetUpdateDetail,
+		RoleGetUpdates,
+		RoleInstallFiles,
+		RoleInstallPackages,
+		RoleInstallSignature,
+		RoleRefreshCache,
+		RoleRemovePackages,
+		RoleRepoEnable,
+		RoleRepoSetData,
+		RoleResolve,
+		RoleRollback,
+		RoleSearchDetails,
+		RoleSearchFile,
+		RoleSearchGroup,
+		RoleSearchName,
+		RoleUpdatePackages,
+		RoleUpdateSystem,
+		RoleWhatProvides,
+		RoleAcceptEula,
+		RoleDownloadPackages,
+		RoleGetDistroUpgrades,
+		RoleGetCategories,
+		RoleGetOldTransactions,
+		RoleSimulateInstallFiles,
+		RoleSimulateInstallPackages,
+		RoleSimulateRemovePackages,
+		RoleSimulateUpdatePackages,
+		/* this always has to be at the end of the list */
+		LastRole
+	} Role;
+	typedef Bitfield Roles;
+
+	/**
+	 * Describes the current state of the transaction
+	 */
+	typedef enum {
+		UnknownStatus,
+		StatusWait,
+		StatusSetup,
+		StatusRunning,
+		StatusQuery,
+		StatusInfo,
+		StatusRemove,
+		StatusRefreshCache,
+		StatusDownload,
+		StatusInstall,
+		StatusUpdate,
+		StatusCleanup,
+		StatusObsolete,
+		StatusDepResolve,
+		StatusSigCheck,
+		StatusRollback,
+		StatusTestCommit,
+		StatusCommit,
+		StatusRequest,
+		StatusFinished,
+		StatusCancel,
+		StatusDownloadRepository,
+		StatusDownloadPackagelist,
+		StatusDownloadFilelist,
+		StatusDownloadChangelog,
+		StatusDownloadGroup,
+		StatusDownloadUpdateinfo,
+		StatusRepackaging,
+		StatusLoadingCache,
+		StatusScanApplications,
+		StatusGeneratePackageList,
+		StatusWaitingForLock,
+		StatusWaitingForAuth,
+		StatusScanProcessList,
+		StatusCheckExecutableFiles,
+		StatusCheckLibraries,
+		StatusCopyFiles,
+		/* this always has to be at the end of the list */
+		LastStatus
+	} Status;
+
+	/**
+	 * Describes how the transaction finished
+	 * \sa Transaction::finished()
+	 */
+	typedef enum {
+		UnknownExit,
+		ExitSuccess,
+		ExitFailed,
+		ExitCancelled,
+		ExitKeyRequired,
+		ExitEulaRequired,
+		ExitKilled, /* when we forced the cancel, but had to sigkill */
+		ExitMediaChangeRequired,
+		ExitNeedUntrusted,
+		/* this always has to be at the end of the list */
+		LastExit
+	} Exit;
+
+	/**
+	 * Describes the current network state
+	 */
+	typedef enum {
+		UnknownNetwork,
+		NetworkOffline,
+		NetworkOnline,
+		NetworkWired,
+		NetworkWifi,
+		NetworkMobile,
+		/* this always has to be at the end of the list */
+		LastNetwork
+	} Network;
+
+		/**
+	 * Describes the different filters
+	 */
+	typedef enum {
+		UnknownFilter		 = 0x0000001,
+		NoFilter		 = 0x0000002,
+		FilterInstalled		 = 0x0000004,
+		FilterNotInstalled	 = 0x0000008,
+		FilterDevelopment	 = 0x0000010,
+		FilterNotDevelopment	 = 0x0000020,
+		FilterGui		 = 0x0000040,
+		FilterNotGui		 = 0x0000080,
+		FilterFree		 = 0x0000100,
+		FilterNotFree		 = 0x0000200,
+		FilterVisible		 = 0x0000400,
+		FilterNotVisible	 = 0x0000800,
+		FilterSupported		 = 0x0001000,
+		FilterNotSupported	 = 0x0002000,
+		FilterBasename		 = 0x0004000,
+		FilterNotBasename	 = 0x0008000,
+		FilterNewest		 = 0x0010000,
+		FilterNotNewest		 = 0x0020000,
+		FilterArch		 = 0x0040000,
+		FilterNotArch		 = 0x0080000,
+		FilterSource		 = 0x0100000,
+		FilterNotSource		 = 0x0200000,
+		FilterCollections	 = 0x0400000,
+		FilterNotCollections	 = 0x0800000,
+		FilterApplication	 = 0x1000000,
+		FilterNotApplication	 = 0x2000000,
+		/* this always has to be at the end of the list */
+		FilterLast		 = 0x4000000
+	} Filter;
+	Q_DECLARE_FLAGS(Filters, Filter)
+
+	/**
+	 * Describes a restart type
+	 */
+	typedef enum {
+		UnknownRestart,
+		RestartNone,
+		RestartApplication,
+		RestartSession,
+		RestartSystem,
+		RestartSecuritySession,
+		RestartSecuritySystem,
+		/* this always has to be at the end of the list */
+		LastRestart
+	} Restart;
+
+	/**
+	 * Describes a message's type
+	 */
+	typedef enum {
+		UnknownMessage,
+		MessageBrokenMirror,
+		MessageConnectionRefused,
+		MessageParameterInvalid,
+		MessagePriorityInvalid,
+		MessageBackendError,
+		MessageDaemonError,
+		MessageCacheBeingRebuilt,
+		MessageUntrustedPackage,
+		MessageNewerPackageExists,
+		MessageCouldNotFindPackage,
+		MessageConfigFilesChanged,
+		MessagePackageAlreadyInstalled,
+		MessageAutoremoveIgnored,
+		MessageRepoMetadataDownloadFailed,
+		MessageRepoForDevelopersOnly,
+		/* this always has to be at the end of the list */
+		LastMessage
+	} Message;
+
+	/**
+	 * Lists the different types of error
+	 */
+	typedef enum {
+		UnknownError,
+		ErrorOom,
+		ErrorNoNetwork,
+		ErrorNotSupported,
+		ErrorInternalError,
+		ErrorGpgFailure,
+		ErrorPackageIdInvalid,
+		ErrorPackageNotInstalled,
+		ErrorPackageNotFound,
+		ErrorPackageAlreadyInstalled,
+		ErrorPackageDownloadFailed,
+		ErrorGroupNotFound,
+		ErrorGroupListInvalid,
+		ErrorDepResolutionFailed,
+		ErrorFilterInvalid,
+		ErrorCreateThreadFailed,
+		ErrorTransactionError,
+		ErrorTransactionCancelled,
+		ErrorNoCache,
+		ErrorRepoNotFound,
+		ErrorCannotRemoveSystemPackage,
+		ErrorProcessKill,
+		ErrorFailedInitialization,
+		ErrorFailedFinalise,
+		ErrorFailedConfigParsing,
+		ErrorCannotCancel,
+		ErrorCannotGetLock,
+		ErrorNoPackagesToUpdate,
+		ErrorCannotWriteRepoConfig,
+		ErrorLocalInstallFailed,
+		ErrorBadGpgSignature,
+		ErrorMissingGpgSignature,
+		ErrorCannotInstallSourcePackage,
+		ErrorRepoConfigurationError,
+		ErrorNoLicenseAgreement,
+		ErrorFileConflicts,
+		ErrorPackageConflicts,
+		ErrorRepoNotAvailable,
+		ErrorInvalidPackageFile,
+		ErrorPackageInstallBlocked,
+		ErrorPackageCorrupt,
+		ErrorAllPackagesAlreadyInstalled,
+		ErrorFileNotFound,
+		ErrorNoMoreMirrorsToTry,
+		ErrorNoDistroUpgradeData,
+		ErrorIncompatibleArchitecture,
+		ErrorNoSpaceOnDevice,
+		ErrorMediaChangeRequired,
+		ErrorNotAuthorized,
+		ErrorUpdateNotFound,
+		ErrorCannotInstallRepoUnsigned,
+		ErrorCannotUpdateRepoUnsigned,
+		ErrorCannotGetFilelist,
+		ErrorCannotGetRequires,
+		ErrorCannotDisableRepository,
+		ErrorRestrictedDownload,
+		ErrorPackageFailedToConfigure,
+		ErrorPackageFailedToBuild,
+		ErrorPackageFailedToInstall,
+		ErrorPackageFailedToRemove,
+		ErrorUpdateFailedDueToRunningProcess,
+		ErrorPackageDatabaseChanged,
+		/* this always has to be at the end of the list */
+		LastError
+	} Error;
+
+	/**
+	 * Describes the different groups
+	 */
+	typedef enum {
+		UnknownGroup,
+		GroupAccessibility,
+		GroupAccessories,
+		GroupAdminTools,
+		GroupCommunication,
+		GroupDesktopGnome,
+		GroupDesktopKde,
+		GroupDesktopOther,
+		GroupDesktopXfce,
+		GroupEducation,
+		GroupFonts,
+		GroupGames,
+		GroupGraphics,
+		GroupInternet,
+		GroupLegacy,
+		GroupLocalization,
+		GroupMaps,
+		GroupMultimedia,
+		GroupNetwork,
+		GroupOffice,
+		GroupOther,
+		GroupPowerManagement,
+		GroupProgramming,
+		GroupPublishing,
+		GroupRepos,
+		GroupSecurity,
+		GroupServers,
+		GroupSystem,
+		GroupVirtualization,
+		GroupScience,
+		GroupDocumentation,
+		GroupElectronics,
+		GroupCollections,
+		GroupVendor,
+		GroupNewest,
+		/* this always has to be at the end of the list */
+		LastGroup
+	} Group;
+	typedef QSet<Group> Groups;
+
+	/**
+	 * Describes an update's state
+	 */
+	typedef enum {
+		UnknownUpdateState,
+		UpdateStateStable,
+		UpdateStateUnstable,
+		UpdateStateTesting,
+		/* this always has to be at the end of the list */
+		LastUpdateState
+	} UpdateState;
+
+	/**
 	 * Describes the state of a package
 	 */
 	typedef enum {
@@ -69,10 +405,51 @@ public:
 		InfoReinstalling,
 		InfoDowngrading,
 		InfoPreparing,
-		InfoDecompressing
+		InfoDecompressing,
+		/* this always has to be at the end of the list */
+		LastInfo
 	} Info;
 
 	/**
+	 * Describes an distro upgrade state
+	 */
+	typedef enum {
+		UnknownDistroUpgrade,
+		DistroUpgradeStable,
+		DistroUpgradeUnstable,
+		/* this always has to be at the end of the list */
+		LastDistroUpgrade
+	} DistroUpgrade;
+
+	/**
+	 * Describes a signature type
+	 */
+	typedef enum {
+		UnknownSigType,
+		SigTypeGpg,
+		/* this always has to be at the end of the list */
+		LastSigType
+	} SigType;
+
+
+	/**
+	 * Enum used to describe a "provides" request
+	 * \sa whatProvides
+	 */
+	typedef enum {
+		UnknownProvides,
+		ProvidesAny,
+		ProvidesModalias,
+		ProvidesCodec,
+		ProvidesMimetype,
+		ProvidesFont,
+		ProvidesHardwareDriver,
+		ProvidesPostscriptDriver,
+		/* this always has to be at the end of the list */
+		LastProvides
+	} Provides;
+
+	/**
 	 * Describes a package's license
 	 */
 	typedef enum {
@@ -201,11 +578,36 @@ public:
 		LicenseVostrom,
 		LicenseXerox,
 		LicenseRicebsd,
-		LicenseQhull
+		LicenseQhull,
+		/* this always has to be at the end of the list */
+		LastLicense
 	} License;
 
-	Enum();
+	/**
+	 * Describes what kind of media is required
+	 */
+	typedef enum {
+		UnknownMediaType,
+		MediaTypeCd,
+		MediaTypeDvd,
+		MediaTypeDisc,
+		/* this always has to be at the end of the list */
+		LastMediaType
+	} MediaType;
+
+	/**
+	 * Describes the authorization result
+	 */
+	typedef enum {
+		UnknownAuthorize,
+		AuthorizeYes,
+		AuthorizeNo,
+		AuthorizeInteractive,
+		/* this always has to be at the end of the list */
+		LastAuthorize
+	} Authorize;
 };
+Q_DECLARE_OPERATORS_FOR_FLAGS(Enum::Filters)
 
 } // End namespace PackageKit
 
diff --git a/lib/packagekit-qt/src/package.cpp b/lib/packagekit-qt/src/package.cpp
index 117eae6..97b2b9a 100644
--- a/lib/packagekit-qt/src/package.cpp
+++ b/lib/packagekit-qt/src/package.cpp
@@ -31,7 +31,7 @@ class Package::DetailsPrivate
 public:
 	Package* package;
 	QString license;
-	Client::Group group;
+	Enum::Group group;
 	QString description;
 	QString url;
 	uint size;
@@ -42,7 +42,7 @@ Package::Details::Details(Package* p, const QString& license, const QString& gro
 	Q_D(Details);
 	d->package = p;
 	d->license = license;
-	d->group = (Client::Group)Util::enumFromString<Client>(group, "Group", "Group");
+	d->group = (Enum::Group)Util::enumFromString<Enum>(group, "Group", "Group");
 	d->description = detail;
 	d->url = url;
 	d->size = size;
@@ -65,7 +65,7 @@ QString Package::Details::license() const
 	return d->license;
 }
 
-Client::Group Package::Details::group() const
+Enum::Group Package::Details::group() const
 {
 	Q_D(const Details);
 	return d->group;
diff --git a/lib/packagekit-qt/src/package.h b/lib/packagekit-qt/src/package.h
index 0bc8a76..69d0de5 100644
--- a/lib/packagekit-qt/src/package.h
+++ b/lib/packagekit-qt/src/package.h
@@ -109,7 +109,7 @@ public:
 			/**
 			 * Returns the package's group (for example Multimedia, Editors...)
 			 */
-			Client::Group group() const;
+			Enum::Group group() const;
 
 			/**
 			 * Returns the package's long description
diff --git a/lib/packagekit-qt/src/transaction.cpp b/lib/packagekit-qt/src/transaction.cpp
index a24d0dc..739f0a8 100644
--- a/lib/packagekit-qt/src/transaction.cpp
+++ b/lib/packagekit-qt/src/transaction.cpp
@@ -22,6 +22,7 @@
 #include "common.h"
 #include "transactionprivate.h"
 #include "transactionproxy.h"
+#include "package.h"
 #include "util.h"
 
 using namespace PackageKit;
@@ -67,7 +68,7 @@ Transaction::Transaction(const QString& tid, const QString& timespec, bool succe
 	d->tid = tid;
 	d->timespec = QDateTime::fromString(timespec, Qt::ISODate);
 	d->succeeded = succeeded;
-	d->role = (Client::Action)Util::enumFromString<Client>(role, "Action", "Action");
+	d->role = (Enum::Role)Util::enumFromString<Enum>(role, "Role", "Role");
 	d->duration = duration;
 	d->data = data;
 	d->uid = uid;
@@ -150,13 +151,13 @@ uint Transaction::speed() const
 	return d->p->speed ();
 }
 
-Client::Action Transaction::role() const
+Enum::Role Transaction::role() const
 {
 	Q_D(const Transaction);
 	if(d->oldtrans)
 		return d->role;
 
-	return (Client::Action) Util::enumFromString<Client>(d->p->role (), "Action", "Action");
+	return (Enum::Role) Util::enumFromString<Enum>(d->p->role (), "Role", "Role");
 }
 
 void Transaction::setHints(const QStringList& hints)
@@ -170,10 +171,10 @@ void Transaction::setHints(const QString& hints)
 	setHints(QStringList() << hints);
 }
 
-Transaction::Status Transaction::status() const
+Enum::Status Transaction::status() const
 {
 	Q_D(const Transaction);
-	return (Transaction::Status) Util::enumFromString<Transaction>(d->p->status (), "Status", "Status");
+	return (Enum::Status) Util::enumFromString<Enum>(d->p->status (), "Status", "Status");
 }
 
 QDateTime Transaction::timespec() const
diff --git a/lib/packagekit-qt/src/transaction.h b/lib/packagekit-qt/src/transaction.h
index 70fd977..01f1819 100644
--- a/lib/packagekit-qt/src/transaction.h
+++ b/lib/packagekit-qt/src/transaction.h
@@ -22,7 +22,7 @@
 #define TRANSACTION_H
 
 #include <QtCore>
-#include "package.h"
+#include "enum.h"
 #include "client.h"
 
 namespace PackageKit {
@@ -49,10 +49,6 @@ class TransactionPrivate;
 class Transaction : public QObject
 {
 	Q_OBJECT
-	Q_ENUMS(TransactionError)
-	Q_ENUMS(Status)
-	Q_ENUMS(ExitStatus)
-	Q_ENUMS(MediaType)
 
 public:
 	/**
@@ -136,9 +132,9 @@ public:
 
 	/**
 	 * Returns information describing the transaction
-	 * \return the current action of the transaction
+	 * \return the current role of the transaction
 	 */
-	Client::Action role() const;
+	Enum::Role role() const;
 
 	/**
 	 * \brief Tells the underlying package manager to use the given \p hints
@@ -162,52 +158,10 @@ public:
 	void setHints(const QStringList& hints);
 
 	/**
-	 * Describes the current state of the transaction
-	 */
-	typedef enum {
-		UnknownStatus,
-		StatusWait,
-		StatusSetup,
-		StatusRunning,
-		StatusQuery,
-		StatusInfo,
-		StatusRemove,
-		StatusRefreshCache,
-		StatusDownload,
-		StatusInstall,
-		StatusUpdate,
-		StatusCleanup,
-		StatusObsolete,
-		StatusDepResolve,
-		StatusSigCheck,
-		StatusRollback,
-		StatusTestCommit,
-		StatusCommit,
-		StatusRequest,
-		StatusFinished,
-		StatusCancel,
-		StatusDownloadRepository,
-		StatusDownloadPackagelist,
-		StatusDownloadFilelist,
-		StatusDownloadChangelog,
-		StatusDownloadGroup,
-		StatusDownloadUpdateinfo,
-		StatusRepackaging,
-		StatusLoadingCache,
-		StatusScanApplications,
-		StatusGeneratePackageList,
-		StatusWaitingForLock,
-		StatusWaitingForAuth,
-		StatusScanProcessList,
-		StatusCheckExecutableFiles,
-		StatusCheckLibraries,
-		StatusCopyFiles
-	} Status;
-	/**
 	 * Returns the current state of the transaction
 	 * \return a Transaction::Status value describing the status of the transaction
 	 */
-	Status status() const;
+	Enum::Status status() const;
 
 	/**
 	 * Returns the date at which the transaction was created
@@ -251,32 +205,6 @@ public:
 	 */
 	QString cmdline() const;
 
-	/**
-	 * Describes how the transaction finished
-	 * \sa finished()
-	 */
-	typedef enum {
-		UnknownExitStatus,
-		ExitSuccess,
-		ExitFailed,
-		ExitCancelled,
-		ExitKeyRequired,
-		ExitEulaRequired,
-		ExitKilled, /* when we forced the cancel, but had to sigkill */
-		ExitMediaChangeRequired,
-		ExitNeedUntrusted
-	} ExitStatus;
-
-	/**
-	 * Describes what kind of media is required
-	 */
-	typedef enum {
-		UnknownMediaType,
-		MediaCd,
-		MediaDvd,
-		MediaDisc
-	} MediaType;
-
 public Q_SLOTS:
 	/**
 	 * Cancels the transaction
@@ -317,12 +245,12 @@ Q_SIGNALS:
 	 * Emitted when a distribution upgrade is available
 	 * \sa Client::getDistroUpgrades
 	 */
-	void distroUpgrade(PackageKit::Client::DistroUpgradeType type, const QString& name, const QString& description);
+	void distroUpgrade(PackageKit::Enum::DistroUpgrade type, const QString& name, const QString& description);
 
 	/**
 	 * Emitted when an error occurs
 	 */
-	void errorCode(PackageKit::Client::ErrorType error, const QString& details);
+	void errorCode(PackageKit::Enum::Error error, const QString& details);
 
 	/**
 	 * Emitted when an EULA agreement prevents the transaction from running
@@ -337,7 +265,7 @@ Q_SIGNALS:
 	 * \note You will need to relaunch the transaction after changing the media
 	 * \sa Transaction::MediaType
 	 */
-	void mediaChangeRequired(PackageKit::Transaction::MediaType type, const QString& id, const QString& text);
+	void mediaChangeRequired(PackageKit::Enum::MediaType type, const QString& id, const QString& text);
 
 	/**
 	 * Sends the \p filenames contained in package \p p
@@ -350,14 +278,14 @@ Q_SIGNALS:
 	 *
 	 * \p status describes the exit status, \p runtime is the number of seconds it took to complete the transaction
 	 */
-	void finished(PackageKit::Transaction::ExitStatus status, uint runtime);
+	void finished(PackageKit::Enum::Exit status, uint runtime);
 
 	/**
 	 * Conveys a message sent from the backend
 	 *
 	 * \p type is the type of the \p message
 	 */
-	void message(PackageKit::Client::MessageType type, const QString& message);
+	void message(PackageKit::Enum::Message type, const QString& message);
 
 	/**
 	 * Emitted when the transaction sends a new package
@@ -379,7 +307,7 @@ Q_SIGNALS:
 	 * Indicates that a restart is required
 	 * \p package is the package who triggered the restart signal
 	 */
-	void requireRestart(PackageKit::Client::RestartType type, Package* p);
+	void requireRestart(PackageKit::Enum::Restart type, Package* p);
 
 	/**
 	 * Sends an old transaction
diff --git a/lib/packagekit-qt/src/transactionprivate.cpp b/lib/packagekit-qt/src/transactionprivate.cpp
index ea07b2d..c1f3b40 100644
--- a/lib/packagekit-qt/src/transactionprivate.cpp
+++ b/lib/packagekit-qt/src/transactionprivate.cpp
@@ -20,6 +20,7 @@
 
 #include "transactionprivate.h"
 #include "transaction.h"
+#include "package.h"
 #include "util.h"
 
 using namespace PackageKit;
@@ -50,12 +51,12 @@ void TransactionPrivate::details(const QString& pid, const QString& license, con
 
 void TransactionPrivate::distroUpgrade(const QString& type, const QString& name, const QString& description)
 {
-	t->distroUpgrade((Client::DistroUpgradeType)Util::enumFromString<Client>(type, "DistroUpgradeType", "DistroUpgrade"), name, description);
+	t->distroUpgrade((Enum::DistroUpgrade)Util::enumFromString<Enum>(type, "DistroUpgrade", "DistroUpgrade"), name, description);
 }
 
 void TransactionPrivate::errorCode(const QString& error, const QString& details)
 {
-	t->errorCode((Client::ErrorType)Util::enumFromString<Client>(error, "ErrorType", "Error"), details);
+	t->errorCode((Enum::Error)Util::enumFromString<Enum>(error, "Error", "Error"), details);
 }
 
 void TransactionPrivate::eulaRequired(const QString& eulaId, const QString& pid, const QString& vendor, const QString& licenseAgreement)
@@ -70,7 +71,7 @@ void TransactionPrivate::eulaRequired(const QString& eulaId, const QString& pid,
 
 void TransactionPrivate::mediaChangeRequired(const QString& mediaType, const QString& mediaId, const QString& mediaText)
 {
-	t->mediaChangeRequired((Transaction::MediaType)Util::enumFromString<Transaction>(mediaType, "MediaType", "Media"), mediaId, mediaText);
+	t->mediaChangeRequired((Enum::MediaType)Util::enumFromString<Enum>(mediaType, "MediaType", "Media"), mediaId, mediaText);
 }
 
 void TransactionPrivate::files(const QString& pid, const QString& filenames)
@@ -80,8 +81,8 @@ void TransactionPrivate::files(const QString& pid, const QString& filenames)
 
 void TransactionPrivate::finished(const QString& exitCode, uint runtime)
 {
-	int exitValue = Util::enumFromString<Transaction>(exitCode, "ExitStatus", "Exit");
-	t->finished((Transaction::ExitStatus)exitValue, runtime);
+	int exitValue = Util::enumFromString<Enum>(exitCode, "Exit", "Exit");
+	t->finished((Enum::Exit)exitValue, runtime);
 }
 
 void TransactionPrivate::destroy()
@@ -92,7 +93,7 @@ void TransactionPrivate::destroy()
 
 void TransactionPrivate::message(const QString& type, const QString& message)
 {
-	t->message((Client::MessageType)Util::enumFromString<Client>(type, "MessageType", "Message"), message);
+	t->message((Enum::Message)Util::enumFromString<Enum>(type, "Message", "Message"), message);
 }
 
 void TransactionPrivate::package(const QString& info, const QString& pid, const QString& summary)
@@ -110,14 +111,14 @@ void TransactionPrivate::repoSignatureRequired(const QString& pid, const QString
 	i.keyId = keyId;
 	i.keyFingerprint = keyFingerprint;
 	i.keyTimestamp = keyTimestamp;
-	i.type = (Client::SignatureType)Util::enumFromString<Client>(type, "SignatureType", "Signature");
+	i.type = (Enum::SigType)Util::enumFromString<Enum>(type, "SigType", "Signature");
 
 	t->repoSignatureRequired(i);
 }
 
 void TransactionPrivate::requireRestart(const QString& type, const QString& pid)
 {
-	t->requireRestart((Client::RestartType)Util::enumFromString<Client>(type, "RestartType", "Restart"), new Package(pid));
+	t->requireRestart((Enum::Restart)Util::enumFromString<Enum>(type, "Restart", "Restart"), new Package(pid));
 }
 
 void TransactionPrivate::transaction(const QString& oldTid, const QString& timespec, bool succeeded, const QString& role, uint duration, const QString& data, uint uid, const QString& cmdline)
@@ -142,10 +143,10 @@ void TransactionPrivate::updateDetail(const QString& pid, const QString& updates
 	i.vendorUrl = vendorUrl;
 	i.bugzillaUrl = bugzillaUrl;
 	i.cveUrl = cveUrl;
-	i.restart = (Client::RestartType)Util::enumFromString<Client>(restart, "RestartType", "Restart");
+	i.restart = (Enum::Restart)Util::enumFromString<Enum>(restart, "Restart", "Restart");
 	i.updateText = updateText;
 	i.changelog = changelog;
-	i.state = (Client::UpdateState)Util::enumFromString<Client>(state, "UpdateState", "Update");
+	i.state = (Enum::UpdateState)Util::enumFromString<Enum>(state, "UpdateState", "Update");
 	i.issued = QDateTime::fromString(issued, Qt::ISODate);
 	i.updated = QDateTime::fromString(updated, Qt::ISODate);
 
diff --git a/lib/packagekit-qt/src/transactionprivate.h b/lib/packagekit-qt/src/transactionprivate.h
index ab00a10..7131bae 100644
--- a/lib/packagekit-qt/src/transactionprivate.h
+++ b/lib/packagekit-qt/src/transactionprivate.h
@@ -22,6 +22,7 @@
 #define TRANSACTIONPRIVATE_H
 
 #include <QtCore>
+#include "enum.h"
 #include "client.h"
 
 namespace PackageKit {
@@ -44,7 +45,7 @@ public:
 	// Only used for old transactions
 	bool oldtrans;
 	QDateTime timespec;
-	Client::Action role;
+	Enum::Role role;
 	bool succeeded;
 	uint duration;
 	QString data;
diff --git a/lib/packagekit-qt/src/util.cpp b/lib/packagekit-qt/src/util.cpp
index 11473ec..285f60d 100644
--- a/lib/packagekit-qt/src/util.cpp
+++ b/lib/packagekit-qt/src/util.cpp
@@ -32,12 +32,12 @@ QStringList Util::packageListToPids(const QList<Package*>& packages)
 	return pids;
 }
 
-QString Util::filtersToString(const QFlags<PackageKit::Client::Filter>& flags)
+QString Util::filtersToString(const QFlags<PackageKit::Enum::Filter>& flags)
 {
 	QStringList flagStrings;
-	for (int i = Client::UnknownFilter; i < Client::FilterLast; i *= 2) {
-		if ((Client::Filter) i & flags) {
-			flagStrings.append(Util::enumToString<Client>((Client::Filter) i, "Filter", "Filter"));
+	for (int i = Enum::UnknownFilter; i < Enum::FilterLast; i *= 2) {
+		if ((Enum::Filter) i & flags) {
+			flagStrings.append(Util::enumToString<Client>((Enum::Filter) i, "Filter", "Filter"));
 		}
 	}
 
diff --git a/lib/packagekit-qt/src/util.h b/lib/packagekit-qt/src/util.h
index 0ca422c..50d78c4 100644
--- a/lib/packagekit-qt/src/util.h
+++ b/lib/packagekit-qt/src/util.h
@@ -127,7 +127,7 @@ public:
 
 	static QStringList packageListToPids(const QList<Package*>& packages);
 
-	static QString filtersToString(const QFlags<PackageKit::Client::Filter>& flags);
+	static QString filtersToString(const QFlags<PackageKit::Enum::Filter>& flags);
 
 	/*
 	 * Describes the different errors that might happen on the bus
commit aee67a4ce44b2abcec0d73f082842d56317306c0
Merge: e88dd57... b7241eb...
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Fri Feb 5 16:06:50 2010 -0200

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

commit e88dd573eca3d341ce5034b355d17302a3394525
Author: Daniel Nicoletti <dantti85-pk at yahoo.com.br>
Date:   Fri Feb 5 16:06:00 2010 -0200

    pk-qt: Added more constness to the lib, cleaned some includes and updated API to 0.6.1

diff --git a/lib/packagekit-qt/src/Makefile.am b/lib/packagekit-qt/src/Makefile.am
index 611af25..28d6380 100644
--- a/lib/packagekit-qt/src/Makefile.am
+++ b/lib/packagekit-qt/src/Makefile.am
@@ -26,16 +26,6 @@ libpackagekit_qt_include_HEADERS =				\
 	enum.h							\
 	$(NULL)
 
-$(libpackagekit_qt_la_OBJECTS) :				\
-	client.moc						\
-	clientprivate.moc					\
-	daemonproxy.moc						\
-	transaction.moc						\
-	transactionprivate.moc					\
-	transactionproxy.moc					\
-	enum.moc						\
-	$(NULL)
-
 libpackagekit_qt_la_SOURCES =					\
 	QPackageKit						\
 	common.h						\
diff --git a/lib/packagekit-qt/src/client.cpp b/lib/packagekit-qt/src/client.cpp
index e90d5af..ee0443e 100644
--- a/lib/packagekit-qt/src/client.cpp
+++ b/lib/packagekit-qt/src/client.cpp
@@ -44,8 +44,9 @@
 		}                                                          \
 
 #define RUN_TRANSACTION(blurb) \
+		Q_D(Client);   \
 		CREATE_NEW_TRANSACTION \
-		QDBusReply<void> r = t->d->p->blurb;        \
+		QDBusReply<void> r = t->d_ptr->p->blurb;        \
 		CHECK_TRANSACTION      \
 		return t;              \
 
@@ -67,10 +68,9 @@ Client* Client::instance()
 	return m_instance;
 }
 
-Client::Client(QObject* parent) : QObject(parent)
+Client::Client(QObject* parent) : QObject(parent), d_ptr(new ClientPrivate(this))
 {
-	d = new ClientPrivate(this);
-
+	Q_D(Client);
 	d->daemon = new DaemonProxy(PK_NAME, PK_PATH, QDBusConnection::systemBus(), this);
 
 	d->error = NoError;
@@ -95,11 +95,11 @@ Client::Client(QObject* parent) : QObject(parent)
 
 Client::~Client()
 {
-	delete d;
 }
 
 Client::Actions Client::actions() const
 {
+	Q_D(const Client);
 	QStringList actions = d->daemon->roles().split(";");
 
 	Actions flags;
@@ -111,21 +111,25 @@ Client::Actions Client::actions() const
 
 QString Client::backendName() const
 {
+	Q_D(const Client);
 	return d->daemon->backendName();
 }
 
 QString Client::backendDescription() const
 {
+	Q_D(const Client);
 	return d->daemon->backendDescription();
 }
 
 QString Client::backendAuthor() const
 {
+	Q_D(const Client);
 	return d->daemon->backendAuthor();
 }
 
 Client::Filters Client::filters() const
 {
+	Q_D(const Client);
 	QStringList filters = d->daemon->filters().split(";");
 
 	// Adapt a slight difference in the enum
@@ -142,6 +146,7 @@ Client::Filters Client::filters() const
 
 Client::Groups Client::groups() const
 {
+	Q_D(const Client);
 	QStringList groups = d->daemon->groups().split(";");
 
 	Groups flags;
@@ -153,33 +158,39 @@ Client::Groups Client::groups() const
 
 bool Client::locked() const
 {
+	Q_D(const Client);
 	return d->daemon->locked();
 }
 
 QStringList Client::mimeTypes() const
 {
+	Q_D(const Client);
 	return d->daemon->mimeTypes().split(";");
 }
 
 Client::NetworkState Client::networkState() const
 {
+	Q_D(const Client);
 	QString state = d->daemon->networkState();
 	return (NetworkState) Util::enumFromString<Client>(state, "NetworkState", "Network");
 }
 
 QString Client::distroId() const
 {
+	Q_D(const Client);
 	return d->daemon->distroId();
 }
 
 uint Client::getTimeSinceAction(Action action) const
 {
+	Q_D(const Client);
 	QString pkName = Util::enumToString<Client>(action, "Action", "Action");
 	return d->daemon->GetTimeSinceAction(pkName);
 }
 
 QList<Transaction*> Client::getTransactions()
 {
+	Q_D(Client);
 	QStringList tids = d->daemon->GetTransactionList();
 
 	return d->transactions(tids);
@@ -187,16 +198,19 @@ QList<Transaction*> Client::getTransactions()
 
 void Client::setHints(const QStringList& hints)
 {
+	Q_D(Client);
 	d->hints = hints;
 }
 
 void Client::setHints(const QString& hints)
 {
+	Q_D(Client);
 	d->hints = QStringList() << hints;
 }
 
 bool Client::setProxy(const QString& http_proxy, const QString& ftp_proxy)
 {
+	Q_D(Client);
 	QDBusReply<void> r = d->daemon->SetProxy(http_proxy, ftp_proxy);
 	if (!r.isValid ()) {
 		setLastError (daemonErrorFromDBusReply (r));
@@ -208,31 +222,37 @@ bool Client::setProxy(const QString& http_proxy, const QString& ftp_proxy)
 
 void Client::stateHasChanged(const QString& reason)
 {
+	Q_D(Client);
 	d->daemon->StateHasChanged(reason);
 }
 
 void Client::suggestDaemonQuit()
 {
+	Q_D(Client);
 	d->daemon->SuggestDaemonQuit();
 }
 
 Client::DaemonError Client::getLastError() const
 {
+	Q_D(const Client);
 	return d->error;
 }
 
 uint Client::versionMajor() const
 {
+	Q_D(const Client);
 	return d->daemon->versionMajor();
 }
 
 uint Client::versionMinor() const
 {
+	Q_D(const Client);
 	return d->daemon->versionMinor();
 }
 
 uint Client::versionMicro() const
 {
+	Q_D(const Client);
 	return d->daemon->versionMicro();
 }
 
@@ -265,13 +285,14 @@ Transaction* Client::getDepends(Package* package, Filters filters, bool recursiv
 
 Transaction* Client::getDetails(const QList<Package*>& packages)
 {
+	Q_D(Client);
 	CREATE_NEW_TRANSACTION
 
 	foreach(Package* p, packages) {
-		t->d->packageMap.insert(p->id(), p);
+		t->d_ptr->packageMap.insert(p->id(), p);
 	}
 
-	QDBusReply<void> r = t->d->p->GetDetails(Util::packageListToPids(packages));
+	QDBusReply<void> r = t->d_ptr->p->GetDetails(Util::packageListToPids(packages));
 
 	CHECK_TRANSACTION
 
@@ -413,15 +434,20 @@ Transaction* Client::searchFiles(const QString& search, Filters filters)
 	return searchFiles(QStringList() << search, filters);
 }
 
-Transaction* Client::searchDetails(const QString& search, Filters filters)
+Transaction* Client::searchDetails(const QStringList& search, Filters filters)
 {
 	RUN_TRANSACTION(SearchDetails(Util::filtersToString(filters), search))
 }
 
+Transaction* Client::searchDetails(const QString& search, Filters filters)
+{
+	return searchDetails(QStringList() << search, filters);
+}
+
 Transaction* Client::searchGroups(Client::Groups groups, Filters filters)
 {
 	QStringList groupsSL;
-	foreach (Client::Group group, groups) {
+	foreach (const Client::Group group, groups) {
 		groupsSL << Util::enumToString<Client>(group, "Group", "Group");
 	}
 
@@ -520,29 +546,31 @@ Transaction* Client::updateSystem(bool only_trusted)
 	RUN_TRANSACTION(UpdateSystem(only_trusted))
 }
 
-Transaction* Client::whatProvides(ProvidesType type, const QString& search, Filters filters)
+Transaction* Client::whatProvides(ProvidesType type, const QStringList& search, Filters filters)
 {
 	RUN_TRANSACTION(WhatProvides(Util::filtersToString(filters), Util::enumToString<Client>(type, "ProvidesType", "Provides"), search))
 }
 
-Transaction* Client::whatProvides(ProvidesType type, const QStringList& search, Filters filters)
+Transaction* Client::whatProvides(ProvidesType type, const QString& search, Filters filters)
 {
-	return whatProvides(type, search.join("&"), filters);
+	return whatProvides(type, QStringList() << search, filters);
 }
 
 void Client::setLastError (DaemonError e)
 {
+	Q_D(Client);
 	d->error = e;
 	emit error (e);
 }
 
 void Client::setTransactionError (Transaction* t, DaemonError e)
 {
-	t->d->error = e;
+	t->d_ptr->error = e;
 }
 
 void Client::destroyTransaction(const QString &tid)
 {
+	Q_D(Client);
 	d->removeTransactionFromPool(tid);
 }
 
diff --git a/lib/packagekit-qt/src/client.h b/lib/packagekit-qt/src/client.h
index dec379f..3de287f 100644
--- a/lib/packagekit-qt/src/client.h
+++ b/lib/packagekit-qt/src/client.h
@@ -26,7 +26,6 @@
 
 namespace PackageKit {
 
-class ClientPrivate;
 class Package;
 class Transaction;
 
@@ -46,6 +45,7 @@ class Transaction;
  * \note This class is a singleton, its constructor is private. Call Client::instance() to get
  * an instance of the Client object
  */
+class ClientPrivate;
 class Client : public QObject
 {
 
@@ -731,6 +731,7 @@ public:
 	 *
 	 * \p filters can be used to restrict the returned packages
 	 */
+	Transaction* searchDetails(const QStringList& search, Filters filters = NoFilter);
 	Transaction* searchDetails(const QString& search, Filters filters = NoFilter);
 
 	/**
@@ -851,12 +852,15 @@ Q_SIGNALS:
 	 */
 	void updatesChanged();
 
+protected:
+	ClientPrivate * const d_ptr;
+
 private:
+	Q_DECLARE_PRIVATE(Client);
 	Client(QObject* parent = 0);
 	static Client* m_instance;
-	friend class ClientPrivate;
 	friend class TransactionPrivate;
-	ClientPrivate* d;
+
 
 	void setLastError (DaemonError e);
 	void setTransactionError (Transaction* t, DaemonError e);
diff --git a/lib/packagekit-qt/src/clientprivate.cpp b/lib/packagekit-qt/src/clientprivate.cpp
index 7d26673..e96029c 100644
--- a/lib/packagekit-qt/src/clientprivate.cpp
+++ b/lib/packagekit-qt/src/clientprivate.cpp
@@ -22,7 +22,6 @@
 #include "daemonproxy.h"
 #include "transaction.h"
 #include "transactionprivate.h"
-#include "util.h"
 #include "common.h"
 
 using namespace PackageKit;
@@ -85,9 +84,9 @@ void ClientPrivate::serviceOwnerChanged (const QString& name, const QString& old
 	error = Client::ErrorDaemonUnreachable;
 	c->error(error);
 
-	foreach(Transaction *t, runningTransactions.values ()) {
+	foreach(Transaction *t, runningTransactions) {
 		t->finished (Transaction::ExitFailed, 0);
-		t->d->destroy ();
+		t->d_ptr->destroy ();
 	}
 }
 
diff --git a/lib/packagekit-qt/src/daemonproxy.h b/lib/packagekit-qt/src/daemonproxy.h
index 728983a..c6db4c2 100644
--- a/lib/packagekit-qt/src/daemonproxy.h
+++ b/lib/packagekit-qt/src/daemonproxy.h
@@ -1,6 +1,6 @@
 /*
  * This file was generated by qdbusxml2cpp version 0.7
- * Command line was: qdbusxml2cpp -c DaemonProxy -p daemonproxy.h /home/daniel/code/PackageKit/src/org.freedesktop.PackageKit.xml
+ * Command line was: qdbusxml2cpp -c DaemonProxy -p daemonproxy.h ../../../src/org.freedesktop.PackageKit.xml -N
  *
  * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
  *
@@ -8,8 +8,8 @@
  * Do not edit! All changes made to it will be lost.
  */
 
-#ifndef DAEMONPROXY_H_1256835922
-#define DAEMONPROXY_H_1256835922
+#ifndef DAEMONPROXY_H_1265392480
+#define DAEMONPROXY_H_1265392480
 
 #include <QtCore/QObject>
 #include <QtCore/QByteArray>
@@ -39,55 +39,55 @@ public:
 
     Q_PROPERTY(QString BackendAuthor READ backendAuthor)
     inline QString backendAuthor() const
-    { return qvariant_cast< QString >(internalPropGet("BackendAuthor")); }
+    { return qvariant_cast< QString >(property("BackendAuthor")); }
 
     Q_PROPERTY(QString BackendDescription READ backendDescription)
     inline QString backendDescription() const
-    { return qvariant_cast< QString >(internalPropGet("BackendDescription")); }
+    { return qvariant_cast< QString >(property("BackendDescription")); }
 
     Q_PROPERTY(QString BackendName READ backendName)
     inline QString backendName() const
-    { return qvariant_cast< QString >(internalPropGet("BackendName")); }
+    { return qvariant_cast< QString >(property("BackendName")); }
+
+    Q_PROPERTY(QString DistroId READ distroId)
+    inline QString distroId() const
+    { return qvariant_cast< QString >(property("DistroId")); }
 
     Q_PROPERTY(QString Filters READ filters)
     inline QString filters() const
-    { return qvariant_cast< QString >(internalPropGet("Filters")); }
+    { return qvariant_cast< QString >(property("Filters")); }
 
     Q_PROPERTY(QString Groups READ groups)
     inline QString groups() const
-    { return qvariant_cast< QString >(internalPropGet("Groups")); }
+    { return qvariant_cast< QString >(property("Groups")); }
 
     Q_PROPERTY(bool Locked READ locked)
     inline bool locked() const
-    { return qvariant_cast< bool >(internalPropGet("Locked")); }
+    { return qvariant_cast< bool >(property("Locked")); }
 
     Q_PROPERTY(QString MimeTypes READ mimeTypes)
     inline QString mimeTypes() const
-    { return qvariant_cast< QString >(internalPropGet("MimeTypes")); }
+    { return qvariant_cast< QString >(property("MimeTypes")); }
 
     Q_PROPERTY(QString NetworkState READ networkState)
     inline QString networkState() const
-    { return qvariant_cast< QString >(internalPropGet("NetworkState")); }
-
-    Q_PROPERTY(QString DistroId READ distroId)
-    inline QString distroId() const
-    { return qvariant_cast< QString >(internalPropGet("DistroId")); }
+    { return qvariant_cast< QString >(property("NetworkState")); }
 
     Q_PROPERTY(QString Roles READ roles)
     inline QString roles() const
-    { return qvariant_cast< QString >(internalPropGet("Roles")); }
+    { return qvariant_cast< QString >(property("Roles")); }
 
     Q_PROPERTY(uint VersionMajor READ versionMajor)
     inline uint versionMajor() const
-    { return qvariant_cast< uint >(internalPropGet("VersionMajor")); }
+    { return qvariant_cast< uint >(property("VersionMajor")); }
 
     Q_PROPERTY(uint VersionMicro READ versionMicro)
     inline uint versionMicro() const
-    { return qvariant_cast< uint >(internalPropGet("VersionMicro")); }
+    { return qvariant_cast< uint >(property("VersionMicro")); }
 
     Q_PROPERTY(uint VersionMinor READ versionMinor)
     inline uint versionMinor() const
-    { return qvariant_cast< uint >(internalPropGet("VersionMinor")); }
+    { return qvariant_cast< uint >(property("VersionMinor")); }
 
 public Q_SLOTS: // METHODS
     inline QDBusPendingReply<QString> CanAuthorize(const QString &action_id)
@@ -97,57 +97,12 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("CanAuthorize"), argumentList);
     }
 
-    inline QDBusPendingReply<QString> GetActions()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetActions"), argumentList);
-    }
-
-    inline QDBusPendingReply<QString, QString> GetBackendDetail()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetBackendDetail"), argumentList);
-    }
-    inline QDBusReply<QString> GetBackendDetail(QString &author)
-    {
-        QList<QVariant> argumentList;
-        QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetBackendDetail"), argumentList);
-        if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
-            author = qdbus_cast<QString>(reply.arguments().at(1));
-        }
-        return reply;
-    }
-
     inline QDBusPendingReply<QString> GetDaemonState()
     {
         QList<QVariant> argumentList;
         return asyncCallWithArgumentList(QLatin1String("GetDaemonState"), argumentList);
     }
 
-    inline QDBusPendingReply<QString> GetFilters()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetFilters"), argumentList);
-    }
-
-    inline QDBusPendingReply<QString> GetGroups()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetGroups"), argumentList);
-    }
-
-    inline QDBusPendingReply<QString> GetMimeTypes()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetMimeTypes"), argumentList);
-    }
-
-    inline QDBusPendingReply<QString> GetNetworkState()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetNetworkState"), argumentList);
-    }
-
     inline QDBusPendingReply<QString> GetTid()
     {
         QList<QVariant> argumentList;
@@ -189,8 +144,6 @@ public Q_SLOTS: // METHODS
 
 Q_SIGNALS: // SIGNALS
     void Changed();
-    void Locked(bool is_locked);
-    void NetworkStateChanged(const QString &state);
     void RepoListChanged();
     void RestartSchedule();
     void TransactionListChanged(const QStringList &transactions);
diff --git a/lib/packagekit-qt/src/enum.cpp b/lib/packagekit-qt/src/enum.cpp
index 610c869..d9d08d8 100644
--- a/lib/packagekit-qt/src/enum.cpp
+++ b/lib/packagekit-qt/src/enum.cpp
@@ -26,5 +26,3 @@ using namespace PackageKit;
 Enum::Enum() : QObject(NULL)
 {
 }
-
-#include "enum.moc"
diff --git a/lib/packagekit-qt/src/package.cpp b/lib/packagekit-qt/src/package.cpp
index 1134b32..117eae6 100644
--- a/lib/packagekit-qt/src/package.cpp
+++ b/lib/packagekit-qt/src/package.cpp
@@ -26,7 +26,7 @@
 using namespace PackageKit;
 
 ////// Details class
-class Package::Details::Private
+class Package::DetailsPrivate
 {
 public:
 	Package* package;
@@ -37,8 +37,9 @@ public:
 	uint size;
 };
 
-Package::Details::Details(Package* p, const QString& license, const QString& group, const QString& detail, const QString& url, qulonglong size) : d(new Private)
+Package::Details::Details(Package* p, const QString& license, const QString& group, const QString& detail, const QString& url, qulonglong size) : d_ptr(new DetailsPrivate)
 {
+	Q_D(Details);
 	d->package = p;
 	d->license = license;
 	d->group = (Client::Group)Util::enumFromString<Client>(group, "Group", "Group");
@@ -49,36 +50,42 @@ Package::Details::Details(Package* p, const QString& license, const QString& gro
 
 Package::Details::~Details()
 {
-	delete d;
+	delete d_ptr;
 }
 
 Package* Package::Details::package() const
 {
+	Q_D(const Details);
 	return d->package;
 }
 
 QString Package::Details::license() const
 {
+	Q_D(const Details);
 	return d->license;
 }
 
 Client::Group Package::Details::group() const
 {
+	Q_D(const Details);
 	return d->group;
 }
 
 QString Package::Details::description() const
 {
+	Q_D(const Details);
 	return d->description;
 }
 
 QString Package::Details::url() const
 {
+	Q_D(const Details);
 	return d->url;
 }
 
 qulonglong Package::Details::size() const
 {
+	Q_D(const Details);
 	return d->size;
 }
 
@@ -98,8 +105,8 @@ public:
 	QString iconPath;
 };
 
-Package::Package(const QString& packageId, const QString& info, const QString& summary)
- : d(new Private)
+Package::Package(const QString& packageId, const QString& info, const QString& summary, QObject *parent)
+    : QObject(parent), d(new Private)
 {
 	d->id = packageId;
 
@@ -222,5 +229,3 @@ bool Package::operator==(const Package *package) const
 {
 	return d->id == package->id();
 }
-
-#include "package.moc"
diff --git a/lib/packagekit-qt/src/package.h b/lib/packagekit-qt/src/package.h
index 5aa95ed..0bc8a76 100644
--- a/lib/packagekit-qt/src/package.h
+++ b/lib/packagekit-qt/src/package.h
@@ -39,8 +39,6 @@ namespace PackageKit {
  */
 class Package : public QObject
 {
-	Q_OBJECT
-
 public:
 	/**
 	 * Destructor
@@ -88,6 +86,7 @@ public:
 	 * Holds additional details about a package
 	 * \sa Client::getDetails
 	 */
+	class DetailsPrivate;
 	class Details
 	{
 		public:
@@ -126,12 +125,15 @@ public:
 			 * Returns the package's size
 			 */
 			qulonglong size() const;
+
+		protected:
+			DetailsPrivate * const d_ptr;
+
 		private:
+			Q_DECLARE_PRIVATE(Details);
 			friend class Package;
 			friend class TransactionPrivate;
 			Details(Package* p, const QString& license, const QString& group, const QString& detail, const QString& url, qulonglong size);
-			class Private;
-			Private* d;
 	};
 
 	/**
@@ -164,11 +166,11 @@ private:
 	friend class TransactionPrivate;
 	friend class Details;
 	friend class Client;
-	Package(const QString& packageId, const QString& info = QString(), const QString& summary = QString());
+	Package(const QString& packageId, const QString& info = QString(), const QString& summary = QString(), QObject *parent = 0);
 	void setDetails(Details* det);
 	void setInfoSummary(const QString& info, const QString& summary);
 	class Private;
-	Private* d;
+	Private * const d;
 };
 
 } // End namespace PackageKit
diff --git a/lib/packagekit-qt/src/transaction.cpp b/lib/packagekit-qt/src/transaction.cpp
index 481c8e9..a24d0dc 100644
--- a/lib/packagekit-qt/src/transaction.cpp
+++ b/lib/packagekit-qt/src/transaction.cpp
@@ -19,19 +19,17 @@
  */
 
 #include "transaction.h"
-#include "client.h"
 #include "common.h"
-#include "package.h"
 #include "transactionprivate.h"
 #include "transactionproxy.h"
 #include "util.h"
 
 using namespace PackageKit;
 
-Transaction::Transaction(const QString& tid, Client* parent) : QObject(parent)
+Transaction::Transaction(const QString& tid, Client* parent)
+	: QObject(parent), d_ptr(new TransactionPrivate(this))
 {
-	d = new TransactionPrivate(this);
-
+	Q_D(Transaction);
 	d->oldtrans = FALSE;
 	d->tid = tid;
 	d->client = parent;
@@ -61,10 +59,10 @@ Transaction::Transaction(const QString& tid, Client* parent) : QObject(parent)
 
 }
 
-Transaction::Transaction(const QString& tid, const QString& timespec, bool succeeded, const QString& role, uint duration, const QString& data, uint uid, const QString& cmdline, Client* parent) : QObject(parent)
+Transaction::Transaction(const QString& tid, const QString& timespec, bool succeeded, const QString& role, uint duration, const QString& data, uint uid, const QString& cmdline, Client* parent)
+	: QObject(parent), d_ptr(new TransactionPrivate(this))
 {
-	d = new TransactionPrivate(this);
-
+	Q_D(Transaction);
 	d->oldtrans = TRUE;
 	d->tid = tid;
 	d->timespec = QDateTime::fromString(timespec, Qt::ISODate);
@@ -85,26 +83,31 @@ Transaction::~Transaction()
 
 QString Transaction::tid() const
 {
+	Q_D(const Transaction);
 	return d->tid;
 }
 
 Client::DaemonError Transaction::error () const
 {
+	Q_D(const Transaction);
 	return d->error;
 }
 
 bool Transaction::allowCancel() const
 {
+	Q_D(const Transaction);
 	return d->p->allowCancel ();
 }
 
 bool Transaction::callerActive() const
 {
+	Q_D(const Transaction);
 	return d->p->callerActive ();
 }
 
 void Transaction::cancel()
 {
+	Q_D(Transaction);
 	QDBusReply<void> r = d->p->Cancel ();
 	if (!r.isValid ()) {
 		d->error = Util::errorFromString (r.error ().message ());
@@ -113,36 +116,43 @@ void Transaction::cancel()
 
 Package* Transaction::lastPackage() const
 {
+	Q_D(const Transaction);
 	return new Package(d->p->lastPackage ());
 }
 
 uint Transaction::percentage() const
 {
+	Q_D(const Transaction);
 	return d->p->percentage ();
 }
 
 uint Transaction::subpercentage() const
 {
+	Q_D(const Transaction);
 	return d->p->subpercentage ();
 }
 
 uint Transaction::elapsedTime() const
 {
+	Q_D(const Transaction);
 	return d->p->elapsedTime ();
 }
 
 uint Transaction::remainingTime() const
 {
+	Q_D(const Transaction);
 	return d->p->remainingTime ();
 }
 
 uint Transaction::speed() const
 {
+	Q_D(const Transaction);
 	return d->p->speed ();
 }
 
 Client::Action Transaction::role() const
 {
+	Q_D(const Transaction);
 	if(d->oldtrans)
 		return d->role;
 
@@ -151,6 +161,7 @@ Client::Action Transaction::role() const
 
 void Transaction::setHints(const QStringList& hints)
 {
+	Q_D(Transaction);
 	d->p->SetHints(hints);
 }
 
@@ -161,31 +172,37 @@ void Transaction::setHints(const QString& hints)
 
 Transaction::Status Transaction::status() const
 {
+	Q_D(const Transaction);
 	return (Transaction::Status) Util::enumFromString<Transaction>(d->p->status (), "Status", "Status");
 }
 
 QDateTime Transaction::timespec() const
 {
+	Q_D(const Transaction);
 	return d->timespec;
 }
 
 bool Transaction::succeeded() const
 {
+	Q_D(const Transaction);
 	return d->succeeded;
 }
 
 uint Transaction::duration() const
 {
+	Q_D(const Transaction);
 	return d->duration;
 }
 
 QString Transaction::data() const
 {
+	Q_D(const Transaction);
 	return d->data;
 }
 
 uint Transaction::uid() const
 {
+	Q_D(const Transaction);
 	if(d->p) {
 		return d->p->uid();
 	}
@@ -194,6 +211,7 @@ uint Transaction::uid() const
 
 QString Transaction::cmdline() const
 {
+	Q_D(const Transaction);
 	return d->cmdline;
 }
 
diff --git a/lib/packagekit-qt/src/transaction.h b/lib/packagekit-qt/src/transaction.h
index 916a49f..70fd977 100644
--- a/lib/packagekit-qt/src/transaction.h
+++ b/lib/packagekit-qt/src/transaction.h
@@ -29,7 +29,6 @@ namespace PackageKit {
 
 class ClientPrivate;
 class Package;
-class TransactionPrivate;
 
 /**
  * \class Transaction transaction.h Transaction
@@ -46,6 +45,7 @@ class TransactionPrivate;
  *
  * \sa Client
  */
+class TransactionPrivate;
 class Transaction : public QObject
 {
 	Q_OBJECT
@@ -393,15 +393,15 @@ Q_SIGNALS:
 	 */
 	void updateDetail(PackageKit::Client::UpdateInfo info);
 
+protected:
+	TransactionPrivate * const d_ptr;
+
 private:
+	Q_DECLARE_PRIVATE(Transaction);
 	friend class Client;
 	friend class ClientPrivate;
 	Transaction(const QString& tid, Client* parent);
 	Transaction(const QString& tid, const QString& timespec, bool succeeded, const QString& role, uint duration, const QString& data, uint uid, const QString& cmdline, Client* parent);
-
-	friend class TransactionPrivate;
-	TransactionPrivate* d;
-
 };
 
 } // End namespace PackageKit
diff --git a/lib/packagekit-qt/src/transactionprivate.cpp b/lib/packagekit-qt/src/transactionprivate.cpp
index f6aa7eb..ea07b2d 100644
--- a/lib/packagekit-qt/src/transactionprivate.cpp
+++ b/lib/packagekit-qt/src/transactionprivate.cpp
@@ -19,6 +19,7 @@
  */
 
 #include "transactionprivate.h"
+#include "transaction.h"
 #include "util.h"
 
 using namespace PackageKit;
diff --git a/lib/packagekit-qt/src/transactionprivate.h b/lib/packagekit-qt/src/transactionprivate.h
index 4e6f918..ab00a10 100644
--- a/lib/packagekit-qt/src/transactionprivate.h
+++ b/lib/packagekit-qt/src/transactionprivate.h
@@ -22,7 +22,7 @@
 #define TRANSACTIONPRIVATE_H
 
 #include <QtCore>
-#include "transaction.h"
+#include "client.h"
 
 namespace PackageKit {
 
diff --git a/lib/packagekit-qt/src/transactionproxy.h b/lib/packagekit-qt/src/transactionproxy.h
index a6648fc..2d16b38 100644
--- a/lib/packagekit-qt/src/transactionproxy.h
+++ b/lib/packagekit-qt/src/transactionproxy.h
@@ -1,6 +1,6 @@
 /*
  * This file was generated by qdbusxml2cpp version 0.7
- * Command line was: qdbusxml2cpp -c TransactionProxy -p transactionproxy.h /home/daniel/code/PackageKit/src/org.freedesktop.PackageKit.Transaction.xml
+ * Command line was: qdbusxml2cpp -c TransactionProxy -p transactionproxy.h ../../../src/org.freedesktop.PackageKit.Transaction.xml -N
  *
  * qdbusxml2cpp is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
  *
@@ -8,8 +8,8 @@
  * Do not edit! All changes made to it will be lost.
  */
 
-#ifndef TRANSACTIONPROXY_H_1256828761
-#define TRANSACTIONPROXY_H_1256828761
+#ifndef TRANSACTIONPROXY_H_1265392707
+#define TRANSACTIONPROXY_H_1265392707
 
 #include <QtCore/QObject>
 #include <QtCore/QByteArray>
@@ -38,47 +38,47 @@ public:
 
     Q_PROPERTY(bool AllowCancel READ allowCancel)
     inline bool allowCancel() const
-    { return qvariant_cast< bool >(internalPropGet("AllowCancel")); }
+    { return qvariant_cast< bool >(property("AllowCancel")); }
 
     Q_PROPERTY(bool CallerActive READ callerActive)
     inline bool callerActive() const
-    { return qvariant_cast< bool >(internalPropGet("CallerActive")); }
+    { return qvariant_cast< bool >(property("CallerActive")); }
 
     Q_PROPERTY(uint ElapsedTime READ elapsedTime)
     inline uint elapsedTime() const
-    { return qvariant_cast< uint >(internalPropGet("ElapsedTime")); }
+    { return qvariant_cast< uint >(property("ElapsedTime")); }
 
     Q_PROPERTY(QString LastPackage READ lastPackage)
     inline QString lastPackage() const
-    { return qvariant_cast< QString >(internalPropGet("LastPackage")); }
+    { return qvariant_cast< QString >(property("LastPackage")); }
 
     Q_PROPERTY(uint Percentage READ percentage)
     inline uint percentage() const
-    { return qvariant_cast< uint >(internalPropGet("Percentage")); }
+    { return qvariant_cast< uint >(property("Percentage")); }
 
     Q_PROPERTY(uint RemainingTime READ remainingTime)
     inline uint remainingTime() const
-    { return qvariant_cast< uint >(internalPropGet("RemainingTime")); }
+    { return qvariant_cast< uint >(property("RemainingTime")); }
 
     Q_PROPERTY(QString Role READ role)
     inline QString role() const
-    { return qvariant_cast< QString >(internalPropGet("Role")); }
+    { return qvariant_cast< QString >(property("Role")); }
 
     Q_PROPERTY(uint Speed READ speed)
     inline uint speed() const
-    { return qvariant_cast< uint >(internalPropGet("Speed")); }
+    { return qvariant_cast< uint >(property("Speed")); }
 
     Q_PROPERTY(QString Status READ status)
     inline QString status() const
-    { return qvariant_cast< QString >(internalPropGet("Status")); }
+    { return qvariant_cast< QString >(property("Status")); }
 
     Q_PROPERTY(uint Subpercentage READ subpercentage)
     inline uint subpercentage() const
-    { return qvariant_cast< uint >(internalPropGet("Subpercentage")); }
+    { return qvariant_cast< uint >(property("Subpercentage")); }
 
     Q_PROPERTY(uint Uid READ uid)
     inline uint uid() const
-    { return qvariant_cast< uint >(internalPropGet("Uid")); }
+    { return qvariant_cast< uint >(property("Uid")); }
 
 public Q_SLOTS: // METHODS
     inline QDBusPendingReply<> AcceptEula(const QString &eula_id)
@@ -101,12 +101,6 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("DownloadPackages"), argumentList);
     }
 
-    inline QDBusPendingReply<bool> GetAllowCancel()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetAllowCancel"), argumentList);
-    }
-
     inline QDBusPendingReply<> GetCategories()
     {
         QList<QVariant> argumentList;
@@ -147,12 +141,6 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("GetOldTransactions"), argumentList);
     }
 
-    inline QDBusPendingReply<QString> GetPackageLast()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetPackageLast"), argumentList);
-    }
-
     inline QDBusPendingReply<> GetPackages(const QString &filter)
     {
         QList<QVariant> argumentList;
@@ -160,23 +148,6 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("GetPackages"), argumentList);
     }
 
-    inline QDBusPendingReply<uint, uint, uint, uint> GetProgress()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetProgress"), argumentList);
-    }
-    inline QDBusReply<uint> GetProgress(uint &subpercentage, uint &elapsed, uint &remaining)
-    {
-        QList<QVariant> argumentList;
-        QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetProgress"), argumentList);
-        if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) {
-            subpercentage = qdbus_cast<uint>(reply.arguments().at(1));
-            elapsed = qdbus_cast<uint>(reply.arguments().at(2));
-            remaining = qdbus_cast<uint>(reply.arguments().at(3));
-        }
-        return reply;
-    }
-
     inline QDBusPendingReply<> GetRepoList(const QString &filter)
     {
         QList<QVariant> argumentList;
@@ -191,27 +162,6 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("GetRequires"), argumentList);
     }
 
-    inline QDBusPendingReply<QString, QString> GetRole()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetRole"), argumentList);
-    }
-    inline QDBusReply<QString> GetRole(QString &text)
-    {
-        QList<QVariant> argumentList;
-        QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("GetRole"), argumentList);
-        if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) {
-            text = qdbus_cast<QString>(reply.arguments().at(1));
-        }
-        return reply;
-    }
-
-    inline QDBusPendingReply<QString> GetStatus()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("GetStatus"), argumentList);
-    }
-
     inline QDBusPendingReply<> GetUpdateDetail(const QStringList &package_ids)
     {
         QList<QVariant> argumentList;
@@ -247,12 +197,6 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("InstallSignature"), argumentList);
     }
 
-    inline QDBusPendingReply<bool> IsCallerActive()
-    {
-        QList<QVariant> argumentList;
-        return asyncCallWithArgumentList(QLatin1String("IsCallerActive"), argumentList);
-    }
-
     inline QDBusPendingReply<> RefreshCache(bool force)
     {
         QList<QVariant> argumentList;
@@ -281,10 +225,10 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("RepoSetData"), argumentList);
     }
 
-    inline QDBusPendingReply<> Resolve(const QString &filter, const QStringList &package)
+    inline QDBusPendingReply<> Resolve(const QString &filter, const QStringList &packages)
     {
         QList<QVariant> argumentList;
-        argumentList << qVariantFromValue(filter) << qVariantFromValue(package);
+        argumentList << qVariantFromValue(filter) << qVariantFromValue(packages);
         return asyncCallWithArgumentList(QLatin1String("Resolve"), argumentList);
     }
 
@@ -295,7 +239,7 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("Rollback"), argumentList);
     }
 
-    inline QDBusPendingReply<> SearchDetails(const QString &filter, const QString &values)
+    inline QDBusPendingReply<> SearchDetails(const QString &filter, const QStringList &values)
     {
         QList<QVariant> argumentList;
         argumentList << qVariantFromValue(filter) << qVariantFromValue(values);
@@ -379,7 +323,7 @@ public Q_SLOTS: // METHODS
         return asyncCallWithArgumentList(QLatin1String("UpdateSystem"), argumentList);
     }
 
-    inline QDBusPendingReply<> WhatProvides(const QString &filter, const QString &type, const QString &values)
+    inline QDBusPendingReply<> WhatProvides(const QString &filter, const QString &type, const QStringList &values)
     {
         QList<QVariant> argumentList;
         argumentList << qVariantFromValue(filter) << qVariantFromValue(type) << qVariantFromValue(values);
@@ -387,7 +331,6 @@ public Q_SLOTS: // METHODS
     }
 
 Q_SIGNALS: // SIGNALS
-    void AllowCancel(bool allow_cancel);
     void Category(const QString &parent_id, const QString &cat_id, const QString &name, const QString &summary, const QString &icon);
     void Changed();
     void Destroy();
commit 1d24f4c9e3ba1c7de8333ee9d0a3478d5d302381
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Thu Feb 4 15:34:41 2010 +0100

    entropy: spawn error on missing accepted EULAs

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 2fd255f..dcb7a64 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -517,6 +517,9 @@ class PackageKitEntropyMixin(object):
 
         if licenses:
             # bye bye, user will have to accept it and get here again
+            self.error(EXIT_EULA_REQUIRED,
+                "Following EULAs are not accepted: %s" % (
+                    ' '.join(licenses.keys()),))
             return
 
         # used in case of errors
commit 08a5bb9780cbc9bd3852d784c13af364e0116c06
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Thu Feb 4 13:30:00 2010 +0100

    entropy: add eula-required signal emission

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 911f7dc..2fd255f 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -500,7 +500,24 @@ class PackageKitEntropyMixin(object):
         self.percentage(0)
         self.status(STATUS_DOWNLOAD)
 
-        # FIXME: where is license dialog? can't be interactive, fook!
+        # Before even starting the fetch
+        # make sure that the user accepts their licenses
+        # send license signal afterwards
+        licenses = self._entropy.get_licenses_to_accept(run_queue)
+
+        for eula_id, eula_pkgs in licenses.items():
+            for pkg_id, repo_id in eula_pkgs:
+                pkg_c_repo = self._entropy.open_repository(repo_id)
+                vendor_name = pkg_c_repo.retrieveHomepage(pkg_id)
+                pk_pkg = self._etp_to_id((pkg_id, pkg_c_repo))
+                license_agreement = pkg_c_repo.retrieveLicenseText(eula_id)
+                self.eula_required(eula_id, pk_pkg, vendor_name,
+                    license_agreement)
+                # FIXME remove here self._entropy.installed_repository().acceptLicense(eula_id)
+
+        if licenses:
+            # bye bye, user will have to accept it and get here again
+            return
 
         # used in case of errors
         match_map = {}
commit 91cd7e7da809bf0300ba52a211f8750d37442116
Merge: cda3a3b... 9641b42...
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Thu Feb 4 12:51:07 2010 +0100

    Merge remote branch 'official/master'

commit cda3a3ba59b90b3bccdaa6fd5fe18ab0a8eccee8
Merge: fd7fde7... cb622dc...
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Thu Feb 4 11:52:15 2010 +0100

    Merge remote branch 'official/master'

commit fd7fde797dd85cca228134ce839e46ae42f5a8aa
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Thu Feb 4 11:50:27 2010 +0100

    entropy: trivial backend module cleanup

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index c54797b..911f7dc 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -48,11 +48,9 @@ from packagekit.backend import PackageKitBaseBackend, \
     STATUS_INSTALL, STATUS_RUNNING, STATUS_REFRESH_CACHE, \
     UPDATE_STATE_TESTING, UPDATE_STATE_STABLE
 
-#from packagekit.progress import *
 from packagekit.package import PackagekitPackage
 
 sys.path.insert(0, '/usr/lib/entropy/libraries')
-
 from entropy.i18n import _, _LOCALE
 from entropy.const import etpConst, const_convert_to_rawstring, \
     const_convert_to_unicode
@@ -64,7 +62,7 @@ from entropy.fetchers import UrlFetcher
 
 import entropy.tools
 
-PK_DEBUG = True
+PK_DEBUG = False
 
 class PackageKitEntropyMixin(object):
 
commit 27f4a3cefd02d45bc8d51c1e10b24b2855324dc1
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 15:07:48 2010 +0100

    [entropy] update TODO

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index 06fe0e2..6046f5d 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -5,7 +5,7 @@ Entropy PackageKit backend developers' TODO:
     - add get_mime_types, install_files, simulate_* support, repo_set_data
     - bind get_distro_upgrades to branch hop?
     - sys-apps/entropy is a syspkg
-    - messages? how push output to stdout?
+    - messages? how push output to stdout? FIXME!!!
     - license dialog??
 
 What is currently implemented:
commit 5ecb7cbfb5c967c8d321a912d67712d5eb63bff4
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 14:28:22 2010 +0100

    [entropy] disable EntropyPackageKitBackend.get_distro_upgrades for now

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index b8b6da8..06fe0e2 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -3,6 +3,7 @@ Entropy PackageKit backend developers' TODO:
     - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
         FILTER_DEVELOPMENT, FILTER_VISIBLE
     - add get_mime_types, install_files, simulate_* support, repo_set_data
+    - bind get_distro_upgrades to branch hop?
     - sys-apps/entropy is a syspkg
     - messages? how push output to stdout?
     - license dialog??
diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 780abdf..c54797b 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -1110,6 +1110,13 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
+    def get_distro_upgrades(self):
+        """
+        FIXME: should this return only system updates? (pkgs marked as syspkgs)
+        Not implemented atm
+        """
+        PackageKitBaseBackend.get_distro_upgrades(self)
+
     def get_updates(self, filters):
 
         self.status(STATUS_INFO)
commit 059fb32e4bbd6dcfe2c088b746f76a7f351d7de5
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 14:18:33 2010 +0100

    [entropy] update TODO

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index 35b5faf..b8b6da8 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -2,8 +2,7 @@ Entropy PackageKit backend developers' TODO:
 
     - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
         FILTER_DEVELOPMENT, FILTER_VISIBLE
-    - add get_mime_types, update_system, install_files, simulate_* support,
-        repo_set_data
+    - add get_mime_types, install_files, simulate_* support, repo_set_data
     - sys-apps/entropy is a syspkg
     - messages? how push output to stdout?
     - license dialog??
@@ -18,7 +17,7 @@ What is currently implemented:
     Y install [packages]
     Y remove [package]
     Y update <package>
-    N update-system ???? not shown
+    Y update-system
     Y refresh
     Y resolve [package]
     Y get-updates
commit d4cb2f8d51d8804460df6fffd67d214be96de04d
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 14:17:15 2010 +0100

    [entropy] implement EntropyPackageKitBackend.update_system()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 08a72a4..780abdf 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -1500,10 +1500,26 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             only_trusted,))
 
         self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
-        self.percentage(None)
-        # FIXME: not yet implemented
-        return
+        self.allow_cancel(True)
+
+        # this is the part that takes time
+        self.percentage(0)
+        try:
+            update, remove, fine, spm_fine = self._entropy.calculate_updates()
+        except SystemDatabaseError as err:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                "System Repository error: %s" % (err,))
+            return
+        self.percentage(100)
+
+        pkgs = []
+        for pkg_id, repo_id in update:
+            repo_db = self._entropy.open_repository(repo_id)
+            pkg = (pkg_id, repo_db)
+            pk_pkg = self._etp_to_id(pkg)
+            pkgs.append((pkg[0], pkg[1], pk_pkg,))
+
+        self._execute_etp_pkgs_install(pkgs, only_trusted)
 
 def main():
     backend = PackageKitEntropyBackend("")
commit 41f4100be8035595bc2ab90800e3f0e2879e5f1c
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 14:16:47 2010 +0100

    [entropy] more backend bits ftw

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 4a7d9e6..775e12b 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -222,6 +222,15 @@ backend_get_details (PkBackend *backend, gchar **package_ids)
 }
 
 /**
+ * backend_get_distro_upgrades:
+ */
+static void
+backend_get_distro_upgrades (PkBackend *backend)
+{
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-distro-upgrades", NULL);
+}
+
+/**
  * backend_get_files:
  */
 static void
@@ -456,43 +465,43 @@ backend_update_system (PkBackend *backend, gboolean only_trusted)
 PK_BACKEND_OPTIONS (
 	"Entropy",				/* description */
 	"Fabio Erculiani (lxnay) <lxnay at sabayon.org>",	/* author */
-	backend_initialize,			/* initalize */
-	backend_destroy,			/* destroy */
-	backend_get_groups,			/* get_groups */
-	backend_get_filters,			/* get_filters */
+	backend_initialize,					/* initalize */
+	backend_destroy,					/* destroy */
+	backend_get_groups,					/* get_groups */
+	backend_get_filters,				/* get_filters */
 	backend_get_roles,					/* get_roles */
-	NULL,					/* get_mime_types */
-	backend_cancel,				/* cancel */
-	backend_download_packages,					/* download_packages */
-	backend_get_categories,					/* get_categories */
-	backend_get_depends,			/* get_depends */
-	backend_get_details,			/* get_details */
-	NULL,					/* get_distro_upgrades */
-	backend_get_files,			/* get_files */
-	backend_get_packages,			/* get_packages */
-	backend_get_repo_list,			/* get_repo_list */
-	backend_get_requires,			/* 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 */
-	backend_remove_packages,		/* remove_packages */
-	backend_repo_enable,			/* repo_enable */
-	NULL,					/* repo_set_data */
-	backend_resolve,			/* resolve */
-	NULL,					/* rollback */
-	backend_search_details,			/* search_details */
-	backend_search_files,			/* search_file */
-	backend_search_groups,			/* search_group */
-	backend_search_names,			/* search_name */
-	backend_update_packages,		/* update_packages */
-	backend_update_system,			/* update_system */
-	NULL,					/* what_provides */
-	NULL,					/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	NULL,								/* get_mime_types */
+	backend_cancel,						/* cancel */
+	backend_download_packages,			/* download_packages */
+	backend_get_categories,				/* get_categories */
+	backend_get_depends,				/* get_depends */
+	backend_get_details,				/* get_details */
+	backend_get_distro_upgrades,		/* get_distro_upgrades */
+	backend_get_files,					/* get_files */
+	backend_get_packages,				/* get_packages */
+	backend_get_repo_list,				/* get_repo_list */
+	backend_get_requires,				/* 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 */
+	backend_remove_packages,			/* remove_packages */
+	backend_repo_enable,				/* repo_enable */
+	NULL,								/* repo_set_data */
+	backend_resolve,					/* resolve */
+	NULL,								/* rollback */
+	backend_search_details,				/* search_details */
+	backend_search_files,				/* search_file */
+	backend_search_groups,				/* search_group */
+	backend_search_names,				/* search_name */
+	backend_update_packages,			/* update_packages */
+	backend_update_system,				/* update_system */
+	NULL,								/* what_provides */
+	NULL,								/* simulate_install_files */
+	NULL,								/* simulate_install_packages */
+	NULL,								/* simulate_remove_packages */
+	NULL								/* simulate_update_packages */
 );
 
commit f30befc9f87c291583a93a70ea104deec686eb32
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 14:02:39 2010 +0100

    [entropy] update more backend bits ;)

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index 90d8956..35b5faf 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -2,10 +2,9 @@ Entropy PackageKit backend developers' TODO:
 
     - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
         FILTER_DEVELOPMENT, FILTER_VISIBLE
-    - remove support for FILTER_NEWEST (useless)
-    - add get_mime_types, update_system support
+    - add get_mime_types, update_system, install_files, simulate_* support,
+        repo_set_data
     - sys-apps/entropy is a syspkg
-    - improve performance of _log_message
     - messages? how push output to stdout?
     - license dialog??
 
diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 9a820ad..4a7d9e6 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -117,6 +117,49 @@ backend_get_filters (PkBackend *backend)
 }
 
 /**
+ * backend_get_roles:
+ */
+static PkBitfield
+backend_get_roles (PkBackend *backend)
+{
+	PkBitfield roles;
+	roles = pk_bitfield_from_enums (
+		PK_ROLE_ENUM_CANCEL,
+		PK_ROLE_ENUM_GET_DEPENDS,
+		PK_ROLE_ENUM_GET_DETAILS,
+		PK_ROLE_ENUM_GET_FILES,
+		PK_ROLE_ENUM_GET_REQUIRES,
+		PK_ROLE_ENUM_GET_PACKAGES,
+		//PK_ROLE_ENUM_WHAT_PROVIDES,
+		PK_ROLE_ENUM_GET_UPDATES,
+		PK_ROLE_ENUM_GET_UPDATE_DETAIL,
+		PK_ROLE_ENUM_INSTALL_PACKAGES,
+		//PK_ROLE_ENUM_INSTALL_FILES,
+		//PK_ROLE_ENUM_INSTALL_SIGNATURE,
+		PK_ROLE_ENUM_REFRESH_CACHE,
+		PK_ROLE_ENUM_REMOVE_PACKAGES,
+		PK_ROLE_ENUM_DOWNLOAD_PACKAGES,
+		PK_ROLE_ENUM_RESOLVE,
+		PK_ROLE_ENUM_SEARCH_DETAILS,
+		PK_ROLE_ENUM_SEARCH_FILE,
+		PK_ROLE_ENUM_SEARCH_GROUP,
+		PK_ROLE_ENUM_SEARCH_NAME,
+		PK_ROLE_ENUM_UPDATE_PACKAGES,
+		PK_ROLE_ENUM_UPDATE_SYSTEM,
+		PK_ROLE_ENUM_GET_REPO_LIST,
+		PK_ROLE_ENUM_REPO_ENABLE,
+		//PK_ROLE_ENUM_REPO_SET_DATA,
+		PK_ROLE_ENUM_GET_CATEGORIES,
+		//PK_ROLE_ENUM_SIMULATE_INSTALL_FILES,
+		//PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES,
+		//PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES,
+		//PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES,
+		-1);
+
+	return roles;
+}
+
+/**
  * backend_cancel:
  */
 static void
@@ -417,7 +460,7 @@ PK_BACKEND_OPTIONS (
 	backend_destroy,			/* destroy */
 	backend_get_groups,			/* get_groups */
 	backend_get_filters,			/* get_filters */
-	NULL,					/* get_roles */
+	backend_get_roles,					/* get_roles */
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
 	backend_download_packages,					/* download_packages */
commit 0e9389c2119be0b6090857da485de4712b8450b3
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 13:48:26 2010 +0100

    [entropy] update TODO

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index daee12e..90d8956 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -3,7 +3,7 @@ Entropy PackageKit backend developers' TODO:
     - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
         FILTER_DEVELOPMENT, FILTER_VISIBLE
     - remove support for FILTER_NEWEST (useless)
-    - add download_packages, get_mime_types, update_system support
+    - add get_mime_types, update_system support
     - sys-apps/entropy is a syspkg
     - improve performance of _log_message
     - messages? how push output to stdout?
commit db81823790cdd9b108b95f015fb8d796c340cf98
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 22:24:48 2010 +0100

    [portage] port portage backend to PackageKit HEAD

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index 8b16934..d745750 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -391,7 +391,7 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, "foo", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
 PK_BACKEND_OPTIONS (
commit 86d84676e8c089e5f1dc1e12688cd7f27a8d769e
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 2 12:46:42 2010 +0000

    trivial: scale lxnay to fit on the page...

diff --git a/docs/html/img/author-lxnay.png b/docs/html/img/author-lxnay.png
index f87c18e..d454111 100644
Binary files a/docs/html/img/author-lxnay.png and b/docs/html/img/author-lxnay.png differ
commit 8e451286badc6de26c3c343106fa2e68dbcdd0a6
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 2 12:34:53 2010 +0000

    Define a new error code for when the user declines the simulation

diff --git a/lib/packagekit-glib2/pk-client.h b/lib/packagekit-glib2/pk-client.h
index 6ce7811..5ad93dc 100644
--- a/lib/packagekit-glib2/pk-client.h
+++ b/lib/packagekit-glib2/pk-client.h
@@ -54,6 +54,7 @@ G_BEGIN_DECLS
  * @PK_CLIENT_ERROR_INVALID_INPUT: the package_id is invalid
  * @PK_CLIENT_ERROR_INVALID_FILE: the file is invalid
  * @PK_CLIENT_ERROR_NOT_SUPPORTED: the action is not supported
+ * @PK_CLIENT_ERROR_DECLINED_SIMULATION: the simulation was declined by the user
  *
  * Errors that can be thrown
  */
@@ -67,7 +68,8 @@ typedef enum
 	PK_CLIENT_ERROR_CANNOT_START_DAEMON,
 	PK_CLIENT_ERROR_INVALID_INPUT,
 	PK_CLIENT_ERROR_INVALID_FILE,
-	PK_CLIENT_ERROR_NOT_SUPPORTED
+	PK_CLIENT_ERROR_NOT_SUPPORTED,
+	PK_CLIENT_ERROR_DECLINED_SIMULATION
 } PkClientError;
 
 typedef struct _PkClientPrivate		PkClientPrivate;
diff --git a/lib/packagekit-glib2/pk-task.c b/lib/packagekit-glib2/pk-task.c
index c5dc34a..c5b6306 100644
--- a/lib/packagekit-glib2/pk-task.c
+++ b/lib/packagekit-glib2/pk-task.c
@@ -628,7 +628,7 @@ pk_task_user_declined_idle_cb (PkTaskState *state)
 
 	/* the introduction is finished */
 	if (state->simulate) {
-		error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "user declined simulation");
+		error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_DECLINED_SIMULATION, "user declined simulation");
 		pk_task_generic_state_finish (state, error);
 		g_error_free (error);
 		goto out;
commit 8fe49c17329ec4bdfc54d1838e429b697e6ffe5b
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 2 10:40:24 2010 +0000

    Add a new library function: pk_package_sack_filter_by_info()

diff --git a/lib/packagekit-glib2/pk-package-sack.c b/lib/packagekit-glib2/pk-package-sack.c
index 88abda9..af61ed6 100644
--- a/lib/packagekit-glib2/pk-package-sack.c
+++ b/lib/packagekit-glib2/pk-package-sack.c
@@ -144,6 +144,43 @@ pk_package_sack_get_array (PkPackageSack *sack)
 }
 
 /**
+ * pk_package_sack_filter_by_info:
+ * @sack: a valid #PkPackageSack instance
+ * @info: a %PkInfoEnum value to match
+ *
+ * Returns a new package sack which only matches packages that match the
+ * specified info enum value.
+ *
+ * Return value: a new #PkPackageSack, free with g_object_unref()
+ *
+ * Since: 0.6.2
+ **/
+PkPackageSack *
+pk_package_sack_filter_by_info (PkPackageSack *sack, PkInfoEnum info)
+{
+	PkPackageSack *results;
+	PkPackage *package;
+	PkInfoEnum info_tmp;
+	guint i;
+	PkPackageSackPrivate *priv = sack->priv;
+
+	g_return_val_if_fail (PK_IS_PACKAGE_SACK (sack), NULL);
+
+	/* create new sack */
+	results = pk_package_sack_new ();
+
+	/* add each that matches the info enum */
+	for (i = 0; i < priv->array->len; i++) {
+		package = g_ptr_array_index (priv->array, i);
+		info_tmp = pk_package_get_info (package);
+		if (info_tmp == info)
+			pk_package_sack_add_package (results, package);
+	}
+
+	return results;
+}
+
+/**
  * pk_package_sack_add_package:
  * @sack: a valid #PkPackageSack instance
  * @package: a valid #PkPackage instance
diff --git a/lib/packagekit-glib2/pk-package-sack.h b/lib/packagekit-glib2/pk-package-sack.h
index 8655d41..fd306c8 100644
--- a/lib/packagekit-glib2/pk-package-sack.h
+++ b/lib/packagekit-glib2/pk-package-sack.h
@@ -98,6 +98,8 @@ gboolean	 pk_package_sack_remove_package_by_id	(PkPackageSack		*sack,
 							 const gchar		*package_id);
 PkPackage	*pk_package_sack_find_by_id		(PkPackageSack		*sack,
 							 const gchar		*package_id);
+PkPackageSack	*pk_package_sack_filter_by_info		(PkPackageSack		*sack,
+							 PkInfoEnum		 info);
 guint64		 pk_package_sack_get_total_bytes	(PkPackageSack		*sack);
 
 gboolean	 pk_package_sack_merge_generic_finish	(PkPackageSack		*sack,
commit c3c2b51492735165475fa75feb7e91b94abb01a6
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 2 10:35:56 2010 +0000

    trivial: re-instate pk_package_sack_get_size()

diff --git a/lib/packagekit-glib2/pk-package-sack.c b/lib/packagekit-glib2/pk-package-sack.c
index 8af4e7f..88abda9 100644
--- a/lib/packagekit-glib2/pk-package-sack.c
+++ b/lib/packagekit-glib2/pk-package-sack.c
@@ -80,6 +80,24 @@ pk_package_sack_clear (PkPackageSack *sack)
 }
 
 /**
+ * pk_package_sack_get_size:
+ * @sack: a valid #PkPackageSack instance
+ *
+ * Gets the number of packages in the sack
+ *
+ * Return value: the number of packages in the sack
+ *
+ * Since: 0.5.2
+ **/
+guint
+pk_package_sack_get_size (PkPackageSack *sack)
+{
+	g_return_val_if_fail (PK_IS_PACKAGE_SACK (sack), 0);
+
+	return sack->priv->array->len;
+}
+
+/**
  * pk_package_sack_get_ids:
  * @sack: a valid #PkPackageSack instance
  *
diff --git a/lib/packagekit-glib2/pk-package-sack.h b/lib/packagekit-glib2/pk-package-sack.h
index 12e56ce..8655d41 100644
--- a/lib/packagekit-glib2/pk-package-sack.h
+++ b/lib/packagekit-glib2/pk-package-sack.h
@@ -83,6 +83,7 @@ void		 pk_package_sack_test			(gpointer		 user_data);
 /* managing the array */
 void		 pk_package_sack_clear			(PkPackageSack		*sack);
 gchar		**pk_package_sack_get_ids		(PkPackageSack		*sack);
+guint		 pk_package_sack_get_size		(PkPackageSack		*sack);
 GPtrArray	*pk_package_sack_get_array		(PkPackageSack		*sack);
 void		 pk_package_sack_sort			(PkPackageSack		*sack,
 							 PkPackageSackSortType	 type);
commit 6285f181eab2256b51227b5d1d6e1de6898418a8
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 13:14:30 2010 +0100

    add myself to developers' page

diff --git a/docs/html/img/author-lxnay.png b/docs/html/img/author-lxnay.png
new file mode 100644
index 0000000..f87c18e
Binary files /dev/null and b/docs/html/img/author-lxnay.png differ
diff --git a/docs/html/pk-authors.html b/docs/html/pk-authors.html
index 3b95d17..c5fb82a 100644
--- a/docs/html/pk-authors.html
+++ b/docs/html/pk-authors.html
@@ -331,6 +331,21 @@
  </td>
 </tr>
 
+<tr>
+ <td>
+  <img src="img/author-lxnay.png" alt=""/><!-- image should be 120px wide -->
+ </td>
+ <td>
+  <h2>Fabio Erculiani</h2>
+  <p>
+    Fabio is the <a href='http://www.sabayon.org'>Sabayon</a> Linux project leader, freelance IT consultant and student at the <a href="http://www.unitn.it">University of Trento</a> (Italy). He is also a <a href='http://www.gentoo.org/'>Gentoo</a> developer. He began helping out on the Portage backend and is also responsible of the implementation of the Entropy one.
+  </p>
+  <p>
+   <b>Responsible for: portage backend, entropy backend</b>
+  </p>
+ </td>
+</tr>
+
 </table>
 
 <p>Back to the <a href="index.html">main page</a></p>
commit c63790de60ff000af3dd19c48bcb5744fcbb1b78
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Feb 2 09:00:18 2010 +0000

    Add the polkit backend library in LIBADD, not LDFLAGS. Fixes fd#26373

diff --git a/src/Makefile.am b/src/Makefile.am
index f893abb..80d5caf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -193,12 +193,12 @@ libpackagekit_action_lookup_la_CFLAGS =				\
 libpackagekit_action_lookup_la_LDFLAGS =			\
 	-export_dynamic -avoid-version -module -no-undefined	\
 	-export-symbols-regex '^g_io_module_(load|unload)'	\
-	$(POLKIT_BACKEND_1_LIBS)				\
 	$(NULL)
 
 libpackagekit_action_lookup_la_LIBADD =				\
 	$(GLIB_LIBS)						\
 	$(PK_GLIB2_LIBS)					\
+	$(POLKIT_BACKEND_1_LIBS)				\
 	$(NULL)
 endif
 
commit 64e8c018d4d579ebb68e6ed3e75829b1c91b8e3b
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 1 15:14:04 2010 +0000

    yum: add simulate-install-packages, simulate-update-packages and simulate-remove-packages

diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index fc3defa..4a3a16e 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -191,6 +191,9 @@ backend_get_roles (PkBackend *backend)
 		PK_ROLE_ENUM_REPO_SET_DATA,
 		PK_ROLE_ENUM_GET_CATEGORIES,
 		PK_ROLE_ENUM_SIMULATE_INSTALL_FILES,
+		PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES,
+		PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES,
+		PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES,
 		-1);
 
 	/* only add GetDistroUpgrades if the binary is present */
@@ -347,6 +350,48 @@ backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **pac
 }
 
 /**
+ * backend_simulate_remove_packages:
+ */
+static void
+backend_simulate_remove_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	pk_backend_spawn_helper (spawn, "yumBackend.py", "simulate-remove-packages", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_update_packages:
+ */
+static void
+backend_simulate_update_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	pk_backend_spawn_helper (spawn, "yumBackend.py", "simulate-update-packages", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_simulate_install_packages:
+ */
+static void
+backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	pk_backend_spawn_helper (spawn, "yumBackend.py", "simulate-install-packages", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
  * backend_install_files:
  */
 static void
@@ -613,8 +658,8 @@ PK_BACKEND_OPTIONS (
 	backend_update_system,			/* update_system */
 	backend_what_provides,			/* what_provides */
 	backend_simulate_install_files,		/* simulate_install_files */
-	NULL,					/* simulate_install_packages */
-	NULL,					/* simulate_remove_packages */
-	NULL					/* simulate_update_packages */
+	backend_simulate_install_packages,	/* simulate_install_packages */
+	backend_simulate_remove_packages,	/* simulate_remove_packages */
+	backend_simulate_update_packages	/* simulate_update_packages */
 );
 
diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 3592347..4316150 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -1028,7 +1028,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         except Exception, e:
             raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
 
-	# multiple entries
+    # multiple entries
         if len(pkgs) > 1:
             raise PkError(ERROR_INTERNAL_ERROR, "more than one package match for %s" % _format_package_id(package_id))
 
@@ -1501,22 +1501,24 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         else:
             if txmbr:
                 # check all the packages in the transaction if only-trusted
-                if only_trusted:
-                    for t in txmbr:
-                        # ignore transactions that do not have to be checked, e.g. obsoleted
-                        if t.output_state not in self.transaction_sig_check_map:
-                            continue
-                        pkg = t.po
-                        try:
-                            signed = self._is_package_repo_signed(pkg)
-                        except PkError, e:
-                            self.error(e.code, e.details, exit=False)
-                            return
-                        if not signed:
-                            self.error(ERROR_CANNOT_UPDATE_REPO_UNSIGNED, "The package %s will not be updated from unsigned repo %s" % (pkg.name, pkg.repoid), exit=False)
-                            return
+                for t in txmbr:
+                    # ignore transactions that do not have to be checked, e.g. obsoleted
+                    if t.output_state not in self.transaction_sig_check_map:
+                        continue
+                    pkg = t.po
+                    try:
+                        signed = self._is_package_repo_signed(pkg)
+                    except PkError, e:
+                        self.error(e.code, e.details, exit=False)
+                        return
+                    if signed:
+                        continue
+                    if only_trusted:
+                        self.error(ERROR_CANNOT_UPDATE_REPO_UNSIGNED, "The package %s will not be updated from unsigned repo %s" % (pkg.name, pkg.repoid), exit=False)
+                        return
+                    self.message (MESSAGE_UNTRUSTED_PACKAGE, "The package %s from repo %s is untrusted" % (pkg.name, pkg.repoid))
                 try:
-                    self._runYumTransaction(allow_skip_broken=True)
+                    self._runYumTransaction(allow_skip_broken=True, only_simulate=False)
                 except PkError, e:
                     self.error(e.code, e.details, exit=False)
             else:
@@ -1634,10 +1636,15 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         package_list = pkgfilter.post_process()
         self._show_package_list(package_list)
 
-    def install_packages(self, only_trusted, package_ids):
+    def install_packages(self, only_trusted, inst_files):
+        self._install_packages(only_trusted, inst_files)
+
+    def simulate_install_packages(self, inst_files):
+        self._install_packages(False, inst_files, True)
+
+    def _install_packages(self, only_trusted, package_ids, simulate=False):
         '''
         Implement the install-packages functionality
-        This will only work with yum 3.2.4 or higher
         '''
         try:
             self._check_init()
@@ -1686,22 +1693,25 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                     self.error(ERROR_PACKAGE_ALREADY_INSTALLED, "The package %s is already installed" % pkg.name, exit=False)
                     return
         if txmbrs:
-            if only_trusted:
-                for t in txmbrs:
-                    pkg = t.po
-                    # ignore transactions that do not have to be checked, e.g. obsoleted
-                    if t.output_state not in self.transaction_sig_check_map:
-                        continue
-                    try:
-                        signed = self._is_package_repo_signed(pkg)
-                    except PkError, e:
-                        self.error(e.code, e.details, exit=False)
-                        return
-                    if not signed:
-                        self.error(ERROR_CANNOT_INSTALL_REPO_UNSIGNED, "The package %s will not be installed from unsigned repo %s" % (pkg.name, pkg.repoid), exit=False)
-                        return
+            for t in txmbrs:
+                pkg = t.po
+                # ignore transactions that do not have to be checked, e.g. obsoleted
+                if t.output_state not in self.transaction_sig_check_map:
+                    continue
+                try:
+                    signed = self._is_package_repo_signed(pkg)
+                except PkError, e:
+                    self.error(e.code, e.details, exit=False)
+                    return
+                if signed:
+                    continue
+                if only_trusted:
+                    self.error(ERROR_CANNOT_INSTALL_REPO_UNSIGNED, "The package %s will not be installed from unsigned repo %s" % (pkg.name, pkg.repoid), exit=False)
+                    return
+                self.message (MESSAGE_UNTRUSTED_PACKAGE, "The package %s from repo %s is untrusted" % (pkg.name, pkg.repoid))
+
             try:
-                self._runYumTransaction()
+                self._runYumTransaction(only_simulate=simulate)
             except PkError, e:
                 self.error(e.code, e.details, exit=False)
         else:
@@ -1723,6 +1733,12 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 self.message(MESSAGE_NEWER_PACKAGE_EXISTS, "A newer version of %s is available online." % po.name)
 
     def install_files(self, only_trusted, inst_files):
+        self._install_files(only_trusted, inst_files)
+
+    def simulate_install_files(self, inst_files):
+        self._install_files(False, inst_files, True)
+
+    def _install_files(self, only_trusted, inst_files, simulate=False):
         '''
         Implement the install-files functionality
         Install the package containing the inst_file file
@@ -1875,8 +1891,9 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             if len(self.yumbase.tsInfo) == 0:
                 self.error(ERROR_LOCAL_INSTALL_FAILED, "Can't install %s" % " or ".join(inst_files), exit=False)
                 return
+
             try:
-                self._runYumTransaction()
+                self._runYumTransaction(only_simulate=simulate)
             except PkError, e:
                 self.error(e.code, e.details, exit=False)
                 return
@@ -1902,7 +1919,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                             if not self.yumbase.tsInfo.pkgSack:
                                 self.yumbase.tsInfo.pkgSack = MetaSack()
                             try:
-                                self._runYumTransaction()
+                                self._runYumTransaction(only_simulate=simulate)
                             except PkError, e:
                                 self.error(e.code, e.details, exit=False)
                                 return
@@ -1950,6 +1967,12 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
         return True
 
     def update_packages(self, only_trusted, package_ids):
+        self._update_packages(only_trusted, package_ids)
+
+    def simulate_update_packages(self, package_ids):
+        self._update_packages(False, package_ids, True)
+
+    def _update_packages(self, only_trusted, package_ids, simulate=False):
         '''
         Implement the install functionality
         This will only work with yum 3.2.4 or higher
@@ -1997,22 +2020,25 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
         else:
             if txmbrs:
-                if only_trusted:
-                    for t in txmbrs:
-                        # ignore transactions that do not have to be checked, e.g. obsoleted
-                        if t.output_state not in self.transaction_sig_check_map:
-                            continue
-                        pkg = t.po
-                        try:
-                            signed = self._is_package_repo_signed(pkg)
-                        except PkError, e:
-                            self.error(e.code, e.details, exit=False)
-                            return
-                        if not signed:
-                            self.error(ERROR_CANNOT_UPDATE_REPO_UNSIGNED, "The package %s will not be updated from unsigned repo %s" % (pkg.name, pkg.repoid), exit=False)
-                            return
+                for t in txmbrs:
+                    # ignore transactions that do not have to be checked, e.g. obsoleted
+                    if t.output_state not in self.transaction_sig_check_map:
+                        continue
+                    pkg = t.po
+                    try:
+                        signed = self._is_package_repo_signed(pkg)
+                    except PkError, e:
+                        self.error(e.code, e.details, exit=False)
+                        return
+                    if signed:
+                        continue
+                    if only_trusted:
+                        self.error(ERROR_CANNOT_UPDATE_REPO_UNSIGNED, "The package %s will not be updated from unsigned repo %s" % (pkg.name, pkg.repoid), exit=False)
+                        return
+                    self.message (MESSAGE_UNTRUSTED_PACKAGE, "The package %s from repo %s is untrusted" % (pkg.name, pkg.repoid))
+
                 try:
-                    self._runYumTransaction(allow_skip_broken=True)
+                    self._runYumTransaction(allow_skip_broken=True, only_simulate=simulate)
                 except PkError, e:
                     self.error(e.code, e.details, exit=False)
             else:
@@ -2029,7 +2055,7 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
                 or (notice and notice.get_metadata().has_key('reboot_suggested') and notice['reboot_suggested'])):
                 self.require_restart(RESTART_SYSTEM, self._pkg_to_id(pkg))
 
-    def _runYumTransaction(self, allow_remove_deps=None, allow_skip_broken=False):
+    def _runYumTransaction(self, allow_remove_deps=None, allow_skip_broken=False, only_simulate=False):
         '''
         Run the yum Transaction
         This will only work with yum 3.2.4 or higher
@@ -2055,60 +2081,79 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             except Exception, e:
                 raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
 
+        # test did succeed
+        self._check_for_reboot()
+        if allow_remove_deps == False:
+            if len(self.yumbase.tsInfo) > 1:
+                retmsg = 'package could not be removed, as other packages depend on it'
+                raise PkError(ERROR_DEP_RESOLUTION_FAILED, retmsg)
+
+        # abort now we have the package list
+        if only_simulate:
+            package_list = []
+            for txmbr in self.yumbase.tsInfo:
+                if txmbr.output_state in TransactionsInfoMap.keys():
+                    info = TransactionsInfoMap[txmbr.output_state]
+                    package_list.append((txmbr.po, info))
+
+            self.percentage(90)
+            self._show_package_list(package_list)
+            self.percentage(100)
+            return
+
         # we did not succeed
         if rc != 2:
             if message.find ("is needed by") != -1:
                 raise PkError(ERROR_DEP_RESOLUTION_FAILED, message)
             if message.find ("empty transaction") != -1:
                 raise PkError(ERROR_NO_PACKAGES_TO_UPDATE, message)
+            raise PkError(ERROR_TRANSACTION_ERROR, message)
+
+        try:
+            rpmDisplay = PackageKitCallback(self)
+            callback = ProcessTransPackageKitCallback(self)
+            self.yumbase.processTransaction(callback=callback,
+                                  rpmDisplay=rpmDisplay)
+        except yum.Errors.YumDownloadError, ye:
+            raise PkError(ERROR_PACKAGE_DOWNLOAD_FAILED, _format_msgs(ye.value))
+        except yum.Errors.YumGPGCheckError, ye:
+            raise PkError(ERROR_BAD_GPG_SIGNATURE, _format_msgs(ye.value))
+        except GPGKeyNotImported, e:
+            keyData = self.yumbase.missingGPGKey
+            if not keyData:
+                raise PkError(ERROR_BAD_GPG_SIGNATURE, "GPG key not imported, and no GPG information was found.")
+            package_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(package_id,
+                                         keyData['po'].repoid,
+                                         keyData['keyurl'].replace("file://", ""),
+                                         keyData['userid'],
+                                         keyData['hexkeyid'],
+                                         hex_fingerprint,
+                                         time.ctime(keyData['timestamp']),
+                                         'gpg')
+            raise PkError(ERROR_GPG_FAILURE, "GPG key %s required" % keyData['hexkeyid'])
+        except yum.Errors.YumBaseError, ye:
+            message = _format_msgs(ye.value)
+            if message.find ("conflicts with file") != -1:
+                raise PkError(ERROR_FILE_CONFLICTS, message)
+            if message.find ("rpm_check_debug vs depsolve") != -1:
+                raise PkError(ERROR_PACKAGE_CONFLICTS, message)
             else:
                 raise PkError(ERROR_TRANSACTION_ERROR, message)
-        else:
-            self._check_for_reboot()
-            if allow_remove_deps == False:
-                if len(self.yumbase.tsInfo) > 1:
-                    retmsg = 'package could not be removed, as other packages depend on it'
-                    raise PkError(ERROR_DEP_RESOLUTION_FAILED, retmsg)
-
-            try:
-                rpmDisplay = PackageKitCallback(self)
-                callback = ProcessTransPackageKitCallback(self)
-                self.yumbase.processTransaction(callback=callback,
-                                      rpmDisplay=rpmDisplay)
-            except yum.Errors.YumDownloadError, ye:
-                raise PkError(ERROR_PACKAGE_DOWNLOAD_FAILED, _format_msgs(ye.value))
-            except yum.Errors.YumGPGCheckError, ye:
-                raise PkError(ERROR_BAD_GPG_SIGNATURE, _format_msgs(ye.value))
-            except GPGKeyNotImported, e:
-                keyData = self.yumbase.missingGPGKey
-                if not keyData:
-                    raise PkError(ERROR_BAD_GPG_SIGNATURE, "GPG key not imported, and no GPG information was found.")
-                package_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(package_id,
-                                             keyData['po'].repoid,
-                                             keyData['keyurl'].replace("file://", ""),
-                                             keyData['userid'],
-                                             keyData['hexkeyid'],
-                                             hex_fingerprint,
-                                             time.ctime(keyData['timestamp']),
-                                             'gpg')
-                raise PkError(ERROR_GPG_FAILURE, "GPG key %s required" % keyData['hexkeyid'])
-            except yum.Errors.YumBaseError, ye:
-                message = _format_msgs(ye.value)
-                if message.find ("conflicts with file") != -1:
-                    raise PkError(ERROR_FILE_CONFLICTS, message)
-                if message.find ("rpm_check_debug vs depsolve") != -1:
-                    raise PkError(ERROR_PACKAGE_CONFLICTS, message)
-                else:
-                    raise PkError(ERROR_TRANSACTION_ERROR, message)
-            except Exception, e:
-                raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
+        except Exception, e:
+            raise PkError(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
 
     def remove_packages(self, allowdep, autoremove, package_ids):
+        self._remove_packages(allowdep, autoremove, package_ids)
+
+    def simulate_remove_packages(self, package_ids):
+        self._remove_packages(True, False, package_ids, True)
+
+    def _remove_packages(self, allowdep, autoremove, package_ids, simulate=False):
         '''
         Implement the remove functionality
         Needed to be implemented in a sub class
@@ -2165,15 +2210,15 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             else:
                 for txmbr in self.yumbase.tsInfo:
                     pkg = txmbr.po
-                    system_packages = ['yum','rpm','glibc','PackageKit']
+                    system_packages = ['yum', 'rpm', 'glibc', 'PackageKit']
                     if pkg.name in system_packages:
                         self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE, "The package %s is essential to correct operation and cannot be removed using this tool." % pkg.name, exit=False)
                         return
             try:
                 if not allowdep:
-                    self._runYumTransaction(allow_remove_deps=False)
+                    self._runYumTransaction(allow_remove_deps=False, only_simulate=simulate)
                 else:
-                    self._runYumTransaction(allow_remove_deps=True)
+                    self._runYumTransaction(allow_remove_deps=True, only_simulate=simulate)
             except PkError, e:
                 self.error(e.code, e.details, exit=False)
         else:
@@ -2661,65 +2706,6 @@ class PackageKitYumBackend(PackageKitBaseBackend, PackagekitPackage):
             except IOError, e:
                 self.error(ERROR_CANNOT_WRITE_REPO_CONFIG, _to_unicode(e))
 
-    def simulate_install_files(self, inst_files):
-        '''
-        Install the package containing the inst_file file
-        '''
-        try:
-            self._check_init()
-        except PkError, e:
-            self.error(e.code, e.details, exit=False)
-            return
-        self.yumbase.conf.cache = 0 # Allow new files
-        self.allow_cancel(True)
-        self.percentage(0)
-        self.status(STATUS_RUNNING)
-
-        for inst_file in inst_files:
-            if inst_file.endswith('.src.rpm'):
-                self.error(ERROR_CANNOT_INSTALL_SOURCE_PACKAGE, 'Backend will not install a src rpm file', exit=False)
-                return
-
-        # common checks copied from yum
-        for inst_file in inst_files:
-            if not self._check_local_file(inst_file):
-                return
-
-        package_list = []
-        txmbrs = []
-        for inst_file in inst_files:
-            try:
-                txmbr = self.yumbase.installLocal(inst_file)
-            except Exception, e:
-                self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
-            if txmbr:
-                txmbrs.extend(txmbr)
-            else:
-                self.error(ERROR_LOCAL_INSTALL_FAILED, "Can't install %s as no transaction" % _to_unicode(inst_file))
-        if len(self.yumbase.tsInfo) == 0:
-            self.error(ERROR_LOCAL_INSTALL_FAILED, "Can't install %s" % " or ".join(inst_files), exit=False)
-            return
-
-        # do the depsolve to pull in deps
-        try:
-            rc, msgs =  self.yumbase.buildTransaction()
-        except yum.Errors.RepoError, e:
-            self.error(ERROR_REPO_NOT_AVAILABLE, _to_unicode(e))
-        except Exception, e:
-            self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
-        if rc != 2:
-            self.error(ERROR_DEP_RESOLUTION_FAILED, _format_msgs(msgs))
-
-        # add each package
-        for txmbr in self.yumbase.tsInfo:
-            if txmbr.output_state in TransactionsInfoMap.keys():
-                info = TransactionsInfoMap[txmbr.output_state]
-                package_list.append((txmbr.po, info))
-
-        self.percentage(90)
-        self._show_package_list(package_list)
-        self.percentage(100)
-
     def install_signature(self, sigtype, key_id, package_id):
         try:
             self._check_init()
commit 47375485bc5abb27f3c9c3f679927ac4fe362bf6
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 1 15:13:27 2010 +0000

    Do not run the transaction with only_trusted if the simulation inferred that any packages were unsigned

diff --git a/lib/packagekit-glib2/pk-task.c b/lib/packagekit-glib2/pk-task.c
index 864435c..c5dc34a 100644
--- a/lib/packagekit-glib2/pk-task.c
+++ b/lib/packagekit-glib2/pk-task.c
@@ -211,9 +211,12 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 	guint idx = 0;
 	guint i;
 	GPtrArray *array = NULL;
+	GPtrArray *array_messages = NULL;
 	PkPackage *item;
 	gboolean ret;
 	PkInfoEnum info;
+	PkMessage *message;
+	PkMessageEnum message_type;
 	const gchar *package_id;
 
 	/* old results no longer valid */
@@ -253,6 +256,23 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 		goto out;
 	}
 
+	/* if we did a simulate and we got a message that a package was untrusted,
+	 * there's no point trying to do the action with only-trusted */
+	if (state->simulate && state->only_trusted) {
+		array_messages = pk_results_get_message_array (state->results);
+		for (i = 0; i < array_messages->len; i++) {
+			message = g_ptr_array_index (array_messages, i);
+			g_object_get (message,
+				      "type", &message_type,
+				      NULL);
+			if (message_type == PK_MESSAGE_ENUM_UNTRUSTED_PACKAGE) {
+				egg_debug ("we got an untrusted message, so skipping only-trusted");
+				state->only_trusted = FALSE;
+				break;
+			}
+		}
+	}
+
 	/* get data */
 	sack = pk_results_get_package_sack (results);
 
@@ -309,6 +329,8 @@ pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskStat
 out:
 	if (array != NULL)
 		g_ptr_array_unref (array);
+	if (array_messages != NULL)
+		g_ptr_array_unref (array_messages);
 	if (results != NULL)
 		g_object_unref (results);
 	if (sack != NULL)
commit 2e9e8484c750d2621a765dae5bc312c85fd1c49a
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 1 15:02:18 2010 +0000

    trivial: show a warning when we fallback to get-depends or get-requires

diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index cab7ab9..94518c1 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1783,6 +1783,7 @@ pk_transaction_set_running (PkTransaction *transaction)
 		if (pk_backend_is_implemented (priv->backend, PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES)) {
 			pk_backend_simulate_install_packages (priv->backend, priv->cached_package_ids);
 		} else {
+			egg_warning ("falling back to get depends as simulate install packages isn't implemented");
 			/* we need to emit the original packages before we fall back */
 			for (i=0; priv->cached_package_ids[i] != NULL; i++)
 				pk_backend_package (priv->backend, PK_INFO_ENUM_INSTALLING, priv->cached_package_ids[i], "");
@@ -1794,6 +1795,7 @@ pk_transaction_set_running (PkTransaction *transaction)
 		if (pk_backend_is_implemented (priv->backend, PK_ROLE_ENUM_SIMULATE_REMOVE_PACKAGES)) {
 			pk_backend_simulate_remove_packages (priv->backend, priv->cached_package_ids);
 		} else {
+			egg_warning ("falling back to get requires as simulate remove packages isn't implemented");
 			filters = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED, PK_FILTER_ENUM_NEWEST, -1);
 			pk_backend_get_requires (priv->backend, filters, priv->cached_package_ids, TRUE);
 		}
@@ -1802,6 +1804,7 @@ pk_transaction_set_running (PkTransaction *transaction)
 		if (pk_backend_is_implemented (priv->backend, PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES)) {
 			pk_backend_simulate_update_packages (priv->backend, priv->cached_package_ids);
 		} else {
+			egg_warning ("falling back to get depends as simulate update packages isn't implemented");
 			/* we need to emit the original packages before we fall back */
 			for (i=0; priv->cached_package_ids[i] != NULL; i++)
 				pk_backend_package (priv->backend, PK_INFO_ENUM_UPDATING, priv->cached_package_ids[i], "");
commit 4c7676549e1eee450c3289037929b7c0ce104bf8
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 1 15:01:15 2010 +0000

    Show messages in the pkmon output when the task has completed

diff --git a/client/pk-monitor.c b/client/pk-monitor.c
index ca2b10f..fd58937 100644
--- a/client/pk-monitor.c
+++ b/client/pk-monitor.c
@@ -84,6 +84,25 @@ pk_monitor_notify_network_status_cb (PkControl *control, GParamSpec *pspec, gpoi
 }
 
 /**
+ * pk_monitor_message_cb:
+ **/
+static void
+pk_monitor_message_cb (PkMessage *item, const gchar *transaction_id)
+{
+	gchar *details;
+	PkMessageEnum type;
+
+	/* get data */
+	g_object_get (item,
+		      "details", &details,
+		      "type", &type,
+		      NULL);
+
+	g_print ("%s\tmessage: %s, %s\n", transaction_id, pk_message_enum_to_string (type), details);
+	g_free (details);
+}
+
+/**
  * pk_monitor_adopt_cb:
  **/
 static void
@@ -95,6 +114,7 @@ pk_monitor_adopt_cb (PkClient *_client, GAsyncResult *res, gpointer user_data)
 	PkExitEnum exit_enum;
 	gchar *transaction_id = NULL;
 	PkError *error_code = NULL;
+	GPtrArray *array = NULL;
 
 	/* get the results */
 	results = pk_client_generic_finish (client, res, &error);
@@ -117,12 +137,18 @@ pk_monitor_adopt_cb (PkClient *_client, GAsyncResult *res, gpointer user_data)
 	exit_enum = pk_results_get_exit_code (results);
 	g_print ("%s\texit code: %s\n", transaction_id, pk_exit_enum_to_string (exit_enum));
 
+	/* message */
+	array = pk_results_get_message_array (results);
+	g_ptr_array_foreach (array, (GFunc) pk_monitor_message_cb, transaction_id);
+
 	/* check error code */
 	error_code = pk_results_get_error_code (results);
 	if (error_code != NULL)
 		g_print ("%s\terror code: %s, %s\n", transaction_id, pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
 out:
 	g_free (transaction_id);
+	if (array != NULL)
+		g_ptr_array_unref (array);
 	if (error_code != NULL)
 		g_object_unref (error_code);
 	if (progress != NULL)
commit 2a9bdd7a5e9ad5946e7debe35acaef2ab9e1e187
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 1 11:22:36 2010 +0000

    trivial: post release version bump

diff --git a/RELEASE b/RELEASE
index 0943b84..2eb8cb1 100644
--- a/RELEASE
+++ b/RELEASE
@@ -2,7 +2,7 @@ PackageKit Release Notes
 
 1. Write NEWS entries for PackageKit in the same format as usual.
 
-git shortlog PACKAGEKIT_0_6_0.. | grep -i -v trivial | grep -v Merge > NEWS.new
+git shortlog PACKAGEKIT_0_6_1.. | grep -i -v trivial | grep -v Merge > NEWS.new
 
 --------------------------------------------------------------------------------
 Version 0.6.x
@@ -26,8 +26,8 @@ Bugfixes:
 
 4. Commit changes in PackageKit git:
 
-git commit -a -m "Release version 0.6.1"
-git tag -s -f -m "Release 0.6.1" PACKAGEKIT_0_6_1
+git commit -a -m "Release version 0.6.2"
+git tag -s -f -m "Release 0.6.2" PACKAGEKIT_0_6_2
 <gpg password>
 git push --tags
 git push
@@ -52,9 +52,9 @@ git push
 10. Send an email to packagekit at lists.freedesktop.org
 
 =================================================
-Subject: PackageKit 0.6.0 released!
+Subject: PackageKit 0.6.1 released!
 
-Today I released PackageKit 0.6.0.
+Today I released PackageKit 0.6.1.
 
 PackageKit release notes: http://cgit.freedesktop.org/packagekit/tree/NEWS
 
diff --git a/configure.ac b/configure.ac
index c454ef2..0c00318 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ(2.65)
 
 m4_define([pk_major_version], [0])
 m4_define([pk_minor_version], [6])
-m4_define([pk_micro_version], [1])
+m4_define([pk_micro_version], [2])
 m4_define([pk_version],
           [pk_major_version.pk_minor_version.pk_micro_version])
 
commit 8aa4c4c30537c9c66533b2de15f8fe8806fcb5d2
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Feb 1 11:21:05 2010 +0000

    Release version 0.6.1

diff --git a/NEWS b/NEWS
index d07c09f..4270838 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,54 @@
+Version 0.6.1
+~~~~~~~~~~~~~
+Released: 2010-02-01
+
+Translations:
+ - Updated translation for Chinese (Simplified) (gml520)
+ - Updated translation for Dutch (warrink)
+ - Updated translation for Polish (raven)
+ - Updated translation for Spanish (elsupergomez)
+
+Libraries:
+
+Backends:
+ - alpm: Added autoremove and HoldPkg functionality (PirateJonno)
+ - alpm: Changed search functions to allow multiple search values (Valeriy Lyasotskiy)
+ - alpm: Handle ILoveCandy config option (PirateJonno)
+ - alpm: More formatting (PirateJonno)
+ - alpm: Understand more config options (PirateJonno)
+ - aptcc: Impoved search file (Daniel Nicoletti)
+ - portage: Fix compilation and port code to new API (Fabio Erculiani)
+ - ports: Convert search params to array values (Anders F Bjorklund)
+ - urpmi: Fix backend api (Aurelien Lefebvre)
+ - yum: Emit a warning when a developer tries to use autoremove (Richard Hughes)
+ - yum: Ensure we look in all update notices for a security update. Fixes rh#526279 (Richard Hughes)
+ - yum: Include PackageKit in the list of essential packages (Richard Hughes)
+ - yum: Show a message to the user if the repo could not be reached. Fixes rh#531838 (Richard Hughes)
+ - yum: Use repo-for-developers-only when enabling rawhide (Richard Hughes)
+ - zypp: Add more features to repo_set_data (Ladislav Slezak)
+ - zypp: Partial support of multiple values for search params (Scott Reeves)
+ - zypp: Work with packagekit-glib2 (Scott Reeves)
+
+New Features:
+ - Add Kubuntu support for upgrade (Daniel Nicoletti)
+ - Add support for the 'interactive' hint in the daemon, and also sent it to the backend (Richard Hughes)
+ - Add a new message enum 'repo-for-developers-only' for repos that should not be used by users (Richard Hughes)
+ - Add sync versions of the PkPackageSack functions (Richard Hughes)
+ - Enable initial introspection support in PackageKit-glib2 (Richard Hughes)
+ - Sort the packages by name in all pkcon results (Richard Hughes)
+
+Bugfixes:
+ - Ensure we enter SETUP before we run the pre-transaction checks (Richard Hughes)
+ - Add a parent object to all the source objects to track the source role and transacton id (Richard Hughes)
+ - Ensure we set an error when the transaction is cancelled (Richard Hughes)
+ - Ensure PkProgress sends ::notify signals when properties change (Richard Hughes)
+ - When adopting a transaction ensure we set the role on the PkResults object (Richard Hughes)
+ - Show the translated role and status when using pkgenpack (Richard Hughes)
+ - Ensure that pkgenpack generates filenames without ';' embedded in them (Richard Hughes)
+ - If the user uses 'pkcon install dave.rpm' then give a useful error message (Richard Hughes)
+ - Fixed packagekit.client.install_packages() in Python bindings (Tim Waugh)
+ - Cache autoremove too in transaction_remove_packages (Valeriy Lyasotskiy)
+
 Version 0.6.0
 ~~~~~~~~~~~~~
 Released: 2010-01-2010
diff --git a/RELEASE b/RELEASE
index 4d632d9..0943b84 100644
--- a/RELEASE
+++ b/RELEASE
@@ -27,7 +27,8 @@ Bugfixes:
 4. Commit changes in PackageKit git:
 
 git commit -a -m "Release version 0.6.1"
-git tag -a -f -m "Release 0.6.1" PACKAGEKIT_0_6_1
+git tag -s -f -m "Release 0.6.1" PACKAGEKIT_0_6_1
+<gpg password>
 git push --tags
 git push
 git push git+ssh://hughsient@git.freedesktop.org/git/packagekit
diff --git a/configure.ac b/configure.ac
index 1f648f6..c454ef2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,7 @@ AC_SUBST(PK_VERSION)
 # AGE		If libpackagekit can be linked into executables which can be
 # 		built with previous versions of this library. Don't use.
 LT_CURRENT=13
-LT_REVISION=0
+LT_REVISION=1
 LT_AGE=0
 AC_SUBST(LT_CURRENT)
 AC_SUBST(LT_REVISION)
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 7a37453..e627dba 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -69,6 +69,7 @@ Releases are normally on the first working Monday of each month.
 <table>
 <tr><td><b>Version</b></td><td>&nbsp;&nbsp;</td><td><b>Date</b></td></tr>
 <tr><td>0.6.0</td><td></td><td>2010-01-04</td></tr>
+<tr><td>0.6.1</td><td></td><td>2010-02-01</td></tr>
 </table>
 <h3>
 ABI Stable Versions:
commit 499fcb7cfc9e826583682bbc93fc97a3902ce39a
Author: Scott Reeves <sreeves at novell.com>
Date:   Fri Jan 29 14:33:04 2010 -0700

    zypp: add more features to repo_set_data.
    patch from Ladislav Slezak

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index c22878b..a6b00b3 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1670,6 +1670,27 @@ backend_repo_set_data_thread (PkBackend *backend)
 			}
 
 			manager.modifyRepository (repo_id, repo);
+		}else if (g_ascii_strcasecmp (parameter, "keep") == 0) {
+			repo = manager.getRepositoryInfo (repo_id);
+
+			if (g_ascii_strcasecmp (value, "true") == 0) {
+				repo.setKeepPackages (TRUE);
+			}else if (g_ascii_strcasecmp (value, "false") == 0) {
+				repo.setKeepPackages (FALSE);
+			}else {
+				pk_backend_message (backend, PK_MESSAGE_ENUM_PARAMETER_INVALID, "Keep downloaded packages: Enter true or false");
+				bReturn = FALSE;
+			}
+
+			manager.modifyRepository (repo_id, repo);
+		}else if (g_ascii_strcasecmp (parameter, "url") == 0) {
+			repo = manager.getRepositoryInfo (repo_id);
+			repo.setBaseUrl (zypp::Url(value));
+			manager.modifyRepository (repo_id, repo);
+		}else if (g_ascii_strcasecmp (parameter, "name") == 0) {
+			repo = manager.getRepositoryInfo (repo_id);
+			repo.setName(value);
+			manager.modifyRepository (repo_id, repo);
 		}else if (g_ascii_strcasecmp (parameter, "prio") == 0) {
 			repo = manager.getRepositoryInfo (repo_id);
 			gint prio = 0;
@@ -1703,7 +1724,7 @@ backend_repo_set_data_thread (PkBackend *backend)
 			}
 
 		} else {
-			pk_backend_error_code (backend, PK_ERROR_ENUM_NOT_SUPPORTED, "Valid parameters for set_repo_data are remove/add/refresh/prio");
+			pk_backend_error_code (backend, PK_ERROR_ENUM_NOT_SUPPORTED, "Valid parameters for set_repo_data are remove/add/refresh/prio/keep/url/name");
 			bReturn = FALSE;
 		}
 
commit e9ec74c453f9d800391d5eea872a02046bff71da
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 13:45:37 2010 +0100

    [entropy] implement EntropyPackageKitBackend.download_packages() support (+ module QA checks)

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
index cc2d486..daee12e 100644
--- a/backends/entropy/TODO
+++ b/backends/entropy/TODO
@@ -3,8 +3,7 @@ Entropy PackageKit backend developers' TODO:
     - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
         FILTER_DEVELOPMENT, FILTER_VISIBLE
     - remove support for FILTER_NEWEST (useless)
-    - add download_packages, get_categories, get_distro_upgrades,
-        get_mime_types, update_system support
+    - add download_packages, get_mime_types, update_system support
     - sys-apps/entropy is a syspkg
     - improve performance of _log_message
     - messages? how push output to stdout?
diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 10bb377..08a72a4 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -25,9 +25,30 @@ import os
 import sys
 import signal
 import time
-
-from packagekit.backend import *
-from packagekit.progress import *
+import traceback
+
+from packagekit.backend import PackageKitBaseBackend, \
+    ERROR_PACKAGE_ID_INVALID, ERROR_REPO_NOT_FOUND, ERROR_INTERNAL_ERROR, \
+    ERROR_CANNOT_DISABLE_REPOSITORY, ERROR_PACKAGE_FAILED_TO_INSTALL, \
+    ERROR_DEP_RESOLUTION_FAILED, ERROR_PACKAGE_FAILED_TO_CONFIGURE, \
+    ERROR_PACKAGE_FAILED_TO_REMOVE, ERROR_GROUP_LIST_INVALID, \
+    ERROR_UPDATE_NOT_FOUND, ERROR_REPO_CONFIGURATION_ERROR, \
+    ERROR_PACKAGE_NOT_FOUND, ERROR_MISSING_GPG_SIGNATURE, FILTER_INSTALLED, \
+    FILTER_NOT_INSTALLED, ERROR_GROUP_LIST_INVALID, FILTER_NOT_DEVELOPMENT, \
+    FILTER_FREE, GROUP_ACCESSIBILITY, GROUP_PROGRAMMING, GROUP_GAMES, \
+    GROUP_DESKTOP_GNOME, GROUP_DESKTOP_KDE, GROUP_DESKTOP_OTHER, \
+    GROUP_MULTIMEDIA, GROUP_NETWORK, GROUP_OFFICE, GROUP_SCIENCE, \
+    GROUP_SYSTEM, GROUP_SECURITY, GROUP_OTHER, GROUP_DESKTOP_XFCE, \
+    GROUP_UNKNOWN, INFO_IMPORTANT, INFO_NORMAL, INFO_DOWNLOADING, \
+    INFO_INSTALLED, \
+    INFO_AVAILABLE, get_package_id, split_package_id, MESSAGE_UNKNOWN, \
+    MESSAGE_AUTOREMOVE_IGNORED, MESSAGE_CONFIG_FILES_CHANGED, STATUS_INFO, \
+    MESSAGE_COULD_NOT_FIND_PACKAGE, MESSAGE_REPO_METADATA_DOWNLOAD_FAILED, \
+    STATUS_QUERY, STATUS_DEP_RESOLVE, STATUS_REMOVE, STATUS_DOWNLOAD, \
+    STATUS_INSTALL, STATUS_RUNNING, STATUS_REFRESH_CACHE, \
+    UPDATE_STATE_TESTING, UPDATE_STATE_STABLE
+
+#from packagekit.progress import *
 from packagekit.package import PackagekitPackage
 
 sys.path.insert(0, '/usr/lib/entropy/libraries')
@@ -45,11 +66,7 @@ import entropy.tools
 
 PK_DEBUG = True
 
-# TODO:
-# remove percentage(None) if percentage is used
-# protection against signal when installing/removing
-
-class PackageKitEntropyMixin:
+class PackageKitEntropyMixin(object):
 
     INST_PKGS_REPO_ID = "installed"
 
@@ -166,13 +183,13 @@ class PackageKitEntropyMixin:
         except IndexError:
             return GROUP_UNKNOWN
 
-        return PackageKitEntropyBackend._GROUP_MAP[generic_group_name]
+        return PackageKitEntropyBackend.GROUP_MAP[generic_group_name]
 
     def _get_entropy_group(self, pk_group):
         """
         Given a PackageKit group identifier, return Entropy packages group.
         """
-        group_map = PackageKitEntropyBackend._GROUP_MAP
+        group_map = PackageKitEntropyBackend.GROUP_MAP
         # reverse dict
         group_map_reverse = dict((y, x) for x, y in group_map.items())
         return group_map_reverse.get(pk_group, 'unknown')
@@ -229,7 +246,7 @@ class PackageKitEntropyMixin:
         elif FILTER_NOT_INSTALLED in fltlist:
             pkgs = set([x for x in pkgs if x[0] != inst_pkgs_repo_id])
         if FILTER_FREE in fltlist:
-            free_pkgs = set([x for x in pkgs if \
+            pkgs = set([x for x in pkgs if \
                 self._entropy.is_entropy_package_free(x[1], x[0])])
 
         return pkgs
@@ -420,8 +437,8 @@ class PackageKitEntropyMixin:
             package = self._entropy.Package()
             package.prepare((pkg_id,), "remove", metaopts)
             if 'remove_installed_vanished' not in package.pkgmeta:
-                rc = package.run()
-                if rc != 0:
+                x_rc = package.run()
+                if x_rc != 0:
                     pk_pkg = match_map.get(pkg_id, (None, None, None))[2]
                     self.error(ERROR_PACKAGE_FAILED_TO_REMOVE,
                         "Cannot remove package: %s" % (pk_pkg,))
@@ -432,7 +449,15 @@ class PackageKitEntropyMixin:
 
         self.finished()
 
-    def _execute_etp_pkgs_install(self, pkgs, only_trusted):
+    def _execute_etp_pkgs_fetch(self, pkgs, directory):
+        """
+        Execute effective packages download.
+        """
+        self._execute_etp_pkgs_install(pkgs, False, only_fetch = True,
+            fetch_path = directory, calculate_deps = False)
+
+    def _execute_etp_pkgs_install(self, pkgs, only_trusted, only_fetch = False,
+        fetch_path = None, calculate_deps = True):
         """
         Execute effective install (including dep calculation).
 
@@ -443,7 +468,7 @@ class PackageKitEntropyMixin:
         @type only_trusted: bool
         """
         self.percentage(0)
-        self.status(STATUS_DEP_RESOLVE)
+        self.status(STATUS_RUNNING)
 
         if only_trusted:
             # check if we have trusted pkgs
@@ -454,16 +479,20 @@ class PackageKitEntropyMixin:
                         "Package %s is not GPG signed" % (pk_pkg,))
                     return
 
-        match_map = dict((
-            (pkg_id, self._get_repo_name(c_repo)), (pkg_id, c_repo, pk_pkg)) \
-                for pkg_id, c_repo, pk_pkg in pkgs)
         matches = [(pkg_id, self._get_repo_name(c_repo),) for \
             pkg_id, c_repo, pk_pkg in pkgs]
 
         # calculate deps
-        empty_deps, deep_deps = False, False
-        run_queue, removal_queue, status = self._entropy.get_install_queue(
-            matches, empty_deps, deep_deps)
+        if calculate_deps:
+            self.status(STATUS_DEP_RESOLVE)
+            empty_deps, deep_deps = False, False
+            run_queue, removal_queue, status = self._entropy.get_install_queue(
+                matches, empty_deps, deep_deps)
+        else:
+            run_queue = matches
+            removal_queue = []
+            status = 0
+
         if status == -2:
             self.error(ERROR_DEP_RESOLUTION_FAILED,
                 "Cannot find the following dependencies: %s" % (
@@ -475,8 +504,17 @@ class PackageKitEntropyMixin:
 
         # FIXME: where is license dialog? can't be interactive, fook!
 
+        # used in case of errors
+        match_map = {}
+        for pkg_id, repo_id in run_queue:
+            pkg_c_repo = self._entropy.open_repository(repo_id)
+            match_map[(pkg_id, repo_id,)] = (pkg_id, pkg_c_repo,
+                self._etp_to_id((pkg_id, pkg_c_repo)),)
+
         # fetch pkgs
-        max_count = len(run_queue)*2
+        max_count = len(run_queue)
+        if not only_fetch:
+            max_count *= 2
         count = 0
         down_data = {}
         for match in run_queue:
@@ -491,24 +529,41 @@ class PackageKitEntropyMixin:
             metaopts = {
                 'dochecksum': True,
             }
+            if fetch_path is not None:
+                metaopts['fetch_path'] = fetch_path
+
             package = self._entropy.Package()
             package.prepare(match, "fetch", metaopts)
             myrepo = package.pkgmeta['repository']
             obj = down_data.setdefault(myrepo, set())
             obj.add(entropy.tools.dep_getkey(package.pkgmeta['atom']))
 
-            rc = package.run()
-            if rc != 0:
+            pkg_id, pkg_c_repo, pk_pkg = match_map.get(match)
+            pkg_desc = pkg_c_repo.retrieveDescription(pkg_id)
+            # show pkg
+            self.package(pk_pkg, INFO_DOWNLOADING, pkg_desc)
+
+            x_rc = package.run()
+            if x_rc != 0:
                 pk_pkg = match_map.get(match, (None, None, None))[2]
                 self.error(ERROR_PACKAGE_FAILED_TO_CONFIGURE,
                     "Cannot download package: %s" % (pk_pkg,))
                 return
+
+            # emit the file we downloaded
+            self.files(pk_pkg, package.pkgmeta['pkgpath'])
+
             package.kill()
             del package
 
         # spawn UGC
         self._etp_spawn_ugc(down_data)
 
+        self.percentage(100)
+        if only_fetch:
+            self.finished()
+            return
+
         # install
         self.status(STATUS_INSTALL)
 
@@ -535,8 +590,8 @@ class PackageKitEntropyMixin:
             package = self._entropy.Package()
             package.prepare(match, "install", metaopts)
 
-            rc = package.run()
-            if rc != 0:
+            x_rc = package.run()
+            if x_rc != 0:
                 pk_pkg = match_map.get(match, (None, None, None))[2]
                 self.error(ERROR_PACKAGE_FAILED_TO_INSTALL,
                     "Cannot install package: %s" % (pk_pkg,))
@@ -580,8 +635,8 @@ Client.__singleton_class__ = PackageKitEntropyClient
 
 class PkUrlFetcher(UrlFetcher):
 
-    _last_avg = 0
     _pk_progress = None
+    _last_t = time.time()
 
     def __init__(self, *args, **kwargs):
         self.__average = 0
@@ -603,14 +658,12 @@ class PkUrlFetcher(UrlFetcher):
         if PkUrlFetcher._pk_progress is None:
             return
 
-        myavg = abs(int(round(float(self.__average), 1)))
-        if abs((myavg - PkUrlFetcher._last_avg)) < 1:
-            return
-
-        if (myavg > PkUrlFetcher._last_avg) or (myavg < 2) or (myavg > 97):
+        last_t = PkUrlFetcher._last_t
+        if (time.time() - last_t) > 1:
+            myavg = abs(int(round(float(self.__average), 1)))
             cur_prog = int(float(self.__average)/100)
             PkUrlFetcher._pk_progress(cur_prog)
-            PkUrlFetcher._last_avg = myavg
+            PkUrlFetcher._last_t = time.time()
 
 
 class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
@@ -618,7 +671,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
     _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
 
     # Entropy <-> PackageKit groups map
-    _GROUP_MAP = {
+    GROUP_MAP = {
         'accessibility': GROUP_ACCESSIBILITY,
         'development': GROUP_PROGRAMMING,
         'games': GROUP_GAMES,
@@ -642,6 +695,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         raise SystemExit(1)
 
     def __init__(self, args):
+        PackageKitEntropyMixin.__init__(self)
+
         signal.signal(signal.SIGQUIT, self.__sigquit)
         self._entropy = PackageKitEntropyClient()
         PkUrlFetcher._pk_progress = self.sub_percentage
@@ -659,8 +714,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def _convert_date_to_iso8601(self, unix_time_str):
         unix_time = float(unix_time_str)
-        t = time.localtime(unix_time)
-        formatted = time.strftime('%Y-%m-%dT%H:%M:%S', t)
+        ux_t = time.localtime(unix_time)
+        formatted = time.strftime('%Y-%m-%dT%H:%M:%S', ux_t)
         return formatted
 
     def _generic_message(self, message):
@@ -777,19 +832,16 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 continue
             pkg_id, c_repo = pkg
 
-            base_data = c_repo.getBaseData(pkg_id)
-            if base_data is None:
+            category = c_repo.retrieveCategory(pkg_id)
+            lic = c_repo.retrieveLicense(pkg_id)
+            homepage = c_repo.retrieveHomepage(pkg_id)
+            description = c_repo.retrieveDescription(pkg_id)
+            if (category is None) or (description is None):
                 self.error(ERROR_PACKAGE_NOT_FOUND,
                     "Package %s was not found in repository" % (pk_pkg,))
                 continue
 
-            atom, name, version, versiontag, \
-            description, category, chost, \
-            cflags, cxxflags, homepage, \
-            license, branch, download, \
-            digest, slot, etpapi, \
-            datecreation, size, revision = base_data
-            self.details(pk_pkg, license, self._get_pk_group(category),
+            self.details(pk_pkg, lic, self._get_pk_group(category),
                 description, homepage, self._get_pkg_size(pkg))
 
         self.percentage(100)
@@ -812,8 +864,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             summary = self._etp_get_category_description(name)
             summary = const_convert_to_rawstring(summary, "utf-8")
 
-            fn = "/usr/share/pixmaps/entropy/%s.png" % (name,)
-            if os.path.isfile(fn) and os.access(fn, os.R_OK):
+            f_name = "/usr/share/pixmaps/entropy/%s.png" % (name,)
+            if os.path.isfile(f_name) and os.access(f_name, os.R_OK):
                 icon = name
             else:
                 icon = const_convert_to_rawstring("image-missing")
@@ -903,8 +955,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def get_repo_list(self, filters):
 
-        self._log_message(__name__, "get_repo_list: got %s and %s" % (
-            filters,))
+        self._log_message(__name__, "get_repo_list: got %s" % (filters,))
 
         self.status(STATUS_INFO)
         self.allow_cancel(True)
@@ -1102,19 +1153,38 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             only_trusted, pk_pkgs,))
 
         self.status(STATUS_RUNNING)
-        self.allow_cancel(True) # correct?
+        self.allow_cancel(True)
 
         pkgs = []
         for pk_pkg in pk_pkgs:
             pkg = self._id_to_etp(pk_pkg)
             if pkg is None:
-                self.error(ERROR_UPDATE_NOT_FOUND,
+                self.error(ERROR_PACKAGE_NOT_FOUND,
                     "Package %s was not found" % (pk_pkg,))
                 continue
             pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
         self._execute_etp_pkgs_install(pkgs, only_trusted)
 
+    def download_packages(self, directory, pk_pkgs):
+
+        self._log_message(__name__, "download_packages: got %s and %s" % (
+            directory, pk_pkgs,))
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(True)
+
+        pkgs = []
+        for pk_pkg in pk_pkgs:
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None:
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                    "Package %s was not found" % (pk_pkg,))
+                continue
+            pkgs.append((pkg[0], pkg[1], pk_pkg,))
+
+        self._execute_etp_pkgs_fetch(pkgs, directory)
+
     def refresh_cache(self, force):
 
         self.status(STATUS_REFRESH_CACHE)
@@ -1425,65 +1495,15 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self._execute_etp_pkgs_install(pkgs, only_trusted)
 
     def update_system(self, only_trusted):
+
+        self._log_message(__name__, "update_system: got %s" % (
+            only_trusted,))
+
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
         self.percentage(None)
-
-        if only_trusted:
-            self.error(ERROR_MISSING_GPG_SIGNATURE,
-                    "Portage backend does not support GPG signature")
-            return
-
-        myopts = {}
-        myopts["--deep"] = True
-        myopts["--newuse"] = True
-        myopts["--update"] = True
-
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        self.status(STATUS_DEP_RESOLVE)
-
-        # creating list of ebuilds needed for the system update
-        # using backtrack_depgraph to prevent errors
-        retval, depgraph, _ = _emerge.depgraph.backtrack_depgraph(
-                self.pvar.settings, self.pvar.trees, myopts, myparams, "",
-                ["@system", "@world"], None)
-        if not retval:
-            self.error(ERROR_INTERNAL_ERROR,
-                    "Wasn't able to get dependency graph")
-            return
-
-        # check fetch restrict, can stop the function via error signal
-        self.check_fetch_restrict(depgraph.altlist())
-
-        self.status(STATUS_INSTALL)
-
-        # get elog messages
-        portage.elog.add_listener(self.elog_listener)
-
-        try:
-            self.block_output()
-            # compiling/installing
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
-                    depgraph.altlist(), None, depgraph.schedulerGraph())
-            rval = mergetask.merge()
-        finally:
-            self.unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self.elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-        self.send_configuration_file_message()
+        # FIXME: not yet implemented
+        return
 
 def main():
     backend = PackageKitEntropyBackend("")
commit 23baf9e6f0bb840b1da47de3f2366af89e2252f3
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 12:04:08 2010 +0100

    [entropy] implement EntropyPackageKitBackend.get_categories() (and prepare download_packages)

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 53137fc..10bb377 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -32,8 +32,9 @@ from packagekit.package import PackagekitPackage
 
 sys.path.insert(0, '/usr/lib/entropy/libraries')
 
-from entropy.i18n import _
-from entropy.const import etpConst
+from entropy.i18n import _, _LOCALE
+from entropy.const import etpConst, const_convert_to_rawstring, \
+    const_convert_to_unicode
 from entropy.client.interfaces import Client
 from entropy.core.settings.base import SystemSettings
 from entropy.misc import LogFile
@@ -74,7 +75,7 @@ class PackageKitEntropyMixin:
         """
         if PK_DEBUG:
             self._entropy_log.write("%s: %s" % (source,
-                ' '.join([str(x) for x in args]),)
+                ' '.join([const_convert_to_unicode(x) for x in args]),)
             )
 
     def _is_repository_enabled(self, repo_name):
@@ -133,8 +134,9 @@ class PackageKitEntropyMixin:
             return
         pkg_key, pkg_ver, cur_arch, repo_name = split_data
 
-        self._log_message(__name__, "_id_to_etp: extracted: %s | %s | %s | %s" % (
-            pkg_key, pkg_ver, cur_arch, repo_name,))
+        self._log_message(__name__,
+            "_id_to_etp: extracted: %s | %s | %s | %s" % (
+                pkg_key, pkg_ver, cur_arch, repo_name,))
         pkg_ver, pkg_slot = pkg_ver.rsplit(":", 1)
 
         if repo_name == "installed":
@@ -331,6 +333,18 @@ class PackageKitEntropyMixin:
             except:
                 pass
 
+    def _etp_get_category_description(self, category):
+        """
+        Return translated Entropy packages category description.
+        """
+        cat_desc = _("No description")
+        cat_desc_data = self._entropy.get_category_description(category)
+        if _LOCALE in cat_desc_data:
+            cat_desc = cat_desc_data[_LOCALE]
+        elif 'en' in cat_desc_data:
+            cat_desc = cat_desc_data['en']
+        return cat_desc
+
     def _execute_etp_pkgs_remove(self, pkgs, allowdep, autoremove):
         """
         Execute effective removal (including dep calculation).
@@ -780,6 +794,38 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
+    def get_categories(self):
+
+        self._log_message(__name__, "get_categories: called")
+
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+
+        categories = self._entropy.get_package_categories()
+        if not categories:
+            self.error(ERROR_GROUP_LIST_INVALID, "no package categires")
+            return
+
+        for name in categories:
+            name = const_convert_to_rawstring(name)
+
+            summary = self._etp_get_category_description(name)
+            summary = const_convert_to_rawstring(summary, "utf-8")
+
+            fn = "/usr/share/pixmaps/entropy/%s.png" % (name,)
+            if os.path.isfile(fn) and os.access(fn, os.R_OK):
+                icon = name
+            else:
+                icon = const_convert_to_rawstring("image-missing")
+
+            nothing = const_convert_to_rawstring("")
+            cat_id = name # same thing
+
+            self._log_message(__name__, "get_categories: pushing",
+                nothing, cat_id, name, summary, icon)
+
+            self.category(nothing, cat_id, name, summary, icon)
+
     def get_files(self, pk_pkgs):
 
         self._log_message(__name__, "get_files: got %s" % (pk_pkgs,))
diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 60e0317..9a820ad 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -127,6 +127,29 @@ backend_cancel (PkBackend *backend)
 }
 
 /**
+ * backend_download_packages:
+ */
+static void
+backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
+{
+	gchar *package_ids_temp;
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "download-packages", directory, package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * pk_backend_get_categories:
+ */
+static void
+backend_get_categories (PkBackend *backend)
+{
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-categories", NULL);
+}
+
+/**
  * backend_get_depends:
  */
 static void
@@ -397,8 +420,8 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* get_roles */
 	NULL,					/* get_mime_types */
 	backend_cancel,				/* cancel */
-	NULL,					/* download_packages */
-	NULL,					/* get_categories */
+	backend_download_packages,					/* download_packages */
+	backend_get_categories,					/* get_categories */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
 	NULL,					/* get_distro_upgrades */
commit c401361c3c04f92bcec9276112a4845af24e2694
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 00:58:24 2010 +0100

    [entropy] add TODO

diff --git a/backends/entropy/TODO b/backends/entropy/TODO
new file mode 100644
index 0000000..cc2d486
--- /dev/null
+++ b/backends/entropy/TODO
@@ -0,0 +1,36 @@
+Entropy PackageKit backend developers' TODO:
+
+    - add support for FILTER_NOT_VISIBLE, FILTER_NOT_DEVELOPMENT,
+        FILTER_DEVELOPMENT, FILTER_VISIBLE
+    - remove support for FILTER_NEWEST (useless)
+    - add download_packages, get_categories, get_distro_upgrades,
+        get_mime_types, update_system support
+    - sys-apps/entropy is a syspkg
+    - improve performance of _log_message
+    - messages? how push output to stdout?
+    - license dialog??
+
+What is currently implemented:
+    Y get-actions
+    Y get-groups
+    Y get-filters
+    Y get-transactions
+    Y get-time
+    Y search [name|details|group|file] [data]
+    Y install [packages]
+    Y remove [package]
+    Y update <package>
+    N update-system ???? not shown
+    Y refresh
+    Y resolve [package]
+    Y get-updates
+    Y get-depends [package]
+    Y get-requires [package]
+    Y get-details [package]
+    Y get-files [package]
+    Y get-update-detail [package]
+    Y get-packages
+    Y repo-list
+    Y repo-enable [repo_id]
+    Y repo-disable [repo_id]
+
commit bcefe8f76c7d961fa50c22b506db1ac9beb17984
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 00:26:51 2010 +0100

    [entropy] subclass UrlFetcher to redirect output to PK, make possible to cancel pkg install/removal

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index d549791..53137fc 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -38,6 +38,7 @@ from entropy.client.interfaces import Client
 from entropy.core.settings.base import SystemSettings
 from entropy.misc import LogFile
 from entropy.exceptions import SystemDatabaseError
+from entropy.fetchers import UrlFetcher
 
 import entropy.tools
 
@@ -562,6 +563,42 @@ class PackageKitEntropyClient(Client):
 # gets PackageKitEntropyClient in change
 Client.__singleton_class__ = PackageKitEntropyClient
 
+
+class PkUrlFetcher(UrlFetcher):
+
+    _last_avg = 0
+    _pk_progress = None
+
+    def __init__(self, *args, **kwargs):
+        self.__average = 0
+        self.__downloadedsize = 0
+        self.__remotesize = 0
+        self.__datatransfer = 0
+        UrlFetcher.__init__(self, *args, **kwargs)
+
+    def handle_statistics(self, th_id, downloaded_size, total_size,
+            average, old_average, update_step, show_speed, data_transfer,
+            time_remaining, time_remaining_secs):
+        self.__average = average
+        self.__downloadedsize = downloaded_size
+        self.__remotesize = total_size
+        self.__datatransfer = data_transfer
+
+    def output(self):
+
+        if PkUrlFetcher._pk_progress is None:
+            return
+
+        myavg = abs(int(round(float(self.__average), 1)))
+        if abs((myavg - PkUrlFetcher._last_avg)) < 1:
+            return
+
+        if (myavg > PkUrlFetcher._last_avg) or (myavg < 2) or (myavg > 97):
+            cur_prog = int(float(self.__average)/100)
+            PkUrlFetcher._pk_progress(cur_prog)
+            PkUrlFetcher._last_avg = myavg
+
+
 class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
@@ -593,6 +630,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
     def __init__(self, args):
         signal.signal(signal.SIGQUIT, self.__sigquit)
         self._entropy = PackageKitEntropyClient()
+        PkUrlFetcher._pk_progress = self.sub_percentage
+        self._entropy.urlFetcher = PkUrlFetcher
         self._repo_name_cache = {}
         PackageKitEntropyClient._pk_progress = self.percentage
         PackageKitEntropyClient._pk_message = self._generic_message
@@ -1017,7 +1056,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             only_trusted, pk_pkgs,))
 
         self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
+        self.allow_cancel(True) # correct?
 
         pkgs = []
         for pk_pkg in pk_pkgs:
@@ -1067,7 +1106,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             allowdep, autoremove, pk_pkgs,))
 
         self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
+        self.allow_cancel(True)
 
         pkgs = []
         for pk_pkg in pk_pkgs:
@@ -1326,7 +1365,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             only_trusted, pk_pkgs,))
 
         self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
+        self.allow_cancel(True)
 
         pkgs = []
         for pk_pkg in pk_pkgs:
commit 4cf6b74bd3d037c4b13f62f9a2311d890800cb51
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Wed Feb 3 00:09:08 2010 +0100

    [entropy] implement EntropyPackageKitBackend.remove_packages()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 1500372..d549791 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -330,6 +330,93 @@ class PackageKitEntropyMixin:
             except:
                 pass
 
+    def _execute_etp_pkgs_remove(self, pkgs, allowdep, autoremove):
+        """
+        Execute effective removal (including dep calculation).
+
+        @param pkgs: list of package tuples composed by
+            (etp_package_id, EntropyRepository, pk_pkg_id)
+        @type pkgs: list
+        @param allowdep: Either true or false. If true allow other packages
+            to be removed with the package, but false should cause the script
+            to abort if other packages are dependant on the package.
+        @type allowdep: bool
+        @param autoremove: Either true or false. This option is only really
+            interesting on embedded devices with a limited amount of flash
+            storage. It suggests to the packagekit backend that
+            dependencies installed at the same time as the package
+            should also be removed if they are not required by
+            anything else. For instance, if you install OpenOffice,
+            it might download libneon as a dependency. When auto_remove
+            is set to true, and you remove OpenOffice then libneon
+            will also get removed automatically.
+        @type autoremove: bool
+        """
+
+        # backend do not implement autoremove
+        if autoremove:
+            self.message(MESSAGE_AUTOREMOVE_IGNORED,
+                "Entropy backend devs refused to implement this feature")
+
+        self.percentage(0)
+        self.status(STATUS_DEP_RESOLVE)
+
+        # check if we have installed pkgs only
+        for pkg_id, c_repo, pk_pkg in pkgs:
+            if c_repo is not self._entropy.installed_repository():
+                self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Cannot remove a package coming fro a repository: %s" % (
+                        pk_pkg,))
+                return
+
+        match_map = dict((
+            (pkg_id, (pkg_id, c_repo, pk_pkg)) \
+                for pkg_id, c_repo, pk_pkg in pkgs))
+        matches = [pkg_id for pkg_id, c_repo, pk_pkg in pkgs]
+
+        # calculate deps
+        run_queue = self._entropy.get_removal_queue(matches)
+        added_pkgs = [x for x in run_queue if x not in matches]
+
+        # if there are required packages, allowdep must be on
+        if added_pkgs and not allowdep:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                "Could not perform remove operation, some packages are needed by other packages")
+            return
+
+        self.percentage(0)
+        self.status(STATUS_REMOVE)
+
+        # remove
+        max_count = len(run_queue)
+        count = 0
+        for pkg_id in run_queue:
+            count += 1
+
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
+
+            self._log_message(__name__, "get_packages: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+
+            metaopts = {}
+            metaopts['removeconfig'] = False
+            package = self._entropy.Package()
+            package.prepare((pkg_id,), "remove", metaopts)
+            if 'remove_installed_vanished' not in package.pkgmeta:
+                rc = package.run()
+                if rc != 0:
+                    pk_pkg = match_map.get(pkg_id, (None, None, None))[2]
+                    self.error(ERROR_PACKAGE_FAILED_TO_REMOVE,
+                        "Cannot remove package: %s" % (pk_pkg,))
+                    return
+
+            package.kill()
+            del package
+
+        self.finished()
+
     def _execute_etp_pkgs_install(self, pkgs, only_trusted):
         """
         Execute effective install (including dep calculation).
@@ -410,7 +497,6 @@ class PackageKitEntropyMixin:
         # install
         self.status(STATUS_INSTALL)
 
-        
         for match in run_queue:
             count += 1
 
@@ -540,34 +626,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             message += ";If you can't do that, ask your system administrator."
             self.message(MESSAGE_CONFIG_FILES_CHANGED, message)
 
-    def get_restricted_fetch_files(self, cpv, metadata):
-        '''
-        This function checks files in SRC_URI and look if they are in DESTDIR.
-        Missing files are returned. If there is no issue, None is returned.
-        We don't care about digest but only about existance of files.
-
-        NOTES:
-        - we are assuming the package has RESTRICT='fetch'
-          be sure to call this function only in this case.
-        - we are not using fetch_check because it's not returning missing files
-          so this function is a simplist fetch_check
-        '''
-        missing_files = []
-        ebuild_settings = self.get_ebuild_settings(cpv, metadata)
-
-        files = self.pvar.portdb.getFetchMap(cpv,
-                ebuild_settings['USE'].split())
-
-        for f in files:
-            file_path = os.path.join(ebuild_settings["DISTDIR"], f)
-            if not os.access(file_path, os.F_OK):
-                missing_files.append([file_path, files[f]])
-
-        if len(missing_files) > 0:
-            return missing_files
-
-        return None
-
     def _package(self, pkg_match, info=None):
 
         # package_id = (package_identifier, EntropyRepository)
@@ -1003,112 +1061,24 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
-    def remove_packages(self, allowdep, autoremove, pkgs):
-        self.status(STATUS_RUNNING)
-        self.allow_cancel(False)
-        self.percentage(None)
+    def remove_packages(self, allowdep, autoremove, pk_pkgs):
 
-        cpv_list = []
-        packages = []
-        required_packages = []
-        system_packages = []
+        self._log_message(__name__, "remove_packages: got %s and %s and %s" % (
+            allowdep, autoremove, pk_pkgs,))
 
-        # get system packages
-        set = portage.sets.base.InternalPackageSet(
-                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("system"))
-        for atom in set:
-            system_packages.append(atom.cp)
-
-        # create cpv_list
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
-
-            if not self.is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            if not self.is_installed(cpv):
-                self.error(ERROR_PACKAGE_NOT_INSTALLED,
-                        "Package %s is not installed" % pkg)
-                continue
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
 
-            # stop removal if a package is in the system set
-            if portage.pkgsplit(cpv)[0] in system_packages:
-                self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
-                        "Package %s is a system package. If you really want to remove it, please use portage" % pkg)
+        pkgs = []
+        for pk_pkg in pk_pkgs:
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None:
+                self.error(ERROR_UPDATE_NOT_FOUND,
+                    "Package %s was not found" % (pk_pkg,))
                 continue
+            pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-            cpv_list.append(cpv)
-
-        # backend do not implement autoremove
-        if autoremove:
-            self.message(MESSAGE_AUTOREMOVE_IGNORED,
-                    "Portage backend do not implement autoremove option")
-
-        # get packages needing candidates for removal
-        required_packages = self.get_packages_required(cpv_list, recursive=True)
-
-        # if there are required packages, allowdep must be on
-        if required_packages and not allowdep:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Could not perform remove operation has packages are needed by other packages")
-            return
-
-        # first, we add required packages
-        for p in required_packages:
-            package = _emerge.Package.Package(
-                    type_name=p.type_name,
-                    built=p.built,
-                    installed=p.installed,
-                    root_config=p.root_config,
-                    cpv=p.cpv,
-                    metadata=p.metadata,
-                    operation='uninstall')
-            packages.append(package)
-
-        # and now, packages we want really to remove
-        for cpv in cpv_list:
-            metadata = self.get_metadata(cpv, [],
-                    in_dict=True, add_cache_keys=True)
-            package = _emerge.Package.Package(
-                    type_name="ebuild",
-                    built=True,
-                    installed=True,
-                    root_config=self.pvar.root_config,
-                    cpv=cpv,
-                    metadata=metadata,
-                    operation="uninstall")
-            packages.append(package)
-
-        # need to define favorites to remove packages from world set
-        favorites = []
-        for p in packages:
-            favorites.append('=' + p.cpv)
-
-        # get elog messages
-        portage.elog.add_listener(self.elog_listener)
-
-        # now, we can remove
-        try:
-            self.block_output()
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, mergelist=packages,
-                    myopts={}, spinner=None, favorites=favorites, digraph=None)
-            rval = mergetask.merge()
-        finally:
-            self.unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_REMOVE)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self.elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
+        self._execute_etp_pkgs_remove(pkgs, allowdep, autoremove)
 
     def repo_enable(self, repoid, enable):
 
commit df998e868842e77c278f3a965edb12e5ee659976
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 23:34:25 2010 +0100

    [entropy] implement EntropyPackageKitBackend.install_packages() and update_packages()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 4c1d3bc..1500372 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -62,7 +62,10 @@ class PackageKitEntropyMixin:
         """
         Prepare percentage value used to feed self.percentage()
         """
-        return int((float(count)/max_count)*100)
+        percent = int((float(count)/max_count)*100)
+        if percent > 100:
+            return 100
+        return percent
 
     def _log_message(self, source, *args):
         """
@@ -313,18 +316,153 @@ class PackageKitEntropyMixin:
             self._repo_name_cache[repo_db] = repo_name
         return repo_name
 
+    def _etp_spawn_ugc(self, pkg_data):
+        """
+        Inform repository maintainers that user fetched packages, if user
+        enabled this feature.
+        """
+        if self._entropy.UGC is None:
+            return
+        for repo_id in pkg_data:
+            repo_pkg_keys = sorted(pkg_data[repo_id])
+            try:
+                self._entropy.UGC.add_download_stats(repo_id, repo_pkg_keys)
+            except:
+                pass
+
+    def _execute_etp_pkgs_install(self, pkgs, only_trusted):
+        """
+        Execute effective install (including dep calculation).
+
+        @param pkgs: list of package tuples composed by
+            (etp_package_id, EntropyRepository, pk_pkg_id)
+        @type pkgs: list
+        @param only_trusted: only accept trusted pkgs?
+        @type only_trusted: bool
+        """
+        self.percentage(0)
+        self.status(STATUS_DEP_RESOLVE)
+
+        if only_trusted:
+            # check if we have trusted pkgs
+            for pkg_id, c_repo, pk_pkg in pkgs:
+                sha1, sha256, sha512, gpg = c_repo.retrieveSignatures(pkg_id)
+                if gpg is None:
+                    self.error(ERROR_MISSING_GPG_SIGNATURE,
+                        "Package %s is not GPG signed" % (pk_pkg,))
+                    return
+
+        match_map = dict((
+            (pkg_id, self._get_repo_name(c_repo)), (pkg_id, c_repo, pk_pkg)) \
+                for pkg_id, c_repo, pk_pkg in pkgs)
+        matches = [(pkg_id, self._get_repo_name(c_repo),) for \
+            pkg_id, c_repo, pk_pkg in pkgs]
+
+        # calculate deps
+        empty_deps, deep_deps = False, False
+        run_queue, removal_queue, status = self._entropy.get_install_queue(
+            matches, empty_deps, deep_deps)
+        if status == -2:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                "Cannot find the following dependencies: %s" % (
+                    ', '.join(run_queue),))
+            return
+
+        self.percentage(0)
+        self.status(STATUS_DOWNLOAD)
+
+        # FIXME: where is license dialog? can't be interactive, fook!
+
+        # fetch pkgs
+        max_count = len(run_queue)*2
+        count = 0
+        down_data = {}
+        for match in run_queue:
+            count += 1
+
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
+
+            self._log_message(__name__, "get_packages: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+            metaopts = {
+                'dochecksum': True,
+            }
+            package = self._entropy.Package()
+            package.prepare(match, "fetch", metaopts)
+            myrepo = package.pkgmeta['repository']
+            obj = down_data.setdefault(myrepo, set())
+            obj.add(entropy.tools.dep_getkey(package.pkgmeta['atom']))
+
+            rc = package.run()
+            if rc != 0:
+                pk_pkg = match_map.get(match, (None, None, None))[2]
+                self.error(ERROR_PACKAGE_FAILED_TO_CONFIGURE,
+                    "Cannot download package: %s" % (pk_pkg,))
+                return
+            package.kill()
+            del package
+
+        # spawn UGC
+        self._etp_spawn_ugc(down_data)
+
+        # install
+        self.status(STATUS_INSTALL)
+
+        
+        for match in run_queue:
+            count += 1
+
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
+
+            self._log_message(__name__, "get_packages: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+
+            metaopts = {
+                'removeconfig': False,
+            }
+            # setup install source
+            if match in matches:
+                metaopts['install_source'] = etpConst['install_sources']['user']
+            else:
+                metaopts['install_source'] = \
+                    etpConst['install_sources']['automatic_dependency']
+
+            package = self._entropy.Package()
+            package.prepare(match, "install", metaopts)
+
+            rc = package.run()
+            if rc != 0:
+                pk_pkg = match_map.get(match, (None, None, None))[2]
+                self.error(ERROR_PACKAGE_FAILED_TO_INSTALL,
+                    "Cannot install package: %s" % (pk_pkg,))
+                return
+
+            package.kill()
+            del package
+
+        self._config_files_message()
+        self.finished()
+
 
 class PackageKitEntropyClient(Client):
     """ PackageKit Entropy Client subclass """
 
     _pk_progress = None
+    _pk_message = None
 
     def output(self, text, header = "", footer = "", back = False,
         importance = 0, type = "info", count = None, percent = False):
         """
         Reimplemented from entropy.output.TextInterface.
         """
-        # just write progress, if possible
+        message_func = PackageKitEntropyClient._pk_message
+        if message_func is not None:
+            message_func(text)
+
         progress = PackageKitEntropyClient._pk_progress
         if progress is None:
             return
@@ -371,6 +509,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self._entropy = PackageKitEntropyClient()
         self._repo_name_cache = {}
         PackageKitEntropyClient._pk_progress = self.percentage
+        PackageKitEntropyClient._pk_message = self._generic_message
 
         self._settings = SystemSettings()
         self._entropy_log = LogFile(
@@ -385,14 +524,19 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         formatted = time.strftime('%Y-%m-%dT%H:%M:%S', t)
         return formatted
 
-    def send_configuration_file_message(self):
-        result = list(portage.util.find_updated_config_files(
-            self.pvar.settings['ROOT'],
-            self.pvar.settings.get('CONFIG_PROTECT', '').split()))
+    def _generic_message(self, message):
+        # FIXME: this doesn't work, it seems there's no way to
+        # print something to user while pkcon runs.
+        self.message(MESSAGE_UNKNOWN, message)
 
-        if result:
+    def _config_files_message(self):
+        scandata = self._entropy.FileUpdates.scanfs(dcache = True,
+            quiet = True)
+        if scandata is None:
+            return
+        if len(scandata) > 0:
             message = "Some configuration files need updating."
-            message += ";You should use Gentoo's tools to update them (dispatch-conf)"
+            message += ";You should use 'equo conf update' to update them"
             message += ";If you can't do that, ask your system administrator."
             self.message(MESSAGE_CONFIG_FILES_CHANGED, message)
 
@@ -424,147 +568,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         return None
 
-    def elog_listener(self, settings, key, logentries, fulltext):
-        '''
-        This is a listener for elog.
-        It's called each time elog is emitting log messages (at end of process).
-        We are not using settings and fulltext but they are used by other
-        listeners so we have to keep them as arguments.
-        '''
-        message = "Messages for package %s:;" % str(key)
-        error_message = ""
-
-        # building the message
-        for phase in logentries:
-            for entries in logentries[phase]:
-                type = entries[0]
-                messages = entries[1]
-
-                # TODO: portage.elog.filtering is using upper() should we ?
-                if type == 'LOG':
-                    message += ";Information messages:"
-                elif type == 'WARN':
-                    message += ";Warning messages:"
-                elif type == 'QA':
-                    message += ";QA messages:"
-                elif type == 'ERROR':
-                    message += ";Error messages:"
-                    self._error_phase = phase
-                else:
-                    continue
-
-                for msg in messages:
-                    msg = msg.replace('\n', '')
-                    if type == 'ERROR':
-                        error_message += msg + ";"
-                    message += "; " + msg
-
-        # add the message to the stack
-        self._elog_messages.append(message)
-        self._error_message = message
-
-    def send_merge_error(self, default):
-        # EAPI-2 compliant (at least)
-        # 'other' phase is ignored except this one, every phase should be there
-        if self._error_phase in ("setup", "unpack", "prepare", "configure",
-            "nofetch", "config", "info"):
-            error_type = ERROR_PACKAGE_FAILED_TO_CONFIGURE
-        elif self._error_phase in ("compile", "test"):
-            error_type = ERROR_PACKAGE_FAILED_TO_BUILD
-        elif self._error_phase in ("install", "preinst", "postinst",
-            "package"):
-            error_type = ERROR_PACKAGE_FAILED_TO_INSTALL
-        elif self._error_phase in ("prerm", "postrm"):
-            error_type = ERROR_PACKAGE_FAILED_TO_REMOVE
-        else:
-            error_type = default
-
-        self.error(error_type, self._error_message)
-
-    def filter_newest(self, cpv_list, fltlist):
-        if len(cpv_list) == 0:
-            return cpv_list
-
-        if FILTER_NEWEST not in fltlist:
-            return cpv_list
-
-        if FILTER_INSTALLED in fltlist:
-            # we have one package per slot, so it's the newest
-            return cpv_list
-
-        cpv_dict = self.get_cpv_slotted(cpv_list)
-
-        # slots are sorted (dict), revert them to have newest slots first
-        slots = cpv_dict.keys()
-        slots.reverse()
-
-        # empty cpv_list, cpv are now in cpv_dict and cpv_list gonna be repop
-        cpv_list = []
-
-        for k in slots:
-            # if not_intalled on, no need to check for newest installed
-            if FILTER_NOT_INSTALLED not in fltlist:
-                newest_installed = self.get_newest_cpv(cpv_dict[k], True)
-                if newest_installed != "":
-                    cpv_list.append(newest_installed)
-            newest_available = self.get_newest_cpv(cpv_dict[k], False)
-            if newest_available != "":
-                cpv_list.append(newest_available)
-
-        return cpv_list
-
-    def get_packages_required(self, cpv_input, recursive):
-        '''
-        Get a list of cpv and recursive parameter.
-        Returns the list of packages required for cpv list.
-        '''
-        packages_list = []
-
-        myopts = {}
-        myopts["--selective"] = True
-        myopts["--deep"] = True
-
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "remove")
-        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
-                self.pvar.trees, myopts, myparams, None)
-
-        # TODO: atm, using FILTER_INSTALLED because it's quicker
-        # and we don't want to manage non-installed packages
-        for cp in self.get_all_cp([FILTER_INSTALLED]):
-            for cpv in self.get_all_cpv(cp, [FILTER_INSTALLED]):
-                depgraph._dynamic_config._dep_stack.append(
-                        _emerge.Dependency.Dependency(
-                            atom=portage.dep.Atom('=' + cpv),
-                            root=self.pvar.settings["ROOT"], parent=None))
-
-        if not depgraph._complete_graph():
-            self.error(ERROR_INTERNAL_ERROR, "Error when generating depgraph")
-            return
-
-        def _add_children_to_list(packages_list, node):
-            for n in depgraph._dynamic_config.digraph.parent_nodes(node):
-                if n not in packages_list \
-                        and not isinstance(n, _emerge.SetArg.SetArg):
-                    packages_list.append(n)
-                    _add_children_to_list(packages_list, n)
-
-        for node in depgraph._dynamic_config.digraph.__iter__():
-            if isinstance(node, _emerge.SetArg.SetArg):
-                continue
-            if node.cpv in cpv_input:
-                if recursive:
-                    _add_children_to_list(packages_list, node)
-                else:
-                    for n in \
-                            depgraph._dynamic_config.digraph.parent_nodes(node):
-                        if not isinstance(n, _emerge.SetArg.SetArg):
-                            packages_list.append(n)
-
-        # remove cpv_input that may be added to the list
-        def filter_cpv_input(x): return x.cpv not in cpv_input
-        return filter(filter_cpv_input, packages_list)
-
     def _package(self, pkg_match, info=None):
 
         # package_id = (package_identifier, EntropyRepository)
@@ -655,6 +658,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             self._log_message(__name__, "get_packages: done %s/100" % (
                 percent,))
 
+            self.percentage(percent)
             pkg = self._id_to_etp(pk_pkg)
             if pkg is None:
                 self.error(ERROR_PACKAGE_NOT_FOUND,
@@ -949,85 +953,24 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
-    def install_packages(self, only_trusted, pkgs):
-        # NOTES:
-        # can't install an already installed packages
-        # even if it happens to be needed in Gentoo but probably not this API
+    def install_packages(self, only_trusted, pk_pkgs):
+
+        self._log_message(__name__, "install_packages: got %s and %s" % (
+            only_trusted, pk_pkgs,))
 
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
-        self.percentage(None)
-
-        cpv_list = []
 
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
-
-            if not self.is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-
-            if self.is_installed(cpv):
-                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                        "Package %s is already installed" % pkg)
+        pkgs = []
+        for pk_pkg in pk_pkgs:
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None:
+                self.error(ERROR_UPDATE_NOT_FOUND,
+                    "Package %s was not found" % (pk_pkg,))
                 continue
+            pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-            cpv_list.append('=' + cpv)
-
-        # only_trusted isn't supported
-        # but better to show it after important errors
-        if only_trusted:
-            self.error(ERROR_MISSING_GPG_SIGNATURE,
-                    "Portage backend does not support GPG signature")
-            return
-
-        # creating installation depgraph
-        myopts = {}
-        favorites = []
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        self.status(STATUS_DEP_RESOLVE)
-
-        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
-                self.pvar.trees, myopts, myparams, None)
-        retval, favorites = depgraph.select_files(cpv_list)
-        if not retval:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Wasn't able to get dependency graph")
-            return
-
-        # check fetch restrict, can stop the function via error signal
-        self.check_fetch_restrict(depgraph.altlist())
-
-        self.status(STATUS_INSTALL)
-
-        # get elog messages
-        portage.elog.add_listener(self.elog_listener)
-
-        try:
-            self.block_output()
-            # compiling/installing
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
-                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
-            rval = mergetask.merge()
-        finally:
-            self.unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self.elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-        self.send_configuration_file_message()
+        self._execute_etp_pkgs_install(pkgs, only_trusted)
 
     def refresh_cache(self, force):
 
@@ -1054,6 +997,9 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 # inform UGC that we are syncing this repo
                 if self._entropy.UGC is not None:
                     self._entropy.UGC.add_download_stats(repo_id, [repo_id])
+        else:
+            self.message(MESSAGE_REPO_METADATA_DOWNLOAD_FAILED,
+                "Cannot update repositories!")
 
         self.percentage(100)
 
@@ -1314,13 +1260,13 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def search_group(self, filters, group):
 
+        self._log_message(__name__, "search_group: got %s and %s" % (
+            filters, group,))
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        self._log_message(__name__, "search_group: got %s and %s" % (
-            filters, group,))
-
         repos = self._get_all_repos()
 
         entropy_groups = self._entropy.get_package_groups()
@@ -1371,13 +1317,13 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def search_name(self, filters, keys):
 
+        self._log_message(__name__, "search_name: got %s and %s" % (
+            filters, keys,))
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        self._log_message(__name__, "search_name: got %s and %s" % (
-            filters, keys,))
-
         repos = self._get_all_repos()
 
         search_keys = keys.split("&")
@@ -1404,79 +1350,24 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
-    def update_packages(self, only_trusted, pkgs):
-        # TODO: manage errors
-        # TODO: manage config file updates
+    def update_packages(self, only_trusted, pk_pkgs):
+
+        self._log_message(__name__, "update_packages: got %s and %s" % (
+            only_trusted, pk_pkgs,))
 
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
-        self.percentage(None)
 
-        cpv_list = []
-
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
-
-            if not self.is_cpv_valid(cpv):
+        pkgs = []
+        for pk_pkg in pk_pkgs:
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None:
                 self.error(ERROR_UPDATE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
+                    "Package %s was not found" % (pk_pkg,))
                 continue
+            pkgs.append((pkg[0], pkg[1], pk_pkg,))
 
-            cpv_list.append('=' + cpv)
-
-        # only_trusted isn't supported
-        # but better to show it after important errors
-        if only_trusted:
-            self.error(ERROR_MISSING_GPG_SIGNATURE,
-                    "Portage backend does not support GPG signature")
-            return
-
-        # creating update depgraph
-        myopts = {}
-        favorites = []
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
-
-        self.status(STATUS_DEP_RESOLVE)
-
-        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
-                self.pvar.trees, myopts, myparams, None)
-        retval, favorites = depgraph.select_files(cpv_list)
-        if not retval:
-            self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Wasn't able to get dependency graph")
-            return
-
-        # check fetch restrict, can stop the function via error signal
-        self.check_fetch_restrict(depgraph.altlist())
-
-        self.status(STATUS_INSTALL)
-
-        # get elog messages
-        portage.elog.add_listener(self.elog_listener)
-
-        try:
-            self.block_output()
-            # compiling/installing
-            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
-                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
-                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
-            rval = mergetask.merge()
-        finally:
-            self.unblock_output()
-
-        # when an error is found print error messages
-        if rval != os.EX_OK:
-            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
-
-        # show elog messages and clean
-        portage.elog.remove_listener(self.elog_listener)
-        for msg in self._elog_messages:
-            # TODO: use specific message ?
-            self.message(MESSAGE_UNKNOWN, msg)
-        self._elog_messages = []
-
-        self.send_configuration_file_message()
+        self._execute_etp_pkgs_install(pkgs, only_trusted)
 
     def update_system(self, only_trusted):
         self.status(STATUS_RUNNING)
commit 9d55e7fae71b8c35c75939c2be921278ce83cdf1
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 23:33:47 2010 +0100

    [entropy] fix backend_update_packages pk_backend_spawn_helper arguments

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 01436ce..60e0317 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -332,7 +332,7 @@ backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **pack
 
 	/* send the complete list as stdin */
 	package_ids_temp = pk_package_ids_to_string (package_ids);
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-packages", package_ids_temp, NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-packages", pk_backend_bool_to_string (only_trusted), package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
 
commit a94db726cd8586f1c2f6d30444c430f44f153b87
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 22:46:34 2010 +0100

    portage: fix backend_update_packages() spawn_helper argument was missing

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index e2ae201..8b16934 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -339,7 +339,7 @@ backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **pack
 
 	/* send the complete list as stdin */
 	package_ids_temp = pk_package_ids_to_string (package_ids);
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-packages", package_ids_temp, NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-packages", pk_backend_bool_to_string (only_trusted), package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
 
commit b5100a8e44efb21e6cd1440ac2f248d32e72d404
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 21:53:07 2010 +0100

    [entropy] implement EntropyPackageKitBackend.get_requires()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index cce00e5..4c1d3bc 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -64,12 +64,14 @@ class PackageKitEntropyMixin:
         """
         return int((float(count)/max_count)*100)
 
-    def _log_message(self, source, message):
+    def _log_message(self, source, *args):
         """
         Write log message to Entropy PackageKit log file.
         """
         if PK_DEBUG:
-            self._entropy_log.write("%s: %s" % (source, message,))
+            self._entropy_log.write("%s: %s" % (source,
+                ' '.join([str(x) for x in args]),)
+            )
 
     def _is_repository_enabled(self, repo_name):
         """
@@ -98,7 +100,7 @@ class PackageKitEntropyMixin:
             pkg_ver += "%s%s" % (etpConst['entropytagprefix'], pkg_tag)
 
         cur_arch = etpConst['currentarch']
-        repo_name = c_repo.get_plugins_metadata().get("repo_name")
+        repo_name = self._get_repo_name(c_repo)
         if repo_name is None:
             self.error(ERROR_PACKAGE_ID_INVALID,
                 "Invalid metadata passed")
@@ -300,6 +302,17 @@ class PackageKitEntropyMixin:
                 "Failed to enable repository %s: %s" % (repoid, err,))
             return
 
+    def _get_repo_name(self, repo_db):
+        """
+        Return repository name (identifier) given an EntropyRepository
+        instance.
+        """
+        repo_name = self._repo_name_cache.get(repo_db)
+        if repo_name is None:
+            repo_name = repo_db.get_plugins_metadata().get("repo_name")
+            self._repo_name_cache[repo_db] = repo_name
+        return repo_name
+
 
 class PackageKitEntropyClient(Client):
     """ PackageKit Entropy Client subclass """
@@ -356,6 +369,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
     def __init__(self, args):
         signal.signal(signal.SIGQUIT, self.__sigquit)
         self._entropy = PackageKitEntropyClient()
+        self._repo_name_cache = {}
         PackageKitEntropyClient._pk_progress = self.percentage
 
         self._settings = SystemSettings()
@@ -586,16 +600,17 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 pk_pkg, pkg,))
 
             pkg_id, repo_db = pkg
-            repo = repo_db.get_plugins_metadata().get("repo_name")
+            repo = self._get_repo_name(repo_db)
             pkgs.add((repo, pkg_id, repo_db,))
 
         matches = [(y, x) for x, y, z in pkgs]
+        self._log_message(__name__, "get_depends: raw matches => %s" % (
+            matches,))
 
-        # FIXME: use relaxed_deps that way?
         empty = False
         deep = False
         install, removal, deps_not_f = self._entropy.get_install_queue(matches,
-            empty, deep, relaxed_deps = not recursive)
+            empty, deep, recursive = recursive)
 
         if deps_not_f == -2:
             self.error(ERROR_DEP_RESOLUTION_FAILED,
@@ -687,7 +702,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 pk_pkg, pkg,))
 
             pkg_id, repo_db = pkg
-            repo = repo_db.get_plugins_metadata().get("repo_name")
+            repo = self._get_repo_name(repo_db)
             pkgs.append((repo, pkg_id, repo_db, pk_pkg))
 
         count = 0
@@ -773,57 +788,57 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         for repo_id, desc, enabled, devel in metadata:
             self.repo_detail(repo_id, desc, enabled)
 
-    def get_requires(self, filters, pkgs, recursive):
-        # TODO: manage non-installed package
+    def get_requires(self, filters, pk_pkgs, recursive):
 
-        # FILTERS:
-        # - installed: error atm, see previous TODO
-        # - free: ok
-        # - newest: ignored because only one version of a package is installed
+        self._log_message(__name__, "get_requires: got %s and %s and %s" % (
+            filters, pk_pkgs, recursive))
 
-        self.status(STATUS_RUNNING)
+        self.status(STATUS_INFO)
         self.allow_cancel(True)
-        self.percentage(None)
+        self.percentage(0)
 
-        fltlist = filters.split(';')
+        pkgs = set()
+        for pk_pkg in pk_pkgs:
 
-        cpv_input = []
-        cpv_list = []
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None: # wtf!
+                self._log_message(__name__, "get_requires: cannot match %s" % (
+                    pk_pkg,))
+                continue
 
-        if FILTER_NOT_INSTALLED in fltlist:
-            self.error(ERROR_CANNOT_GET_REQUIRES,
-                    "get-requires returns only installed packages at the moment")
-            return
+            self._log_message(__name__, "get_requires: translated %s => %s" % (
+                pk_pkg, pkg,))
 
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
+            pkg_id, repo_db = pkg
+            repo = self._get_repo_name(repo_db)
+            pkgs.add((repo, pkg_id, repo_db,))
 
-            if not self.is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
-                continue
-            if not self.is_installed(cpv):
-                self.error(ERROR_CANNOT_GET_REQUIRES,
-                        "get-requires is only available for installed packages at the moment")
-                continue
+        matches = [(y, x) for x, y, z in pkgs]
 
-            cpv_input.append(cpv)
+        self._log_message(__name__, "get_requires: cooked => %s" % (
+            matches,))
 
-        packages_list = self.get_packages_required(cpv_input, recursive)
+        empty = False
+        deep = False
+        reverse_deps = self._entropy.get_reverse_dependencies(matches,
+            deep = deep, recursive = recursive)
 
-        # now we can populate cpv_list
-        cpv_list = []
-        for p in packages_list:
-            cpv_list.append(p.cpv)
-        del packages_list
+        self._log_message(__name__, "get_requires: reverse_deps => %s" % (
+            reverse_deps,))
 
-        # free filter
-        cpv_list = self.filter_free(cpv_list, fltlist)
+        pkgs = set([(y, x, self._entropy.open_repository(y),) for x, y in \
+            reverse_deps])
 
-        for cpv in cpv_list:
-            # prevent showing input packages
-            if '=' + cpv not in cpv_input:
-                self._package(cpv)
+        self._log_message(__name__, "get_requires: matches %s" % (
+            pkgs,))
+
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
+
+        self.percentage(100)
 
     def get_update_detail(self, pk_pkgs):
 
@@ -852,7 +867,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                     "could not find %s" % (pk_pkg,))
                 continue
             pkg_id, c_repo = pkg
-            repo_name = c_repo.get_plugins_metadata().get("repo_name")
+            repo_name = self._get_repo_name(c_repo)
 
             updates = []
             keyslot = c_repo.retrieveKeySlotAggregated(pkg_id)
commit 368b253e45a63976ccae7aeac9df86276dd6864d
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 13:30:56 2010 +0100

    [entropy] implement PackageKitEntropyBackend.get_update_detail()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index f3df247..cce00e5 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -24,6 +24,7 @@
 import os
 import sys
 import signal
+import time
 
 from packagekit.backend import *
 from packagekit.progress import *
@@ -31,6 +32,7 @@ from packagekit.package import PackagekitPackage
 
 sys.path.insert(0, '/usr/lib/entropy/libraries')
 
+from entropy.i18n import _
 from entropy.const import etpConst
 from entropy.client.interfaces import Client
 from entropy.core.settings.base import SystemSettings
@@ -363,6 +365,12 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         PackageKitBaseBackend.__init__(self, args)
 
+    def _convert_date_to_iso8601(self, unix_time_str):
+        unix_time = float(unix_time_str)
+        t = time.localtime(unix_time)
+        formatted = time.strftime('%Y-%m-%dT%H:%M:%S', t)
+        return formatted
+
     def send_configuration_file_message(self):
         result = list(portage.util.find_updated_config_files(
             self.pvar.settings['ROOT'],
@@ -817,36 +825,77 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             if '=' + cpv not in cpv_input:
                 self._package(cpv)
 
-    def get_update_detail(self, pkgs):
-        # TODO: a lot of informations are missing
+    def get_update_detail(self, pk_pkgs):
+
+        self._log_message(__name__, "get_update_detail: got %s" % (
+            pk_pkgs,))
 
         self.status(STATUS_INFO)
         self.allow_cancel(True)
-        self.percentage(None)
+        self.percentage(0)
+
+        count = 0
+        max_count = len(pk_pkgs)
+        default_repo = self._settings['repositories']['default_repository']
+        i_repo = self._entropy.installed_repository()
+        for pk_pkg in pk_pkgs:
+            count += 1
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
+
+            self._log_message(__name__, "get_update_detail: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None:
+                self.message(MESSAGE_COULD_NOT_FIND_PACKAGE,
+                    "could not find %s" % (pk_pkg,))
+                continue
+            pkg_id, c_repo = pkg
+            repo_name = c_repo.get_plugins_metadata().get("repo_name")
 
-        for pkg in pkgs:
             updates = []
+            keyslot = c_repo.retrieveKeySlotAggregated(pkg_id)
+            matches, m_rc = self._entropy.atom_match(keyslot, multiMatch = True,
+                multiRepo = True)
+            for m_pkg_id, m_repo_id in matches:
+                if (m_pkg_id, m_repo_id) == (pkg_id, repo_name):
+                    continue # fliter myself
+                m_c_repo = self._entropy.open_repository(m_repo_id)
+                updates.append(self._etp_to_id((m_pkg_id, m_c_repo)))
+
             obsoletes = ""
-            vendor_url = ""
-            bugzilla_url = ""
+            bugzilla_url = "http://bugs.sabayon.org"
             cve_url = ""
+            vendor_url = c_repo.retrieveHomepage(pkg_id)
+            changelog = c_repo.retrieveChangelog(pkg_id)
+            updates = "&".join(updates)
 
-            cpv = self._id_to_etp(pkg)
+            # when package has been issued
+            issued = self._convert_date_to_iso8601(
+                c_repo.retrieveCreationDate(pkg_id))
 
-            if not self.pvar.portdb.cpv_exists(cpv):
-                self.message(MESSAGE_COULD_NOT_FIND_PACKAGE, "could not find %s" % pkg)
+            # when package has been updated on system
+            # search inside installed pkgs db
+            updated = ''
+            c_id, c_rc = i_repo.atomMatch(keyslot)
+            if c_rc == 0:
+                updated = self._convert_date_to_iso8601(
+                    i_repo.retrieveCreationDate(c_id))
 
-            for cpv in self.pvar.vardb.match(portage.pkgsplit(cpv)[0]):
-                updates.append(cpv)
-            updates = "&".join(updates)
+            update_message = _("Update")
+            state = UPDATE_STATE_STABLE
+            if repo_name != default_repo:
+                state = UPDATE_STATE_TESTING
+
+            self._log_message(__name__, "get_update_detail: issuing %s" % (
+                (pk_pkg, updates, obsoletes, vendor_url, bugzilla_url),))
 
-            # temporarily set vendor_url = homepage
-            homepage = self.get_metadata(cpv, ["HOMEPAGE"])[0]
-            vendor_url = homepage
+            self.update_detail(pk_pkg, updates, obsoletes, vendor_url,
+                bugzilla_url, cve_url, "none", update_message, changelog,
+                state, issued, updated)
 
-            self.update_detail(pkg, updates, obsoletes, vendor_url, bugzilla_url,
-                    cve_url, "none", "No update text", "No ChangeLog",
-                    UPDATE_STATE_STABLE, None, None)
+        self.percentage(100)
 
     def get_updates(self, filters):
 
commit f6ff602d814d188afae3bb91eb770c70ee4a1d93
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 12:59:05 2010 +0100

    [portage] fix PackageKitPortageBackend.get_update_detail()

diff --git a/backends/portage/portageBackend.py b/backends/portage/portageBackend.py
index b316bdd..c250abd 100755
--- a/backends/portage/portageBackend.py
+++ b/backends/portage/portageBackend.py
@@ -1078,10 +1078,12 @@ class PackageKitPortageBackend(PackageKitBaseBackend):
             # temporarily set vendor_url = homepage
             homepage = self.get_metadata(cpv, ["HOMEPAGE"])[0]
             vendor_url = homepage
+            issued = ""
+            updated = ""
 
             self.update_detail(pkg, updates, obsoletes, vendor_url, bugzilla_url,
                     cve_url, "none", "No update text", "No ChangeLog",
-                    UPDATE_STATE_STABLE, None, None)
+                    UPDATE_STATE_STABLE, issued, updated)
 
     def get_updates(self, filters):
         # NOTES:
commit 259e29781fc18f4d41d3c4d079ecb3837c8396d6
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Feb 2 08:27:45 2010 +0100

    [entropy] implement PackageKitEntropyBackend.get_details()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 2430f6e..f3df247 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -144,14 +144,13 @@ class PackageKitEntropyMixin:
 
         return pkg_id, c_repo
 
-    def _get_pk_group(self, dep):
+    def _get_pk_group(self, category):
         """
-        Return PackageKit group belonging to given dependency.
+        Return PackageKit group belonging to given Entropy package category.
         """
-        category = entropy.tools.dep_getcat(dep)
-
-        group_data = [key for key, data in self._entropy.get_package_groups() \
-            if category in data['categories']]
+        group_data = [key for key, data in \
+            self._entropy.get_package_groups().items() \
+                if category in data['categories']]
         try:
             generic_group_name = group_data.pop(0)
         except IndexError:
@@ -185,6 +184,18 @@ class PackageKitEntropyMixin:
             repos.append((repo_db, repo,))
         return repos
 
+    def _get_pkg_size(self, pkg_match):
+        """
+        Return package size for both installed and available packages.
+        For available packages, the download size is returned, for installed
+        packages, the on-disk size is returned instead.
+        """
+        pkg_id, c_repo = pkg_match
+        if c_repo is self._entropy.installed_repository():
+            return c_repo.retrieveOnDiskSize(pkg_id)
+        else:
+            return c_repo.retrieveSize(pkg_id)
+
     def _pk_feed_sorted_pkgs(self, pkgs):
         """
         Given an unsorted list of tuples composed by repository identifier and
@@ -604,33 +615,44 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
-    def get_details(self, pkgs):
+    def get_details(self, pk_pkgs):
+
+        self._log_message(__name__, "get_details: got %s" % (pk_pkgs,))
+
         self.status(STATUS_INFO)
         self.allow_cancel(True)
         self.percentage(0)
 
-        nb_pkg = float(len(pkgs))
-        pkg_processed = 0.0
+        count = 0
+        max_count = len(pk_pkgs)
+        for pk_pkg in pk_pkgs:
+            count += 1
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
+            self._log_message(__name__, "get_packages: done %s/100" % (
+                percent,))
 
-            if not self.is_cpv_valid(cpv):
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None:
                 self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
+                    "Package %s was not found" % (pk_pkg,))
                 continue
+            pkg_id, c_repo = pkg
 
-            metadata = self.get_metadata(cpv,
-                    ["DESCRIPTION", "HOMEPAGE", "IUSE", "LICENSE", "SLOT"],
-                    in_dict=True)
-            license = self.get_real_license_str(cpv, metadata)
-
-            self.details(self._etp_to_id(cpv), license, self._get_group(cpv),
-                    metadata["DESCRIPTION"], metadata["HOMEPAGE"],
-                    self.get_size(cpv))
+            base_data = c_repo.getBaseData(pkg_id)
+            if base_data is None:
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                    "Package %s was not found in repository" % (pk_pkg,))
+                continue
 
-            pkg_processed += 100.0
-            self.percentage(int(pkg_processed/nb_pkg))
+            atom, name, version, versiontag, \
+            description, category, chost, \
+            cflags, cxxflags, homepage, \
+            license, branch, download, \
+            digest, slot, etpapi, \
+            datecreation, size, revision = base_data
+            self.details(pk_pkg, license, self._get_pk_group(category),
+                description, homepage, self._get_pkg_size(pkg))
 
         self.percentage(100)
 
commit 9ced345300e193b150c95dcadca66c20d621d339
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 22:35:21 2010 +0100

    [entropy] fix log message typo

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 90c734c..2430f6e 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -695,7 +695,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             count += 1
             percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
-            self._log_message(__name__, "resolve: done %s/100" % (percent,))
+            self._log_message(__name__, "get_packages: done %s/100" % (percent,))
 
             self.percentage(percent)
             pkg_ids = repo_db.listAllIdpackages()
commit 3c3b31d5dad0bb0ad7d9c4945b5ba831c291b221
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 22:34:39 2010 +0100

    [entropy] implement PackageKitEntropyBackend.get_packages()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 74f6926..90c734c 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -202,16 +202,15 @@ class PackageKitEntropyMixin:
         """
         inst_pkgs_repo_id = PackageKitEntropyMixin.INST_PKGS_REPO_ID
         fltlist = filters.split(';')
-        for flt in fltlist:
-            if flt == FILTER_NONE:
-                continue
-            elif flt == FILTER_INSTALLED:
-                pkgs = set([x for x in pkgs if x[0] == inst_pkgs_repo_id])
-            elif flt == FILTER_NOT_INSTALLED:
-                pkgs = set([x for x in pkgs if x[0] != inst_pkgs_repo_id])
-            elif flt == FILTER_FREE:
-                free_pkgs = set([x for x in pkgs if \
-                    self._entropy.is_entropy_package_free(x[1], x[0])])
+
+        if FILTER_INSTALLED in fltlist:
+            pkgs = set([x for x in pkgs if x[0] == inst_pkgs_repo_id])
+        elif FILTER_NOT_INSTALLED in fltlist:
+            pkgs = set([x for x in pkgs if x[0] != inst_pkgs_repo_id])
+        if FILTER_FREE in fltlist:
+            free_pkgs = set([x for x in pkgs if \
+                self._entropy.is_entropy_package_free(x[1], x[0])])
+
         return pkgs
 
     def _pk_add_pkg_type(self, pkgs, important_check = False):
@@ -598,7 +597,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
             pkgs,))
 
         # now filter
-        # FIXME: check if filters are properly applied
         pkgs = self._pk_filter_pkgs(pkgs, filters)
         pkgs = self._pk_add_pkg_type(pkgs)
         # now feed stdout
@@ -679,21 +677,35 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self.percentage(100)
 
     def get_packages(self, filters):
+
+        self._log_message(__name__, "get_packages: got %s" % (
+            filters,))
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        fltlist = filters.split(';')
-        cp_list = self.get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
+        repos = self._get_all_repos()
 
-        for cp in self.get_all_cp(fltlist):
-            for cpv in self.get_all_cpv(cp, fltlist):
-                self._package(cpv)
+        pkgs = set()
+        count = 0
+        max_count = len(repos)
+        for repo_db, repo in repos:
 
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
+            count += 1
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
+
+            self._log_message(__name__, "resolve: done %s/100" % (percent,))
+
+            self.percentage(percent)
+            pkg_ids = repo_db.listAllIdpackages()
+            pkgs.update((repo, x, repo_db,) for x in pkg_ids)
+
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
 
         self.percentage(100)
 
@@ -1084,13 +1096,13 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def resolve(self, filters, search_keys):
 
+        self._log_message(__name__, "resolve: got %s and %s" % (
+            filters, search_keys,))
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        self._log_message(__name__, "resolve: got %s and %s" % (
-            filters, search_keys,))
-
         repos = self._get_all_repos()
 
         pkgs = set()
commit 764c930b659d5ca2b6e81313b225813308a6a37b
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 21:56:31 2010 +0100

    [entropy] implement PackageKitEntropyBackend.get_files()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 3c4d054..74f6926 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -636,35 +636,45 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.percentage(100)
 
-    def get_files(self, pkgs):
+    def get_files(self, pk_pkgs):
+
+        self._log_message(__name__, "get_files: got %s" % (pk_pkgs,))
+
         self.status(STATUS_INFO)
         self.allow_cancel(True)
         self.percentage(0)
 
-        nb_pkg = float(len(pkgs))
-        pkg_processed = 0.0
-
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
+        pkgs = []
+        for pk_pkg in pk_pkgs:
 
-            if not self.is_cpv_valid(cpv):
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None: # wtf!
                 self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
+                        "Package %s was not found" % (pk_pkg,))
+                self._log_message(__name__, "get_files: cannot match %s" % (
+                    pk_pkg,))
                 continue
 
-            if not self.is_installed(cpv):
-                self.error(ERROR_CANNOT_GET_FILELIST,
-                        "get-files is only available for installed packages")
-                continue
+            self._log_message(__name__, "get_files: translated %s => %s" % (
+                pk_pkg, pkg,))
 
-            files = self.get_file_list(cpv)
-            files = sorted(files)
-            files = ";".join(files)
+            pkg_id, repo_db = pkg
+            repo = repo_db.get_plugins_metadata().get("repo_name")
+            pkgs.append((repo, pkg_id, repo_db, pk_pkg))
+
+        count = 0
+        max_count = len(pkgs)
+        for repo, pkg_id, repo_db, pk_pkg in pkgs:
+            count += 1
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
-            self.files(pkg, files)
+            self._log_message(__name__, "get_files: done %s/100" % (
+                percent,))
 
-            pkg_processed += 100.0
-            self.percentage(int(pkg_processed/nb_pkg))
+            self.percentage(percent)
+            files = repo_db.retrieveContent(pkg_id, order_by = 'file')
+            files = ";".join(files)
+            self.files(pk_pkg, files)
 
         self.percentage(100)
 
commit 12408e9348b15d1bb714aba69e4368d424e08c36
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 21:48:33 2010 +0100

    [entropy] implement PackageKitEntropyBackend.get_depends()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 16a9001..3c4d054 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -47,6 +47,8 @@ PK_DEBUG = True
 
 class PackageKitEntropyMixin:
 
+    INST_PKGS_REPO_ID = "installed"
+
     """
     Entropy relaxed code can be found in this Mixin class.
     The aim is to separate PackageKit code and reimplemented methods from
@@ -74,6 +76,74 @@ class PackageKitEntropyMixin:
         repo_data = self._settings['repositories']
         return repo_name in repo_data['available']
 
+    def _etp_to_id(self, pkg_match):
+        """
+        Transform an Entropy package match (pkg_id, EntropyRepository) into
+        PackageKit id.
+        @param pkg_match: tuple composed by package identifier and its parent
+            EntropyRepository instance
+        @type pkg_match: tuple
+        @return: PackageKit package id
+        @rtype: string
+        """
+        pkg_id, c_repo = pkg_match
+
+        pkg_key, pkg_slot, pkg_ver, pkg_tag, pkg_rev, atom = \
+            c_repo.getStrictData(pkg_id)
+
+        pkg_ver += "%s%s" % (etpConst['entropyslotprefix'], pkg_slot,)
+        if pkg_tag:
+            pkg_ver += "%s%s" % (etpConst['entropytagprefix'], pkg_tag)
+
+        cur_arch = etpConst['currentarch']
+        repo_name = c_repo.get_plugins_metadata().get("repo_name")
+        if repo_name is None:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                "Invalid metadata passed")
+
+        # if installed, repo should be 'installed', packagekit rule
+        if repo_name == etpConst['clientdbid']:
+            repo_name = "installed"
+
+        # openoffice-clipart;2.6.22;ppc64;fedora
+        return get_package_id(pkg_key, pkg_ver, cur_arch, repo_name)
+
+    def _id_to_etp(self, pkit_id):
+        """
+        Transform a PackageKit package id into Entropy package match.
+
+        @param pkit_id: PackageKit package id
+        @type pkit_id: string
+        @return: tuple composed by package identifier and its parent
+            EntropyRepository instance
+        @rtype: tuple
+        """
+        split_data = split_package_id(pkit_id)
+        if len(split_data) < 4:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                "The package id %s does not contain 4 fields" % pkit_id)
+            return
+        pkg_key, pkg_ver, cur_arch, repo_name = split_data
+
+        self._log_message(__name__, "_id_to_etp: extracted: %s | %s | %s | %s" % (
+            pkg_key, pkg_ver, cur_arch, repo_name,))
+        pkg_ver, pkg_slot = pkg_ver.rsplit(":", 1)
+
+        if repo_name == "installed":
+            c_repo = self._entropy.installed_repository()
+        else:
+            c_repo = self._entropy.open_repository(repo_name)
+
+        atom = pkg_key + "-" + pkg_ver + etpConst['entropyslotprefix'] + \
+            pkg_slot
+        pkg_id, pkg_rc = c_repo.atomMatch(atom)
+        if pkg_rc != 0:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                "Package not found in repository")
+            return
+
+        return pkg_id, c_repo
+
     def _get_pk_group(self, dep):
         """
         Return PackageKit group belonging to given dependency.
@@ -104,7 +174,7 @@ class PackageKitEntropyMixin:
         repository identifier for every available repository, including
         installed packages one.
         """
-        inst_pkgs_repo_id = PackageKitEntropyBackend.INST_PKGS_REPO_ID
+        inst_pkgs_repo_id = PackageKitEntropyMixin.INST_PKGS_REPO_ID
         repo_ids = self._entropy.repositories() + [inst_pkgs_repo_id]
         repos = []
         for repo in repo_ids:
@@ -130,7 +200,7 @@ class PackageKitEntropyMixin:
         """
         Filter pkgs list given PackageKit filters.
         """
-        inst_pkgs_repo_id = PackageKitEntropyBackend.INST_PKGS_REPO_ID
+        inst_pkgs_repo_id = PackageKitEntropyMixin.INST_PKGS_REPO_ID
         fltlist = filters.split(';')
         for flt in fltlist:
             if flt == FILTER_NONE:
@@ -266,8 +336,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         'unknown': GROUP_UNKNOWN,
     }
 
-    INST_PKGS_REPO_ID = "__system__"
-
     def __sigquit(self, signum, frame):
         if hasattr(self, '_entropy'):
             self._entropy.destroy()
@@ -413,86 +481,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         return cpv_list
 
-    def _etp_to_id(self, pkg_match):
-        """
-        Transform an Entropy package match (pkg_id, EntropyRepository) into
-        PackageKit id.
-        @param pkg_match: tuple composed by package identifier and its parent
-            EntropyRepository instance
-        @type pkg_match: tuple
-        @return: PackageKit package id
-        @rtype: string
-        """
-        pkg_id, c_repo = pkg_match
-
-        pkg_key, pkg_slot, pkg_ver, pkg_tag, pkg_rev, atom = \
-            c_repo.getStrictData(pkg_id)
-
-        if pkg_tag:
-            pkg_ver += "%s%s" % (etpConst['entropytagprefix'], pkg_tag)
-            pkg_ver += "%s%s" % (etpConst['entropyslotprefix'], pkg_slot,)
-        cur_arch = etpConst['currentarch']
-        repo_name = c_repo.get_plugins_metadata().get("repo_name")
-        if repo_name is None:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                "Invalid metadata passed")
-
-        # if installed, repo should be 'installed', packagekit rule
-        if repo_name == etpConst['clientdbid']:
-            repo_name = "installed"
-
-        # openoffice-clipart;2.6.22;ppc64;fedora
-        return get_package_id(pkg_key, pkg_ver, cur_arch, repo_name)
-
-    def _id_to_etp(self, pkit_id):
-        """
-        Transform a PackageKit package id into Entropy package match.
-
-        @param pkit_id: PackageKit package id
-        @type pkit_id: string
-        @return: tuple composed by package identifier and its parent
-            EntropyRepository instance
-        @rtype: tuple
-        """
-        split_data = split_package_id(pkgid)
-        if len(ret) < 4:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                "The package id %s does not contain 4 fields" % pkgid)
-        pkg_key, pkg_ver, cur_arch, repo_name = split_data
-        pkg_ver, pkg_slot = pkg_ver.rsplit(":", 1)
-
-        if repo_name == "installed":
-            c_repo = self._entropy.installed_repository()
-        else:
-            c_repo = self._entropy.open_repository(repo_name)
-
-        atom = pkg_key + "-" + pkg_ver + etpConst['entropyslotprefix'] + \
-            pkg_slot
-        pkg_id, pkg_rc = c_repo.atomMatch(atom)
-        if pkg_rc != 0:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                "Package not found in repository")
-
-        return pkg_id, c_repo
-
-    def id_to_cpv(self, pkgid):
-        '''
-        Transform the package id (packagekit) to a cpv (portage)
-        '''
-        ret = split_package_id(pkgid)
-
-        if len(ret) < 4:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                    "The package id %s does not contain 4 fields" % pkgid)
-        if '/' not in ret[0]:
-            self.error(ERROR_PACKAGE_ID_INVALID,
-                    "The first field of the package id must contain a category")
-
-        # remove slot info from version field
-        version = ret[1].split(':')[0]
-
-        return ret[0] + "-" + version
-
     def get_packages_required(self, cpv_input, recursive):
         '''
         Get a list of cpv and recursive parameter.
@@ -558,99 +546,65 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 info = INFO_AVAILABLE
         return self.package(self._etp_to_id(pkg_match), info, desc)
 
-    def get_depends(self, filters, pkgs, recursive):
-        # TODO: use only myparams ?
-        # TODO: improve error management / info
+    def get_depends(self, filters, pk_pkgs, recursive):
 
-        # FILTERS:
-        # - installed: ok
-        # - free: ok
-        # - newest: ignored because only one version of a package is installed
+        self._log_message(__name__, "get_depends: got %s and %s and %s" % (
+            filters, pk_pkgs, recursive,))
 
         self.status(STATUS_INFO)
         self.allow_cancel(True)
-        self.percentage(None)
-
-        fltlist = filters.split(';')
+        self.percentage(0)
 
-        cpv_input = []
-        cpv_list = []
+        pkgs = set()
+        for pk_pkg in pk_pkgs:
 
-        for pkg in pkgs:
-            cpv = self._id_to_etp(pkg)
-            if not self.is_cpv_valid(cpv):
-                self.error(ERROR_PACKAGE_NOT_FOUND,
-                        "Package %s was not found" % pkg)
+            pkg = self._id_to_etp(pk_pkg)
+            if pkg is None: # wtf!
+                self._log_message(__name__, "get_depends: cannot match %s" % (
+                    pk_pkg,))
                 continue
-            cpv_input.append('=' + cpv)
 
-        myopts = {}
-        myopts["--selective"] = True
-        myopts["--deep"] = True
-        myparams = _emerge.create_depgraph_params.create_depgraph_params(
-                myopts, "")
+            self._log_message(__name__, "get_depends: translated %s => %s" % (
+                pk_pkg, pkg,))
 
-        depgraph = _emerge.depgraph.depgraph(
-                self.pvar.settings, self.pvar.trees, myopts, myparams, None)
-        retval, fav = depgraph.select_files(cpv_input)
+            pkg_id, repo_db = pkg
+            repo = repo_db.get_plugins_metadata().get("repo_name")
+            pkgs.add((repo, pkg_id, repo_db,))
 
-        if not retval:
+        matches = [(y, x) for x, y, z in pkgs]
+
+        # FIXME: use relaxed_deps that way?
+        empty = False
+        deep = False
+        install, removal, deps_not_f = self._entropy.get_install_queue(matches,
+            empty, deep, relaxed_deps = not recursive)
+
+        if deps_not_f == -2:
             self.error(ERROR_DEP_RESOLUTION_FAILED,
-                    "Wasn't able to get dependency graph")
+                "Dependencies not found: %s" % (sorted(install),))
             return
 
-        def _add_children_to_list(cpv_list, node):
-            for n in depgraph._dynamic_config.digraph.child_nodes(node):
-                if n not in cpv_list:
-                    cpv_list.append(n)
-                    _add_children_to_list(cpv_list, n)
-
-        for cpv in cpv_input:
-            for r in depgraph._dynamic_config.digraph.root_nodes():
-                # TODO: remove things with @ as first char
-                # TODO: or refuse SetArgs
-                if not isinstance(r, _emerge.AtomArg.AtomArg):
-                    continue
-                if r.atom == cpv:
-                    if recursive:
-                        _add_children_to_list(cpv_list, r)
-                    else:
-                        for n in \
-                                depgraph._dynamic_config.digraph.child_nodes(r):
-                            for c in \
-                                depgraph._dynamic_config.digraph.child_nodes(n):
-                                cpv_list.append(c)
-
-        def _filter_uninstall(cpv):
-            return cpv[3] != 'uninstall'
-        def _filter_installed(cpv):
-            return cpv[0] == 'installed'
-        def _filter_not_installed(cpv):
-            return cpv[0] != 'installed'
-
-        # removing packages going to be uninstalled
-        cpv_list = filter(_filter_uninstall, cpv_list)
-
-        # install filter
-        if FILTER_INSTALLED in fltlist:
-            cpv_list = filter(_filter_installed, cpv_list)
-        if FILTER_NOT_INSTALLED in fltlist:
-            cpv_list = filter(_filter_not_installed, cpv_list)
+        # transform install into (repo, pkg_id, c_repo) list
+        install = [(y, x, self._entropy.open_repository(y),) for x, y in \
+            install]
+        # transform remove the same way
+        inst_pkg_r_id = PackageKitEntropyMixin.INST_PKGS_REPO_ID
+        removal = [(inst_pkg_r_id, x, self._entropy.installed_repository()) \
+            for x in removal]
 
-        # now we can change cpv_list to a real cpv list
-        tmp_list = cpv_list[:]
-        cpv_list = []
-        for x in tmp_list:
-            cpv_list.append(x[2])
-        del tmp_list
+        pkgs = set(install + removal)
 
-        # free filter
-        cpv_list = self.filter_free(cpv_list, fltlist)
+        self._log_message(__name__, "get_depends: matches %s" % (
+            pkgs,))
 
-        for cpv in cpv_list:
-            # prevent showing input packages
-            if '=' + cpv not in cpv_input:
-                self._package(cpv)
+        # now filter
+        # FIXME: check if filters are properly applied
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
+
+        self.percentage(100)
 
     def get_details(self, pkgs):
         self.status(STATUS_INFO)
@@ -735,6 +689,9 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def get_repo_list(self, filters):
 
+        self._log_message(__name__, "get_repo_list: got %s and %s" % (
+            filters,))
+
         self.status(STATUS_INFO)
         self.allow_cancel(True)
         self.percentage(None)
@@ -1130,6 +1087,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         count = 0
         max_count = len(repos)
         for repo_db, repo in repos:
+
             count += 1
             percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
commit 9a9e8694e8d0ac616981392d3da1665637cbd6bf
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 20:51:37 2010 +0100

    [entropy] implement PackageKitEntropyBackend.get_repo_list()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 3e2930a..16a9001 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -734,29 +734,35 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self.percentage(100)
 
     def get_repo_list(self, filters):
-        # NOTES:
-        # use layman API
-        # returns only official and supported repositories
-        # and creates a dummy repo for portage tree
+
         self.status(STATUS_INFO)
         self.allow_cancel(True)
         self.percentage(None)
 
-        fltlist = filters.split(';')
+        excluded_repos = self._settings['repositories']['excluded']
+        available_repos = self._settings['repositories']['available']
+        default_repo = self._settings['repositories']['default_repository']
+
+        all_repos = sorted(excluded_repos.keys() + available_repos.keys())
+        metadata = []
+        for repo_id in all_repos:
 
-        # get installed and available dbs
-        installed_layman_db = layman.db.DB(layman.config.Config())
-        available_layman_db = layman.db.RemoteDB(layman.config.Config())
+            repo_data = available_repos.get(repo_id,
+                excluded_repos.get(repo_id))
+            if repo_data is None: # wtf?
+                continue
 
-        # 'gentoo' is a dummy repo
-        self.repo_detail('gentoo', 'Gentoo Portage tree', True)
+            enabled = self._is_repository_enabled(repo_id)
+            desc = repo_data['description']
+            devel = repo_id != default_repo
+            metadata.append((repo_id, desc, enabled, devel))
+
+        fltlist = filters.split(';')
+        if FILTER_NOT_DEVELOPMENT in fltlist:
+            metadata = [x for x in metadata if not x[3]]
 
-        if FILTER_NOT_DEVELOPMENT not in fltlist:
-            for o in available_layman_db.overlays.keys():
-                if available_layman_db.overlays[o].is_official() \
-                        and available_layman_db.overlays[o].is_supported():
-                    self.repo_detail(o, o,
-                            self._is_repository_enabled(o))
+        for repo_id, desc, enabled, devel in metadata:
+            self.repo_detail(repo_id, desc, enabled)
 
     def get_requires(self, filters, pkgs, recursive):
         # TODO: manage non-installed package
commit 344b6409fa0c36489bfa5cb3bcaa161ebc7c8fcd
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 20:34:17 2010 +0100

    [entropy] implement PackageKitEntropyBackend.repo_enable()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 88a4f58..3e2930a 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -174,6 +174,50 @@ class PackageKitEntropyMixin:
 
         return new_pkgs
 
+    def _repo_enable(self, repoid):
+        excluded_repos = self._settings['repositories']['excluded']
+        available_repos = self._settings['repositories']['available']
+
+        if repoid in available_repos:
+            # just ignore
+            return
+        if repoid not in excluded_repos:
+            self.error(ERROR_REPO_NOT_FOUND,
+                    "Repository %s was not found" % (repoid,))
+            return
+
+        try:
+            self._entropy.enable_repository(repoid)
+        except Exception as err:
+            self.error(ERROR_INTERNAL_ERROR,
+                "Failed to enable repository %s: %s" % (repoid, err,))
+            return
+
+    def _repo_disable(self, repoid):
+        excluded_repos = self._settings['repositories']['excluded']
+        available_repos = self._settings['repositories']['available']
+        default_repo = self._settings['repositories']['default_repository']
+
+        if repoid in excluded_repos:
+            # just ignore
+            return
+        if repoid not in available_repos:
+            self.error(ERROR_REPO_NOT_FOUND,
+                    "Repository %s was not found" % (repoid,))
+            return
+
+        if repoid == default_repo:
+            self.error(ERROR_CANNOT_DISABLE_REPOSITORY,
+                "%s repository can't be disabled" % (repoid,))
+            return
+
+        try:
+            self._entropy.disable_repository(repoid)
+        except Exception as err:
+            self.error(ERROR_INTERNAL_ERROR,
+                "Failed to enable repository %s: %s" % (repoid, err,))
+            return
+
 
 class PackageKitEntropyClient(Client):
     """ PackageKit Entropy Client subclass """
@@ -1050,52 +1094,20 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         self._elog_messages = []
 
     def repo_enable(self, repoid, enable):
-        # NOTES: use layman API >= 1.2.3
+
+        self._log_message(__name__, "repo_enable: got %s and %s" % (
+            repoid, enable,))
+
         self.status(STATUS_INFO)
         self.allow_cancel(True)
         self.percentage(None)
 
-        # special case: trying to work with gentoo repo
-        if repoid == 'gentoo':
-            if not enable:
-                self.error(ERROR_CANNOT_DISABLE_REPOSITORY,
-                        "gentoo repository can't be disabled")
-            return
-
-        # get installed and available dbs
-        installed_layman_db = layman.db.DB(layman.config.Config())
-        available_layman_db = layman.db.RemoteDB(layman.config.Config())
-
-        # check now for repoid so we don't have to do it after
-        if not repoid in available_layman_db.overlays.keys():
-            self.error(ERROR_REPO_NOT_FOUND,
-                    "Repository %s was not found" % repoid)
-            return
+        if enable:
+            self._repo_enable(repoid)
+        else:
+            self._repo_disable(repoid)
 
-        # disabling (removing) a db
-        # if repository already disabled, ignoring
-        if not enable and self._is_repository_enabled(repoid):
-            try:
-                installed_layman_db.delete(installed_layman_db.select(repoid))
-            except Exception, e:
-                self.error(ERROR_INTERNAL_ERROR,
-                        "Failed to disable repository "+repoid+" : "+str(e))
-                return
-
-        # enabling (adding) a db
-        # if repository already enabled, ignoring
-        if enable and not self._is_repository_enabled(repoid):
-            try:
-                # TODO: clean the trick to prevent outputs from layman
-                self.block_output()
-                installed_layman_db.add(available_layman_db.select(repoid),
-                        quiet=True)
-                self.unblock_output()
-            except Exception, e:
-                self.unblock_output()
-                self.error(ERROR_INTERNAL_ERROR,
-                        "Failed to enable repository "+repoid+" : "+str(e))
-                return
+        self._log_message(__name__, "repo_enable: done")
 
     def resolve(self, filters, search_keys):
 
commit a737f8b90bb70e4764406cbc3fabe53274c54954
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 20:20:39 2010 +0100

    [entropy] implement PackageKitEntropyBackend.resolve()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index be5e736..88a4f58 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -39,6 +39,8 @@ from entropy.exceptions import SystemDatabaseError
 
 import entropy.tools
 
+PK_DEBUG = True
+
 # TODO:
 # remove percentage(None) if percentage is used
 # protection against signal when installing/removing
@@ -62,7 +64,8 @@ class PackageKitEntropyMixin:
         """
         Write log message to Entropy PackageKit log file.
         """
-        self._entropy_log.write("%s: %s" % (source, message,))
+        if PK_DEBUG:
+            self._entropy_log.write("%s: %s" % (source, message,))
 
     def _is_repository_enabled(self, repo_name):
         """
@@ -1094,31 +1097,37 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                         "Failed to enable repository "+repoid+" : "+str(e))
                 return
 
-    def resolve(self, filters, pkgs):
+    def resolve(self, filters, search_keys):
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        fltlist = filters.split(';')
-        cp_list = self.get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
+        self._log_message(__name__, "resolve: got %s and %s" % (
+            filters, search_keys,))
 
-        reg_expr = []
-        for pkg in pkgs:
-            reg_expr.append("^" + re.escape(pkg) + "$")
-        reg_expr = "|".join(reg_expr)
+        repos = self._get_all_repos()
+
+        pkgs = set()
+        count = 0
+        max_count = len(repos)
+        for repo_db, repo in repos:
+            count += 1
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
-        # specifications says "be case sensitive"
-        s = re.compile(reg_expr)
+            self._log_message(__name__, "resolve: done %s/100" % (
+                percent,))
 
-        for cp in cp_list:
-            if s.match(cp):
-                for cpv in self.get_all_cpv(cp, fltlist):
-                    self._package(cpv)
+            self.percentage(percent)
+            for key in search_keys:
+                pkg_ids, pkg_rc = repo_db.atomMatch(key, multiMatch = True)
+                pkgs.update((repo, x, repo_db,) for x in pkg_ids)
 
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
 
         self.percentage(100)
 
commit c8ddf8649ec18edc0b2c9e02a0da2dcf7f86eed9
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 19:34:29 2010 +0100

    [entropy] complete PackageKitEntropyBackend.get_updates()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 6541f04..be5e736 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -32,10 +32,12 @@ from packagekit.package import PackagekitPackage
 sys.path.insert(0, '/usr/lib/entropy/libraries')
 
 from entropy.const import etpConst
-import entropy.tools
 from entropy.client.interfaces import Client
 from entropy.core.settings.base import SystemSettings
 from entropy.misc import LogFile
+from entropy.exceptions import SystemDatabaseError
+
+import entropy.tools
 
 # TODO:
 # remove percentage(None) if percentage is used
@@ -118,13 +120,12 @@ class PackageKitEntropyMixin:
         """
         lambda_sort = lambda x: x[2].retrieveAtom(x[1])
 
-        for repo, pkg_id, c_repo in sorted(pkgs, key = lambda_sort):
-            self._package((pkg_id, c_repo))
+        for repo, pkg_id, c_repo, pkg_type in sorted(pkgs, key = lambda_sort):
+            self._package((pkg_id, c_repo), info = pkg_type)
 
     def _pk_filter_pkgs(self, pkgs, filters):
         """
         Filter pkgs list given PackageKit filters.
-        TODO: add support for FILTER_NEWEST
         """
         inst_pkgs_repo_id = PackageKitEntropyBackend.INST_PKGS_REPO_ID
         fltlist = filters.split(';')
@@ -140,6 +141,37 @@ class PackageKitEntropyMixin:
                     self._entropy.is_entropy_package_free(x[1], x[0])])
         return pkgs
 
+    def _pk_add_pkg_type(self, pkgs, important_check = False):
+        """
+        Expand list of pkg tuples by adding PackageKit package type to it.
+        """
+        # we have INFO_IMPORTANT, INFO_SECURITY, INFO_NORMAL
+        new_pkgs = set()
+        sys_pkg_map = {}
+
+        for repo, pkg_id, c_repo in pkgs:
+
+            pkg_type = None
+            if important_check:
+                repo_sys_pkgs = sys_pkg_map.get(repo,
+                    c_repo.getSystemPackages())
+
+                if pkg_id in repo_sys_pkgs:
+                    pkg_type = INFO_IMPORTANT
+                else:
+                    pkg_type = INFO_NORMAL
+
+            if pkg_type is None:
+                if c_repo is self._entropy.installed_repository():
+                    info = INFO_INSTALLED
+                else:
+                    info = INFO_AVAILABLE
+
+            new_pkgs.add((repo, pkg_id, c_repo, pkg_type))
+
+        return new_pkgs
+
+
 class PackageKitEntropyClient(Client):
     """ PackageKit Entropy Client subclass """
 
@@ -763,126 +795,41 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                     UPDATE_STATE_STABLE, None, None)
 
     def get_updates(self, filters):
-        # NOTES:
-        # because of a lot of things related to Gentoo,
-        # only world and system packages are can be listed as updates
-        # _except_ for security updates
-
-        # UPDATE TYPES:
-        # - blocked: wait for feedbacks
-        # - low: TODO: --newuse
-        # - normal: default
-        # - important: none atm
-        # - security: from @security
-
-        # FILTERS:
-        # - installed: try to update non-installed packages and call me ;)
-        # - free: ok
-        # - newest: ok
 
         self.status(STATUS_INFO)
         self.allow_cancel(True)
-        self.percentage(None)
 
-        fltlist = filters.split(';')
+        # this is the part that takes time
+        self.percentage(0)
+        try:
+            update, remove, fine, spm_fine = self._entropy.calculate_updates()
+        except SystemDatabaseError as err:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                "System Repository error: %s" % (err,))
+            return
+        self.percentage(100)
 
-        update_candidates = []
-        cpv_updates = {}
-        cpv_downgra = {}
-
-        # get system and world packages
-        for s in ["system", "world"]:
-            set = portage.sets.base.InternalPackageSet(
-                    initial_atoms=self.pvar.root_config.setconfig.getSetAtoms(s))
-            for atom in set:
-                update_candidates.append(atom.cp)
-
-        # check if a candidate can be updated
-        for cp in update_candidates:
-            cpv_list_inst = self.pvar.vardb.match(cp)
-            cpv_list_avai = self.pvar.portdb.match(cp)
-
-            cpv_dict_inst = self.get_cpv_slotted(cpv_list_inst)
-            cpv_dict_avai = self.get_cpv_slotted(cpv_list_avai)
-
-            dict_upda = {}
-            dict_down = {}
-
-            # candidate slots are installed slots
-            slots = cpv_dict_inst.keys()
-            slots.reverse()
-
-            for s in slots:
-                cpv_list_updates = []
-                cpv_inst = cpv_dict_inst[s][0] # only one install per slot
-
-                # the slot can be outdated (not in the tree)
-                if s not in cpv_dict_avai:
-                    break
-
-                tmp_list_avai = cpv_dict_avai[s]
-                tmp_list_avai.reverse()
-
-                for cpv in tmp_list_avai:
-                    if self.cmp_cpv(cpv_inst, cpv) == -1:
-                        cpv_list_updates.append(cpv)
-                    else: # because the list is sorted
-                        break
-
-                # no update for this slot
-                if len(cpv_list_updates) == 0:
-                    if [cpv_inst] == self.pvar.portdb.visible([cpv_inst]):
-                        break # really no update
-                    else:
-                        # that's actually a downgrade or even worst
-                        if len(tmp_list_avai) == 0:
-                            break # this package is not known in the tree...
-                        else:
-                            dict_down[s] = [tmp_list_avai.pop()]
-
-                cpv_list_updates = self.filter_free(cpv_list_updates, fltlist)
-
-                if len(cpv_list_updates) == 0:
-                    break
-
-                if FILTER_NEWEST in fltlist:
-                    best_cpv = portage.best(cpv_list_updates)
-                    cpv_list_updates = [best_cpv]
-
-                dict_upda[s] = cpv_list_updates
-
-            if len(dict_upda) != 0:
-                cpv_updates[cp] = dict_upda
-            if len(dict_down) != 0:
-                cpv_downgra[cp] = dict_down
-
-        # get security updates
-        for atom in portage.sets.base.InternalPackageSet(
-                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("security")):
-            # send update message and remove atom from cpv_updates
-            if atom.cp in cpv_updates:
-                slot = self.get_metadata(atom.cpv, ["SLOT"])[0]
-                if slot in cpv_updates[atom.cp]:
-                    tmp_cpv_list = cpv_updates[atom.cp][slot][:]
-                    for cpv in tmp_cpv_list:
-                        if self.cmp_cpv(cpv, atom.cpv) >= 0:
-                            # cpv is a security update and removed from list
-                            cpv_updates[atom.cp][slot].remove(cpv)
-                            self._package(cpv, INFO_SECURITY)
-            else: # update also non-world and non-system packages if security
-                self._package(atom.cpv, INFO_SECURITY)
-
-        # downgrades
-        for cp in cpv_downgra:
-            for slot in cpv_downgra[cp]:
-                for cpv in cpv_downgra[cp][slot]:
-                    self._package(cpv, INFO_IMPORTANT)
-
-        # normal updates
-        for cp in cpv_updates:
-            for slot in cpv_updates[cp]:
-                for cpv in cpv_updates[cp][slot]:
-                    self._package(cpv, INFO_NORMAL)
+        pkgs = set()
+        count = 0
+        max_count = len(update)
+        for pkg_id, repo_id in update:
+            count += 1
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
+
+            self._log_message(__name__, "get_updates: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+            repo_db = self._entropy.open_repository(repo_id)
+            pkgs.add((repo_id, pkg_id, repo_db))
+
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs, important_check = True)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
+
+        self.percentage(100)
 
     def install_packages(self, only_trusted, pkgs):
         # NOTES:
@@ -1207,6 +1154,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         # now filter
         pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
         # now feed stdout
         self._pk_feed_sorted_pkgs(pkgs)
 
@@ -1265,6 +1213,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         # now filter
         pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
         # now feed stdout
         self._pk_feed_sorted_pkgs(pkgs)
 
@@ -1323,6 +1272,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         # now filter
         pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
         # now feed stdout
         self._pk_feed_sorted_pkgs(pkgs)
 
@@ -1355,6 +1305,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         # now filter
         pkgs = self._pk_filter_pkgs(pkgs, filters)
+        pkgs = self._pk_add_pkg_type(pkgs)
         # now feed stdout
         self._pk_feed_sorted_pkgs(pkgs)
 
commit 425f1c43f172505b9decfeca319e5cf32c9b1edb
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 18:30:21 2010 +0100

    [entropy] subclass entropy.client.interfaces.Client, get transparent progress update support

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 8c8bebb..6541f04 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -49,17 +49,18 @@ class PackageKitEntropyMixin:
     Entropy-only protected methods.
     """
 
-    def _log_message(self, source, message):
+    @staticmethod
+    def get_percentage(count, max_count):
         """
-        Write log message to Entropy PackageKit log file.
+        Prepare percentage value used to feed self.percentage()
         """
-        self._entropy_log.write("%s: %s" % (source, message,))
+        return int((float(count)/max_count)*100)
 
-    def _get_percentage(self, count, max_count):
+    def _log_message(self, source, message):
         """
-        Prepare percentage value used to feed self.percentage()
+        Write log message to Entropy PackageKit log file.
         """
-        return int((float(count)/max_count)*100)
+        self._entropy_log.write("%s: %s" % (source, message,))
 
     def _is_repository_enabled(self, repo_name):
         """
@@ -139,6 +140,30 @@ class PackageKitEntropyMixin:
                     self._entropy.is_entropy_package_free(x[1], x[0])])
         return pkgs
 
+class PackageKitEntropyClient(Client):
+    """ PackageKit Entropy Client subclass """
+
+    _pk_progress = None
+
+    def output(self, text, header = "", footer = "", back = False,
+        importance = 0, type = "info", count = None, percent = False):
+        """
+        Reimplemented from entropy.output.TextInterface.
+        """
+        # just write progress, if possible
+        progress = PackageKitEntropyClient._pk_progress
+        if progress is None:
+            return
+        if count is None:
+            return
+
+        cur, tot = count[0], count[1]
+        progress(PackageKitEntropyMixin.get_percentage(cur, tot))
+
+# in this way, any singleton class that tries to directly load Client
+# gets PackageKitEntropyClient in change
+Client.__singleton_class__ = PackageKitEntropyClient
+
 class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
@@ -171,7 +196,9 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
     def __init__(self, args):
         signal.signal(signal.SIGQUIT, self.__sigquit)
-        self._entropy = Client()
+        self._entropy = PackageKitEntropyClient()
+        PackageKitEntropyClient._pk_progress = self.percentage
+
         self._settings = SystemSettings()
         self._entropy_log = LogFile(
             level = self._settings['system']['log_level'],
@@ -941,7 +968,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
 
         self.status(STATUS_REFRESH_CACHE)
         self.allow_cancel(False)
-        self.percentage(None)
+        self.percentage(0)
 
         repo_intf = None
         repo_identifiers = sorted(self._settings['repositories']['available'])
@@ -963,6 +990,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
                 if self._entropy.UGC is not None:
                     self._entropy.UGC.add_download_stats(repo_id, [repo_id])
 
+        self.percentage(100)
+
     def remove_packages(self, allowdep, autoremove, pkgs):
         self.status(STATUS_RUNNING)
         self.allow_cancel(False)
@@ -1163,7 +1192,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         max_count = len(repos)
         for repo_db, repo in repos:
             count += 1
-            percent = self._get_percentage(count, max_count)
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
             self._log_message(__name__, "search_details: done %s/100" % (
                 percent,))
@@ -1201,7 +1230,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         max_count = len(repos)
         for repo_db, repo in repos:
             count += 1
-            percent = self._get_percentage(count, max_count)
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
             self._log_message(__name__, "search_file: done %s/100" % (
                 percent,))
@@ -1273,7 +1302,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         max_count = len(repos)
         for repo_db, repo in repos:
             count += 1
-            percent = self._get_percentage(count, max_count)
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
             self._log_message(__name__, "search_group: done %s/100" % (
                 percent,))
@@ -1314,7 +1343,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
         max_count = len(repos)
         for repo_db, repo in repos:
             count += 1
-            percent = self._get_percentage(count, max_count)
+            percent = PackageKitEntropyMixin.get_percentage(count, max_count)
 
             self._log_message(__name__, "search_name: done %s/100" % (
                 percent,))
commit 559607f03b970d83d8ebb8e1a8ecbdbe5cdd4ead
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 18:16:55 2010 +0100

    [entropy] basic functionality of PackageKitEntropyBackend.refresh_cache() implemented, split class functions

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 8fd123b..8c8bebb 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -41,45 +41,13 @@ from entropy.misc import LogFile
 # remove percentage(None) if percentage is used
 # protection against signal when installing/removing
 
-class PackageKitEntropyBackend(PackageKitBaseBackend):
+class PackageKitEntropyMixin:
 
-    _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
-
-    # Entropy <-> PackageKit groups map
-    _GROUP_MAP = {
-        'accessibility': GROUP_ACCESSIBILITY,
-        'development': GROUP_PROGRAMMING,
-        'games': GROUP_GAMES,
-        'gnome': GROUP_DESKTOP_GNOME,
-        'kde': GROUP_DESKTOP_KDE,
-        'lxde': GROUP_DESKTOP_OTHER,
-        'multimedia': GROUP_MULTIMEDIA,
-        'networking': GROUP_NETWORK,
-        'office': GROUP_OFFICE,
-        'science': GROUP_SCIENCE,
-        'system': GROUP_SYSTEM,
-        'security': GROUP_SECURITY,
-        'x11': GROUP_OTHER,
-        'xfce': GROUP_DESKTOP_XFCE,
-        'unknown': GROUP_UNKNOWN,
-    }
-
-    INST_PKGS_REPO_ID = "__system__"
-
-    def __sigquit(self, signum, frame):
-        if hasattr(self, '_entropy'):
-            self._entropy.destroy()
-        raise SystemExit(1)
-
-    def __init__(self, args):
-        signal.signal(signal.SIGQUIT, self.__sigquit)
-        self._entropy = Client()
-        self._settings = SystemSettings()
-        self._entropy_log = LogFile(
-            level = self._settings['system']['log_level'],
-            filename = self._log_fname, header = "[packagekit]")
-
-        PackageKitBaseBackend.__init__(self, args)
+    """
+    Entropy relaxed code can be found in this Mixin class.
+    The aim is to separate PackageKit code and reimplemented methods from
+    Entropy-only protected methods.
+    """
 
     def _log_message(self, source, message):
         """
@@ -171,6 +139,46 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
                     self._entropy.is_entropy_package_free(x[1], x[0])])
         return pkgs
 
+class PackageKitEntropyBackend(PackageKitBaseBackend, PackageKitEntropyMixin):
+
+    _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
+
+    # Entropy <-> PackageKit groups map
+    _GROUP_MAP = {
+        'accessibility': GROUP_ACCESSIBILITY,
+        'development': GROUP_PROGRAMMING,
+        'games': GROUP_GAMES,
+        'gnome': GROUP_DESKTOP_GNOME,
+        'kde': GROUP_DESKTOP_KDE,
+        'lxde': GROUP_DESKTOP_OTHER,
+        'multimedia': GROUP_MULTIMEDIA,
+        'networking': GROUP_NETWORK,
+        'office': GROUP_OFFICE,
+        'science': GROUP_SCIENCE,
+        'system': GROUP_SYSTEM,
+        'security': GROUP_SECURITY,
+        'x11': GROUP_OTHER,
+        'xfce': GROUP_DESKTOP_XFCE,
+        'unknown': GROUP_UNKNOWN,
+    }
+
+    INST_PKGS_REPO_ID = "__system__"
+
+    def __sigquit(self, signum, frame):
+        if hasattr(self, '_entropy'):
+            self._entropy.destroy()
+        raise SystemExit(1)
+
+    def __init__(self, args):
+        signal.signal(signal.SIGQUIT, self.__sigquit)
+        self._entropy = Client()
+        self._settings = SystemSettings()
+        self._entropy_log = LogFile(
+            level = self._settings['system']['log_level'],
+            filename = self._log_fname, header = "[packagekit]")
+
+        PackageKitBaseBackend.__init__(self, args)
+
     def send_configuration_file_message(self):
         result = list(portage.util.find_updated_config_files(
             self.pvar.settings['ROOT'],
@@ -930,34 +938,30 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         self.send_configuration_file_message()
 
     def refresh_cache(self, force):
-        # NOTES: can't manage progress even if it could be better
-        # TODO: do not wait for exception, check timestamp
-        # TODO: message if overlay repo has changed (layman)
+
         self.status(STATUS_REFRESH_CACHE)
         self.allow_cancel(False)
         self.percentage(None)
 
-        myopts = {'--quiet': True}
-
-        # get installed and available dbs
-        installed_layman_db = layman.db.DB(layman.config.Config())
-
-        if force:
-            timestamp_path = os.path.join(
-                    self.pvar.settings["PORTDIR"], "metadata", "timestamp.chk")
-            if os.access(timestamp_path, os.F_OK):
-                os.remove(timestamp_path)
-
+        repo_intf = None
+        repo_identifiers = sorted(self._settings['repositories']['available'])
         try:
-            self.block_output()
-            for o in installed_layman_db.overlays.keys():
-                installed_layman_db.sync(o, quiet=True)
-            _emerge.actions.action_sync(self.pvar.settings, self.pvar.trees,
-                    self.pvar.mtimedb, myopts, "")
-        except:
+            repo_intf = self._entropy.Repositories(repo_identifiers,
+                force = force)
+        except AttributeError:
+            self.error(ERROR_REPO_CONFIGURATION_ERROR, traceback.format_exc())
+        except Exception as err:
             self.error(ERROR_INTERNAL_ERROR, traceback.format_exc())
-        finally:
-            self.unblock_output()
+
+        if repo_intf is None:
+            return
+
+        ex_rc = repo_intf.sync()
+        if not ex_rc:
+            for repo_id in repo_identifiers:
+                # inform UGC that we are syncing this repo
+                if self._entropy.UGC is not None:
+                    self._entropy.UGC.add_download_stats(repo_id, [repo_id])
 
     def remove_packages(self, allowdep, autoremove, pkgs):
         self.status(STATUS_RUNNING)
commit 84a54410cf60b4da76a4dbb08d4ef57bdd2efe42
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 17:39:40 2010 +0100

    complete PackageKitEntropyBackend.search_details()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 812a708..8fd123b 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -171,26 +171,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
                     self._entropy.is_entropy_package_free(x[1], x[0])])
         return pkgs
 
-    def is_cpv_valid(self, cpv):
-        if self.is_installed(cpv):
-            # actually if is_installed return True that means cpv is in db
-            return True
-        elif self.pvar.portdb.cpv_exists(cpv):
-            return True
-
-        return False
-
-    def get_real_license_str(self, cpv, metadata):
-        # use conditionals info (w/ USE) in LICENSE and remove ||
-        ebuild_settings = self.get_ebuild_settings(cpv, metadata)
-        license = set(portage.flatten(portage.dep.use_reduce(
-            portage.dep.paren_reduce(metadata["LICENSE"]),
-            uselist=ebuild_settings.get("USE", "").split())))
-        license.discard('||')
-        license = ' '.join(license)
-
-        return license
-
     def send_configuration_file_message(self):
         result = list(portage.util.find_updated_config_files(
             self.pvar.settings['ROOT'],
@@ -230,17 +210,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
         return None
 
-    def check_fetch_restrict(self, packages_list):
-        for p in packages_list:
-            if 'fetch' in p.metadata['RESTRICT']:
-                files = self.get_restricted_fetch_files(p.cpv, p.metadata)
-                if files:
-                    message = "Package %s can't download some files." % p.cpv
-                    message += ";Please, download manually the followonig file(s):"
-                    for x in files:
-                        message += ";- %s then copy it to %s" % (' '.join(x[1]), x[0])
-                    self.error(ERROR_RESTRICTED_DOWNLOAD, message)
-
     def elog_listener(self, settings, key, logentries, fulltext):
         '''
         This is a listener for elog.
@@ -298,110 +267,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
         self.error(error_type, self._error_message)
 
-    def get_file_list(self, cpv):
-        cat, pv = portage.catsplit(cpv)
-        db = portage.dblink(cat, pv, self.pvar.settings['ROOT'],
-                self.pvar.settings, treetype="vartree",
-                vartree=self.pvar.vardb)
-
-        contents = db.getcontents()
-        if not contents:
-            return []
-
-        return db.getcontents().keys()
-
-    def cmp_cpv(self, cpv1, cpv2):
-        '''
-        returns 1 if cpv1 > cpv2
-        returns 0 if cpv1 = cpv2
-        returns -1 if cpv1 < cpv2
-        '''
-        return portage.pkgcmp(portage.pkgsplit(cpv1), portage.pkgsplit(cpv2))
-
-    def get_newest_cpv(self, cpv_list, installed):
-        newer = ""
-
-        # get the first cpv following the installed rule
-        for cpv in cpv_list:
-            if self.is_installed(cpv) == installed:
-                newer = cpv
-                break
-
-        if newer == "":
-            return ""
-
-        for cpv in cpv_list:
-            if self.is_installed(cpv) == installed:
-                if self.cmp_cpv(cpv, newer) == 1:
-                    newer = cpv
-
-        return newer
-
-    def get_metadata(self, cpv, keys, in_dict = False, add_cache_keys = False):
-        '''
-        This function returns required metadata.
-        If in_dict is True, metadata is returned in a dict object.
-        If add_cache_keys is True, cached keys are added to keys in parameter.
-        '''
-        if self.is_installed(cpv):
-            aux_get = self.pvar.vardb.aux_get
-            if add_cache_keys:
-                keys.extend(list(self.pvar.vardb._aux_cache_keys))
-        else:
-            aux_get = self.pvar.portdb.aux_get
-            if add_cache_keys:
-                keys.extend(list(self.pvar.portdb._aux_cache_keys))
-
-        if in_dict:
-            return dict(keys, aux_get(cpv, keys))
-        else:
-            return aux_get(cpv, keys)
-
-    def get_size(self, cpv):
-        '''
-        Returns the installed size if the package is installed.
-        Otherwise, the size of files needed to be downloaded.
-        If some required files have been downloaded,
-        only the remaining size will be considered.
-        '''
-        size = 0
-        if self.is_installed(cpv):
-            size = self.get_metadata(cpv, ["SIZE"])[0]
-            if size == '':
-                size = 0
-            else:
-                size = int(size)
-        else:
-            self
-            metadata = self.get_metadata(cpv, ["IUSE", "SLOT"], in_dict=True)
-
-            package = _emerge.Package.Package(
-                    type_name="ebuild",
-                    built=False,
-                    installed=False,
-                    root_config=self.pvar.root_config,
-                    cpv=cpv,
-                    metadata=metadata)
-
-            fetch_file = self.pvar.portdb.getfetchsizes(package[2],
-                    package.use.enabled)
-            for f in fetch_file:
-                size += fetch_file[f]
-
-        return size
-
-    def get_cpv_slotted(self, cpv_list):
-        cpv_dict = {}
-
-        for cpv in cpv_list:
-            slot = self.get_metadata(cpv, ["SLOT"])[0]
-            if slot not in cpv_dict:
-                cpv_dict[slot] = [cpv]
-            else:
-                cpv_dict[slot].append(cpv)
-
-        return cpv_dict
-
     def filter_newest(self, cpv_list, fltlist):
         if len(cpv_list) == 0:
             return cpv_list
@@ -434,62 +299,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
         return cpv_list
 
-    def get_all_cp(self, fltlist):
-        # NOTES:
-        # returns a list of cp
-        #
-        # FILTERS:
-        # - installed: ok
-        # - free: ok (should be done with cpv)
-        # - newest: ok (should be finished with cpv)
-        cp_list = []
-
-        if FILTER_INSTALLED in fltlist:
-            cp_list = self.pvar.vardb.cp_all()
-        elif FILTER_NOT_INSTALLED in fltlist:
-            cp_list = self.pvar.portdb.cp_all()
-        else:
-            # need installed packages first
-            cp_list = self.pvar.vardb.cp_all()
-            for cp in self.pvar.portdb.cp_all():
-                if cp not in cp_list:
-                    cp_list.append(cp)
-
-        return cp_list
-
-    def get_all_cpv(self, cp, fltlist, filter_newest=True):
-        # NOTES:
-        # returns a list of cpv
-        #
-        # FILTERS:
-        # - installed: ok
-        # - free: ok
-        # - newest: ok
-
-        cpv_list = []
-
-        # populate cpv_list taking care of installed filter
-        if FILTER_INSTALLED in fltlist:
-            cpv_list = self.pvar.vardb.match(cp)
-        elif FILTER_NOT_INSTALLED in fltlist:
-            for cpv in self.pvar.portdb.match(cp):
-                if not self.is_installed(cpv):
-                    cpv_list.append(cpv)
-        else:
-            cpv_list = self.pvar.vardb.match(cp)
-            for cpv in self.pvar.portdb.match(cp):
-                if cpv not in cpv_list:
-                    cpv_list.append(cpv)
-
-        # free filter
-        cpv_list = self.filter_free(cpv_list, fltlist)
-
-        # newest filter
-        if filter_newest:
-            cpv_list = self.filter_newest(cpv_list, fltlist)
-
-        return cpv_list
-
     def _etp_to_id(self, pkg_match):
         """
         Transform an Entropy package match (pkg_id, EntropyRepository) into
@@ -1334,53 +1143,39 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         self.percentage(100)
 
     def search_details(self, filters, keys):
-        # NOTES: very bad performance
+
+        self._log_message(__name__, "search_details: got %s and %s" % (
+            filters, keys,))
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        fltlist = filters.split(';')
-        cp_list = self.get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
-        search_list = get_search_list(keys)
+        repos = self._get_all_repos()
 
-        for cp in cp_list:
-            # unfortunatelly, everything is related to cpv, not cp
-            # can't filter cp
-            cpv_list = []
-
-            # newest filter can't be executed now
-            # because some cpv are going to be filtered by search conditions
-            # and newest filter could be alterated
-            for cpv in self.get_all_cpv(cp, fltlist, filter_newest=False):
-                match = True
-                metadata =  self.get_metadata(cpv,
-                        ["DESCRIPTION", "HOMEPAGE", "IUSE",
-                            "LICENSE", "repository", "SLOT"],
-                        in_dict=True)
-                # update LICENSE to correspond to system settings
-                metadata["LICENSE"] = self.get_real_license_str(cpv, metadata)
-                for s in search_list:
-                    found = False
-                    for x in metadata:
-                        if s.search(metadata[x]):
-                            found = True
-                            break
-                    if not found:
-                        match = False
-                        break
-                if match:
-                    cpv_list.append(cpv)
+        search_keys = keys.split("&")
+        pkgs = set()
+        count = 0
+        max_count = len(repos)
+        for repo_db, repo in repos:
+            count += 1
+            percent = self._get_percentage(count, max_count)
 
-            # newest filter
-            cpv_list = self.filter_newest(cpv_list, fltlist)
+            self._log_message(__name__, "search_details: done %s/100" % (
+                percent,))
 
-            for cpv in cpv_list:
-                self._package(cpv)
+            self.percentage(percent)
+            for key in search_keys:
+                pkg_ids = repo_db.searchDescription(key,
+                    just_id = True)
+                pkg_ids |= repo_db.searchHomepage(key, just_id = True)
+                pkg_ids |= repo_db.searchLicense(key, just_id = True)
+                pkgs.update((repo, x, repo_db,) for x in pkg_ids)
 
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
 
         self.percentage(100)
 
commit a5b4c9f1ad4aacc65efd80bccdf887fe51eccc94
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 16:28:18 2010 +0100

    [entropy] complete PackageKitEntropyBackend.search_file()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 2eeadb1..812a708 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -21,6 +21,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
+import os
 import sys
 import signal
 
@@ -154,6 +155,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
     def _pk_filter_pkgs(self, pkgs, filters):
         """
         Filter pkgs list given PackageKit filters.
+        TODO: add support for FILTER_NEWEST
         """
         inst_pkgs_repo_id = PackageKitEntropyBackend.INST_PKGS_REPO_ID
         fltlist = filters.split(';')
@@ -164,6 +166,9 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
                 pkgs = set([x for x in pkgs if x[0] == inst_pkgs_repo_id])
             elif flt == FILTER_NOT_INSTALLED:
                 pkgs = set([x for x in pkgs if x[0] != inst_pkgs_repo_id])
+            elif flt == FILTER_FREE:
+                free_pkgs = set([x for x in pkgs if \
+                    self._entropy.is_entropy_package_free(x[1], x[0])])
         return pkgs
 
     def is_cpv_valid(self, cpv):
@@ -397,36 +402,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
         return cpv_dict
 
-    def filter_free(self, cpv_list, fltlist):
-        if len(cpv_list) == 0:
-            return cpv_list
-
-        def _has_validLicense(cpv):
-            metadata = self.get_metadata(cpv, ["LICENSE", "USE", "SLOT"], True)
-            return not self.pvar.settings._getMissingLicenses(cpv, metadata)
-
-        if FILTER_FREE in fltlist or FILTER_NOT_FREE in fltlist:
-            free_licenses = "@FSF-APPROVED"
-            if FILTER_FREE in fltlist:
-                licenses = "-* " + free_licenses
-            elif FILTER_NOT_FREE in fltlist:
-                licenses = "* -" + free_licenses
-            backup_license = self.pvar.settings["ACCEPT_LICENSE"]
-
-            self.pvar.settings.unlock()
-            self.pvar.settings["ACCEPT_LICENSE"] = licenses
-            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
-            self.pvar.settings.regenerate()
-
-            cpv_list = filter(_has_validLicense, cpv_list)
-
-            self.pvar.settings["ACCEPT_LICENSE"] = backup_license
-            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
-            self.pvar.settings.regenerate()
-            self.pvar.settings.lock()
-
-        return cpv_list
-
     def filter_newest(self, cpv_list, fltlist):
         if len(cpv_list) == 0:
             return cpv_list
@@ -1409,47 +1384,61 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
         self.percentage(100)
 
-    def search_file(self, filters, key):
-        # FILTERS:
-        # - ~installed is not accepted (error)
-        # - free: ok
-        # - newest: as only installed, by himself
+    def search_file(self, filters, keys):
+
+        self._log_message(__name__, "search_file: got %s and %s" % (
+            filters, keys,))
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        fltlist = filters.split(';')
-
-        if FILTER_NOT_INSTALLED in fltlist:
-            self.error(ERROR_CANNOT_GET_FILELIST,
-                    "search-file isn't available with ~installed filter")
-            return
+        reverse_symlink_map = self._settings['system_rev_symlinks']
+        repos = self._get_all_repos()
 
-        cpv_list = self.pvar.vardb.cpv_all()
-        nb_cpv = 0.0
-        cpv_processed = 0.0
-        is_full_path = True
+        search_keys = keys.split("&")
+        pkgs = set()
+        count = 0
+        max_count = len(repos)
+        for repo_db, repo in repos:
+            count += 1
+            percent = self._get_percentage(count, max_count)
 
-        if key[0] != "/":
-            is_full_path = False
-            key = re.escape(key)
-            searchre = re.compile("/" + key + "$", re.IGNORECASE)
+            self._log_message(__name__, "search_file: done %s/100" % (
+                percent,))
 
-        # free filter
-        cpv_list = self.filter_free(cpv_list, fltlist)
-        nb_cpv = float(len(cpv_list))
+            self.percentage(percent)
 
-        for cpv in cpv_list:
-            for f in self.get_file_list(cpv):
-                if (is_full_path and key == f) \
-                or (not is_full_path and searchre.search(f)):
-                    self._package(cpv)
-                    break
+            for key in search_keys:
 
-            cpv_processed += 100.0
-            self.percentage(int(cpv_processed/nb_cpv))
+                like = False
+                # wildcard support
+                if key.find("*") != -1:
+                    key.replace("*", "%")
+                    like = True
+
+                pkg_ids = repo_db.searchBelongs(key, like = like)
+                if not pkg_ids:
+                    # try real path if possible
+                    pkg_ids = repo_db.searchBelongs(os.path.realpath(key),
+                        like = like)
+                if not pkg_ids:
+                    # try using reverse symlink mapping
+                    for sym_dir in reverse_symlink_map:
+                        if key.startswith(sym_dir):
+                            for sym_child in reverse_symlink_map[sym_dir]:
+                                my_file = sym_child+key[len(sym_dir):]
+                                pkg_ids = repo_db.searchBelongs(my_file,
+                                    like = like)
+                                if pkg_ids:
+                                    break
 
+                pkgs.update((repo, x, repo_db,) for x in pkg_ids)
 
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        # now feed stdout
+        self._pk_feed_sorted_pkgs(pkgs)
 
         self.percentage(100)
 
commit 0205e31b8c7a1ab166d30e051e1fcad43925426e
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 15:19:27 2010 +0100

    [entropy] improve PackageKitEntropyBackend.search_group(), implement filters support

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 60955b6..2eeadb1 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -63,6 +63,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         'unknown': GROUP_UNKNOWN,
     }
 
+    INST_PKGS_REPO_ID = "__system__"
+
     def __sigquit(self, signum, frame):
         if hasattr(self, '_entropy'):
             self._entropy.destroy()
@@ -127,10 +129,11 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         repository identifier for every available repository, including
         installed packages one.
         """
-        repo_ids = self._entropy.repositories() + ["__system__"]
+        inst_pkgs_repo_id = PackageKitEntropyBackend.INST_PKGS_REPO_ID
+        repo_ids = self._entropy.repositories() + [inst_pkgs_repo_id]
         repos = []
         for repo in repo_ids:
-            if repo == "__system__":
+            if repo == inst_pkgs_repo_id:
                 repo_db = self._entropy.installed_repository()
             else:
                 repo_db = self._entropy.open_repository(repo)
@@ -148,6 +151,20 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         for repo, pkg_id, c_repo in sorted(pkgs, key = lambda_sort):
             self._package((pkg_id, c_repo))
 
+    def _pk_filter_pkgs(self, pkgs, filters):
+        """
+        Filter pkgs list given PackageKit filters.
+        """
+        inst_pkgs_repo_id = PackageKitEntropyBackend.INST_PKGS_REPO_ID
+        fltlist = filters.split(';')
+        for flt in fltlist:
+            if flt == FILTER_NONE:
+                continue
+            elif flt == FILTER_INSTALLED:
+                pkgs = set([x for x in pkgs if x[0] == inst_pkgs_repo_id])
+            elif flt == FILTER_NOT_INSTALLED:
+                pkgs = set([x for x in pkgs if x[0] != inst_pkgs_repo_id])
+        return pkgs
 
     def is_cpv_valid(self, cpv):
         if self.is_installed(cpv):
@@ -1432,6 +1449,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
             cpv_processed += 100.0
             self.percentage(int(cpv_processed/nb_cpv))
 
+
+
         self.percentage(100)
 
     def search_group(self, filters, group):
@@ -1444,7 +1463,6 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
             filters, group,))
 
         repos = self._get_all_repos()
-        fltlist = filters.split(';')
 
         entropy_groups = self._entropy.get_package_groups()
         all_matched_categories = set()
@@ -1486,6 +1504,9 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
                 pkg_ids = repo_db.listIdPackagesInIdcategory(cat_id)
                 pkgs.update((repo, x, repo_db,) for x in pkg_ids)
 
+        # now filter
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        # now feed stdout
         self._pk_feed_sorted_pkgs(pkgs)
 
     def search_name(self, filters, keys):
@@ -1516,15 +1537,8 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
                 pkgs.update((repo, x, repo_db,) for x in pkg_ids)
 
         # now filter
-        fltlist = filters.split(';')
-        for flt in fltlist:
-            if flt == FILTER_NONE:
-                continue
-            elif flt == FILTER_INSTALLED:
-                pkgs = set([x for x in pkgs if x[0] == "__system__"])
-            elif flt == FILTER_NOT_INSTALLED:
-                pkgs = set([x for x in pkgs if x[0] != "__system__"])
-
+        pkgs = self._pk_filter_pkgs(pkgs, filters)
+        # now feed stdout
         self._pk_feed_sorted_pkgs(pkgs)
 
         self.percentage(100)
commit bf807d78c23bce26899b3230a81ea24efbbff8f9
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Mon Feb 1 15:12:55 2010 +0100

    [entropy] complete PackageKitEntropyBackend.search_group()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 79bdb3b..60955b6 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -44,6 +44,25 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
     _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
 
+    # Entropy <-> PackageKit groups map
+    _GROUP_MAP = {
+        'accessibility': GROUP_ACCESSIBILITY,
+        'development': GROUP_PROGRAMMING,
+        'games': GROUP_GAMES,
+        'gnome': GROUP_DESKTOP_GNOME,
+        'kde': GROUP_DESKTOP_KDE,
+        'lxde': GROUP_DESKTOP_OTHER,
+        'multimedia': GROUP_MULTIMEDIA,
+        'networking': GROUP_NETWORK,
+        'office': GROUP_OFFICE,
+        'science': GROUP_SCIENCE,
+        'system': GROUP_SYSTEM,
+        'security': GROUP_SECURITY,
+        'x11': GROUP_OTHER,
+        'xfce': GROUP_DESKTOP_XFCE,
+        'unknown': GROUP_UNKNOWN,
+    }
+
     def __sigquit(self, signum, frame):
         if hasattr(self, '_entropy'):
             self._entropy.destroy()
@@ -59,54 +78,76 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
         PackageKitBaseBackend.__init__(self, args)
 
+    def _log_message(self, source, message):
+        """
+        Write log message to Entropy PackageKit log file.
+        """
+        self._entropy_log.write("%s: %s" % (source, message,))
+
+    def _get_percentage(self, count, max_count):
+        """
+        Prepare percentage value used to feed self.percentage()
+        """
+        return int((float(count)/max_count)*100)
+
     def _is_repository_enabled(self, repo_name):
+        """
+        Return whether given repository identifier is available and enabled.
+        """
         repo_data = self._settings['repositories']
         return repo_name in repo_data['available']
 
-    def _get_group(self, dep):
+    def _get_pk_group(self, dep):
         """
         Return PackageKit group belonging to given dependency.
         """
         category = entropy.tools.dep_getcat(dep)
-        entropy_groups = self._entropy.get_package_groups()
-
-        generic_group_name = None
-        for group_key, group_data in entropy_groups.items():
-            if category in group_data['categories']:
-                generic_group_name = group_key
-                break
 
-        if generic_group_name is None:
+        group_data = [key for key, data in self._entropy.get_package_groups() \
+            if category in data['categories']]
+        try:
+            generic_group_name = group_data.pop(0)
+        except IndexError:
             return GROUP_UNKNOWN
 
-        pk_group_map = {
-            'accessibility': GROUP_ACCESSIBILITY,
-            'development': GROUP_PROGRAMMING,
-            'games': GROUP_GAMES,
-            'gnome': GROUP_DESKTOP_GNOME,
-            'kde': GROUP_DESKTOP_KDE,
-            'lxde': GROUP_DESKTOP_OTHER,
-            'multimedia': GROUP_MULTIMEDIA,
-            'networking': GROUP_NETWORK,
-            'office': GROUP_OFFICE,
-            'science': GROUP_SCIENCE,
-            'system': GROUP_SYSTEM,
-            'x11': GROUP_OTHER,
-            'xfce': GROUP_DESKTOP_XFCE,
-        }
-        return pk_group_map[generic_group_name]
+        return PackageKitEntropyBackend._GROUP_MAP[generic_group_name]
 
-    def _log_message(self, source, message):
+    def _get_entropy_group(self, pk_group):
         """
-        Write log message to Entropy PackageKit log file.
+        Given a PackageKit group identifier, return Entropy packages group.
         """
-        self._entropy_log.write("%s: %s" % (source, message,))
+        group_map = PackageKitEntropyBackend._GROUP_MAP
+        # reverse dict
+        group_map_reverse = dict((y, x) for x, y in group_map.items())
+        return group_map_reverse.get(pk_group, 'unknown')
 
-    def _get_percentage(self, count, max_count):
+    def _get_all_repos(self):
         """
-        Prepare percentage value used to feed self.percentage()
+        Return a list of tuples containing EntropyRepository instance and
+        repository identifier for every available repository, including
+        installed packages one.
         """
-        return int((float(count)/max_count)*100)
+        repo_ids = self._entropy.repositories() + ["__system__"]
+        repos = []
+        for repo in repo_ids:
+            if repo == "__system__":
+                repo_db = self._entropy.installed_repository()
+            else:
+                repo_db = self._entropy.open_repository(repo)
+            repos.append((repo_db, repo,))
+        return repos
+
+    def _pk_feed_sorted_pkgs(self, pkgs):
+        """
+        Given an unsorted list of tuples composed by repository identifier and
+        EntropyRepository instance, feed PackageKit output by calling
+        self._package()
+        """
+        lambda_sort = lambda x: x[2].retrieveAtom(x[1])
+
+        for repo, pkg_id, c_repo in sorted(pkgs, key = lambda_sort):
+            self._package((pkg_id, c_repo))
+
 
     def is_cpv_valid(self, cpv):
         if self.is_installed(cpv):
@@ -1394,25 +1435,58 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         self.percentage(100)
 
     def search_group(self, filters, group):
-        # TODO: filter unknown groups before searching ? (optimization)
+
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
+        self._log_message(__name__, "search_group: got %s and %s" % (
+            filters, group,))
+
+        repos = self._get_all_repos()
         fltlist = filters.split(';')
-        cp_list = self.get_all_cp(fltlist)
-        nb_cp = float(len(cp_list))
-        cp_processed = 0.0
 
-        for cp in cp_list:
-            if self._get_group(cp) == group:
-                for cpv in self.get_all_cpv(cp, fltlist):
-                    self._package(cpv)
+        entropy_groups = self._entropy.get_package_groups()
+        all_matched_categories = set()
+        for e_data in entropy_groups.values():
+            all_matched_categories.update(e_data['categories'])
+        all_matched_categories = sorted(all_matched_categories)
 
-            cp_processed += 100.0
-            self.percentage(int(cp_processed/nb_cp))
+        entropy_group = self._get_entropy_group(group)
+        # group_data is None when there's no matching group
+        group_data = entropy_groups.get(entropy_group)
+        selected_categories = set()
+        if group_data is not None:
+            selected_categories.update(group_data['categories'])
 
-        self.percentage(100)
+        # if selected_categories is empty, then pull in pkgs with non matching
+        # category in all_matched_categories
+
+        pkgs = set()
+        count = 0
+        max_count = len(repos)
+        for repo_db, repo in repos:
+            count += 1
+            percent = self._get_percentage(count, max_count)
+
+            self._log_message(__name__, "search_group: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+            repo_all_cats = repo_db.listAllCategories()
+            if selected_categories:
+                etp_cat_ids = set([cat_id for cat_id, cat_name in \
+                    repo_all_cats if cat_name in selected_categories])
+            else:
+                # get all etp category ids excluding all_matched_categories
+                etp_cat_ids = set([cat_id for cat_id, cat_name in \
+                     repo_all_cats if cat_name not in all_matched_categories])
+
+            for cat_id in etp_cat_ids:
+                pkg_ids = repo_db.listIdPackagesInIdcategory(cat_id)
+                pkgs.update((repo, x, repo_db,) for x in pkg_ids)
+
+        self._pk_feed_sorted_pkgs(pkgs)
 
     def search_name(self, filters, keys):
 
@@ -1423,14 +1497,7 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         self._log_message(__name__, "search_name: got %s and %s" % (
             filters, keys,))
 
-        repo_ids = self._entropy.repositories() + ["__system__"]
-        repos = []
-        for repo in repo_ids:
-            if repo == "__system__":
-                repo_db = self._entropy.installed_repository()
-            else:
-                repo_db = self._entropy.open_repository(repo)
-            repos.append((repo_db, repo,))
+        repos = self._get_all_repos()
 
         search_keys = keys.split("&")
         pkgs = set()
@@ -1455,11 +1522,10 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
                 continue
             elif flt == FILTER_INSTALLED:
                 pkgs = set([x for x in pkgs if x[0] == "__system__"])
+            elif flt == FILTER_NOT_INSTALLED:
+                pkgs = set([x for x in pkgs if x[0] != "__system__"])
 
-        lambda_sort = lambda x: x[2].retrieveAtom(x[1])
-
-        for repo, pkg_id, c_repo in sorted(pkgs, key = lambda_sort):
-            self._package((pkg_id, c_repo))
+        self._pk_feed_sorted_pkgs(pkgs)
 
         self.percentage(100)
 
commit 80e8444c52c42071663a93491ed2f347e7744199
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Sun Jan 31 22:48:04 2010 +0100

    [entropy] complete PackageKitEntropyBackend.search_name()

diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
index 913f908..79bdb3b 100755
--- a/backends/entropy/entropyBackend.py
+++ b/backends/entropy/entropyBackend.py
@@ -1,4 +1,5 @@
 #!/usr/bin/python2
+# -*- coding: utf-8 -*-
 #
 #
 # Copyright (C) 2009 Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
@@ -33,6 +34,7 @@ from entropy.const import etpConst
 import entropy.tools
 from entropy.client.interfaces import Client
 from entropy.core.settings.base import SystemSettings
+from entropy.misc import LogFile
 
 # TODO:
 # remove percentage(None) if percentage is used
@@ -40,6 +42,8 @@ from entropy.core.settings.base import SystemSettings
 
 class PackageKitEntropyBackend(PackageKitBaseBackend):
 
+    _log_fname = os.path.join(etpConst['syslogdir'], "packagekit.log")
+
     def __sigquit(self, signum, frame):
         if hasattr(self, '_entropy'):
             self._entropy.destroy()
@@ -47,16 +51,14 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
     def __init__(self, args):
         signal.signal(signal.SIGQUIT, self.__sigquit)
-        self.__dev_null = open("/dev/null", "w")
         self._entropy = Client()
         self._settings = SystemSettings()
+        self._entropy_log = LogFile(
+            level = self._settings['system']['log_level'],
+            filename = self._log_fname, header = "[packagekit]")
 
         PackageKitBaseBackend.__init__(self, args)
 
-        # TODO: should be removed when using non-verbose function API
-        self.orig_out = None
-        self.orig_err = None
-
     def _is_repository_enabled(self, repo_name):
         repo_data = self._settings['repositories']
         return repo_name in repo_data['available']
@@ -94,17 +96,17 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
         }
         return pk_group_map[generic_group_name]
 
-    # TODO: should be removed when using non-verbose function API
-    def block_output(self):
-        self.orig_out = sys.stdout
-        self.orig_err = sys.stderr
-        sys.stdout = self.__dev_null
-        sys.stderr = self.__dev_null
+    def _log_message(self, source, message):
+        """
+        Write log message to Entropy PackageKit log file.
+        """
+        self._entropy_log.write("%s: %s" % (source, message,))
 
-    # TODO: should be removed when using non-verbose function API
-    def unblock_output(self):
-        sys.stdout = self.orig_out
-        sys.stderr = self.orig_err
+    def _get_percentage(self, count, max_count):
+        """
+        Prepare percentage value used to feed self.percentage()
+        """
+        return int((float(count)/max_count)*100)
 
     def is_cpv_valid(self, cpv):
         if self.is_installed(cpv):
@@ -1414,18 +1416,50 @@ class PackageKitEntropyBackend(PackageKitBaseBackend):
 
     def search_name(self, filters, keys):
 
-        c_repo = self._entropy.installed_repository()
-
         self.status(STATUS_QUERY)
         self.allow_cancel(True)
         self.percentage(0)
 
-        search_keys = keys.split()
-        #print "filters", filters, "keys", keys
-        for key in search_keys:
-            pkg_ids = c_repo.searchPackages(key, just_id = True)
-            for pkg_id in pkg_ids:
-                self._package((pkg_id, c_repo))
+        self._log_message(__name__, "search_name: got %s and %s" % (
+            filters, keys,))
+
+        repo_ids = self._entropy.repositories() + ["__system__"]
+        repos = []
+        for repo in repo_ids:
+            if repo == "__system__":
+                repo_db = self._entropy.installed_repository()
+            else:
+                repo_db = self._entropy.open_repository(repo)
+            repos.append((repo_db, repo,))
+
+        search_keys = keys.split("&")
+        pkgs = set()
+        count = 0
+        max_count = len(repos)
+        for repo_db, repo in repos:
+            count += 1
+            percent = self._get_percentage(count, max_count)
+
+            self._log_message(__name__, "search_name: done %s/100" % (
+                percent,))
+
+            self.percentage(percent)
+            for key in search_keys:
+                pkg_ids = repo_db.searchPackages(key, just_id = True)
+                pkgs.update((repo, x, repo_db,) for x in pkg_ids)
+
+        # now filter
+        fltlist = filters.split(';')
+        for flt in fltlist:
+            if flt == FILTER_NONE:
+                continue
+            elif flt == FILTER_INSTALLED:
+                pkgs = set([x for x in pkgs if x[0] == "__system__"])
+
+        lambda_sort = lambda x: x[2].retrieveAtom(x[1])
+
+        for repo, pkg_id, c_repo in sorted(pkgs, key = lambda_sort):
+            self._package((pkg_id, c_repo))
 
         self.percentage(100)
 
commit 568d23e682de8d8cc6c0d89f026c8476bee50204
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 22:48:16 2010 +0100

    [entropy] fix variable in backend_update_system

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index f99a8c8..01436ce 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -384,7 +384,7 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, "foo", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
 PK_BACKEND_OPTIONS (
commit ec3fb2a5971b687b693874f41b8d947a19584adf
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 22:38:54 2010 +0100

    [portage] fix variable in backend_update_system

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index e507896..e2ae201 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -391,7 +391,7 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, "foo", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
 PK_BACKEND_OPTIONS (
commit 7a5d0aa0d478592b11d2d4cf1a4920493e1ad77e
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 22:34:38 2010 +0100

    [entropy] make Entropy backend back working, port to HEAD

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 2f38c19..f99a8c8 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -266,52 +266,60 @@ backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-details", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
- * backend_search_file:
+ * backend_search_files:
  */
 static void
-backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-file", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
- * pk_backend_search_group:
+ * pk_backend_search_groups:
  */
 static void
-backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 { 
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-group", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
- * backend_search_name:
+ * backend_search_names:
  */
 static void
-backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-name", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
@@ -376,7 +384,7 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, "foo", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
 PK_BACKEND_OPTIONS (
@@ -410,9 +418,9 @@ PK_BACKEND_OPTIONS (
 	backend_resolve,			/* resolve */
 	NULL,					/* rollback */
 	backend_search_details,			/* search_details */
-	backend_search_file,			/* search_file */
-	backend_search_group,			/* search_group */
-	backend_search_name,			/* search_name */
+	backend_search_files,			/* search_file */
+	backend_search_groups,			/* search_group */
+	backend_search_names,			/* search_name */
 	backend_update_packages,		/* update_packages */
 	backend_update_system,			/* update_system */
 	NULL,					/* what_provides */
commit 3b67ae7abc22da1c7511f1851e4ebc37c05fdb05
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 22:24:48 2010 +0100

    [portage] port portage backend to PackageKit HEAD

diff --git a/backends/portage/pk-backend-portage.c b/backends/portage/pk-backend-portage.c
index d8291ba..e507896 100644
--- a/backends/portage/pk-backend-portage.c
+++ b/backends/portage/pk-backend-portage.c
@@ -273,52 +273,60 @@ backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-details", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
- * backend_search_file:
+ * backend_search_files:
  */
 static void
-backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_files (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-file", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
- * pk_backend_search_group:
+ * pk_backend_search_groups:
  */
 static void
-backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_groups (PkBackend *backend, PkBitfield filters, gchar **values)
 { 
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-group", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
- * backend_search_name:
+ * backend_search_names:
  */
 static void
-backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
+backend_search_names (PkBackend *backend, PkBitfield filters, gchar **values)
 {
 	gchar *filters_text;
-
+	gchar *search;
 	filters_text = pk_filter_bitfield_to_string (filters);
+	search = g_strjoinv ("&", values);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-name", filters_text, search, NULL);
 	g_free (filters_text);
+	g_free (search);
 }
 
 /**
@@ -383,7 +391,7 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, "foo", "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
 PK_BACKEND_OPTIONS (
@@ -417,9 +425,9 @@ PK_BACKEND_OPTIONS (
 	backend_resolve,			/* resolve */
 	NULL,					/* rollback */
 	backend_search_details,			/* search_details */
-	backend_search_file,			/* search_file */
-	backend_search_group,			/* search_group */
-	backend_search_name,			/* search_name */
+	backend_search_files,			/* search_file */
+	backend_search_groups,			/* search_group */
+	backend_search_names,			/* search_name */
 	backend_update_packages,		/* update_packages */
 	backend_update_system,			/* update_system */
 	NULL,					/* what_provides */
commit e30680d68f6865dec55ed29037a88097f8cc79b1
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 20:51:24 2010 +0100

    [entropy] make backend C part working with PackageKit HEAD

diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
index 26e0e10..2f38c19 100644
--- a/backends/entropy/pk-backend-entropy.c
+++ b/backends/entropy/pk-backend-entropy.c
@@ -16,7 +16,7 @@
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <pk-backend.h>
@@ -135,9 +135,9 @@ backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids
 	gchar *filters_text;
 	gchar *package_ids_temp;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids);
-	filters_text = pk_filter_bitfield_to_text (filters);
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-depends", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	filters_text = pk_filter_bitfield_to_string (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-depends", filters_text, package_ids_temp, pk_backend_bool_to_string (recursive), NULL);
 	g_free (package_ids_temp);
 	g_free (filters_text);
 }
@@ -150,7 +150,7 @@ backend_get_details (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-details", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -163,7 +163,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-files", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -176,7 +176,7 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
 {
 	gchar *package_ids_temp;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-update-detail", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -189,7 +189,7 @@ backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-updates", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -202,16 +202,9 @@ backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **pac
 {
 	gchar *package_ids_temp;
 
-	/*
-	 * TODO: portage manage to install when offline
-	 * but maybe packagekit implementation will make this forbidden
-	 * (because of download funcion dir)
-	 * If needed, add something that will check for network _NOW_ (see yum)
-	 */
-
 	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids);
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "install-packages", pk_backend_bool_to_text (only_trusted), package_ids_temp, NULL);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "install-packages", pk_backend_bool_to_string (only_trusted), package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
 
@@ -228,7 +221,7 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
 		return;
 	}
 
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "refresh-cache", pk_backend_bool_to_text (force), NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "refresh-cache", pk_backend_bool_to_string (force), NULL);
 }
 
 /**
@@ -239,8 +232,8 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 {
 	gchar *package_ids_temp;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids);
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "remove-packages", pk_backend_bool_to_text (allow_deps), pk_backend_bool_to_text (autoremove), package_ids_temp, NULL);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "remove-packages", pk_backend_bool_to_string (allow_deps), pk_backend_bool_to_string (autoremove), package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
 
@@ -250,7 +243,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 static void
 backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
 {
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "repo-enable", rid, pk_backend_bool_to_text (enabled), NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "repo-enable", rid, pk_backend_bool_to_string (enabled), NULL);
 }
 
 /**
@@ -262,8 +255,8 @@ backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 	gchar *filters_text;
 	gchar *package_ids_temp;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
-	package_ids_temp = pk_package_ids_to_text (package_ids);
+	filters_text = pk_filter_bitfield_to_string (filters);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "resolve", filters_text, package_ids_temp, NULL);
 	g_free (package_ids_temp);
 	g_free (filters_text);
@@ -277,7 +270,7 @@ backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *sea
 {
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-details", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -290,7 +283,7 @@ backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search
 {
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-file", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -303,7 +296,7 @@ backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *searc
 { 
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-group", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -316,7 +309,7 @@ backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search
 {
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-name", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -330,7 +323,7 @@ backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **pack
 	gchar *package_ids_temp;
 
 	/* send the complete list as stdin */
-	package_ids_temp = pk_package_ids_to_text (package_ids);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-packages", package_ids_temp, NULL);
 	g_free (package_ids_temp);
 }
@@ -343,7 +336,7 @@ backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-packages", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -356,7 +349,7 @@ backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
 
-	filters_text = pk_filter_bitfield_to_text (filters);
+	filters_text = pk_filter_bitfield_to_string (filters);
 	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-repo-list", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -370,9 +363,9 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 	gchar *package_ids_temp;
 	gchar *filters_text;
 
-	package_ids_temp = pk_package_ids_to_text (package_ids);
-	filters_text = pk_filter_bitfield_to_text (filters);
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-requires", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
+	package_ids_temp = pk_package_ids_to_string (package_ids);
+	filters_text = pk_filter_bitfield_to_string (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-requires", filters_text, package_ids_temp, pk_backend_bool_to_string (recursive), NULL);
 	g_free (filters_text);
 	g_free (package_ids_temp);
 }
@@ -383,7 +376,7 @@ backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_id
 static void
 backend_update_system (PkBackend *backend, gboolean only_trusted)
 {
-	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_text (only_trusted), NULL);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_string (only_trusted), NULL);
 }
 
 PK_BACKEND_OPTIONS (
commit aba7b6b775eaa3e8d80416c93725624602a6e0f6
Author: Fabio Erculiani <fabio.erculiani at itsme.it>
Date:   Sat Jan 30 20:25:13 2010 +0100

    [entropy] initial commit, add build system support and basic (non-working) backend

diff --git a/backends/Makefile.am b/backends/Makefile.am
index 63d33e1..7e0439a 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -24,6 +24,10 @@ if BACKEND_TYPE_DUMMY
 SUBDIRS += dummy
 endif
 
+if BACKEND_TYPE_ENTROPY
+SUBDIRS += entropy
+endif
+
 if BACKEND_TYPE_OPKG
 SUBDIRS += opkg
 endif
diff --git a/backends/entropy/Makefile.am b/backends/entropy/Makefile.am
new file mode 100644
index 0000000..2078c4e
--- /dev/null
+++ b/backends/entropy/Makefile.am
@@ -0,0 +1,16 @@
+helperdir = $(datadir)/PackageKit/helpers/entropy
+dist_helper_DATA = entropyBackend.py
+
+plugindir = $(PK_PLUGIN_DIR)
+plugin_LTLIBRARIES = libpk_backend_entropy.la
+libpk_backend_entropy_la_SOURCES = pk-backend-entropy.c
+libpk_backend_entropy_la_LIBADD = $(PK_PLUGIN_LIBS)
+libpk_backend_entropy_la_LDFLAGS = -module -avoid-version
+libpk_backend_entropy_la_CFLAGS = $(PK_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
+
+install-data-hook:
+	chmod a+rx $(DESTDIR)$(helperdir)/*.py
+
+clean-local :
+	rm -f *~
+	rm -f *.pyc
diff --git a/backends/entropy/entropyBackend.py b/backends/entropy/entropyBackend.py
new file mode 100755
index 0000000..913f908
--- /dev/null
+++ b/backends/entropy/entropyBackend.py
@@ -0,0 +1,1572 @@
+#!/usr/bin/python2
+#
+#
+# Copyright (C) 2009 Mounir Lamouri (volkmar) <mounir.lamouri at gmail.com>
+# Copyright (C) 2010 Fabio Erculiani (lxnay) <lxnay at sabayon.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.
+#
+# 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.
+
+import sys
+import signal
+
+from packagekit.backend import *
+from packagekit.progress import *
+from packagekit.package import PackagekitPackage
+
+sys.path.insert(0, '/usr/lib/entropy/libraries')
+
+from entropy.const import etpConst
+import entropy.tools
+from entropy.client.interfaces import Client
+from entropy.core.settings.base import SystemSettings
+
+# TODO:
+# remove percentage(None) if percentage is used
+# protection against signal when installing/removing
+
+class PackageKitEntropyBackend(PackageKitBaseBackend):
+
+    def __sigquit(self, signum, frame):
+        if hasattr(self, '_entropy'):
+            self._entropy.destroy()
+        raise SystemExit(1)
+
+    def __init__(self, args):
+        signal.signal(signal.SIGQUIT, self.__sigquit)
+        self.__dev_null = open("/dev/null", "w")
+        self._entropy = Client()
+        self._settings = SystemSettings()
+
+        PackageKitBaseBackend.__init__(self, args)
+
+        # TODO: should be removed when using non-verbose function API
+        self.orig_out = None
+        self.orig_err = None
+
+    def _is_repository_enabled(self, repo_name):
+        repo_data = self._settings['repositories']
+        return repo_name in repo_data['available']
+
+    def _get_group(self, dep):
+        """
+        Return PackageKit group belonging to given dependency.
+        """
+        category = entropy.tools.dep_getcat(dep)
+        entropy_groups = self._entropy.get_package_groups()
+
+        generic_group_name = None
+        for group_key, group_data in entropy_groups.items():
+            if category in group_data['categories']:
+                generic_group_name = group_key
+                break
+
+        if generic_group_name is None:
+            return GROUP_UNKNOWN
+
+        pk_group_map = {
+            'accessibility': GROUP_ACCESSIBILITY,
+            'development': GROUP_PROGRAMMING,
+            'games': GROUP_GAMES,
+            'gnome': GROUP_DESKTOP_GNOME,
+            'kde': GROUP_DESKTOP_KDE,
+            'lxde': GROUP_DESKTOP_OTHER,
+            'multimedia': GROUP_MULTIMEDIA,
+            'networking': GROUP_NETWORK,
+            'office': GROUP_OFFICE,
+            'science': GROUP_SCIENCE,
+            'system': GROUP_SYSTEM,
+            'x11': GROUP_OTHER,
+            'xfce': GROUP_DESKTOP_XFCE,
+        }
+        return pk_group_map[generic_group_name]
+
+    # TODO: should be removed when using non-verbose function API
+    def block_output(self):
+        self.orig_out = sys.stdout
+        self.orig_err = sys.stderr
+        sys.stdout = self.__dev_null
+        sys.stderr = self.__dev_null
+
+    # TODO: should be removed when using non-verbose function API
+    def unblock_output(self):
+        sys.stdout = self.orig_out
+        sys.stderr = self.orig_err
+
+    def is_cpv_valid(self, cpv):
+        if self.is_installed(cpv):
+            # actually if is_installed return True that means cpv is in db
+            return True
+        elif self.pvar.portdb.cpv_exists(cpv):
+            return True
+
+        return False
+
+    def get_real_license_str(self, cpv, metadata):
+        # use conditionals info (w/ USE) in LICENSE and remove ||
+        ebuild_settings = self.get_ebuild_settings(cpv, metadata)
+        license = set(portage.flatten(portage.dep.use_reduce(
+            portage.dep.paren_reduce(metadata["LICENSE"]),
+            uselist=ebuild_settings.get("USE", "").split())))
+        license.discard('||')
+        license = ' '.join(license)
+
+        return license
+
+    def send_configuration_file_message(self):
+        result = list(portage.util.find_updated_config_files(
+            self.pvar.settings['ROOT'],
+            self.pvar.settings.get('CONFIG_PROTECT', '').split()))
+
+        if result:
+            message = "Some configuration files need updating."
+            message += ";You should use Gentoo's tools to update them (dispatch-conf)"
+            message += ";If you can't do that, ask your system administrator."
+            self.message(MESSAGE_CONFIG_FILES_CHANGED, message)
+
+    def get_restricted_fetch_files(self, cpv, metadata):
+        '''
+        This function checks files in SRC_URI and look if they are in DESTDIR.
+        Missing files are returned. If there is no issue, None is returned.
+        We don't care about digest but only about existance of files.
+
+        NOTES:
+        - we are assuming the package has RESTRICT='fetch'
+          be sure to call this function only in this case.
+        - we are not using fetch_check because it's not returning missing files
+          so this function is a simplist fetch_check
+        '''
+        missing_files = []
+        ebuild_settings = self.get_ebuild_settings(cpv, metadata)
+
+        files = self.pvar.portdb.getFetchMap(cpv,
+                ebuild_settings['USE'].split())
+
+        for f in files:
+            file_path = os.path.join(ebuild_settings["DISTDIR"], f)
+            if not os.access(file_path, os.F_OK):
+                missing_files.append([file_path, files[f]])
+
+        if len(missing_files) > 0:
+            return missing_files
+
+        return None
+
+    def check_fetch_restrict(self, packages_list):
+        for p in packages_list:
+            if 'fetch' in p.metadata['RESTRICT']:
+                files = self.get_restricted_fetch_files(p.cpv, p.metadata)
+                if files:
+                    message = "Package %s can't download some files." % p.cpv
+                    message += ";Please, download manually the followonig file(s):"
+                    for x in files:
+                        message += ";- %s then copy it to %s" % (' '.join(x[1]), x[0])
+                    self.error(ERROR_RESTRICTED_DOWNLOAD, message)
+
+    def elog_listener(self, settings, key, logentries, fulltext):
+        '''
+        This is a listener for elog.
+        It's called each time elog is emitting log messages (at end of process).
+        We are not using settings and fulltext but they are used by other
+        listeners so we have to keep them as arguments.
+        '''
+        message = "Messages for package %s:;" % str(key)
+        error_message = ""
+
+        # building the message
+        for phase in logentries:
+            for entries in logentries[phase]:
+                type = entries[0]
+                messages = entries[1]
+
+                # TODO: portage.elog.filtering is using upper() should we ?
+                if type == 'LOG':
+                    message += ";Information messages:"
+                elif type == 'WARN':
+                    message += ";Warning messages:"
+                elif type == 'QA':
+                    message += ";QA messages:"
+                elif type == 'ERROR':
+                    message += ";Error messages:"
+                    self._error_phase = phase
+                else:
+                    continue
+
+                for msg in messages:
+                    msg = msg.replace('\n', '')
+                    if type == 'ERROR':
+                        error_message += msg + ";"
+                    message += "; " + msg
+
+        # add the message to the stack
+        self._elog_messages.append(message)
+        self._error_message = message
+
+    def send_merge_error(self, default):
+        # EAPI-2 compliant (at least)
+        # 'other' phase is ignored except this one, every phase should be there
+        if self._error_phase in ("setup", "unpack", "prepare", "configure",
+            "nofetch", "config", "info"):
+            error_type = ERROR_PACKAGE_FAILED_TO_CONFIGURE
+        elif self._error_phase in ("compile", "test"):
+            error_type = ERROR_PACKAGE_FAILED_TO_BUILD
+        elif self._error_phase in ("install", "preinst", "postinst",
+            "package"):
+            error_type = ERROR_PACKAGE_FAILED_TO_INSTALL
+        elif self._error_phase in ("prerm", "postrm"):
+            error_type = ERROR_PACKAGE_FAILED_TO_REMOVE
+        else:
+            error_type = default
+
+        self.error(error_type, self._error_message)
+
+    def get_file_list(self, cpv):
+        cat, pv = portage.catsplit(cpv)
+        db = portage.dblink(cat, pv, self.pvar.settings['ROOT'],
+                self.pvar.settings, treetype="vartree",
+                vartree=self.pvar.vardb)
+
+        contents = db.getcontents()
+        if not contents:
+            return []
+
+        return db.getcontents().keys()
+
+    def cmp_cpv(self, cpv1, cpv2):
+        '''
+        returns 1 if cpv1 > cpv2
+        returns 0 if cpv1 = cpv2
+        returns -1 if cpv1 < cpv2
+        '''
+        return portage.pkgcmp(portage.pkgsplit(cpv1), portage.pkgsplit(cpv2))
+
+    def get_newest_cpv(self, cpv_list, installed):
+        newer = ""
+
+        # get the first cpv following the installed rule
+        for cpv in cpv_list:
+            if self.is_installed(cpv) == installed:
+                newer = cpv
+                break
+
+        if newer == "":
+            return ""
+
+        for cpv in cpv_list:
+            if self.is_installed(cpv) == installed:
+                if self.cmp_cpv(cpv, newer) == 1:
+                    newer = cpv
+
+        return newer
+
+    def get_metadata(self, cpv, keys, in_dict = False, add_cache_keys = False):
+        '''
+        This function returns required metadata.
+        If in_dict is True, metadata is returned in a dict object.
+        If add_cache_keys is True, cached keys are added to keys in parameter.
+        '''
+        if self.is_installed(cpv):
+            aux_get = self.pvar.vardb.aux_get
+            if add_cache_keys:
+                keys.extend(list(self.pvar.vardb._aux_cache_keys))
+        else:
+            aux_get = self.pvar.portdb.aux_get
+            if add_cache_keys:
+                keys.extend(list(self.pvar.portdb._aux_cache_keys))
+
+        if in_dict:
+            return dict(keys, aux_get(cpv, keys))
+        else:
+            return aux_get(cpv, keys)
+
+    def get_size(self, cpv):
+        '''
+        Returns the installed size if the package is installed.
+        Otherwise, the size of files needed to be downloaded.
+        If some required files have been downloaded,
+        only the remaining size will be considered.
+        '''
+        size = 0
+        if self.is_installed(cpv):
+            size = self.get_metadata(cpv, ["SIZE"])[0]
+            if size == '':
+                size = 0
+            else:
+                size = int(size)
+        else:
+            self
+            metadata = self.get_metadata(cpv, ["IUSE", "SLOT"], in_dict=True)
+
+            package = _emerge.Package.Package(
+                    type_name="ebuild",
+                    built=False,
+                    installed=False,
+                    root_config=self.pvar.root_config,
+                    cpv=cpv,
+                    metadata=metadata)
+
+            fetch_file = self.pvar.portdb.getfetchsizes(package[2],
+                    package.use.enabled)
+            for f in fetch_file:
+                size += fetch_file[f]
+
+        return size
+
+    def get_cpv_slotted(self, cpv_list):
+        cpv_dict = {}
+
+        for cpv in cpv_list:
+            slot = self.get_metadata(cpv, ["SLOT"])[0]
+            if slot not in cpv_dict:
+                cpv_dict[slot] = [cpv]
+            else:
+                cpv_dict[slot].append(cpv)
+
+        return cpv_dict
+
+    def filter_free(self, cpv_list, fltlist):
+        if len(cpv_list) == 0:
+            return cpv_list
+
+        def _has_validLicense(cpv):
+            metadata = self.get_metadata(cpv, ["LICENSE", "USE", "SLOT"], True)
+            return not self.pvar.settings._getMissingLicenses(cpv, metadata)
+
+        if FILTER_FREE in fltlist or FILTER_NOT_FREE in fltlist:
+            free_licenses = "@FSF-APPROVED"
+            if FILTER_FREE in fltlist:
+                licenses = "-* " + free_licenses
+            elif FILTER_NOT_FREE in fltlist:
+                licenses = "* -" + free_licenses
+            backup_license = self.pvar.settings["ACCEPT_LICENSE"]
+
+            self.pvar.settings.unlock()
+            self.pvar.settings["ACCEPT_LICENSE"] = licenses
+            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
+            self.pvar.settings.regenerate()
+
+            cpv_list = filter(_has_validLicense, cpv_list)
+
+            self.pvar.settings["ACCEPT_LICENSE"] = backup_license
+            self.pvar.settings.backup_changes("ACCEPT_LICENSE")
+            self.pvar.settings.regenerate()
+            self.pvar.settings.lock()
+
+        return cpv_list
+
+    def filter_newest(self, cpv_list, fltlist):
+        if len(cpv_list) == 0:
+            return cpv_list
+
+        if FILTER_NEWEST not in fltlist:
+            return cpv_list
+
+        if FILTER_INSTALLED in fltlist:
+            # we have one package per slot, so it's the newest
+            return cpv_list
+
+        cpv_dict = self.get_cpv_slotted(cpv_list)
+
+        # slots are sorted (dict), revert them to have newest slots first
+        slots = cpv_dict.keys()
+        slots.reverse()
+
+        # empty cpv_list, cpv are now in cpv_dict and cpv_list gonna be repop
+        cpv_list = []
+
+        for k in slots:
+            # if not_intalled on, no need to check for newest installed
+            if FILTER_NOT_INSTALLED not in fltlist:
+                newest_installed = self.get_newest_cpv(cpv_dict[k], True)
+                if newest_installed != "":
+                    cpv_list.append(newest_installed)
+            newest_available = self.get_newest_cpv(cpv_dict[k], False)
+            if newest_available != "":
+                cpv_list.append(newest_available)
+
+        return cpv_list
+
+    def get_all_cp(self, fltlist):
+        # NOTES:
+        # returns a list of cp
+        #
+        # FILTERS:
+        # - installed: ok
+        # - free: ok (should be done with cpv)
+        # - newest: ok (should be finished with cpv)
+        cp_list = []
+
+        if FILTER_INSTALLED in fltlist:
+            cp_list = self.pvar.vardb.cp_all()
+        elif FILTER_NOT_INSTALLED in fltlist:
+            cp_list = self.pvar.portdb.cp_all()
+        else:
+            # need installed packages first
+            cp_list = self.pvar.vardb.cp_all()
+            for cp in self.pvar.portdb.cp_all():
+                if cp not in cp_list:
+                    cp_list.append(cp)
+
+        return cp_list
+
+    def get_all_cpv(self, cp, fltlist, filter_newest=True):
+        # NOTES:
+        # returns a list of cpv
+        #
+        # FILTERS:
+        # - installed: ok
+        # - free: ok
+        # - newest: ok
+
+        cpv_list = []
+
+        # populate cpv_list taking care of installed filter
+        if FILTER_INSTALLED in fltlist:
+            cpv_list = self.pvar.vardb.match(cp)
+        elif FILTER_NOT_INSTALLED in fltlist:
+            for cpv in self.pvar.portdb.match(cp):
+                if not self.is_installed(cpv):
+                    cpv_list.append(cpv)
+        else:
+            cpv_list = self.pvar.vardb.match(cp)
+            for cpv in self.pvar.portdb.match(cp):
+                if cpv not in cpv_list:
+                    cpv_list.append(cpv)
+
+        # free filter
+        cpv_list = self.filter_free(cpv_list, fltlist)
+
+        # newest filter
+        if filter_newest:
+            cpv_list = self.filter_newest(cpv_list, fltlist)
+
+        return cpv_list
+
+    def _etp_to_id(self, pkg_match):
+        """
+        Transform an Entropy package match (pkg_id, EntropyRepository) into
+        PackageKit id.
+        @param pkg_match: tuple composed by package identifier and its parent
+            EntropyRepository instance
+        @type pkg_match: tuple
+        @return: PackageKit package id
+        @rtype: string
+        """
+        pkg_id, c_repo = pkg_match
+
+        pkg_key, pkg_slot, pkg_ver, pkg_tag, pkg_rev, atom = \
+            c_repo.getStrictData(pkg_id)
+
+        if pkg_tag:
+            pkg_ver += "%s%s" % (etpConst['entropytagprefix'], pkg_tag)
+            pkg_ver += "%s%s" % (etpConst['entropyslotprefix'], pkg_slot,)
+        cur_arch = etpConst['currentarch']
+        repo_name = c_repo.get_plugins_metadata().get("repo_name")
+        if repo_name is None:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                "Invalid metadata passed")
+
+        # if installed, repo should be 'installed', packagekit rule
+        if repo_name == etpConst['clientdbid']:
+            repo_name = "installed"
+
+        # openoffice-clipart;2.6.22;ppc64;fedora
+        return get_package_id(pkg_key, pkg_ver, cur_arch, repo_name)
+
+    def _id_to_etp(self, pkit_id):
+        """
+        Transform a PackageKit package id into Entropy package match.
+
+        @param pkit_id: PackageKit package id
+        @type pkit_id: string
+        @return: tuple composed by package identifier and its parent
+            EntropyRepository instance
+        @rtype: tuple
+        """
+        split_data = split_package_id(pkgid)
+        if len(ret) < 4:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                "The package id %s does not contain 4 fields" % pkgid)
+        pkg_key, pkg_ver, cur_arch, repo_name = split_data
+        pkg_ver, pkg_slot = pkg_ver.rsplit(":", 1)
+
+        if repo_name == "installed":
+            c_repo = self._entropy.installed_repository()
+        else:
+            c_repo = self._entropy.open_repository(repo_name)
+
+        atom = pkg_key + "-" + pkg_ver + etpConst['entropyslotprefix'] + \
+            pkg_slot
+        pkg_id, pkg_rc = c_repo.atomMatch(atom)
+        if pkg_rc != 0:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                "Package not found in repository")
+
+        return pkg_id, c_repo
+
+    def id_to_cpv(self, pkgid):
+        '''
+        Transform the package id (packagekit) to a cpv (portage)
+        '''
+        ret = split_package_id(pkgid)
+
+        if len(ret) < 4:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                    "The package id %s does not contain 4 fields" % pkgid)
+        if '/' not in ret[0]:
+            self.error(ERROR_PACKAGE_ID_INVALID,
+                    "The first field of the package id must contain a category")
+
+        # remove slot info from version field
+        version = ret[1].split(':')[0]
+
+        return ret[0] + "-" + version
+
+    def get_packages_required(self, cpv_input, recursive):
+        '''
+        Get a list of cpv and recursive parameter.
+        Returns the list of packages required for cpv list.
+        '''
+        packages_list = []
+
+        myopts = {}
+        myopts["--selective"] = True
+        myopts["--deep"] = True
+
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "remove")
+        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
+                self.pvar.trees, myopts, myparams, None)
+
+        # TODO: atm, using FILTER_INSTALLED because it's quicker
+        # and we don't want to manage non-installed packages
+        for cp in self.get_all_cp([FILTER_INSTALLED]):
+            for cpv in self.get_all_cpv(cp, [FILTER_INSTALLED]):
+                depgraph._dynamic_config._dep_stack.append(
+                        _emerge.Dependency.Dependency(
+                            atom=portage.dep.Atom('=' + cpv),
+                            root=self.pvar.settings["ROOT"], parent=None))
+
+        if not depgraph._complete_graph():
+            self.error(ERROR_INTERNAL_ERROR, "Error when generating depgraph")
+            return
+
+        def _add_children_to_list(packages_list, node):
+            for n in depgraph._dynamic_config.digraph.parent_nodes(node):
+                if n not in packages_list \
+                        and not isinstance(n, _emerge.SetArg.SetArg):
+                    packages_list.append(n)
+                    _add_children_to_list(packages_list, n)
+
+        for node in depgraph._dynamic_config.digraph.__iter__():
+            if isinstance(node, _emerge.SetArg.SetArg):
+                continue
+            if node.cpv in cpv_input:
+                if recursive:
+                    _add_children_to_list(packages_list, node)
+                else:
+                    for n in \
+                            depgraph._dynamic_config.digraph.parent_nodes(node):
+                        if not isinstance(n, _emerge.SetArg.SetArg):
+                            packages_list.append(n)
+
+        # remove cpv_input that may be added to the list
+        def filter_cpv_input(x): return x.cpv not in cpv_input
+        return filter(filter_cpv_input, packages_list)
+
+    def _package(self, pkg_match, info=None):
+
+        # package_id = (package_identifier, EntropyRepository)
+        pkg_id, c_repo = pkg_match
+        desc = c_repo.retrieveDescription(pkg_id)
+
+        if not info:
+            if c_repo is self._entropy.installed_repository():
+                info = INFO_INSTALLED
+            else:
+                info = INFO_AVAILABLE
+        return self.package(self._etp_to_id(pkg_match), info, desc)
+
+    def get_depends(self, filters, pkgs, recursive):
+        # TODO: use only myparams ?
+        # TODO: improve error management / info
+
+        # FILTERS:
+        # - installed: ok
+        # - free: ok
+        # - newest: ignored because only one version of a package is installed
+
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        cpv_input = []
+        cpv_list = []
+
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+            cpv_input.append('=' + cpv)
+
+        myopts = {}
+        myopts["--selective"] = True
+        myopts["--deep"] = True
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        depgraph = _emerge.depgraph.depgraph(
+                self.pvar.settings, self.pvar.trees, myopts, myparams, None)
+        retval, fav = depgraph.select_files(cpv_input)
+
+        if not retval:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Wasn't able to get dependency graph")
+            return
+
+        def _add_children_to_list(cpv_list, node):
+            for n in depgraph._dynamic_config.digraph.child_nodes(node):
+                if n not in cpv_list:
+                    cpv_list.append(n)
+                    _add_children_to_list(cpv_list, n)
+
+        for cpv in cpv_input:
+            for r in depgraph._dynamic_config.digraph.root_nodes():
+                # TODO: remove things with @ as first char
+                # TODO: or refuse SetArgs
+                if not isinstance(r, _emerge.AtomArg.AtomArg):
+                    continue
+                if r.atom == cpv:
+                    if recursive:
+                        _add_children_to_list(cpv_list, r)
+                    else:
+                        for n in \
+                                depgraph._dynamic_config.digraph.child_nodes(r):
+                            for c in \
+                                depgraph._dynamic_config.digraph.child_nodes(n):
+                                cpv_list.append(c)
+
+        def _filter_uninstall(cpv):
+            return cpv[3] != 'uninstall'
+        def _filter_installed(cpv):
+            return cpv[0] == 'installed'
+        def _filter_not_installed(cpv):
+            return cpv[0] != 'installed'
+
+        # removing packages going to be uninstalled
+        cpv_list = filter(_filter_uninstall, cpv_list)
+
+        # install filter
+        if FILTER_INSTALLED in fltlist:
+            cpv_list = filter(_filter_installed, cpv_list)
+        if FILTER_NOT_INSTALLED in fltlist:
+            cpv_list = filter(_filter_not_installed, cpv_list)
+
+        # now we can change cpv_list to a real cpv list
+        tmp_list = cpv_list[:]
+        cpv_list = []
+        for x in tmp_list:
+            cpv_list.append(x[2])
+        del tmp_list
+
+        # free filter
+        cpv_list = self.filter_free(cpv_list, fltlist)
+
+        for cpv in cpv_list:
+            # prevent showing input packages
+            if '=' + cpv not in cpv_input:
+                self._package(cpv)
+
+    def get_details(self, pkgs):
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        nb_pkg = float(len(pkgs))
+        pkg_processed = 0.0
+
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            metadata = self.get_metadata(cpv,
+                    ["DESCRIPTION", "HOMEPAGE", "IUSE", "LICENSE", "SLOT"],
+                    in_dict=True)
+            license = self.get_real_license_str(cpv, metadata)
+
+            self.details(self._etp_to_id(cpv), license, self._get_group(cpv),
+                    metadata["DESCRIPTION"], metadata["HOMEPAGE"],
+                    self.get_size(cpv))
+
+            pkg_processed += 100.0
+            self.percentage(int(pkg_processed/nb_pkg))
+
+        self.percentage(100)
+
+    def get_files(self, pkgs):
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        nb_pkg = float(len(pkgs))
+        pkg_processed = 0.0
+
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            if not self.is_installed(cpv):
+                self.error(ERROR_CANNOT_GET_FILELIST,
+                        "get-files is only available for installed packages")
+                continue
+
+            files = self.get_file_list(cpv)
+            files = sorted(files)
+            files = ";".join(files)
+
+            self.files(pkg, files)
+
+            pkg_processed += 100.0
+            self.percentage(int(pkg_processed/nb_pkg))
+
+        self.percentage(100)
+
+    def get_packages(self, filters):
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self.get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        for cp in self.get_all_cp(fltlist):
+            for cpv in self.get_all_cpv(cp, fltlist):
+                self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def get_repo_list(self, filters):
+        # NOTES:
+        # use layman API
+        # returns only official and supported repositories
+        # and creates a dummy repo for portage tree
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        # get installed and available dbs
+        installed_layman_db = layman.db.DB(layman.config.Config())
+        available_layman_db = layman.db.RemoteDB(layman.config.Config())
+
+        # 'gentoo' is a dummy repo
+        self.repo_detail('gentoo', 'Gentoo Portage tree', True)
+
+        if FILTER_NOT_DEVELOPMENT not in fltlist:
+            for o in available_layman_db.overlays.keys():
+                if available_layman_db.overlays[o].is_official() \
+                        and available_layman_db.overlays[o].is_supported():
+                    self.repo_detail(o, o,
+                            self._is_repository_enabled(o))
+
+    def get_requires(self, filters, pkgs, recursive):
+        # TODO: manage non-installed package
+
+        # FILTERS:
+        # - installed: error atm, see previous TODO
+        # - free: ok
+        # - newest: ignored because only one version of a package is installed
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        cpv_input = []
+        cpv_list = []
+
+        if FILTER_NOT_INSTALLED in fltlist:
+            self.error(ERROR_CANNOT_GET_REQUIRES,
+                    "get-requires returns only installed packages at the moment")
+            return
+
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+            if not self.is_installed(cpv):
+                self.error(ERROR_CANNOT_GET_REQUIRES,
+                        "get-requires is only available for installed packages at the moment")
+                continue
+
+            cpv_input.append(cpv)
+
+        packages_list = self.get_packages_required(cpv_input, recursive)
+
+        # now we can populate cpv_list
+        cpv_list = []
+        for p in packages_list:
+            cpv_list.append(p.cpv)
+        del packages_list
+
+        # free filter
+        cpv_list = self.filter_free(cpv_list, fltlist)
+
+        for cpv in cpv_list:
+            # prevent showing input packages
+            if '=' + cpv not in cpv_input:
+                self._package(cpv)
+
+    def get_update_detail(self, pkgs):
+        # TODO: a lot of informations are missing
+
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        for pkg in pkgs:
+            updates = []
+            obsoletes = ""
+            vendor_url = ""
+            bugzilla_url = ""
+            cve_url = ""
+
+            cpv = self._id_to_etp(pkg)
+
+            if not self.pvar.portdb.cpv_exists(cpv):
+                self.message(MESSAGE_COULD_NOT_FIND_PACKAGE, "could not find %s" % pkg)
+
+            for cpv in self.pvar.vardb.match(portage.pkgsplit(cpv)[0]):
+                updates.append(cpv)
+            updates = "&".join(updates)
+
+            # temporarily set vendor_url = homepage
+            homepage = self.get_metadata(cpv, ["HOMEPAGE"])[0]
+            vendor_url = homepage
+
+            self.update_detail(pkg, updates, obsoletes, vendor_url, bugzilla_url,
+                    cve_url, "none", "No update text", "No ChangeLog",
+                    UPDATE_STATE_STABLE, None, None)
+
+    def get_updates(self, filters):
+        # NOTES:
+        # because of a lot of things related to Gentoo,
+        # only world and system packages are can be listed as updates
+        # _except_ for security updates
+
+        # UPDATE TYPES:
+        # - blocked: wait for feedbacks
+        # - low: TODO: --newuse
+        # - normal: default
+        # - important: none atm
+        # - security: from @security
+
+        # FILTERS:
+        # - installed: try to update non-installed packages and call me ;)
+        # - free: ok
+        # - newest: ok
+
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        fltlist = filters.split(';')
+
+        update_candidates = []
+        cpv_updates = {}
+        cpv_downgra = {}
+
+        # get system and world packages
+        for s in ["system", "world"]:
+            set = portage.sets.base.InternalPackageSet(
+                    initial_atoms=self.pvar.root_config.setconfig.getSetAtoms(s))
+            for atom in set:
+                update_candidates.append(atom.cp)
+
+        # check if a candidate can be updated
+        for cp in update_candidates:
+            cpv_list_inst = self.pvar.vardb.match(cp)
+            cpv_list_avai = self.pvar.portdb.match(cp)
+
+            cpv_dict_inst = self.get_cpv_slotted(cpv_list_inst)
+            cpv_dict_avai = self.get_cpv_slotted(cpv_list_avai)
+
+            dict_upda = {}
+            dict_down = {}
+
+            # candidate slots are installed slots
+            slots = cpv_dict_inst.keys()
+            slots.reverse()
+
+            for s in slots:
+                cpv_list_updates = []
+                cpv_inst = cpv_dict_inst[s][0] # only one install per slot
+
+                # the slot can be outdated (not in the tree)
+                if s not in cpv_dict_avai:
+                    break
+
+                tmp_list_avai = cpv_dict_avai[s]
+                tmp_list_avai.reverse()
+
+                for cpv in tmp_list_avai:
+                    if self.cmp_cpv(cpv_inst, cpv) == -1:
+                        cpv_list_updates.append(cpv)
+                    else: # because the list is sorted
+                        break
+
+                # no update for this slot
+                if len(cpv_list_updates) == 0:
+                    if [cpv_inst] == self.pvar.portdb.visible([cpv_inst]):
+                        break # really no update
+                    else:
+                        # that's actually a downgrade or even worst
+                        if len(tmp_list_avai) == 0:
+                            break # this package is not known in the tree...
+                        else:
+                            dict_down[s] = [tmp_list_avai.pop()]
+
+                cpv_list_updates = self.filter_free(cpv_list_updates, fltlist)
+
+                if len(cpv_list_updates) == 0:
+                    break
+
+                if FILTER_NEWEST in fltlist:
+                    best_cpv = portage.best(cpv_list_updates)
+                    cpv_list_updates = [best_cpv]
+
+                dict_upda[s] = cpv_list_updates
+
+            if len(dict_upda) != 0:
+                cpv_updates[cp] = dict_upda
+            if len(dict_down) != 0:
+                cpv_downgra[cp] = dict_down
+
+        # get security updates
+        for atom in portage.sets.base.InternalPackageSet(
+                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("security")):
+            # send update message and remove atom from cpv_updates
+            if atom.cp in cpv_updates:
+                slot = self.get_metadata(atom.cpv, ["SLOT"])[0]
+                if slot in cpv_updates[atom.cp]:
+                    tmp_cpv_list = cpv_updates[atom.cp][slot][:]
+                    for cpv in tmp_cpv_list:
+                        if self.cmp_cpv(cpv, atom.cpv) >= 0:
+                            # cpv is a security update and removed from list
+                            cpv_updates[atom.cp][slot].remove(cpv)
+                            self._package(cpv, INFO_SECURITY)
+            else: # update also non-world and non-system packages if security
+                self._package(atom.cpv, INFO_SECURITY)
+
+        # downgrades
+        for cp in cpv_downgra:
+            for slot in cpv_downgra[cp]:
+                for cpv in cpv_downgra[cp][slot]:
+                    self._package(cpv, INFO_IMPORTANT)
+
+        # normal updates
+        for cp in cpv_updates:
+            for slot in cpv_updates[cp]:
+                for cpv in cpv_updates[cp][slot]:
+                    self._package(cpv, INFO_NORMAL)
+
+    def install_packages(self, only_trusted, pkgs):
+        # NOTES:
+        # can't install an already installed packages
+        # even if it happens to be needed in Gentoo but probably not this API
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        cpv_list = []
+
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            if self.is_installed(cpv):
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
+                        "Package %s is already installed" % pkg)
+                continue
+
+            cpv_list.append('=' + cpv)
+
+        # only_trusted isn't supported
+        # but better to show it after important errors
+        if only_trusted:
+            self.error(ERROR_MISSING_GPG_SIGNATURE,
+                    "Portage backend does not support GPG signature")
+            return
+
+        # creating installation depgraph
+        myopts = {}
+        favorites = []
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        self.status(STATUS_DEP_RESOLVE)
+
+        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
+                self.pvar.trees, myopts, myparams, None)
+        retval, favorites = depgraph.select_files(cpv_list)
+        if not retval:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Wasn't able to get dependency graph")
+            return
+
+        # check fetch restrict, can stop the function via error signal
+        self.check_fetch_restrict(depgraph.altlist())
+
+        self.status(STATUS_INSTALL)
+
+        # get elog messages
+        portage.elog.add_listener(self.elog_listener)
+
+        try:
+            self.block_output()
+            # compiling/installing
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
+                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
+            rval = mergetask.merge()
+        finally:
+            self.unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self.elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+        self.send_configuration_file_message()
+
+    def refresh_cache(self, force):
+        # NOTES: can't manage progress even if it could be better
+        # TODO: do not wait for exception, check timestamp
+        # TODO: message if overlay repo has changed (layman)
+        self.status(STATUS_REFRESH_CACHE)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        myopts = {'--quiet': True}
+
+        # get installed and available dbs
+        installed_layman_db = layman.db.DB(layman.config.Config())
+
+        if force:
+            timestamp_path = os.path.join(
+                    self.pvar.settings["PORTDIR"], "metadata", "timestamp.chk")
+            if os.access(timestamp_path, os.F_OK):
+                os.remove(timestamp_path)
+
+        try:
+            self.block_output()
+            for o in installed_layman_db.overlays.keys():
+                installed_layman_db.sync(o, quiet=True)
+            _emerge.actions.action_sync(self.pvar.settings, self.pvar.trees,
+                    self.pvar.mtimedb, myopts, "")
+        except:
+            self.error(ERROR_INTERNAL_ERROR, traceback.format_exc())
+        finally:
+            self.unblock_output()
+
+    def remove_packages(self, allowdep, autoremove, pkgs):
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        cpv_list = []
+        packages = []
+        required_packages = []
+        system_packages = []
+
+        # get system packages
+        set = portage.sets.base.InternalPackageSet(
+                initial_atoms=self.pvar.root_config.setconfig.getSetAtoms("system"))
+        for atom in set:
+            system_packages.append(atom.cp)
+
+        # create cpv_list
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_PACKAGE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            if not self.is_installed(cpv):
+                self.error(ERROR_PACKAGE_NOT_INSTALLED,
+                        "Package %s is not installed" % pkg)
+                continue
+
+            # stop removal if a package is in the system set
+            if portage.pkgsplit(cpv)[0] in system_packages:
+                self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
+                        "Package %s is a system package. If you really want to remove it, please use portage" % pkg)
+                continue
+
+            cpv_list.append(cpv)
+
+        # backend do not implement autoremove
+        if autoremove:
+            self.message(MESSAGE_AUTOREMOVE_IGNORED,
+                    "Portage backend do not implement autoremove option")
+
+        # get packages needing candidates for removal
+        required_packages = self.get_packages_required(cpv_list, recursive=True)
+
+        # if there are required packages, allowdep must be on
+        if required_packages and not allowdep:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Could not perform remove operation has packages are needed by other packages")
+            return
+
+        # first, we add required packages
+        for p in required_packages:
+            package = _emerge.Package.Package(
+                    type_name=p.type_name,
+                    built=p.built,
+                    installed=p.installed,
+                    root_config=p.root_config,
+                    cpv=p.cpv,
+                    metadata=p.metadata,
+                    operation='uninstall')
+            packages.append(package)
+
+        # and now, packages we want really to remove
+        for cpv in cpv_list:
+            metadata = self.get_metadata(cpv, [],
+                    in_dict=True, add_cache_keys=True)
+            package = _emerge.Package.Package(
+                    type_name="ebuild",
+                    built=True,
+                    installed=True,
+                    root_config=self.pvar.root_config,
+                    cpv=cpv,
+                    metadata=metadata,
+                    operation="uninstall")
+            packages.append(package)
+
+        # need to define favorites to remove packages from world set
+        favorites = []
+        for p in packages:
+            favorites.append('=' + p.cpv)
+
+        # get elog messages
+        portage.elog.add_listener(self.elog_listener)
+
+        # now, we can remove
+        try:
+            self.block_output()
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, mergelist=packages,
+                    myopts={}, spinner=None, favorites=favorites, digraph=None)
+            rval = mergetask.merge()
+        finally:
+            self.unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_REMOVE)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self.elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+    def repo_enable(self, repoid, enable):
+        # NOTES: use layman API >= 1.2.3
+        self.status(STATUS_INFO)
+        self.allow_cancel(True)
+        self.percentage(None)
+
+        # special case: trying to work with gentoo repo
+        if repoid == 'gentoo':
+            if not enable:
+                self.error(ERROR_CANNOT_DISABLE_REPOSITORY,
+                        "gentoo repository can't be disabled")
+            return
+
+        # get installed and available dbs
+        installed_layman_db = layman.db.DB(layman.config.Config())
+        available_layman_db = layman.db.RemoteDB(layman.config.Config())
+
+        # check now for repoid so we don't have to do it after
+        if not repoid in available_layman_db.overlays.keys():
+            self.error(ERROR_REPO_NOT_FOUND,
+                    "Repository %s was not found" % repoid)
+            return
+
+        # disabling (removing) a db
+        # if repository already disabled, ignoring
+        if not enable and self._is_repository_enabled(repoid):
+            try:
+                installed_layman_db.delete(installed_layman_db.select(repoid))
+            except Exception, e:
+                self.error(ERROR_INTERNAL_ERROR,
+                        "Failed to disable repository "+repoid+" : "+str(e))
+                return
+
+        # enabling (adding) a db
+        # if repository already enabled, ignoring
+        if enable and not self._is_repository_enabled(repoid):
+            try:
+                # TODO: clean the trick to prevent outputs from layman
+                self.block_output()
+                installed_layman_db.add(available_layman_db.select(repoid),
+                        quiet=True)
+                self.unblock_output()
+            except Exception, e:
+                self.unblock_output()
+                self.error(ERROR_INTERNAL_ERROR,
+                        "Failed to enable repository "+repoid+" : "+str(e))
+                return
+
+    def resolve(self, filters, pkgs):
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self.get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        reg_expr = []
+        for pkg in pkgs:
+            reg_expr.append("^" + re.escape(pkg) + "$")
+        reg_expr = "|".join(reg_expr)
+
+        # specifications says "be case sensitive"
+        s = re.compile(reg_expr)
+
+        for cp in cp_list:
+            if s.match(cp):
+                for cpv in self.get_all_cpv(cp, fltlist):
+                    self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def search_details(self, filters, keys):
+        # NOTES: very bad performance
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self.get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+        search_list = get_search_list(keys)
+
+        for cp in cp_list:
+            # unfortunatelly, everything is related to cpv, not cp
+            # can't filter cp
+            cpv_list = []
+
+            # newest filter can't be executed now
+            # because some cpv are going to be filtered by search conditions
+            # and newest filter could be alterated
+            for cpv in self.get_all_cpv(cp, fltlist, filter_newest=False):
+                match = True
+                metadata =  self.get_metadata(cpv,
+                        ["DESCRIPTION", "HOMEPAGE", "IUSE",
+                            "LICENSE", "repository", "SLOT"],
+                        in_dict=True)
+                # update LICENSE to correspond to system settings
+                metadata["LICENSE"] = self.get_real_license_str(cpv, metadata)
+                for s in search_list:
+                    found = False
+                    for x in metadata:
+                        if s.search(metadata[x]):
+                            found = True
+                            break
+                    if not found:
+                        match = False
+                        break
+                if match:
+                    cpv_list.append(cpv)
+
+            # newest filter
+            cpv_list = self.filter_newest(cpv_list, fltlist)
+
+            for cpv in cpv_list:
+                self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def search_file(self, filters, key):
+        # FILTERS:
+        # - ~installed is not accepted (error)
+        # - free: ok
+        # - newest: as only installed, by himself
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+
+        if FILTER_NOT_INSTALLED in fltlist:
+            self.error(ERROR_CANNOT_GET_FILELIST,
+                    "search-file isn't available with ~installed filter")
+            return
+
+        cpv_list = self.pvar.vardb.cpv_all()
+        nb_cpv = 0.0
+        cpv_processed = 0.0
+        is_full_path = True
+
+        if key[0] != "/":
+            is_full_path = False
+            key = re.escape(key)
+            searchre = re.compile("/" + key + "$", re.IGNORECASE)
+
+        # free filter
+        cpv_list = self.filter_free(cpv_list, fltlist)
+        nb_cpv = float(len(cpv_list))
+
+        for cpv in cpv_list:
+            for f in self.get_file_list(cpv):
+                if (is_full_path and key == f) \
+                or (not is_full_path and searchre.search(f)):
+                    self._package(cpv)
+                    break
+
+            cpv_processed += 100.0
+            self.percentage(int(cpv_processed/nb_cpv))
+
+        self.percentage(100)
+
+    def search_group(self, filters, group):
+        # TODO: filter unknown groups before searching ? (optimization)
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        fltlist = filters.split(';')
+        cp_list = self.get_all_cp(fltlist)
+        nb_cp = float(len(cp_list))
+        cp_processed = 0.0
+
+        for cp in cp_list:
+            if self._get_group(cp) == group:
+                for cpv in self.get_all_cpv(cp, fltlist):
+                    self._package(cpv)
+
+            cp_processed += 100.0
+            self.percentage(int(cp_processed/nb_cp))
+
+        self.percentage(100)
+
+    def search_name(self, filters, keys):
+
+        c_repo = self._entropy.installed_repository()
+
+        self.status(STATUS_QUERY)
+        self.allow_cancel(True)
+        self.percentage(0)
+
+        search_keys = keys.split()
+        #print "filters", filters, "keys", keys
+        for key in search_keys:
+            pkg_ids = c_repo.searchPackages(key, just_id = True)
+            for pkg_id in pkg_ids:
+                self._package((pkg_id, c_repo))
+
+        self.percentage(100)
+
+    def update_packages(self, only_trusted, pkgs):
+        # TODO: manage errors
+        # TODO: manage config file updates
+
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        cpv_list = []
+
+        for pkg in pkgs:
+            cpv = self._id_to_etp(pkg)
+
+            if not self.is_cpv_valid(cpv):
+                self.error(ERROR_UPDATE_NOT_FOUND,
+                        "Package %s was not found" % pkg)
+                continue
+
+            cpv_list.append('=' + cpv)
+
+        # only_trusted isn't supported
+        # but better to show it after important errors
+        if only_trusted:
+            self.error(ERROR_MISSING_GPG_SIGNATURE,
+                    "Portage backend does not support GPG signature")
+            return
+
+        # creating update depgraph
+        myopts = {}
+        favorites = []
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        self.status(STATUS_DEP_RESOLVE)
+
+        depgraph = _emerge.depgraph.depgraph(self.pvar.settings,
+                self.pvar.trees, myopts, myparams, None)
+        retval, favorites = depgraph.select_files(cpv_list)
+        if not retval:
+            self.error(ERROR_DEP_RESOLUTION_FAILED,
+                    "Wasn't able to get dependency graph")
+            return
+
+        # check fetch restrict, can stop the function via error signal
+        self.check_fetch_restrict(depgraph.altlist())
+
+        self.status(STATUS_INSTALL)
+
+        # get elog messages
+        portage.elog.add_listener(self.elog_listener)
+
+        try:
+            self.block_output()
+            # compiling/installing
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
+                    depgraph.altlist(), favorites, depgraph.schedulerGraph())
+            rval = mergetask.merge()
+        finally:
+            self.unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self.elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+        self.send_configuration_file_message()
+
+    def update_system(self, only_trusted):
+        self.status(STATUS_RUNNING)
+        self.allow_cancel(False)
+        self.percentage(None)
+
+        if only_trusted:
+            self.error(ERROR_MISSING_GPG_SIGNATURE,
+                    "Portage backend does not support GPG signature")
+            return
+
+        myopts = {}
+        myopts["--deep"] = True
+        myopts["--newuse"] = True
+        myopts["--update"] = True
+
+        myparams = _emerge.create_depgraph_params.create_depgraph_params(
+                myopts, "")
+
+        self.status(STATUS_DEP_RESOLVE)
+
+        # creating list of ebuilds needed for the system update
+        # using backtrack_depgraph to prevent errors
+        retval, depgraph, _ = _emerge.depgraph.backtrack_depgraph(
+                self.pvar.settings, self.pvar.trees, myopts, myparams, "",
+                ["@system", "@world"], None)
+        if not retval:
+            self.error(ERROR_INTERNAL_ERROR,
+                    "Wasn't able to get dependency graph")
+            return
+
+        # check fetch restrict, can stop the function via error signal
+        self.check_fetch_restrict(depgraph.altlist())
+
+        self.status(STATUS_INSTALL)
+
+        # get elog messages
+        portage.elog.add_listener(self.elog_listener)
+
+        try:
+            self.block_output()
+            # compiling/installing
+            mergetask = _emerge.Scheduler.Scheduler(self.pvar.settings,
+                    self.pvar.trees, self.pvar.mtimedb, myopts, None,
+                    depgraph.altlist(), None, depgraph.schedulerGraph())
+            rval = mergetask.merge()
+        finally:
+            self.unblock_output()
+
+        # when an error is found print error messages
+        if rval != os.EX_OK:
+            self.send_merge_error(ERROR_PACKAGE_FAILED_TO_INSTALL)
+
+        # show elog messages and clean
+        portage.elog.remove_listener(self.elog_listener)
+        for msg in self._elog_messages:
+            # TODO: use specific message ?
+            self.message(MESSAGE_UNKNOWN, msg)
+        self._elog_messages = []
+
+        self.send_configuration_file_message()
+
+def main():
+    backend = PackageKitEntropyBackend("")
+    backend.dispatcher(sys.argv[1:])
+
+if __name__ == "__main__":
+    main()
diff --git a/backends/entropy/pk-backend-entropy.c b/backends/entropy/pk-backend-entropy.c
new file mode 100644
index 0000000..26e0e10
--- /dev/null
+++ b/backends/entropy/pk-backend-entropy.c
@@ -0,0 +1,431 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Mounir Lamouri (volkmar) <mounir.lamouri 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 <pk-backend.h>
+#include <pk-backend-spawn.h>
+
+static PkBackendSpawn *spawn = 0;
+static const gchar* BACKEND_FILE = "entropyBackend.py";
+
+/**
+ * backend_initialize:
+ * This should only be run once per backend load, i.e. not every transaction
+ */
+static void
+backend_initialize (PkBackend *backend)
+{
+	egg_debug ("backend: initialize");
+	spawn = pk_backend_spawn_new ();
+	pk_backend_spawn_set_name (spawn, "entropy");
+	/* allowing sigkill as long as no one complain */
+	pk_backend_spawn_set_allow_sigkill (spawn, TRUE);
+}
+
+/**
+ * backend_destroy:
+ * This should only be run once per backend load, i.e. not every transaction
+ */
+static void
+backend_destroy (PkBackend *backend)
+{
+	egg_debug ("backend: destroy");
+	g_object_unref (spawn);
+}
+
+/**
+ * backend_get_groups:
+ */
+static PkBitfield
+backend_get_groups (PkBackend *backend)
+{
+	return pk_bitfield_from_enums (
+			PK_GROUP_ENUM_ACCESSIBILITY,
+			PK_GROUP_ENUM_ACCESSORIES,
+			PK_GROUP_ENUM_ADMIN_TOOLS,
+			PK_GROUP_ENUM_COMMUNICATION,
+			PK_GROUP_ENUM_DESKTOP_GNOME,
+			PK_GROUP_ENUM_DESKTOP_KDE,
+			PK_GROUP_ENUM_DESKTOP_OTHER,
+			PK_GROUP_ENUM_DESKTOP_XFCE,
+			//PK_GROUP_ENUM_EDUCATION,
+			PK_GROUP_ENUM_FONTS,
+			PK_GROUP_ENUM_GAMES,
+			PK_GROUP_ENUM_GRAPHICS,
+			PK_GROUP_ENUM_INTERNET,
+			PK_GROUP_ENUM_LEGACY,
+			PK_GROUP_ENUM_LOCALIZATION,
+			//PK_GROUP_ENUM_MAPS,
+			PK_GROUP_ENUM_MULTIMEDIA,
+			PK_GROUP_ENUM_NETWORK,
+			PK_GROUP_ENUM_OFFICE,
+			PK_GROUP_ENUM_OTHER,
+			PK_GROUP_ENUM_POWER_MANAGEMENT,
+			PK_GROUP_ENUM_PROGRAMMING,
+			//PK_GROUP_ENUM_PUBLISHING,
+			PK_GROUP_ENUM_REPOS,
+			PK_GROUP_ENUM_SECURITY,
+			PK_GROUP_ENUM_SERVERS,
+			PK_GROUP_ENUM_SYSTEM,
+			PK_GROUP_ENUM_VIRTUALIZATION,
+			PK_GROUP_ENUM_SCIENCE,
+			PK_GROUP_ENUM_DOCUMENTATION,
+			//PK_GROUP_ENUM_ELECTRONICS,
+			//PK_GROUP_ENUM_COLLECTIONS,
+			//PK_GROUP_ENUM_VENDOR,
+			//PK_GROUP_ENUM_NEWEST,
+			//PK_GROUP_ENUM_UNKNOWN,
+			-1);
+}
+
+/**
+ * backend_get_filters:
+ */
+static PkBitfield
+backend_get_filters (PkBackend *backend)
+{
+	return pk_bitfield_from_enums (
+			PK_FILTER_ENUM_INSTALLED,
+			PK_FILTER_ENUM_FREE,
+			PK_FILTER_ENUM_NEWEST,
+			-1);
+	/*
+	 * These filters are candidate for further add:
+	 * PK_FILTER_ENUM_GUI	(need new PROPERTIES entry)
+	 * PK_FILTER_ENUM_ARCH (need some work, see ML)
+	 * PK_FILTER_ENUM_SOURCE (need some work/support, see ML)
+	 * PK_FILTER_ENUM_COLLECTIONS (need new PROPERTIES entry)
+	 * PK_FILTER_ENUM_APPLICATION (need new PROPERTIES entry)
+	 */
+}
+
+/**
+ * backend_cancel:
+ */
+static void
+backend_cancel (PkBackend *backend)
+{
+	/* this feels bad... */
+	pk_backend_spawn_kill (spawn);
+}
+
+/**
+ * backend_get_depends:
+ */
+static void
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+{
+	gchar *filters_text;
+	gchar *package_ids_temp;
+
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-depends", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
+	g_free (package_ids_temp);
+	g_free (filters_text);
+}
+
+/**
+ * backend_get_details:
+ */
+static void
+backend_get_details (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-details", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_get_files:
+ */
+static void
+backend_get_files (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-files", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_get_update_detail:
+ */
+static void
+backend_get_update_detail (PkBackend *backend, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-update-detail", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_get_updates:
+ */
+static void
+backend_get_updates (PkBackend *backend, PkBitfield filters)
+{
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-updates", filters_text, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_install_packages:
+ */
+static void
+backend_install_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+{
+	gchar *package_ids_temp;
+
+	/*
+	 * TODO: portage manage to install when offline
+	 * but maybe packagekit implementation will make this forbidden
+	 * (because of download funcion dir)
+	 * If needed, add something that will check for network _NOW_ (see yum)
+	 */
+
+	/* send the complete list as stdin */
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "install-packages", pk_backend_bool_to_text (only_trusted), 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, BACKEND_FILE, "refresh-cache", pk_backend_bool_to_text (force), NULL);
+}
+
+/**
+ * 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, BACKEND_FILE, "remove-packages", pk_backend_bool_to_text (allow_deps), pk_backend_bool_to_text (autoremove), package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * pk_backend_repo_enable:
+ */
+static void
+backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
+{
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "repo-enable", rid, pk_backend_bool_to_text (enabled), NULL);
+}
+
+/**
+ * pk_backend_resolve:
+ */
+static void
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
+{
+	gchar *filters_text;
+	gchar *package_ids_temp;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "resolve", filters_text, package_ids_temp, NULL);
+	g_free (package_ids_temp);
+	g_free (filters_text);
+}
+
+/**
+ * pk_backend_search_details:
+ */
+static void
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
+{
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-details", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_search_file:
+ */
+static void
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
+{
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-file", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * pk_backend_search_group:
+ */
+static void
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
+{ 
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-group", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_search_name:
+ */
+static void
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
+{
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "search-name", filters_text, search, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_update_packages:
+ */
+static void
+backend_update_packages (PkBackend *backend, gboolean only_trusted, gchar **package_ids)
+{
+	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, BACKEND_FILE, "update-packages", package_ids_temp, NULL);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_get_packages:
+ */
+static void
+backend_get_packages (PkBackend *backend, PkBitfield filters)
+{
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-packages", filters_text, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * pk_backend_get_repo_list:
+ */
+static void
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
+{
+	gchar *filters_text;
+
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-repo-list", filters_text, NULL);
+	g_free (filters_text);
+}
+
+/**
+ * backend_get_requires:
+ */
+static void
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
+{ 
+	gchar *package_ids_temp;
+	gchar *filters_text;
+
+	package_ids_temp = pk_package_ids_to_text (package_ids);
+	filters_text = pk_filter_bitfield_to_text (filters);
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "get-requires", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
+	g_free (filters_text);
+	g_free (package_ids_temp);
+}
+
+/**
+ * backend_update_system:
+ */
+static void
+backend_update_system (PkBackend *backend, gboolean only_trusted)
+{
+	pk_backend_spawn_helper (spawn, BACKEND_FILE, "update-system", pk_backend_bool_to_text (only_trusted), NULL);
+}
+
+PK_BACKEND_OPTIONS (
+	"Entropy",				/* description */
+	"Fabio Erculiani (lxnay) <lxnay at sabayon.org>",	/* author */
+	backend_initialize,			/* initalize */
+	backend_destroy,			/* destroy */
+	backend_get_groups,			/* get_groups */
+	backend_get_filters,			/* get_filters */
+	NULL,					/* get_roles */
+	NULL,					/* get_mime_types */
+	backend_cancel,				/* cancel */
+	NULL,					/* download_packages */
+	NULL,					/* get_categories */
+	backend_get_depends,			/* get_depends */
+	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
+	backend_get_files,			/* get_files */
+	backend_get_packages,			/* get_packages */
+	backend_get_repo_list,			/* get_repo_list */
+	backend_get_requires,			/* 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 */
+	backend_remove_packages,		/* remove_packages */
+	backend_repo_enable,			/* repo_enable */
+	NULL,					/* repo_set_data */
+	backend_resolve,			/* resolve */
+	NULL,					/* rollback */
+	backend_search_details,			/* search_details */
+	backend_search_file,			/* search_file */
+	backend_search_group,			/* search_group */
+	backend_search_name,			/* search_name */
+	backend_update_packages,		/* update_packages */
+	backend_update_system,			/* update_system */
+	NULL,					/* what_provides */
+	NULL,					/* simulate_install_files */
+	NULL,					/* simulate_install_packages */
+	NULL,					/* simulate_remove_packages */
+	NULL					/* simulate_update_packages */
+);
+
diff --git a/configure.ac b/configure.ac
index 9f80b3c..1f648f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -541,6 +541,7 @@ AC_ARG_ENABLE(aptcc, AS_HELP_STRING([--enable-aptcc],[use the APTcc backend]),en
 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)
+AC_ARG_ENABLE(entropy, AS_HELP_STRING([--enable-entropy],[use the entropy backend]),enable_entropy=$enableval,enable_entropy=no)
 AC_ARG_ENABLE(opkg, AS_HELP_STRING([--enable-opkg],[use the OPKG backend]),enable_opkg=$enableval,enable_opkg=no)
 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)
@@ -560,6 +561,7 @@ AM_CONDITIONAL(BACKEND_TYPE_APTCC, [test x$enable_aptcc = xyes])
 AM_CONDITIONAL(BACKEND_TYPE_BOX, [test x$enable_box = xyes])
 AM_CONDITIONAL(BACKEND_TYPE_CONARY, [test x$enable_conary = xyes])
 AM_CONDITIONAL(BACKEND_TYPE_DUMMY, [test x$enable_dummy = xyes])
+AM_CONDITIONAL(BACKEND_TYPE_ENTROPY, [test x$enable_entropy = xyes])
 AM_CONDITIONAL(BACKEND_TYPE_OPKG, [test x$enable_opkg = xyes])
 AM_CONDITIONAL(BACKEND_TYPE_PISI, [test x$enable_pisi = xyes])
 AM_CONDITIONAL(BACKEND_TYPE_POLDEK, [test x$enable_poldek = xyes])
@@ -632,7 +634,7 @@ dnl ---------------------------------------------------------------------------
 AC_ARG_WITH([default_backend],
 	    AS_HELP_STRING([--with-default-backend=<option>],
 			   [Default backend to use
-                           alpm,apt,aptcc,box,conary,dummy,opkg,pisi,portage,ports,razor,slapt,smart,urpmi,yum,zypp (dummy)]))
+                           alpm,apt,aptcc,box,conary,dummy,entropy,opkg,pisi,portage,ports,razor,slapt,smart,urpmi,yum,zypp (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
@@ -659,6 +661,8 @@ if test x$with_default_backend = x; then
 		with_default_backend=urpmi
 	elif test -f /usr/bin/zypper ; then
 		with_default_backend=zypp
+	elif test -d /usr/lib/entropy ; then
+		with_default_backend=entropy
 	elif test -f /usr/bin/emerge ; then
 		with_default_backend=portage
 	elif test -f /usr/local/sbin/portupgrade ; then
@@ -810,6 +814,7 @@ backends/aptcc/Makefile
 backends/box/Makefile
 backends/conary/Makefile
 backends/dummy/Makefile
+backends/entropy/Makefile
 backends/opkg/Makefile
 backends/slapt/Makefile
 backends/smart/Makefile
@@ -884,6 +889,7 @@ echo "
         BOX backend:               ${enable_box}
         CONARY backend:            ${enable_conary}
         dummy backend:             ${enable_dummy}
+        Entropy backend:           ${enable_entropy}
         OPKG backend:              ${enable_opkg}
         Razor backend:             ${enable_razor}
         PiSi backend:              ${enable_pisi}


More information about the PackageKit-commit mailing list