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

Richard Hughes hughsient at kemper.freedesktop.org
Tue Aug 19 09:59:24 PDT 2008


 RELEASE                                          |   32 -
 TODO                                             |    4 
 backends/alpm/pk-backend-alpm.c                  |   67 +--
 backends/apt.deprecated/pk-apt-search-plain.c    |   14 
 backends/apt.deprecated/pk-apt-search-sqlite.cpp |    2 
 backends/apt.deprecated/pk-backend-apt.c         |   49 +-
 backends/apt/aptDBUSBackend.py                   |   43 +-
 backends/apt/pk-backend-apt.c                    |   70 +--
 backends/box/pk-backend-box.c                    |   53 +-
 backends/conary/helpers/conaryBackend.py         |   92 ++--
 backends/conary/helpers/install-packages.py      |    4 
 backends/conary/helpers/remove-packages.py       |    4 
 backends/conary/pk-backend-conary.c              |   43 +-
 backends/dummy/pk-backend-dummy.c                |   80 ++-
 backends/opkg/pk-backend-opkg.c                  |   41 +-
 backends/pisi/pk-backend-pisi.c                  |   89 ++--
 backends/poldek/pk-backend-poldek.c              |  131 +++---
 backends/razor/pk-backend-razor.c                |   19 
 backends/smart/pk-backend-smart.c                |   25 -
 backends/test/pk-backend-test-dbus.c             |    3 
 backends/test/pk-backend-test-fail.c             |   37 +
 backends/test/pk-backend-test-nop.c              |    1 
 backends/test/pk-backend-test-spawn.c            |    5 
 backends/test/pk-backend-test-succeed.c          |   45 +-
 backends/test/pk-backend-test-thread.c           |    9 
 backends/urpmi/pk-backend-urpmi.c                |  109 ++---
 backends/yum/helpers/yumBackend.py               |   14 
 backends/yum/pk-backend-yum.c                    |  105 ++---
 backends/yum2/helpers/yumDBUSBackend.py          |   18 
 backends/yum2/pk-backend-yum2.c                  |   77 ++-
 backends/zypp/pk-backend-zypp.cpp                |   96 ++--
 backends/zypp/zypp-utils.cpp                     |    8 
 backends/zypp/zypp-utils.h                       |    2 
 client/pk-console.c                              |   77 +--
 client/pk-generate-pack-main.c                   |    4 
 client/pk-generate-pack.c                        |    2 
 client/pk-generate-pack.h                        |    2 
 configure.ac                                     |    2 
 libpackagekit/Makefile.am                        |    5 
 libpackagekit/pk-bitfield.c                      |  470 +++++++++++++++++++++++
 libpackagekit/pk-bitfield.h                      |   51 ++
 libpackagekit/pk-client.c                        |  108 +++--
 libpackagekit/pk-client.h                        |   23 -
 libpackagekit/pk-control.c                       |   20 
 libpackagekit/pk-control.h                       |    7 
 libpackagekit/pk-enum.c                          |  463 +++-------------------
 libpackagekit/pk-enum.h                          |  308 +++++++--------
 libpackagekit/pk-self-test.c                     |    2 
 libpackagekit/pk-task-list.c                     |    2 
 python/packagekit/backend.py                     |    2 
 src/Makefile.am                                  |    5 
 src/pk-backend-dbus.c                            |   50 +-
 src/pk-backend-dbus.h                            |  144 +++----
 src/pk-backend-internal.h                        |    7 
 src/pk-backend-python.c                          |   22 -
 src/pk-backend-spawn.c                           |   18 
 src/pk-backend.c                                 |  126 ++++--
 src/pk-backend.h                                 |   35 +
 src/pk-engine.c                                  |   67 ++-
 src/pk-interface-transaction.xml                 |   68 ++-
 src/pk-transaction-db.c                          |    2 
 src/pk-transaction.c                             |  159 +++++--
 src/pk-transaction.h                             |    3 
 63 files changed, 2134 insertions(+), 1511 deletions(-)

New commits:
commit 753d930a44dc1fefd8d97924bee6d89beb347a50
Author: Ken VanDine <ken at vandine.org>
Date:   Tue Aug 19 12:10:45 2008 -0400

    update to support {install,remove}-packages

diff --git a/backends/conary/helpers/conaryBackend.py b/backends/conary/helpers/conaryBackend.py
index d6735cd..4d89cec 100644
--- a/backends/conary/helpers/conaryBackend.py
+++ b/backends/conary/helpers/conaryBackend.py
@@ -19,8 +19,11 @@ from conary.local import database
 from conary import trove
 
 from packagekit.backend import *
+from packagekit.package import *
 from conaryCallback import UpdateCallback
 
+pkpackage = PackagekitPackage()
+
 groupMap = {
     '2DGraphics'          : GROUP_GRAPHICS,
     'Accessibility'       : GROUP_ACCESSIBILITY,
@@ -147,13 +150,12 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
         version = versionObj.trailingRevision()
         arch = self._get_arch(flavor)
         data = self._freezeData(versionObj, flavor)
-        return PackageKitBaseBackend.get_package_id(self, name, version, arch,
-                                                    data)
+        return pkpackage.get_package_id(name, version, arch, data)
 
     @ExceptionHandler
     def get_package_from_id(self, id):
         name, verString, archString, data = \
-            PackageKitBaseBackend.get_package_from_id(self, id)
+            pkpackage.get_package_from_id(id)
 
         version, flavor = self._thawData(data)
 
@@ -363,6 +365,22 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
         updJob, suggMap = self._do_update(applyList)
 
     @ExceptionHandler
+    def update_packages(self, packages):
+        '''
+        Implement the {backend}-update functionality
+        '''
+        self.allow_cancel(True);
+        self.percentage(0)
+        self.status(STATUS_RUNNING)
+
+        for package in packages.split("|"):
+            name, version, flavor, installed = self._findPackage(package)
+            if name:
+                self._do_package_update(name, version, flavor)
+            else:
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'No available updates')
+
+    @ExceptionHandler
     def refresh_cache(self):
         self.percentage()
         self.status(STATUS_REFRESH_CACHE)
@@ -383,53 +401,53 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
             if name:
                 self._do_package_update(name, version, flavor)
             else:
-                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                    'No available updates')
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'No available updates')
 
     @ExceptionHandler
-    def install(self, package_id):
+    def install_packages(self, package_ids):
         '''
-        Implement the {backend}-install functionality
+        Implement the {backend}-install-packages functionality
         '''
-        name, version, flavor, installed = self._findPackage(package_id)
+        for package_id in package_ids.split():
+            name, version, flavor, installed = self._findPackage(package_id)
 
-        self.allow_cancel(True)
-        self.percentage(0)
-        self.status(STATUS_INSTALL)
+            self.allow_cancel(True)
+            self.percentage(0)
+            self.status(STATUS_RUNNING)
 
-        if name:
-            if installed == INFO_INSTALLED:
-                self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                    'Package already installed')
+            if name:
+                if installed == INFO_INSTALLED:
+                    self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
+                        'Package already installed')
 
-            self.status(STATUS_INSTALL)
-            self._get_package_update(name, version, flavor)
-            self._do_package_update(name, version, flavor)
-        else:
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                'Package was not found')
+                self.status(INFO_INSTALLING)
+                self._get_package_update(name, version, flavor)
+                self._do_package_update(name, version, flavor)
+            else:
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'Package was not found')
 
     @ExceptionHandler
-    def remove(self, allowDeps, package_id):
+    def remove_packages(self, allowDeps, package_ids):
         '''
-        Implement the {backend}-remove functionality
+        Implement the {backend}-remove-packages functionality
         '''
-        name, version, flavor, installed = self._findPackage(package_id)
-
         self.allow_cancel(True)
+        self.percentage(0)
+        self.status(STATUS_RUNNING)
 
-        if name:
-            if not installed == INFO_INSTALLED:
-                self.error(ERROR_PACKAGE_NOT_INSTALLED,
-                    'Package not installed')
-
-            self.status(STATUS_REMOVE)
-            name = '-%s' % name
-            self._get_package_update(name, version, flavor)
-            self._do_package_update(name, version, flavor)
-        else:
-            self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
-                'Package was not found')
+        for package_id in package_ids:
+            name, version, flavor, installed = self._findPackage(package_id)
+
+            if name:
+                if not installed == INFO_INSTALLED:
+                    self.error(ERROR_PACKAGE_NOT_INSTALLED, 'The package %s is not installed' % name)
+
+                name = '-%s' % name
+                self.status(INFO_REMOVING)
+                self._get_package_update(name, version, flavor)
+                self._do_package_update(name, version, flavor)
+            else:
+                self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'The package was not found')
 
     def _get_metadata(self, id, field):
         '''
diff --git a/backends/conary/helpers/install-packages.py b/backends/conary/helpers/install-packages.py
index 338fafd..c6147dc 100755
--- a/backends/conary/helpers/install-packages.py
+++ b/backends/conary/helpers/install-packages.py
@@ -12,7 +12,7 @@
 import sys
 from conaryBackend import PackageKitConaryBackend
 
-package = sys.argv[1]
+package_ids = sys.argv[1]
 backend = PackageKitConaryBackend(sys.argv[1:])
-backend.install_packages(package)
+backend.install_packages(package_ids)
 sys.exit(0)
diff --git a/backends/conary/helpers/remove-packages.py b/backends/conary/helpers/remove-packages.py
index ada7c41..fce9c68 100755
--- a/backends/conary/helpers/remove-packages.py
+++ b/backends/conary/helpers/remove-packages.py
@@ -13,7 +13,7 @@ import sys
 from conaryBackend import PackageKitConaryBackend
 
 allowDeps = sys.argv[1]
-package = sys.argv[2]
+package_ids = sys.argv[2:]
 backend = PackageKitConaryBackend(sys.argv[1:])
-backend.remove_packages(allowDeps, package)
+backend.remove_packages(allowDeps, package_ids)
 sys.exit(0)
commit dce415d8991ebe55e94f76ea48adad9c7557f12f
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Aug 19 16:59:24 2008 +0100

    Make PkMessages into proper enumerated types with localised descriptions

diff --git a/TODO b/TODO
index 11bb2d9..7d56c6c 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,3 @@
-*** Timeframe: 0.2.x ***
-
-* Make PkMessages into proper enumerated types with localised descriptions
-
 *** Timeframe: 0.3.x ***
 
 * Enable GetUpdateDetail to handle arrays for 'updates' and 'obsoletes'
diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index a4fad01..f7f643a 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -214,7 +214,7 @@ class PackageKitInstallProgress(apt.progress.InstallProgress):
     def finishUpdate(self):
         pklog.debug("finishUpdate()")
         if self.conffile_prompts:
-            self._backend.Message(MESSAGE_NOTICE, "The following conffile prompts were found and need investiagtion: %s" % "\n".join(self.conffile_prompts))
+            self._backend.Message(MESSAGE_CONFIG_FILES_CHANGED, "The following conffile prompts were found and need investiagtion: %s" % "\n".join(self.conffile_prompts))
 
 def sigquit(signum, frame):
     pklog.error("Was killed")
diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index d251711..8db89c9 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -1643,7 +1643,7 @@ poldek_backend_log (void *data, int pri, char *message)
 		pberror->vfffmsg = g_strdup (message);
 
 		// 'vfff: unable to connect to ftp.pld-linux.org:21: Connection refused'
-		pk_backend_message (backend, PK_MESSAGE_ENUM_WARNING, "%s", message);
+		pk_backend_message (backend, PK_MESSAGE_ENUM_CONNECTION_REFUSED, "%s", message);
 	} else {
 		if (pri & LOGERR) {
 			g_string_append_printf (pberror->tslog, "error: %s", message);
diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 0d832c3..9905761 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -390,7 +390,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
 
             # if we couldn't map package_id -> pkg
             if len(packs) == 0:
-                self.message(MESSAGE_WARNING,"Could not find a match for package %s" % package)
+                self.message(MESSAGE_COULD_NOT_FIND_PACKAGE,"Could not find a match for package %s" % package)
                 continue
 
             # should have only one...
@@ -833,7 +833,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             if pkg and not inst:
                 repo = self.yumbase.repos.getRepo(pkg.repoid)
                 if not already_warned and not repo.gpgcheck:
-                    self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
+                    self.message(MESSAGE_UNTRUSTED_PACKAGE,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
                     already_warned = True
                 txmbr = self.yumbase.install(po=pkg)
                 txmbrs.extend(txmbr)
@@ -849,7 +849,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         if pkgs:
             newest = pkgs[0]
             if newest.EVR > po.EVR:
-                self.message(MESSAGE_WARNING,"A newer version of %s is available online." % po.name)
+                self.message(MESSAGE_NEWER_PACKAGE_EXISTS,"A newer version of %s is available online." % po.name)
 
     def install_files(self,trusted,inst_files):
         '''
@@ -1588,7 +1588,7 @@ class PackageKitCallback(RPMBaseCallback):
                 self.base.status(self.state_actions[action])
                 self._showName(self.info_actions[action])
             except exceptions.KeyError,e:
-                self.base.message(MESSAGE_WARNING,"The constant '%s' was unknown, please report" % action)
+                self.base.message(MESSAGE_BACKEND_ERROR,"The constant '%s' was unknown, please report" % action)
             pct = self._calcTotalPct(ts_current,ts_total)
             self.base.percentage(pct)
         val = (ts_current*100L)/ts_total
diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index c7c0bfe..33707cf 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -477,7 +477,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             self.ErrorCode(ERROR_GROUP_NOT_FOUND, str(e))
             self.Finished(EXIT_FAILED)
         except yum.Errors.RepoError,e:
-            self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
+            self.Message(MESSAGE_CACHE_BEING_REBUILT, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
             self._unlock_yum()
             self.Finished(EXIT_FAILED)
@@ -534,7 +534,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                             self._show_package(pkg, INFO_AVAILABLE)
                             found[str(pkg)] = 1
         except yum.Errors.RepoError,e:
-            self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
+            self.Message(MESSAGE_CACHE_BEING_REBUILT, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
             self._unlock_yum()
             self.Finished(EXIT_FAILED)
@@ -801,7 +801,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                             self._show_package(pkg,INFO_AVAILABLE)
                             break
         except yum.Errors.RepoError,e:
-            self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
+            self.Message(MESSAGE_CACHE_BEING_REBUILT, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
             self._unlock_yum()
             self.Finished(EXIT_FAILED)
@@ -831,7 +831,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             if pkg and not inst:
                 repo = self.yumbase.repos.getRepo(pkg.repoid)
                 if not already_warned and not repo.gpgcheck:
-                    self.message(MESSAGE_WARNING,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
+                    self.message(MESSAGE_UNTRUSTED_PACKAGE,"The untrusted package %s will be installed from %s." % (pkg.name, repo))
                     already_warned = True
                 txmbr = self.yumbase.install(po=pkg)
                 txmbrs.extend(txmbr)
@@ -1106,7 +1106,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                     else:
                         self._show_package(pkg,INFO_NORMAL)
         except yum.Errors.RepoError,e:
-            self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
+            self.Message(MESSAGE_CACHE_BEING_REBUILT, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
             self._unlock_yum()
             self.Finished(EXIT_FAILED)
@@ -1163,7 +1163,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                         if showDesc:
                             self._show_package_details(pkg)
         except yum.Errors.RepoError,e:
-            self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
+            self.Message(MESSAGE_CACHE_BEING_REBUILT, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
             self._unlock_yum()
             self.Finished(EXIT_FAILED)
@@ -1453,7 +1453,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                         package_list.append((pkg,INFO_AVAILABLE))
                         seen_nevra.append(self._get_nevra(pkg))
         except yum.Errors.RepoError,e:
-            self.Message(MESSAGE_NOTICE, "The package cache is invalid and is being rebuilt.")
+            self.Message(MESSAGE_CACHE_BEING_REBUILT, "The package cache is invalid and is being rebuilt.")
             self._refresh_yum_cache()
             self._unlock_yum()
             self.Finished(EXIT_FAILED)
@@ -1609,7 +1609,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             newest = pkgs[0]
             if newest.EVR > po.EVR:
                 #TODO Add code to send a message here
-                self.Message(MESSAGE_WARNING,"Newer version of %s, exist in the repositories " % po.name)
+                self.Message(MESSAGE_NEWER_PACKAGE_EXISTS,"Newer version of %s, exist in the repositories " % po.name)
 
 
 
@@ -2174,7 +2174,7 @@ class PackageKitCallback(RPMBaseCallback):
                 self.base.StatusChanged(self.state_actions[action])
                 self._showName(self.info_actions[action])
             except exceptions.KeyError,e:
-                self.base.Message(MESSAGE_WARNING,"The constant '%s' was unknown, please report" % action)
+                self.base.Message(MESSAGE_BACKEND_ERROR,"The constant '%s' was unknown, please report" % action)
             pct = self._calcTotalPct(ts_current, ts_total)
             self.base.PercentageChanged(pct)
         val = (ts_current*100L)/ts_total
diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 3e8bcec..a5babb4 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1618,7 +1618,7 @@ backend_repo_set_data_thread (PkBackend *backend)
 			}else if (g_ascii_strcasecmp (value, "false") == 0) {
 				repo.setAutorefresh (FALSE);
 			} else {
-				pk_backend_message (backend, PK_MESSAGE_ENUM_NOTICE, "Autorefresh a repo: Enter true or false");
+				pk_backend_message (backend, PK_MESSAGE_ENUM_PARAMETER_INVALID, "Autorefresh a repo: Enter true or false");
 				bReturn = FALSE;
 			}
 
@@ -1629,14 +1629,14 @@ backend_repo_set_data_thread (PkBackend *backend)
 			gint length = strlen (value);
 
 			if (length > 2) {
-				pk_backend_message (backend, PK_MESSAGE_ENUM_NOTICE, "Priorities has to be between 1 (highest) and 99");
+				pk_backend_message (backend, PK_MESSAGE_ENUM_PRIORITY_INVALID, "Priorities has to be between 1 (highest) and 99");
 				bReturn = false;
 			} else {
 				for (gint i = 0; i < length; i++) {
 					gint tmp = g_ascii_digit_value (value[i]);
 
 					if (tmp == -1) {
-						pk_backend_message (backend, PK_MESSAGE_ENUM_NOTICE, "Priorities has to be a number between 1 (highest) and 99");
+						pk_backend_message (backend, PK_MESSAGE_ENUM_PRIORITY_INVALID, "Priorities has to be a number between 1 (highest) and 99");
 						bReturn = FALSE;
 						prio = 0;
 						break;
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 6675c87..ff7b536 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -3568,7 +3568,7 @@ pk_client_class_init (PkClientClass *klass)
 	/**
 	 * PkClient::message:
 	 * @client: the #PkClient instance that emitted the signal
-	 * @message: the PkMessageEnum type of the message, e.g. PK_MESSAGE_ENUM_WARNING
+	 * @message: the PkMessageEnum type of the message, e.g. %PK_MESSAGE_ENUM_BROKEN_MIRROR
 	 * @details: the non-localised message details
 	 *
 	 * The ::message signal is emitted when the transaction wants to tell
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index d51bb78..1a1c239 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -170,9 +170,17 @@ static PkEnumMatch enum_restart[] = {
 
 static PkEnumMatch enum_message[] = {
 	{PK_MESSAGE_ENUM_UNKNOWN,		"unknown"},	/* fall though value */
-	{PK_MESSAGE_ENUM_NOTICE,		"notice"},
-	{PK_MESSAGE_ENUM_WARNING,		"warning"},
-	{PK_MESSAGE_ENUM_DAEMON,		"daemon"},
+	{PK_MESSAGE_ENUM_BROKEN_MIRROR,		"broken-mirror"},
+	{PK_MESSAGE_ENUM_CONNECTION_REFUSED,	"connection-refused"},
+	{PK_MESSAGE_ENUM_PARAMETER_INVALID,	"parameter-invalid"},
+	{PK_MESSAGE_ENUM_PRIORITY_INVALID,	"priority-invalid"},
+	{PK_MESSAGE_ENUM_BACKEND_ERROR,		"backend-error"},
+	{PK_MESSAGE_ENUM_DAEMON_ERROR,		"daemon-error"},
+	{PK_MESSAGE_ENUM_CACHE_BEING_REBUILT,	"cache-being-rebuilt"},
+	{PK_MESSAGE_ENUM_UNTRUSTED_PACKAGE,	"untrusted-package"},
+	{PK_MESSAGE_ENUM_NEWER_PACKAGE_EXISTS,	"newer-package-exists"},
+	{PK_MESSAGE_ENUM_COULD_NOT_FIND_PACKAGE,"could-not-find-package"},
+	{PK_MESSAGE_ENUM_CONFIG_FILES_CHANGED,	"config-files-changed"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 1d04637..505c2bf 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -204,9 +204,17 @@ typedef enum {
  * What message type we need to show
  **/
 typedef enum {
-	PK_MESSAGE_ENUM_NOTICE,
-	PK_MESSAGE_ENUM_WARNING,
-	PK_MESSAGE_ENUM_DAEMON,
+	PK_MESSAGE_ENUM_BROKEN_MIRROR,
+	PK_MESSAGE_ENUM_CONNECTION_REFUSED,
+	PK_MESSAGE_ENUM_PARAMETER_INVALID,
+	PK_MESSAGE_ENUM_PRIORITY_INVALID,
+	PK_MESSAGE_ENUM_BACKEND_ERROR,
+	PK_MESSAGE_ENUM_DAEMON_ERROR,
+	PK_MESSAGE_ENUM_CACHE_BEING_REBUILT,
+	PK_MESSAGE_ENUM_UNTRUSTED_PACKAGE,
+	PK_MESSAGE_ENUM_NEWER_PACKAGE_EXISTS,
+	PK_MESSAGE_ENUM_COULD_NOT_FIND_PACKAGE,
+	PK_MESSAGE_ENUM_CONFIG_FILES_CHANGED,
 	PK_MESSAGE_ENUM_UNKNOWN
 } PkMessageEnum;
 
diff --git a/libpackagekit/pk-task-list.c b/libpackagekit/pk-task-list.c
index d374f08..1bfe59e 100644
--- a/libpackagekit/pk-task-list.c
+++ b/libpackagekit/pk-task-list.c
@@ -373,7 +373,7 @@ pk_task_list_class_init (PkTaskListClass *klass)
 	 * PkTaskList::message:
 	 * @tlist: the #PkTaskList instance that emitted the signal
 	 * @client: the #PkClient instance that caused the signal
-	 * @message: the PkMessageEnum type of the message, e.g. PK_MESSAGE_ENUM_WARNING
+	 * @message: the PkMessageEnum type of the message, e.g. %PK_MESSAGE_ENUM_BROKEN_MIRROR
 	 * @details: the non-localised message details
 	 *
 	 * The ::message signal is emitted when the transaction wants to tell
diff --git a/python/packagekit/backend.py b/python/packagekit/backend.py
index 1337d1d..f025f31 100644
--- a/python/packagekit/backend.py
+++ b/python/packagekit/backend.py
@@ -87,7 +87,7 @@ class PackageKitBaseBackend:
     def message(self,typ,msg):
         '''
         send 'message' signal
-        @param typ: MESSAGE_WARNING, MESSAGE_NOTICE, MESSAGE_DEAMON
+        @param typ: MESSAGE_BROKEN_MIRROR
         '''
         print "message\t%s\t%s" % (typ,msg)
         sys.stdout.flush()
diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index be2651c..74e7da8 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -414,7 +414,7 @@ pk_backend_dbus_startup (PkBackendDbus *backend_dbus)
 	if (!ret) {
 		pk_warning ("%s", error->message);
 		/* cannot use ErrorCode as not in transaction */
-		pk_backend_message (backend_dbus->priv->backend, PK_MESSAGE_ENUM_DAEMON, error->message);
+		pk_backend_message (backend_dbus->priv->backend, PK_MESSAGE_ENUM_DAEMON_ERROR, error->message);
 		g_error_free (error);
 		goto out;
 	}
@@ -1416,11 +1416,11 @@ pk_backend_dbus_monitor_changed_cb (PkDbusMonitor *pk_dbus_monitor, gboolean is_
 
 	if (!is_active) {
 		pk_warning ("DBUS backend disconnected");
-		pk_backend_message (backend_dbus->priv->backend, PK_MESSAGE_ENUM_DAEMON, "DBUS backend has exited");
+		pk_backend_message (backend_dbus->priv->backend, PK_MESSAGE_ENUM_DAEMON_ERROR, "DBUS backend has exited");
 		/* Init() */
 		ret = pk_backend_dbus_startup (backend_dbus);
 		if (!ret) {
-			pk_backend_message (backend_dbus->priv->backend, PK_MESSAGE_ENUM_DAEMON, "DBUS backend will not start");
+			pk_backend_message (backend_dbus->priv->backend, PK_MESSAGE_ENUM_DAEMON_ERROR, "DBUS backend will not start");
 		}
 	}
 }
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 17d6c89..4e8988d 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -120,7 +120,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		info = pk_info_enum_from_text (sections[1]);
 		if (info == PK_INFO_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Info enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -177,7 +177,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		restart = pk_restart_enum_from_text (sections[7]);
 		if (restart == PK_RESTART_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Restart enum not recognised, and hence ignored: '%s'", sections[7]);
 			ret = FALSE;
 			goto out;
@@ -230,7 +230,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		error_enum = pk_error_enum_from_text (sections[1]);
 		if (error_enum == PK_ERROR_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Error enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -254,7 +254,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		restart_enum = pk_restart_enum_from_text (sections[1]);
 		if (restart_enum == PK_RESTART_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Restart enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -268,7 +268,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		message_enum = pk_message_enum_from_text (sections[1]);
 		if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Message enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -293,7 +293,7 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 		}
 		status_enum = pk_status_enum_from_text (sections[1]);
 		if (status_enum == PK_STATUS_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Status enum not recognised, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
@@ -331,19 +331,19 @@ pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line)
 
 		sig_type = pk_sig_type_enum_from_text (sections[8]);
 		if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "Sig enum not recognised, and hence ignored: '%s'", sections[8]);
 			ret = FALSE;
 			goto out;
 		}
 		if (pk_strzero (sections[1])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "package_id blank, and hence ignored: '%s'", sections[1]);
 			ret = FALSE;
 			goto out;
 		}
 		if (pk_strzero (sections[2])) {
-			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (backend_spawn->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "repository name blank, and hence ignored: '%s'", sections[2]);
 			ret = FALSE;
 			goto out;
diff --git a/src/pk-backend.c b/src/pk-backend.c
index d5166cf..462ac81 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -758,7 +758,7 @@ pk_backend_set_percentage (PkBackend *backend, guint percentage)
 
 	/* check over */
 	if (percentage > PK_BACKEND_PERCENTAGE_INVALID) {
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "percentage value is invalid: %i", percentage);
 		return FALSE;
 	}
@@ -767,7 +767,7 @@ pk_backend_set_percentage (PkBackend *backend, guint percentage)
 	if (percentage < 100 &&
 	    backend->priv->last_percentage < 100 &&
 	    percentage < backend->priv->last_percentage) {
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "percentage value is going down to %i from %i",
 				    percentage, backend->priv->last_percentage);
 		return FALSE;
@@ -868,7 +868,7 @@ pk_backend_set_status (PkBackend *backend, PkStatusEnum status)
 	/* backends don't do this */
 	if (status == PK_STATUS_ENUM_WAIT) {
 		pk_warning ("backend tried to WAIT, only the runner should set this value");
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "backends shouldn't use STATUS_WAIT");
 		return FALSE;
 	}
@@ -876,7 +876,7 @@ pk_backend_set_status (PkBackend *backend, PkStatusEnum status)
 	/* sanity check */
 	if (status == PK_STATUS_ENUM_SETUP && backend->priv->status != PK_STATUS_ENUM_WAIT) {
 		pk_warning ("backend tried to SETUP, but should be in WAIT");
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "Tried to SETUP when not in WAIT");
 		return FALSE;
 	}
@@ -1087,7 +1087,7 @@ pk_backend_message (PkBackend *backend, PkMessageEnum message, const gchar *form
 	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
 
 	/* have we already set an error? */
-	if (backend->priv->set_error && message != PK_MESSAGE_ENUM_DAEMON) {
+	if (backend->priv->set_error && message != PK_MESSAGE_ENUM_BACKEND_ERROR) {
 		pk_warning ("already set error, cannot process");
 		return FALSE;
 	}
@@ -1366,7 +1366,7 @@ pk_backend_error_timeout_delay_cb (gpointer data)
 	/* warn the backend developer that they've done something worng
 	 * - we can't use pk_backend_message here as we have already set
 	 * backend->priv->set_error to TRUE and hence the message would be ignored */
-	message = PK_MESSAGE_ENUM_DAEMON;
+	message = PK_MESSAGE_ENUM_BACKEND_ERROR;
 	buffer = "ErrorCode() has to be followed with Finished()!";
 	pk_warning ("emit message %i, %s", message, buffer);
 	g_signal_emit (backend, signals [PK_BACKEND_MESSAGE], 0, message, buffer);
@@ -1567,14 +1567,14 @@ pk_backend_finished (PkBackend *backend)
 
 	/* are we trying to finish in init? */
 	if (backend->priv->during_initialize) {
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "You can't call pk_backend_finished in backend_initialize!");
 		return FALSE;
 	}
 
 	/* check we have not already finished */
 	if (backend->priv->finished) {
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "Backends cannot request Finished more than once!");
 		return FALSE;
 	}
@@ -1585,7 +1585,7 @@ pk_backend_finished (PkBackend *backend)
 	    (backend->priv->role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
 	     backend->priv->role == PK_ROLE_ENUM_REMOVE_PACKAGES ||
 	     backend->priv->role == PK_ROLE_ENUM_UPDATE_PACKAGES)) {
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "Backends should send a Package() for this role!");
 	}
 
@@ -1598,7 +1598,7 @@ pk_backend_finished (PkBackend *backend)
 	/* check we sent at least one status calls */
 	if (backend->priv->set_error == FALSE &&
 	    backend->priv->status == PK_STATUS_ENUM_SETUP) {
-		pk_backend_message (backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "Backends should send status <value> signals for %s!", role_text);
 		pk_warning ("GUI will remain unchanged!");
 	}
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index dda37c4..600bab1 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -419,7 +419,7 @@ pk_transaction_error_code_cb (PkBackend *backend, PkErrorCodeEnum code,
 	g_return_if_fail (transaction->priv->tid != NULL);
 
 	if (code == PK_ERROR_ENUM_UNKNOWN) {
-		pk_backend_message (transaction->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+		pk_backend_message (transaction->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 				    "backend emitted 'unknown error' rather than a specific error "
 				    "- this is a backend problem and should be fixed!");
 	}
@@ -570,7 +570,8 @@ pk_transaction_message_cb (PkBackend *backend, PkMessageEnum message, const gcha
 	g_return_if_fail (transaction->priv->tid != NULL);
 
 #ifndef PK_IS_DEVELOPER
-	if (message == PK_MESSAGE_ENUM_DAEMON) {
+	if (message == PK_MESSAGE_ENUM_BACKEND_ERROR ||
+	    message == PK_MESSAGE_ENUM_DAEMON_ERROR) {
 		pk_warning ("ignoring message: %s", details);
 		return;
 	}
@@ -603,7 +604,7 @@ pk_transaction_package_cb (PkBackend *backend, const PkPackageObj *obj, PkTransa
 	    transaction->priv->role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
 	    transaction->priv->role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
 		if (obj->info == PK_INFO_ENUM_INSTALLED) {
-			pk_backend_message (transaction->priv->backend, PK_MESSAGE_ENUM_DAEMON,
+			pk_backend_message (transaction->priv->backend, PK_MESSAGE_ENUM_BACKEND_ERROR,
 					    "backend emitted 'installed' rather than 'installing' "
 					    "- you need to do the package *before* you do the action");
 			return;
commit bc0134575b589de353d2bf15845034dc44160300
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Aug 19 14:43:16 2008 +0100

    feature: switch to using a guint64 bitfield type as we are abusing the C enum using it as a long bitfield

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 0cce539..453c2a4 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -855,28 +855,30 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
 	// TODO: Provide support for groups in alpm
-	return (PK_GROUP_ENUM_DESKTOP_GNOME |
-			PK_GROUP_ENUM_DESKTOP_KDE |
-			PK_GROUP_ENUM_DESKTOP_OTHER |
-			PK_GROUP_ENUM_DESKTOP_XFCE |
-			PK_GROUP_ENUM_MULTIMEDIA |
-			PK_GROUP_ENUM_OTHER |
-			PK_GROUP_ENUM_PROGRAMMING |
-			PK_GROUP_ENUM_PUBLISHING |
-			PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_DESKTOP_GNOME,
+		PK_GROUP_ENUM_DESKTOP_KDE,
+		PK_GROUP_ENUM_DESKTOP_OTHER,
+		PK_GROUP_ENUM_DESKTOP_XFCE,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return PK_FILTER_ENUM_INSTALLED;
+	return pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED, -1);
 }
 
 /**
@@ -892,7 +894,7 @@ backend_cancel (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, FALSE);
@@ -914,7 +916,7 @@ backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_i
 			pmpkg_t *dep_pkg;
 			gboolean found = FALSE;
 
-			if (!pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+			if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 				/* search in sync dbs */
 				alpm_list_t *db_iterator;
 				for (db_iterator = alpm_option_get_syncdbs (); found == FALSE && db_iterator; db_iterator = alpm_list_next (db_iterator)) {
@@ -932,7 +934,7 @@ backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_i
 				}
 			}
 
-			if (!pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+			if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 				pk_debug ("alpm: searching for %s in local db", alpm_dep_get_name (dep));
 
 				/* search in local db */
@@ -1044,14 +1046,14 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_packages:
  */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	alpm_list_t *result = NULL;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	gboolean search_installed = pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED);
-	gboolean search_not_installed = pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
+	gboolean search_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED);
+	gboolean search_not_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
 
 	if (!search_not_installed) {
 		// Search in local db
@@ -1077,7 +1079,7 @@ backend_get_packages (PkBackend *backend, PkFilterEnum filters)
  * backend_get_repo_list:
  */
 void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
@@ -1123,7 +1125,7 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, FALSE);
@@ -1423,7 +1425,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	alpm_list_t *result = NULL;
 
@@ -1431,8 +1433,8 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
 
 	int iterator;
 	for (iterator = 0; iterator < g_strv_length (packages); ++iterator) {
-		gboolean search_installed = pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED);
-		gboolean search_not_installed = pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
+		gboolean search_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED);
+		gboolean search_not_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
 
 		if (!search_not_installed) {
 			// Search in local db
@@ -1459,14 +1461,14 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	alpm_list_t *result = NULL;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	gboolean search_installed = pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED);
-	gboolean search_not_installed = pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
+	gboolean search_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED);
+	gboolean search_not_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
 
 	if (!search_not_installed) {
 		// Search in local db
@@ -1492,14 +1494,14 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	alpm_list_t *result = NULL;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	gboolean search_installed = pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED);
-	gboolean search_not_installed = pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
+	gboolean search_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED);
+	gboolean search_not_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
 
 	if (!search_not_installed) {
 		// Search in local db
@@ -1525,14 +1527,14 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	alpm_list_t *result = NULL;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	gboolean search_installed = pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED);
-	gboolean search_not_installed = pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
+	gboolean search_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED);
+	gboolean search_not_installed = pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED);
 
 	if (!search_not_installed) {
 		// Search in local db
diff --git a/backends/apt.deprecated/pk-apt-search-plain.c b/backends/apt.deprecated/pk-apt-search-plain.c
index 5e5b4e5..24517fe 100644
--- a/backends/apt.deprecated/pk-apt-search-plain.c
+++ b/backends/apt.deprecated/pk-apt-search-plain.c
@@ -30,7 +30,7 @@ extern PkBackendSpawn *spawn;
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
 	return (PK_GROUP_ENUM_ACCESSORIES |
@@ -47,7 +47,7 @@ backend_get_groups (PkBackend *backend)
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
 	return (PK_FILTER_ENUM_GUI |
@@ -70,10 +70,10 @@ backend_get_details (PkBackend *backend, const gchar *package_id)
  */
 
 void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-details.py", filters_texts_text, search, NULL);
 	g_free (filters_text);
 }
@@ -82,10 +82,10 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_name:
  */
 void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -94,7 +94,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_group:
  */
 void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
 	pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL);
diff --git a/backends/apt.deprecated/pk-apt-search-sqlite.cpp b/backends/apt.deprecated/pk-apt-search-sqlite.cpp
index 98bdc7f..929a288 100644
--- a/backends/apt.deprecated/pk-apt-search-sqlite.cpp
+++ b/backends/apt.deprecated/pk-apt-search-sqlite.cpp
@@ -51,7 +51,7 @@ backend_get_groups (PkBackend *backend)
 /**
  * backend_get_filters:
  */
-extern "C" PkFilterEnum
+extern "C" PkBitfield
 backend_get_filters (PkBackend *backend)
 {
 	return (PK_FILTER_ENUM_GUI |
diff --git a/backends/apt.deprecated/pk-backend-apt.c b/backends/apt.deprecated/pk-backend-apt.c
index 25ac069..6022882 100644
--- a/backends/apt.deprecated/pk-backend-apt.c
+++ b/backends/apt.deprecated/pk-backend-apt.c
@@ -59,29 +59,33 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ACCESSORIES,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_GRAPHICS,
+		PK_GROUP_ENUM_INTERNET,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		-1);
 }
 
 /**
@@ -100,10 +104,10 @@ pk_backend_bool_to_text (gboolean value)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_id, pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 }
@@ -112,10 +116,10 @@ backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_i
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -212,10 +216,10 @@ backend_update_system (PkBackend *backend)
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_id, NULL);
 	g_free (filters_text);
 }
@@ -224,10 +228,10 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL);
 	g_free (filters_text);
 }
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 19ca644..3a0e02e 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -54,46 +54,50 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (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_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_LEGACY |
-		PK_GROUP_ENUM_LOCALIZATION |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_NETWORK |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_PUBLISHING |
-		PK_GROUP_ENUM_SYSTEM |
-		PK_GROUP_ENUM_UNKNOWN);
+	return pk_bitfield_from_enums (
+		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_GAMES,
+		PK_GROUP_ENUM_GRAPHICS,
+		PK_GROUP_ENUM_INTERNET,
+		PK_GROUP_ENUM_LEGACY,
+		PK_GROUP_ENUM_LOCALIZATION,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_NETWORK,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SYSTEM,
+		PK_GROUP_ENUM_UNKNOWN,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT |
-		PK_FILTER_ENUM_SUPPORTED);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		PK_FILTER_ENUM_SUPPORTED,
+		-1);
 }
 
 /**
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_dbus_get_updates (dbus, filters);
 }
@@ -172,7 +176,7 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
  *  * pk_backend_search_details:
  *   */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_dbus_search_details (dbus, filters, search);
 }
@@ -181,7 +185,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  *  * pk_backend_search_name:
  *   */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_dbus_search_name (dbus, filters, search);
 }
@@ -190,7 +194,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  *  * pk_backend_search_group:
  *   */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *group)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *group)
 {
 	pk_backend_dbus_search_group (dbus, filters, group);
 }
@@ -209,7 +213,7 @@ backend_cancel (PkBackend *backend)
  *  * pk_backend_resolve:
  *   */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	        pk_backend_dbus_resolve (dbus, filters, package_ids);
 }
@@ -218,7 +222,7 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
  *  * pk_backend_get_packages:
  *   */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	        pk_backend_dbus_get_packages (dbus, filters);
 }
@@ -227,7 +231,7 @@ backend_get_packages (PkBackend *backend, PkFilterEnum filters)
  *  * pk_backend_get_requires:
  *   */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	        pk_backend_dbus_get_requires (dbus, filters, package_ids, recursive);
 }
@@ -236,7 +240,7 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_
  *  * pk_backend_get_depends:
  *   */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	        pk_backend_dbus_get_depends (dbus, filters, package_ids, recursive);
 }
@@ -254,7 +258,7 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
  *  * pk_backend_what_provides
  *   */
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, const gchar *search)
 {
 	        pk_backend_dbus_what_provides (dbus, filters, provides, search);
 }
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index 46854e1..5c9a282 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -103,7 +103,7 @@ add_packages_from_list (PkBackend *backend, GList *list, gboolean updates)
 static gboolean
 backend_find_packages_thread (PkBackend *backend)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *search;
 	guint mode;
 	GList *list = NULL;
@@ -116,22 +116,22 @@ backend_find_packages_thread (PkBackend *backend)
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 		filter_box = filter_box | PKG_INSTALLED;
 	}
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 		filter_box = filter_box | PKG_AVAILABLE;
 	}
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_DEVELOPMENT)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_DEVELOPMENT)) {
 		filter_box = filter_box | PKG_DEVEL;
 	}
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
 		filter_box = filter_box | PKG_NON_DEVEL;
 	}
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_GUI)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_GUI)) {
 		filter_box = filter_box | PKG_GUI;
 	}
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_GUI)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_GUI)) {
 		filter_box = filter_box | PKG_TEXT;
 	}
 	if (mode == SEARCH_TYPE_DETAILS) {
@@ -151,14 +151,14 @@ backend_find_packages_thread (PkBackend *backend)
 		add_packages_from_list (backend, list, FALSE);
 		box_db_repos_package_list_free (list);
 	} else {
-		if ((pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED) &&
-		     pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) ||
-		    (!pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED) &&
-		     !pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED))) {
+		if ((pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED) &&
+		     pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) ||
+		    (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED) &&
+		     !pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED))) {
 			list = box_db_repos_packages_search_all(db, (gchar *)search, filter_box);
-		} else if (pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+		} else if (pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 			list = box_db_repos_packages_search_installed(db, (gchar *)search, filter_box);
-		} else if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+		} else if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 			list = box_db_repos_packages_search_available(db, (gchar *)search, filter_box);
 		}
 		add_packages_from_list (backend, list, FALSE);
@@ -438,19 +438,21 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		-1);
 }
 
 /**
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_uint (backend, "type", DEPS_TYPE_DEPENDS);
 	pk_backend_thread_create (backend, backend_get_depends_requires_thread);
@@ -478,7 +480,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_uint (backend, "type", DEPS_TYPE_REQUIRES);
 	pk_backend_thread_create (backend, backend_get_depends_requires_thread);
@@ -488,7 +490,7 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_thread_create (backend, backend_get_updates_thread);
 }
@@ -547,7 +549,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_id, gboolean allow_
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package)
+backend_resolve (PkBackend *backend, PkBitfield filters, const gchar *package)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_RESOLVE);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -557,7 +559,7 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, const gchar *package)
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_DETAILS);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -567,7 +569,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_FILE);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -577,7 +579,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_NAME);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -611,7 +613,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	GList *list;
 	GList *li;
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index ee062eb..223e12c 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -53,29 +53,31 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSIBILITY |
-		PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_EDUCATION |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ACCESSIBILITY,
+		PK_GROUP_ENUM_ACCESSORIES,
+		PK_GROUP_ENUM_EDUCATION,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_GRAPHICS,
+		PK_GROUP_ENUM_INTERNET,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return PK_FILTER_ENUM_INSTALLED;
+	return pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED, -1);
 }
 
 /**
@@ -128,10 +130,10 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -218,10 +220,10 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * pk_backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -261,10 +263,10 @@ backend_update_system (PkBackend *backend)
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_ids[0], NULL);
 	g_free (filters_text);
 }
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 872b295..c9b413d 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -61,23 +61,25 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSIBILITY |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (PK_GROUP_ENUM_ACCESSIBILITY,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		-1);
 }
 
 /**
@@ -117,7 +119,7 @@ backend_cancel (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
@@ -178,7 +180,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
@@ -283,7 +285,7 @@ backend_get_updates_timeout (gpointer data)
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -461,7 +463,7 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	if (pk_strequal (packages[0], "vips-doc")) {
@@ -499,7 +501,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -513,7 +515,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -527,7 +529,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -577,7 +579,7 @@ backend_search_name_timeout (gpointer data)
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	pk_backend_set_allow_cancel (backend, TRUE);
@@ -726,7 +728,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	if (_has_service_pack) {
@@ -735,7 +737,7 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
 	}
 	pk_backend_repo_detail (backend, "fedora",
 				"Fedora - 9", _repo_enabled_fedora);
-	if (!pk_enums_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
+	if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
 		pk_backend_repo_detail (backend, "development",
 					"Fedora - Development", _repo_enabled_devel);
 	}
@@ -808,7 +810,7 @@ backend_service_pack (PkBackend *backend, const gchar *location, gboolean enable
  * backend_what_provides:
  */
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 	pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
@@ -824,7 +826,7 @@ backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum
  * backend_get_packages:
  */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 	pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 70ba9bb..694a5ed 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -43,7 +43,7 @@ enum {
 typedef struct {
 	gint search_type;
 	gchar *needle;
-	PkFilterEnum filters;
+	PkBitfield filters;
 	PkBackend *backend;
 } SearchParams;
 
@@ -264,7 +264,7 @@ pk_opkg_package_list_cb (opkg_t *opkg, opkg_package_t *pkg, void *data)
 	gchar *uid;
 	gchar *haystack;
 	gint status, match;
-	PkFilterEnum filters = params->filters;
+	PkBitfield filters = params->filters;
 
 	if (!pkg->name)
 		return;
@@ -345,7 +345,7 @@ backend_search_thread (PkBackend *backend)
 }
 
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	SearchParams *params;
 
@@ -367,7 +367,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_description:
  */
 static void
-backend_search_description (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_description (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	SearchParams *params;
 
@@ -386,7 +386,7 @@ backend_search_description (PkBackend *backend, PkFilterEnum filters, const gcha
 }
 
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	SearchParams *params;
 
@@ -519,12 +519,14 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT |
-		PK_FILTER_ENUM_GUI);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		PK_FILTER_ENUM_GUI,
+		-1);
 }
 
 
@@ -629,7 +631,7 @@ backend_get_updates_thread (PkBackend *backend)
 }
 
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -640,16 +642,18 @@ backend_get_updates (PkBackend *backend, PkFilterEnum filters)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_COMMUNICATION |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_REPOS |
-		PK_GROUP_ENUM_MAPS);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_COMMUNICATION,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_INTERNET,
+		PK_GROUP_ENUM_REPOS,
+		PK_GROUP_ENUM_MAPS,
+		-1);
 }
 
 /**
diff --git a/backends/pisi/pk-backend-pisi.c b/backends/pisi/pk-backend-pisi.c
index a71cee3..cf22342 100644
--- a/backends/pisi/pk-backend-pisi.c
+++ b/backends/pisi/pk-backend-pisi.c
@@ -52,39 +52,43 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_EDUCATION |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_INTERNET |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_SYSTEM |
-		PK_GROUP_ENUM_DESKTOP_GNOME |
-		PK_GROUP_ENUM_DESKTOP_KDE |
-		PK_GROUP_ENUM_DESKTOP_OTHER |
-		PK_GROUP_ENUM_PUBLISHING |
-		PK_GROUP_ENUM_SERVERS |
-		PK_GROUP_ENUM_FONTS |
-		PK_GROUP_ENUM_ADMIN_TOOLS |
-		PK_GROUP_ENUM_LOCALIZATION |
-		PK_GROUP_ENUM_VIRTUALIZATION |
-		PK_GROUP_ENUM_SECURITY |
-		PK_GROUP_ENUM_POWER_MANAGEMENT |
-		PK_GROUP_ENUM_UNKNOWN);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ACCESSORIES,
+		PK_GROUP_ENUM_EDUCATION,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_INTERNET,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_SYSTEM,
+		PK_GROUP_ENUM_DESKTOP_GNOME,
+		PK_GROUP_ENUM_DESKTOP_KDE,
+		PK_GROUP_ENUM_DESKTOP_OTHER,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SERVERS,
+		PK_GROUP_ENUM_FONTS,
+		PK_GROUP_ENUM_ADMIN_TOOLS,
+		PK_GROUP_ENUM_LOCALIZATION,
+		PK_GROUP_ENUM_VIRTUALIZATION,
+		PK_GROUP_ENUM_SECURITY,
+		PK_GROUP_ENUM_POWER_MANAGEMENT,
+		PK_GROUP_ENUM_UNKNOWN,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED);
+	return pk_bitfield_from_enums(
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		-1);
 }
 
 /**
@@ -113,12 +117,12 @@ backend_cancel (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+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_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 	g_free (package_ids_temp);
@@ -152,12 +156,12 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (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_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-requires.py", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 	g_free (package_ids_temp);
@@ -167,10 +171,10 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -244,10 +248,10 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-details.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -256,10 +260,10 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * pk_backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-file.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -268,10 +272,10 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * pk_backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -280,10 +284,10 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * pk_backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -323,11 +327,11 @@ backend_update_system (PkBackend *backend)
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	gchar *filters_text;
 	gchar *package_ids_temp;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
 	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_ids_temp, NULL);
 	g_free (filters_text);
@@ -338,10 +342,10 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL);
 	g_free (filters_text);
 }
diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index 123e629..d251711 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -36,7 +36,7 @@
 #include <sigint/sigint.h>
 
 static gchar* poldek_pkg_evr (const struct pkg *pkg);
-static void poldek_backend_package (PkBackend *backend, struct pkg *pkg, PkInfoEnum infoenum, PkFilterEnum filters);
+static void poldek_backend_package (PkBackend *backend, struct pkg *pkg, PkInfoEnum infoenum, PkBitfield filters);
 static long do_get_bytes_to_download (struct poldek_ts *ts, tn_array *pkgs);
 static gint do_get_files_to_download (const struct poldek_ts *ts, const gchar *mark);
 static void pb_load_packages (PkBackend *backend);
@@ -546,7 +546,7 @@ poldek_get_security_updates (void)
  *
  * Converts PLD RPM group to PkGroupEnum.
  **/
-static PkGroupEnum
+static PkBitfield
 pld_group_to_enum (const gchar *group)
 {
 	g_return_val_if_fail (group != NULL, PK_GROUP_ENUM_OTHER);
@@ -821,14 +821,14 @@ do_requires (tn_array *installed, tn_array *available, tn_array *requires,
 {
 	tn_array	*tmp = NULL;
 	gint		i;
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gboolean recursive;
 
 	tmp = n_array_new (2, NULL, NULL);
 	filters = pk_backend_get_uint (backend, "filters");
 
 	/* if ~installed doesn't exists in filters, we can query installed */
-	if (!pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+	if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 		for (i = 0; i < n_array_size (installed); i++) {
 			struct pkg      *ipkg = n_array_nth (installed, i);
 			int j;
@@ -861,7 +861,7 @@ do_requires (tn_array *installed, tn_array *available, tn_array *requires,
 			}
 		}
 	}
-	if (!pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+	if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 		for (i = 0; i < n_array_size (available); i++) {
 			struct pkg      *apkg = n_array_nth (available, i);
 			int j;
@@ -895,7 +895,7 @@ do_requires (tn_array *installed, tn_array *available, tn_array *requires,
 	}
 
 	/* FIXME: recursive takes too much time for available packages, so don't use it */
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 		recursive = pk_backend_get_bool (backend, "recursive");
 		if (recursive && tmp && n_array_size (tmp) > 0) {
 			for (i = 0; i < n_array_size (tmp); i++) {
@@ -917,7 +917,7 @@ do_depends (tn_array *installed, tn_array *available, tn_array *depends, struct
 	tn_array	*reqs = pkg->reqs;
 	tn_array	*tmp = NULL;
 	gint		i;
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gboolean recursive;
 
 	tmp = n_array_new (2, NULL, NULL);
@@ -962,7 +962,7 @@ do_depends (tn_array *installed, tn_array *available, tn_array *depends, struct
 			continue;
 
 		/* first check in installed packages */
-		if (!pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+		if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 			for (j = 0; j < n_array_size (installed); j++) {
 				struct pkg	*p = n_array_nth (installed, j);
 
@@ -979,7 +979,7 @@ do_depends (tn_array *installed, tn_array *available, tn_array *depends, struct
 			continue;
 
 		/* ... now available */
-		if (!pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+		if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 			for (j = 0; j < n_array_size (available); j++) {
 				struct pkg	*p = n_array_nth (available, j);
 
@@ -988,7 +988,7 @@ do_depends (tn_array *installed, tn_array *available, tn_array *depends, struct
 					 * don't return these, which are installed.
 					 * Can be used to tell the user which packages
 					 * will be additionaly installed. */
-					if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+					if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 						gint	ret;
 
 						ret = poldek_pkg_in_array_idx (p, installed, (tn_fn_cmp)pkg_cmp_name);
@@ -1023,7 +1023,7 @@ do_depends (tn_array *installed, tn_array *available, tn_array *depends, struct
 }
 
 static gchar*
-package_id_from_pkg (struct pkg *pkg, const gchar *repo, PkFilterEnum filters)
+package_id_from_pkg (struct pkg *pkg, const gchar *repo, PkBitfield filters)
 {
 	gchar *evr, *package_id, *poldek_dir;
 
@@ -1036,7 +1036,7 @@ package_id_from_pkg (struct pkg *pkg, const gchar *repo, PkFilterEnum filters)
 	} else {
 		/* when filters contain PK_FILTER_ENUM_NOT_INSTALLED package
 		 * can't be marked as installed */
-		if (!pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED) &&
+		if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED) &&
 		    pkg_is_installed (pkg)) {
 			poldek_dir = g_strdup ("installed");
 		} else {
@@ -1063,15 +1063,15 @@ package_id_from_pkg (struct pkg *pkg, const gchar *repo, PkFilterEnum filters)
  * poldek_backend_package:
  */
 static void
-poldek_backend_package (PkBackend *backend, struct pkg *pkg, PkInfoEnum infoenum, PkFilterEnum filters)
+poldek_backend_package (PkBackend *backend, struct pkg *pkg, PkInfoEnum infoenum, PkBitfield filters)
 {
 	struct pkguinf	*pkgu;
 	gchar		*package_id;
 
 	if (infoenum == PK_INFO_ENUM_UNKNOWN) {
-		if (pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+		if (pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 			infoenum = PK_INFO_ENUM_INSTALLED;
-		} else if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+		} else if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 			infoenum = PK_INFO_ENUM_AVAILABLE;
 		} else {
 			if (pkg_is_installed (pkg)) {
@@ -1168,7 +1168,7 @@ poldek_pkg_is_gui (struct pkg *pkg)
 static gboolean
 search_package_thread (PkBackend *backend)
 {
-	PkFilterEnum		filters;
+	PkBitfield		filters;
 	PkProvidesEnum		provides;
 	gchar			*search_cmd = NULL;
 	struct poclidek_rcmd	*cmd = NULL;
@@ -1228,7 +1228,7 @@ search_package_thread (PkBackend *backend)
 		gchar		*command;
 		tn_array	*pkgs = NULL, *installed = NULL, *available = NULL;
 
-		if (!pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+		if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
 			command = g_strdup_printf ("cd /installed; %s", search_cmd);
 			if (poclidek_rcmd_execline (cmd, command)) {
 				installed = poclidek_rcmd_get_packages (cmd);
@@ -1236,7 +1236,7 @@ search_package_thread (PkBackend *backend)
 
 			g_free (command);
 		}
-		if (!pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+		if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
 			command = g_strdup_printf ("cd /all-avail; %s", search_cmd);
 			if (poclidek_rcmd_execline (cmd, command))
 				available = poclidek_rcmd_get_packages (cmd);
@@ -1244,8 +1244,8 @@ search_package_thread (PkBackend *backend)
 			g_free (command);
 		}
 
-		if (!pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED) &&
-		    !pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED) &&
+		if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED) &&
+		    !pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED) &&
 		    installed && available) {
 			gint	i;
 
@@ -1263,14 +1263,14 @@ search_package_thread (PkBackend *backend)
 			n_array_sort_ex(pkgs, (tn_fn_cmp)pkg_cmp_name_evr_rev_recno);
 
 			n_array_free (available);
-		} else if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED) || available) {
+		} else if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED) || available) {
 			pkgs = available;
-		} else if (pk_enums_contain (filters, PK_FILTER_ENUM_INSTALLED) || installed)
+		} else if (pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED) || installed)
 			pkgs = installed;
 		if (pkgs) {
 			gint	i;
 
-			if (pk_enums_contain (filters, PK_FILTER_ENUM_NEWEST))
+			if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NEWEST))
 				do_newest (pkgs);
 
 			for (i = 0; i < n_array_size (pkgs); i++) {
@@ -1281,9 +1281,9 @@ search_package_thread (PkBackend *backend)
 
 				/* check if we have to do development filtering
 				 * (devel or ~devel in filters) */
-				if (pk_enums_contain (filters, PK_FILTER_ENUM_DEVELOPMENT) ||
-				    pk_enums_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
-					if (pk_enums_contain (filters, PK_FILTER_ENUM_DEVELOPMENT)) {
+				if (pk_bitfield_contain (filters, PK_FILTER_ENUM_DEVELOPMENT) ||
+				    pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
+					if (pk_bitfield_contain (filters, PK_FILTER_ENUM_DEVELOPMENT)) {
 						/* devel in filters */
 						if (!poldek_pkg_is_devel (pkg))
 							continue;
@@ -1296,9 +1296,9 @@ search_package_thread (PkBackend *backend)
 
 				/* check if we have to do gui filtering
 				 * (gui or ~gui in filters) */
-				if (pk_enums_contain (filters, PK_FILTER_ENUM_GUI) ||
-				    pk_enums_contain (filters, PK_FILTER_ENUM_NOT_GUI)) {
-					if (pk_enums_contain (filters, PK_FILTER_ENUM_GUI)) {
+				if (pk_bitfield_contain (filters, PK_FILTER_ENUM_GUI) ||
+				    pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_GUI)) {
+					if (pk_bitfield_contain (filters, PK_FILTER_ENUM_GUI)) {
 						/* gui in filters */
 						if (!poldek_pkg_is_gui (pkg))
 							continue;
@@ -1875,37 +1875,41 @@ backend_download_packages (PkBackend *backend, gchar **package_ids,
 /**
  * backend_get_groups:
  **/
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSORIES |
-		PK_GROUP_ENUM_ADMIN_TOOLS |
-		PK_GROUP_ENUM_COMMUNICATION |
-		PK_GROUP_ENUM_EDUCATION |
-		PK_GROUP_ENUM_FONTS |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_GRAPHICS |
-		PK_GROUP_ENUM_LOCALIZATION |
-		PK_GROUP_ENUM_MULTIMEDIA |
-		PK_GROUP_ENUM_NETWORK |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_PUBLISHING |
-		PK_GROUP_ENUM_SERVERS |
-		PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ACCESSORIES,
+		PK_GROUP_ENUM_ADMIN_TOOLS,
+		PK_GROUP_ENUM_COMMUNICATION,
+		PK_GROUP_ENUM_EDUCATION,
+		PK_GROUP_ENUM_FONTS,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_GRAPHICS,
+		PK_GROUP_ENUM_LOCALIZATION,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_NETWORK,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SERVERS,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_NEWEST |
-		PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_NEWEST,
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		-1);
 }
 
 /**
@@ -1961,7 +1965,7 @@ backend_get_depends_thread (PkBackend *backend)
 }
 
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, FALSE, TRUE);
@@ -2106,7 +2110,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_packages:
  **/
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2156,7 +2160,7 @@ backend_get_requires_thread (PkBackend *backend)
 }
 
 static void
-backend_get_requires (PkBackend	*backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend	*backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, FALSE, TRUE);
@@ -2364,7 +2368,7 @@ backend_get_updates_thread (PkBackend *backend)
 }
 
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2581,7 +2585,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2594,7 +2598,7 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2607,7 +2611,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2620,7 +2624,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2633,7 +2637,7 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
@@ -2687,7 +2691,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	tn_array	*sources = NULL;
 
@@ -2720,7 +2724,7 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
  * backend_what_provides:
  **/
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	poldek_backend_set_allow_cancel (backend, TRUE, TRUE);
diff --git a/backends/razor/pk-backend-razor.c b/backends/razor/pk-backend-razor.c
index 283e4dc..c03828c 100644
--- a/backends/razor/pk-backend-razor.c
+++ b/backends/razor/pk-backend-razor.c
@@ -80,18 +80,18 @@ pk_razor_filter_devel (const gchar *name)
 static gboolean
 pk_razor_emit_package (PkBackend *backend, const gchar *name, const gchar *version, const gchar *arch, const gchar *summary)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gchar *package_id;
 	gboolean ret;
 
 	filters = pk_backend_get_uint (backend, "filters");
 
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_DEVELOPMENT)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_DEVELOPMENT)) {
 		ret = pk_razor_filter_devel (name);
 		if (!ret)
 			return FALSE;
 	}
-	if (pk_enums_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
+	if (pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
 		ret = pk_razor_filter_devel (name);
 		if (ret)
 			return FALSE;
@@ -139,7 +139,7 @@ backend_resolve_thread (PkBackend *backend)
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -278,7 +278,7 @@ backend_get_packages_thread (PkBackend *backend)
  * backend_get_packages:
  */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -365,7 +365,7 @@ backend_search_thread (PkBackend *backend)
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -377,7 +377,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_description:
  */
 static void
-backend_search_description (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_description (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
@@ -388,10 +388,10 @@ backend_search_description (PkBackend *backend, PkFilterEnum filters, const gcha
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (PK_FILTER_ENUM_DEVELOPMENT, -1);
 }
 
 PK_BACKEND_OPTIONS (
diff --git a/backends/smart/pk-backend-smart.c b/backends/smart/pk-backend-smart.c
index b611460..c5e86fc 100644
--- a/backends/smart/pk-backend-smart.c
+++ b/backends/smart/pk-backend-smart.c
@@ -54,12 +54,12 @@ backend_destroy (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gchar *filters_text;
 	gchar *package_ids_temp;
 	/* FIXME: Use recursive and filter here */
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
 	pk_backend_spawn_helper (spawn, "get-depends.py", package_ids_temp, NULL);
 	g_free (filters_text);
@@ -94,10 +94,10 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -184,11 +184,11 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	gchar *filters_text;
 	gchar *package_ids_temp;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
 	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_ids_temp, NULL);
 	g_free (filters_text);
@@ -199,10 +199,10 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-details.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -211,10 +211,10 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * pk_backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -254,10 +254,10 @@ backend_update_system (PkBackend *backend)
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL);
 	g_free (filters_text);
 }
diff --git a/backends/test/pk-backend-test-dbus.c b/backends/test/pk-backend-test-dbus.c
index acaf5c9..a0b91c9 100644
--- a/backends/test/pk-backend-test-dbus.c
+++ b/backends/test/pk-backend-test-dbus.c
@@ -33,7 +33,7 @@ static PkBackendDbus *dbus;
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
diff --git a/backends/test/pk-backend-test-fail.c b/backends/test/pk-backend-test-fail.c
index 64e6af8..3003f9a 100644
--- a/backends/test/pk-backend-test-fail.c
+++ b/backends/test/pk-backend-test-fail.c
@@ -47,23 +47,27 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSIBILITY |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ACCESSIBILITY,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		-1);
 }
 
 /**
@@ -79,7 +83,7 @@ backend_cancel (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
@@ -106,7 +110,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
@@ -124,7 +128,7 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
@@ -169,7 +173,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
@@ -187,7 +191,7 @@ backend_rollback (PkBackend *backend, const gchar *transaction_id)
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_finished (backend);
 }
@@ -196,7 +200,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 			       "Error number 1");
@@ -209,7 +213,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_finished (backend);
 }
@@ -218,7 +222,7 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR,
 			       "Error number 1");
diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c
index 683002a..a4090f0 100644
--- a/backends/test/pk-backend-test-spawn.c
+++ b/backends/test/pk-backend-test-spawn.c
@@ -31,12 +31,12 @@ static PkBackendSpawn *spawn;
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.sh", filters_text, search, NULL);
 	g_free (filters_text);
 }
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index bd59bdf..833ef57 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -43,24 +43,28 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ACCESSIBILITY |
-		PK_GROUP_ENUM_GAMES |
-		PK_GROUP_ENUM_SYSTEM);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ACCESSIBILITY,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_SYSTEM,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT |
-		PK_FILTER_ENUM_FREE);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		PK_FILTER_ENUM_FREE,
+		-1);
 }
 
 /**
@@ -76,7 +80,7 @@ backend_cancel (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
@@ -103,7 +107,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_finished (backend);
 }
@@ -121,7 +125,7 @@ backend_get_update_detail (PkBackend *backend, gchar **package_ids)
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
@@ -176,7 +180,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	pk_backend_finished (backend);
 }
@@ -194,7 +198,7 @@ backend_rollback (PkBackend *backend, const gchar *transaction_id)
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_finished (backend);
 }
@@ -203,7 +207,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_finished (backend);
 }
@@ -212,7 +216,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_finished (backend);
 }
@@ -234,7 +238,7 @@ backend_search_name_timeout (gpointer data)
  * A really long wait........
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
 	g_timeout_add (200000, backend_search_name_timeout, backend);
@@ -262,7 +266,7 @@ backend_update_system (PkBackend *backend)
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
@@ -298,7 +302,7 @@ backend_service_pack (PkBackend *backend, const gchar *location, gboolean enable
  * backend_what_provides:
  */
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, const gchar *search)
 {
 	pk_backend_finished (backend);
 }
@@ -307,7 +311,7 @@ backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum
  * backend_get_packages:
  */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_finished (backend);
 }
diff --git a/backends/test/pk-backend-test-thread.c b/backends/test/pk-backend-test-thread.c
index 1890821..c25954c 100644
--- a/backends/test/pk-backend-test-thread.c
+++ b/backends/test/pk-backend-test-thread.c
@@ -67,7 +67,7 @@ backend_search_group_thread (PkBackend *backend)
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_thread_create (backend, backend_search_group_thread);
 }
@@ -80,14 +80,14 @@ backend_search_name_thread (PkBackend *backend)
 {
 	GTimer *timer;
 	guint percentage;
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gchar *filters_text;
 	const gchar *search;
 
 	filters = pk_backend_get_uint (backend, "filters");
 	search = pk_backend_get_string (backend, "search");
 
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_debug ("started task (%p) search=%s filters=%s", backend, search, filters_text);
 	g_free (filters_text);
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
@@ -121,7 +121,7 @@ backend_search_name_thread (PkBackend *backend)
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_thread_create (backend, backend_search_name_thread);
 }
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 581d725..0e05fc5 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -51,49 +51,53 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-  return(PK_GROUP_ENUM_UNKNOWN |
-  PK_GROUP_ENUM_ACCESSIBILITY |
-  PK_GROUP_ENUM_ACCESSORIES |
-  PK_GROUP_ENUM_EDUCATION |
-  PK_GROUP_ENUM_GAMES |
-  PK_GROUP_ENUM_GRAPHICS |
-  PK_GROUP_ENUM_INTERNET |
-  PK_GROUP_ENUM_OFFICE |
-  PK_GROUP_ENUM_OTHER |
-  PK_GROUP_ENUM_PROGRAMMING |
-  PK_GROUP_ENUM_MULTIMEDIA |
-  PK_GROUP_ENUM_SYSTEM |
-  PK_GROUP_ENUM_DESKTOP_GNOME |
-  PK_GROUP_ENUM_DESKTOP_KDE |
-  PK_GROUP_ENUM_DESKTOP_XFCE |
-  PK_GROUP_ENUM_DESKTOP_OTHER |
-  PK_GROUP_ENUM_PUBLISHING |
-  PK_GROUP_ENUM_SERVERS |
-  PK_GROUP_ENUM_FONTS |
-  PK_GROUP_ENUM_ADMIN_TOOLS |
-  PK_GROUP_ENUM_LEGACY |
-  PK_GROUP_ENUM_LOCALIZATION |
-  PK_GROUP_ENUM_VIRTUALIZATION |
-  PK_GROUP_ENUM_POWER_MANAGEMENT |
-  PK_GROUP_ENUM_SECURITY |
-  PK_GROUP_ENUM_COMMUNICATION |
-  PK_GROUP_ENUM_NETWORK |
-  PK_GROUP_ENUM_MAPS |
-  PK_GROUP_ENUM_REPOS);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_UNKNOWN,
+		PK_GROUP_ENUM_ACCESSIBILITY,
+		PK_GROUP_ENUM_ACCESSORIES,
+		PK_GROUP_ENUM_EDUCATION,
+		PK_GROUP_ENUM_GAMES,
+		PK_GROUP_ENUM_GRAPHICS,
+		PK_GROUP_ENUM_INTERNET,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_SYSTEM,
+		PK_GROUP_ENUM_DESKTOP_GNOME,
+		PK_GROUP_ENUM_DESKTOP_KDE,
+		PK_GROUP_ENUM_DESKTOP_XFCE,
+		PK_GROUP_ENUM_DESKTOP_OTHER,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SERVERS,
+		PK_GROUP_ENUM_FONTS,
+		PK_GROUP_ENUM_ADMIN_TOOLS,
+		PK_GROUP_ENUM_LEGACY,
+		PK_GROUP_ENUM_LOCALIZATION,
+		PK_GROUP_ENUM_VIRTUALIZATION,
+		PK_GROUP_ENUM_POWER_MANAGEMENT,
+		PK_GROUP_ENUM_SECURITY,
+		PK_GROUP_ENUM_COMMUNICATION,
+		PK_GROUP_ENUM_NETWORK,
+		PK_GROUP_ENUM_MAPS,
+		PK_GROUP_ENUM_REPOS,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		-1);
 }
 
 /**
@@ -113,10 +117,10 @@ pk_backend_bool_to_text (gboolean value)
  * pk_backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.pl", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -143,10 +147,10 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-depends.pl", filters_text, package_ids[0], pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 }
@@ -155,10 +159,10 @@ backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_i
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-updates.pl", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -227,10 +231,10 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * pk_backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-group.pl", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -239,10 +243,10 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * backend_get_packages:
  */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-packages.pl", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -251,10 +255,10 @@ backend_get_packages (PkBackend *backend, PkFilterEnum filters)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-requires.pl", filters_text, package_ids[0], pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 }
@@ -263,10 +267,10 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-details.pl", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -275,10 +279,10 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * pk_backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-file.pl", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -287,10 +291,10 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "resolve.pl", filters_text, package_ids[0], NULL);
 	g_free (filters_text);
 }
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index a4e1540..d868c52 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -51,43 +51,47 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ADMIN_TOOLS |
-		PK_GROUP_ENUM_DESKTOP_GNOME |
-		PK_GROUP_ENUM_DESKTOP_KDE |
-		PK_GROUP_ENUM_DESKTOP_XFCE |
-		PK_GROUP_ENUM_DESKTOP_OTHER |
-		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_MULTIMEDIA |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_PUBLISHING |
-		PK_GROUP_ENUM_SERVERS |
-		PK_GROUP_ENUM_SYSTEM |
-		PK_GROUP_ENUM_VIRTUALIZATION);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ADMIN_TOOLS,
+		PK_GROUP_ENUM_DESKTOP_GNOME,
+		PK_GROUP_ENUM_DESKTOP_KDE,
+		PK_GROUP_ENUM_DESKTOP_XFCE,
+		PK_GROUP_ENUM_DESKTOP_OTHER,
+		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_MULTIMEDIA,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SERVERS,
+		PK_GROUP_ENUM_SYSTEM,
+		PK_GROUP_ENUM_VIRTUALIZATION,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT |
-		PK_FILTER_ENUM_BASENAME |
-		PK_FILTER_ENUM_FREE |
-		PK_FILTER_ENUM_NEWEST);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		PK_FILTER_ENUM_BASENAME,
+		PK_FILTER_ENUM_FREE,
+		PK_FILTER_ENUM_NEWEST,
+		-1);
 }
 
 /**
@@ -130,12 +134,12 @@ backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+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_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-depends.py", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 	g_free (package_ids_temp);
@@ -169,12 +173,12 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gchar *package_ids_temp;
 	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-requires.py", filters_text, package_ids_temp, pk_backend_bool_to_text (recursive), NULL);
 	g_free (filters_text);
 	g_free (package_ids_temp);
@@ -184,10 +188,10 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-updates.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -196,10 +200,10 @@ backend_get_updates (PkBackend *backend, PkFilterEnum filters)
  * backend_get_packages:
  */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filters)
+backend_get_packages (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-packages.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -298,10 +302,10 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-details.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -310,10 +314,10 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * pk_backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-file.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -322,10 +326,10 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * pk_backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-group.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -334,10 +338,10 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * pk_backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "search-name.py", filters_text, search, NULL);
 	g_free (filters_text);
 }
@@ -376,11 +380,11 @@ backend_update_system (PkBackend *backend)
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	gchar *filters_text;
 	gchar *package_ids_temp;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	package_ids_temp = pk_package_ids_to_text (package_ids, "|");
 	pk_backend_spawn_helper (spawn, "resolve.py", filters_text, package_ids_temp, NULL);
 	g_free (filters_text);
@@ -391,10 +395,10 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	gchar *filters_text;
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "get-repo-list.py", filters_text, NULL);
 	g_free (filters_text);
 }
@@ -425,12 +429,12 @@ backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parame
  * backend_what_provides:
  */
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, const gchar *search)
 {
 	gchar *filters_text;
 	const gchar *provides_text;
 	provides_text = pk_provides_enum_to_text (provides);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	pk_backend_spawn_helper (spawn, "what-provides.py", filters_text, provides_text, search, NULL);
 	g_free (filters_text);
 }
diff --git a/backends/yum2/pk-backend-yum2.c b/backends/yum2/pk-backend-yum2.c
index dd46101..7beceb9 100644
--- a/backends/yum2/pk-backend-yum2.c
+++ b/backends/yum2/pk-backend-yum2.c
@@ -53,41 +53,45 @@ backend_destroy (PkBackend *backend)
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PK_GROUP_ENUM_ADMIN_TOOLS |
-		PK_GROUP_ENUM_DESKTOP_GNOME |
-		PK_GROUP_ENUM_DESKTOP_KDE |
-		PK_GROUP_ENUM_DESKTOP_XFCE |
-		PK_GROUP_ENUM_DESKTOP_OTHER |
-		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_MULTIMEDIA |
-		PK_GROUP_ENUM_OFFICE |
-		PK_GROUP_ENUM_OTHER |
-		PK_GROUP_ENUM_PROGRAMMING |
-		PK_GROUP_ENUM_PUBLISHING |
-		PK_GROUP_ENUM_SERVERS |
-		PK_GROUP_ENUM_SYSTEM |
-		PK_GROUP_ENUM_VIRTUALIZATION);
+	return pk_bitfield_from_enums (
+		PK_GROUP_ENUM_ADMIN_TOOLS,
+		PK_GROUP_ENUM_DESKTOP_GNOME,
+		PK_GROUP_ENUM_DESKTOP_KDE,
+		PK_GROUP_ENUM_DESKTOP_XFCE,
+		PK_GROUP_ENUM_DESKTOP_OTHER,
+		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_MULTIMEDIA,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_OTHER,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SERVERS,
+		PK_GROUP_ENUM_SYSTEM,
+		PK_GROUP_ENUM_VIRTUALIZATION,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PK_FILTER_ENUM_GUI |
-		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT |
-		PK_FILTER_ENUM_FREE);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_GUI,
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_DEVELOPMENT,
+		PK_FILTER_ENUM_FREE,
+		-1);
 }
 
 /**
@@ -103,7 +107,7 @@ backend_cancel (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_dbus_get_depends (dbus, filters, package_ids, recursive);
 }
@@ -130,7 +134,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
  * backend_get_requires:
  */
 static void
-backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_dbus_get_requires (dbus, filters, package_ids, recursive);
 }
@@ -139,7 +143,7 @@ backend_get_requires (PkBackend *backend, PkFilterEnum filters, gchar **package_
  * backend_get_updates:
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_dbus_get_updates (dbus, filters);
 }
@@ -207,7 +211,7 @@ backend_remove_packages (PkBackend *backend, gchar **package_ids, gboolean allow
  * pk_backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_dbus_search_details (dbus, filters, search);
 }
@@ -216,7 +220,7 @@ backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *s
  * pk_backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_dbus_search_file (dbus, filters, search);
 }
@@ -225,7 +229,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * pk_backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_dbus_search_group (dbus, filters, search);
 }
@@ -234,7 +238,7 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *sea
  * pk_backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_dbus_search_name (dbus, filters, search);
 }
@@ -268,7 +272,7 @@ backend_update_system (PkBackend *backend)
  * pk_backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 {
 	pk_backend_dbus_resolve (dbus, filters, packages);
 }
@@ -277,7 +281,7 @@ backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **packages)
  * pk_backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_dbus_get_repo_list (dbus, filters);
 }
@@ -304,7 +308,7 @@ backend_repo_set_data (PkBackend *backend, const gchar *rid, const gchar *parame
  * pk_backend_what_provides:
  */
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provides, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provides, const gchar *search)
 {
 	pk_backend_dbus_what_provides (dbus, filters, provides, search);
 }
diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index a241ba3..3e8bcec 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -251,7 +251,7 @@ backend_get_requires_thread (PkBackend *backend)
   * backend_get_requires:
   */
 static void
-backend_get_requires(PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_requires(PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_thread_create (backend, backend_get_requires_thread);
 }
@@ -259,41 +259,44 @@ backend_get_requires(PkBackend *backend, PkFilterEnum filters, gchar **package_i
 /**
  * backend_get_groups:
  */
-static PkGroupEnum
+static PkBitfield
 backend_get_groups (PkBackend *backend)
 {
-	return (PkGroupEnum)(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_GAMES |
-			PK_GROUP_ENUM_GRAPHICS |
-			PK_GROUP_ENUM_LOCALIZATION |
-			PK_GROUP_ENUM_MULTIMEDIA |
-			PK_GROUP_ENUM_NETWORK |
-			PK_GROUP_ENUM_OFFICE |
-			PK_GROUP_ENUM_PROGRAMMING |
-			PK_GROUP_ENUM_PUBLISHING |
-			PK_GROUP_ENUM_SECURITY |
-			PK_GROUP_ENUM_SYSTEM |
-			PK_GROUP_ENUM_UNKNOWN);
+	return (PkGroupEnum)(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_GAMES,
+		PK_GROUP_ENUM_GRAPHICS,
+		PK_GROUP_ENUM_LOCALIZATION,
+		PK_GROUP_ENUM_MULTIMEDIA,
+		PK_GROUP_ENUM_NETWORK,
+		PK_GROUP_ENUM_OFFICE,
+		PK_GROUP_ENUM_PROGRAMMING,
+		PK_GROUP_ENUM_PUBLISHING,
+		PK_GROUP_ENUM_SECURITY,
+		PK_GROUP_ENUM_SYSTEM,
+		PK_GROUP_ENUM_UNKNOWN,
+		-1);
 }
 
 /**
  * backend_get_filters:
  */
-static PkFilterEnum
+static PkBitfield
 backend_get_filters (PkBackend *backend)
 {
-	return (PkFilterEnum) (PK_FILTER_ENUM_INSTALLED |
-			PK_FILTER_ENUM_NOT_INSTALLED |
-			PK_FILTER_ENUM_ARCH |
-			PK_FILTER_ENUM_NOT_ARCH |
-			PK_FILTER_ENUM_SOURCE |
-			PK_FILTER_ENUM_NOT_SOURCE);
+	return pk_bitfield_from_enums (
+		PK_FILTER_ENUM_INSTALLED,
+		PK_FILTER_ENUM_NOT_INSTALLED,
+		PK_FILTER_ENUM_ARCH,
+		PK_FILTER_ENUM_NOT_ARCH,
+		PK_FILTER_ENUM_SOURCE,
+		PK_FILTER_ENUM_NOT_SOURCE,
+		-1);
 }
 
 static gboolean
@@ -452,7 +455,7 @@ backend_get_depends_thread (PkBackend *backend)
  * backend_get_depends:
  */
 static void
-backend_get_depends (PkBackend *backend, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+backend_get_depends (PkBackend *backend, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	pk_backend_set_uint (backend, "type", DEPS_TYPE_DEPENDS);
 	pk_backend_thread_create (backend, backend_get_depends_thread);
@@ -683,7 +686,7 @@ backend_get_updates_thread (PkBackend *backend)
  * backend_get_updates
  */
 static void
-backend_get_updates (PkBackend *backend, PkFilterEnum filters)
+backend_get_updates (PkBackend *backend, PkBitfield filters)
 {
 	pk_backend_thread_create (backend, backend_get_updates_thread);
 }
@@ -1223,7 +1226,7 @@ backend_resolve_thread (PkBackend *backend)
  * backend_resolve:
  */
 static void
-backend_resolve (PkBackend *backend, PkFilterEnum filters, gchar **package_ids)
+backend_resolve (PkBackend *backend, PkBitfield filters, gchar **package_ids)
 {
 	pk_backend_thread_create (backend, backend_resolve_thread);
 }
@@ -1232,12 +1235,12 @@ static gboolean
 backend_find_packages_thread (PkBackend *backend)
 {
 	const gchar *search;
-	PkFilterEnum filters;
+	PkBitfield filters;
 	guint mode;
 	//GList *list = NULL;
 
 	search = pk_backend_get_string (backend, "search");
-	filters = (PkFilterEnum) pk_backend_get_uint (backend, "filters");
+	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 	mode = pk_backend_get_uint (backend, "mode");
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
@@ -1273,7 +1276,7 @@ backend_find_packages_thread (PkBackend *backend)
  * backend_search_name:
  */
 static void
-backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_name (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_NAME);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -1283,7 +1286,7 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_search_details:
  */
 static void
-backend_search_details (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_details (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_DETAILS);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -1293,10 +1296,10 @@ static gboolean
 backend_search_group_thread (PkBackend *backend)
 {
 	const gchar *group;
-	PkFilterEnum filters;
+	PkBitfield filters;
 
 	group = pk_backend_get_string (backend, "search");
-	filters = (PkFilterEnum) pk_backend_get_uint (backend, "filters");
+	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 
 	if (group == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_GROUP_NOT_FOUND, "Group is invalid.");
@@ -1336,7 +1339,7 @@ backend_search_group_thread (PkBackend *backend)
  * backend_search_group:
  */
 static void
-backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *pkGroup)
+backend_search_group (PkBackend *backend, PkBitfield filters, const gchar *pkGroup)
 {
 	pk_backend_thread_create (backend, backend_search_group_thread);
 }
@@ -1345,7 +1348,7 @@ backend_search_group (PkBackend *backend, PkFilterEnum filters, const gchar *pkG
  * backend_search_file:
  */
 static void
-backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *search)
+backend_search_file (PkBackend *backend, PkBitfield filters, const gchar *search)
 {
 	pk_backend_set_uint (backend, "mode", SEARCH_TYPE_FILE);
 	pk_backend_thread_create (backend, backend_find_packages_thread);
@@ -1355,7 +1358,7 @@ backend_search_file (PkBackend *backend, PkFilterEnum filters, const gchar *sear
  * backend_get_repo_list:
  */
 static void
-backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
+backend_get_repo_list (PkBackend *backend, PkBitfield filters)
 {
 	//FIXME - use the new param - filter
 
@@ -1507,8 +1510,8 @@ backend_get_files(PkBackend *backend, gchar **package_ids)
 static gboolean
 backend_get_packages_thread (PkBackend *backend)
 {
-	PkFilterEnum filters;
-	filters = (PkFilterEnum) pk_backend_get_uint (backend, "filters");
+	PkBitfield filters;
+	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
@@ -1530,7 +1533,7 @@ backend_get_packages_thread (PkBackend *backend)
   * backend_get_packages:
   */
 static void
-backend_get_packages (PkBackend *backend, PkFilterEnum filter)
+backend_get_packages (PkBackend *backend, PkBitfield filter)
 {
 	pk_backend_thread_create (backend, backend_get_packages_thread);
 }
@@ -1769,7 +1772,7 @@ backend_what_provides_thread (PkBackend *backend)
   * backend_what_provides
   */
 static void
-backend_what_provides (PkBackend *backend, PkFilterEnum filters, PkProvidesEnum provide, const gchar *search)
+backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum provide, const gchar *search)
 {
 	pk_backend_thread_create (backend, backend_what_provides_thread);
 }
diff --git a/backends/zypp/zypp-utils.cpp b/backends/zypp/zypp-utils.cpp
index 751742a..86f51db 100644
--- a/backends/zypp/zypp-utils.cpp
+++ b/backends/zypp/zypp-utils.cpp
@@ -520,17 +520,17 @@ system_and_package_are_x86 (zypp::sat::Solvable item)
 }
 
 void
-zypp_emit_packages_in_list (PkBackend *backend, std::vector<zypp::sat::Solvable> *v, PkFilterEnum filters)
+zypp_emit_packages_in_list (PkBackend *backend, std::vector<zypp::sat::Solvable> *v, PkBitfield filters)
 {
 	for (std::vector<zypp::sat::Solvable>::iterator it = v->begin ();
 			it != v->end (); it++) {
 		gchar *package_id = zypp_build_package_id_from_resolvable (*it);
 
 		// iterate through the given filters
-		if (filters != PK_FILTER_ENUM_NONE){
+		if (filters != 0){
 			gboolean print = TRUE;
-			for (guint i = 1; i < PK_FILTER_ENUM_UNKNOWN; i*=2) {
-				if ((filters & i) == 0)
+			for (guint i = 0; i < PK_FILTER_ENUM_UNKNOWN; i++) {
+				if ((filters & pk_bitfield_value (i)) == 0)
 					continue;
 				if (i == PK_FILTER_ENUM_INSTALLED && !(it->isSystem ()))
 					print = FALSE;
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index 4fea6d5..4a31fdd 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -175,7 +175,7 @@ std::set<zypp::PoolItem> * zypp_get_patches (PkRestartEnum restart = PK_RESTART_
   */
 gboolean zypp_perform_execution (PkBackend *backend, PerformType type, gboolean force);
 
-void zypp_emit_packages_in_list (PkBackend *backend, std::vector<zypp::sat::Solvable> *v, PkFilterEnum filters);
+void zypp_emit_packages_in_list (PkBackend *backend, std::vector<zypp::sat::Solvable> *v, PkBitfield filters);
 
 /**
   * convert a std::set<zypp::sat::Solvable to gchar ** array
diff --git a/client/pk-console.c b/client/pk-console.c
index f483904..0825513 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -45,7 +45,7 @@
 #define PROGRESS_BAR_SIZE 15
 
 static GMainLoop *loop = NULL;
-static PkRoleEnum roles;
+static PkBitfield roles;
 static gboolean is_console = FALSE;
 static gboolean has_output_bar = FALSE;
 static gboolean need_requeue = FALSE;
@@ -467,7 +467,7 @@ pk_console_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpoint
  * pk_console_perhaps_resolve:
  **/
 static gchar *
-pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *package, GError **error)
+pk_console_perhaps_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
 {
 	gboolean ret;
 	gboolean valid;
@@ -696,7 +696,7 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 	package_ids = pk_ptr_array_to_argv (array);
 
 	/* are we dumb and can't check for requires? */
-	if (!pk_enums_contain (roles, PK_ROLE_ENUM_GET_REQUIRES)) {
+	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_REQUIRES)) {
 		/* no, just try to remove it without deps */
 		ret = pk_console_remove_only (client, package_ids, FALSE, error);
 		goto out;
@@ -849,7 +849,7 @@ pk_console_update_package (PkClient *client, const gchar *package, GError **erro
  * pk_console_get_requires:
  **/
 static gboolean
-pk_console_get_requires (PkClient *client, PkFilterEnum filters, const gchar *package, GError **error)
+pk_console_get_requires (PkClient *client, PkBitfield filters, const gchar *package, GError **error)
 {
 	gboolean ret;
 	gchar *package_id;
@@ -870,7 +870,7 @@ pk_console_get_requires (PkClient *client, PkFilterEnum filters, const gchar *pa
  * pk_console_get_depends:
  **/
 static gboolean
-pk_console_get_depends (PkClient *client, PkFilterEnum filters, const gchar *package, GError **error)
+pk_console_get_depends (PkClient *client, PkBitfield filters, const gchar *package, GError **error)
 {
 	gboolean ret;
 	gchar *package_id;
@@ -1193,7 +1193,7 @@ pk_console_sigint_handler (int sig)
  * pk_console_get_summary:
  **/
 static gchar *
-pk_console_get_summary (PkRoleEnum roles)
+pk_console_get_summary (PkBitfield roles)
 {
 	GString *string;
 	string = g_string_new ("");
@@ -1208,70 +1208,70 @@ pk_console_get_summary (PkRoleEnum roles)
 	g_string_append_printf (string, "  %s\n", "get-transactions");
 	g_string_append_printf (string, "  %s\n", "get-time");
 
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_SEARCH_NAME) ||
-	    pk_enums_contain (roles, PK_ROLE_ENUM_SEARCH_DETAILS) ||
-	    pk_enums_contain (roles, PK_ROLE_ENUM_SEARCH_GROUP) ||
-	    pk_enums_contain (roles, PK_ROLE_ENUM_SEARCH_FILE)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_SEARCH_NAME) ||
+	    pk_bitfield_contain (roles, PK_ROLE_ENUM_SEARCH_DETAILS) ||
+	    pk_bitfield_contain (roles, PK_ROLE_ENUM_SEARCH_GROUP) ||
+	    pk_bitfield_contain (roles, PK_ROLE_ENUM_SEARCH_FILE)) {
 		g_string_append_printf (string, "  %s\n", "search [name|details|group|file] [data]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_INSTALL_PACKAGES) ||
-	    pk_enums_contain (roles, PK_ROLE_ENUM_INSTALL_FILES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_INSTALL_PACKAGES) ||
+	    pk_bitfield_contain (roles, PK_ROLE_ENUM_INSTALL_FILES)) {
 		g_string_append_printf (string, "  %s\n", "install [packages|files]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_DOWNLOAD_PACKAGES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_DOWNLOAD_PACKAGES)) {
 		g_string_append_printf (string, "  %s\n", "download [directory] [packages]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_INSTALL_SIGNATURE)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_INSTALL_SIGNATURE)) {
 		g_string_append_printf (string, "  %s\n", "install-sig [type] [key_id] [package_id]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_REMOVE_PACKAGES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_REMOVE_PACKAGES)) {
 		g_string_append_printf (string, "  %s\n", "remove [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_UPDATE_SYSTEM) ||
-	    pk_enums_contain (roles, PK_ROLE_ENUM_UPDATE_PACKAGES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_SYSTEM) ||
+	    pk_bitfield_contain (roles, PK_ROLE_ENUM_UPDATE_PACKAGES)) {
 		g_string_append_printf (string, "  %s\n", "update <package>");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_REFRESH_CACHE)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_REFRESH_CACHE)) {
 		g_string_append_printf (string, "  %s\n", "refresh");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_RESOLVE)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_RESOLVE)) {
 		g_string_append_printf (string, "  %s\n", "resolve [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_UPDATES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_UPDATES)) {
 		g_string_append_printf (string, "  %s\n", "get-updates");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
 		g_string_append_printf (string, "  %s\n", "get-depends [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_REQUIRES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_REQUIRES)) {
 		g_string_append_printf (string, "  %s\n", "get-requires [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_DETAILS)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DETAILS)) {
 		g_string_append_printf (string, "  %s\n", "get-details [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_FILES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_FILES)) {
 		g_string_append_printf (string, "  %s\n", "get-files [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_UPDATE_DETAIL)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_UPDATE_DETAIL)) {
 		g_string_append_printf (string, "  %s\n", "get-update-detail [package]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_PACKAGES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_PACKAGES)) {
 		g_string_append_printf (string, "  %s\n", "get-packages");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_GET_REPO_LIST)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_REPO_LIST)) {
 		g_string_append_printf (string, "  %s\n", "repo-list");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_REPO_ENABLE)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_REPO_ENABLE)) {
 		g_string_append_printf (string, "  %s\n", "repo-enable [repo_id]");
 		g_string_append_printf (string, "  %s\n", "repo-disable [repo_id]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_REPO_SET_DATA)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_REPO_SET_DATA)) {
 		g_string_append_printf (string, "  %s\n", "repo-set-data [repo_id] [parameter] [value];");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_WHAT_PROVIDES)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_WHAT_PROVIDES)) {
 		g_string_append_printf (string, "  %s\n", "what-provides [search]");
 	}
-	if (pk_enums_contain (roles, PK_ROLE_ENUM_ACCEPT_EULA)) {
+	if (pk_bitfield_contain (roles, PK_ROLE_ENUM_ACCEPT_EULA)) {
 		g_string_append_printf (string, "  %s\n", "accept-eula [eula-id]");
 	}
 	return g_string_free (string, FALSE);
@@ -1298,11 +1298,11 @@ main (int argc, char *argv[])
 	const gchar *value = NULL;
 	const gchar *details = NULL;
 	const gchar *parameter = NULL;
-	PkGroupEnum groups;
+	PkBitfield groups;
 	gchar *text;
 	ret = FALSE;
 	gboolean maybe_sync = TRUE;
-	PkFilterEnum filters = 0;
+	PkBitfield filters = 0;
 
 	const GOptionEntry options[] = {
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
@@ -1321,6 +1321,7 @@ main (int argc, char *argv[])
 	}
 	dbus_g_thread_init ();
 	g_type_init ();
+	pk_debug_init (verbose);
 
 	/* do stuff on ctrl-c */
 	signal (SIGINT, pk_console_sigint_handler);
@@ -1351,8 +1352,6 @@ main (int argc, char *argv[])
 	options_help = g_option_context_get_help (context, TRUE, NULL);
 	g_option_context_free (context);
 
-	pk_debug_init (verbose);
-
 	if (program_version) {
 		g_print (VERSION "\n");
 		return 0;
@@ -1411,7 +1410,7 @@ main (int argc, char *argv[])
 			  G_CALLBACK (pk_console_signature_finished_cb), NULL);
 
 	if (filter != NULL) {
-		filters = pk_filter_enums_from_text (filter);
+		filters = pk_filter_bitfield_from_text (filter);
 	}
 	pk_debug ("filter=%s, filters=%i", filter, filters);
 
@@ -1613,7 +1612,7 @@ main (int argc, char *argv[])
 		ret = pk_client_get_packages (client, filters, &error);
 
 	} else if (strcmp (mode, "get-actions") == 0) {
-		text = pk_role_enums_to_text (roles);
+		text = pk_role_bitfield_to_text (roles);
 		g_strdelimit (text, ";", '\n');
 		g_print ("%s\n", text);
 		g_free (text);
@@ -1623,7 +1622,7 @@ main (int argc, char *argv[])
 
 	} else if (strcmp (mode, "get-filters") == 0) {
 		filters = pk_control_get_filters (control);
-		text = pk_filter_enums_to_text (filters);
+		text = pk_filter_bitfield_to_text (filters);
 		g_strdelimit (text, ";", '\n');
 		g_print ("%s\n", text);
 		g_free (text);
@@ -1633,7 +1632,7 @@ main (int argc, char *argv[])
 
 	} else if (strcmp (mode, "get-groups") == 0) {
 		groups = pk_control_get_groups (control);
-		text = pk_group_enums_to_text (groups);
+		text = pk_group_bitfield_to_text (groups);
 		g_strdelimit (text, ";", '\n');
 		g_print ("%s\n", text);
 		g_free (text);
diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index 386eedc..0cbd95e 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -53,7 +53,7 @@ main (int argc, char *argv[])
 	gchar *pack_filename = NULL;
 	gchar *packname = NULL;
 	PkControl *control = NULL;
-	PkRoleEnum roles;
+	PkBitfield roles;
 	const gchar *package_list = NULL;
 	gchar *tempdir = NULL;
 	gboolean exists;
@@ -95,7 +95,7 @@ main (int argc, char *argv[])
 	/* are we dumb and can't check for depends? */
 	control = pk_control_new ();
 	roles = pk_control_get_actions (control);
-	if (!pk_enums_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
+	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
 		g_print ("Please use a backend that supports GetDepends!\n");
 		goto out;
 	}
diff --git a/client/pk-generate-pack.c b/client/pk-generate-pack.c
index 774e1a3..60b3608 100644
--- a/client/pk-generate-pack.c
+++ b/client/pk-generate-pack.c
@@ -49,7 +49,7 @@
  * pk_generate_pack_perhaps_resolve:
  **/
 gchar *
-pk_generate_pack_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *package, GError **error)
+pk_generate_pack_perhaps_resolve (PkClient *client, PkBitfield filter, const gchar *package, GError **error)
 {
 	gboolean ret;
 	gboolean valid;
diff --git a/client/pk-generate-pack.h b/client/pk-generate-pack.h
index 587a1b8..57daef7 100644
--- a/client/pk-generate-pack.h
+++ b/client/pk-generate-pack.h
@@ -24,7 +24,7 @@
 #define __PK_GENERATE_PACK_H
 
 gchar		*pk_generate_pack_perhaps_resolve		(PkClient *client,
-								 PkFilterEnum filter, 
+								 PkBitfield filter,
 								 const gchar *package,
 								 GError **error);
 gboolean	 pk_generate_pack_download_only 		(PkClient *client,
diff --git a/contrib/packagekit-plugin/src/contents.cpp b/contrib/packagekit-plugin/src/contents.cpp
index 3be68fb..9d51ac9 100644
--- a/contrib/packagekit-plugin/src/contents.cpp
+++ b/contrib/packagekit-plugin/src/contents.cpp
@@ -598,9 +598,6 @@ void
 PkpContents::runApplication (Time time)
 {
     GError *error = NULL;
-#ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
-    GdkAppLaunchContext *context;
-#endif
 
     if (mAppInfo == 0) {
         g_warning("Didn't find application to launch");
@@ -610,22 +607,20 @@ PkpContents::runApplication (Time time)
     if (time == 0)
         time = get_server_timestamp();
 
+    GAppLaunchContext *context = 0;
 #ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
     context = gdk_app_launch_context_new();
-    gdk_app_launch_context_set_timestamp(context, time);
-    if (!g_app_info_launch(mAppInfo, NULL, G_APP_LAUNCH_CONTEXT (context), &error)) {
-#else
-    if (!g_app_info_launch(mAppInfo, NULL, NULL, &error)) {
+    gdk_app_launch_context_set_timestamp(time);
 #endif
+
+    if (!g_app_info_launch(mAppInfo, NULL, context, &error)) {
         g_warning("%s\n", error->message);
         g_clear_error(&error);
         return;
     }
 
-#ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
-    if (context != NULL)
+    if (context != 0)
         g_object_unref(context);
-#endif
 }
 
 void
diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am
index 9a3c619..27b4c9d 100644
--- a/libpackagekit/Makefile.am
+++ b/libpackagekit/Makefile.am
@@ -35,6 +35,7 @@ libpackagekit_include_HEADERS =					\
 	pk-update-detail-list.h					\
 	pk-details-obj.h					\
 	pk-enum.h						\
+	pk-bitfield.h						\
 	pk-common.h						\
 	pk-client.h						\
 	pk-dbus-monitor.h					\
@@ -68,8 +69,10 @@ libpackagekit_la_SOURCES =					\
 	pk-update-detail-list.h					\
 	pk-details-obj.c					\
 	pk-details-obj.h					\
-	pk-enum.h						\
 	pk-enum.c						\
+	pk-enum.h						\
+	pk-bitfield.c						\
+	pk-bitfield.h						\
 	pk-common.c						\
 	pk-common.h						\
 	pk-client.c						\
diff --git a/libpackagekit/pk-bitfield.c b/libpackagekit/pk-bitfield.c
new file mode 100644
index 0000000..0d40f03
--- /dev/null
+++ b/libpackagekit/pk-bitfield.c
@@ -0,0 +1,470 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:pk-enum
+ * @short_description: Functions for converting strings to enum and vice-versa
+ *
+ * This file contains functions to convert to and from enumerated types.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <glib/gi18n.h>
+
+#include "pk-debug.h"
+#include "pk-common.h"
+#include "pk-enum.h"
+#include "pk-bitfield.h"
+
+/**
+ * pk_bitfield_contain_priority:
+ * @values: a valid bitfield instance
+ * @value: the values we are searching for
+ *
+ * Finds elements in a list, but with priority going to the preceeding entry
+ *
+ * Return value: The return enumerated type, or -1 if none are found
+ **/
+gint
+pk_bitfield_contain_priority (PkBitfield values, gint value, ...)
+{
+	va_list args;
+	guint i;
+	guint value_temp;
+	gint retval = -1;
+
+	/* we must query at least one thing */
+	if (pk_bitfield_contain (values, value)) {
+		return value;
+	}
+
+	/* process the valist */
+	va_start (args, value);
+	for (i=0;; i++) {
+		value_temp = va_arg (args, gint);
+		/* do we have this one? */
+		if (pk_bitfield_contain (values, value_temp)) {
+			retval = value_temp;
+			break;
+		}
+		/* end of the list */
+		if (value_temp == -1) {
+			break;
+		}
+	}
+	va_end (args);
+
+	return retval;
+}
+
+/**
+ * pk_bitfield_from_enums:
+ * @value: the values we want to add to the bitfield
+ *
+ * Return value: The return bitfield, or 0 if invalid
+ **/
+PkBitfield
+pk_bitfield_from_enums (gint value, ...)
+{
+	va_list args;
+	guint i;
+	gint value_temp;
+	PkBitfield values;
+
+	/* we must query at least one thing */
+	values = pk_bitfield_value (value);
+
+	/* process the valist */
+	va_start (args, value);
+	for (i=0;; i++) {
+		value_temp = va_arg (args, gint);
+		if (value_temp == -1)
+			break;
+		values += pk_bitfield_value (value_temp);
+	}
+	va_end (args);
+
+	return values;
+}
+
+/**
+ * pk_roles_bitfield_to_text:
+ * @roles: The enumerated type values
+ *
+ * Converts a enumerated type bitfield to its text representation
+ *
+ * Return value: the enumerated constant value, e.g. "install-file;update-system"
+ **/
+gchar *
+pk_role_bitfield_to_text (PkBitfield roles)
+{
+	GString *string;
+	guint i;
+
+	string = g_string_new ("");
+	for (i=0; i<PK_ROLE_ENUM_UNKNOWN; i++) {
+		if ((roles & pk_bitfield_value (i)) == 0) {
+			continue;
+		}
+		g_string_append_printf (string, "%s;", pk_role_enum_to_text (i));
+	}
+	/* do we have a no bitfield? \n */
+	if (string->len == 0) {
+		pk_warning ("not valid!");
+		g_string_append (string, pk_role_enum_to_text (PK_ROLE_ENUM_UNKNOWN));
+	} else {
+		/* remove last \n */
+		g_string_set_size (string, string->len - 1);
+	}
+	return g_string_free (string, FALSE);
+}
+
+/**
+ * pk_role_bitfield_from_text:
+ * @roles: the enumerated constant value, e.g. "available;~gui"
+ *
+ * Converts text representation to its enumerated type bitfield
+ *
+ * Return value: The enumerated type values
+ **/
+PkBitfield
+pk_role_bitfield_from_text (const gchar *roles)
+{
+	PkBitfield roles_enum = 0;
+	gchar **split;
+	guint length;
+	guint i;
+
+	split = g_strsplit (roles, ";", 0);
+	if (split == NULL) {
+		pk_warning ("unable to split");
+		goto out;
+	}
+
+	length = g_strv_length (split);
+	for (i=0; i<length; i++) {
+		roles_enum += pk_bitfield_value (pk_role_enum_from_text (split[i]));
+	}
+out:
+	g_strfreev (split);
+	return roles_enum;
+}
+
+/**
+ * pk_groups_bitfield_to_text:
+ * @groups: The enumerated type values
+ *
+ * Converts a enumerated type bitfield to its text representation
+ *
+ * Return value: the enumerated constant value, e.g. "gnome;kde"
+ **/
+gchar *
+pk_group_bitfield_to_text (PkBitfield groups)
+{
+	GString *string;
+	guint i;
+
+	string = g_string_new ("");
+	for (i=0; i<PK_GROUP_ENUM_UNKNOWN; i++) {
+		if ((groups & pk_bitfield_value (i)) == 0) {
+			continue;
+		}
+		g_string_append_printf (string, "%s;", pk_group_enum_to_text (i));
+	}
+	/* do we have a no bitfield? \n */
+	if (string->len == 0) {
+		pk_warning ("not valid!");
+		g_string_append (string, pk_group_enum_to_text (PK_GROUP_ENUM_UNKNOWN));
+	} else {
+		/* remove last \n */
+		g_string_set_size (string, string->len - 1);
+	}
+	return g_string_free (string, FALSE);
+}
+
+/**
+ * pk_group_bitfield_from_text:
+ * @groups: the enumerated constant value, e.g. "available;~gui"
+ *
+ * Converts text representation to its enumerated type bitfield
+ *
+ * Return value: The enumerated type values
+ **/
+PkBitfield
+pk_group_bitfield_from_text (const gchar *groups)
+{
+	PkBitfield groups_enum = 0;
+	gchar **split;
+	guint length;
+	guint i;
+
+	split = g_strsplit (groups, ";", 0);
+	if (split == NULL) {
+		pk_warning ("unable to split");
+		goto out;
+	}
+
+	length = g_strv_length (split);
+	for (i=0; i<length; i++) {
+		groups_enum += pk_bitfield_value (pk_group_enum_from_text (split[i]));
+	}
+out:
+	g_strfreev (split);
+	return groups_enum;
+}
+
+/**
+ * pk_filter_bitfield_to_text:
+ * @filters: The enumerated type values
+ *
+ * Converts a enumerated type bitfield to its text representation
+ *
+ * Return value: the enumerated constant value, e.g. "available;~gui"
+ **/
+gchar *
+pk_filter_bitfield_to_text (PkBitfield filters)
+{
+	GString *string;
+	guint i;
+
+	/* shortcut */
+	if (filters == 0) {
+		return g_strdup (pk_filter_enum_to_text (filters));
+	}
+
+	string = g_string_new ("");
+	for (i=0; i<PK_FILTER_ENUM_UNKNOWN; i++) {
+		if ((filters & pk_bitfield_value (i)) == 0) {
+			continue;
+		}
+		g_string_append_printf (string, "%s;", pk_filter_enum_to_text (i));
+	}
+	/* do we have a 'none' filter? \n */
+	if (string->len == 0) {
+		pk_warning ("not valid!");
+		g_string_append (string, pk_filter_enum_to_text (PK_FILTER_ENUM_NONE));
+	} else {
+		/* remove last \n */
+		g_string_set_size (string, string->len - 1);
+	}
+	return g_string_free (string, FALSE);
+}
+
+/**
+ * pk_filter_bitfield_from_text:
+ * @filters: the enumerated constant value, e.g. "available;~gui"
+ *
+ * Converts text representation to its enumerated type bitfield
+ *
+ * Return value: The enumerated type values
+ **/
+PkBitfield
+pk_filter_bitfield_from_text (const gchar *filters)
+{
+	PkBitfield filters_enum = PK_FILTER_ENUM_NONE;
+	gchar **split;
+	guint length;
+	guint i;
+
+	split = g_strsplit (filters, ";", 0);
+	if (split == NULL) {
+		pk_warning ("unable to split");
+		goto out;
+	}
+
+	length = g_strv_length (split);
+	for (i=0; i<length; i++) {
+		filters_enum += pk_bitfield_value (pk_filter_enum_from_text (split[i]));
+	}
+out:
+	g_strfreev (split);
+	return filters_enum;
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_bitfield (LibSelfTest *test)
+{
+	gchar *text;
+	PkBitfield filter;
+	guint value;
+	PkBitfield values;
+
+	if (libst_start (test, "PkBitfield", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "check we can convert filter bitfield to text (none)");
+	text = pk_filter_bitfield_to_text (pk_bitfield_value (PK_FILTER_ENUM_NONE));
+	if (pk_strequal (text, "none")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "text was %s", text);
+	}
+	g_free (text);
+
+	/************************************************************/
+	libst_title (test, "check we can convert filter bitfield to text (single)");
+	text = pk_filter_bitfield_to_text (pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT));
+	if (pk_strequal (text, "~devel")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "text was %s", text);
+	}
+	g_free (text);
+
+	/************************************************************/
+	libst_title (test, "check we can convert filter bitfield to text (plural)");
+	text = pk_filter_bitfield_to_text (pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT) |
+					   pk_bitfield_value (PK_FILTER_ENUM_GUI) |
+					   pk_bitfield_value (PK_FILTER_ENUM_NEWEST));
+	if (pk_strequal (text, "~devel;gui;newest")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "text was %s", text);
+	}
+	g_free (text);
+
+	/************************************************************/
+	libst_title (test, "check we can convert filter text to bitfield (none)");
+	filter = pk_filter_bitfield_from_text ("none");
+	if (filter == pk_bitfield_value (PK_FILTER_ENUM_NONE)) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "filter was %i", filter);
+	}
+
+	/************************************************************/
+	libst_title (test, "check we can convert filter text to bitfield (single)");
+	filter = pk_filter_bitfield_from_text ("~devel");
+	if (filter == pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "filter was %i", filter);
+	}
+
+	/************************************************************/
+	libst_title (test, "check we can convert filter text to bitfield (plural)");
+	filter = pk_filter_bitfield_from_text ("~devel;gui;newest");
+	if (filter == (pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT) |
+		       pk_bitfield_value (PK_FILTER_ENUM_GUI) |
+		       pk_bitfield_value (PK_FILTER_ENUM_NEWEST))) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "filter was %i", filter);
+	}
+
+	/************************************************************/
+	libst_title (test, "check we can add / remove bitfield");
+	filter = pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT) |
+		 pk_bitfield_value (PK_FILTER_ENUM_GUI) |
+		 pk_bitfield_value (PK_FILTER_ENUM_NEWEST);
+	pk_bitfield_add (filter, PK_FILTER_ENUM_NOT_FREE);
+	pk_bitfield_remove (filter, PK_FILTER_ENUM_NOT_DEVELOPMENT);
+	text = pk_filter_bitfield_to_text (filter);
+	if (pk_strequal (text, "gui;~free;newest")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "text was %s", text);
+	}
+	g_free (text);
+
+	/************************************************************/
+	libst_title (test, "check we can test enum presence");
+	filter = pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT) |
+		 pk_bitfield_value (PK_FILTER_ENUM_GUI) |
+		 pk_bitfield_value (PK_FILTER_ENUM_NEWEST);
+	if (pk_bitfield_contain (filter, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "wrong boolean");
+	}
+	libst_title (test, "check we can test enum false-presence");
+	if (!pk_bitfield_contain (filter, PK_FILTER_ENUM_FREE)) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "wrong boolean");
+	}
+
+	/************************************************************/
+	libst_title (test, "check we can add / remove bitfield to nothing");
+	filter = pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT);
+	pk_bitfield_remove (filter, PK_FILTER_ENUM_NOT_DEVELOPMENT);
+	text = pk_filter_bitfield_to_text (filter);
+	if (pk_strequal (text, "none")) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "text was %s", text);
+	}
+	g_free (text);
+
+	/************************************************************/
+	libst_title (test, "bitfield from enums");
+	values = pk_bitfield_from_enums (PK_ROLE_ENUM_SEARCH_GROUP, PK_ROLE_ENUM_SEARCH_DETAILS, -1);
+	if (values == (pk_bitfield_value (PK_ROLE_ENUM_SEARCH_DETAILS) |
+		       pk_bitfield_value (PK_ROLE_ENUM_SEARCH_GROUP))) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "returned bitfield %i", values);
+	}
+
+	/************************************************************/
+	libst_title (test, "priority check missing");
+	values = pk_bitfield_value (PK_ROLE_ENUM_SEARCH_DETAILS) |
+		 pk_bitfield_value (PK_ROLE_ENUM_SEARCH_GROUP);
+	value = pk_bitfield_contain_priority (values, PK_ROLE_ENUM_SEARCH_FILE, -1);
+	if (value == -1) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "returned priority %i when should be missing", value);
+	}
+
+	/************************************************************/
+	libst_title (test, "priority check first");
+	value = pk_bitfield_contain_priority (values, PK_ROLE_ENUM_SEARCH_GROUP, -1);
+	if (value == PK_ROLE_ENUM_SEARCH_GROUP) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "returned wrong value; %i", value);
+	}
+
+	/************************************************************/
+	libst_title (test, "priority check second, correct");
+	value = pk_bitfield_contain_priority (values, PK_ROLE_ENUM_SEARCH_FILE, PK_ROLE_ENUM_SEARCH_GROUP, -1);
+	if (value == PK_ROLE_ENUM_SEARCH_GROUP) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, "returned wrong value; %i", value);
+	}
+
+	libst_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-bitfield.h b/libpackagekit/pk-bitfield.h
new file mode 100644
index 0000000..3fd27bc
--- /dev/null
+++ b/libpackagekit/pk-bitfield.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_BITFIELD_H
+#define __PK_BITFIELD_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include "pk-enum.h"
+
+G_BEGIN_DECLS
+
+/* convenience functions as it's easy to forget the bitwise operators */
+#define pk_bitfield_add(bitfield,enum)		do { ((bitfield) |= (pk_bitfield_value(enum))); } while (0)
+#define pk_bitfield_remove(bitfield,enum)	do { ((bitfield) &= ~(pk_bitfield_value(enum))); } while (0)
+#define pk_bitfield_contain(bitfield,enum)	(((bitfield) & (pk_bitfield_value(enum))) > 0)
+#define pk_bitfield_value(enum)			(1 << (enum))
+
+typedef guint PkBitfield;
+
+gint		 pk_bitfield_contain_priority		(PkBitfield	 values,
+							 gint		 value, ...);
+PkBitfield	 pk_bitfield_from_enums			(gint		 value, ...);
+PkBitfield	 pk_role_bitfield_from_text 		(const gchar	*roles);
+gchar		*pk_role_bitfield_to_text		(PkBitfield	 roles);
+PkBitfield	 pk_group_bitfield_from_text 		(const gchar	*groups);
+gchar		*pk_group_bitfield_to_text		(PkBitfield groups);
+PkBitfield	 pk_filter_bitfield_from_text 		(const gchar	*filters);
+gchar		*pk_filter_bitfield_to_text		(PkBitfield filters);
+
+G_END_DECLS
+
+#endif /* __PK_BITFIELD_H */
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index e74afd7..6675c87 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -47,6 +47,7 @@
 #endif
 
 #include "pk-enum.h"
+#include "pk-bitfield.h"
 #include "pk-client.h"
 #include "pk-connection.h"
 #include "pk-package-id.h"
@@ -98,7 +99,7 @@ struct _PkClientPrivate
 	gchar			*cached_search;
 	gchar			*cached_directory;
 	PkProvidesEnum		 cached_provides;
-	PkFilterEnum		 cached_filters;
+	PkBitfield	 cached_filters;
 };
 
 typedef enum {
@@ -1132,7 +1133,7 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error)
 /**
  * pk_client_get_updates:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @error: a %GError to put the error code and message in, or %NULL
  *
  * Get a list of all the packages that can be updated for all repositories.
@@ -1140,7 +1141,7 @@ pk_client_allocate_transaction_id (PkClient *client, GError **error)
  * Return value: %TRUE if we got told the daemon to get the update list
  **/
 gboolean
-pk_client_get_updates (PkClient *client, PkFilterEnum filters, GError **error)
+pk_client_get_updates (PkClient *client, PkBitfield filters, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1163,7 +1164,7 @@ pk_client_get_updates (PkClient *client, PkFilterEnum filters, GError **error)
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetUpdates", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
@@ -1276,7 +1277,7 @@ pk_client_update_system (PkClient *client, GError **error)
 /**
  * pk_client_search_name:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @search: free text to search for, for instance, "power"
  * @error: a %GError to put the error code and message in, or %NULL
  *
@@ -1286,7 +1287,7 @@ pk_client_update_system (PkClient *client, GError **error)
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_search_name (PkClient *client, PkFilterEnum filters, const gchar *search, GError **error)
+pk_client_search_name (PkClient *client, PkBitfield filters, const gchar *search, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1310,7 +1311,7 @@ pk_client_search_name (PkClient *client, PkFilterEnum filters, const gchar *sear
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "SearchName", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRING, search,
@@ -1332,7 +1333,7 @@ pk_client_search_name (PkClient *client, PkFilterEnum filters, const gchar *sear
 /**
  * pk_client_search_details:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @search: free text to search for, for instance, "power"
  * @error: a %GError to put the error code and message in, or %NULL
  *
@@ -1343,7 +1344,7 @@ pk_client_search_name (PkClient *client, PkFilterEnum filters, const gchar *sear
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_search_details (PkClient *client, PkFilterEnum filters, const gchar *search, GError **error)
+pk_client_search_details (PkClient *client, PkBitfield filters, const gchar *search, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1367,7 +1368,7 @@ pk_client_search_details (PkClient *client, PkFilterEnum filters, const gchar *s
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "SearchDetails", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRING, search,
@@ -1389,7 +1390,7 @@ pk_client_search_details (PkClient *client, PkFilterEnum filters, const gchar *s
 /**
  * pk_client_search_group:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @search: a group enum to search for, for instance, "system-tools"
  * @error: a %GError to put the error code and message in, or %NULL
  *
@@ -1398,7 +1399,7 @@ pk_client_search_details (PkClient *client, PkFilterEnum filters, const gchar *s
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_search_group (PkClient *client, PkFilterEnum filters, const gchar *search, GError **error)
+pk_client_search_group (PkClient *client, PkBitfield filters, const gchar *search, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1422,7 +1423,7 @@ pk_client_search_group (PkClient *client, PkFilterEnum filters, const gchar *sea
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "SearchGroup", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRING, search,
@@ -1444,7 +1445,7 @@ pk_client_search_group (PkClient *client, PkFilterEnum filters, const gchar *sea
 /**
  * pk_client_search_file:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @search: file to search for, for instance, "/sbin/service"
  * @error: a %GError to put the error code and message in, or %NULL
  *
@@ -1453,7 +1454,7 @@ pk_client_search_group (PkClient *client, PkFilterEnum filters, const gchar *sea
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_search_file (PkClient *client, PkFilterEnum filters, const gchar *search, GError **error)
+pk_client_search_file (PkClient *client, PkBitfield filters, const gchar *search, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1477,7 +1478,7 @@ pk_client_search_file (PkClient *client, PkFilterEnum filters, const gchar *sear
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "SearchFile", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRING, search,
@@ -1499,7 +1500,7 @@ pk_client_search_file (PkClient *client, PkFilterEnum filters, const gchar *sear
 /**
  * pk_client_get_depends:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @package_ids: an array of package_id structures such as "gnome-power-manager;0.0.1;i386;fedora"
  * @recursive: If we should search recursively for depends
  * @error: a %GError to put the error code and message in, or %NULL
@@ -1509,7 +1510,7 @@ pk_client_search_file (PkClient *client, PkFilterEnum filters, const gchar *sear
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_get_depends (PkClient *client, PkFilterEnum filters, gchar **package_ids, gboolean recursive, GError **error)
+pk_client_get_depends (PkClient *client, PkBitfield filters, gchar **package_ids, gboolean recursive, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1546,7 +1547,7 @@ pk_client_get_depends (PkClient *client, PkFilterEnum filters, gchar **package_i
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetDepends", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRV, package_ids,
@@ -1631,7 +1632,7 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar
 /**
  * pk_client_get_packages:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @error: a %GError to put the error code and message in, or %NULL
  *
  * Get the list of packages from the backend
@@ -1639,7 +1640,7 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_get_packages (PkClient *client, PkFilterEnum filters, GError **error)
+pk_client_get_packages (PkClient *client, PkBitfield filters, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1662,7 +1663,7 @@ pk_client_get_packages (PkClient *client, PkFilterEnum filters, GError **error)
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetPackages", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
@@ -1716,7 +1717,7 @@ pk_client_set_locale (PkClient *client, const gchar *code, GError **error)
 /**
  * pk_client_get_requires:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @package_ids: an array of package_id structures such as "gnome-power-manager;0.0.1;i386;fedora"
  * @recursive: If we should search recursively for requires
  * @error: a %GError to put the error code and message in, or %NULL
@@ -1726,7 +1727,7 @@ pk_client_set_locale (PkClient *client, const gchar *code, GError **error)
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_get_requires (PkClient *client, PkFilterEnum filters, gchar **package_ids, gboolean recursive, GError **error)
+pk_client_get_requires (PkClient *client, PkBitfield filters, gchar **package_ids, gboolean recursive, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -1763,7 +1764,7 @@ pk_client_get_requires (PkClient *client, PkFilterEnum filters, gchar **package_
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetRequires", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRV, package_ids,
@@ -1786,7 +1787,7 @@ pk_client_get_requires (PkClient *client, PkFilterEnum filters, gchar **package_
 /**
  * pk_client_what_provides:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @provides: a #PkProvidesEnum value such as PK_PROVIDES_ENUM_CODEC
  * @search: a search term such as "sound/mp3"
  * @error: a %GError to put the error code and message in, or %NULL
@@ -1798,7 +1799,7 @@ pk_client_get_requires (PkClient *client, PkFilterEnum filters, gchar **package_
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_what_provides (PkClient *client, PkFilterEnum filters, PkProvidesEnum provides,
+pk_client_what_provides (PkClient *client, PkBitfield filters, PkProvidesEnum provides,
 			 const gchar *search, GError **error)
 {
 	gboolean ret;
@@ -1829,7 +1830,7 @@ pk_client_what_provides (PkClient *client, PkFilterEnum filters, PkProvidesEnum
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "WhatProvides", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRING, provides_text,
@@ -1964,7 +1965,7 @@ pk_client_rollback (PkClient *client, const gchar *transaction_id, GError **erro
 /**
  * pk_client_resolve:
  * @client: a valid #PkClient instance
- * @filters: a %PkFilterEnum such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
+ * @filters: a %PkBitfield such as %PK_FILTER_ENUM_GUI | %PK_FILTER_ENUM_FREE or %PK_FILTER_ENUM_NONE
  * @packages: an array of package names to resolve, e.g. "gnome-system-tools"
  * @error: a %GError to put the error code and message in, or %NULL
  *
@@ -1975,7 +1976,7 @@ pk_client_rollback (PkClient *client, const gchar *transaction_id, GError **erro
  * Return value: %TRUE if the daemon queued the transaction
  **/
 gboolean
-pk_client_resolve (PkClient *client, PkFilterEnum filters, gchar **packages, GError **error)
+pk_client_resolve (PkClient *client, PkBitfield filters, gchar **packages, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -2000,7 +2001,7 @@ pk_client_resolve (PkClient *client, PkFilterEnum filters, gchar **packages, GEr
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "Resolve", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_STRV, packages,
@@ -2781,7 +2782,7 @@ pk_client_install_files (PkClient *client, gboolean trusted, gchar **files_rel,
  * Return value: %TRUE if the daemon queued the transaction
  */
 gboolean
-pk_client_get_repo_list (PkClient *client, PkFilterEnum filters, GError **error)
+pk_client_get_repo_list (PkClient *client, PkBitfield filters, GError **error)
 {
 	gboolean ret;
 	gchar *filter_text;
@@ -2804,7 +2805,7 @@ pk_client_get_repo_list (PkClient *client, PkFilterEnum filters, GError **error)
 		pk_client_error_set (error, PK_CLIENT_ERROR_NO_TID, "No proxy for transaction");
 		return FALSE;
 	}
-	filter_text = pk_filter_enums_to_text (filters);
+	filter_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (client->priv->proxy, "GetRepoList", error,
 				 G_TYPE_STRING, filter_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 8ac91b2..5ad87ba 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -24,6 +24,7 @@
 
 #include <glib-object.h>
 #include "pk-enum.h"
+#include "pk-bitfield.h"
 #include "pk-package-list.h"
 #include "pk-update-detail-obj.h"
 #include "pk-details-obj.h"
@@ -198,39 +199,39 @@ gboolean	 pk_client_download_packages		(PkClient	*client,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;	
 gboolean	 pk_client_get_updates			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_update_system		(PkClient	*client,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_search_name			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 const gchar	*search,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_search_details		(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 const gchar	*search,
 							 GError		**error);
 gboolean	 pk_client_search_group			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 const gchar	*search,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_search_file			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 const gchar	*search,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_depends			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 gchar		**package_ids,
 							 gboolean	 recursive,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_packages			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_update_detail		(PkClient	*client,
@@ -238,13 +239,13 @@ gboolean	 pk_client_get_update_detail		(PkClient	*client,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_requires			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 gchar		**package_ids,
 							 gboolean	 recursive,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_what_provides		(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 PkProvidesEnum	 provides,
 							 const gchar	*search,
 							 GError		**error)
@@ -291,7 +292,7 @@ gboolean	 pk_client_install_file			(PkClient	*client,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_resolve			(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 gchar		**packages,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
@@ -312,7 +313,7 @@ gboolean	 pk_client_accept_eula			(PkClient	*client,
 
 /* repo stuff */
 gboolean	 pk_client_get_repo_list		(PkClient	*client,
-							 PkFilterEnum	 filters,
+							 PkBitfield filters,
 							 GError		**error)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_repo_enable			(PkClient	*client,
diff --git a/libpackagekit/pk-control.c b/libpackagekit/pk-control.c
index 6483112..f86e4d3 100644
--- a/libpackagekit/pk-control.c
+++ b/libpackagekit/pk-control.c
@@ -167,13 +167,13 @@ pk_control_error_fixup (GError **error)
  *
  * Return value: an enumerated list of the actions the backend supports
  **/
-PkRoleEnum
+PkBitfield
 pk_control_get_actions (PkControl *control)
 {
 	gboolean ret;
 	GError *error = NULL;
 	gchar *actions;
-	PkRoleEnum roles_enum = PK_GROUP_ENUM_UNKNOWN;
+	PkBitfield roles_enum = 0;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN);
 
@@ -194,7 +194,7 @@ pk_control_get_actions (PkControl *control)
 	}
 
 	/* convert to enumerated types */
-	roles_enum = pk_role_enums_from_text (actions);
+	roles_enum = pk_role_bitfield_from_text (actions);
 	g_free (actions);
 out:
 	return roles_enum;
@@ -247,13 +247,13 @@ out:
  *
  * Return value: an enumerated list of the groups the backend supports
  **/
-PkGroupEnum
+PkBitfield
 pk_control_get_groups (PkControl *control)
 {
 	gboolean ret;
 	GError *error = NULL;
 	gchar *groups;
-	PkGroupEnum groups_enum = PK_GROUP_ENUM_UNKNOWN;
+	PkBitfield groups_enum = 0;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN);
 
@@ -274,7 +274,7 @@ pk_control_get_groups (PkControl *control)
 	}
 
 	/* convert to enumerated types */
-	groups_enum = pk_group_enums_from_text (groups);
+	groups_enum = pk_group_bitfield_from_text (groups);
 	g_free (groups);
 out:
 	return groups_enum;
@@ -292,7 +292,7 @@ pk_control_get_network_state (PkControl *control)
 	gboolean ret;
 	GError *error = NULL;
 	gchar *network_state;
-	PkGroupEnum network_state_enum = PK_NETWORK_ENUM_UNKNOWN;
+	PkNetworkEnum network_state_enum = PK_NETWORK_ENUM_UNKNOWN;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_NETWORK_ENUM_UNKNOWN);
 
@@ -327,13 +327,13 @@ out:
  *
  * Return value: an enumerated list of the filters the backend supports
  **/
-PkFilterEnum
+PkBitfield
 pk_control_get_filters (PkControl *control)
 {
 	gboolean ret;
 	GError *error = NULL;
 	gchar *filters;
-	PkFilterEnum filters_enum = PK_FILTER_ENUM_UNKNOWN;
+	PkBitfield filters_enum = 0;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_FILTER_ENUM_UNKNOWN);
 
@@ -354,7 +354,7 @@ pk_control_get_filters (PkControl *control)
 	}
 
 	/* convert to enumerated types */
-	filters_enum = pk_filter_enums_from_text (filters);
+	filters_enum = pk_filter_bitfield_from_text (filters);
 	g_free (filters);
 out:
 	return filters_enum;
diff --git a/libpackagekit/pk-control.h b/libpackagekit/pk-control.h
index c1b1be8..a2d787f 100644
--- a/libpackagekit/pk-control.h
+++ b/libpackagekit/pk-control.h
@@ -29,6 +29,7 @@
 
 #include <glib-object.h>
 #include "pk-enum.h"
+#include "pk-bitfield.h"
 
 G_BEGIN_DECLS
 
@@ -91,9 +92,9 @@ gboolean	 pk_control_allocate_transaction_id	(PkControl	*control,
 gboolean	 pk_control_set_proxy			(PkControl	*control,
 							 const gchar	*proxy_http,
 							 const gchar	*proxy_ftp);
-PkRoleEnum	 pk_control_get_actions			(PkControl	*control);
-PkFilterEnum	 pk_control_get_filters			(PkControl	*control);
-PkGroupEnum	 pk_control_get_groups			(PkControl	*control);
+PkBitfield	 pk_control_get_actions			(PkControl	*control);
+PkBitfield pk_control_get_filters			(PkControl	*control);
+PkBitfield	 pk_control_get_groups			(PkControl	*control);
 PkNetworkEnum	 pk_control_get_network_state		(PkControl	*control);
 gboolean	 pk_control_get_backend_detail		(PkControl	*control,
 							 gchar		**name,
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 98d3c89..d51bb78 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -21,7 +21,7 @@
 
 /**
  * SECTION:pk-enum
- * @short_description: Functions for converting strings to enums and vice-versa
+ * @short_description: Functions for converting strings to enum and vice-versa
  *
  * This file contains functions to convert to and from enumerated types.
  */
@@ -232,9 +232,9 @@ static PkEnumMatch enum_group[] = {
 	{PK_GROUP_ENUM_NETWORK,			"network"},
 	{PK_GROUP_ENUM_MAPS,			"maps"},
 	{PK_GROUP_ENUM_REPOS,			"repos"},
-//	{PK_GROUP_ENUM_SCIENCE,			"science"},
-//	{PK_GROUP_ENUM_DOCUMENTATION,		"documentation"},
-//	{PK_GROUP_ENUM_ELECTRONICS,		"electronics"},
+	{PK_GROUP_ENUM_SCIENCE,			"science"},
+	{PK_GROUP_ENUM_DOCUMENTATION,		"documentation"},
+	{PK_GROUP_ENUM_ELECTRONICS,		"electronics"},
 	{0, NULL}
 };
 
@@ -507,47 +507,6 @@ pk_enum_find_string (PkEnumMatch *table, guint value)
 }
 
 /**
- * pk_enums_contain_priority:
- * @values: a valid enums instance
- * @value: the values we are searching for
- *
- * Finds elements in a list, but with priority going to the preceeding entry
- *
- * Return value: The return enumerated type, or -1 if none are found
- **/
-gint
-pk_enums_contain_priority (guint values, gint value, ...)
-{
-	va_list args;
-	guint i;
-	guint value_temp;
-	gint retval = -1;
-
-	/* we must query at least one thing */
-	if (pk_enums_contain (values, value)) {
-		return value;
-	}
-
-	/* process the valist */
-	va_start (args, value);
-	for (i=0;; i++) {
-		value_temp = va_arg (args, gint);
-		/* do we have this one? */
-		if (pk_enums_contain (values, value_temp)) {
-			retval = value_temp;
-			break;
-		}
-		/* end of the list */
-		if (value_temp == -1) {
-			break;
-		}
-	}
-	va_end (args);
-
-	return retval;
-}
-
-/**
  * pk_sig_type_enum_from_text:
  * @sig_type: Text describing the enumerated type
  *
@@ -772,69 +731,6 @@ pk_role_enum_to_text (PkRoleEnum role)
 }
 
 /**
- * pk_roles_enums_to_text:
- * @filters: The enumerated type values
- *
- * Converts a enumerated type bitfield to its text representation
- *
- * Return value: the enumerated constant value, e.g. "install-file;update-system"
- **/
-gchar *
-pk_role_enums_to_text (PkRoleEnum roles)
-{
-	GString *string;
-	guint i;
-
-	string = g_string_new ("");
-	for (i=1; i<PK_ROLE_ENUM_UNKNOWN; i*=2) {
-		if ((roles & i) == 0) {
-			continue;
-		}
-		g_string_append_printf (string, "%s;", pk_role_enum_to_text (i));
-	}
-	/* do we have a no enums? \n */
-	if (string->len == 0) {
-		pk_warning ("not valid!");
-		g_string_append (string, pk_role_enum_to_text (PK_ROLE_ENUM_UNKNOWN));
-	} else {
-		/* remove last \n */
-		g_string_set_size (string, string->len - 1);
-	}
-	return g_string_free (string, FALSE);
-}
-
-/**
- * pk_role_enums_from_text:
- * @roles: the enumerated constant value, e.g. "available;~gui"
- *
- * Converts text representation to its enumerated type bitfield
- *
- * Return value: The enumerated type values
- **/
-PkRoleEnum
-pk_role_enums_from_text (const gchar *roles)
-{
-	PkRoleEnum roles_enum = 0;
-	gchar **split;
-	guint length;
-	guint i;
-
-	split = g_strsplit (roles, ";", 0);
-	if (split == NULL) {
-		pk_warning ("unable to split");
-		goto out;
-	}
-
-	length = g_strv_length (split);
-	for (i=0; i<length; i++) {
-		roles_enum += pk_role_enum_from_text (split[i]);
-	}
-out:
-	g_strfreev (split);
-	return roles_enum;
-}
-
-/**
  * pk_error_enum_from_text:
  * @code: Text describing the enumerated type
  *
@@ -947,69 +843,6 @@ pk_group_enum_to_text (PkGroupEnum group)
 }
 
 /**
- * pk_groups_enums_to_text:
- * @groups: The enumerated type values
- *
- * Converts a enumerated type bitfield to its text representation
- *
- * Return value: the enumerated constant value, e.g. "gnome;kde"
- **/
-gchar *
-pk_group_enums_to_text (PkGroupEnum groups)
-{
-	GString *string;
-	guint i;
-
-	string = g_string_new ("");
-	for (i=1; i<PK_GROUP_ENUM_UNKNOWN; i*=2) {
-		if ((groups & i) == 0) {
-			continue;
-		}
-		g_string_append_printf (string, "%s;", pk_group_enum_to_text (i));
-	}
-	/* do we have a no enums? \n */
-	if (string->len == 0) {
-		pk_warning ("not valid!");
-		g_string_append (string, pk_group_enum_to_text (PK_GROUP_ENUM_UNKNOWN));
-	} else {
-		/* remove last \n */
-		g_string_set_size (string, string->len - 1);
-	}
-	return g_string_free (string, FALSE);
-}
-
-/**
- * pk_group_enums_from_text:
- * @groups: the enumerated constant value, e.g. "available;~gui"
- *
- * Converts text representation to its enumerated type bitfield
- *
- * Return value: The enumerated type values
- **/
-PkGroupEnum
-pk_group_enums_from_text (const gchar *groups)
-{
-	PkGroupEnum groups_enum = 0;
-	gchar **split;
-	guint length;
-	guint i;
-
-	split = g_strsplit (groups, ";", 0);
-	if (split == NULL) {
-		pk_warning ("unable to split");
-		goto out;
-	}
-
-	length = g_strv_length (split);
-	for (i=0; i<length; i++) {
-		groups_enum += pk_group_enum_from_text (split[i]);
-	}
-out:
-	g_strfreev (split);
-	return groups_enum;
-}
-
-/**
  * pk_freq_enum_from_text:
  * @freq: Text describing the enumerated type
  *
@@ -1122,74 +955,6 @@ pk_filter_enum_to_text (PkFilterEnum filter)
 }
 
 /**
- * pk_filter_enums_to_text:
- * @filters: The enumerated type values
- *
- * Converts a enumerated type bitfield to its text representation
- *
- * Return value: the enumerated constant value, e.g. "available;~gui"
- **/
-gchar *
-pk_filter_enums_to_text (PkFilterEnum filters)
-{
-	GString *string;
-	guint i;
-
-	/* shortcut */
-	if (filters == PK_FILTER_ENUM_NONE) {
-		return g_strdup (pk_filter_enum_to_text (filters));
-	}
-
-	string = g_string_new ("");
-	for (i=1; i<PK_FILTER_ENUM_UNKNOWN; i*=2) {
-		if ((filters & i) == 0) {
-			continue;
-		}
-		g_string_append_printf (string, "%s;", pk_filter_enum_to_text (i));
-	}
-	/* do we have a 'none' filter? \n */
-	if (string->len == 0) {
-		pk_warning ("not valid!");
-		g_string_append (string, pk_filter_enum_to_text (PK_FILTER_ENUM_NONE));
-	} else {
-		/* remove last \n */
-		g_string_set_size (string, string->len - 1);
-	}
-	return g_string_free (string, FALSE);
-}
-
-/**
- * pk_filter_enums_from_text:
- * @filters: the enumerated constant value, e.g. "available;~gui"
- *
- * Converts text representation to its enumerated type bitfield
- *
- * Return value: The enumerated type values
- **/
-PkFilterEnum
-pk_filter_enums_from_text (const gchar *filters)
-{
-	PkFilterEnum filters_enum = PK_FILTER_ENUM_NONE;
-	gchar **split;
-	guint length;
-	guint i;
-
-	split = g_strsplit (filters, ";", 0);
-	if (split == NULL) {
-		pk_warning ("unable to split");
-		goto out;
-	}
-
-	length = g_strv_length (split);
-	for (i=0; i<length; i++) {
-		filters_enum += pk_filter_enum_from_text (split[i]);
-	}
-out:
-	g_strfreev (split);
-	return filters_enum;
-}
-
-/**
  * pk_license_enum_from_text:
  * @license: Text describing the enumerated type
  *
@@ -1229,10 +994,6 @@ libst_enum (LibSelfTest *test)
 	const gchar *string;
 	PkRoleEnum role_value;
 	guint i;
-	gchar *text;
-	PkFilterEnum filter;
-	guint value;
-	guint values;
 
 	if (libst_start (test, "PkEnum", CLASS_AUTO) == FALSE) {
 		return;
@@ -1275,8 +1036,8 @@ libst_enum (LibSelfTest *test)
 	}
 
 	/************************************************************/
-	libst_title (test, "check we convert all the role enums");
-	for (i=1; i<=PK_ROLE_ENUM_UNKNOWN; i*=2) {
+	libst_title (test, "check we convert all the role bitfield");
+	for (i=1; i<=PK_ROLE_ENUM_UNKNOWN; i++) {
 		string = pk_role_enum_to_text (i);
 		if (string == NULL) {
 			libst_failed (test, "failed to get %i", i);
@@ -1286,8 +1047,8 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the status enums");
-	for (i=1; i<=PK_STATUS_ENUM_UNKNOWN; i*=2) {
+	libst_title (test, "check we convert all the status bitfield");
+	for (i=1; i<=PK_STATUS_ENUM_UNKNOWN; i++) {
 		string = pk_status_enum_to_text (i);
 		if (string == NULL) {
 			libst_failed (test, "failed to get %i", i);
@@ -1297,7 +1058,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the exit enums");
+	libst_title (test, "check we convert all the exit bitfield");
 	for (i=0; i<=PK_EXIT_ENUM_UNKNOWN; i++) {
 		string = pk_exit_enum_to_text (i);
 		if (string == NULL) {
@@ -1308,7 +1069,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the filter enums");
+	libst_title (test, "check we convert all the filter bitfield");
 	for (i=0; i<=PK_FILTER_ENUM_UNKNOWN; i++) {
 		string = pk_filter_enum_to_text (i);
 		if (string == NULL) {
@@ -1319,7 +1080,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the restart enums");
+	libst_title (test, "check we convert all the restart bitfield");
 	for (i=0; i<=PK_RESTART_ENUM_UNKNOWN; i++) {
 		string = pk_restart_enum_to_text (i);
 		if (string == NULL) {
@@ -1330,7 +1091,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the error_code enums");
+	libst_title (test, "check we convert all the error_code bitfield");
 	for (i=0; i<=PK_ERROR_ENUM_UNKNOWN; i++) {
 		string = pk_error_enum_to_text (i);
 		if (string == NULL) {
@@ -1341,8 +1102,8 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the group enums");
-	for (i=1; i<=PK_GROUP_ENUM_UNKNOWN; i*=2) {
+	libst_title (test, "check we convert all the group bitfield");
+	for (i=1; i<=PK_GROUP_ENUM_UNKNOWN; i++) {
 		string = pk_group_enum_to_text (i);
 		if (string == NULL) {
 			libst_failed (test, "failed to get %i", i);
@@ -1352,7 +1113,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the freq enums");
+	libst_title (test, "check we convert all the freq bitfield");
 	for (i=0; i<=PK_FREQ_ENUM_UNKNOWN; i++) {
 		string = pk_freq_enum_to_text (i);
 		if (string == NULL) {
@@ -1363,7 +1124,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the update enums");
+	libst_title (test, "check we convert all the update bitfield");
 	for (i=0; i<=PK_UPDATE_ENUM_UNKNOWN; i++) {
 		string = pk_update_enum_to_text (i);
 		if (string == NULL) {
@@ -1374,8 +1135,8 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the info enums");
-	for (i=1; i<=PK_INFO_ENUM_UNKNOWN; i*=2) {
+	libst_title (test, "check we convert all the info bitfield");
+	for (i=1; i<=PK_INFO_ENUM_UNKNOWN; i++) {
 		string = pk_info_enum_to_text (i);
 		if (string == NULL) {
 			libst_failed (test, "failed to get %i", i);
@@ -1385,7 +1146,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the sig_type enums");
+	libst_title (test, "check we convert all the sig_type bitfield");
 	for (i=0; i<=PK_SIGTYPE_ENUM_UNKNOWN; i++) {
 		string = pk_sig_type_enum_to_text (i);
 		if (string == NULL) {
@@ -1396,7 +1157,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the upgrade enums");
+	libst_title (test, "check we convert all the upgrade bitfield");
 	for (i=0; i<=PK_DISTRO_UPGRADE_ENUM_UNKNOWN; i++) {
 		string = pk_distro_upgrade_enum_to_text (i);
 		if (string == NULL) {
@@ -1407,7 +1168,7 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
-	libst_title (test, "check we convert all the license enums");
+	libst_title (test, "check we convert all the license bitfield");
 	for (i=0; i<=PK_LICENSE_ENUM_UNKNOWN; i++) {
 		string = pk_license_enum_to_text (i);
 		if (string == NULL) {
@@ -1417,131 +1178,6 @@ libst_enum (LibSelfTest *test)
 	}
 	libst_success (test, NULL);
 
-	/************************************************************/
-	libst_title (test, "check we can convert filter enums to text (none)");
-	text = pk_filter_enums_to_text (PK_FILTER_ENUM_NONE);
-	if (pk_strequal (text, "none")) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "text was %s", text);
-	}
-	g_free (text);
-
-	/************************************************************/
-	libst_title (test, "check we can convert filter enums to text (single)");
-	text = pk_filter_enums_to_text (PK_FILTER_ENUM_NOT_DEVELOPMENT);
-	if (pk_strequal (text, "~devel")) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "text was %s", text);
-	}
-	g_free (text);
-
-	/************************************************************/
-	libst_title (test, "check we can convert filter enums to text (plural)");
-	text = pk_filter_enums_to_text (PK_FILTER_ENUM_NOT_DEVELOPMENT | PK_FILTER_ENUM_GUI | PK_FILTER_ENUM_NEWEST);
-	if (pk_strequal (text, "~devel;gui;newest")) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "text was %s", text);
-	}
-	g_free (text);
-
-	/************************************************************/
-	libst_title (test, "check we can convert filter text to enums (none)");
-	filter = pk_filter_enums_from_text ("none");
-	if (filter == PK_FILTER_ENUM_NONE) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "filter was %i", i);
-	}
-
-	/************************************************************/
-	libst_title (test, "check we can convert filter text to enums (single)");
-	filter = pk_filter_enums_from_text ("~devel");
-	if (filter == PK_FILTER_ENUM_NOT_DEVELOPMENT) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "filter was %i", i);
-	}
-
-	/************************************************************/
-	libst_title (test, "check we can convert filter text to enums (plural)");
-	filter = pk_filter_enums_from_text ("~devel;gui;newest");
-	if (filter == (PK_FILTER_ENUM_NOT_DEVELOPMENT | PK_FILTER_ENUM_GUI | PK_FILTER_ENUM_NEWEST)) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "filter was %i", i);
-	}
-
-	/************************************************************/
-	libst_title (test, "check we can add / remove enums");
-	filter = PK_FILTER_ENUM_NOT_DEVELOPMENT | PK_FILTER_ENUM_GUI | PK_FILTER_ENUM_NEWEST;
-	pk_enums_add (filter, PK_FILTER_ENUM_NOT_FREE);
-	pk_enums_remove (filter, PK_FILTER_ENUM_NOT_DEVELOPMENT);
-	text = pk_filter_enums_to_text (filter);
-	if (pk_strequal (text, "gui;~free;newest")) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "text was %s", text);
-	}
-	g_free (text);
-
-	/************************************************************/
-	libst_title (test, "check we can test enum presence");
-	filter = PK_FILTER_ENUM_NOT_DEVELOPMENT | PK_FILTER_ENUM_GUI | PK_FILTER_ENUM_NEWEST;
-	if (pk_enums_contain (filter, PK_FILTER_ENUM_NOT_DEVELOPMENT)) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "wrong boolean");
-	}
-	libst_title (test, "check we can test enum false-presence");
-	if (!pk_enums_contain (filter, PK_FILTER_ENUM_FREE)) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "wrong boolean");
-	}
-
-	/************************************************************/
-	libst_title (test, "check we can add / remove enums to nothing");
-	filter = PK_FILTER_ENUM_NOT_DEVELOPMENT;
-	pk_enums_remove (filter, PK_FILTER_ENUM_NOT_DEVELOPMENT);
-	text = pk_filter_enums_to_text (filter);
-	if (pk_strequal (text, "none")) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "text was %s", text);
-	}
-	g_free (text);
-
-	/************************************************************/
-	libst_title (test, "priority check missing");
-	values = PK_ROLE_ENUM_SEARCH_DETAILS | PK_ROLE_ENUM_SEARCH_GROUP;
-	value = pk_enums_contain_priority (values, PK_ROLE_ENUM_SEARCH_FILE, -1);
-	if (value == -1) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "returned priority %i when should be missing", value);
-	}
-
-	/************************************************************/
-	libst_title (test, "priority check first");
-	value = pk_enums_contain_priority (values, PK_ROLE_ENUM_SEARCH_GROUP, -1);
-	if (value == PK_ROLE_ENUM_SEARCH_GROUP) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "returned wrong value; %i", value);
-	}
-
-	/************************************************************/
-	libst_title (test, "priority check second, correct");
-	value = pk_enums_contain_priority (values, PK_ROLE_ENUM_SEARCH_FILE, PK_ROLE_ENUM_SEARCH_GROUP, -1);
-	if (value == PK_ROLE_ENUM_SEARCH_GROUP) {
-		libst_success (test, NULL);
-	} else {
-		libst_failed (test, "returned wrong value; %i", value);
-	}
-
 	libst_end (test);
 }
 #endif
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index e8a8c62..1d04637 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -37,11 +37,6 @@ typedef struct {
 	const gchar	*string;
 } PkEnumMatch;
 
-/* convenience functions as it's easy to forget the bitwise operators */
-#define pk_enums_add(enums,enum)	do { ((enums) |= (enum)); } while (0)
-#define pk_enums_remove(enums,enum)	do { ((enums) &= ~(enum)); } while (0)
-#define pk_enums_contain(enums,enum)	(((enums) & (enum)) > 0)
-
 /**
  * PkRoleEnum:
  *
@@ -51,36 +46,36 @@ typedef struct {
  * these constants
  **/
 typedef enum {
-	PK_ROLE_ENUM_CANCEL			= 1 << 0,
-	PK_ROLE_ENUM_GET_DEPENDS		= 1 << 1,
-	PK_ROLE_ENUM_GET_DETAILS		= 1 << 2,
-	PK_ROLE_ENUM_GET_FILES			= 1 << 3,
-	PK_ROLE_ENUM_GET_PACKAGES		= 1 << 4,
-	PK_ROLE_ENUM_GET_REPO_LIST		= 1 << 5,
-	PK_ROLE_ENUM_GET_REQUIRES		= 1 << 6,
-	PK_ROLE_ENUM_GET_UPDATE_DETAIL		= 1 << 7,
-	PK_ROLE_ENUM_GET_UPDATES		= 1 << 8,
-	PK_ROLE_ENUM_INSTALL_FILES		= 1 << 9,
-	PK_ROLE_ENUM_INSTALL_PACKAGES		= 1 << 10,
-	PK_ROLE_ENUM_INSTALL_SIGNATURE		= 1 << 11,
-	PK_ROLE_ENUM_REFRESH_CACHE		= 1 << 12,
-	PK_ROLE_ENUM_REMOVE_PACKAGES		= 1 << 13,
-	PK_ROLE_ENUM_REPO_ENABLE		= 1 << 14,
-	PK_ROLE_ENUM_REPO_SET_DATA		= 1 << 15,
-	PK_ROLE_ENUM_RESOLVE			= 1 << 16,
-	PK_ROLE_ENUM_ROLLBACK			= 1 << 17,
-	PK_ROLE_ENUM_SEARCH_DETAILS		= 1 << 18,
-	PK_ROLE_ENUM_SEARCH_FILE		= 1 << 19,
-	PK_ROLE_ENUM_SEARCH_GROUP		= 1 << 20,
-	PK_ROLE_ENUM_SEARCH_NAME		= 1 << 21,
-	PK_ROLE_ENUM_SERVICE_PACK		= 1 << 22,
-	PK_ROLE_ENUM_UPDATE_PACKAGES		= 1 << 23,
-	PK_ROLE_ENUM_UPDATE_SYSTEM		= 1 << 24,
-	PK_ROLE_ENUM_WHAT_PROVIDES		= 1 << 25,
-	PK_ROLE_ENUM_ACCEPT_EULA		= 1 << 26,
-	PK_ROLE_ENUM_DOWNLOAD_PACKAGES		= 1 << 27,
-	PK_ROLE_ENUM_GET_DISTRO_UPGRADES	= 1 << 28,
-	PK_ROLE_ENUM_UNKNOWN			= 1 << 29
+	PK_ROLE_ENUM_CANCEL,
+	PK_ROLE_ENUM_GET_DEPENDS,
+	PK_ROLE_ENUM_GET_DETAILS,
+	PK_ROLE_ENUM_GET_FILES,
+	PK_ROLE_ENUM_GET_PACKAGES,
+	PK_ROLE_ENUM_GET_REPO_LIST,
+	PK_ROLE_ENUM_GET_REQUIRES,
+	PK_ROLE_ENUM_GET_UPDATE_DETAIL,
+	PK_ROLE_ENUM_GET_UPDATES,
+	PK_ROLE_ENUM_INSTALL_FILES,
+	PK_ROLE_ENUM_INSTALL_PACKAGES,
+	PK_ROLE_ENUM_INSTALL_SIGNATURE,
+	PK_ROLE_ENUM_REFRESH_CACHE,
+	PK_ROLE_ENUM_REMOVE_PACKAGES,
+	PK_ROLE_ENUM_REPO_ENABLE,
+	PK_ROLE_ENUM_REPO_SET_DATA,
+	PK_ROLE_ENUM_RESOLVE,
+	PK_ROLE_ENUM_ROLLBACK,
+	PK_ROLE_ENUM_SEARCH_DETAILS,
+	PK_ROLE_ENUM_SEARCH_FILE,
+	PK_ROLE_ENUM_SEARCH_GROUP,
+	PK_ROLE_ENUM_SEARCH_NAME,
+	PK_ROLE_ENUM_SERVICE_PACK,
+	PK_ROLE_ENUM_UPDATE_PACKAGES,
+	PK_ROLE_ENUM_UPDATE_SYSTEM,
+	PK_ROLE_ENUM_WHAT_PROVIDES,
+	PK_ROLE_ENUM_ACCEPT_EULA,
+	PK_ROLE_ENUM_DOWNLOAD_PACKAGES,
+	PK_ROLE_ENUM_GET_DISTRO_UPGRADES,
+	PK_ROLE_ENUM_UNKNOWN
 } PkRoleEnum;
 
 /**
@@ -104,34 +99,34 @@ typedef enum {
  * when they are ready to start running the transaction and after a lock has been got.
  **/
 typedef enum {
-	PK_STATUS_ENUM_WAIT			= 1 << 0,
-	PK_STATUS_ENUM_SETUP			= 1 << 1,
-	PK_STATUS_ENUM_RUNNING			= 1 << 2,
-	PK_STATUS_ENUM_QUERY			= 1 << 3,
-	PK_STATUS_ENUM_INFO			= 1 << 4,
-	PK_STATUS_ENUM_REMOVE			= 1 << 5,
-	PK_STATUS_ENUM_REFRESH_CACHE		= 1 << 6,
-	PK_STATUS_ENUM_DOWNLOAD			= 1 << 7,
-	PK_STATUS_ENUM_INSTALL			= 1 << 8,
-	PK_STATUS_ENUM_UPDATE			= 1 << 9,
-	PK_STATUS_ENUM_CLEANUP			= 1 << 10,
-	PK_STATUS_ENUM_OBSOLETE			= 1 << 11,
-	PK_STATUS_ENUM_DEP_RESOLVE		= 1 << 12,
-	PK_STATUS_ENUM_SIG_CHECK		= 1 << 13,
-	PK_STATUS_ENUM_ROLLBACK			= 1 << 14,
-	PK_STATUS_ENUM_TEST_COMMIT		= 1 << 15,
-	PK_STATUS_ENUM_COMMIT			= 1 << 16,
-	PK_STATUS_ENUM_REQUEST			= 1 << 17,
-	PK_STATUS_ENUM_FINISHED			= 1 << 18,
-	PK_STATUS_ENUM_CANCEL			= 1 << 19,
-	PK_STATUS_ENUM_DOWNLOAD_REPOSITORY	= 1 << 20,
-	PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST	= 1 << 21,
-	PK_STATUS_ENUM_DOWNLOAD_FILELIST	= 1 << 22,
-	PK_STATUS_ENUM_DOWNLOAD_CHANGELOG	= 1 << 23,
-	PK_STATUS_ENUM_DOWNLOAD_GROUP		= 1 << 24,
-	PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO	= 1 << 25,
-	PK_STATUS_ENUM_REPACKAGING		= 1 << 26,
-	PK_STATUS_ENUM_UNKNOWN			= 1 << 27
+	PK_STATUS_ENUM_WAIT,
+	PK_STATUS_ENUM_SETUP,
+	PK_STATUS_ENUM_RUNNING,
+	PK_STATUS_ENUM_QUERY,
+	PK_STATUS_ENUM_INFO,
+	PK_STATUS_ENUM_REMOVE,
+	PK_STATUS_ENUM_REFRESH_CACHE,
+	PK_STATUS_ENUM_DOWNLOAD,
+	PK_STATUS_ENUM_INSTALL,
+	PK_STATUS_ENUM_UPDATE,
+	PK_STATUS_ENUM_CLEANUP,
+	PK_STATUS_ENUM_OBSOLETE,
+	PK_STATUS_ENUM_DEP_RESOLVE,
+	PK_STATUS_ENUM_SIG_CHECK,
+	PK_STATUS_ENUM_ROLLBACK,
+	PK_STATUS_ENUM_TEST_COMMIT,
+	PK_STATUS_ENUM_COMMIT,
+	PK_STATUS_ENUM_REQUEST,
+	PK_STATUS_ENUM_FINISHED,
+	PK_STATUS_ENUM_CANCEL,
+	PK_STATUS_ENUM_DOWNLOAD_REPOSITORY,
+	PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST,
+	PK_STATUS_ENUM_DOWNLOAD_FILELIST,
+	PK_STATUS_ENUM_DOWNLOAD_CHANGELOG,
+	PK_STATUS_ENUM_DOWNLOAD_GROUP,
+	PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO,
+	PK_STATUS_ENUM_REPACKAGING,
+	PK_STATUS_ENUM_UNKNOWN
 } PkStatusEnum;
 
 /**
@@ -152,12 +147,12 @@ typedef enum {
 /**
  * PkNetworkEnum:
  **/
-typedef enum {					     /* fso */
-	PK_NETWORK_ENUM_OFFLINE			= 0, /* 000 */
-	PK_NETWORK_ENUM_ONLINE			= 1, /* 001 */
-	PK_NETWORK_ENUM_SLOW			= 3, /* 011 */
-	PK_NETWORK_ENUM_FAST			= 5, /* 101 */
-	PK_NETWORK_ENUM_UNKNOWN			= 7  /* 111 */
+typedef enum {
+	PK_NETWORK_ENUM_OFFLINE,
+	PK_NETWORK_ENUM_ONLINE,
+	PK_NETWORK_ENUM_SLOW,
+	PK_NETWORK_ENUM_FAST,
+	PK_NETWORK_ENUM_UNKNOWN
 } PkNetworkEnum;
 
 /**
@@ -166,28 +161,28 @@ typedef enum {					     /* fso */
  * The filter types
  **/
 typedef enum {
-	PK_FILTER_ENUM_NONE			= 0,
-	PK_FILTER_ENUM_INSTALLED		= 1 << 0,
-	PK_FILTER_ENUM_NOT_INSTALLED		= 1 << 1,
-	PK_FILTER_ENUM_DEVELOPMENT		= 1 << 2,
-	PK_FILTER_ENUM_NOT_DEVELOPMENT		= 1 << 3,
-	PK_FILTER_ENUM_GUI			= 1 << 4,
-	PK_FILTER_ENUM_NOT_GUI			= 1 << 5,
-	PK_FILTER_ENUM_FREE			= 1 << 6,
-	PK_FILTER_ENUM_NOT_FREE			= 1 << 7,
-	PK_FILTER_ENUM_VISIBLE			= 1 << 8,
-	PK_FILTER_ENUM_NOT_VISIBLE		= 1 << 9,
-	PK_FILTER_ENUM_SUPPORTED		= 1 << 10,
-	PK_FILTER_ENUM_NOT_SUPPORTED		= 1 << 11,
-	PK_FILTER_ENUM_BASENAME			= 1 << 12,
-	PK_FILTER_ENUM_NOT_BASENAME		= 1 << 13,
-	PK_FILTER_ENUM_NEWEST			= 1 << 14,
-	PK_FILTER_ENUM_NOT_NEWEST		= 1 << 15,
-	PK_FILTER_ENUM_ARCH			= 1 << 16,
-	PK_FILTER_ENUM_NOT_ARCH			= 1 << 17,
-	PK_FILTER_ENUM_SOURCE			= 1 << 18,
-	PK_FILTER_ENUM_NOT_SOURCE		= 1 << 19,
-	PK_FILTER_ENUM_UNKNOWN			= 1 << 20
+	PK_FILTER_ENUM_NONE,
+	PK_FILTER_ENUM_INSTALLED,
+	PK_FILTER_ENUM_NOT_INSTALLED,
+	PK_FILTER_ENUM_DEVELOPMENT,
+	PK_FILTER_ENUM_NOT_DEVELOPMENT,
+	PK_FILTER_ENUM_GUI,
+	PK_FILTER_ENUM_NOT_GUI,
+	PK_FILTER_ENUM_FREE,
+	PK_FILTER_ENUM_NOT_FREE,
+	PK_FILTER_ENUM_VISIBLE,
+	PK_FILTER_ENUM_NOT_VISIBLE,
+	PK_FILTER_ENUM_SUPPORTED,
+	PK_FILTER_ENUM_NOT_SUPPORTED,
+	PK_FILTER_ENUM_BASENAME,
+	PK_FILTER_ENUM_NOT_BASENAME,
+	PK_FILTER_ENUM_NEWEST,
+	PK_FILTER_ENUM_NOT_NEWEST,
+	PK_FILTER_ENUM_ARCH,
+	PK_FILTER_ENUM_NOT_ARCH,
+	PK_FILTER_ENUM_SOURCE,
+	PK_FILTER_ENUM_NOT_SOURCE,
+	PK_FILTER_ENUM_UNKNOWN
 } PkFilterEnum;
 
 /**
@@ -269,38 +264,38 @@ typedef enum {
  * The group type
  **/
 typedef enum {
-	PK_GROUP_ENUM_ACCESSIBILITY		= 1 << 0,
-	PK_GROUP_ENUM_ACCESSORIES		= 1 << 1,
-	PK_GROUP_ENUM_ADMIN_TOOLS		= 1 << 2,
-	PK_GROUP_ENUM_COMMUNICATION		= 1 << 3,
-	PK_GROUP_ENUM_DESKTOP_GNOME		= 1 << 4,
-	PK_GROUP_ENUM_DESKTOP_KDE		= 1 << 5,
-	PK_GROUP_ENUM_DESKTOP_OTHER		= 1 << 6,
-	PK_GROUP_ENUM_DESKTOP_XFCE		= 1 << 7,
-	PK_GROUP_ENUM_EDUCATION			= 1 << 8,
-	PK_GROUP_ENUM_FONTS			= 1 << 9,
-	PK_GROUP_ENUM_GAMES			= 1 << 10,
-	PK_GROUP_ENUM_GRAPHICS			= 1 << 11,
-	PK_GROUP_ENUM_INTERNET			= 1 << 12,
-	PK_GROUP_ENUM_LEGACY			= 1 << 13,
-	PK_GROUP_ENUM_LOCALIZATION		= 1 << 14,
-	PK_GROUP_ENUM_MAPS			= 1 << 15,
-	PK_GROUP_ENUM_MULTIMEDIA		= 1 << 16,
-	PK_GROUP_ENUM_NETWORK			= 1 << 17,
-	PK_GROUP_ENUM_OFFICE			= 1 << 18,
-	PK_GROUP_ENUM_OTHER			= 1 << 19,
-	PK_GROUP_ENUM_POWER_MANAGEMENT		= 1 << 20,
-	PK_GROUP_ENUM_PROGRAMMING		= 1 << 21,
-	PK_GROUP_ENUM_PUBLISHING		= 1 << 22,
-	PK_GROUP_ENUM_REPOS			= 1 << 23,
-	PK_GROUP_ENUM_SECURITY			= 1 << 24,
-	PK_GROUP_ENUM_SERVERS			= 1 << 25,
-	PK_GROUP_ENUM_SYSTEM			= 1 << 26,
-	PK_GROUP_ENUM_VIRTUALIZATION		= 1 << 27,
-//	PK_GROUP_ENUM_SCIENCE			= 1 << 28,
-//	PK_GROUP_ENUM_DOCUMENTATION		= 1 << 29,
-//	PK_GROUP_ENUM_ELECTRONICS		= 1 << 30,
-	PK_GROUP_ENUM_UNKNOWN			= 1 << 28
+	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_UNKNOWN
 } PkGroupEnum;
 
 /**
@@ -347,22 +342,22 @@ typedef enum {
  * package action, rather than a general state
  **/
 typedef enum {
-	PK_INFO_ENUM_INSTALLED			= 1 << 0,
-	PK_INFO_ENUM_AVAILABLE			= 1 << 1,
-	PK_INFO_ENUM_LOW			= 1 << 2,
-	PK_INFO_ENUM_ENHANCEMENT		= 1 << 3,
-	PK_INFO_ENUM_NORMAL			= 1 << 4,
-	PK_INFO_ENUM_BUGFIX			= 1 << 5,
-	PK_INFO_ENUM_IMPORTANT			= 1 << 6,
-	PK_INFO_ENUM_SECURITY			= 1 << 7,
-	PK_INFO_ENUM_BLOCKED			= 1 << 8,
-	PK_INFO_ENUM_DOWNLOADING		= 1 << 9,
-	PK_INFO_ENUM_UPDATING			= 1 << 10,
-	PK_INFO_ENUM_INSTALLING			= 1 << 11,
-	PK_INFO_ENUM_REMOVING			= 1 << 12,
-	PK_INFO_ENUM_CLEANUP			= 1 << 13,
-	PK_INFO_ENUM_OBSOLETING			= 1 << 14,
-	PK_INFO_ENUM_UNKNOWN			= 1 << 15
+	PK_INFO_ENUM_INSTALLED,
+	PK_INFO_ENUM_AVAILABLE,
+	PK_INFO_ENUM_LOW,
+	PK_INFO_ENUM_ENHANCEMENT,
+	PK_INFO_ENUM_NORMAL,
+	PK_INFO_ENUM_BUGFIX,
+	PK_INFO_ENUM_IMPORTANT,
+	PK_INFO_ENUM_SECURITY,
+	PK_INFO_ENUM_BLOCKED,
+	PK_INFO_ENUM_DOWNLOADING,
+	PK_INFO_ENUM_UPDATING,
+	PK_INFO_ENUM_INSTALLING,
+	PK_INFO_ENUM_REMOVING,
+	PK_INFO_ENUM_CLEANUP,
+	PK_INFO_ENUM_OBSOLETING,
+	PK_INFO_ENUM_UNKNOWN
 } PkInfoEnum;
 
 /**
@@ -536,8 +531,6 @@ guint		 pk_enum_find_value			(PkEnumMatch	*table,
 const gchar	*pk_enum_find_string			(PkEnumMatch	*table,
 							 guint		 value)
 							 G_GNUC_WARN_UNUSED_RESULT;
-gint		 pk_enums_contain_priority		(guint		 values,
-							 gint		 value, ...);
 
 PkSigTypeEnum    pk_sig_type_enum_from_text             (const gchar    *sig_type);
 const gchar     *pk_sig_type_enum_to_text               (PkSigTypeEnum   sig_type);
@@ -565,8 +558,6 @@ const gchar	*pk_status_enum_to_text			(PkStatusEnum	 status);
 
 PkRoleEnum	 pk_role_enum_from_text			(const gchar	*role);
 const gchar	*pk_role_enum_to_text			(PkRoleEnum	 role);
-PkRoleEnum	 pk_role_enums_from_text 		(const gchar	*roles);
-gchar		*pk_role_enums_to_text			(PkRoleEnum	 roles);
 
 PkErrorCodeEnum	 pk_error_enum_from_text		(const gchar	*code);
 const gchar	*pk_error_enum_to_text			(PkErrorCodeEnum code);
@@ -579,13 +570,9 @@ const gchar	*pk_message_enum_to_text		(PkMessageEnum	 message);
 
 PkGroupEnum	 pk_group_enum_from_text		(const gchar	*group);
 const gchar	*pk_group_enum_to_text			(PkGroupEnum	 group);
-PkGroupEnum	 pk_group_enums_from_text 		(const gchar	*groups);
-gchar		*pk_group_enums_to_text			(PkGroupEnum	 groups);
 
 PkFilterEnum	 pk_filter_enum_from_text		(const gchar	*filter);
 const gchar	*pk_filter_enum_to_text			(PkFilterEnum	 filter);
-PkFilterEnum	 pk_filter_enums_from_text 		(const gchar	*filters);
-gchar		*pk_filter_enums_to_text		(PkFilterEnum	 filters);
 
 PkProvidesEnum	 pk_provides_enum_from_text		(const gchar	*provides);
 const gchar	*pk_provides_enum_to_text		(PkProvidesEnum	 provides);
diff --git a/libpackagekit/pk-self-test.c b/libpackagekit/pk-self-test.c
index 70fc642..1dbfd51 100644
--- a/libpackagekit/pk-self-test.c
+++ b/libpackagekit/pk-self-test.c
@@ -32,6 +32,7 @@ void libst_package_ids (LibSelfTest *test);
 void libst_package_obj (LibSelfTest *test);
 void libst_package_list (LibSelfTest *test);
 void libst_enum (LibSelfTest *test);
+void libst_bitfield (LibSelfTest *test);
 void libst_common (LibSelfTest *test);
 void libst_enum_list (LibSelfTest *test);
 void libst_extra (LibSelfTest *test);
@@ -58,6 +59,7 @@ main (int argc, char **argv)
 	libst_package_obj (&test);
 	libst_package_list (&test);
 	libst_enum (&test);
+	libst_bitfield (&test);
 	libst_extra (&test);
 	libst_client (&test);
 	libst_catalog (&test);
diff --git a/src/Makefile.am b/src/Makefile.am
index 3ee3b27..6d5d757 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -206,7 +206,9 @@ gprof: clean-gprof all check
 endif
 
 install-data-hook:
-	mkdir -p $(localstatedir)/cache/PackageKit/downloads
+	if test -w $(localstatedir); then \
+		mkdir -p $(localstatedir)/cache/PackageKit/downloads; \
+	fi
 
 EXTRA_DIST =						\
 	pk-marshal.list					\
diff --git a/src/pk-backend-dbus.c b/src/pk-backend-dbus.c
index 720cf2b..be2651c 100644
--- a/src/pk-backend-dbus.c
+++ b/src/pk-backend-dbus.c
@@ -605,7 +605,7 @@ pk_backend_dbus_cancel (PkBackendDbus *backend_dbus)
  * pk_backend_dbus_get_updates:
  **/
 gboolean
-pk_backend_dbus_get_updates (PkBackendDbus *backend_dbus, PkFilterEnum filters)
+pk_backend_dbus_get_updates (PkBackendDbus *backend_dbus, PkBitfield filters)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -616,7 +616,7 @@ pk_backend_dbus_get_updates (PkBackendDbus *backend_dbus, PkFilterEnum filters)
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetUpdates", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
@@ -637,7 +637,7 @@ pk_backend_dbus_get_updates (PkBackendDbus *backend_dbus, PkFilterEnum filters)
  * pk_backend_dbus_get_repo_list:
  **/
 gboolean
-pk_backend_dbus_get_repo_list (PkBackendDbus *backend_dbus, PkFilterEnum filters)
+pk_backend_dbus_get_repo_list (PkBackendDbus *backend_dbus, PkBitfield filters)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -648,7 +648,7 @@ pk_backend_dbus_get_repo_list (PkBackendDbus *backend_dbus, PkFilterEnum filters
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetRepoList", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
@@ -792,7 +792,7 @@ pk_backend_dbus_repo_set_data (PkBackendDbus *backend_dbus, const gchar *rid,
  * pk_backend_dbus_resolve:
  **/
 gboolean
-pk_backend_dbus_resolve (PkBackendDbus *backend_dbus, PkFilterEnum filters, gchar **packages)
+pk_backend_dbus_resolve (PkBackendDbus *backend_dbus, PkBitfield filters, gchar **packages)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -804,7 +804,7 @@ pk_backend_dbus_resolve (PkBackendDbus *backend_dbus, PkFilterEnum filters, gcha
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "Resolve", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRV, packages,
@@ -856,7 +856,7 @@ pk_backend_dbus_rollback (PkBackendDbus *backend_dbus, const gchar *transaction_
  * pk_backend_dbus_search_name:
  **/
 gboolean
-pk_backend_dbus_search_name (PkBackendDbus *backend_dbus, PkFilterEnum filters, const gchar *search)
+pk_backend_dbus_search_name (PkBackendDbus *backend_dbus, PkBitfield filters, const gchar *search)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -868,7 +868,7 @@ pk_backend_dbus_search_name (PkBackendDbus *backend_dbus, PkFilterEnum filters,
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "SearchName", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRING, search,
@@ -890,7 +890,7 @@ pk_backend_dbus_search_name (PkBackendDbus *backend_dbus, PkFilterEnum filters,
  * pk_backend_dbus_search_details:
  **/
 gboolean
-pk_backend_dbus_search_details (PkBackendDbus *backend_dbus, PkFilterEnum filters, const gchar *search)
+pk_backend_dbus_search_details (PkBackendDbus *backend_dbus, PkBitfield filters, const gchar *search)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -902,7 +902,7 @@ pk_backend_dbus_search_details (PkBackendDbus *backend_dbus, PkFilterEnum filter
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "SearchDetails", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRING, search,
@@ -924,7 +924,7 @@ pk_backend_dbus_search_details (PkBackendDbus *backend_dbus, PkFilterEnum filter
  * pk_backend_dbus_search_group:
  **/
 gboolean
-pk_backend_dbus_search_group (PkBackendDbus *backend_dbus, PkFilterEnum filters, const gchar *search)
+pk_backend_dbus_search_group (PkBackendDbus *backend_dbus, PkBitfield filters, const gchar *search)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -936,7 +936,7 @@ pk_backend_dbus_search_group (PkBackendDbus *backend_dbus, PkFilterEnum filters,
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "SearchGroup", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRING, search,
@@ -958,7 +958,7 @@ pk_backend_dbus_search_group (PkBackendDbus *backend_dbus, PkFilterEnum filters,
  * pk_backend_dbus_search_file:
  **/
 gboolean
-pk_backend_dbus_search_file (PkBackendDbus *backend_dbus, PkFilterEnum filters, const gchar *search)
+pk_backend_dbus_search_file (PkBackendDbus *backend_dbus, PkBitfield filters, const gchar *search)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -970,7 +970,7 @@ pk_backend_dbus_search_file (PkBackendDbus *backend_dbus, PkFilterEnum filters,
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "SearchFile", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRING, search,
@@ -992,7 +992,7 @@ pk_backend_dbus_search_file (PkBackendDbus *backend_dbus, PkFilterEnum filters,
  * pk_backend_dbus_get_depends:
  **/
 gboolean
-pk_backend_dbus_get_depends (PkBackendDbus *backend_dbus, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+pk_backend_dbus_get_depends (PkBackendDbus *backend_dbus, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -1004,7 +1004,7 @@ pk_backend_dbus_get_depends (PkBackendDbus *backend_dbus, PkFilterEnum filters,
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetDepends", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRV, package_ids,
@@ -1027,7 +1027,7 @@ pk_backend_dbus_get_depends (PkBackendDbus *backend_dbus, PkFilterEnum filters,
  * pk_backend_dbus_get_requires:
  **/
 gboolean
-pk_backend_dbus_get_requires (PkBackendDbus *backend_dbus, PkFilterEnum filters, gchar **package_ids, gboolean recursive)
+pk_backend_dbus_get_requires (PkBackendDbus *backend_dbus, PkBitfield filters, gchar **package_ids, gboolean recursive)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -1039,7 +1039,7 @@ pk_backend_dbus_get_requires (PkBackendDbus *backend_dbus, PkFilterEnum filters,
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetRequires", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRV, package_ids,
@@ -1062,7 +1062,7 @@ pk_backend_dbus_get_requires (PkBackendDbus *backend_dbus, PkFilterEnum filters,
  * pk_backend_dbus_get_packages:
  **/
 gboolean
-pk_backend_dbus_get_packages (PkBackendDbus *backend_dbus, PkFilterEnum filters)
+pk_backend_dbus_get_packages (PkBackendDbus *backend_dbus, PkBitfield filters)
 {
 	gboolean ret;
 	GError *error = NULL;
@@ -1073,7 +1073,7 @@ pk_backend_dbus_get_packages (PkBackendDbus *backend_dbus, PkFilterEnum filters)
 
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "GetPackages", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
@@ -1370,7 +1370,7 @@ pk_backend_dbus_service_pack (PkBackendDbus *backend_dbus, const gchar *location
  * pk_backend_dbus_what_provides:
  **/
 gboolean
-pk_backend_dbus_what_provides (PkBackendDbus *backend_dbus, PkFilterEnum filters,
+pk_backend_dbus_what_provides (PkBackendDbus *backend_dbus, PkBitfield filters,
 			       PkProvidesEnum provides, const gchar *search)
 {
 	gboolean ret;
@@ -1386,7 +1386,7 @@ pk_backend_dbus_what_provides (PkBackendDbus *backend_dbus, PkFilterEnum filters
 	/* new sync method call */
 	pk_backend_dbus_time_reset (backend_dbus);
 	provides_text = pk_provides_enum_to_text (provides);
-	filters_text = pk_filter_enums_to_text (filters);
+	filters_text = pk_filter_bitfield_to_text (filters);
 	ret = dbus_g_proxy_call (backend_dbus->priv->proxy, "WhatProvides", &error,
 				 G_TYPE_STRING, filters_text,
 				 G_TYPE_STRING, provides_text,
diff --git a/src/pk-backend-dbus.h b/src/pk-backend-dbus.h
index c4c13b1..b9df368 100644
--- a/src/pk-backend-dbus.h
+++ b/src/pk-backend-dbus.h
@@ -63,78 +63,78 @@ typedef struct
 
 GType		 pk_backend_dbus_get_type		(void) G_GNUC_CONST;
 PkBackendDbus	*pk_backend_dbus_new			(void);
-gboolean	 pk_backend_dbus_refresh_cache		(PkBackendDbus	*backend_dbus,
-							 gboolean	 force);
-gboolean	 pk_backend_dbus_update_system		(PkBackendDbus	*backend_dbus);
-gboolean	 pk_backend_dbus_resolve		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 gchar		**packages);
-gboolean	 pk_backend_dbus_rollback		(PkBackendDbus	*backend_dbus,
-							 const gchar	*transaction_id);
-gboolean	 pk_backend_dbus_search_name		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 const gchar	*search);
-gboolean	 pk_backend_dbus_search_details		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 const gchar	*search);
-gboolean	 pk_backend_dbus_search_group		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 const gchar	*search);
-gboolean	 pk_backend_dbus_search_file		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 const gchar	*search);
-gboolean	 pk_backend_dbus_get_packages		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters);
-gboolean	 pk_backend_dbus_download_packages	(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids,
-							 const gchar	*directory);
-gboolean	 pk_backend_dbus_get_depends		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 gchar		**package_ids,
-							 gboolean	 recursive);
-gboolean	 pk_backend_dbus_get_requires		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 gchar		**package_ids,
-							 gboolean	 recursive);
-gboolean	 pk_backend_dbus_get_update_detail	(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids);
-gboolean	 pk_backend_dbus_get_details		(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids);
-gboolean	 pk_backend_dbus_get_files		(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids);
-gboolean	 pk_backend_dbus_remove_packages	(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids,
-							 gboolean	 allow_deps,
-							 gboolean	 autoremove);
-gboolean	 pk_backend_dbus_install_packages	(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids);
-gboolean	 pk_backend_dbus_update_packages	(PkBackendDbus	*backend_dbus,
-							 gchar		**package_ids);
-gboolean	 pk_backend_dbus_install_files		(PkBackendDbus	*backend_dbus,
-							 gboolean	 trusted,
-							 gchar		**full_paths);
-gboolean	 pk_backend_dbus_service_pack		(PkBackendDbus	*backend_dbus,
-							 const gchar	*location,
-							 gboolean	 enabled);
-gboolean	 pk_backend_dbus_what_provides		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters,
-							 PkProvidesEnum	 provides,
-							 const gchar	*search);
-gboolean	 pk_backend_dbus_kill			(PkBackendDbus	*backend_dbus);
-gboolean	 pk_backend_dbus_repo_enable		(PkBackendDbus	*backend_dbus,
-							 const gchar	*rid,
-							 gboolean	 enabled);
-gboolean	 pk_backend_dbus_repo_set_data		(PkBackendDbus	*backend_dbus,
-							 const gchar	*rid,
-							 const gchar	*parameter,
-							 const gchar	*value);
-gboolean	 pk_backend_dbus_get_repo_list		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters);
-gboolean	 pk_backend_dbus_cancel			(PkBackendDbus	*backend_dbus);
-gboolean	 pk_backend_dbus_get_updates		(PkBackendDbus	*backend_dbus,
-							 PkFilterEnum	 filters);
-gboolean	 pk_backend_dbus_set_name		(PkBackendDbus	*backend_dbus,
-							 const gchar	*service);
+gboolean	 pk_backend_dbus_refresh_cache		(PkBackendDbus		*backend_dbus,
+							 gboolean		 force);
+gboolean	 pk_backend_dbus_update_system		(PkBackendDbus		*backend_dbus);
+gboolean	 pk_backend_dbus_resolve		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 gchar			**packages);
+gboolean	 pk_backend_dbus_rollback		(PkBackendDbus		*backend_dbus,
+							 const gchar		*transaction_id);
+gboolean	 pk_backend_dbus_search_name		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 const gchar		*search);
+gboolean	 pk_backend_dbus_search_details		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 const gchar		*search);
+gboolean	 pk_backend_dbus_search_group		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 const gchar		*search);
+gboolean	 pk_backend_dbus_search_file		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 const gchar		*search);
+gboolean	 pk_backend_dbus_get_packages		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters);
+gboolean	 pk_backend_dbus_download_packages	(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids,
+							 const gchar		*directory);
+gboolean	 pk_backend_dbus_get_depends		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 gchar			**package_ids,
+							 gboolean		 recursive);
+gboolean	 pk_backend_dbus_get_requires		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 gchar			**package_ids,
+							 gboolean		 recursive);
+gboolean	 pk_backend_dbus_get_update_detail	(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids);
+gboolean	 pk_backend_dbus_get_details		(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids);
+gboolean	 pk_backend_dbus_get_files		(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids);
+gboolean	 pk_backend_dbus_remove_packages	(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids,
+							 gboolean		 allow_deps,
+							 gboolean		 autoremove);
+gboolean	 pk_backend_dbus_install_packages	(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids);
+gboolean	 pk_backend_dbus_update_packages	(PkBackendDbus		*backend_dbus,
+							 gchar			**package_ids);
+gboolean	 pk_backend_dbus_install_files		(PkBackendDbus		*backend_dbus,
+							 gboolean		 trusted,
+							 gchar			**full_paths);
+gboolean	 pk_backend_dbus_service_pack		(PkBackendDbus		*backend_dbus,
+							 const gchar		*location,
+							 gboolean		 enabled);
+gboolean	 pk_backend_dbus_what_provides		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters,
+							 PkProvidesEnum		 provides,
+							 const gchar		*search);
+gboolean	 pk_backend_dbus_kill			(PkBackendDbus		*backend_dbus);
+gboolean	 pk_backend_dbus_repo_enable		(PkBackendDbus		*backend_dbus,
+							 const gchar		*rid,
+							 gboolean		 enabled);
+gboolean	 pk_backend_dbus_repo_set_data		(PkBackendDbus		*backend_dbus,
+							 const gchar		*rid,
+							 const gchar		*parameter,
+							 const gchar		*value);
+gboolean	 pk_backend_dbus_get_repo_list		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters);
+gboolean	 pk_backend_dbus_cancel			(PkBackendDbus		*backend_dbus);
+gboolean	 pk_backend_dbus_get_updates		(PkBackendDbus		*backend_dbus,
+							 PkBitfield	 filters);
+gboolean	 pk_backend_dbus_set_name		(PkBackendDbus		*backend_dbus,
+							 const gchar		*service);
 
 G_END_DECLS
 
diff --git a/src/pk-backend-internal.h b/src/pk-backend-internal.h
index 2bffaff..b828d4e 100644
--- a/src/pk-backend-internal.h
+++ b/src/pk-backend-internal.h
@@ -24,6 +24,7 @@
 
 #include <glib-object.h>
 #include "pk-backend.h"
+#include "pk-bitfield.h"
 
 G_BEGIN_DECLS
 
@@ -67,9 +68,9 @@ gchar		*pk_backend_get_name			(PkBackend	*backend)
 gboolean	 pk_backend_get_backend_detail		(PkBackend	*backend,
 							 gchar		**name,
 							 gchar		**author);
-PkGroupEnum	 pk_backend_get_groups			(PkBackend	*backend);
-PkFilterEnum	 pk_backend_get_filters			(PkBackend	*backend);
-PkRoleEnum	 pk_backend_get_actions			(PkBackend	*backend);
+PkBitfield	 pk_backend_get_groups			(PkBackend	*backend);
+PkBitfield	 pk_backend_get_filters			(PkBackend	*backend);
+PkBitfield	 pk_backend_get_actions			(PkBackend	*backend);
 
 G_END_DECLS
 
diff --git a/src/pk-backend-python.c b/src/pk-backend-python.c
index 66d4d17..b0f6c68 100644
--- a/src/pk-backend-python.c
+++ b/src/pk-backend-python.c
@@ -510,7 +510,7 @@ pk_backend_python_cancel (PkBackendPython *python)
 gboolean
 pk_backend_python_get_updates (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *method = "get_updates";
 
 	g_return_val_if_fail (PK_IS_BACKEND_PYTHON (python), FALSE);
@@ -535,7 +535,7 @@ pk_backend_python_get_updates (PkBackendPython *python)
 gboolean
 pk_backend_python_get_repo_list (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *method = "get_repo_list";
 
 	g_return_val_if_fail (PK_IS_BACKEND_PYTHON (python), FALSE);
@@ -660,7 +660,7 @@ pk_backend_python_repo_set_data (PkBackendPython *python)
 gboolean
 pk_backend_python_resolve (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gchar **packages;
 	const gchar *method = "resolve";
 
@@ -709,7 +709,7 @@ pk_backend_python_rollback (PkBackendPython *python)
 gboolean
 pk_backend_python_search_name (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *search;
 	const gchar *method = "search_name";
 
@@ -735,7 +735,7 @@ pk_backend_python_search_name (PkBackendPython *python)
 gboolean
 pk_backend_python_search_details (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *search;
 	const gchar *method = "search_details";
 
@@ -761,7 +761,7 @@ pk_backend_python_search_details (PkBackendPython *python)
 gboolean
 pk_backend_python_search_group (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *search;
 	const gchar *method = "search_group";
 
@@ -787,7 +787,7 @@ pk_backend_python_search_group (PkBackendPython *python)
 gboolean
 pk_backend_python_search_file (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *search;
 	const gchar *method = "search_file";
 
@@ -813,7 +813,7 @@ pk_backend_python_search_file (PkBackendPython *python)
 gboolean
 pk_backend_python_get_depends (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gchar **package_ids;
 	gboolean recursive;
 	const gchar *method = "get_depends";
@@ -841,7 +841,7 @@ pk_backend_python_get_depends (PkBackendPython *python)
 gboolean
 pk_backend_python_get_requires (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	gchar **package_ids;
 	gboolean recursive;
 	const gchar *method = "get_requires";
@@ -869,7 +869,7 @@ pk_backend_python_get_requires (PkBackendPython *python)
 gboolean
 pk_backend_python_get_packages (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	const gchar *method = "get_packages";
 
 	g_return_val_if_fail (PK_IS_BACKEND_PYTHON (python), FALSE);
@@ -1116,7 +1116,7 @@ pk_backend_python_service_pack (PkBackendPython *python)
 gboolean
 pk_backend_python_what_provides (PkBackendPython *python)
 {
-	PkFilterEnum filters;
+	PkBitfield filters;
 	PkProvidesEnum provides;
 	const gchar *search;
 	const gchar *method = "what_provides";
diff --git a/src/pk-backend.c b/src/pk-backend.c
index 92697bf..d5166cf 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -139,7 +139,7 @@ static guint signals [PK_BACKEND_LAST_SIGNAL] = { 0 };
 /**
  * pk_backend_get_groups:
  **/
-PkGroupEnum
+PkBitfield
 pk_backend_get_groups (PkBackend *backend)
 {
 	g_return_val_if_fail (PK_IS_BACKEND (backend), PK_GROUP_ENUM_UNKNOWN);
@@ -155,7 +155,7 @@ pk_backend_get_groups (PkBackend *backend)
 /**
  * pk_backend_get_filters:
  **/
-PkFilterEnum
+PkBitfield
 pk_backend_get_filters (PkBackend *backend)
 {
 	g_return_val_if_fail (PK_IS_BACKEND (backend), PK_FILTER_ENUM_UNKNOWN);
@@ -171,10 +171,10 @@ pk_backend_get_filters (PkBackend *backend)
 /**
  * pk_backend_get_actions:
  **/
-PkRoleEnum
+PkBitfield
 pk_backend_get_actions (PkBackend *backend)
 {
-	PkRoleEnum roles = 0;
+	PkBitfield roles = 0;
 	PkBackendDesc *desc;
 
 	g_return_val_if_fail (PK_IS_BACKEND (backend), PK_ROLE_ENUM_UNKNOWN);
@@ -183,79 +183,79 @@ pk_backend_get_actions (PkBackend *backend)
 	/* lets reduce pointer dereferences... */
 	desc = backend->desc;
 	if (desc->cancel != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_CANCEL);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_CANCEL);
 	}
 	if (desc->get_depends != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_DEPENDS);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_DEPENDS);
 	}
 	if (desc->get_details != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_DETAILS);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_DETAILS);
 	}
 	if (desc->get_files != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_FILES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_FILES);
 	}
 	if (desc->get_requires != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_REQUIRES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_REQUIRES);
 	}
 	if (desc->get_packages != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_PACKAGES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_PACKAGES);
 	}
 	if (desc->what_provides != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_WHAT_PROVIDES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_WHAT_PROVIDES);
 	}
 	if (desc->get_updates != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_UPDATES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_UPDATES);
 	}
 	if (desc->get_update_detail != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_UPDATE_DETAIL);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_UPDATE_DETAIL);
 	}
 	if (desc->install_packages != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_INSTALL_PACKAGES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_INSTALL_PACKAGES);
 	}
 	if (desc->install_files != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_INSTALL_FILES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_INSTALL_FILES);
 	}
 	if (desc->refresh_cache != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_REFRESH_CACHE);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_REFRESH_CACHE);
 	}
 	if (desc->remove_packages != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_REMOVE_PACKAGES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_REMOVE_PACKAGES);
 	}
 	if (desc->download_packages != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_DOWNLOAD_PACKAGES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_DOWNLOAD_PACKAGES);
 	}
 	if (desc->resolve != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_RESOLVE);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_RESOLVE);
 	}
 	if (desc->rollback != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_ROLLBACK);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_ROLLBACK);
 	}
 	if (desc->search_details != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_SEARCH_DETAILS);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_SEARCH_DETAILS);
 	}
 	if (desc->search_file != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_SEARCH_FILE);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_SEARCH_FILE);
 	}
 	if (desc->search_group != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_SEARCH_GROUP);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_SEARCH_GROUP);
 	}
 	if (desc->search_name != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_SEARCH_NAME);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_SEARCH_NAME);
 	}
 	if (desc->update_packages != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_UPDATE_PACKAGES);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_UPDATE_PACKAGES);
 	}
 	if (desc->update_system != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_UPDATE_SYSTEM);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_UPDATE_SYSTEM);
 	}
 	if (desc->get_repo_list != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_GET_REPO_LIST);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_GET_REPO_LIST);
 	}
 	if (desc->repo_enable != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_REPO_ENABLE);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_REPO_ENABLE);
 	}
 	if (desc->repo_set_data != NULL) {
-		pk_enums_add (roles, PK_ROLE_ENUM_REPO_SET_DATA);
+		pk_bitfield_add (roles, PK_ROLE_ENUM_REPO_SET_DATA);
 	}
 	return roles;
 }
@@ -1648,9 +1648,10 @@ pk_backend_is_online (PkBackend *backend)
 	PkNetworkEnum state;
 	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
 	state = pk_network_get_network_state (backend->priv->network);
-	if (pk_enums_contain (state, PK_NETWORK_ENUM_ONLINE)) {
+	if (state == PK_NETWORK_ENUM_ONLINE ||
+	    state == PK_NETWORK_ENUM_SLOW ||
+	    state == PK_NETWORK_ENUM_FAST)
 		return TRUE;
-	}
 	return FALSE;
 }
 
diff --git a/src/pk-backend.h b/src/pk-backend.h
index ac975ff..0e4b7d1 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -25,6 +25,7 @@
 #include <glib.h>
 #include <gmodule.h>
 #include <pk-enum.h>
+#include <pk-bitfield.h>
 #include <pk-package-id.h>
 #include <pk-debug.h>
 
@@ -197,14 +198,14 @@ typedef struct {
 	const gchar	*author;
 	void		(*initialize)			(PkBackend	*backend);
 	void		(*destroy)			(PkBackend	*backend);
-	PkGroupEnum	(*get_groups)			(PkBackend	*backend);
-	PkFilterEnum	(*get_filters)			(PkBackend	*backend);
+	PkBitfield	(*get_groups)			(PkBackend	*backend);
+	PkBitfield	(*get_filters)			(PkBackend	*backend);
 	void		(*cancel)			(PkBackend	*backend);
 	void		(*download_packages)		(PkBackend	*backend,
 							 gchar		**package_ids,
 							 const gchar	*directory);
 	void		(*get_depends)			(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 gchar		**package_ids,
 							 gboolean	 recursive);
 	void		(*get_details)			(PkBackend	*backend,
@@ -213,17 +214,17 @@ typedef struct {
 	void		(*get_files)			(PkBackend	*backend,
 							 gchar		**package_ids);
 	void		(*get_packages)			(PkBackend	*backend,
-							 PkFilterEnum	 filters);
+							 PkBitfield	 filters);
 	void		(*get_repo_list)		(PkBackend	*backend,
-							 PkFilterEnum	 filters);
+							 PkBitfield	 filters);
 	void		(*get_requires)			(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 gchar		**package_ids,
 							 gboolean	 recursive);
 	void		(*get_update_detail)		(PkBackend	*backend,
 							 gchar		**package_ids);
 	void		(*get_updates)			(PkBackend	*backend,
-							 PkFilterEnum	 filters);
+							 PkBitfield	 filters);
 	void		(*install_files)		(PkBackend	*backend,
 							 gboolean	 trusted,
 							 gchar		**full_paths);
@@ -247,21 +248,21 @@ typedef struct {
 							 const gchar	*parameter,
 							 const gchar	*value);
 	void		(*resolve)			(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 gchar		**packages);
 	void		(*rollback)			(PkBackend	*backend,
 							 const gchar	*transaction_id);
 	void		(*search_details)		(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 const gchar	*search);
 	void		(*search_file)			(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 const gchar	*search);
 	void		(*search_group)			(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 const gchar	*search);
 	void		(*search_name)			(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 const gchar	*search);
 	void		(*service_pack)			(PkBackend	*backend,
 							 const gchar	*location,
@@ -270,7 +271,7 @@ typedef struct {
 							 gchar		**package_ids);
 	void		(*update_system)		(PkBackend	*backend);
 	void		(*what_provides)		(PkBackend	*backend,
-							 PkFilterEnum	 filters,
+							 PkBitfield	 filters,
 							 PkProvidesEnum	 provides,
 							 const gchar	*search);
 	gpointer	padding[10];
diff --git a/src/pk-engine.c b/src/pk-engine.c
index ebc407d..96618a4 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -106,9 +106,9 @@ struct PkEnginePrivate
 	PkNotify		*notify;
 	PkConf			*conf;
 	PkFileMonitor		*file_monitor;
-	PkRoleEnum		 actions;
-	PkGroupEnum		 groups;
-	PkFilterEnum		 filters;
+	PkBitfield		 actions;
+	PkBitfield		 groups;
+	PkBitfield	 filters;
 	guint			 signal_state_priority_timeout;
 	guint			 signal_state_normal_timeout;
 };
@@ -395,7 +395,7 @@ gboolean
 pk_engine_get_actions (PkEngine *engine, gchar **actions, GError **error)
 {
 	g_return_val_if_fail (PK_IS_ENGINE (engine), FALSE);
-	*actions = pk_role_enums_to_text (engine->priv->actions);
+	*actions = pk_role_bitfield_to_text (engine->priv->actions);
 	return TRUE;
 }
 
@@ -406,7 +406,7 @@ gboolean
 pk_engine_get_groups (PkEngine *engine, gchar **groups, GError **error)
 {
 	g_return_val_if_fail (PK_IS_ENGINE (engine), FALSE);
-	*groups = pk_group_enums_to_text (engine->priv->groups);
+	*groups = pk_group_bitfield_to_text (engine->priv->groups);
 	return TRUE;
 }
 
@@ -417,7 +417,7 @@ gboolean
 pk_engine_get_filters (PkEngine *engine, gchar **filters, GError **error)
 {
 	g_return_val_if_fail (PK_IS_ENGINE (engine), FALSE);
-	*filters = pk_filter_enums_to_text (engine->priv->filters);
+	*filters = pk_filter_bitfield_to_text (engine->priv->filters);
 	return TRUE;
 }
 
@@ -628,7 +628,7 @@ pk_engine_remove_contents (const gchar *directory)
 {
 	gboolean ret = FALSE;
 	GDir *dir;
-	GError *error = NULL;
+	GError *error;
 	const gchar *filename;
 	gchar *src;
 	gint retval;
diff --git a/src/pk-transaction-db.c b/src/pk-transaction-db.c
index 36a1d0c..b47ee7b 100644
--- a/src/pk-transaction-db.c
+++ b/src/pk-transaction-db.c
@@ -463,7 +463,7 @@ pk_transaction_db_create_table_last_action (PkTransactionDb *tdb)
 	timespec = pk_iso8601_present ();
 	statement = "CREATE TABLE last_action (role TEXT primary key, timespec TEXT);";
 	sqlite3_exec (tdb->priv->db, statement, NULL, NULL, NULL);
-	for (i=1; i<PK_ROLE_ENUM_UNKNOWN; i*=2) {
+	for (i=0; i<PK_ROLE_ENUM_UNKNOWN; i++) {
 		role_text = pk_role_enum_to_text (i);
 		/* reset to now if the role does not exist */
 		statement = g_strdup_printf ("INSERT INTO last_action (role, timespec) VALUES ('%s', '%s')", role_text, timespec);
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 993cd16..dda37c4 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -109,7 +109,7 @@ struct PkTransactionPrivate
 	gchar			*cached_transaction_id;
 	gchar			*cached_full_path;
 	gchar			**cached_full_paths;
-	PkFilterEnum		 cached_filters;
+	PkBitfield	 cached_filters;
 	gchar			*cached_search;
 	gchar			*cached_repo_id;
 	gchar			*cached_key_id;
@@ -1418,7 +1418,7 @@ pk_transaction_get_depends (PkTransaction *transaction, const gchar *filter, gch
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_package_ids = g_strdupv (package_ids);
 	transaction->priv->cached_force = recursive;
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
@@ -1641,7 +1641,7 @@ pk_transaction_get_packages (PkTransaction *transaction, const gchar *filter, DB
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_GET_PACKAGES);
 
@@ -1760,7 +1760,7 @@ pk_transaction_get_repo_list (PkTransaction *transaction, const gchar *filter, D
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_GET_REPO_LIST);
 
@@ -1828,7 +1828,7 @@ pk_transaction_get_requires (PkTransaction *transaction, const gchar *filter, gc
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_package_ids = g_strdupv (package_ids);
 	transaction->priv->cached_force = recursive;
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
@@ -2047,7 +2047,7 @@ pk_transaction_get_updates (PkTransaction *transaction, const gchar *filter, DBu
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_GET_UPDATES);
 
@@ -2784,7 +2784,7 @@ pk_transaction_resolve (PkTransaction *transaction, const gchar *filter,
 
 	/* save so we can run later */
 	transaction->priv->cached_package_ids = g_strdupv (packages);
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_RESOLVE);
 
@@ -2912,7 +2912,7 @@ pk_transaction_search_details (PkTransaction *transaction, const gchar *filter,
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_search = g_strdup (search);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_SEARCH_DETAILS);
@@ -2974,7 +2974,7 @@ pk_transaction_search_file (PkTransaction *transaction, const gchar *filter,
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_search = g_strdup (search);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_SEARCH_FILE);
@@ -3036,7 +3036,7 @@ pk_transaction_search_group (PkTransaction *transaction, const gchar *filter,
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_search = g_strdup (search);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_SEARCH_GROUP);
@@ -3098,7 +3098,7 @@ pk_transaction_search_name (PkTransaction *transaction, const gchar *filter,
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_search = g_strdup (search);
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
 	pk_transaction_set_role (transaction, PK_ROLE_ENUM_SEARCH_NAME);
@@ -3347,7 +3347,7 @@ pk_transaction_what_provides (PkTransaction *transaction, const gchar *filter, c
 	}
 
 	/* save so we can run later */
-	transaction->priv->cached_filters = pk_filter_enums_from_text (filter);
+	transaction->priv->cached_filters = pk_filter_bitfield_from_text (filter);
 	transaction->priv->cached_search = g_strdup (search);
 	transaction->priv->cached_provides = provides;
 	transaction->priv->status = PK_STATUS_ENUM_WAIT;
commit 2225e230200fa09711ca3d7b70788d4f8f51ff41
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Aug 19 14:30:36 2008 +0100

    bugfix: fix compiling the browser plugins where HAVE_GDK_APP_LAUNCH_CONTEXT_NEW is defined

diff --git a/contrib/packagekit-plugin/src/contents.cpp b/contrib/packagekit-plugin/src/contents.cpp
index 9d51ac9..3be68fb 100644
--- a/contrib/packagekit-plugin/src/contents.cpp
+++ b/contrib/packagekit-plugin/src/contents.cpp
@@ -598,6 +598,9 @@ void
 PkpContents::runApplication (Time time)
 {
     GError *error = NULL;
+#ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
+    GdkAppLaunchContext *context;
+#endif
 
     if (mAppInfo == 0) {
         g_warning("Didn't find application to launch");
@@ -607,20 +610,22 @@ PkpContents::runApplication (Time time)
     if (time == 0)
         time = get_server_timestamp();
 
-    GAppLaunchContext *context = 0;
 #ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
     context = gdk_app_launch_context_new();
-    gdk_app_launch_context_set_timestamp(time);
+    gdk_app_launch_context_set_timestamp(context, time);
+    if (!g_app_info_launch(mAppInfo, NULL, G_APP_LAUNCH_CONTEXT (context), &error)) {
+#else
+    if (!g_app_info_launch(mAppInfo, NULL, NULL, &error)) {
 #endif
-
-    if (!g_app_info_launch(mAppInfo, NULL, context, &error)) {
         g_warning("%s\n", error->message);
         g_clear_error(&error);
         return;
     }
 
-    if (context != 0)
+#ifdef HAVE_GDK_APP_LAUNCH_CONTEXT_NEW
+    if (context != NULL)
         g_object_unref(context);
+#endif
 }
 
 void
commit d8dee4e2741bbbd20d70e22d86b95191e585ae42
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Aug 19 12:58:38 2008 +0100

    trivial: fix a GError initialisation error

diff --git a/src/pk-engine.c b/src/pk-engine.c
index 0ed478e..ebc407d 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -628,7 +628,7 @@ pk_engine_remove_contents (const gchar *directory)
 {
 	gboolean ret = FALSE;
 	GDir *dir;
-	GError *error;
+	GError *error = NULL;
 	const gchar *filename;
 	gchar *src;
 	gint retval;
commit 692597a3574eef946560ecfe6e7e27470e1c0878
Merge: 3472415... 35a6ffd...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Aug 18 23:55:00 2008 +0200

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

commit 3472415c08d6160ad57360c79010f77920181637
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Aug 18 21:34:49 2008 +0200

    APT: Fix wrong use of the STATUS_SETUP in doInit()

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 5defb74..3aedd4d 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -238,7 +238,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
 
     def doInit(self):
         pklog.info("Initializing cache")
-        self.StatusChanged(STATUS_SETUP)
+        self.StatusChanged(STATUS_RUNNING)
         self.AllowCancel(False)
         self.NoPercentageUpdates()
         self._open_cache(progress=False)
commit 35a6ffd98925a824178f8ebd7139dce5ba1766be
Merge: 8702328... 5420a50...
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Aug 18 20:11:27 2008 +0100

    Merge branch 'distro-upgrade'

commit 87023287a8a5c1eac88fa99eb1c9f8e5c11df235
Merge: 4d5b136... b2d78ef...
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Aug 18 20:11:09 2008 +0100

    Merge branch 'fix-download-packages'

commit 4d5b1369a9ef721c58ba99c79da9ae811a1b84c3
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Aug 18 20:07:40 2008 +0100

    post release version bump

diff --git a/RELEASE b/RELEASE
index 8a1dc83..43e44dd 100644
--- a/RELEASE
+++ b/RELEASE
@@ -3,7 +3,7 @@ PackageKit Release Notes
 1. Write NEWS entries for PackageKit and gnome-packagekit in the same
    format as usual. Ignore any trivial commits.
 
-$ git-shortlog PACKAGEKIT_0_2_4.. | grep -v trivial | grep -v Merge > NEWS.new
+git-shortlog PACKAGEKIT_0_2_4.. | grep -v trivial | grep -v Merge > NEWS.new
 
 2. Add download date to docs/html/pk-download.html, save file.
 
@@ -11,39 +11,39 @@ $ git-shortlog PACKAGEKIT_0_2_4.. | grep -v trivial | grep -v Merge > NEWS.new
 
 4. Commit changes in PackageKit git:
 
-$ git commit -a -m "Release version 0.3.0"
-$ git tag -a -f -m "Release 0.3.0" PACKAGEKIT_0_3_0
-$ git push --tags
-$ git push
-$ git push git+ssh://username@git.freedesktop.org/git/packagekit
-$ git push --tags git+ssh://username@git.freedesktop.org/git/packagekit
+git commit -a -m "Release version 0.3.1"
+git tag -a -f -m "Release 0.3.1" PACKAGEKIT_0_3_1
+git push --tags
+git push
+git push git+ssh://hughsient@git.freedesktop.org/git/packagekit
+git push --tags git+ssh://hughsient@git.freedesktop.org/git/packagekit
 
 5. Commit changes in gnome-packagekit git:
 
-$ git commit -a -m "Release version 0.3.0"
-$ git-tag GNOME_PACKAGEKIT_0_3_0
-$ git push --tags
-$ git push
+git commit -a -m "Release version 0.3.1"
+git-tag GNOME_PACKAGEKIT_0_3_1
+git push --tags
+git push
 
 6. run 'make dist-gzip' in both the PackageKit and gnome-packagekit dirs.
 
 7. Upload both tarballs to:
 
-$ scp *.tar.gz packagekit.org:/srv/www/html/releases/
+scp *.tar.gz packagekit.org:/srv/www/html/releases/
 
 8. Do post release version bump in configure.ac
 
 9. Commit changes in both projects:
 
-$ git commit -a -m "post release version bump"
-$ git push
+git commit -a -m "post release version bump"
+git push
 
 10. Send an email to packagekit at lists.freedesktop.org
 
 =================================================
-Subject: PackageKit and gnome-packagekit 0.3.0 released!
+Subject: PackageKit and gnome-packagekit 0.3.1 released!
 
-Today I released PackageKit and gnome-packagekit 0.3.0.
+Today I released PackageKit and gnome-packagekit 0.3.1.
 
 PackageKit release notes: http://gitweb.freedesktop.org/?p=packagekit.git;a=blob;f=NEWS
 
diff --git a/configure.ac b/configure.ac
index 68e91a2..6ff1fbe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 AC_PREREQ(2.52)
 
-AC_INIT(PackageKit, 0.3.0)
+AC_INIT(PackageKit, 0.3.1)
 AC_CONFIG_SRCDIR(src)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 AM_CONFIG_HEADER(config.h)
commit b2d78eff40c72c6fd1b4cfbfe8d20c96395c043b
Author: Richard Hughes <richard at hughsie.com>
Date:   Mon Aug 18 15:56:30 2008 +0100

    change the interface for DownloadPackages so we get the correct owners and SELinux contexts

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index ea4f03a..2c66235 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -822,11 +822,29 @@ backend_get_packages (PkBackend *backend, PkFilterEnum filters)
 static void
 backend_download_packages (PkBackend *backend, gchar **package_ids, const gchar *directory)
 {
+	gchar *filename1;
+	gchar *filename2;
+	gchar *filelist;
 	pk_backend_set_status (backend, PK_STATUS_ENUM_DOWNLOAD);
+
+	filename1 = g_build_filename (directory, "powertop-1.8-1.fc8.rpm", NULL);
+	g_file_set_contents (filename1, "hello dave", -1, NULL);
 	pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
 			    "powertop;1.8-1.fc8;i386;fedora", "Power consumption monitor");
+
+	filename2 = g_build_filename (directory, "gtk2-2.11.6-6.fc8.rpm", NULL);
+	g_file_set_contents (filename2, "hello brian", -1, NULL);
 	pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
-			    "gtk2;gtk2-2.11.6-6.fc8;i386;fedora", "GTK+ Libraries for GIMP");
+			    "gtk2;2.11.6-6.fc8;i386;fedora", "GTK+ Libraries for GIMP");
+
+	/* send the filelist */
+	filelist = g_strjoin (";", filename1, filename2, NULL);
+	pk_backend_files (backend, NULL, filelist);
+
+	g_free (filename1);
+	g_free (filename2);
+	g_free (filelist);
+
 	pk_backend_finished (backend);
 }
 
diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index b04cb3e..0d832c3 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -379,6 +379,7 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         self.status(STATUS_DOWNLOAD)
         percentage = 0;
         bump = 100 / len(package_ids)
+        files = []
 
         # download each package
         for package in package_ids:
@@ -409,11 +410,16 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 pkg_download.localpath = local #Hack:To set the localpath we want
                 try:
                     path = repo.getPackage(pkg_download)
+                    files.append(path)
                 except IOError, e:
                     self.error(ERROR_WRITE_ERROR,"Cannot write to file")
                     continue
             percentage += bump
 
+        # emit the file list we downloaded
+        file_list = ";".join(files)
+        self.files(package,file_list)
+
         # in case we don't sum to 100
         self.percentage(100)
 
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index d5d7de1..e74afd7 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -666,15 +666,51 @@ pk_client_details_cb (DBusGProxy *proxy, const gchar *package_id, const gchar *l
 }
 
 /**
+ * pk_client_file_copy:
+ */
+static gboolean
+pk_client_file_copy (const gchar *filename, const gchar *directory)
+{
+	gboolean ret;
+	GError *error = NULL;
+	gchar *command;
+
+	/* TODO: use GIO when we have a hard dep on it */
+	command = g_strdup_printf ("cp \"%s\" \"%s\"", filename, directory);
+	pk_debug ("command: %s", command);
+	ret = g_spawn_command_line_async (command, &error);
+	if (!ret) {
+		pk_warning ("failed to copy: %s", error->message);
+		g_error_free (error);
+	}
+	g_free (command);
+	return ret;
+}
+
+/**
  * pk_client_files_cb:
  */
 static void
-pk_client_files_cb (DBusGProxy  *proxy, const gchar *package_id, const gchar *filelist, PkClient *client)
+pk_client_files_cb (DBusGProxy *proxy, const gchar *package_id, const gchar *filelist, PkClient *client)
 {
+	guint i;
+	guint length;
+	gchar **split;
+
 	g_return_if_fail (PK_IS_CLIENT (client));
 
 	pk_debug ("emit files %s, <lots of files>", package_id);
 	g_signal_emit (client , signals [PK_CLIENT_FILES], 0, package_id, filelist);
+
+	/* we are a callback from DownloadPackages */
+	if (client->priv->role == PK_ROLE_ENUM_DOWNLOAD_PACKAGES && pk_strzero (package_id)) {
+		split = g_strsplit (filelist, ";", -1);
+		length = g_strv_length (split);
+		for (i=0; i<length; i++) {
+			pk_client_file_copy (split[i], client->priv->cached_directory);
+		}
+		g_strfreev (split);
+	}
 }
 
 /**
@@ -1577,7 +1613,6 @@ pk_client_download_packages (PkClient *client, gchar **package_ids, const gchar
         }
         ret = dbus_g_proxy_call (client->priv->proxy, "DownloadPackages", error,
                                  G_TYPE_STRV, package_ids,
-                                 G_TYPE_STRING, directory,
                                  G_TYPE_INVALID, G_TYPE_INVALID);
         if (ret && !client->priv->is_finished) {
                 /* allow clients to respond in the status changed callback */
diff --git a/src/Makefile.am b/src/Makefile.am
index 58e6cf7..3ee3b27 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -205,6 +205,9 @@ gprof: clean-gprof all check
 	gprof .libs/pk-self-test > gprof.txt
 endif
 
+install-data-hook:
+	mkdir -p $(localstatedir)/cache/PackageKit/downloads
+
 EXTRA_DIST =						\
 	pk-marshal.list					\
 	pk-security-polkit.c				\
diff --git a/src/pk-backend.c b/src/pk-backend.c
index cac5019..edca492 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -1188,12 +1188,13 @@ pk_backend_details (PkBackend *backend, const gchar *package_id,
 
 /**
  * pk_backend_files:
+ *
+ * package_id is NULL when we are using this as a calback from DownloadPackages
  **/
 gboolean
 pk_backend_files (PkBackend *backend, const gchar *package_id, const gchar *filelist)
 {
 	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
-	g_return_val_if_fail (package_id != NULL, FALSE);
 	g_return_val_if_fail (filelist != NULL, FALSE);
 	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
 
diff --git a/src/pk-engine.c b/src/pk-engine.c
index d818bc5..0ed478e 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -34,6 +34,7 @@
 #endif /* HAVE_UNISTD_H */
 
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <pk-package-id.h>
@@ -618,6 +619,54 @@ pk_engine_network_state_changed_cb (PkNetwork *file_monitor, PkNetworkEnum state
 }
 
 /**
+ * pk_engine_remove_contents:
+ *
+ * Does not remove the directory itself, only the contents.
+ **/
+static gboolean
+pk_engine_remove_contents (const gchar *directory)
+{
+	gboolean ret = FALSE;
+	GDir *dir;
+	GError *error;
+	const gchar *filename;
+	gchar *src;
+	gint retval;
+
+	/* try to open */
+	dir = g_dir_open (directory, 0, &error);
+	if (dir == NULL) {
+		pk_warning ("cannot open directory: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* find each */
+	while ((filename = g_dir_read_name (dir))) {
+		src = g_build_filename (directory, filename, NULL);
+		ret = g_file_test (src, G_FILE_TEST_IS_DIR);
+		if (ret) {
+			pk_debug ("directory %s found in %s, deleting", filename, directory);
+			/* recurse, but should be only 1 level deep */
+			pk_engine_remove_contents (src);
+			retval = g_remove (src);
+			if (retval != 0)
+				pk_warning ("failed to delete %s", src);
+		} else {
+			pk_debug ("file found in %s, deleting", directory);
+			retval = g_unlink (src);
+			if (retval != 0)
+				pk_warning ("failed to delete %s", src);
+		}
+		g_free (src);
+	}
+	g_dir_close (dir);
+	ret = TRUE;
+out:
+	return ret;
+}
+
+/**
  * pk_engine_init:
  **/
 static void
@@ -635,6 +684,12 @@ pk_engine_init (PkEngine *engine)
 	/* use the config file */
 	engine->priv->conf = pk_conf_new ();
 
+	/* clear the download cache */
+	filename = g_build_filename (LOCALSTATEDIR, "cache", "PackageKit", "downloads", NULL);
+	pk_debug ("clearing download cache at %s", filename);
+	pk_engine_remove_contents (filename);
+	g_free (filename);
+
 	/* setup the backend backend */
 	engine->priv->backend = pk_backend_new ();
 	g_signal_connect (engine->priv->backend, "finished",
diff --git a/src/pk-interface-transaction.xml b/src/pk-interface-transaction.xml
index fb59409..e805e45 100644
--- a/src/pk-interface-transaction.xml
+++ b/src/pk-interface-transaction.xml
@@ -87,15 +87,6 @@
           </doc:summary>
         </doc:doc>
       </arg>
-      <arg type="s" name="directory" direction="in">
-        <doc:doc>
-          <doc:summary>
-            <doc:para>
-              The directory to install the packages into.
-            </doc:para>
-          </doc:summary>
-        </doc:doc>
-      </arg>
     </method>
 
     <!--*****************************************************************************************-->
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 6ede97d..99e29b4 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -1255,19 +1255,18 @@ pk_transaction_cancel (PkTransaction *transaction, GError **error)
  * pk_transaction_download_packages:
  **/
 void
-pk_transaction_download_packages (PkTransaction *transaction, gchar **package_ids,
-				  const gchar *directory, DBusGMethodInvocation *context)
+pk_transaction_download_packages (PkTransaction *transaction, gchar **package_ids, DBusGMethodInvocation *context)
 {
 	gboolean ret;
 	GError *error;
 	gchar *package_ids_temp;
-	guint uid;
-	const gchar *dbus_name;
+	gchar *directory;
+	gint retval;
 
 	g_return_if_fail (PK_IS_TRANSACTION (transaction));
 	g_return_if_fail (transaction->priv->tid != NULL);
 
-	pk_debug ("DownloadPackages method called: %s, %s", package_ids[0], directory);
+	pk_debug ("DownloadPackages method called: %s", package_ids[0]);
 
 	/* not implemented yet */
 	if (transaction->priv->backend->desc->download_packages == NULL) {
@@ -1279,34 +1278,6 @@ pk_transaction_download_packages (PkTransaction *transaction, gchar **package_id
 	        return;
 	}
 
-	/* does directory exist? */
-	ret = g_file_test (directory, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR);
-	if (!ret) {
-	        error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NO_SUCH_DIRECTORY,
-	                             "directory '%s' cannot be found", directory);
-	        dbus_g_method_return_error (context, error);
-	        return;
-	}
-
-	/* get the UID of the sender */
-	dbus_name = dbus_g_method_get_sender (context);
-	ret = pk_security_uid_from_dbus_sender (transaction->priv->security, dbus_name, &uid);
-	if (!ret) {
-	        error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_REFUSED_BY_POLICY,
-	                             "cannot get uid from dbus sender: %s", dbus_name);
-	        dbus_g_method_return_error (context, error);
-	        return;
-	}
-
-	/* check for write access on the directory */
-	ret = pk_check_permissions (directory, uid, uid, W_OK);
-	if (!ret) {
-	        error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_DENIED,
-	                             "cannot get write to %s with uid %i", directory, uid);
-	        dbus_g_method_return_error (context, error);
-	        return;
-	}
-
 	/* check package_ids */
 	ret = pk_package_ids_check (package_ids);
 	if (ret == FALSE) {
@@ -1318,6 +1289,18 @@ pk_transaction_download_packages (PkTransaction *transaction, gchar **package_id
 	        return;
 	}
 
+	/* create cache directory */
+	directory = g_build_filename (LOCALSTATEDIR, "cache", "PackageKit",
+				     "downloads", transaction->priv->tid, NULL);
+	/* rwxrwxr-x */
+	retval = g_mkdir (directory, 0775);
+	if (retval != 0) {
+	        error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_DENIED,
+	                             "cannot create %s", directory);
+	        dbus_g_method_return_error (context, error);
+	        return;
+	}
+
 	/* set the dbus name, so we can get the disconnect */
 	if (context != NULL) {
 		/* not set inside the test suite */
@@ -1340,6 +1323,7 @@ pk_transaction_download_packages (PkTransaction *transaction, gchar **package_id
 	        return;
 	}
 
+	g_free (directory);
 	dbus_g_method_return (context);
 }
 
diff --git a/src/pk-transaction.h b/src/pk-transaction.h
index 1dce619..36a1814 100644
--- a/src/pk-transaction.h
+++ b/src/pk-transaction.h
@@ -104,7 +104,6 @@ gboolean	 pk_transaction_cancel			(PkTransaction	*transaction,
 							 GError		**error);
 void		 pk_transaction_download_packages	(PkTransaction  *transaction,
 							 gchar		**package_ids,
-							 const gchar	*directory,
 							 DBusGMethodInvocation *context);
 gboolean	 pk_transaction_get_allow_cancel	(PkTransaction	*transaction,
 							 gboolean	*allow_cancel,
commit 4f3fd6a6db7dd753aab4014b72ea6e3ea186176e
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Aug 18 16:14:16 2008 +0200

    APT: Fix filtering. Was totally broken.

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 21bc070..5defb74 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1167,39 +1167,36 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         '''
         Return True if the package should be shown in the user interface
         '''
-        #FIXME: Needs to be optmized
-        if filters == 'none':
+        if filters == FILTER_NONE:
             return True
-        if FILTER_INSTALLED in filters and not pkg.isInstalled:
-            return False
-        if FILTER_NOT_INSTALLED in filters and pkg.isInstalled:
-            return False
-        if FILTER_GUI in filters and not self._package_has_gui(pkg):
-            return False
-        if FILTER_NOT_GUI in filters and self._package_has_gui(pkg):
-            return False
-        if FILTER_DEVELOPMENT in filters and not self._package_is_devel(pkg):
-            return False
-        if FILTER_NOT_DEVELOPMENT in filters and self._package_is_devel(pkg):
-            return False
-        if FILTER_SUPPORTED in filters and not self._package_is_supported(pkg):
-            return False
-        if FILTER_NOT_SUPPORTED in filters and self._package_is_supported(pkg):
-            return False
+        for filter in filters.split(";"):
+            if (filter == FILTER_INSTALLED and not pkg.isInstalled) or \
+               (filter == FILTER_NOT_INSTALLED and pkg.isInstalled) or \
+               (filter == FILTER_SUPPORTED and not \
+                self._is_package_supported(pkg)) or \
+               (filter == FILTER_NOT_SUPPORTED and \
+                self._is_package_supported(pkg)) or \
+               (filter == FILTER_GUI and not self._has_package_gui(pkg)) or \
+               (filter == FILTER_NOT_GUI and self._has_package_gui(pkg)) or \
+               (filter == FILTER_DEVELOPMENT and not \
+                self._is_package_devel(pkg)) or \
+               (filter == FILTER_NOT_DEVELOPMENT and \
+                self._is_package_devel(pkg)):
+                return False
         return True
 
-    def _package_has_gui(self, pkg):
+    def _has_package_gui(self, pkg):
         #FIXME: should go to a modified Package class
         #FIXME: take application data into account. perhaps checking for
         #       property in the xapian database
         return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde']
 
-    def _package_is_devel(self, pkg):
+    def _is_package_devel(self, pkg):
         #FIXME: should go to a modified Package class
         return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \
                pkg.section.split('/')[-1].lower() in ['devel', 'libdevel']
 
-    def _package_is_supported(self, pkg):
+    def _is_package_supported(self, pkg):
         origin = pkg.candidateOrigin[0]
         return origin.origin == "Ubuntu" and \
                origin.component in ["main", "restricted"] and \
commit d3f11231cd473881d7f6405abdb3daf29aa354c4
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Aug 18 15:52:47 2008 +0200

    APT: Add support for Ubuntu supported filter

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index dc004ab..21bc070 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1182,6 +1182,10 @@ class PackageKitAptBackend(PackageKitBaseBackend):
             return False
         if FILTER_NOT_DEVELOPMENT in filters and self._package_is_devel(pkg):
             return False
+        if FILTER_SUPPORTED in filters and not self._package_is_supported(pkg):
+            return False
+        if FILTER_NOT_SUPPORTED in filters and self._package_is_supported(pkg):
+            return False
         return True
 
     def _package_has_gui(self, pkg):
@@ -1195,6 +1199,12 @@ class PackageKitAptBackend(PackageKitBaseBackend):
         return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \
                pkg.section.split('/')[-1].lower() in ['devel', 'libdevel']
 
+    def _package_is_supported(self, pkg):
+        origin = pkg.candidateOrigin[0]
+        return origin.origin == "Ubuntu" and \
+               origin.component in ["main", "restricted"] and \
+               origin.trusted == True
+
     def _find_package_by_id(self, id):
         '''
         Return a package matching to the given package id
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index f49b92d..b92e207 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -85,7 +85,8 @@ backend_get_filters (PkBackend *backend)
 {
 	return (PK_FILTER_ENUM_GUI |
 		PK_FILTER_ENUM_INSTALLED |
-		PK_FILTER_ENUM_DEVELOPMENT);
+		PK_FILTER_ENUM_DEVELOPMENT |
+		PK_FILTER_ENUM_SUPPORTED);
 }
 
 /**
commit 5420a50cc3eb45d301e4c4793b0306d333243d04
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Aug 15 16:02:10 2008 +0100

    API: add two new bits of public API, GetDistroUpgrades() and ::DistroUpgrade()

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 6a6378f..0cce539 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -1575,6 +1575,7 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* download_packages */
 	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 */
diff --git a/backends/apt.deprecated/pk-backend-apt.c b/backends/apt.deprecated/pk-backend-apt.c
index e7849e6..25ac069 100644
--- a/backends/apt.deprecated/pk-backend-apt.c
+++ b/backends/apt.deprecated/pk-backend-apt.c
@@ -243,6 +243,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	NULL,					/* get_packages */
 	backend_get_repo_list,			/* get_repo_list */
diff --git a/backends/apt/pk-backend-apt.c b/backends/apt/pk-backend-apt.c
index 00b2fee..b4c75ce 100644
--- a/backends/apt/pk-backend-apt.c
+++ b/backends/apt/pk-backend-apt.c
@@ -242,6 +242,7 @@ PK_BACKEND_OPTIONS (
 	backend_download_packages,		/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	backend_get_packages,			/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/box/pk-backend-box.c b/backends/box/pk-backend-box.c
index 6d417cf..46854e1 100644
--- a/backends/box/pk-backend-box.c
+++ b/backends/box/pk-backend-box.c
@@ -669,6 +669,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	NULL,					/* get_packages */
 	backend_get_repo_list,			/* get_repo_list */
diff --git a/backends/conary/pk-backend-conary.c b/backends/conary/pk-backend-conary.c
index 9dc1aa2..ee062eb 100644
--- a/backends/conary/pk-backend-conary.c
+++ b/backends/conary/pk-backend-conary.c
@@ -280,6 +280,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index ea4f03a..35237ee 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -147,6 +147,22 @@ backend_get_details (PkBackend *backend, gchar **package_ids)
 }
 
 /**
+ * backend_get_distro_upgrades:
+ */
+static void
+backend_get_distro_upgrades (PkBackend *backend)
+{
+	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
+	pk_backend_distro_upgrade (backend, PK_DISTRO_UPGRADE_ENUM_STABLE,
+				   "Fedora 9", "Fedora 9 is a Linux-based operating system "
+				   "that showcases the latest in free and open source software.");
+	pk_backend_distro_upgrade (backend, PK_DISTRO_UPGRADE_ENUM_UNSTABLE,
+				   "Fedora 10 RC1", "Fedora 10 RC1 is the first unstable version "
+				   "of Fedora for people to test.");
+	pk_backend_finished (backend);
+}
+
+/**
  * backend_get_files:
  */
 static void
@@ -157,6 +173,7 @@ backend_get_files (PkBackend *backend, gchar **package_ids)
 			  "/usr/share/man/man1;/usr/share/man/man1/gnome-power-manager.1.gz");
 	pk_backend_finished (backend);
 }
+
 /**
  * backend_get_requires:
  */
@@ -841,6 +858,7 @@ PK_BACKEND_OPTIONS (
 	backend_download_packages,		/* download_packages */
 	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 */
diff --git a/backends/opkg/pk-backend-opkg.c b/backends/opkg/pk-backend-opkg.c
index 8f43829..70ba9bb 100644
--- a/backends/opkg/pk-backend-opkg.c
+++ b/backends/opkg/pk-backend-opkg.c
@@ -721,6 +721,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/pisi/pk-backend-pisi.c b/backends/pisi/pk-backend-pisi.c
index 07e7d16..a71cee3 100644
--- a/backends/pisi/pk-backend-pisi.c
+++ b/backends/pisi/pk-backend-pisi.c
@@ -366,6 +366,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	NULL,					/* get_packages */
 	backend_get_repo_list,			/* get_repo_list */
diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index ef09c5a..123e629 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -2741,6 +2741,7 @@ PK_BACKEND_OPTIONS (
 	backend_download_packages,			/* download_packages */
 	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 */
diff --git a/backends/razor/pk-backend-razor.c b/backends/razor/pk-backend-razor.c
index a2246c5..283e4dc 100644
--- a/backends/razor/pk-backend-razor.c
+++ b/backends/razor/pk-backend-razor.c
@@ -405,6 +405,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	backend_get_packages,			/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/smart/pk-backend-smart.c b/backends/smart/pk-backend-smart.c
index 950208c..b611460 100644
--- a/backends/smart/pk-backend-smart.c
+++ b/backends/smart/pk-backend-smart.c
@@ -286,6 +286,7 @@ PK_BACKEND_OPTIONS (
 	NULL,						/* download_packages */
 	backend_get_depends,				/* get_depends */
 	backend_get_details,				/* get_details */
+	NULL,						/* get_distro_upgrades */
 	backend_get_files,				/* get_files */
 	NULL,						/* get_packages */
 	backend_get_repo_list,				/* get_repo_list */
diff --git a/backends/test/pk-backend-test-dbus.c b/backends/test/pk-backend-test-dbus.c
index 208fc80..acaf5c9 100644
--- a/backends/test/pk-backend-test-dbus.c
+++ b/backends/test/pk-backend-test-dbus.c
@@ -84,6 +84,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/test/pk-backend-test-fail.c b/backends/test/pk-backend-test-fail.c
index 0f343ce..64e6af8 100644
--- a/backends/test/pk-backend-test-fail.c
+++ b/backends/test/pk-backend-test-fail.c
@@ -254,6 +254,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/test/pk-backend-test-nop.c b/backends/test/pk-backend-test-nop.c
index 4d484d9..89a6408 100644
--- a/backends/test/pk-backend-test-nop.c
+++ b/backends/test/pk-backend-test-nop.c
@@ -34,6 +34,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/test/pk-backend-test-spawn.c b/backends/test/pk-backend-test-spawn.c
index fdb4772..683002a 100644
--- a/backends/test/pk-backend-test-spawn.c
+++ b/backends/test/pk-backend-test-spawn.c
@@ -75,6 +75,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/test/pk-backend-test-succeed.c b/backends/test/pk-backend-test-succeed.c
index 86335a4..bd59bdf 100644
--- a/backends/test/pk-backend-test-succeed.c
+++ b/backends/test/pk-backend-test-succeed.c
@@ -323,6 +323,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	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 */
diff --git a/backends/test/pk-backend-test-thread.c b/backends/test/pk-backend-test-thread.c
index 257c9ed..1890821 100644
--- a/backends/test/pk-backend-test-thread.c
+++ b/backends/test/pk-backend-test-thread.c
@@ -147,6 +147,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	NULL,					/* get_depends */
 	NULL,					/* get_details */
+	NULL,					/* get_distro_upgrades */
 	NULL,					/* get_files */
 	NULL,					/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/urpmi/pk-backend-urpmi.c b/backends/urpmi/pk-backend-urpmi.c
index 0436b52..581d725 100644
--- a/backends/urpmi/pk-backend-urpmi.c
+++ b/backends/urpmi/pk-backend-urpmi.c
@@ -338,6 +338,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	backend_get_packages,			/* get_packages */
 	NULL,					/* get_repo_list */
diff --git a/backends/yum/pk-backend-yum.c b/backends/yum/pk-backend-yum.c
index 0b16cb2..a4e1540 100644
--- a/backends/yum/pk-backend-yum.c
+++ b/backends/yum/pk-backend-yum.c
@@ -446,6 +446,7 @@ PK_BACKEND_OPTIONS (
 	backend_download_packages,		/* download_packages */
 	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 */
diff --git a/backends/yum2/pk-backend-yum2.c b/backends/yum2/pk-backend-yum2.c
index f7cd39c..dd46101 100644
--- a/backends/yum2/pk-backend-yum2.c
+++ b/backends/yum2/pk-backend-yum2.c
@@ -320,6 +320,7 @@ PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	backend_get_depends,			/* get_depends */
 	backend_get_details,			/* get_details */
+	NULL,					/* get_distro_upgrades */
 	backend_get_files,			/* get_files */
 	NULL,					/* get_packages */
 	backend_get_repo_list,			/* get_repo_list */
diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 6d53a21..a241ba3 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -1787,6 +1787,7 @@ extern "C" PK_BACKEND_OPTIONS (
 	NULL,					/* download_packages */
 	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 */
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index abb1abb..6dcf61c 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -111,6 +111,7 @@ static PkEnumMatch enum_role[] = {
 	{PK_ROLE_ENUM_WHAT_PROVIDES,		"what-provides"},
 	{PK_ROLE_ENUM_ACCEPT_EULA,		"accept-eula"},
 	{PK_ROLE_ENUM_DOWNLOAD_PACKAGES,	"download-packages"},
+	{PK_ROLE_ENUM_GET_DISTRO_UPGRADES,	"get-distro-upgrades"},
 	{0, NULL}
 };
 
@@ -285,6 +286,13 @@ static PkEnumMatch enum_sig_type[] = {
 	{0, NULL}
 };
 
+static PkEnumMatch enum_upgrade[] = {
+	{PK_DISTRO_UPGRADE_ENUM_UNKNOWN,	"unknown"},	/* fall though value */
+	{PK_DISTRO_UPGRADE_ENUM_STABLE,		"stable"},
+	{PK_DISTRO_UPGRADE_ENUM_UNSTABLE,		"unstable"},
+	{0, NULL}
+};
+
 static PkEnumMatch enum_provides[] = {
 	{PK_PROVIDES_ENUM_UNKNOWN,		"unknown"},	/* fall though value */
 	{PK_PROVIDES_ENUM_ANY,			"any"},
@@ -565,6 +573,34 @@ pk_sig_type_enum_to_text (PkSigTypeEnum sig_type)
 }
 
 /**
+ * pk_distro_upgrade_enum_from_text:
+ * @upgrade: Text describing the enumerated type
+ *
+ * Converts a text enumerated type to its unsigned integer representation
+ *
+ * Return value: the enumerated constant value, e.g. PK_DISTRO_UPGRADE_ENUM_STABLE
+ */
+PkDistroUpgradeEnum
+pk_distro_upgrade_enum_from_text (const gchar *upgrade)
+{
+	return pk_enum_find_value (enum_upgrade, upgrade);
+}
+
+/**
+ * pk_distro_upgrade_enum_to_text:
+ * @upgrade: The enumerated type value
+ *
+ * Converts a enumerated type to its text representation
+ *
+ * Return value: the enumerated constant value, e.g. "stable"
+ **/
+const gchar *
+pk_distro_upgrade_enum_to_text (PkDistroUpgradeEnum upgrade)
+{
+	return pk_enum_find_string (enum_upgrade, upgrade);
+}
+
+/**
  * pk_provides_enum_from_text:
  * @provides: Text describing the enumerated type
  *
@@ -1357,6 +1393,17 @@ libst_enum (LibSelfTest *test)
 	libst_success (test, NULL);
 
 	/************************************************************/
+	libst_title (test, "check we convert all the upgrade enums");
+	for (i=0; i<=PK_DISTRO_UPGRADE_ENUM_UNKNOWN; i++) {
+		string = pk_distro_upgrade_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
 	libst_title (test, "check we convert all the license enums");
 	for (i=0; i<=PK_LICENSE_ENUM_UNKNOWN; i++) {
 		string = pk_license_enum_to_text (i);
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 21461b3..c728e50 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -79,7 +79,8 @@ typedef enum {
 	PK_ROLE_ENUM_WHAT_PROVIDES		= 1 << 25,
 	PK_ROLE_ENUM_ACCEPT_EULA		= 1 << 26,
 	PK_ROLE_ENUM_DOWNLOAD_PACKAGES		= 1 << 27,
-	PK_ROLE_ENUM_UNKNOWN			= 1 << 28
+	PK_ROLE_ENUM_GET_DISTRO_UPGRADES	= 1 << 28,
+	PK_ROLE_ENUM_UNKNOWN			= 1 << 29
 } PkRoleEnum;
 
 /**
@@ -362,6 +363,17 @@ typedef enum {
 } PkInfoEnum;
 
 /**
+ * PkDistroUpgradeEnum:
+ *
+ * The distro upgrade status
+ **/
+typedef enum {
+	PK_DISTRO_UPGRADE_ENUM_STABLE,
+	PK_DISTRO_UPGRADE_ENUM_UNSTABLE,
+	PK_DISTRO_UPGRADE_ENUM_UNKNOWN
+} PkDistroUpgradeEnum;
+
+/**
  * PkSigTypeEnum:
  *
  * The signature type type
@@ -578,6 +590,9 @@ const gchar	*pk_provides_enum_to_text		(PkProvidesEnum	 provides);
 PkLicenseEnum	 pk_license_enum_from_text		(const gchar	*license);
 const gchar	*pk_license_enum_to_text		(PkLicenseEnum	 license);
 
+PkDistroUpgradeEnum pk_distro_upgrade_enum_from_text	(const gchar	*upgrade);
+const gchar	*pk_distro_upgrade_enum_to_text		(PkDistroUpgradeEnum upgrade);
+
 G_END_DECLS
 
 #endif /* __PK_ENUM_H */
diff --git a/src/pk-backend.c b/src/pk-backend.c
index cac5019..c36cb97 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -119,6 +119,7 @@ enum {
 	PK_BACKEND_PROGRESS_CHANGED,
 	PK_BACKEND_DETAILS,
 	PK_BACKEND_FILES,
+	PK_BACKEND_DISTRO_UPGRADE,
 	PK_BACKEND_PACKAGE,
 	PK_BACKEND_UPDATE_DETAIL,
 	PK_BACKEND_ERROR_CODE,
@@ -1211,6 +1212,40 @@ pk_backend_files (PkBackend *backend, const gchar *package_id, const gchar *file
 }
 
 /**
+ * pk_backend_distro_upgrade:
+ **/
+gboolean
+pk_backend_distro_upgrade (PkBackend *backend, PkDistroUpgradeEnum type, const gchar *name, const gchar *summary)
+{
+	gchar *name_safe;
+	gchar *summary_safe;
+
+	g_return_val_if_fail (PK_IS_BACKEND (backend), FALSE);
+	g_return_val_if_fail (type != PK_DISTRO_UPGRADE_ENUM_UNKNOWN, FALSE);
+	g_return_val_if_fail (name != NULL, FALSE);
+	g_return_val_if_fail (summary != NULL, FALSE);
+	g_return_val_if_fail (backend->priv->locked != FALSE, FALSE);
+
+	/* have we already set an error? */
+	if (backend->priv->set_error) {
+		pk_warning ("already set error, cannot process");
+		return FALSE;
+	}
+
+	/* replace unsafe chars */
+	name_safe = pk_strsafe (name);
+	summary_safe = pk_strsafe (summary);
+
+	pk_debug ("emit distro-upgrade %s, %s, %s", pk_distro_upgrade_enum_to_text (type), name_safe, summary_safe);
+	g_signal_emit (backend, signals [PK_BACKEND_DISTRO_UPGRADE], 0, type, name_safe, summary_safe);
+
+	g_free (name_safe);
+	g_free (summary_safe);
+
+	return TRUE;
+}
+
+/**
  * pk_backend_repo_signature_required:
  **/
 gboolean
@@ -1845,6 +1880,11 @@ pk_backend_class_init (PkBackendClass *klass)
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING,
 			      G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+	signals [PK_BACKEND_DISTRO_UPGRADE] =
+		g_signal_new ("distro-upgrade",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__UINT_STRING_STRING,
+			      G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
 	signals [PK_BACKEND_ERROR_CODE] =
 		g_signal_new ("error-code",
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
diff --git a/src/pk-backend.h b/src/pk-backend.h
index 6f50253..ac975ff 100644
--- a/src/pk-backend.h
+++ b/src/pk-backend.h
@@ -117,6 +117,10 @@ gboolean	 pk_backend_details			(PkBackend	*backend,
 gboolean 	 pk_backend_files 			(PkBackend 	*backend,
 							 const gchar	*package_id,
 							 const gchar 	*filelist);
+gboolean 	 pk_backend_distro_upgrade		(PkBackend 	*backend,
+							 PkDistroUpgradeEnum type,
+							 const gchar 	*name,
+							 const gchar 	*summary);
 gboolean	 pk_backend_error_code			(PkBackend	*backend,
 							 PkErrorCodeEnum code,
 							 const gchar	*details, ...);
@@ -205,6 +209,7 @@ typedef struct {
 							 gboolean	 recursive);
 	void		(*get_details)			(PkBackend	*backend,
 							 gchar		**package_ids);
+	void		(*get_distro_upgrades)		(PkBackend	*backend);
 	void		(*get_files)			(PkBackend	*backend,
 							 gchar		**package_ids);
 	void		(*get_packages)			(PkBackend	*backend,
@@ -272,7 +277,7 @@ typedef struct {
 } PkBackendDesc;
 
 #define PK_BACKEND_OPTIONS(description, author, initialize, destroy, get_filters, get_groups, cancel, download_packages, \
-			   get_depends, get_details, get_files, get_packages, get_repo_list, get_requires,	\
+			   get_depends, get_details, get_distro_upgrades, get_files, get_packages, get_repo_list, get_requires,	\
 			   get_update_detail, get_updates, install_files, install_packages,		\
 			   install_signature, refresh_cache, remove_packages, repo_enable,		\
 			   repo_set_data, resolve, rollback, search_details, search_file, search_group,	\
@@ -288,6 +293,7 @@ typedef struct {
 		download_packages,	\
 		get_depends,		\
 		get_details,		\
+		get_distro_upgrades,	\
 		get_files,		\
 		get_packages,		\
 		get_repo_list,		\
diff --git a/src/pk-interface-transaction.xml b/src/pk-interface-transaction.xml
index fb59409..1c1df28 100644
--- a/src/pk-interface-transaction.xml
+++ b/src/pk-interface-transaction.xml
@@ -561,6 +561,25 @@
     </method>
 
     <!--*****************************************************************************************-->
+    <method name="GetDistroUpgrades">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            This method should return a list of distribution upgrades that are
+            available.
+            It should not return updates, only major upgrades.
+          </doc:para>
+          <doc:para>
+            This method typically emits
+            <literal>DistroUpgrade</literal>,
+            <literal>Error</literal> and
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+    </method>
+
+    <!--*****************************************************************************************-->
     <method name="InstallFiles">
       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <doc:doc>
@@ -2042,6 +2061,46 @@
       </arg>
     </signal>
 
+    <!--*****************************************************************************************-->
+    <signal name="DistroUpgrade">
+      <doc:doc>
+        <doc:description>
+          <doc:para>
+            This signal allows the backend to communicate distribution
+            upgrades to the session.
+          </doc:para>
+        </doc:description>
+      </doc:doc>
+      <arg type="s" name="type" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              A valid upgrade string enumerated type, e.g. <literal>stable</literal>
+              or <literal>unstable</literal>
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="name" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The short name of the distribution, e.g. <literal>Fedora Core 10 RC1</literal>
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="s" name="summary" direction="out">
+        <doc:doc>
+          <doc:summary>
+            <doc:para>
+              The multi-line description of the release.
+            </doc:para>
+          </doc:summary>
+        </doc:doc>
+      </arg>
+    </signal>
+
   </interface>
 </node>
 
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 9fc5d25..f923282 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -122,6 +122,7 @@ struct PkTransactionPrivate
 	guint			 signal_details;
 	guint			 signal_error_code;
 	guint			 signal_files;
+	guint			 signal_distro_upgrade;
 	guint			 signal_finished;
 	guint			 signal_message;
 	guint			 signal_package;
@@ -139,6 +140,7 @@ enum {
 	PK_TRANSACTION_CALLER_ACTIVE_CHANGED,
 	PK_TRANSACTION_DETAILS,
 	PK_TRANSACTION_ERROR_CODE,
+	PK_TRANSACTION_DISTRO_UPGRADE,
 	PK_TRANSACTION_FILES,
 	PK_TRANSACTION_FINISHED,
 	PK_TRANSACTION_MESSAGE,
@@ -442,6 +444,23 @@ pk_transaction_files_cb (PkBackend *backend, const gchar *package_id,
 }
 
 /**
+ * pk_transaction_distro_upgrade_cb:
+ **/
+static void
+pk_transaction_distro_upgrade_cb (PkBackend *backend, PkDistroUpgradeEnum type,
+				  const gchar *name, const gchar *summary, PkTransaction *transaction)
+{
+	const gchar *type_text;
+
+	g_return_if_fail (PK_IS_TRANSACTION (transaction));
+	g_return_if_fail (transaction->priv->tid != NULL);
+
+	type_text = pk_distro_upgrade_enum_to_text (type);
+	pk_debug ("emitting distro-upgrade %s, %s, %s", type_text, name, summary);
+	g_signal_emit (transaction, signals [PK_TRANSACTION_DISTRO_UPGRADE], 0, type_text, name, summary);
+}
+
+/**
  * pk_transaction_finished_cb:
  **/
 static void
@@ -521,6 +540,7 @@ pk_transaction_finished_cb (PkBackend *backend, PkExitEnum exit, PkTransaction *
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_details);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_error_code);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_files);
+	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_distro_upgrade);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_finished);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_message);
 	g_signal_handler_disconnect (transaction->priv->backend, transaction->priv->signal_package);
@@ -809,6 +829,9 @@ pk_transaction_set_running (PkTransaction *transaction)
 	transaction->priv->signal_files =
 		g_signal_connect (transaction->priv->backend, "files",
 				  G_CALLBACK (pk_transaction_files_cb), transaction);
+	transaction->priv->signal_distro_upgrade =
+		g_signal_connect (transaction->priv->backend, "distro-upgrade",
+				  G_CALLBACK (pk_transaction_distro_upgrade_cb), transaction);
 	transaction->priv->signal_finished =
 		g_signal_connect (transaction->priv->backend, "finished",
 				  G_CALLBACK (pk_transaction_finished_cb), transaction);
@@ -879,6 +902,8 @@ pk_transaction_set_running (PkTransaction *transaction)
 		desc->download_packages (priv->backend, priv->cached_package_ids, priv->cached_directory);
 	} else if (priv->role == PK_ROLE_ENUM_GET_DETAILS) {
 		desc->get_details (priv->backend, priv->cached_package_ids);
+	} else if (priv->role == PK_ROLE_ENUM_GET_DISTRO_UPGRADES) {
+		desc->get_distro_upgrades (priv->backend);
 	} else if (priv->role == PK_ROLE_ENUM_GET_FILES) {
 		desc->get_files (priv->backend, priv->cached_package_ids);
 	} else if (priv->role == PK_ROLE_ENUM_GET_REQUIRES) {
@@ -1488,6 +1513,54 @@ pk_transaction_get_details (PkTransaction *transaction, gchar **package_ids, DBu
 }
 
 /**
+ * pk_transaction_get_distro_upgrades:
+ **/
+void
+pk_transaction_get_distro_upgrades (PkTransaction *transaction, DBusGMethodInvocation *context)
+{
+	gboolean ret;
+	GError *error;
+
+	g_return_if_fail (PK_IS_TRANSACTION (transaction));
+	g_return_if_fail (transaction->priv->tid != NULL);
+
+	pk_debug ("GetDistroUpgrades method called");
+
+	/* not implemented yet */
+	if (transaction->priv->backend->desc->get_distro_upgrades == NULL) {
+		pk_debug ("Not implemented yet: GetDistroUpgrades");
+		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_NOT_SUPPORTED,
+				     "Operation not yet supported by backend");
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	/* set the dbus name, so we can get the disconnect */
+	if (context != NULL) {
+		/* not set inside the test suite */
+		pk_transaction_set_dbus_name (transaction, dbus_g_method_get_sender (context));
+	}
+
+	/* save so we can run later */
+	transaction->priv->status = PK_STATUS_ENUM_WAIT;
+	pk_transaction_set_role (transaction, PK_ROLE_ENUM_GET_DISTRO_UPGRADES);
+
+	/* try to commit this */
+	ret = pk_transaction_commit (transaction);
+	if (!ret) {
+		error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_COMMIT_FAILED,
+				     "Could not commit to a transaction object");
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	if (context != NULL) {
+		/* not set inside the test suite */
+		dbus_g_method_return (context);
+	}
+}
+
+/**
  * pk_transaction_get_files:
  **/
 void
@@ -3344,6 +3417,11 @@ pk_transaction_class_init (PkTransactionClass *klass)
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING,
 			      G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+	signals [PK_TRANSACTION_DISTRO_UPGRADE] =
+		g_signal_new ("distro-upgrade",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__STRING_STRING_STRING,
+			      G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 	signals [PK_TRANSACTION_FINISHED] =
 		g_signal_new ("finished",
 			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
diff --git a/src/pk-transaction.h b/src/pk-transaction.h
index 1dce619..b111151 100644
--- a/src/pk-transaction.h
+++ b/src/pk-transaction.h
@@ -117,6 +117,8 @@ void		 pk_transaction_get_depends		(PkTransaction	*transaction,
 void		 pk_transaction_get_details		(PkTransaction	*transaction,
 							 gchar		**package_ids,
 							 DBusGMethodInvocation *context);
+void		 pk_transaction_get_distro_upgrades	(PkTransaction	*transaction,
+							 DBusGMethodInvocation *context);
 void		 pk_transaction_get_files		(PkTransaction	*transaction,
 							 gchar		**package_ids,
 							 DBusGMethodInvocation *context);


More information about the PackageKit-commit mailing list