Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37404717
en ru br
ALT Linux repos
S:1.2.5.0.0.30-alt1

Group :: Other
RPM: packagekit

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: packagekit-1.2.5.0.0.30-alt.patch
Download


 .gear/packagekit.sh                         |    3 +
 .gear/packagekit.spec                       |  420 ++++++++++
 .gear/rules                                 |    4 +
 .gear/tags/list                             |    1 +
 backends/aptcc/20packagekit                 |    8 +-
 backends/aptcc/acqpkitstatus.h              |   16 +-
 backends/aptcc/apt-cache-file.cpp           |  167 ++--
 backends/aptcc/apt-cache-file.h             |   60 +-
 backends/aptcc/apt-intf.cpp                 | 1103 ++++-----------------------
 backends/aptcc/apt-intf.h                   |   50 +-
 backends/aptcc/apt-utils.cpp                |  295 +++----
 backends/aptcc/meson.build                  |   39 +-
 backends/aptcc/pk-backend-aptcc.cpp         |  144 +---
 backends/aptcc/pk-debconf-helper.c          |   54 --
 backends/aptcc/pk-debconf-helper.service.in |    7 -
 backends/aptcc/pk-debconf-helper.socket.in  |    8 -
 backends/aptcc/pkg-list.cpp                 |    2 +
 client/meson.build                          |   11 +
 client/pk-invoke-filetriggers.sh.in         |    7 +
 client/pk-offline-update.c                  |   72 +-
 data/meson.build                            |    1 +
 data/packagekit-offline-update.service.in   |    6 +
 data/packagekit.service.in                  |    2 +
 lib/packagekit-glib2/pk-offline.c           |    3 +-
 24 files changed, 965 insertions(+), 1518 deletions(-)
diff --git a/.gear/packagekit.sh b/.gear/packagekit.sh
new file mode 100644
index 000000000..c8f76961b
--- /dev/null
+++ b/.gear/packagekit.sh
@@ -0,0 +1,3 @@
+#/bin/sh
+PKCON=`which pkcon`
+[ -n "$PKCON" ] && $PKCON quit ||:
diff --git a/.gear/packagekit.spec b/.gear/packagekit.spec
new file mode 100644
index 000000000..7abdfc043
--- /dev/null
+++ b/.gear/packagekit.spec
@@ -0,0 +1,420 @@
+%define _unpackaged_files_terminate_build 1
+%define _stripped_files_terminate_build 1
+%set_verify_elf_method strict
+# it's also needed for RPM_LD_PRELOAD_packagekit to work (see below).
+
+Summary:   Package management service
+Name:      packagekit
+Version:   1.2.5.0.0.30
+Release:   alt1
+License:   LGPL-2.1+
+Group:     Other
+URL:       http://www.freedesktop.org/software/PackageKit/
+
+# https://github.com/PackageKit/PackageKit.git
+Source: %name-%version.tar
+Source2: packagekit.sh
+Patch1: %name-%version-alt.patch
+
+BuildRequires(pre): rpm-build-python3
+BuildRequires(pre): meson
+BuildRequires: gcc-c++
+BuildRequires: gobject-introspection-devel
+BuildRequires: gtk-doc
+BuildRequires: intltool
+BuildRequires: libsqlite3-devel
+BuildRequires: libpolkit-devel
+BuildRequires: libsystemd-devel
+BuildRequires: libapt-devel
+BuildRequires: gstreamer1.0-devel
+BuildRequires: gst-plugins1.0-devel
+BuildRequires: appstream-devel
+BuildRequires: bash-completion
+
+BuildRequires: vala-tools
+BuildRequires: libgtk+3-devel
+
+BuildRequires: boost-devel
+
+# It provides the stuff needed to run the APT backend: the download methods
+# (/usr/lib*/apt/methods/), conf files (/etc/apt/), and cache dirs
+# (/var/cache/apt/archives/).
+Requires: apt
+
+%add_findreq_skiplist  %_datadir/vala/vapi/*
+%add_findprov_skiplist %_datadir/vala/vapi/*
+
+%description
+PackageKit is a D-Bus abstraction layer that allows the session user
+to manage packages in a secure way using a cross-distro,
+cross-architecture API.
+
+%package -n lib%name-glib
+Summary: GLib libraries for accessing PackageKit
+Group: Other
+
+%description -n lib%name-glib
+GLib libraries for accessing PackageKit.
+Group: Other
+
+%package cron
+Summary: Cron job and related utilities for PackageKit
+Group: Other
+BuildArch: noarch
+Requires: %name = %EVR
+
+%description cron
+Crontab and utilities for running PackageKit as a cron job.
+
+%package -n lib%name-glib-devel
+Summary: GLib Libraries and headers for PackageKit
+Group: Development/Other
+Requires: lib%name-glib = %EVR
+
+%description -n lib%name-glib-devel
+GLib headers and libraries for PackageKit.
+
+%package gstreamer-plugin
+Summary: Install GStreamer codecs using PackageKit
+Group: Other
+Requires: lib%name-glib = %EVR
+
+%description gstreamer-plugin
+The PackageKit GStreamer plugin allows any Gstreamer application to install
+codecs from configured repositories using PackageKit.
+
+%package -n lib%name-gtk3-module
+Summary: Install fonts automatically using PackageKit
+Group: Other
+Requires: lib%name-glib = %EVR
+
+%description -n lib%name-gtk3-module
+The PackageKit GTK3+ module allows any Pango application to install
+fonts from configured repositories using PackageKit.
+
+%package command-not-found
+Summary: Ask the user to install command line programs automatically
+Group: Other
+Requires: lib%name-glib = %EVR
+
+%description command-not-found
+A simple helper that offers to install new packages on the command line
+using PackageKit.
+
+%package -n python3-module-%name
+Summary: Python3 backend for PackageKit
+Group: Development/Python3
+BuildArch: noarch
+Requires: %name = %EVR
+
+%description -n python3-module-%name
+Python3 backend for PackageKit.
+
+%prep
+%setup
+%patch1 -p1
+%ifarch %e2k
+# workaround for EDG frontend
+sed -i "s|g_autofree gchar \*|g_autofree_edg(gchar) |" backends/aptcc/apt-{utils,intf}.cpp
+%endif
+
+%build
+%ifnarch %e2k
+%add_optflags -std=c++17
+%else
+%add_optflags -std=c++14
+%endif
+%add_optflags -D_FILE_OFFSET_BITS=64
+%meson \
+	-Dpackaging_backend=aptcc \
+	-Dsystemd=true \
+	-Doffline_update=true \
+	-Dgtk_doc=true \
+	-Dlocal_checkout=false \
+	-Dpython_backend=true \
+	-Ddaemon_tests=false \
+	%nil
+
+%meson_build
+
+%install
+%meson_install
+
+# Create directories for downloaded appstream data
+mkdir -p %buildroot%_cachedir/app-info/{icons,xmls}
+
+# create a link that GStreamer will recognise
+pushd %buildroot%_libexecdir
+ln -s pk-gstreamer-install gst-install-plugins-helper
+popd
+
+# enable packagekit-offline-updates.service here for now, till we
+# decide how to do it upstream after the meson conversion:
+# https://github.com/PackageKit/PackageKit/issues/401
+# https://bugzilla.redhat.com/show_bug.cgi?id=1833176
+mkdir -p %{buildroot}%{_unitdir}/system-update.target.wants/
+ln -sf ../packagekit-offline-update.service %{buildroot}%{_unitdir}/system-update.target.wants/packagekit-offline-update.service
+
+# get rid of test backend
+rm -f %buildroot%_libdir/packagekit-backend/libpk_backend_test_*.so
+rm -rf %buildroot%_datadir/PackageKit/helpers/test_spawn
+
+# Following scripts seems unused, and it needs to be patched for ALT should it be used
+rm -f %buildroot%_datadir/PackageKit/pk-upgrade-distro.sh
+
+# Remove unused files
+rm -f %buildroot%_datadir/PackageKit/helpers/aptcc/pkconffile.nodiff
+
+touch %buildroot%_localstatedir/PackageKit/upgrade_lock
+
+mkdir -p %buildroot%_sysconfdir/NetworkManager/dispatcher.d/pre-up.d/
+install -m 0755 %SOURCE2 %buildroot%_sysconfdir/NetworkManager/dispatcher.d/pre-up.d/
+
+%find_lang PackageKit
+
+# We have to choose against which executable to verify the symbols
+# in the backend modules. I've chosen the one that rarely gets to be used
+# (packagekit-direct), so that it receives more "testing" and problems like
+# https://github.com/PackageKit/PackageKit/issues/477 don't stay unnoticed.
+#export RPM_LD_PRELOAD_packagekit=%buildroot%_libexecdir/packagekitd
+export RPM_LD_PRELOAD_packagekit=%buildroot%_libexecdir/packagekit-direct
+export RPM_FILES_TO_LD_PRELOAD_packagekit='%_libdir/packagekit-backend/*.so'
+# To rely on this feature, one should have set_verify_elf_method strict
+
+%post
+SYSTEMCTL=systemctl
+if sd_booted && "$SYSTEMCTL" --version >/dev/null 2>&1; then
+	"$SYSTEMCTL" daemon-reload
+	if [ "$RPM_INSTALL_ARG1" -eq 1 ]; then
+		"$SYSTEMCTL" -q preset %name
+	else
+		# only request stop of service, don't restart it
+		"$SYSTEMCTL" is-active --quiet %name && %_bindir/pkcon quit 2>/dev/null ||:
+	fi
+fi
+
+%preun
+SYSTEMCTL=systemctl
+
+[ "$RPM_INSTALL_ARG1" -eq 0 ] 2>/dev/null || exit 0
+
+if sd_booted && "$SYSTEMCTL" --version >/dev/null 2>&1; then
+	"$SYSTEMCTL" --no-reload -q disable "$1.service"
+	%_bindir/pkcon quit 2>/dev/null ||:
+fi
+
+%triggerin -- librpm7
+# only on update of librpm7
+if [ $2 -eq 2 ] ; then
+	# if librpm7 is updated, prohibit packagekit to start and ask it to quit
+	touch %_localstatedir/PackageKit/upgrade_lock
+	SYSTEMCTL=systemctl
+	sd_booted && $SYSTEMCTL is-active --quiet %name && %_bindir/pkcon quit 2>/dev/null ||:
+fi
+:
+
+%triggerpostun -- librpm7
+# after librpm7 is updated, allow packagekit to restart on request
+# it may be a good idea to move this to librpm7 package's delayed actions
+rm -f %_localstatedir/PackageKit/upgrade_lock ||:
+:
+
+%files -f PackageKit.lang
+%doc COPYING
+%doc README AUTHORS NEWS
+%dir %_datadir/PackageKit
+%dir %_datadir/PackageKit/helpers
+%dir %_sysconfdir/PackageKit
+%dir %_localstatedir/PackageKit
+%dir %_cachedir/app-info
+%dir %_cachedir/app-info/icons
+%dir %_cachedir/app-info/xmls
+%dir %_libdir/packagekit-backend
+%config(noreplace) %_sysconfdir/PackageKit/PackageKit.conf
+%config(noreplace) %_sysconfdir/PackageKit/Vendor.conf
+%config %_sysconfdir/dbus-1/system.d/*
+%_man1dir/pkcon.1*
+%_man1dir/pkmon.1*
+%_datadir/polkit-1/actions/*.policy
+%_datadir/polkit-1/rules.d/*
+%_datadir/bash-completion/completions/pkcon
+%_libexecdir/packagekitd
+%_libexecdir/packagekit-direct
+%_bindir/pkmon
+%_bindir/pkcon
+%exclude %_libdir/libpackagekit*.so.*
+%ghost %verify(not md5 size mtime) %_localstatedir/PackageKit/transactions.db
+%ghost %_localstatedir/PackageKit/upgrade_lock
+%_datadir/dbus-1/system-services/*.service
+%_unitdir/packagekit-offline-update.service
+%_unitdir/packagekit.service
+%_unitdir/system-update.target.wants/
+%_libexecdir/pk-*offline-update
+%config %_sysconfdir/apt/apt.conf.d/20packagekit
+%_libdir/packagekit-backend/libpk_backend_aptcc.so
+%_libexecdir/pk-invoke-filetriggers.sh
+%_sysconfdir/NetworkManager/dispatcher.d/pre-up.d/packagekit.sh
+
+%files -n lib%name-glib
+%_libdir/*packagekit-glib2.so.*
+%_libdir/girepository-1.0/PackageKitGlib-1.0.typelib
+
+%files cron
+%config %_sysconfdir/cron.daily/packagekit-background.cron
+%config(noreplace) %_sysconfdir/sysconfig/packagekit-background
+
+%files gstreamer-plugin
+%_libexecdir/pk-gstreamer-install
+%_libexecdir/gst-install-plugins-helper
+
+%files -n lib%name-gtk3-module
+%_libdir/gtk-3.0/modules/*.so
+%_libdir/gnome-settings-daemon-3.0/gtk-modules/*.desktop
+
+%files command-not-found
+%_sysconfdir/profile.d/*
+%_libexecdir/pk-command-not-found
+%config(noreplace) %_sysconfdir/PackageKit/CommandNotFound.conf
+
+%files -n lib%name-glib-devel
+%_libdir/libpackagekit-glib2.so
+%_pkgconfigdir/packagekit-glib2.pc
+%dir %_includedir/PackageKit
+%dir %_includedir/PackageKit/packagekit-glib2
+%_includedir/PackageKit/packagekit-glib*/*.h
+%_datadir/dbus-1/interfaces/*.xml
+%_datadir/gir-1.0/PackageKitGlib-1.0.gir
+%_datadir/gtk-doc/html/PackageKit
+%_datadir/vala/vapi/packagekit-glib2.vapi
+%_datadir/vala/vapi/packagekit-glib2.deps
+
+%files -n python3-module-%name
+%python3_sitelibdir_noarch/*
+
+
+%package checkinstall
+Summary: Immediately test PK when installing this package
+Group: Other
+BuildArch: noarch
+Requires: apt-under-pkdirect-checkinstall
+
+%description checkinstall
+Immediately test PackageKit when installing this package.
+
+%files checkinstall
+
+
+%changelog
+* Mon Jul 17 2023 Ivan Zakharyaschev <imz@altlinux.org> 1.2.5.0.0.30-alt1
+- Build PACKAGEKIT_1_2_5-30-g8957e9e49 with a fix for
+  https://github.com/PackageKit/PackageKit/issues/539 (random crash).
+
+* Wed Aug 24 2022 Ivan Zakharyaschev <imz@altlinux.org> 1.2.5-alt7
+- Rewritten a tiny piece of code to fix build with lcc.
+- Adapted to ALT's apt API a bit further by dropping an unused parameter of
+  MarkInstall(). (In apt, it either has a default value or will be eliminated.)
+
+* Wed Aug 17 2022 Oleg Solovyov <mcpain@altlinux.org> 1.2.5-alt6
+- offline-update: create btrfs snapshot via timeshift before committing changes
+
+* Tue Mar 22 2022 Oleg Solovyov <mcpain@altlinux.org> 1.2.5-alt5
+- Restart via 'pkcon quit'
+
+* Fri Mar 18 2022 Oleg Solovyov <mcpain@altlinux.org> 1.2.5-alt4
+- Fix gnome-software "No packages to remove" error (Closes: #42094)
+
+* Tue Mar 15 2022 Oleg Solovyov <mcpain@altlinux.org> 1.2.5-alt3
+- Fix package for dependent builds
+- Restart service before connecting to network
+
+* Mon Mar 14 2022 Oleg Solovyov <mcpain@altlinux.org> 1.2.5-alt2
+- Avoid restarting via 'pkcon quit'
+- Break circular dependencies between packagekit and libpackagekit-glib
+
+* Thu Feb 24 2022 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.5-alt1
+- Updated to upstream version 1.2.5.
+
+* Thu Jan 27 2022 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.4-alt5
+- Reworked refresh action.
+
+* Mon Jan 10 2022 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.4-alt4
+- Packagekit service must wait for network connection (Closes: #41633).
+
+* Thu Dec 02 2021 Oleg Solovyov <mcpain@altlinux.org> 1.2.4-alt3
+- Show actual update percentage during offline update
+
+* Thu Sep 16 2021 Ilya Kurdyukov <ilyakurdyukov@altlinux.org> 1.2.4-alt2
+- Fixes for Elbrus build.
+
+* Mon Aug 02 2021 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.4-alt1
+- Updated to upstream version 1.2.4.
+
+* Wed Jun 16 2021 Ivan Zakharyaschev <imz@altlinux.org> 1.2.3-alt3
+- Adapted to changed API in apt-0.5.15lorg2-alt72
+  (pkgCacheFile class in RAII style).
+- This also fixed a memory leak/dangling pointers to the caches.
+  (The old implementation of pkgCacheFile in apt was "wrong".)
+
+* Mon May 24 2021 Ivan Zakharyaschev <imz@altlinux.org> 1.2.3-alt2
+- Fixed /usr/lib/packagekit-direct (that didn't work, because
+  it couldn't load the APT backend).
+
+* Thu Mar 25 2021 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.3-alt1
+- Updated to upstream version 1.2.3.
+
+* Tue Dec 01 2020 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.2-alt1
+- Updated to upstream version 1.2.2.
+- Disabled vala requires and provides due to conflicts.
+
+* Tue Oct 27 2020 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.1-alt2
+- Cut functions depending on access to rpm via apt (on request by rider@).
+
+* Mon Sep 14 2020 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.1-alt1
+- Updated to upstream version 1.2.1.
+
+* Fri Jun 05 2020 Aleksei Nikiforov <darktemplar@altlinux.org> 1.2.0-alt1
+- Updated to upstream version 1.2.0.
+
+* Wed Apr 01 2020 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.13-alt1
+- Updated to upstream version 1.1.13.
+
+* Mon Oct 14 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt12
+- Imported changes from upstream.
+
+* Mon Sep 30 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt11
+- Improved provision of information about obsoleting and obsoleted packages.
+
+* Tue Sep 17 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt10
+- Added support for lua scripts.
+- Disabled verbose logging for packagekit service.
+- Pulled minor fixes and updates from upstream.
+
+* Fri Aug 30 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt9
+- Added special formatting for ALT repositories origin.
+- Fixed displaying obsoleted packages in output of 'pkcon get-updates'.
+
+* Fri Aug 30 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt8
+- Fixed processing obsoletes during upgrades (Closes: #36342).
+
+* Wed Jun 26 2019 Ivan Zakharyaschev <imz@altlinux.org> 1.1.12-alt7
+- Fixed support for refreshCache action. (Thx Aleksei Nikiforov darktemplar@)
+
+* Thu Jun 13 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt6
+- Rebuilt with new Apt.
+
+* Wed Feb 06 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt5
+- Fixed crash during showing errors.
+- Enabled verbose logging for packagekit service.
+
+* Fri Feb 01 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt4
+- Fixed stopping service without finishing current request.
+
+* Thu Jan 31 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt3
+- Updated build dependencies.
+
+* Mon Jan 28 2019 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt2
+- Forced stopping and blocked restarting of packagekit service during
+  upgrade of librpm7, improved locking (Closes: #35987).
+
+* Tue Dec 18 2018 Aleksei Nikiforov <darktemplar@altlinux.org> 1.1.12-alt1
+- Initial build for ALT.
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 000000000..e19b673ec
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,4 @@
+spec: .gear/packagekit.spec
+tar: @name@-@version@:.
+diff: @name@-@version@:. . name=@name@-@version@-alt.patch
+copy: .gear/packagekit.sh
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 000000000..4e93dae81
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+8957e9e49c3276b3affbe1c1023a520ac2daa8d2 packagekit-1.2.5.0.0.30
diff --git a/backends/aptcc/20packagekit b/backends/aptcc/20packagekit
index 705cc2fed..6fc6cbea5 100644
--- a/backends/aptcc/20packagekit
+++ b/backends/aptcc/20packagekit
@@ -1,13 +1,7 @@
 // THIS FILE IS USED TO INFORM PACKAGEKIT
 // THAT THE UPDATE-INFO MIGHT HAVE CHANGED
 
-// Whenever dpkg is called we might have different updates
-// i.e. if an user removes a package that had an update
-DPkg::Post-Invoke {
-"/usr/bin/test -e /usr/share/dbus-1/system-services/org.freedesktop.PackageKit.service && /usr/bin/test -S /var/run/dbus/system_bus_socket && /usr/bin/gdbus call --system --dest org.freedesktop.PackageKit --object-path /org/freedesktop/PackageKit --timeout 4 --method org.freedesktop.PackageKit.StateHasChanged cache-update > /dev/null; /bin/echo > /dev/null";
-};
-
 // When Apt's cache is updated (i.e. apt-cache update)
-APT::Update::Post-Invoke-Success {
+RPM::Post-Invoke {
 "/usr/bin/test -e /usr/share/dbus-1/system-services/org.freedesktop.PackageKit.service && /usr/bin/test -S /var/run/dbus/system_bus_socket && /usr/bin/gdbus call --system --dest org.freedesktop.PackageKit --object-path /org/freedesktop/PackageKit --timeout 4 --method org.freedesktop.PackageKit.StateHasChanged cache-update > /dev/null; /bin/echo > /dev/null";
 };
diff --git a/backends/aptcc/acqpkitstatus.h b/backends/aptcc/acqpkitstatus.h
index 7a303debe..35e834668 100644
--- a/backends/aptcc/acqpkitstatus.h
+++ b/backends/aptcc/acqpkitstatus.h
@@ -37,15 +37,15 @@ class AcqPackageKitStatus : public pkgAcquireStatus
 public:
     AcqPackageKitStatus(AptIntf *apt, PkBackendJob *job);
 
-    virtual bool MediaChange(string Media, string Drive);
-    virtual void IMSHit(pkgAcquire::ItemDesc &Itm);
-    virtual void Fetch(pkgAcquire::ItemDesc &Itm);
-    virtual void Done(pkgAcquire::ItemDesc &Itm);
-    virtual void Fail(pkgAcquire::ItemDesc &Itm);
-    virtual void Start();
-    virtual void Stop();
+    virtual bool MediaChange(string Media, string Drive) override;
+    virtual void IMSHit(pkgAcquire::ItemDesc &Itm) override;
+    virtual void Fetch(pkgAcquire::ItemDesc &Itm) override;
+    virtual void Done(pkgAcquire::ItemDesc &Itm) override;
+    virtual void Fail(pkgAcquire::ItemDesc &Itm) override;
+    virtual void Start() override;
+    virtual void Stop() override;
 
-    bool Pulse(pkgAcquire *Owner);
+    bool Pulse(pkgAcquire *Owner) override;
 
 private:
     void updateStatus(pkgAcquire::ItemDesc & Itm, int status);
diff --git a/backends/aptcc/apt-cache-file.cpp b/backends/aptcc/apt-cache-file.cpp
index 6cc89e66a..13195b195 100644
--- a/backends/aptcc/apt-cache-file.cpp
+++ b/backends/aptcc/apt-cache-file.cpp
@@ -25,47 +25,55 @@
 #include <cstdio>
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/progress.h>
-#include <apt-pkg/upgrade.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/version.h>
 
 #include "apt-utils.h"
 #include "apt-messages.h"
 
-using namespace APT;
-
-AptCacheFile::AptCacheFile(PkBackendJob *job) :
+AptCacheFile::AptCacheFile(PkBackendJob *job, bool const withLock,
+                           OpPackageKitProgress *progress) :
+    pkgCacheFile(withLock),
     m_packageRecords(0),
-    m_job(job)
+    m_job(job),
+    m_progress(progress)
 {
 }
 
 AptCacheFile::~AptCacheFile()
 {
-    Close();
+    delete m_packageRecords;
+
+    m_packageRecords = 0;
+
+    // Discard all errors to avoid a future failure when opening
+    // the package cache
+    _error->Discard();
 }
 
-bool AptCacheFile::Open(bool withLock)
+bool AptCacheFile::Open()
 {
-    OpPackageKitProgress progress(m_job);
-    return pkgCacheFile::Open(&progress, withLock);
+    return pkgCacheFile::Open(*m_progress);
 }
 
-void AptCacheFile::Close()
+bool AptCacheFile::BuildCaches()
 {
-    delete m_packageRecords;
-
-    m_packageRecords = 0;
+    return pkgCacheFile::BuildCaches(*m_progress);
+}
 
-    pkgCacheFile::Close();
+pkgCache* AptCacheFile::GetPkgCache()
+{
+    return pkgCacheFile::GetPkgCache(*m_progress);
+}
 
-    // Discard all errors to avoid a future failure when opening
-    // the package cache
-    _error->Discard();
+pkgPolicy* AptCacheFile::GetPolicy()
+{
+    return pkgCacheFile::GetPolicy(*m_progress);
 }
 
-bool AptCacheFile::BuildCaches(bool withLock)
+pkgDepCache* AptCacheFile::GetDepCache()
 {
-    OpPackageKitProgress progress(m_job);
-    return pkgCacheFile::BuildCaches(&progress, withLock);
+    return pkgCacheFile::GetDepCache(*m_progress);
 }
 
 bool AptCacheFile::CheckDeps(bool AllowBroken)
@@ -75,26 +83,26 @@ bool AptCacheFile::CheckDeps(bool AllowBroken)
     }
 
     // Check that the system is OK
-    if (DCache->DelCount() != 0 || DCache->InstCount() != 0) {
+    if (getDCache()->DelCount() != 0 || getDCache()->InstCount() != 0) {
         _error->Error("Internal error, non-zero counts");
         show_errors(m_job, PK_ERROR_ENUM_INTERNAL_ERROR);
         return false;
     }
 
     // Apply corrections for half-installed packages
-    if (pkgApplyStatus(*DCache) == false) {
+    if (pkgApplyStatus(*getDCache()) == false) {
         _error->Error("Unable to apply corrections for half-installed packages");;
         show_errors(m_job, PK_ERROR_ENUM_INTERNAL_ERROR);
         return false;
     }
 
     // Nothing is broken or we don't want to try fixing it
-    if (DCache->BrokenCount() == 0 || AllowBroken == true) {
+    if (getDCache()->BrokenCount() == 0 || AllowBroken == true) {
         return true;
     }
 
     // Attempt to fix broken things
-    if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0) {
+    if (pkgFixBroken(*getDCache()) == false || getDCache()->BrokenCount() != 0) {
         // We failed to fix the cache
         ShowBroken(true, PK_ERROR_ENUM_UNFINISHED_TRANSACTION);
 
@@ -102,7 +110,7 @@ bool AptCacheFile::CheckDeps(bool AllowBroken)
         return false;
     }
 
-    if (pkgMinimizeUpgrade(*DCache) == false) {
+    if (pkgMinimizeUpgrade(*getDCache()) == false) {
         g_warning("Unable to minimize the upgrade set");
         show_errors(m_job, PK_ERROR_ENUM_INTERNAL_ERROR);
         return false;
@@ -114,8 +122,7 @@ bool AptCacheFile::CheckDeps(bool AllowBroken)
 
 bool AptCacheFile::DistUpgrade()
 {
-    OpPackageKitProgress progress(m_job);
-    return Upgrade::Upgrade(*this, Upgrade::ALLOW_EVERYTHING, &progress);
+    return pkgDistUpgrade(*getDCache());
 }
 
 void AptCacheFile::ShowBroken(bool Now, PkErrorEnum error)
@@ -261,27 +268,9 @@ void AptCacheFile::buildPkgRecords()
     m_packageRecords = new pkgRecords(*this);
 }
 
-bool AptCacheFile::isGarbage(const pkgCache::PkgIterator &pkg)
-{
-    return (*this)[pkg].Garbage;
-}
-
 bool AptCacheFile::doAutomaticRemove()
 {
-    pkgDepCache::ActionGroup group(*this);
-
-    // look over the cache to see what can be removed
-    for (pkgCache::PkgIterator Pkg = (*this)->PkgBegin(); ! Pkg.end(); ++Pkg) {
-        if ((*this)[Pkg].Garbage) {
-            if (Pkg.CurrentVer() != 0 &&
-                    Pkg->CurrentState != pkgCache::State::ConfigFiles) {
-                // TODO, packagekit could provide a way to purge
-                (*this)->MarkDelete(Pkg, false);
-            } else {
-                (*this)->MarkKeep(Pkg, false, false);
-            }
-        }
-    }
+    pkgAutoremove(*getDCache());
 
     // Now see if we destroyed anything
     if ((*this)->BrokenCount() != 0) {
@@ -310,7 +299,24 @@ bool AptCacheFile::isRemovingEssentialPackages()
         }
 
         if ((*this)[I].Delete() == true) {
-            if (Added[I->ID] == false) {
+            bool is_obsoleted = false;
+
+            /* Following code fragment should be similar to pkgDistUpgrade's one */
+            for (pkgCache::DepIterator D = I.RevDependsList(); not D.end(); ++D)
+            {
+                if ((D->Type == pkgCache::Dep::Obsoletes)
+                    && ((*this)[D.ParentPkg()].CandidateVer != nullptr)
+                    && (*this)[D.ParentPkg()].CandidateVerIter(*this).Downloadable()
+                    && ((pkgCache::Version*)D.ParentVer() == (*this)[D.ParentPkg()].CandidateVer)
+                    && (*this)->VS().CheckDep(I.CurrentVer().VerStr(), D)
+                    && ((*this)->GetPkgPriority(D.ParentPkg()) >= (*this)->GetPkgPriority(I)))
+                {
+                    is_obsoleted = true;
+                    break;
+                }
+            }
+
+            if ((Added[I->ID] == false) && (is_obsoleted == false)) {
                 Added[I->ID] = true;
                 List += string(I.Name()) + " ";
             }
@@ -331,7 +337,24 @@ bool AptCacheFile::isRemovingEssentialPackages()
             pkgCache::PkgIterator P = D.SmartTargetPkg();
             if ((*this)[P].Delete() == true)
             {
-                if (Added[P->ID] == true){
+                bool is_obsoleted = false;
+
+                /* Following code fragment should be similar to pkgDistUpgrade's one */
+                for (pkgCache::DepIterator Dep2 = P.RevDependsList(); not Dep2.end(); ++Dep2)
+                {
+                    if ((Dep2->Type == pkgCache::Dep::Obsoletes)
+                        && ((*this)[Dep2.ParentPkg()].CandidateVer != nullptr)
+                        && (*this)[Dep2.ParentPkg()].CandidateVerIter(*this).Downloadable()
+                        && ((pkgCache::Version*)Dep2.ParentVer() == (*this)[Dep2.ParentPkg()].CandidateVer)
+                        && (*this)->VS().CheckDep(P.CurrentVer().VerStr(), Dep2)
+                        && ((*this)->GetPkgPriority(Dep2.ParentPkg()) >= (*this)->GetPkgPriority(P)))
+                    {
+                        is_obsoleted = true;
+                        break;
+                    }
+                }
+
+                if ((Added[P->ID] == true) || (is_obsoleted == true)){
                     continue;
                 }
                 Added[P->ID] = true;
@@ -361,7 +384,7 @@ PkgInfo AptCacheFile::resolvePkgID(const gchar *packageId)
     pkgCache::PkgIterator pkg;
 
     parts = pk_package_id_split(packageId);
-    pkg = (*this)->FindPkg(parts[PK_PACKAGE_ID_NAME], parts[PK_PACKAGE_ID_ARCH]);
+    pkg = (*this)->FindPkg(parts[PK_PACKAGE_ID_NAME]);
 
     // Ignore packages that could not be found or that exist only due to dependencies.
     if (pkg.end() || (pkg.VersionList().end() && pkg.ProvidesList().end()))
@@ -392,25 +415,15 @@ PkgInfo AptCacheFile::resolvePkgID(const gchar *packageId)
 
 gchar *AptCacheFile::buildPackageId(const pkgCache::VerIterator &ver)
 {
+    string data;
     pkgCache::VerFileIterator vf = ver.FileList();
     const pkgCache::PkgIterator &pkg = ver.ParentPkg();
-    pkgDepCache::StateCache &State = (*this)[pkg];
-
-    const bool isInstalled = (pkg->CurrentState == pkgCache::State::Installed && pkg.CurrentVer() == ver);
-    const bool isAuto = (State.CandidateVer != 0) && (State.Flags & pkgCache::Flag::Auto);
-
-    // when a package is installed manually, the data part of a package-id is "manual:<repo-id>",
-    // otherwise it is "auto:<repo-id>". Available (not installed) packages have no prefix, unless
-    // a pending installation is marked, in which case we prefix the desired new mode of the installed
-    // package (auto/manual) with a plus sign (+).
-    string data = "";
-    if (isInstalled) {
-        data = isAuto? "auto:" : "manual:";
+    if (pkg->CurrentState == pkgCache::State::Installed && pkg.CurrentVer() == ver) {
+        // when a package is installed, the data part of a package-id is "installed:<repo-id>"
+        data = "installed:" + utilBuildPackageOriginId(vf);
     } else {
-        if (State.NewInstall())
-            data = isAuto? "+auto:" : "+manual:";
+        data = utilBuildPackageOriginId(vf);
     }
-    data += utilBuildPackageOriginId(vf);
 
     return pk_package_id_build(ver.ParentPkg().Name(),
                                ver.VerStr(),
@@ -447,17 +460,7 @@ std::string AptCacheFile::getShortDescription(const pkgCache::VerIterator &ver)
         return string();
     }
 
-    pkgCache::DescIterator d = ver.TranslatedDescription();
-    if (d.end()) {
-        return string();
-    }
-
-    pkgCache::DescFileIterator df = d.FileList();
-    if (df.end()) {
-        return string();
-    } else {
-        return m_packageRecords->Lookup(df).ShortDesc();
-    }
+    return m_packageRecords->Lookup(ver.FileList()).ShortDesc();
 }
 
 std::string AptCacheFile::getLongDescription(const pkgCache::VerIterator &ver)
@@ -466,17 +469,7 @@ std::string AptCacheFile::getLongDescription(const pkgCache::VerIterator &ver)
         return string();
     }
 
-    pkgCache::DescIterator d = ver.TranslatedDescription();
-    if (d.end()) {
-        return string();
-    }
-
-    pkgCache::DescFileIterator df = d.FileList();
-    if (df.end()) {
-        return string();
-    } else {
-        return m_packageRecords->Lookup(df).LongDesc();
-    }
+    return m_packageRecords->Lookup(ver.FileList()).LongDesc();
 }
 
 std::string AptCacheFile::getLongDescriptionParsed(const pkgCache::VerIterator &ver)
@@ -535,7 +528,7 @@ bool AptCacheFile::tryToInstall(pkgProblemResolver &Fix,
     //   We probably should change the return value behavior and have the callee decide whether to
     //   error out or call us again with autoinst. This however is further complicated by us
     //   having protected, so we'd have to lift protection before this?
-    GetDepCache()->MarkInstall(Pkg, autoInst, 0, fromUser);
+    GetDepCache()->MarkInstall(Pkg, (fromUser ? pkgDepCache::AutoMarkFlag::Manual : pkgDepCache::AutoMarkFlag::Auto), autoInst);
     // Protect against further resolver changes.
     Fix.Clear(Pkg);
     Fix.Protect(Pkg);
diff --git a/backends/aptcc/apt-cache-file.h b/backends/aptcc/apt-cache-file.h
index 2deb8f1e9..ca9f9da8f 100644
--- a/backends/aptcc/apt-cache-file.h
+++ b/backends/aptcc/apt-cache-file.h
@@ -26,6 +26,25 @@
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/progress.h>
 #include <pk-backend.h>
+#include <apt-pkg/pkgrecords.h>
+
+/**
+ * This class is meant to show Operation Progress using PackageKit
+ */
+class OpPackageKitProgress : public OpProgress
+{
+public:
+    OpPackageKitProgress(PkBackendJob *job);
+    virtual ~OpPackageKitProgress();
+
+    virtual void Done() override;
+
+protected:
+    virtual void Update() override;
+
+private:
+    PkBackendJob  *m_job;
+};
 
 #include "pkg-list.h"
 
@@ -33,23 +52,18 @@ class pkgProblemResolver;
 class AptCacheFile : public pkgCacheFile
 {
 public:
-    AptCacheFile(PkBackendJob *job);
+    AptCacheFile(PkBackendJob *job, bool withLock, OpPackageKitProgress *progress);
     ~AptCacheFile();
 
     /**
       * Inits the package cache returning false if it can't open
       */
-    bool Open(bool withLock = false);
-
-    /**
-      * Closes the package cache
-      */
-    void Close();
+    bool Open();
 
     /**
       * Build caches
       */
-    bool BuildCaches(bool withLock = false);
+    bool BuildCaches();
 
     /**
       * This routine generates the caches and then opens the dependency cache
@@ -71,24 +85,21 @@ public:
      */
     void ShowBroken(bool Now, PkErrorEnum error = PK_ERROR_ENUM_DEP_RESOLUTION_FAILED);
 
+    pkgCache* GetPkgCache();
+
     inline pkgRecords* GetPkgRecords() { buildPkgRecords(); return m_packageRecords; }
 
     /**
       * GetPolicy will build the policy object if needed and return it
       * @note This override if because the cache should be built before the policy
       */
-    inline pkgPolicy* GetPolicy() { BuildCaches(); BuildPolicy(); return Policy; }
+    pkgPolicy* GetPolicy();
 
     /**
       * GetDepCache will build the dependency cache if needed and return it
       * @note This override if because the policy should be built before the dependency cache
       */
-    inline pkgDepCache* GetDepCache() { BuildCaches(); BuildPolicy(); BuildDepCache(); return DCache; }
-
-    /**
-     * Checks if the package is garbage (not depended on)
-     */
-    bool isGarbage(const pkgCache::PkgIterator &pkg);
+    pkgDepCache* GetDepCache();
 
     /**
      * DoAutomaticRemove - Remove all automatic unused packages
@@ -158,24 +169,7 @@ private:
 
     pkgRecords *m_packageRecords;
     PkBackendJob *m_job;
-};
-
-/**
- * This class is maent to show Operation Progress using PackageKit
- */
-class OpPackageKitProgress : public OpProgress
-{
-public:
-    OpPackageKitProgress(PkBackendJob *job);
-    virtual ~OpPackageKitProgress();
-
-    virtual void Done();
-
-protected:
-    virtual void Update();
-
-private:
-    PkBackendJob  *m_job;
+    OpPackageKitProgress *m_progress;
 };
 
 #endif // APT_CACHE_FILE_H
diff --git a/backends/aptcc/apt-intf.cpp b/backends/aptcc/apt-intf.cpp
index c34d71e7c..335f18d98 100644
--- a/backends/aptcc/apt-intf.cpp
+++ b/backends/aptcc/apt-intf.cpp
@@ -24,16 +24,20 @@
 
 #include "apt-intf.h"
 
-#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/init.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
-#include <apt-pkg/install-progress.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/update.h>
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/pkgsystem.h>
+#include <apt-pkg/update.h>
 #include <apt-pkg/version.h>
+#include <apt-pkg/sourcelist.h>
+
+#ifdef WITH_LUA
+#include <apt-pkg/luaiface.h>
+#endif
 
 #include <appstream.h>
 
@@ -44,31 +48,29 @@
 #include <sys/fcntl.h>
 #include <pty.h>
 
+#include <algorithm>
 #include <iostream>
 #include <sstream>
 #include <memory>
 #include <fstream>
 #include <dirent.h>
+#include <regex.h>
 
 #include "apt-cache-file.h"
 #include "apt-utils.h"
 #include "gst-matcher.h"
 #include "apt-messages.h"
 #include "acqpkitstatus.h"
-#include "deb-file.h"
-
-using namespace APT;
 
 #define RAMFS_MAGIC     0x858458f6
 
 AptIntf::AptIntf(PkBackendJob *job) :
-    m_cache(0),
     m_job(job),
     m_cancel(false),
     m_lastSubProgress(0),
-    m_terminalTimeout(120)
+    m_terminalTimeout(120),
+    m_progress(OpPackageKitProgress(job))
 {
-    m_cancel = false;
 }
 
 bool AptIntf::init(gchar **localDebs)
@@ -76,8 +78,6 @@ bool AptIntf::init(gchar **localDebs)
     const gchar *http_proxy;
     const gchar *ftp_proxy;
 
-    m_isMultiArch = APT::Configuration::getArchitectures(false).size() > 1;
-
     // set locale
     setEnvLocaleFromJob();
 
@@ -123,26 +123,32 @@ bool AptIntf::init(gchar **localDebs)
         withLock = !simulate;
     }
 
-    // Create the AptCacheFile class to search for packages
-    m_cache = new AptCacheFile(m_job);
-    if (localDebs) {
-        PkBitfield flags = pk_backend_job_get_transaction_flags(m_job);
-        if (pk_bitfield_contain(flags, PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED)) {
-            // We are NOT simulating and have untrusted packages
-            // fail the transaction.
-            pk_backend_job_error_code(m_job,
-                                  PK_ERROR_ENUM_CANNOT_INSTALL_REPO_UNSIGNED,
-                                  "Local packages cannot be authenticated");
-            return false;
-        }
+    int timeout = 10;
+    // TODO test this
+    if (withLock) {
+        for (;;) {
+            m_fileFd.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+            if (not _error->PendingError())
+            {
+                break;
+            }
 
-        for (guint i = 0; i < g_strv_length(localDebs); ++i)
-            markFileForInstall(localDebs[i]);
+            if (timeout <= 0)
+            {
+                show_errors(m_job, PK_ERROR_ENUM_CANNOT_GET_LOCK);
+                return false;
+            }
+
+            _error->Discard();
+            pk_backend_job_set_status(m_job, PK_STATUS_ENUM_WAITING_FOR_LOCK);
+            sleep(1);
+            timeout--;
+        }
     }
 
-    int timeout = 10;
-    // TODO test this
-    while (m_cache->Open(withLock) == false) {
+    // Create the AptCacheFile class to search for packages
+    m_cache.reset(new AptCacheFile(m_job, withLock, &m_progress));
+    while (m_cache->Open() == false) {
         if (withLock == false || (timeout <= 0)) {
             show_errors(m_job, PK_ERROR_ENUM_CANNOT_GET_LOCK);
             return false;
@@ -153,8 +159,10 @@ bool AptIntf::init(gchar **localDebs)
             timeout--;
         }
 
-        // Close the cache if we are going to try again
-        m_cache->Close();
+        // If we are going to try again, we can either simply try Open() once
+        // again (since pkgCacheFile is monotonic in creating required objects),
+        // or simply continue with a new pkgCacheFile object.
+        m_cache.reset(new AptCacheFile(m_job, withLock, &m_progress));
     }
 
     // default settings
@@ -174,11 +182,6 @@ bool AptIntf::init(gchar **localDebs)
     return m_cache->CheckDeps(AllowBroken);
 }
 
-AptIntf::~AptIntf()
-{
-    delete m_cache;
-}
-
 void AptIntf::setEnvLocaleFromJob()
 {
     const gchar *locale = pk_backend_job_get_locale(m_job);
@@ -220,16 +223,6 @@ bool AptIntf::matchPackage(const pkgCache::VerIterator &ver, PkBitfield filters)
         if (pkg->CurrentState == pkgCache::State::Installed && pkg.CurrentVer() == ver)
             installed = true;
 
-        // if we are on multiarch check also the arch filter
-        if (m_isMultiArch && pk_bitfield_contain(filters, PK_FILTER_ENUM_ARCH)/* && !installed*/) {
-            // don't emit the package if it does not match
-            // the native architecture
-            if (strcmp(ver.Arch(), "all") != 0 &&
-                    strcmp(ver.Arch(), _config->Find("APT::Architecture").c_str()) != 0) {
-                return false;
-            }
-        }
-
         std::string str = ver.Section() == NULL ? "" : ver.Section();
         std::string section, component;
 
@@ -295,32 +288,6 @@ bool AptIntf::matchPackage(const pkgCache::VerIterator &ver, PkBitfield filters)
             }
         }
 
-        // Check for supported packages
-        if (pk_bitfield_contain(filters, PK_FILTER_ENUM_SUPPORTED)) {
-            if (!packageIsSupported(ver, component)) {
-                return false;
-            }
-        } else if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_SUPPORTED)) {
-            if (packageIsSupported(ver, component)) {
-                return false;
-            }
-        }
-
-        // Check for applications, if they have files with .desktop
-        if (pk_bitfield_contain(filters, PK_FILTER_ENUM_APPLICATION)) {
-            // We do not support checking if it is an Application
-            // if NOT installed
-            if (!installed || !isApplication(ver)) {
-                return false;
-            }
-        } else if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_APPLICATION)) {
-            // We do not support checking if it is an Application
-            // if NOT installed
-            if (!installed || isApplication(ver)) {
-                return false;
-            }
-        }
-
         // TODO test this one..
 #if 0
         // I couldn'tfind any packages with the metapackages component, and I
@@ -360,11 +327,11 @@ PkgList AptIntf::filterPackages(const PkgList &packages, PkBitfield filters)
 
         pkgProblemResolver Fix(*m_cache);
         {
-            pkgDepCache::ActionGroup group(*m_cache);
             for (auto autoInst : { true, false }) {
                 for (const PkgInfo &pki : ret) {
-                    if (m_cancel)
+                    if (m_cancel) {
                         break;
+                    }
 
                     m_cache->tryToInstall(Fix, pki, autoInst, false);
                 }
@@ -374,14 +341,15 @@ PkgList AptIntf::filterPackages(const PkgList &packages, PkBitfield filters)
         // get a fetcher
         pkgAcquire fetcher;
 
+        pkgSourceList List;
         // Read the source list
-        if (m_cache->BuildSourceList() == false) {
+        if (List.ReadMainList() == false) {
             return downloaded;
         }
 
         // Create the package manager and prepare to download
         std::unique_ptr<pkgPackageManager> PM (_system->CreatePM(*m_cache));
-        if (!PM->GetArchives(&fetcher, m_cache->GetSourceList(), m_cache->GetPkgRecords()) ||
+        if (!PM->GetArchives(&fetcher, &List, m_cache->GetPkgRecords()) ||
                 _error->PendingError() == true) {
             return downloaded;
         }
@@ -498,26 +466,6 @@ void AptIntf::emitUpdates(PkgList &output, PkBitfield filters)
         // the default update info
         state = PK_INFO_ENUM_NORMAL;
 
-        // let find what kind of upgrade this is
-        pkgCache::VerFileIterator vf = pkgInfo.ver.FileList();
-        std::string origin  = vf.File().Origin() == NULL ? "" : vf.File().Origin();
-        std::string archive = vf.File().Archive() == NULL ? "" : vf.File().Archive();
-        std::string label   = vf.File().Label() == NULL ? "" : vf.File().Label();
-        if (origin.compare("Debian") == 0 ||
-                origin.compare("Ubuntu") == 0) {
-            if (ends_with(archive, "-security") ||
-                    label.compare("Debian-Security") == 0) {
-                state = PK_INFO_ENUM_SECURITY;
-            } else if (ends_with(archive, "-backports")) {
-                state = PK_INFO_ENUM_ENHANCEMENT;
-            } else if (ends_with(archive, "-updates")) {
-                state = PK_INFO_ENUM_BUGFIX;
-            }
-        } else if (origin.compare("Backports.org archive") == 0 ||
-                   ends_with(origin, "-backports")) {
-            state = PK_INFO_ENUM_ENHANCEMENT;
-        }
-
         emitPackage(pkgInfo.ver, state);
     }
 }
@@ -690,7 +638,12 @@ bool AptIntf::getArchive(pkgAcquire *Owner,
 
         // Try to cross match against the source list
         pkgIndexFile *Index;
-        if (m_cache->GetSourceList()->FindIndex(Vf.File(),Index) == false) {
+        pkgSourceList List;
+        if (List.ReadMainList() == false) {
+            continue;
+        }
+
+        if (List.FindIndex(Vf.File(),Index) == false) {
             continue;
         }
 
@@ -701,7 +654,7 @@ bool AptIntf::getArchive(pkgAcquire *Owner,
         }
 
         const string PkgFile = Parse.FileName();
-        const HashStringList hashes = Parse.Hashes();
+        const std::string hash_md5 = Parse.MD5Hash();
         if (PkgFile.empty() == true) {
             return _error->Error("The package index files are corrupted. No Filename: "
                                  "field for package %s.",
@@ -713,12 +666,10 @@ bool AptIntf::getArchive(pkgAcquire *Owner,
         // Create the item
         new pkgAcqFile(Owner,
                        Index->ArchiveURI(PkgFile),
-                       hashes,
+                       hash_md5,
                        Version->Size,
                        Index->ArchiveInfo(Version),
-                       Version.ParentPkg().Name(),
-                       "",
-                       DestFile);
+                       Version.ParentPkg().Name());
 
         Vf++;
         return true;
@@ -728,7 +679,7 @@ bool AptIntf::getArchive(pkgAcquire *Owner,
 
 AptCacheFile* AptIntf::aptCacheFile() const
 {
-    return m_cache;
+    return m_cache.get();
 }
 
 // used to emit packages it collects all the needed info
@@ -741,10 +692,6 @@ void AptIntf::emitPackageDetail(const pkgCache::VerIterator &ver)
     const pkgCache::PkgIterator &pkg = ver.ParentPkg();
     std::string section = ver.Section() == NULL ? "" : ver.Section();
 
-    size_t found;
-    found = section.find_last_of("/");
-    section = section.substr(found + 1);
-
     pkgCache::VerFileIterator vf = ver.FileList();
     pkgRecords::Parser &rec = m_cache->GetPkgRecords()->Lookup(vf);
 
@@ -763,7 +710,7 @@ void AptIntf::emitPackageDetail(const pkgCache::VerIterator &ver)
                            "unknown",
                            get_enum_group(section),
                            m_cache->getLongDescriptionParsed(ver).c_str(),
-                           rec.Homepage().c_str(),
+                           "",
                            size);
 }
 
@@ -821,8 +768,7 @@ void AptIntf::emitUpdateDetail(const pkgCache::VerIterator &candver)
         AcqPackageKitStatus Stat(this, m_job);
 
         // get a fetcher
-        pkgAcquire fetcher;
-        fetcher.SetLog(&Stat);
+        pkgAcquire fetcher(&Stat);
 
         // fetch the changelog
         pk_backend_job_set_status(m_job, PK_STATUS_ENUM_DOWNLOAD_CHANGELOG);
@@ -1075,10 +1021,6 @@ PkgList AptIntf::getPackagesFromGroup(gchar **values)
         if (ver.end() == false) {
             string section = pkg.VersionList().Section() == NULL ? "" : pkg.VersionList().Section();
 
-            size_t found;
-            found = section.find_last_of("/");
-            section = section.substr(found + 1);
-
             // Don't insert virtual packages instead add what it provides
             for (PkGroupEnum group : groups) {
                 if (group == get_enum_group(section)) {
@@ -1185,108 +1127,6 @@ PkgList AptIntf::searchPackageDetails(const vector<string> &queries)
     return output;
 }
 
-// used to return files it reads, using the info from the files in /var/lib/dpkg/info/
-PkgList AptIntf::searchPackageFiles(gchar **values)
-{
-    PkgList output;
-    vector<string> packages;
-    string search;
-    regex_t re;
-
-    for (uint i = 0; i < g_strv_length(values); ++i) {
-        gchar *value = values[i];
-        if (strlen(value) < 1) {
-            continue;
-        }
-
-        if (!search.empty()) {
-            search.append("|");
-        }
-
-        if (value[0] == '/') {
-            search.append("^");
-            search.append(value);
-            search.append("$");
-        } else {
-            search.append(value);
-            search.append("$");
-        }
-    }
-
-    if(regcomp(&re, search.c_str(), REG_NOSUB) != 0) {
-        g_debug("Regex compilation error");
-        return output;
-    }
-
-    DIR *dp;
-    struct dirent *dirp;
-    if (!(dp = opendir("/var/lib/dpkg/info/"))) {
-        g_debug ("Error opening /var/lib/dpkg/info/\n");
-        regfree(&re);
-        return output;
-    }
-
-    string line;
-    while ((dirp = readdir(dp)) != NULL) {
-        if (m_cancel) {
-            break;
-        }
-
-        if (ends_with(dirp->d_name, ".list")) {
-            string file(dirp->d_name);
-            string f = "/var/lib/dpkg/info/" + file;
-            ifstream in(f.c_str());
-            if (!in != 0) {
-                continue;
-            }
-
-            while (!in.eof()) {
-                getline(in, line);
-                if (regexec(&re, line.c_str(), (size_t)0, NULL, 0) == 0) {
-                    packages.push_back(file.erase(file.size() - 5, file.size()));
-                    break;
-                }
-            }
-        }
-    }
-    closedir(dp);
-    regfree(&re);
-
-    // Resolve the package names now
-    for (const string &name : packages) {
-        if (m_cancel) {
-            break;
-        }
-
-        pkgCache::PkgIterator pkg;
-        if (name.find(':') != std::string::npos) {
-            pkg = (*m_cache)->FindPkg(name);
-            if (pkg.end()) {
-                continue;
-            }
-        } else {
-            pkgCache::GrpIterator grp = (*m_cache)->FindGrp(name);
-            for (pkg = grp.PackageList(); pkg.end() == false; pkg = grp.NextPkg(pkg)) {
-                if (pkg->CurrentState == pkgCache::State::Installed) {
-                    break;
-                }
-            }
-
-            if (pkg->CurrentState != pkgCache::State::Installed) {
-                 continue;
-            }
-        }
-
-        const pkgCache::VerIterator &ver = m_cache->findVer(pkg);
-        if (ver.end()) {
-            continue;
-        }
-        output.append(ver);
-    }
-
-    return output;
-}
-
 PkgList AptIntf::getUpdates(PkgList &blocked, PkgList &downgrades, PkgList &installs, PkgList &removals, PkgList &obsoleted)
 {
     PkgList updates;
@@ -1332,14 +1172,15 @@ PkgList AptIntf::getUpdates(PkgList &blocked, PkgList &downgrades, PkgList &inst
             if (!ver.end()) {
                 bool is_obsoleted = false;
 
+                /* Following code fragment should be similar to pkgDistUpgrade's one */
                 for (pkgCache::DepIterator D = pkg.RevDependsList(); not D.end(); ++D)
                 {
                     if ((D->Type == pkgCache::Dep::Obsoletes)
                         && ((*m_cache)[D.ParentPkg()].CandidateVer != nullptr)
                         && (*m_cache)[D.ParentPkg()].CandidateVerIter(*m_cache).Downloadable()
                         && ((pkgCache::Version*)D.ParentVer() == (*m_cache)[D.ParentPkg()].CandidateVer)
-                        && (*m_cache)->VS().CheckDep(pkg.CurrentVer().VerStr(), D->CompareOp, D.TargetVer())
-                        && ((*m_cache)->GetPolicy().GetPriority(D.ParentPkg()) >= (*m_cache)->GetPolicy().GetPriority(pkg)))
+                        && (*m_cache)->VS().CheckDep(pkg.CurrentVer().VerStr(), D)
+                        && ((*m_cache)->GetPkgPriority(D.ParentPkg()) >= (*m_cache)->GetPkgPriority(pkg)))
                     {
                         is_obsoleted = true;
                         break;
@@ -1417,183 +1258,6 @@ void AptIntf::providesMimeType(PkgList &output, gchar **values)
     }
 }
 
-bool AptIntf::isApplication(const pkgCache::VerIterator &ver)
-{
-    bool ret = false;
-    gchar *fileName;
-    string line;
-
-    fileName = g_strdup_printf("/var/lib/dpkg/info/%s:%s.list",
-                               ver.ParentPkg().Name(),
-                               ver.Arch());
-    if (!FileExists(fileName)) {
-        g_free(fileName);
-        // if the file was not found try without the arch field
-        fileName = g_strdup_printf("/var/lib/dpkg/info/%s.list",
-                                   ver.ParentPkg().Name());
-    }
-
-    if (FileExists(fileName)) {
-        ifstream in(fileName);
-        if (!in != 0) {
-            g_free(fileName);
-            return false;
-        }
-
-        while (in.eof() == false) {
-            getline(in, line);
-            if (ends_with(line, ".desktop")) {
-                ret = true;
-                break;
-            }
-        }
-    }
-
-    g_free(fileName);
-    return ret;
-}
-
-// used to emit files it reads the info directly from the files
-void AptIntf::emitPackageFiles(const gchar *pi)
-{
-    GPtrArray *files;
-    string line;
-
-    g_auto(GStrv) parts = pk_package_id_split(pi);
-    string fName;
-    fName = "/var/lib/dpkg/info/" +
-            string(parts[PK_PACKAGE_ID_NAME]) +
-            ":" +
-            string(parts[PK_PACKAGE_ID_ARCH]) +
-            ".list";
-    if (!FileExists(fName)) {
-        // if the file was not found try without the arch field
-        fName = "/var/lib/dpkg/info/" +
-                string(parts[PK_PACKAGE_ID_NAME]) +
-                ".list";
-    }
-
-    if (FileExists(fName)) {
-        ifstream in(fName.c_str());
-        if (!in != 0) {
-            return;
-        }
-
-        files = g_ptr_array_new_with_free_func(g_free);
-        while (in.eof() == false) {
-            getline(in, line);
-            if (!line.empty()) {
-                g_ptr_array_add(files, g_strdup(line.c_str()));
-            }
-        }
-
-        if (files->len) {
-            g_ptr_array_add(files, NULL);
-            pk_backend_job_files(m_job, pi, (gchar **) files->pdata);
-        }
-        g_ptr_array_unref(files);
-    }
-}
-
-void AptIntf::emitPackageFilesLocal(const gchar *file)
-{
-    DebFile deb(file);
-    if (!deb.isValid()){
-        return;
-    }
-
-    g_autofree gchar *package_id = pk_package_id_build(deb.packageName().c_str(),
-                                                       deb.version().c_str(),
-                                                       deb.architecture().c_str(),
-                                                       file);
-
-    g_autoptr(GPtrArray) files = g_ptr_array_new_with_free_func(g_free);
-    for (auto file : deb.files()) {
-        g_ptr_array_add(files, g_canonicalize_filename(file.c_str(), "/"));
-    }
-    g_ptr_array_add(files, NULL);
-    pk_backend_job_files(m_job, package_id, (gchar **) files->pdata);
-}
-
-/**
-  * Check if package is officially supported by the current distribution
-  */
-bool AptIntf::packageIsSupported(const pkgCache::VerIterator &verIter, string component)
-{
-    string origin;
-    if (!verIter.end()) {
-        pkgCache::VerFileIterator vf = verIter.FileList();
-        origin = vf.File().Origin() == NULL ? "" : vf.File().Origin();
-    }
-
-    if (component.empty()) {
-        component = "main";
-    }
-
-    // Get a fetcher
-    AcqPackageKitStatus Stat(this, m_job);
-    pkgAcquire fetcher;
-    fetcher.SetLog(&Stat);
-
-    PkBitfield flags = pk_backend_job_get_transaction_flags(m_job);
-    bool trusted = checkTrusted(fetcher, flags);
-
-    if ((origin.compare("Debian") == 0) || (origin.compare("Ubuntu") == 0))  {
-        if ((component.compare("main") == 0 ||
-             component.compare("restricted") == 0 ||
-             component.compare("unstable") == 0 ||
-             component.compare("testing") == 0) && trusted) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool AptIntf::checkTrusted(pkgAcquire &fetcher, PkBitfield flags)
-{
-    string UntrustedList;
-    PkgList untrusted;
-    for (pkgAcquire::ItemIterator I = fetcher.ItemsBegin(); I < fetcher.ItemsEnd(); ++I) {
-        if (!(*I)->IsTrusted()) {
-            // The pkgAcquire::Item had a version hiden on it's subclass
-            // pkgAcqArchive but it was protected our subclass exposes that
-            pkgAcqArchiveSane *archive = static_cast<pkgAcqArchiveSane*>(dynamic_cast<pkgAcqArchive*>(*I));
-            if (archive == nullptr) {
-                continue;
-            }
-            untrusted.append(archive->version());
-
-            UntrustedList += string((*I)->ShortDesc()) + " ";
-        }
-    }
-
-    if (untrusted.empty()) {
-        return true;
-    } else if (pk_bitfield_contain(flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
-        // We are just simulating and have untrusted packages emit them
-        // and return true to continue processing
-        emitPackages(untrusted, PK_FILTER_ENUM_NONE, PK_INFO_ENUM_UNTRUSTED);
-
-        return true;
-    } else if (pk_bitfield_contain(flags, PK_TRANSACTION_FLAG_ENUM_ONLY_TRUSTED)) {
-        // We are NOT simulating and have untrusted packages
-        // fail the transaction.
-        pk_backend_job_error_code(m_job,
-                                  PK_ERROR_ENUM_CANNOT_INSTALL_REPO_UNSIGNED,
-                                  "The following packages cannot be authenticated:\n%s",
-                                  UntrustedList.c_str());
-        _error->Discard();
-
-        return false;
-    } else {
-        // We are NOT simulating and have untrusted packages
-        // But the user didn't set ONLY_TRUSTED flag
-        g_debug ("Authentication warning overridden.\n");
-        return true;
-    }
-}
-
 /**
  * checkChangedPackages - Check whas is goind to happen to the packages
  */
@@ -1627,14 +1291,15 @@ PkgList AptIntf::checkChangedPackages(bool emitChanged)
 
                 bool is_obsoleted = false;
 
+                /* Following code fragment should be similar to pkgDistUpgrade's one */
                 for (pkgCache::DepIterator D = pkg.RevDependsList(); not D.end(); ++D)
                 {
                     if ((D->Type == pkgCache::Dep::Obsoletes)
                             && ((*m_cache)[D.ParentPkg()].CandidateVer != nullptr)
                             && (*m_cache)[D.ParentPkg()].CandidateVerIter(*m_cache).Downloadable()
                             && ((pkgCache::Version*)D.ParentVer() == (*m_cache)[D.ParentPkg()].CandidateVer)
-                            && (*m_cache)->VS().CheckDep(pkg.CurrentVer().VerStr(), D->CompareOp, D.TargetVer())
-                            && ((*m_cache)->GetPolicy().GetPriority(D.ParentPkg()) >= (*m_cache)->GetPolicy().GetPriority(pkg)))
+                            && (*m_cache)->VS().CheckDep(pkg.CurrentVer().VerStr(), D)
+                            && ((*m_cache)->GetPkgPriority(D.ParentPkg()) >= (*m_cache)->GetPkgPriority(pkg)))
                     {
                         is_obsoleted = true;
                         break;
@@ -1717,323 +1382,6 @@ pkgCache::VerIterator AptIntf::findTransactionPackage(const std::string &name)
     return candidateVer;
 }
 
-void AptIntf::updateInterface(int fd, int writeFd, bool *errorEmitted)
-{
-    char buf[2];
-    static char line[1024] = "";
-
-    while (1) {
-        // This algorithm should be improved (it's the same as the rpm one ;)
-        int len = read(fd, buf, 1);
-
-        // nothing was read
-        if(len < 1)
-            break;
-
-        // update the time we last saw some action
-        m_lastTermAction = time(NULL);
-
-        if (buf[0] == '\n') {
-            if (m_cancel)
-                kill(m_child_pid, SIGTERM);
-
-            //cout << "got line: " << line << endl;
-
-            g_auto(GStrv) split   = g_strsplit(line, ":",5);
-            const gchar *status   = g_strstrip(split[0]);
-            const gchar *pkg      = g_strstrip(split[1]);
-            const gchar *percent  = g_strstrip(split[2]);
-            const std::string str = g_strstrip(split[3]);
-
-            // major problem here, we got unexpected input. should _never_ happen
-            if(pkg == nullptr && status == nullptr)
-                continue;
-
-            // Since PackageKit doesn't emulate finished anymore
-            // we need to manually do it here, as at this point
-            // dpkg doesn't process two packages at the same time
-            if (!m_lastPackage.empty() && m_lastPackage.compare(pkg) != 0) {
-                const pkgCache::VerIterator &ver = findTransactionPackage(m_lastPackage);
-                if (!ver.end()) {
-                    emitPackage(ver, PK_INFO_ENUM_FINISHED);
-                }
-                m_lastSubProgress = 0;
-            }
-
-            // first check for errors and conf-file prompts
-            if (strstr(status, "pmerror") != NULL) {
-                // error from dpkg
-                pk_backend_job_error_code(m_job,
-                                          PK_ERROR_ENUM_PACKAGE_FAILED_TO_INSTALL,
-                                          "Error while installing package: %s",
-                                          str.c_str());
-                if (errorEmitted != nullptr)
-                    *errorEmitted = true;
-            } else if (strstr(status, "pmconffile") != NULL) {
-                // conffile-request from dpkg, needs to be parsed different
-                int i = 0;
-                string orig_file, new_file;
-
-                // go to first ' and read until the end
-                for(;str[i] != '\'' || str[i] == 0; i++)
-                    /*nothing*/
-                    ;
-                i++;
-                for(;str[i] != '\'' || str[i] == 0; i++)
-                    orig_file.append(1, str[i]);
-                i++;
-
-                // same for second ' and read until the end
-                for(;str[i] != '\'' || str[i] == 0; i++)
-                    /*nothing*/
-                    ;
-                i++;
-                for(;str[i] != '\'' || str[i] == 0; i++)
-                    new_file.append(1, str[i]);
-                i++;
-
-                gchar *filename;
-                filename = g_build_filename(DATADIR, "PackageKit", "helpers", "aptcc", "pkconffile", NULL);
-                gchar **argv;
-                gchar **envp;
-                GError *error = NULL;
-                argv = (gchar **) g_malloc(5 * sizeof(gchar *));
-                argv[0] = filename;
-                argv[1] = g_strdup(m_lastPackage.c_str());
-                argv[2] = g_strdup(orig_file.c_str());
-                argv[3] = g_strdup(new_file.c_str());
-                argv[4] = NULL;
-
-                const gchar *socket = pk_backend_job_get_frontend_socket(m_job);
-                if ((m_interactive) && (socket != NULL)) {
-                    envp = (gchar **) g_malloc(3 * sizeof(gchar *));
-                    envp[0] = g_strdup("DEBIAN_FRONTEND=passthrough");
-                    envp[1] = g_strdup_printf("DEBCONF_PIPE=%s", socket);
-                    envp[2] = NULL;
-                } else {
-                    // we don't have a socket set or are non-interactive. Use the noninteractive frontend.
-                    envp = (gchar **) g_malloc(2 * sizeof(gchar *));
-                    envp[0] = g_strdup("DEBIAN_FRONTEND=noninteractive");
-                    envp[1] = NULL;
-                }
-
-                gboolean ret;
-                gint exitStatus;
-                ret = g_spawn_sync(NULL, // working dir
-                                   argv, // argv
-                                   envp, // envp
-                                   G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
-                                   NULL, // child_setup
-                                   NULL, // user_data
-                                   NULL, // standard_output
-                                   NULL, // standard_error
-                                   &exitStatus,
-                                   &error);
-
-                int exit_code = WEXITSTATUS(exitStatus);
-                cout << filename << " " << exit_code << " ret: "<< ret << endl;
-
-                g_strfreev(argv);
-                g_strfreev(envp);
-
-                if (exit_code == 10) {
-                    // 1 means the user wants the package config
-                    if (write(writeFd, "Y\n", 2) != 2) {
-                        // TODO we need a DPKG patch to use debconf
-                        g_debug("Failed to write");
-                    }
-                } else if (exit_code == 20) {
-                    // 2 means the user wants to keep the current config
-                    if (write(writeFd, "N\n", 2) != 2) {
-                        // TODO we need a DPKG patch to use debconf
-                        g_debug("Failed to write");
-                    }
-                } else {
-                    // either the user didn't choose an option or the front end failed'
-                    //                     pk_backend_job_message(m_job,
-                    //                                            PK_MESSAGE_ENUM_CONFIG_FILES_CHANGED,
-                    //                                            "The configuration file '%s' "
-                    //                                            "(modified by you or a script) "
-                    //                                            "has a newer version '%s'.\n"
-                    //                                            "Please verify your changes and update it manually.",
-                    //                                            orig_file.c_str(),
-                    //                                            new_file.c_str());
-                    // fall back to keep the current config file
-                    if (write(writeFd, "N\n", 2) != 2) {
-                        // TODO we need a DPKG patch to use debconf
-                        g_debug("Failed to write");
-                    }
-                }
-            } else if (strstr(status, "pmstatus") != NULL) {
-                // INSTALL & UPDATE
-                // - Running dpkg
-                // loops ALL
-                // -  0 Installing pkg (sometimes this is skiped)
-                // - 25 Preparing pkg
-                // - 50 Unpacking pkg
-                // - 75 Preparing to configure pkg
-                //   ** Some pkgs have
-                //   - Running post-installation
-                //   - Running dpkg
-                // reloops all
-                // -   0 Configuring pkg
-                // - +25 Configuring pkg (SOMETIMES)
-                // - 100 Installed pkg
-                // after all
-                // - Running post-installation
-
-                // REMOVE
-                // - Running dpkg
-                // loops
-                // - 25  Removing pkg
-                // - 50  Preparing for removal of pkg
-                // - 75  Removing pkg
-                // - 100 Removed pkg
-                // after all
-                // - Running post-installation
-
-                // Let's start parsing the status:
-                if (starts_with(str, "Preparing to configure")) {
-                    // Preparing to Install/configure
-                    // cout << "Found Preparing to configure! " << line << endl;
-                    // The next item might be Configuring so better it be 100
-                    m_lastSubProgress = 100;
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_PREPARING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_SETUP, 75);
-                    }
-                } else if (starts_with(str, "Preparing for removal")) {
-                    // Preparing to Install/configure
-                    // cout << "Found Preparing for removal! " << line << endl;
-                    m_lastSubProgress = 50;
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_REMOVING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_SETUP, m_lastSubProgress);
-                    }
-                } else if (starts_with(str, "Preparing")) {
-                    // Preparing to Install/configure
-                    // cout << "Found Preparing! " << line << endl;
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_PREPARING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_SETUP, 25);
-                    }
-                } else if (starts_with(str, "Unpacking")) {
-                    // cout << "Found Unpacking! " << line << endl;
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_DECOMPRESSING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_INSTALL, 50);
-                    }
-                } else if (starts_with(str, "Configuring")) {
-                    // Installing Package
-                    // cout << "Found Configuring! " << line << endl;
-                    if (m_lastSubProgress >= 100 && !m_lastPackage.empty()) {
-                        // cout << "FINISH the last package: " << m_lastPackage << endl;
-                        const pkgCache::VerIterator &ver = findTransactionPackage(m_lastPackage);
-                        if (!ver.end()) {
-                            emitPackage(ver, PK_INFO_ENUM_FINISHED);
-                        }
-                        m_lastSubProgress = 0;
-                    }
-
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_INSTALLING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_INSTALL, m_lastSubProgress);
-                    }
-                    m_lastSubProgress += 25;
-                } else if (starts_with(str, "Running dpkg")) {
-                    // cout << "Found Running dpkg! " << line << endl;
-                } else if (starts_with(str, "Running")) {
-                    // cout << "Found Running! " << line << endl;
-                    pk_backend_job_set_status (m_job, PK_STATUS_ENUM_COMMIT);
-                } else if (starts_with(str, "Installing")) {
-                    // cout << "Found Installing! " << line << endl;
-                    // FINISH the last package
-                    if (!m_lastPackage.empty()) {
-                        // cout << "FINISH the last package: " << m_lastPackage << endl;
-                        const pkgCache::VerIterator &ver = findTransactionPackage(m_lastPackage);
-                        if (!ver.end()) {
-                            emitPackage(ver, PK_INFO_ENUM_FINISHED);
-                        }
-                    }
-                    m_lastSubProgress = 0;
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_INSTALLING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_INSTALL, m_lastSubProgress);
-                    }
-                } else if (starts_with(str, "Removing")) {
-                    // cout << "Found Removing! " << line << endl;
-                    if (m_lastSubProgress >= 100 && !m_lastPackage.empty()) {
-                        // cout << "FINISH the last package: " << m_lastPackage << endl;
-                        const pkgCache::VerIterator &ver = findTransactionPackage(m_lastPackage);
-                        if (!ver.end()) {
-                            emitPackage(ver, PK_INFO_ENUM_FINISHED);
-                        }
-                    }
-                    m_lastSubProgress += 25;
-
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_REMOVING);
-                        emitPackageProgress(ver, PK_STATUS_ENUM_REMOVE, m_lastSubProgress);
-                    }
-                } else if (starts_with(str, "Installed") ||
-                           starts_with(str, "Removed")) {
-                    // cout << "Found FINISHED! " << line << endl;
-                    m_lastSubProgress = 100;
-                    const pkgCache::VerIterator &ver = findTransactionPackage(pkg);
-                    if (!ver.end()) {
-                        emitPackage(ver, PK_INFO_ENUM_FINISHED);
-                        //                         emitPackageProgress(ver, m_lastSubProgress);
-                    }
-                } else {
-                    std::cout << "aptcc: >>>Unmaped dpkg status value: " << line << std::endl;
-                }
-
-                if (!starts_with(str, "Running")) {
-                    m_lastPackage = pkg;
-                }
-                m_startCounting = true;
-            } else {
-                m_startCounting = true;
-            }
-
-            int val = atoi(percent);
-            //cout << "progress: " << val << endl;
-            pk_backend_job_set_percentage(m_job, val);
-
-            // clean-up
-            line[0] = 0;
-        } else {
-            buf[1] = 0;
-            strcat(line, buf);
-        }
-    }
-
-    time_t now = time(NULL);
-
-    if (!m_startCounting) {
-        usleep(100000);
-        // wait until we get the first message from apt
-        m_lastTermAction = now;
-    }
-
-    if ((now - m_lastTermAction) > m_terminalTimeout) {
-        // get some debug info
-        g_warning("no statusfd changes/content updates in terminal for %i"
-                  " seconds",m_terminalTimeout);
-        m_lastTermAction = time(NULL);
-    }
-
-    // sleep for a while to not obsess over it
-    usleep(5000);
-}
-
 PkgList AptIntf::resolvePackageIds(gchar **package_ids, PkBitfield filters)
 {
     PkgList ret;
@@ -2053,53 +1401,22 @@ PkgList AptIntf::resolvePackageIds(gchar **package_ids, PkBitfield filters)
         // Check if it's a valid package id
         if (pk_package_id_check(pkgid) == false) {
             string name(pkgid);
-            // Check if the package name didn't contains the arch field
-            if (name.find(':') == std::string::npos) {
-                // OK FindPkg is not suitable on muitarch without ":arch"
-                // it can only return one package in this case we need to
-                // search the whole package cache and match the package
-                // name manually
-                pkgCache::PkgIterator pkg;
-                // Name can be supplied user input and may not be an actually valid id. In this
-                // case FindGrp can come back with a bad group we shouldn't process any further
-                // as results are undefined.
-                pkgCache::GrpIterator grp = (*m_cache)->FindGrp(name);
-                for (pkg = grp.PackageList(); grp.IsGood() && pkg.end() == false; pkg = grp.NextPkg(pkg)) {
-                    if (m_cancel) {
-                        break;
-                    }
-
-                    // Ignore packages that exist only due to dependencies.
-                    if (pkg.VersionList().end() && pkg.ProvidesList().end()) {
-                        continue;
-                    }
+            const pkgCache::PkgIterator &pkg = (*m_cache)->FindPkg(name);
+            // Ignore packages that could not be found or that exist only due to dependencies.
+            if (pkg.end() == true || (pkg.VersionList().end() && pkg.ProvidesList().end())) {
+                continue;
+            }
 
-                    const pkgCache::VerIterator &ver = m_cache->findVer(pkg);
-                    // check to see if the provided package isn't virtual too
-                    if (!ver.end())
-                        ret.append(ver);
+            const pkgCache::VerIterator &ver = m_cache->findVer(pkg);
+            // check to see if the provided package isn't virtual too
+            if (ver.end() == false)
+                ret.append(ver);
 
-                    const pkgCache::VerIterator &candidateVer = m_cache->findCandidateVer(pkg);
-                    // check to see if the provided package isn't virtual too
-                    if (!candidateVer.end())
-                        ret.append(candidateVer);
-                }
-            } else {
-                const pkgCache::PkgIterator &pkg = (*m_cache)->FindPkg(name);
-                // Ignore packages that could not be found or that exist only due to dependencies.
-                if (pkg.end() == true || (pkg.VersionList().end() && pkg.ProvidesList().end())) {
-                    continue;
-                }
+            const pkgCache::VerIterator &candidateVer = m_cache->findCandidateVer(pkg);
+            // check to see if the provided package isn't virtual too
 
-                const pkgCache::VerIterator &ver = m_cache->findVer(pkg);
-                // check to see if the provided package isn't virtual too
-                if (ver.end() == false)
-                    ret.append(ver);
-
-                const pkgCache::VerIterator &candidateVer = m_cache->findCandidateVer(pkg);
-                // check to see if the provided package isn't virtual too
-                if (candidateVer.end() == false)
-                    ret.append(candidateVer);
+            if (candidateVer.end() == false) {
+                ret.append(candidateVer);
             }
         } else {
             const PkgInfo &pkgi = m_cache->resolvePkgID(pkgid);
@@ -2116,6 +1433,17 @@ void AptIntf::refreshCache()
 {
     pk_backend_job_set_status(m_job, PK_STATUS_ENUM_REFRESH_CACHE);
 
+    // Rebuild the cache.
+
+    // First, destroy m_cache which holds the old copy of the pkgCache and
+    // dependent objects. Note that BuildCaches() alone won't overwrite the held
+    // pkgCache if it's already computed (per Debian's current APT API).
+    m_cache.reset();
+
+    pkgCacheFile::RemoveCaches();
+
+    m_cache.reset(new AptCacheFile(m_job, true /* withLock */, &m_progress));
+
     if (m_cache->BuildSourceList() == false) {
         return;
     }
@@ -2124,10 +1452,13 @@ void AptIntf::refreshCache()
     AcqPackageKitStatus Stat(this, m_job);
 
     // do the work
-    ListUpdate(Stat, *m_cache->GetSourceList());
+    ListUpdate(Stat, *m_cache->GetSourceList(), *m_cache);
 
-    // Rebuild the cache.
-    pkgCacheFile::RemoveCaches();
+    // Setting WithLock implies not AllowMem in APT. (Building in memory only
+    // would be a waste of time for refreshCache(): nothing saved to disk.)
+    // So does apt-get update, too.
+
+    // Ultimately, force the cache to be computed.
     if (m_cache->BuildCaches() == false) {
         return;
     }
@@ -2140,33 +1471,8 @@ void AptIntf::markAutoInstalled(const PkgList &pkgs)
             break;
 
         // Mark package as auto-installed
-        (*m_cache)->MarkAuto(pkInfo.ver.ParentPkg(), true);
-    }
-}
-
-bool AptIntf::markFileForInstall(std::string const &file)
-{
-    return m_cache->GetSourceList()->AddVolatileFile(file);
-}
-
-PkgList AptIntf::resolveLocalFiles(gchar **localDebs)
-{
-    PkgList ret;
-    for (guint i = 0; i < g_strv_length(localDebs); ++i) {
-        pkgCache::PkgIterator const P = (*m_cache)->FindPkg(localDebs[i]);
-        if (P.end()) {
-            continue;
-        }
-
-        // Set any version providing the .deb as the candidate.
-        for (auto Prv = P.ProvidesList(); Prv.end() == false; Prv++)
-            ret.append(Prv.OwnerVer());
-
-        // TODO do we need this?
-        // via cacheset to have our usual virtual handling
-        //APT::VersionContainerInterface::FromPackage(&(verset[MOD_INSTALL]), Cache, P, APT::CacheSetHelper::CANDIDATE, helper);
+        (*m_cache)->MarkAuto(pkInfo.ver.ParentPkg(), pkgDepCache::AutoMarkFlag::Auto);
     }
-    return ret;
 }
 
 bool AptIntf::runTransaction(const PkgList &install, const PkgList &remove, const PkgList &update,
@@ -2192,19 +1498,17 @@ bool AptIntf::runTransaction(const PkgList &install, const PkgList &remove, cons
     };
 
     // Calculate existing garbage before the transaction
-    PkgList initial_garbage;
+    std::set<std::string> initial_garbage;
     if (autoremove) {
-        for (pkgCache::PkgIterator pkg = (*m_cache)->PkgBegin(); ! pkg.end(); ++pkg) {
-            const pkgCache::VerIterator &ver = pkg.CurrentVer();
-            if (!ver.end() && m_cache->isGarbage(pkg))
-                initial_garbage.append(ver);
+        if (!pkgAutoremoveGetKeptAndUnneededPackages(*m_cache, nullptr, &initial_garbage)) {
+            return false;
         }
     }
 
     // new scope for the ActionGroup
     {
-        pkgDepCache::ActionGroup group(*m_cache);
-
+        m_progress.OverallProgress(0, install.size() + remove.size() + update.size(), 1, "updating");
+        unsigned long long processed_packages = 0;
         for (auto op : { Operation { install, false }, Operation { update, true } }) {
             // We first need to mark all manual selections with AutoInst=false, so they influence which packages
             // are chosen when resolving dependencies.
@@ -2225,6 +1529,7 @@ bool AptIntf::runTransaction(const PkgList &install, const PkgList &remove, cons
                                                attemptFixBroken)) {
                         return false;
                     }
+                    m_progress.Progress(++processed_packages);
                 }
             }
         }
@@ -2234,6 +1539,7 @@ bool AptIntf::runTransaction(const PkgList &install, const PkgList &remove, cons
                 break;
 
             m_cache->tryToRemove(Fix, pkInfo);
+            m_progress.Progress(++processed_packages);
         }
 
         // Call the scored problem resolver
@@ -2253,10 +1559,16 @@ bool AptIntf::runTransaction(const PkgList &install, const PkgList &remove, cons
 
     // Remove new garbage that is created
     if (autoremove) {
+        std::set<std::string> new_garbage;
+        if (!pkgAutoremoveGetKeptAndUnneededPackages(*m_cache, nullptr, &new_garbage)) {
+            return false;
+        }
+
         for (pkgCache::PkgIterator pkg = (*m_cache)->PkgBegin(); ! pkg.end(); ++pkg) {
             const pkgCache::VerIterator &ver = pkg.CurrentVer();
-            if (!ver.end() && !initial_garbage.contains(pkg) && m_cache->isGarbage(pkg))
-                m_cache->tryToRemove (Fix, PkgInfo(ver));
+            if (!ver.end() && (initial_garbage.find(pkg.Name()) == initial_garbage.end()) && (new_garbage.find(pkg.Name()) != new_garbage.end())) {
+                m_cache->tryToRemove(Fix, PkgInfo(ver));
+            }
         }
     }
 
@@ -2291,6 +1603,22 @@ bool AptIntf::runTransaction(const PkgList &install, const PkgList &remove, cons
     return ret;
 }
 
+void AptIntf::showProgress(const char *nevra,
+                           const aptCallbackType what,
+                           const uint64_t amount,
+                           const uint64_t total,
+                           void *data)
+{
+    OpProgress *progress = (OpProgress *) data;
+    switch (what) {
+    case APTCALLBACK_ELEM_PROGRESS:
+        progress->OverallProgress(amount, total, 1, "Installing updates");
+        break;
+    default:
+        break;
+    }
+}
+
 /**
  * InstallPackages - Download and install the packages
  *
@@ -2309,6 +1637,12 @@ bool AptIntf::installPackages(PkBitfield flags)
         return false;
     }
 
+#ifdef WITH_LUA
+    _lua->SetDepCache(*m_cache);
+    _lua->RunScripts("Scripts::PackageKit::RunTransaction::Pre");
+    _lua->ResetCaches();
+#endif
+
     // Sanity check
     if ((*m_cache)->BrokenCount() != 0) {
         // TODO
@@ -2327,21 +1661,28 @@ bool AptIntf::installPackages(PkBitfield flags)
 
     // get a fetcher
     pkgAcquire fetcher(&Stat);
+    FileFd Lock;
     if (!simulate) {
         // Only lock the archive directory if we will download
-        if (fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false) {
-            return false;
+        // Lock the archive directory
+        if (_config->FindB("Debug::NoLocking",false) == false)
+        {
+            Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
+            if (_error->PendingError() == true)
+            {
+                return _error->Error("Unable to lock the download directory");
+            }
         }
     }
 
-    // Read the source list
-    if (m_cache->BuildSourceList() == false) {
+    pkgSourceList List;
+    if (List.ReadMainList() == false) {
         return false;
     }
 
     // Create the package manager and prepare to download
     std::unique_ptr<pkgPackageManager> PM (_system->CreatePM(*m_cache));
-    if (!PM->GetArchives(&fetcher, m_cache->GetSourceList(), m_cache->GetPkgRecords()) ||
+    if (!PM->GetArchives(&fetcher, &List, m_cache->GetPkgRecords()) ||
             _error->PendingError() == true) {
         return false;
     }
@@ -2395,11 +1736,6 @@ bool AptIntf::installPackages(PkBitfield flags)
         return false;
     }
 
-    // Make sure we are not installing any untrusted package is untrusted is not set
-    if (!checkTrusted(fetcher, flags) && !simulate) {
-        return false;
-    }
-
     if (simulate) {
         // Print out a list of packages that are going to be installed extra
         checkChangedPackages(true);
@@ -2440,164 +1776,9 @@ bool AptIntf::installPackages(PkBitfield flags)
     // Download should be finished by now, changing it's status
     pk_backend_job_set_percentage(m_job, PK_BACKEND_PERCENTAGE_INVALID);
 
-    // we could try to see if this is the case
-    g_setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", TRUE);
-    _system->UnLockInner();
+    _system->UnLock();
 
-    pkgPackageManager::OrderResult res;
-    res = PM->DoInstallPreFork();
-    if (res == pkgPackageManager::Failed) {
-        g_warning ("Failed to prepare installation");
-        show_errors(m_job, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
-        return false;
-    }
-
-    // File descriptors for reading dpkg --status-fd
-    int readFromChildFD[2];
-    if (pipe(readFromChildFD) < 0) {
-        cout << "Failed to create a pipe" << endl;
-        return false;
-    }
-
-    int pty_master;
-    m_child_pid = forkpty(&pty_master, NULL, NULL, NULL);
-    if (m_child_pid == -1) {
-        return false;
-    }
-
-    if (m_child_pid == 0) {
-        //cout << "FORKED: installPackages(): DoInstall" << endl;
-
-        // ensure that this process dies with its parent
-        prctl(PR_SET_PDEATHSIG, SIGKILL);
-
-        // close pipe we don't need
-        close(readFromChildFD[0]);
-
-        // Change the locale to not get libapt localization
-        setlocale(LC_ALL, "C.UTF-8");
-        g_setenv("LANG", "C.UTF-8", TRUE);
-        g_setenv("LANGUAGE", "C.UTF-8", TRUE);
-
-        // Debconf handling
-        const gchar *socket = pk_backend_job_get_frontend_socket(m_job);
-        if ((m_interactive) && (socket != NULL)) {
-            g_setenv("DEBIAN_FRONTEND", "passthrough", TRUE);
-            g_setenv("DEBCONF_PIPE", socket, TRUE);
-
-            // Set the LANGUAGE so debconf messages get localization
-            // NOTE: This will cause dpkg messages to be localized and APTcc's string matching
-            // to fail, so progress information may no longer be accurate in these cases.
-            setEnvLocaleFromJob();
-        } else {
-            // we don't have a socket set or are not interactive, let's fallback to noninteractive
-            g_setenv("DEBIAN_FRONTEND", "noninteractive", TRUE);
-        }
-
-        // apt will record this in its history.log
-        guint uid = pk_backend_job_get_uid(m_job);
-        if (uid > 0) {
-            gchar buf[16];
-            snprintf(buf, sizeof(buf), "%d", uid);
-            g_setenv("PACKAGEKIT_CALLER_UID", buf, TRUE);
-        }
-
-        PkRoleEnum role = pk_backend_job_get_role(m_job);
-        gchar *cmd = g_strdup_printf("packagekit role='%s'", pk_role_enum_to_string(role));
-        _config->Set("CommandLine::AsString", cmd);
-        g_free(cmd);
-
-        // Pass the write end of the pipe to the install function
-        auto *progress = new Progress::PackageManagerProgressFd(readFromChildFD[1]);
-        res = PM->DoInstallPostFork(progress);
-        delete progress;
-
-        // dump errors into cerr (pass it to the parent process)
-        _error->DumpErrors();
-
-        // finishes the child process, _exit is used to not
-        // close some parent file descriptors
-        _exit(res);
-    }
-
-    cout << "APTcc parent process running..." << endl;
-
-    // make it nonblocking, very important otherwise
-    // when the child finish we stay stuck.
-    fcntl(readFromChildFD[0], F_SETFL, O_NONBLOCK);
-    fcntl(pty_master, F_SETFL, O_NONBLOCK);
-
-    // init the timer
-    m_lastTermAction = time(NULL);
-    m_startCounting = false;
-
-    // process messages from child
-    int ret = 0;
-    char masterbuf[1024];
-    std::string errorLogTail = "";
-    bool errorEmitted = false;
-    bool childTerminated = false;
-    while (true) {
-        while (true) {
-            int bufLen = read(pty_master, masterbuf, sizeof(masterbuf));
-            if (bufLen <= 0)
-                break;
-            masterbuf[bufLen] = '\0';
-            errorLogTail.append(masterbuf);
-            if (errorLogTail.length() > 2048)
-                errorLogTail.erase(0, errorLogTail.length() - 2048);
-        }
-
-        // don't continue if the child terminated previously
-        if (childTerminated)
-            break;
-
-        // try to parse dpkg status
-        updateInterface(readFromChildFD[0], pty_master, &errorEmitted);
-
-        // Check if the child died
-        if (waitpid(m_child_pid, &ret, WNOHANG) != 0)
-            childTerminated = true; // one last round to read remaining output
-    }
-
-    close(readFromChildFD[0]);
-    close(readFromChildFD[1]);
-    close(pty_master);
-    _system->LockInner();
-
-    cout << "APTcc parent process finished: " << ret << endl;
-
-    if (ret != 0 && !m_cancel && !errorEmitted) {
-        // If the child died with a non-zero exit code, and we didn't deliberately
-        // kill it in a cancel operation and we didn't already emit an error,
-        // we still need to find out what went wrong to present a message to the user.
-        // Let's see if we can find any kind of not overlay verbose information to display.
-
-        std::stringstream ss(errorLogTail);
-        std::string line;
-        std::string shortErrorLog = "";
-        while(std::getline(ss, line, '\n')) {
-            if (g_str_has_prefix (line.c_str(), "E:"))
-                shortErrorLog.append("\n" + line);
-        }
-
-        if (shortErrorLog.empty()) {
-            if (errorLogTail.length() > 1200)
-                errorLogTail.erase(0, errorLogTail.length() - 1200);
-            std::string logExcerpt = errorLogTail.substr(errorLogTail.find("\n") + 1, errorLogTail.length());
-            logExcerpt = logExcerpt.empty()? "No log generated. Check `/var/log/apt/term.log`!" : "\n" + logExcerpt;
-            pk_backend_job_error_code(m_job,
-                                      PK_ERROR_ENUM_TRANSACTION_ERROR,
-                                      "Error while running dpkg. Log excerpt: %s",
-                                       logExcerpt.c_str());
-        } else {
-            pk_backend_job_error_code(m_job,
-                                      PK_ERROR_ENUM_TRANSACTION_ERROR,
-                                      "Error while running the transaction: %s",
-                                      shortErrorLog.c_str());
-        }
-        return false;
-    }
+    PM->DoInstall(showProgress, &m_progress);
 
     return true;
 }
diff --git a/backends/aptcc/apt-intf.h b/backends/aptcc/apt-intf.h
index 0a76bb153..6847cf435 100644
--- a/backends/aptcc/apt-intf.h
+++ b/backends/aptcc/apt-intf.h
@@ -29,22 +29,26 @@
 
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/acquire.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/packagemanager.h>
 
 #include <pk-backend.h>
 
 #include "pkg-list.h"
 #include "apt-sourceslist.h"
+#include "apt-cache-file.h"
+
+#include <memory>
 
 #define REBOOT_REQUIRED      "/var/run/reboot-required"
 
 class pkgProblemResolver;
 class Matcher;
-class AptCacheFile;
 class AptIntf
 {
 public:
     AptIntf(PkBackendJob *job);
-    ~AptIntf();
+    ~AptIntf() = default;
 
     bool init(gchar **localDebs = nullptr);
     void cancel();
@@ -62,21 +66,11 @@ public:
      */
     PkgList resolvePackageIds(gchar **package_ids, PkBitfield filters = PK_FILTER_ENUM_NONE);
 
-    PkgList resolveLocalFiles(gchar **localDebs);
-
     /**
       * Refreshes the sources of packages
       */
     void refreshCache();
 
-    /**
-      * Tries to resolve a pkg file installation of the given \sa file
-      * @param install is where the packages to be installed will be stored
-      * @param remove is where the packages to be removed will be stored
-      * @returns true if the package can be installed
-      */
-    bool markFileForInstall(std::string const &file);
-
     /**
       * Marks the given packages as auto installed
       */
@@ -137,11 +131,6 @@ public:
       */
     PkgList searchPackageDetails(const vector<string> &queries);
 
-    /**
-      * Returns a list of all packages that matched contains the given files
-      */
-    PkgList searchPackageFiles(gchar **values);
-
     /**
       * Returns a list of all packages that can be updated
       * Pass a PkgList to get the blocked updates as well
@@ -204,15 +193,11 @@ public:
       */
     void emitUpdateDetails(const PkgList &pkgs);
 
-    /**
-      *  Emits the files of a package
-      */
-    void emitPackageFiles(const gchar *pi);
-
-    /**
-      *  Emits the files of a package
-      */
-    void emitPackageFilesLocal(const gchar *file);
+    static void showProgress(const char *nevra,
+                       const aptCallbackType what,
+                       const uint64_t amount,
+                       const uint64_t total,
+                       void *data);
 
     /**
       *  Download and install packages
@@ -244,24 +229,16 @@ public:
 
 private:
     void setEnvLocaleFromJob();
-    bool checkTrusted(pkgAcquire &fetcher, PkBitfield flags);
-    bool packageIsSupported(const pkgCache::VerIterator &verIter, string component);
-    bool isApplication(const pkgCache::VerIterator &verIter);
     bool matchesQueries(const vector<string> &queries, string s);
 
-    /**
-     *  interprets dpkg status fd
-     */
-    void updateInterface(int readFd, int writeFd, bool *errorEmitted = nullptr);
     PkgList checkChangedPackages(bool emitChanged);
     pkgCache::VerIterator findTransactionPackage(const std::string &name);
 
-    AptCacheFile *m_cache;
+    std::unique_ptr<AptCacheFile> m_cache;
     PkBackendJob  *m_job;
     bool       m_cancel;
     struct stat m_restartStat;
 
-    bool m_isMultiArch;
     PkgList m_pkgs;
     PkgList m_restartPackages;
 
@@ -274,6 +251,9 @@ private:
     // when the internal terminal timesout after no activity
     int m_terminalTimeout;
     pid_t m_child_pid;
+
+    FileFd m_fileFd;
+    OpPackageKitProgress m_progress;
 };
 
 #endif
diff --git a/backends/aptcc/apt-utils.cpp b/backends/aptcc/apt-utils.cpp
index bef3eb105..a34addc92 100644
--- a/backends/aptcc/apt-utils.cpp
+++ b/backends/aptcc/apt-utils.cpp
@@ -30,130 +30,139 @@
 
 #include <fstream>
 #include <regex>
+#include <map>
+
+static const std::map<std::string, PkGroupEnum> groups_map = {
+	{ "Accessibility", PK_GROUP_ENUM_ACCESSIBILITY },
+	{ "Archiving/Backup", PK_GROUP_ENUM_ADMIN_TOOLS },
+	{ "Archiving/Cd burning", PK_GROUP_ENUM_ACCESSORIES },
+	{ "Archiving/Compression", PK_GROUP_ENUM_ACCESSORIES },
+	{ "Archiving/Other", PK_GROUP_ENUM_ACCESSORIES },
+	{ "Books/Computer books", PK_GROUP_ENUM_DOCUMENTATION },
+	{ "Books/Faqs", PK_GROUP_ENUM_DOCUMENTATION },
+	{ "Books/Howtos", PK_GROUP_ENUM_DOCUMENTATION },
+	{ "Books/Literature", PK_GROUP_ENUM_EDUCATION },
+	{ "Books/Other", PK_GROUP_ENUM_EDUCATION },
+	{ "Communications", PK_GROUP_ENUM_COMMUNICATION },
+	{ "Databases", PK_GROUP_ENUM_OTHER },
+	{ "Development/C", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/C++", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Databases", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Debug", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Debuggers", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Documentation", PK_GROUP_ENUM_DOCUMENTATION },
+	{ "Development/Erlang", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Functional", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/GNOME and GTK+", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Haskell", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Java", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/KDE and QT", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Kernel", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Lisp", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/ML", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Objective-C", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Other", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Perl", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Python", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Python3", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Ruby", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Scheme", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Tcl", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Development/Tools", PK_GROUP_ENUM_PROGRAMMING },
+	{ "Documentation", PK_GROUP_ENUM_DOCUMENTATION },
+	{ "Editors", PK_GROUP_ENUM_PUBLISHING },
+	{ "Education", PK_GROUP_ENUM_EDUCATION },
+	{ "Emulators", PK_GROUP_ENUM_SYSTEM },
+	{ "Engineering", PK_GROUP_ENUM_ELECTRONICS },
+	{ "File tools", PK_GROUP_ENUM_ACCESSORIES },
+	{ "Games/Adventure", PK_GROUP_ENUM_GAMES },
+	{ "Games/Arcade", PK_GROUP_ENUM_GAMES },
+	{ "Games/Boards", PK_GROUP_ENUM_GAMES },
+	{ "Games/Cards", PK_GROUP_ENUM_GAMES },
+	{ "Games/Educational", PK_GROUP_ENUM_GAMES },
+	{ "Games/Other", PK_GROUP_ENUM_GAMES },
+	{ "Games/Puzzles", PK_GROUP_ENUM_GAMES },
+	{ "Games/Sports", PK_GROUP_ENUM_GAMES },
+	{ "Games/Strategy", PK_GROUP_ENUM_GAMES },
+	{ "Graphical desktop/Enlightenment", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/FVWM based", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/GNOME", PK_GROUP_ENUM_DESKTOP_GNOME },
+	{ "Graphical desktop/GNUstep", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Icewm", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/KDE", PK_GROUP_ENUM_DESKTOP_KDE },
+	{ "Graphical desktop/MATE", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Motif", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Other", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Rox", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Sawfish", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Sugar", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/Window Maker", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Graphical desktop/XFce", PK_GROUP_ENUM_DESKTOP_XFCE },
+	{ "Graphics", PK_GROUP_ENUM_GRAPHICS },
+	{ "Monitoring", PK_GROUP_ENUM_ACCESSORIES },
+	{ "Networking/Chat", PK_GROUP_ENUM_COMMUNICATION },
+	{ "Networking/DNS", PK_GROUP_ENUM_NETWORK },
+	{ "Networking/File transfer", PK_GROUP_ENUM_NETWORK },
+	{ "Networking/FTN", PK_GROUP_ENUM_NETWORK },
+	{ "Networking/IRC", PK_GROUP_ENUM_COMMUNICATION },
+	{ "Networking/Instant messaging", PK_GROUP_ENUM_COMMUNICATION },
+	{ "Networking/Mail", PK_GROUP_ENUM_INTERNET },
+	{ "Networking/News", PK_GROUP_ENUM_INTERNET },
+	{ "Networking/Other", PK_GROUP_ENUM_NETWORK },
+	{ "Networking/Remote access", PK_GROUP_ENUM_NETWORK },
+	{ "Networking/WWW", PK_GROUP_ENUM_INTERNET },
+	{ "Office", PK_GROUP_ENUM_OFFICE },
+	{ "Other", PK_GROUP_ENUM_OTHER },
+	{ "Publishing", PK_GROUP_ENUM_PUBLISHING },
+	{ "Sciences/Astronomy", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Biology", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Chemistry", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Computer science", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Geosciences", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Mathematics", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Medicine", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Other", PK_GROUP_ENUM_SCIENCE },
+	{ "Sciences/Physics", PK_GROUP_ENUM_SCIENCE },
+	{ "Security/Antivirus", PK_GROUP_ENUM_SCIENCE },
+	{ "Security/Networking", PK_GROUP_ENUM_SCIENCE },
+	{ "Shells", PK_GROUP_ENUM_SYSTEM },
+	{ "Sound", PK_GROUP_ENUM_MULTIMEDIA },
+	{ "System/Base", PK_GROUP_ENUM_SYSTEM },
+	{ "System/Configuration/Boot and Init", PK_GROUP_ENUM_SYSTEM },
+	{ "System/Configuration/Hardware", PK_GROUP_ENUM_ADMIN_TOOLS },
+	{ "System/Configuration/Networking", PK_GROUP_ENUM_NETWORK },
+	{ "System/Configuration/Other", PK_GROUP_ENUM_SYSTEM },
+	{ "System/Configuration/Packaging", PK_GROUP_ENUM_ADMIN_TOOLS },
+	{ "System/Configuration/Printing", PK_GROUP_ENUM_SYSTEM },
+	{ "System/Fonts/Console", PK_GROUP_ENUM_FONTS },
+	{ "System/Fonts/True type", PK_GROUP_ENUM_FONTS },
+	{ "System/Fonts/Type1", PK_GROUP_ENUM_FONTS },
+	{ "System/Fonts/X11 bitmap", PK_GROUP_ENUM_FONTS },
+	{ "System/Internationalization", PK_GROUP_ENUM_LOCALIZATION },
+	{ "System/Kernel and hardware", PK_GROUP_ENUM_ADMIN_TOOLS },
+	{ "System/Libraries", PK_GROUP_ENUM_SYSTEM },
+	{ "System/Legacy libraries", PK_GROUP_ENUM_LEGACY },
+	{ "System/Servers", PK_GROUP_ENUM_SERVERS },
+	{ "System/Servers/ZProducts", PK_GROUP_ENUM_UNKNOWN },
+	{ "System/X11", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "System/XFree86", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Terminals", PK_GROUP_ENUM_DESKTOP_OTHER },
+	{ "Text tools", PK_GROUP_ENUM_PUBLISHING },
+	{ "Toys", PK_GROUP_ENUM_GAMES },
+	{ "Video", PK_GROUP_ENUM_MULTIMEDIA },
+};
 
 PkGroupEnum get_enum_group(string group)
 {
-    if (group.compare ("admin") == 0) {
-        return PK_GROUP_ENUM_ADMIN_TOOLS;
-    } else if (group.compare ("base") == 0) {
-        return PK_GROUP_ENUM_SYSTEM;
-    } else if (group.compare ("cli-mono") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("comm") == 0) {
-        return PK_GROUP_ENUM_COMMUNICATION;
-    } else if (group.compare ("database") == 0) {
-        return PK_GROUP_ENUM_ADMIN_TOOLS;
-    } else if (group.compare ("debug") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("devel") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("doc") == 0) {
-        return PK_GROUP_ENUM_DOCUMENTATION;
-    } else if (group.compare ("editors") == 0) {
-        return PK_GROUP_ENUM_PUBLISHING;
-    } else if (group.compare ("education") == 0) {
-        return PK_GROUP_ENUM_EDUCATION;
-    } else if (group.compare ("electronics") == 0) {
-        return PK_GROUP_ENUM_ELECTRONICS;
-    } else if (group.compare ("embedded") == 0) {
-        return PK_GROUP_ENUM_SYSTEM;
-    } else if (group.compare ("fonts") == 0) {
-        return PK_GROUP_ENUM_FONTS;
-    } else if (group.compare ("games") == 0) {
-        return PK_GROUP_ENUM_GAMES;
-    } else if (group.compare ("gnome") == 0) {
-        return PK_GROUP_ENUM_DESKTOP_GNOME;
-    } else if (group.compare ("gnu-r") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("gnustep") == 0) {
-        return PK_GROUP_ENUM_DESKTOP_OTHER;
-    } else if (group.compare ("golang") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("graphics") == 0) {
-        return PK_GROUP_ENUM_GRAPHICS;
-    } else if (group.compare ("hamradio") == 0) {
-        return PK_GROUP_ENUM_COMMUNICATION;
-    } else if (group.compare ("haskell") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("httpd") == 0) {
-        return PK_GROUP_ENUM_SERVERS;
-    } else if (group.compare ("interpreters") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("introspection") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("java") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("javascript") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("kde") == 0) {
-        return PK_GROUP_ENUM_DESKTOP_KDE;
-    } else if (group.compare ("kernel") == 0) {
-        return PK_GROUP_ENUM_SYSTEM;
-    } else if (group.compare ("libdevel") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("libs") == 0) {
-        return PK_GROUP_ENUM_SYSTEM;
-    } else if (group.compare ("lisp") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("mail") == 0) {
-        return PK_GROUP_ENUM_INTERNET;
-    } else if (group.compare ("math") == 0) {
-        return PK_GROUP_ENUM_SCIENCE;
-    } else if (group.compare ("misc") == 0) {
-        return PK_GROUP_ENUM_OTHER;
-    } else if (group.compare ("net") == 0) {
-        return PK_GROUP_ENUM_NETWORK;
-    } else if (group.compare ("news") == 0) {
-        return PK_GROUP_ENUM_INTERNET;
-    } else if (group.compare ("ocaml") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("oldlibs") == 0) {
-        return PK_GROUP_ENUM_LEGACY;
-    } else if (group.compare ("otherosfs") == 0) {
-        return PK_GROUP_ENUM_SYSTEM;
-    } else if (group.compare ("perl") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("php") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("python") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("ruby") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("rust") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("science") == 0) {
-        return PK_GROUP_ENUM_SCIENCE;
-    } else if (group.compare ("shells") == 0) {
-        return PK_GROUP_ENUM_SYSTEM;
-    } else if (group.compare ("sound") == 0) {
-        return PK_GROUP_ENUM_MULTIMEDIA;
-    } else if (group.compare ("tex") == 0) {
-        return PK_GROUP_ENUM_PUBLISHING;
-    } else if (group.compare ("text") == 0) {
-        return PK_GROUP_ENUM_PUBLISHING;
-    } else if (group.compare ("utils") == 0) {
-        return PK_GROUP_ENUM_ACCESSORIES;
-    } else if (group.compare ("vcs") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("video") == 0) {
-        return PK_GROUP_ENUM_MULTIMEDIA;
-    } else if (group.compare ("web") == 0) {
-        return PK_GROUP_ENUM_INTERNET;
-    } else if (group.compare ("x11") == 0) {
-        return PK_GROUP_ENUM_DESKTOP_OTHER;
-    } else if (group.compare ("xfce") == 0) {
-        return PK_GROUP_ENUM_DESKTOP_XFCE;
-    } else if (group.compare ("zope") == 0) {
-        return PK_GROUP_ENUM_PROGRAMMING;
-    } else if (group.compare ("alien") == 0) {
-        return PK_GROUP_ENUM_UNKNOWN;//FIXME alien is an unknown group?
-    } else if (group.compare ("translations") == 0) {
-        return PK_GROUP_ENUM_LOCALIZATION;
-    } else if (group.compare ("metapackages") == 0) {
-        return PK_GROUP_ENUM_COLLECTIONS;
-    } else {
-        return PK_GROUP_ENUM_UNKNOWN;
-    }
+	auto iter = groups_map.find(group);
+	if (iter != groups_map.end())
+	{
+		return iter->second;
+	}
+	else
+	{
+		return PK_GROUP_ENUM_UNKNOWN;
+	}
 }
 
 string fetchChangelogData(AptCacheFile &CacheFile,
@@ -166,6 +175,7 @@ string fetchChangelogData(AptCacheFile &CacheFile,
 {
     string changelog;
 
+#if 0
     pkgAcqChangelog *c = new pkgAcqChangelog(&Fetcher, Ver);
 
     // try downloading it, if that fails, try third-party-changelogs location
@@ -177,8 +187,10 @@ string fetchChangelogData(AptCacheFile &CacheFile,
     pkgCache::PkgIterator Pkg = Ver.ParentPkg();
     pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList());
     string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg();
+#endif
     changelog = "Changelog for this version is not yet available";
 
+#if 0
     // return empty string if we don't have a file to read
     if (!FileExists(c->DestFile)) {
         return changelog;
@@ -268,6 +280,7 @@ string fetchChangelogData(AptCacheFile &CacheFile,
         changelog.append(str);
         changelog.append("\n");
     }
+#endif
 
     changelog.erase(changelog.find_last_not_of(" \t\n") + 1);
     return changelog;
@@ -416,17 +429,35 @@ string utilBuildPackageOriginId(pkgCache::VerFileIterator vf)
     //    seem a problem though. we'll allow them until otherwise indicated
     auto component = string(vf.File().Component());
 
-    // Origin is defined as 'a single line of free form text'.
-    // Sanitize it!
-    // All space characters, control characters and punctuation get replaced
-    // with underscore.
-    // In particular the punctuations ':', ';' and ',' may be used as list separators
-    // so we must not have them appear in our package_ids as that would cause
-    // breakage down the line.
-    std::transform(origin.begin(), origin.end(), origin.begin(), ::tolower);
-    origin = std::regex_replace(origin, std::regex("[[:space:][:cntrl:][:punct:]]+"), "_");
-
-    string res = origin + "-" + suite + "-" + component;
+    std::string res;
+
+    if ((strcasecmp(origin.c_str(), "ALT Linux Team") == 0)
+        && (strncasecmp(suite.c_str(), "ALT Linux ", strlen("ALT Linux ")) == 0)
+        && (suite.length() > strlen("ALT Linux ")))
+    {
+       res = suite + " (" + component + ")";
+    }
+    else
+    {
+       // Origin is defined as 'a single line of free form text'.
+       // Sanitize it!
+       // All space characters, control characters and punctuation get replaced
+       // with underscore.
+       // In particular the punctuations ':', ';' and ',' may be used as list separators
+       // so we must not have them appear in our package_ids as that would cause
+       // breakage down the line.
+       std::transform(origin.begin(), origin.end(), origin.begin(), ::tolower);
+       origin = std::regex_replace(origin, std::regex("[[:space:][:cntrl:][:punct:]]+"), "_");
+
+       std::transform(suite.begin(), suite.end(), suite.begin(), ::tolower);
+       suite = std::regex_replace(suite, std::regex("[[:space:][:cntrl:][:punct:]]+"), "_");
+
+       std::transform(component.begin(), component.end(), component.begin(), ::tolower);
+       component = std::regex_replace(component, std::regex("[[:space:][:cntrl:][:punct:]]+"), "_");
+
+       res = origin + "-" + suite + "-" + component;
+    }
+
     return res;
 }
 
diff --git a/backends/aptcc/meson.build b/backends/aptcc/meson.build
index 5df8f29e2..3187755de 100644
--- a/backends/aptcc/meson.build
+++ b/backends/aptcc/meson.build
@@ -6,7 +6,7 @@ gstreamer_dep = dependency('gstreamer-1.0')
 gstreamer_base_dep = dependency('gstreamer-base-1.0')
 gstreamer_plugins_base_dep = dependency('gstreamer-plugins-base-1.0')
 appstream_dep = dependency('appstream', version: '>=0.12')
-apt_pkg_dep = dependency('apt-pkg', version: '>=1.9.2')
+apt_pkg_dep = cpp_compiler.find_library('apt-pkg')
 
 # Check whether apt supports ddtp
 ddtp_flag = []
@@ -43,8 +43,6 @@ shared_module(
   'apt-intf.h',
   'pkg-list.cpp',
   'pkg-list.h',
-  'deb-file.cpp',
-  'deb-file.h',
   'pk-backend-aptcc.cpp',
   include_directories: packagekit_src_include,
   dependencies: [
@@ -61,6 +59,10 @@ shared_module(
     '-DPK_COMPILATION=1',
     '-DDATADIR="@0@"'.format(join_paths(get_option('prefix'), get_option('datadir'))),
     ddtp_flag,
+    # To avoid some errors on API change:
+    '-Werror=overloaded-virtual',
+    # style enforcement: always use the keyword, which helps to avoid API misuse
+    '-Werror=suggest-override',
   ],
   link_args: [
     '-lutil',
@@ -82,34 +84,3 @@ install_data(
   'pkconffile.nodiff',
   install_dir: join_paths(get_option('datadir'), 'PackageKit', 'helpers', 'aptcc'),
 )
-
-if get_option('systemd')
-  executable(
-    'pk-debconf-helper',
-    'pk-debconf-helper.c',
-    dependencies: [
-      packagekit_glib2_dep,
-      libsystemd
-    ],
-    install: true,
-    install_dir: get_option('libexecdir')
-  )
-
-  sd_config_data = configuration_data()
-  sd_config_data.set('libexecdir', join_paths(get_option('prefix'), get_option('libexecdir')))
-
-  configure_file(
-    input: 'pk-debconf-helper.service.in',
-    output: 'pk-debconf-helper.service',
-    configuration: sd_config_data,
-    install: true,
-    install_dir: systemd_user_unit_dir,
-  )
-  configure_file(
-    input: 'pk-debconf-helper.socket.in',
-    output: 'pk-debconf-helper.socket',
-    configuration: sd_config_data,
-    install: true,
-    install_dir: systemd_user_unit_dir,
-  )
-endif
diff --git a/backends/aptcc/pk-backend-aptcc.cpp b/backends/aptcc/pk-backend-aptcc.cpp
index 6abc03804..866423bbd 100644
--- a/backends/aptcc/pk-backend-aptcc.cpp
+++ b/backends/aptcc/pk-backend-aptcc.cpp
@@ -28,10 +28,10 @@
 #include <pk-backend.h>
 #include <pk-backend-spawn.h>
 
-#include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/init.h>
+#include <apt-pkg/error.h>
 #include <apt-pkg/pkgsystem.h>
 
 #include "apt-intf.h"
@@ -127,24 +127,16 @@ PkBitfield pk_backend_get_filters(PkBackend *backend)
                 PK_FILTER_ENUM_GUI,
                 PK_FILTER_ENUM_INSTALLED,
                 PK_FILTER_ENUM_DEVELOPMENT,
-                PK_FILTER_ENUM_SUPPORTED,
                 PK_FILTER_ENUM_FREE,
-                PK_FILTER_ENUM_APPLICATION,
                 PK_FILTER_ENUM_DOWNLOADED,
                 -1);
 
-    // if we have multiArch support we add the native filter
-    if (APT::Configuration::getArchitectures(false).size() > 1) {
-        pk_bitfield_add(filters, PK_FILTER_ENUM_ARCH);
-    }
-
     return filters;
 }
 
 gchar** pk_backend_get_mime_types(PkBackend *backend)
 {
-    const gchar *mime_types[] = { "application/vnd.debian.binary-package",
-                                  "application/x-deb",
+    const gchar *mime_types[] = { "application/x-rpm",
                                   NULL };
     return g_strdupv ((gchar **) mime_types);
 }
@@ -249,56 +241,6 @@ void pk_backend_required_by(PkBackend *backend,
     pk_backend_job_thread_create(job, backend_depends_on_or_requires_thread, NULL, NULL);
 }
 
-static void backend_get_files_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
-{
-    gchar **package_ids;
-    gchar *pi;
-
-    g_variant_get(params, "(^a&s)",
-                  &package_ids);
-
-    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
-    if (!apt->init()) {
-        g_debug("Failed to create apt cache");
-        return;
-    }
-
-    if (package_ids == NULL) {
-        pk_backend_job_error_code(job,
-                                  PK_ERROR_ENUM_PACKAGE_ID_INVALID,
-                                  "Invalid package id");
-        return;
-    }
-
-    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
-    for (uint i = 0; i < g_strv_length(package_ids); ++i) {
-        pi = package_ids[i];
-        if (pk_package_id_check(pi) == false) {
-            pk_backend_job_error_code(job,
-                                      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
-                                      "%s",
-                                      pi);
-            return;
-        }
-
-        const PkgInfo &pkInfo = apt->aptCacheFile()->resolvePkgID(pi);
-        if (pkInfo.ver.end()) {
-            pk_backend_job_error_code(job,
-                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
-                                      "Couldn't find package %s",
-                                      pi);
-            return;
-        }
-
-        apt->emitPackageFiles(pi);
-    }
-}
-
-void pk_backend_get_files(PkBackend *backend, PkBackendJob *job, gchar **package_ids)
-{
-    pk_backend_job_thread_create(job, backend_get_files_thread, NULL, NULL);
-}
-
 static void backend_get_details_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
 {
     gchar **package_ids = nullptr;
@@ -306,13 +248,8 @@ static void backend_get_details_thread(PkBackendJob *job, GVariant *params, gpoi
     PkRoleEnum role;
     role = pk_backend_job_get_role(job);
 
-    if (role == PK_ROLE_ENUM_GET_DETAILS_LOCAL) {
-        g_variant_get(params, "(^a&s)",
-                      &files);
-    } else {
-        g_variant_get(params, "(^a&s)",
-                      &package_ids);
-    }
+    g_variant_get(params, "(^a&s)",
+                  &package_ids);
 
     AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
     if (!apt->init(files)) {
@@ -322,11 +259,7 @@ static void backend_get_details_thread(PkBackendJob *job, GVariant *params, gpoi
 
     pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
     PkgList pkgs;
-    if (role == PK_ROLE_ENUM_GET_DETAILS_LOCAL) {
-        pkgs = apt->resolveLocalFiles(files);
-    } else {
-        pkgs = apt->resolvePackageIds(package_ids);
-    }
+    pkgs = apt->resolvePackageIds(package_ids);
 
     if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
         apt->emitUpdateDetails(pkgs);
@@ -345,27 +278,6 @@ void pk_backend_get_details(PkBackend *backend, PkBackendJob *job, gchar **packa
     pk_backend_job_thread_create(job, backend_get_details_thread, NULL, NULL);
 }
 
-void pk_backend_get_details_local(PkBackend *backend, PkBackendJob *job, gchar **files)
-{
-    pk_backend_job_thread_create(job, backend_get_details_thread, NULL, NULL);
-}
-
-static void backend_get_files_local_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
-{
-    g_autofree gchar **files = nullptr;
-    g_variant_get(params, "(^a&s)",
-                  &files);
-    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
-
-    for (guint i = 0; files[i] != nullptr; ++i)
-        apt->emitPackageFilesLocal(files[i]);
-}
-
-void pk_backend_get_files_local(PkBackend *backend, PkBackendJob *job, gchar **files)
-{
-    pk_backend_job_thread_create(job, backend_get_files_local_thread, NULL, NULL);
-}
-
 static void backend_get_updates_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
 {
     PkBitfield filters;
@@ -615,39 +527,6 @@ void pk_backend_resolve(PkBackend *backend, PkBackendJob *job, PkBitfield filter
     pk_backend_job_thread_create(job, pk_backend_resolve_thread, NULL, NULL);
 }
 
-static void pk_backend_search_files_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
-{
-    gchar **search;
-    PkBitfield filters;
-    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
-
-    g_variant_get(params, "(t^a&s)",
-                  &filters,
-                  &search);
-
-    pk_backend_job_set_allow_cancel(job, true);
-
-    // as we can only search for installed files lets avoid the opposite
-    if (!pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
-        if (!apt->init()) {
-            g_debug("Failed to create apt cache");
-            return;
-        }
-
-        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
-        PkgList output;
-        output = apt->searchPackageFiles(search);
-
-        // It's faster to emit the packages here rather than in the matching part
-        apt->emitPackages(output, filters);
-    }
-}
-
-void pk_backend_search_files(PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **values)
-{
-    pk_backend_job_thread_create(job, pk_backend_search_files_thread, NULL, NULL);
-}
-
 static void backend_search_groups_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
 {
     gchar **search;
@@ -742,11 +621,7 @@ static void backend_manage_packages_thread(PkBackendJob *job, GVariant *params,
 
     // Get the transaction role since this method is called by install/remove/update/repair
     PkRoleEnum role = pk_backend_job_get_role(job);
-    if (role == PK_ROLE_ENUM_INSTALL_FILES) {
-        g_variant_get(params, "(t^a&s)",
-                      &transaction_flags,
-                      &full_paths);
-    } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
+    if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
         g_variant_get(params, "(t^a&sbb)",
                       &transaction_flags,
                       &package_ids,
@@ -788,8 +663,6 @@ static void backend_manage_packages_thread(PkBackendJob *job, GVariant *params,
             installPkgs = apt->resolvePackageIds(package_ids);
         } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
             updatePkgs = apt->resolvePackageIds(package_ids);
-        } else if (role == PK_ROLE_ENUM_INSTALL_FILES) {
-            installPkgs = apt->resolveLocalFiles(full_paths);
         } else {
             pk_backend_job_error_code(job,
                                       PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
@@ -1051,9 +924,6 @@ PkBitfield pk_backend_get_roles(PkBackend *backend)
                 PK_ROLE_ENUM_CANCEL,
                 PK_ROLE_ENUM_DEPENDS_ON,
                 PK_ROLE_ENUM_GET_DETAILS,
-                PK_ROLE_ENUM_GET_DETAILS_LOCAL,
-                PK_ROLE_ENUM_GET_FILES,
-                PK_ROLE_ENUM_GET_FILES_LOCAL,
                 PK_ROLE_ENUM_REQUIRED_BY,
                 PK_ROLE_ENUM_GET_PACKAGES,
                 PK_ROLE_ENUM_WHAT_PROVIDES,
@@ -1066,7 +936,6 @@ PkBitfield pk_backend_get_roles(PkBackend *backend)
                 PK_ROLE_ENUM_DOWNLOAD_PACKAGES,
                 PK_ROLE_ENUM_RESOLVE,
                 PK_ROLE_ENUM_SEARCH_DETAILS,
-                PK_ROLE_ENUM_SEARCH_FILE,
                 PK_ROLE_ENUM_SEARCH_GROUP,
                 PK_ROLE_ENUM_SEARCH_NAME,
                 PK_ROLE_ENUM_UPDATE_PACKAGES,
@@ -1074,7 +943,6 @@ PkBitfield pk_backend_get_roles(PkBackend *backend)
                 PK_ROLE_ENUM_REPO_ENABLE,
                 PK_ROLE_ENUM_REPAIR_SYSTEM,
                 PK_ROLE_ENUM_REPO_REMOVE,
-                PK_ROLE_ENUM_INSTALL_FILES,
                 -1);
 
     return roles;
diff --git a/backends/aptcc/pk-debconf-helper.c b/backends/aptcc/pk-debconf-helper.c
deleted file mode 100644
index 56f7ca48a..000000000
--- a/backends/aptcc/pk-debconf-helper.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "config.h"
-#include <stdio.h>
-#include <packagekit-glib2/pk-client.h>
-#include <packagekit-glib2/pk-client-helper.h>
-#include <systemd/sd-daemon.h>
-
-static GMainLoop *main_loop;
-static PkClientHelper *helper;
-
-static gboolean exit_loop(gpointer user_data)
-{
-	g_debug("Checking for active connections");
-	if (!pk_client_helper_is_active(helper)) {
-		g_message("No active connections, exiting");
-		g_main_loop_quit(main_loop);
-	}
-	return TRUE;
-}
-
-int main(void)
-{
-	char **argv = NULL;
-	char **envp = NULL;
-	GSocket *socket = NULL;
-	GError *error = NULL;
-	int fd = -1;
-
-	main_loop = g_main_loop_new(NULL, FALSE);
-	pk_client_create_helper_argv_envp(&argv, &envp);
-
-
-	if (sd_listen_fds(0) != 1) {
-			g_error("No or too many file descriptors received.\n");
-			exit(1);
-	}
-
-	fd = SD_LISTEN_FDS_START + 0;
-	socket = g_socket_new_from_fd(fd, &error);
-
-	if (error != NULL) {
-		g_error("%s\n", error->message);
-		return 1;
-	}
-
-	helper = pk_client_helper_new();
-	if (!pk_client_helper_start_with_socket(helper, socket, argv, envp, &error)) {
-		g_error("%s\n", error->message);
-		return 1;
-	}
-
-	g_timeout_add_seconds(60, exit_loop, NULL);
-
-	g_main_loop_run(main_loop);
-}
diff --git a/backends/aptcc/pk-debconf-helper.service.in b/backends/aptcc/pk-debconf-helper.service.in
deleted file mode 100644
index eaa66d584..000000000
--- a/backends/aptcc/pk-debconf-helper.service.in
+++ /dev/null
@@ -1,7 +0,0 @@
-[Unit]
-Description=debconf communication service
-Requires=pk-debconf-helper.socket
-RefuseManualStart=true
-
-[Service]
-ExecStart=@libexecdir@/pk-debconf-helper
diff --git a/backends/aptcc/pk-debconf-helper.socket.in b/backends/aptcc/pk-debconf-helper.socket.in
deleted file mode 100644
index 1b912ec5b..000000000
--- a/backends/aptcc/pk-debconf-helper.socket.in
+++ /dev/null
@@ -1,8 +0,0 @@
-[Unit]
-Description=debconf communication socket
-
-[Socket]
-ListenStream=%t/pk-debconf-socket
-
-[Install]
-WantedBy=sockets.target
diff --git a/backends/aptcc/pkg-list.cpp b/backends/aptcc/pkg-list.cpp
index c1dd40c41..9923edac1 100644
--- a/backends/aptcc/pkg-list.cpp
+++ b/backends/aptcc/pkg-list.cpp
@@ -23,6 +23,8 @@
 
 #include <algorithm>
 
+#include <string.h>
+
 // compare...uses the candidate version of each package.
 class compare
 {
diff --git a/client/meson.build b/client/meson.build
index ea2401b00..5b4198b77 100644
--- a/client/meson.build
+++ b/client/meson.build
@@ -40,6 +40,17 @@ if get_option('offline_update')
       '-DPACKAGE_LOCALE_DIR="@0@"'.format(package_locale_dir),
     ]
   )
+
+  offline_update_data = configuration_data()
+  offline_update_data.set('libexecdir', join_paths(get_option('prefix'), get_option('libexecdir')))
+  offline_update_data.set('cachedir', join_paths(get_option('prefix'), get_option('localstatedir'), 'cache'))
+  configure_file(
+    input: 'pk-invoke-filetriggers.sh.in',
+    output: 'pk-invoke-filetriggers.sh',
+    configuration: offline_update_data,
+    install: true,
+    install_dir: get_option('libexecdir'),
+  )
 endif
 
 if get_option('man_pages')
diff --git a/client/pk-invoke-filetriggers.sh.in b/client/pk-invoke-filetriggers.sh.in
new file mode 100644
index 000000000..5366b5794
--- /dev/null
+++ b/client/pk-invoke-filetriggers.sh.in
@@ -0,0 +1,7 @@
+#/bin/sh -efu
+
+@libexecdir@/rpm/postupdate
+
+if set @cachedir@/apt/*.bin && [ -f "$1" ]; then
+    /bin/rm -f "$@"
+fi
diff --git a/client/pk-offline-update.c b/client/pk-offline-update.c
index 900f975ce..bcc0cd5f7 100644
--- a/client/pk-offline-update.c
+++ b/client/pk-offline-update.c
@@ -34,6 +34,32 @@
 #include <unistd.h>
 #include <systemd/sd-journal.h>
 
+static void
+pk_offline_update_create_snapshot ()
+{
+	g_autoptr(GError) error = NULL;
+	g_autofree gchar *cmdargv = NULL;
+	g_autofree gchar *cmdline = NULL;
+	gint exit_status;
+
+	cmdargv = g_find_program_in_path ("timeshift");
+	if (cmdargv == NULL) {
+		sd_journal_print (LOG_WARNING, "timeshift not found");
+		return;
+	}
+
+	/* --btrfs is an one-shot option, if using rsync mode, it won't change */
+	cmdline = g_strdup_printf ("timeshift --btrfs --create --comments \"%s\"", "Before Offline Update");
+
+	/* Intentional, package DB should be intact until snapshot is created */
+	g_spawn_command_line_sync (cmdline, NULL, NULL, &exit_status, &error);
+	if (!exit_status) {
+		sd_journal_print (LOG_WARNING, "failed to create snapshot");
+	} else {
+		sd_journal_print (LOG_INFO, "Created pre-update snapshot via timeshift");
+	}
+}
+
 static void
 pk_offline_update_set_plymouth_msg (const gchar *msg)
 {
@@ -160,8 +186,7 @@ pk_offline_update_progress_cb (PkProgress *progress,
 			 * advise of the new percentage completion when installing updates */
 			msg = g_strdup_printf ("%s - %i%%", _("Installing Updates"), percentage);
 		}
-		if (percentage > 10)
-			pk_offline_update_set_plymouth_msg (msg);
+		pk_offline_update_set_plymouth_msg (msg);
 
 		/* print on terminal */
 		pk_progress_bar_set_percentage (progressbar, percentage);
@@ -445,11 +470,26 @@ main (int argc, char *argv[])
 	g_autoptr(PkProgressBar) progressbar = NULL;
 	g_autoptr(PkTask) task = NULL;
 
+	gboolean do_action = FALSE;
+	GOptionContext *context;
+
+	const GOptionEntry options[] = {
+		{ "shutdown", '\0', 0, G_OPTION_ARG_NONE, &do_action,
+		  _("Actually reboot or shutdown"), NULL },
+		{ NULL }
+	};
+
 	setlocale (LC_ALL, "");
 	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 	textdomain (GETTEXT_PACKAGE);
 
+	context = g_option_context_new (_("PackageKit offline update service"));
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_add_group (context, pk_debug_get_option_group ());
+	g_option_context_parse (context, &argc, &argv, NULL);
+	g_option_context_free (context);
+
 	/* ensure root user */
 	if (getuid () != 0 || geteuid () != 0) {
 		retval = EXIT_FAILURE;
@@ -458,6 +498,22 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
+	if (do_action) {
+		/* if action is undefined, return error */
+		retval = EXIT_FAILURE;
+		/* get the action, and then delete the file */
+		action = pk_offline_update_get_action ();
+		g_unlink (PK_OFFLINE_ACTION_FILENAME);
+
+		/* we have to manually either restart or shutdown */
+		if (action == PK_OFFLINE_ACTION_REBOOT)
+			retval = pk_offline_update_reboot ();
+		else if (action == PK_OFFLINE_ACTION_POWER_OFF)
+			retval = pk_offline_update_power_off ();
+
+		return retval;
+	}
+
 	/* verify this is pointing to our cache */
 	link = g_file_read_link (PK_OFFLINE_TRIGGER_FILENAME, NULL);
 	if (link == NULL) {
@@ -474,10 +530,6 @@ main (int argc, char *argv[])
 		goto out;
 	}
 
-	/* get the action, and then delete the file */
-	action = pk_offline_update_get_action ();
-	g_unlink (PK_OFFLINE_ACTION_FILENAME);
-
 	/* always do this first to avoid a loop if this tool segfaults */
 	g_unlink (PK_OFFLINE_TRIGGER_FILENAME);
 
@@ -496,6 +548,8 @@ main (int argc, char *argv[])
 	task = pk_task_new ();
 	pk_client_set_interactive (PK_CLIENT (task), FALSE);
 
+	pk_offline_update_create_snapshot ();
+
 	if (g_strcmp0 (link, PK_OFFLINE_PREPARED_UPGRADE_FILENAME) == 0 &&
 	    g_file_test (PK_OFFLINE_PREPARED_UPGRADE_FILENAME, G_FILE_TEST_EXISTS)) {
 		/* do system upgrade */
@@ -541,12 +595,6 @@ out:
 		g_main_loop_run (loop);
 	}
 
-	/* we have to manually either restart or shutdown */
-	if (action == PK_OFFLINE_ACTION_REBOOT)
-		retval = pk_offline_update_reboot ();
-	else if (action == PK_OFFLINE_ACTION_POWER_OFF)
-		retval = pk_offline_update_power_off ();
-
 	/* We must return success if we queued the shutdown or reboot
 	 * request, so the failure action specified by the unit is not
 	 * triggered. If we failed to enqueue, return failure which
diff --git a/data/meson.build b/data/meson.build
index a953f6280..931e7fd79 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -6,6 +6,7 @@ install_data(
 dbus_config_data = configuration_data()
 dbus_config_data.set('PACKAGEKIT_USER', get_option('packagekit_user'))
 dbus_config_data.set('libexecdir', join_paths(get_option('prefix'), get_option('libexecdir')))
+dbus_config_data.set('bindir', join_paths(get_option('prefix'), get_option('bindir')))
 
 dbus_sys_dir = get_option('dbus_sys')
 if dbus_sys_dir == ''
diff --git a/data/packagekit-offline-update.service.in b/data/packagekit-offline-update.service.in
index 23096058f..43d08d937 100644
--- a/data/packagekit-offline-update.service.in
+++ b/data/packagekit-offline-update.service.in
@@ -7,9 +7,15 @@ After=sysinit.target dbus.socket systemd-journald.socket system-update-pre.targe
 Before=shutdown.target system-update.target
 # See packagekit.service
 ConditionPathExists=!/run/ostree-booted
+ConditionPathExists=!/var/lib/PackageKit/upgrade_lock
 
 [Service]
 Type=oneshot
+ExecStartPre=/bin/touch /var/lib/PackageKit/disable-rpm-triggers
 ExecStart=@libexecdir@/pk-offline-update
+ExecStartPost=-/bin/sh @libexecdir@/pk-invoke-filetriggers.sh
+ExecStartPost=-/bin/rm /var/lib/PackageKit/disable-rpm-triggers
+ExecStartPost=@libexecdir@/pk-offline-update --shutdown
+ExecStopPost=-/bin/rm /var/lib/PackageKit/disable-rpm-triggers
 
 FailureAction=reboot
diff --git a/data/packagekit.service.in b/data/packagekit.service.in
index 52884589a..fe9ea4e7c 100644
--- a/data/packagekit.service.in
+++ b/data/packagekit.service.in
@@ -4,6 +4,8 @@ Description=PackageKit Daemon
 # currently the design is to have dedicated daemons like
 # eos-updater and rpm-ostree, and gnome-software talks to those.
 ConditionPathExists=!/run/ostree-booted
+# PK shouldn't run while librpm is updated
+ConditionPathExists=!/var/lib/PackageKit/upgrade_lock
 Wants=network-online.target
 
 [Service]
diff --git a/lib/packagekit-glib2/pk-offline.c b/lib/packagekit-glib2/pk-offline.c
index 9030be293..048fa9cde 100644
--- a/lib/packagekit-glib2/pk-offline.c
+++ b/lib/packagekit-glib2/pk-offline.c
@@ -373,8 +373,7 @@ pk_offline_get_action (GError **error)
 	g_return_val_if_fail (error == NULL || *error == NULL, PK_OFFLINE_ACTION_UNKNOWN);
 
 	/* is the trigger set? */
-	if (!g_file_test (PK_OFFLINE_TRIGGER_FILENAME, G_FILE_TEST_EXISTS) ||
-	    !g_file_test (PK_OFFLINE_ACTION_FILENAME, G_FILE_TEST_EXISTS))
+	if (!g_file_test (PK_OFFLINE_ACTION_FILENAME, G_FILE_TEST_EXISTS))
 		return PK_OFFLINE_ACTION_UNSET;
 
 	/* read data file */
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin