diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 8ce7775..9ed8ab6 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -46,6 +46,7 @@ static gboolean _use_eula = FALSE;
 static gboolean _use_media = FALSE;
 static gboolean _use_gpg = FALSE;
 static gboolean _use_distro_upgrade = FALSE;
+static PkBitfield _filters = 0;
 
 /**
  * backend_initialize:
@@ -612,13 +613,17 @@ backend_resolve (PkBackend *backend, PkBitfield filters, gchar **packages)
 	/* each one has a different detail for testing */
 	len = g_strv_length (packages);
 	for (i=0; i<len; i++) {
-		if (g_strcmp0 (packages[i], "vips-doc") == 0)
-			pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
-					    "vips-doc;7.12.4-2.fc8;noarch;linva", "The vips documentation package.");
-		else if (g_strcmp0 (packages[i], "glib2") == 0)
-			pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
-					    "glib2;2.14.0;i386;fedora", "The GLib library");
-		else if (g_strcmp0 (packages[i], "powertop") == 0)
+		if (g_strcmp0 (packages[i], "vips-doc") == 0) {
+			if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_INSTALLED)) {
+				pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
+						    "vips-doc;7.12.4-2.fc8;noarch;linva", "The vips documentation package.");
+			}
+		} else if (g_strcmp0 (packages[i], "glib2") == 0) {
+			if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+				pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
+						    "glib2;2.14.0;i386;fedora", "The GLib library");
+			}
+		} else if (g_strcmp0 (packages[i], "powertop") == 0)
 			pk_backend_package (backend, PK_INFO_ENUM_UPDATING,
 					    "powertop;1.8-1.fc8;i386;fedora", "Power consumption monitor");
 		else if (g_strcmp0 (packages[i], "kernel") == 0)
@@ -1086,12 +1091,19 @@ backend_what_provides_timeout (gpointer data)
 					    "gstreamer-plugins-flumpegdemux;0.10.15-5.lvn;i386;available",
 					    "MPEG demuxer for GStreamer");
 		} else {
-			pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
-					    "evince;0.9.3-5.fc8;i386;installed",
-					    "PDF Document viewer");
-			pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
-					    "scribus;1.3.4-1.fc8;i386;fedora",
-					    "Scribus is an desktop open source page layout program");
+			// pkcon install vips-doc says it's installed cause evince is INSTALLED
+			if (g_strcmp0 (_search, "vips-doc") != 0) {
+				if (!pk_bitfield_contain (_filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
+					pk_backend_package (backend, PK_INFO_ENUM_INSTALLED,
+							    "evince;0.9.3-5.fc8;i386;installed",
+							    "PDF Document viewer");
+				}
+				if (!pk_bitfield_contain (_filters, PK_FILTER_ENUM_INSTALLED)) {
+					pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
+							    "scribus;1.3.4-1.fc8;i386;fedora",
+							    "Scribus is an desktop open source page layout program");
+				}
+			}
 		}
 		pk_backend_finished (backend);
 		return FALSE;
@@ -1110,6 +1122,7 @@ backend_what_provides (PkBackend *backend, PkBitfield filters, PkProvidesEnum pr
 	_progress_percentage = 0;
 	_search = search;
 	_signal_timeout = g_timeout_add (200, backend_what_provides_timeout, backend);
+	_filters = filters;
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REQUEST);
 	pk_backend_set_allow_cancel (backend, TRUE);
 	pk_backend_set_percentage (backend, _progress_percentage);
@@ -1177,7 +1190,7 @@ backend_simulate_install_packages (PkBackend *backend, gchar **package_ids)
 	pk_backend_package (backend, PK_INFO_ENUM_UPDATING,
 			    "lib7;7.0.1-6.fc13;i386;fedora", "C Libraries");
 
-	pk_backend_package (backend, PK_INFO_ENUM_INSTALLING,
+	pk_backend_package (backend, PK_INFO_ENUM_REINSTALLING,
 			    "libssl;3.5.7-2.fc13;i386;fedora", "SSL Libraries");
 
 	pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
diff --git a/client/pk-console.c b/client/pk-console.c
index 3d51572..6f06ff9 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -287,6 +287,61 @@ pk_console_transaction_cb (PkClient *client, const PkTransactionObj *obj, gpoint
 }
 
 /**
+ * pk_console_print_deps_list_info:
+ **/
+static guint
+pk_console_print_deps_list_info (PkPackageList *list, PkInfoEnum info, const gchar *header)
+{
+	const PkPackageObj *obj;
+	gboolean ret = FALSE;
+	guint found = 0;
+	guint i;
+	guint length;
+
+	length = pk_package_list_get_size (list);
+	for (i=0; i<length; i++) {
+		obj = pk_package_list_get_obj (list, i);
+
+		/* are we interested in this type */
+		if (obj->info != info)
+			continue;
+
+		/* print header if it's not been done before */
+		if (!ret) {
+			g_print ("%s\n", header);
+			ret = TRUE;
+		}
+
+		/* print package */
+		g_print ("%i\t%s-%s.%s\n", ++found, obj->id->name, obj->id->version, obj->id->arch);
+	}
+	return found;
+}
+
+/**
+ * pk_console_print_deps_list:
+ **/
+static guint
+pk_console_print_deps_list (PkPackageList *list)
+{
+	guint found = 0;
+
+	/* TRANSLATORS: When processing, we might have to remove other dependencies */
+	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_REMOVING, _("The following packages have to be removed:"));
+
+	/* TRANSLATORS: When processing, we might have to install other dependencies */
+	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_INSTALLING, _("The following packages have to be installed:"));
+
+	/* TRANSLATORS: When processing, we might have to update other dependencies */
+	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_UPDATING, _("The following packages have to be updated:"));
+
+	/* TRANSLATORS: When processing, we might have to reinstall other dependencies */
+	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_REINSTALLING, _("The following packages have to be reinstalled:"));
+
+	return found;
+}
+
+/**
  * pk_console_distro_upgrade_cb:
  **/
 static void
@@ -702,11 +757,14 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 	gboolean ret = TRUE;
 	gboolean installed;
 	gboolean is_local;
+	gboolean accept_changes;
 	gchar *package_id = NULL;
 	gchar **package_ids = NULL;
 	gchar **files = NULL;
 	guint i;
 	guint length;
+	PkPackageList *list;
+	PkPackageList *list_single;
 	GPtrArray *array_packages;
 	GPtrArray *array_files;
 	GError *error_local = NULL;
@@ -714,6 +772,8 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 	array_packages = g_ptr_array_new ();
 	array_files = g_ptr_array_new ();
 	length = g_strv_length (packages);
+	list = pk_package_list_new ();
+
 	for (i=2; i<length; i++) {
 		/* are we a local file */
 		is_local = g_file_test (packages[i], G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR);
@@ -753,6 +813,55 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 		/* convert to strv */
 		package_ids = pk_ptr_array_to_strv (array_packages);
 
+		/* can we simulate? */
+		if (pk_bitfield_contain (roles, PK_ROLE_ENUM_SIMULATE_INSTALL_PACKAGES)) {
+			ret = pk_client_reset (client_sync, &error_local);
+			if (!ret) {
+				/* TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows */
+				*error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
+				g_error_free (error_local);
+				goto out;
+			}
+
+			egg_debug ("Simullating install for %s", package_ids[0]);
+			ret = pk_client_simulate_install_packages (client_sync, package_ids, error);
+			if (!ret) {
+				egg_warning ("failed to simulate a package install");
+				goto out;
+			}
+
+			/* see how many packages there are */
+			list_single = pk_client_get_package_list (client_sync);
+			pk_obj_list_add_list (PK_OBJ_LIST(list), PK_OBJ_LIST(list_single));
+			g_object_unref (list_single);
+
+			/* one of the simulate-install-packages failed */
+			if (!ret)
+				goto out;
+
+			/* if there are no required packages, just do the remove */
+			length = pk_package_list_get_size (list);
+			if (length != 0) {
+				/* present this to the user */
+				if (awaiting_space)
+					g_print ("\n");
+
+				/* print the additional deps to the screen */
+				pk_console_print_deps_list (list);
+
+				/* TRANSLATORS: We are checking if it's okay to remove a list of packages */
+				accept_changes = pk_console_get_prompt (_("Are you ok with these changes?"), FALSE);
+
+				/* we chickened out */
+				if (!accept_changes) {
+					/* TRANSLATORS: There was an error removing the packages. The detailed error follows */
+					*error = g_error_new (1, 0, "%s", _("The package install was canceled!"));
+					ret = FALSE;
+					goto out;
+				}
+			}
+		}
+
 		/* reset */
 		ret = pk_client_reset (client, &error_local);
 		if (!ret) {
@@ -776,6 +885,55 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 		/* convert to strv */
 		files = pk_ptr_array_to_strv (array_files);
 
+		/* can we simulate? */
+		if (pk_bitfield_contain (roles, PK_ROLE_ENUM_SIMULATE_INSTALL_FILES)) {
+			ret = pk_client_reset (client_sync, &error_local);
+			if (!ret) {
+				/* TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows */
+				*error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
+				g_error_free (error_local);
+				goto out;
+			}
+
+			egg_debug ("Simullating install for %s", files[0]);
+			ret = pk_client_simulate_install_files (client_sync, files, error);
+			if (!ret) {
+				egg_warning ("failed to simulate a package install");
+				goto out;
+			}
+
+			/* see how many packages there are */
+			list_single = pk_client_get_package_list (client_sync);
+			pk_obj_list_add_list (PK_OBJ_LIST(list), PK_OBJ_LIST(list_single));
+			g_object_unref (list_single);
+
+			/* one of the simulate-install-packages failed */
+			if (!ret)
+				goto out;
+
+			/* if there are no required packages, just do the remove */
+			length = pk_package_list_get_size (list);
+			if (length != 0) {
+				/* present this to the user */
+				if (awaiting_space)
+					g_print ("\n");
+
+				/* print the additional deps to the screen */
+				pk_console_print_deps_list (list);
+
+				/* TRANSLATORS: We are checking if it's okay to remove a list of packages */
+				accept_changes = pk_console_get_prompt (_("Are you ok with these changes?"), FALSE);
+
+				/* we chickened out */
+				if (!accept_changes) {
+					/* TRANSLATORS: There was an error removing the packages. The detailed error follows */
+					*error = g_error_new (1, 0, "%s", _("The package install was canceled!"));
+					ret = FALSE;
+					goto out;
+				}
+			}
+		}
+
 		/* reset */
 		ret = pk_client_reset (client, &error_local);
 		if (!ret) {
@@ -795,6 +953,7 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 	}
 
 out:
+	g_object_unref (list);
 	g_strfreev (package_ids);
 	g_strfreev (files);
 	g_ptr_array_foreach (array_files, (GFunc) g_free, NULL);
@@ -820,61 +979,6 @@ pk_console_remove_only (PkClient *client, gchar **package_ids, gboolean force, G
 }
 
 /**
- * pk_console_print_deps_list_info:
- **/
-static guint
-pk_console_print_deps_list_info (PkPackageList *list, PkInfoEnum info, const gchar *header)
-{
-	const PkPackageObj *obj;
-	gboolean ret = FALSE;
-	guint found = 0;
-	guint i;
-	guint length;
-
-	length = pk_package_list_get_size (list);
-	for (i=0; i<length; i++) {
-		obj = pk_package_list_get_obj (list, i);
-
-		/* are we interested in this type */
-		if (obj->info != info)
-			continue;
-
-		/* print header if it's not been done before */
-		if (!ret) {
-			g_print ("%s\n", header);
-			ret = TRUE;
-		}
-
-		/* print package */
-		g_print ("%i\t%s-%s.%s\n", ++found, obj->id->name, obj->id->version, obj->id->arch);
-	}
-	return found;
-}
-
-/**
- * pk_console_print_deps_list:
- **/
-static guint
-pk_console_print_deps_list (PkPackageList *list)
-{
-	guint found = 0;
-
-	/* TRANSLATORS: When processing, we might have to remove other dependencies */
-	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_REMOVING, _("The following packages have to be removed:"));
-
-	/* TRANSLATORS: When processing, we might have to install other dependencies */
-	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_INSTALLING, _("The following packages have to be installed:"));
-
-	/* TRANSLATORS: When processing, we might have to update other dependencies */
-	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_UPDATING, _("The following packages have to be updated:"));
-
-	/* TRANSLATORS: When processing, we might have to reinstall other dependencies */
-	found += pk_console_print_deps_list_info (list, PK_INFO_ENUM_REINSTALLING, _("The following packages have to be reinstalled:"));
-
-	return found;
-}
-
-/**
  * pk_console_remove_packages:
  **/
 static gboolean
@@ -1073,8 +1177,13 @@ pk_console_update_package (PkClient *client, const gchar *package, GError **erro
 	gboolean ret;
 	gchar *package_id;
 	gchar **package_ids;
+	guint length;
 	GError *error_local = NULL;
+	gboolean accept_changes;
+	PkPackageList *list;
+	PkPackageList *list_single;
 
+	list = pk_package_list_new ();
 	package_id = pk_console_perhaps_resolve (client, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package, &error_local);
 	if (package_id == NULL) {
 		/* TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows */
@@ -1082,14 +1191,74 @@ pk_console_update_package (PkClient *client, const gchar *package, GError **erro
 		g_error_free (error_local);
 		return FALSE;
 	}
-
 	package_ids = pk_package_ids_from_id (package_id);
+
+	/* are we dumb and can't simulate? */
+	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_SIMULATE_UPDATE_PACKAGES)) {
+		/* no, just try to update it without deps */
+		ret = pk_client_update_packages (client, TRUE, package_ids, error);
+		if (!ret) {
+			/* TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows */
+			*error = g_error_new (1, 0, _("This tool could not update %s: %s"), package, error_local->message);
+			g_error_free (error_local);
+		}
+		goto out;
+	}
+
+	ret = pk_client_reset (client_sync, &error_local);
+	if (!ret) {
+		/* TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows */
+		*error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
+		g_error_free (error_local);
+		goto out;
+	}
+
+	egg_debug ("Simullating update for %s", package_ids[0]);
+	ret = pk_client_simulate_update_packages (client_sync, package_ids, error);
+	if (!ret) {
+		egg_warning ("failed to simulate a package update");
+		goto out;
+	}
+
+	/* see how many packages there are */
+	list_single = pk_client_get_package_list (client_sync);
+	pk_obj_list_add_list (PK_OBJ_LIST(list), PK_OBJ_LIST(list_single));
+	g_object_unref (list_single);
+
+	/* one of the simulate-update-packages failed */
+	if (!ret)
+		goto out;
+
+	/* if there are no required packages, just do the remove */
+	length = pk_package_list_get_size (list);
+	if (length != 0) {
+		/* present this to the user */
+		if (awaiting_space)
+			g_print ("\n");
+
+		/* print the additional deps to the screen */
+		pk_console_print_deps_list (list);
+
+		/* TRANSLATORS: We are checking if it's okay to remove a list of packages */
+		accept_changes = pk_console_get_prompt (_("Are you ok with these changes?"), FALSE);
+
+		/* we chickened out */
+		if (!accept_changes) {
+			/* TRANSLATORS: There was an error removing the packages. The detailed error follows */
+			*error = g_error_new (1, 0, "%s", _("The package update was canceled!"));
+			ret = FALSE;
+			goto out;
+		}
+	}
+
 	ret = pk_client_update_packages (client, TRUE, package_ids, error);
 	if (!ret) {
 		/* TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows */
 		*error = g_error_new (1, 0, _("This tool could not update %s: %s"), package, error_local->message);
 		g_error_free (error_local);
 	}
+out:
+	g_object_unref (list);
 	g_strfreev (package_ids);
 	g_free (package_id);
 	return ret;
diff --git a/lib/packagekit-qt/src/client.cpp b/lib/packagekit-qt/src/client.cpp
index aba8cc9..141afde 100644
--- a/lib/packagekit-qt/src/client.cpp
+++ b/lib/packagekit-qt/src/client.cpp
@@ -410,6 +410,46 @@ Package* Client::searchFromDesktopFile(const QString& path)
 
 }
 
+Transaction* Client::simulateInstallFiles(const QStringList& files)
+{
+	RUN_TRANSACTION(SimulateInstallFiles(files))
+}
+
+Transaction* Client::simulateInstallFile(const QString& file)
+{
+	return simulateInstallFiles(QStringList() << file);
+}
+
+Transaction* Client::simulateInstallPackages(const QList<Package*>& packages)
+{
+	RUN_TRANSACTION(SimulateInstallFiles(Util::packageListToPids(packages)))
+}
+
+Transaction* Client::simulateInstallPackage(Package* package)
+{
+	return simulateInstallPackages(QList<Package*>() << package);
+}
+
+Transaction* Client::simulateRemovePackages(const QList<Package*>& packages)
+{
+	RUN_TRANSACTION(SimulateRemovePackages(Util::packageListToPids(packages)))
+}
+
+Transaction* Client::simulateRemovePackage(Package* package)
+{
+	return simulateRemovePackages(QList<Package*>() << package);
+}
+
+Transaction* Client::simulateUpdatePackages(const QList<Package*>& packages)
+{
+	RUN_TRANSACTION(SimulateUpdatePackages(Util::packageListToPids(packages)))
+}
+
+Transaction* Client::simulateUpdatePackage(Package* package)
+{
+	return simulateUpdatePackages(QList<Package*>() << package);
+}
+
 Transaction* Client::updatePackages(bool only_trusted, const QList<Package*>& packages)
 {
 	RUN_TRANSACTION(UpdatePackages(only_trusted, Util::packageListToPids(packages)))
diff --git a/lib/packagekit-qt/src/client.h b/lib/packagekit-qt/src/client.h
index d46bb65..6243ad7 100644
--- a/lib/packagekit-qt/src/client.h
+++ b/lib/packagekit-qt/src/client.h
@@ -83,37 +83,41 @@ public:
 	 * \sa getActions
 	 */
 	typedef enum {
-		ActionCancel		 = 0x00000001,
-		ActionGetDepends	 = 0x00000002,
-		ActionGetDetails	 = 0x00000004,
-		ActionGetFiles		 = 0x00000008,
-		ActionGetPackages	 = 0x00000010,
-		ActionGetRepoList	 = 0x00000020,
-		ActionGetRequires	 = 0x00000040,
-		ActionGetUpdateDetail	 = 0x00000080,
-		ActionGetUpdates	 = 0x00000100,
-		ActionInstallFiles	 = 0x00000200,
-		ActionInstallPackages	 = 0x00000400,
-		ActionInstallSignature	 = 0x00000800,
-		ActionRefreshCache	 = 0x00001000,
-		ActionRemovePackages	 = 0x00002000,
-		ActionRepoEnable	 = 0x00004000,
-		ActionRepoSetData	 = 0x00008000,
-		ActionResolve		 = 0x00010000,
-		ActionRollback		 = 0x00020000,
-		ActionSearchDetails	 = 0x00040000,
-		ActionSearchFile	 = 0x00080000,
-		ActionSearchGroup	 = 0x00100000,
-		ActionSearchName	 = 0x00200000,
-		ActionUpdatePackages	 = 0x00400000,
-		ActionUpdateSystem	 = 0x00800000,
-		ActionWhatProvides	 = 0x01000000,
-		ActionAcceptEula	 = 0x02000000,
-		ActionDownloadPackages	 = 0x04000000,
-		ActionGetDistroUpgrades	 = 0x08000000,
-		ActionGetCategories	 = 0x10000000,
-		ActionGetOldTransactions = 0x20000000,
-		UnknownAction		 = 0x40000000
+		ActionCancel			 = 0x000000001,
+		ActionGetDepends		 = 0x000000002,
+		ActionGetDetails		 = 0x000000004,
+		ActionGetFiles			 = 0x000000008,
+		ActionGetPackages		 = 0x000000010,
+		ActionGetRepoList		 = 0x000000020,
+		ActionGetRequires		 = 0x000000040,
+		ActionGetUpdateDetail		 = 0x000000080,
+		ActionGetUpdates		 = 0x000000100,
+		ActionInstallFiles		 = 0x000000200,
+		ActionInstallPackages		 = 0x000000400,
+		ActionInstallSignature		 = 0x000000800,
+		ActionRefreshCache		 = 0x000001000,
+		ActionRemovePackages		 = 0x000002000,
+		ActionRepoEnable		 = 0x000004000,
+		ActionRepoSetData		 = 0x000008000,
+		ActionResolve			 = 0x000010000,
+		ActionRollback			 = 0x000020000,
+		ActionSearchDetails		 = 0x000040000,
+		ActionSearchFile		 = 0x000080000,
+		ActionSearchGroup		 = 0x000100000,
+		ActionSearchName		 = 0x000200000,
+		ActionUpdatePackages		 = 0x000400000,
+		ActionUpdateSystem		 = 0x000800000,
+		ActionWhatProvides		 = 0x001000000,
+		ActionAcceptEula		 = 0x002000000,
+		ActionDownloadPackages		 = 0x004000000,
+		ActionGetDistroUpgrades		 = 0x008000000,
+		ActionGetCategories		 = 0x010000000,
+		ActionGetOldTransactions	 = 0x020000000,
+		ActionSimulateInstallFiles	 = 0x040000000,
+		ActionSimulateInstallPackages	 = 0x080000000,
+		ActionSimulateRemovePackages	 = 0x100000000,
+		ActionSimulateUpdatePackages	 = 0x200000000,
+		UnknownAction			 = 0x400000000
 	} Action;
 	Q_DECLARE_FLAGS(Actions, Action);
 
@@ -708,6 +712,46 @@ public:
 	Package* searchFromDesktopFile(const QString& path);
 
 	/**
+	 * \brief Simulates an installation of \p files.
+	 *
+	 * You should call this method before installing \p files
+	 * \note: This method might emit packages with INSTALLING, REMOVING, UPDATING,
+	 *        REINSTALLING or OBSOLETING status.
+	 */
+	Transaction* simulateInstallFiles(const QStringList& files);
+	Transaction* simulateInstallFile(const QString& file);
+
+	/**
+	 * \brief Simulates an installation of \p packages.
+	 *
+	 * You should call this method before installing \p packages
+	 * \note: This method might emit packages with INSTALLING, REMOVING, UPDATING,
+	 *        REINSTALLING or OBSOLETING status.
+	 */
+	Transaction* simulateInstallPackages(const QList<Package*>& packages);
+	Transaction* simulateInstallPackage(Package* package);
+
+	/**
+	 * \brief Simulates a removal of \p packages.
+	 *
+	 * You should call this method before removing \p packages
+	 * \note: This method might emit packages with INSTALLING, REMOVING, UPDATING,
+	 *        REINSTALLING or OBSOLETING status.
+	 */
+	Transaction* simulateRemovePackages(const QList<Package*>& packages);
+	Transaction* simulateRemovePackage(Package* package);
+
+	/**
+	 * \brief Simulates an update of \p packages.
+	 *
+	 * You should call this method before updating \p packages
+	 * \note: This method might emit packages with INSTALLING, REMOVING, UPDATING,
+	 *        REINSTALLING or OBSOLETING status.
+	 */
+	Transaction* simulateUpdatePackages(const QList<Package*>& packages);
+	Transaction* simulateUpdatePackage(Package* package);
+
+	/**
 	 * Update the given \p packages
 	 */
 	Transaction* updatePackages(bool only_trusted, const QList<Package*>& packages);
diff --git a/lib/packagekit-qt/src/transactionproxy.h b/lib/packagekit-qt/src/transactionproxy.h
index 68e9a33..015091a 100644
--- a/lib/packagekit-qt/src/transactionproxy.h
+++ b/lib/packagekit-qt/src/transactionproxy.h
@@ -277,6 +277,34 @@ public Q_SLOTS: // METHODS
         return callWithArgumentList(QDBus::Block, QLatin1String("SetLocale"), argumentList);
     }
 
+    inline QDBusReply<void> SimulateInstallFiles(const QStringList &full_paths)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(full_paths);
+        return callWithArgumentList(QDBus::Block, QLatin1String("SimulateInstallFiles"), argumentList);
+    }
+
+    inline QDBusReply<void> SimulateInstallPackages(const QStringList &package_ids)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(package_ids);
+        return callWithArgumentList(QDBus::Block, QLatin1String("SimulateInstallPackages"), argumentList);
+    }
+
+    inline QDBusReply<void> SimulateRemovePackages(const QStringList &package_ids)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(package_ids);
+        return callWithArgumentList(QDBus::Block, QLatin1String("SimulateRemovePackages"), argumentList);
+    }
+
+    inline QDBusReply<void> SimulateUpdatePackages(const QStringList &package_ids)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(package_ids);
+        return callWithArgumentList(QDBus::Block, QLatin1String("SimulateUpdatePackages"), argumentList);
+    }
+
     inline QDBusReply<void> UpdatePackages(bool only_trusted, const QStringList &package_ids)
     {
         QList<QVariant> argumentList;
@@ -287,7 +315,7 @@ public Q_SLOTS: // METHODS
     inline QDBusReply<void> UpdateSystem(bool only_trusted)
     {
         QList<QVariant> argumentList;
-		argumentList << qVariantFromValue (only_trusted);
+        argumentList << qVariantFromValue (only_trusted);
         return callWithArgumentList(QDBus::Block, QLatin1String("UpdateSystem"), argumentList);
     }
 
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 6a80e63..de1e2c6 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -3131,7 +3131,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 	GError *error;
 	GError *error_local = NULL;
 	PkServicePack *service_pack;
-	gchar *content_type = NULL;
+	gchar *content_type;
 	guint length;
 	guint i;
 
@@ -3148,7 +3148,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 				     "InstallFiles not yet supported by backend");
 		pk_transaction_release_tid (transaction);
 		pk_transaction_dbus_return_error (context, error);
-		goto out;
+		return;
 	}
 
 	/* check if the sender is the same */
@@ -3156,7 +3156,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 	if (!ret) {
 		/* don't release tid */
 		pk_transaction_dbus_return_error (context, error);
-		goto out;
+		return;
 	}
 
 	/* check all files exists and are valid */
@@ -3170,7 +3170,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 					     "No such file %s", full_paths[i]);
 			pk_transaction_release_tid (transaction);
 			pk_transaction_dbus_return_error (context, error);
-			goto out;
+			return;
 		}
 
 		/* get content type */
@@ -3180,17 +3180,18 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 					     "Failed to get content type for file %s", full_paths[i]);
 			pk_transaction_release_tid (transaction);
 			pk_transaction_dbus_return_error (context, error);
-			goto out;
+			return;
 		}
 
 		/* supported content type? */
 		ret = pk_transaction_is_supported_content_type (transaction, content_type);
+		g_free (content_type);
 		if (!ret) {
 			error = g_error_new (PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_MIME_TYPE_NOT_SUPPORTED,
 					     "MIME type '%s' not supported %s", content_type, full_paths[i]);
 			pk_transaction_release_tid (transaction);
 			pk_transaction_dbus_return_error (context, error);
-			goto out;
+			return;
 		}
 
 		/* valid */
@@ -3204,7 +3205,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 				pk_transaction_release_tid (transaction);
 				pk_transaction_dbus_return_error (context, error);
 				g_error_free (error_local);
-				goto out;
+				return;
 			}
 		}
 	}
@@ -3214,7 +3215,7 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 	if (!ret) {
 		pk_transaction_release_tid (transaction);
 		pk_transaction_dbus_return_error (context, error);
-		goto out;
+		return;
 	}
 
 	/* save so we can run later */
@@ -3224,8 +3225,6 @@ pk_transaction_install_files (PkTransaction *transaction, gboolean only_trusted,
 
 	/* return from async with success */
 	pk_transaction_dbus_return (context);
-out:
-	g_free (content_type);
 	return;
 }
 
