diff --git a/pressure-vessel/flatpak-bwrap-private.h b/pressure-vessel/flatpak-bwrap-private.h
index 03c83a3ee798d367ef5da56ebf50af73d2dfefdd..44818bfc013f04b9cb876234d9d4b92fabd5301e 100644
--- a/pressure-vessel/flatpak-bwrap-private.h
+++ b/pressure-vessel/flatpak-bwrap-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2014-2018 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
diff --git a/pressure-vessel/flatpak-bwrap.c b/pressure-vessel/flatpak-bwrap.c
index 392711480ab8fcd946a688c37f76cde27ead917a..54e0b696d73604ed253f29c172f96c17b563d12a 100644
--- a/pressure-vessel/flatpak-bwrap.c
+++ b/pressure-vessel/flatpak-bwrap.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2014-2018 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
diff --git a/pressure-vessel/flatpak-common-types-private.h b/pressure-vessel/flatpak-common-types-private.h
index b24aa061c6ed0167c06661e8053eac5bcbf9012f..b943a2eefd9a33436bcb6b012afa559e4ffbccd2 100644
--- a/pressure-vessel/flatpak-common-types-private.h
+++ b/pressure-vessel/flatpak-common-types-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2015 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-context-private.h b/pressure-vessel/flatpak-context-private.h
index e7bee68c153a09e26e06093665ff38fec6b8cb3b..b9ab61b606f9dd1745c9625d4c459fb687ffae64 100644
--- a/pressure-vessel/flatpak-context-private.h
+++ b/pressure-vessel/flatpak-context-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2014-2018 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
@@ -179,6 +179,13 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakContext, flatpak_context_free)
 GFile *flatpak_get_user_base_dir_location (void);
 GFile *flatpak_get_data_dir (const char *app_id);
 
+gboolean flatpak_context_get_allowed_exports (FlatpakContext *context,
+                                              const char     *source_path,
+                                              const char     *app_id,
+                                              char         ***allowed_extensions_out,
+                                              char         ***allowed_prefixes_out,
+                                              gboolean       *require_exact_match_out);
+
 #endif
 
 #endif /* __FLATPAK_CONTEXT_H__ */
diff --git a/pressure-vessel/flatpak-error.h b/pressure-vessel/flatpak-error.h
index 3b9c9a9390b966ab80655d7fd880964fad77291c..97ce8866fe8c79d8366b3f760eaeefd40cd795c2 100644
--- a/pressure-vessel/flatpak-error.h
+++ b/pressure-vessel/flatpak-error.h
@@ -1,6 +1,6 @@
 /* flatpak-error.c
  * Adapted from Flatpak
- * Last updated: Flatpak 1.14.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright (C) 2015 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.0-or-later
diff --git a/pressure-vessel/flatpak-exports-private.h b/pressure-vessel/flatpak-exports-private.h
index a356e20698712782cf2767cf92969fd3e841950b..ae2b01fbf71520c9cb2386d492717d4c19b6a864 100644
--- a/pressure-vessel/flatpak-exports-private.h
+++ b/pressure-vessel/flatpak-exports-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2018 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-exports.c b/pressure-vessel/flatpak-exports.c
index 805fad4fb5dbfdcb05ad2e05b525f1dcf5614701..adc754bfd1f5d516e789f0f91e55f651144549a8 100644
--- a/pressure-vessel/flatpak-exports.c
+++ b/pressure-vessel/flatpak-exports.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
@@ -49,10 +49,6 @@
 #include "flatpak-metadata-private.h"
 #include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
-#if 0
-#include "flatpak-dir-private.h"
-#include "flatpak-systemd-dbus-generated.h"
-#endif
 #include "flatpak-error.h"
 
 /* pressure-vessel-specific */
diff --git a/pressure-vessel/flatpak-glib-backports-private.h b/pressure-vessel/flatpak-glib-backports-private.h
index 48935cf4a18fe6497f489d1b16f818de76498c84..2f843bbe69dd2b99e883d7150ee19947800b1863 100644
--- a/pressure-vessel/flatpak-glib-backports-private.h
+++ b/pressure-vessel/flatpak-glib-backports-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright 2013 Allison Karlitskaya
  * Copyright 2013 Collabora Ltd.
diff --git a/pressure-vessel/flatpak-glib-backports.c b/pressure-vessel/flatpak-glib-backports.c
index b91271f147a2b48fa362d8a13447764baeee80ba..e0bea9a3346063a2482402d73081544bac87c600 100644
--- a/pressure-vessel/flatpak-glib-backports.c
+++ b/pressure-vessel/flatpak-glib-backports.c
@@ -1,7 +1,7 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  *
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright 1995-1998 Free Software Foundation, Inc.
  * Copyright 2004 Hidetoshi Tajima
diff --git a/pressure-vessel/flatpak-metadata-private.h b/pressure-vessel/flatpak-metadata-private.h
index 429f81aa12b2fa5bba863618a51499a68434328c..0f140b20a69d61bb2cfb9988b6b2e7a4bc6ea542 100644
--- a/pressure-vessel/flatpak-metadata-private.h
+++ b/pressure-vessel/flatpak-metadata-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
diff --git a/pressure-vessel/flatpak-portal.h b/pressure-vessel/flatpak-portal.h
index 065eeb0dcd7b36ffad3e33d499c1d81b90be19ff..ef97b4c65f2a08ba429f0667dd4504a9b9fc09ea 100644
--- a/pressure-vessel/flatpak-portal.h
+++ b/pressure-vessel/flatpak-portal.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2018 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
diff --git a/pressure-vessel/flatpak-run-dbus-private.h b/pressure-vessel/flatpak-run-dbus-private.h
index 33ca66af89e8d893499c68445e2291bb80fcee2f..24ed52baad493e8af20a12a65065adfc25d84c30 100644
--- a/pressure-vessel/flatpak-run-dbus-private.h
+++ b/pressure-vessel/flatpak-run-dbus-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run-dbus.c b/pressure-vessel/flatpak-run-dbus.c
index 2e66d1ecf214072b0114acee932168156dcf8be9..0f8af933d767445ade019fc848712c0e1d252d6a 100644
--- a/pressure-vessel/flatpak-run-dbus.c
+++ b/pressure-vessel/flatpak-run-dbus.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
@@ -460,6 +460,8 @@ flatpak_run_add_a11y_dbus_args (FlatpakBwrap   *app_bwrap,
   flatpak_bwrap_add_args (proxy_arg_bwrap,
                           a11y_address,
                           proxy_socket, "--filter", "--sloppy-names",
+                          "--broadcast=org.a11y.atspi.Registry.EventListenerRegistered=@/org/a11y/atspi/registry",
+                          "--broadcast=org.a11y.atspi.Registry.EventListenerDeregistered=@/org/a11y/atspi/registry",
                           "--call=org.a11y.atspi.Registry=org.a11y.atspi.Socket.Embed@/org/a11y/atspi/accessible/root",
                           "--call=org.a11y.atspi.Registry=org.a11y.atspi.Socket.Unembed@/org/a11y/atspi/accessible/root",
                           "--call=org.a11y.atspi.Registry=org.a11y.atspi.Registry.GetRegisteredEvents@/org/a11y/atspi/registry",
diff --git a/pressure-vessel/flatpak-run-private.h b/pressure-vessel/flatpak-run-private.h
index f59bc5bad790b80c28fe5882f6095d5939d71ab4..debcaffc99d73331c4427f81bb7347dcdd8893ea 100644
--- a/pressure-vessel/flatpak-run-private.h
+++ b/pressure-vessel/flatpak-run-private.h
@@ -1,6 +1,6 @@
 /*
  * Cut-down version of common/flatpak-run-private.h from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2017-2022 Collabora Ltd.
  * Copyright © 2014-2022 Red Hat, Inc
diff --git a/pressure-vessel/flatpak-run-pulseaudio-private.h b/pressure-vessel/flatpak-run-pulseaudio-private.h
index ea52ab652f1734c94a7d7ee9301107e9f84a007c..049d39693be0e16dc91c3ad088af53c838505eed 100644
--- a/pressure-vessel/flatpak-run-pulseaudio-private.h
+++ b/pressure-vessel/flatpak-run-pulseaudio-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run-pulseaudio.c b/pressure-vessel/flatpak-run-pulseaudio.c
index 73b5d6c6535ac000bf5ea07985b22b9f6dce1627..dea2ef72947687c6a15a7203bb7eb986f77dcc01 100644
--- a/pressure-vessel/flatpak-run-pulseaudio.c
+++ b/pressure-vessel/flatpak-run-pulseaudio.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run-sockets-private.h b/pressure-vessel/flatpak-run-sockets-private.h
index 7d7015aa4265f981a002ce177be28d674683df83..fd71d35163dc49b8a008b42dfa02d1302d0131f7 100644
--- a/pressure-vessel/flatpak-run-sockets-private.h
+++ b/pressure-vessel/flatpak-run-sockets-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run-sockets.c b/pressure-vessel/flatpak-run-sockets.c
index 439b265b27a7f4a012f1acb87c1ab682ea64a7d1..c1f18f502cba90489f07f73b5a2f5c41ef120435 100644
--- a/pressure-vessel/flatpak-run-sockets.c
+++ b/pressure-vessel/flatpak-run-sockets.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run-wayland-private.h b/pressure-vessel/flatpak-run-wayland-private.h
index ccf2e5baae439281d800f29f487cd76e9af70b68..d084a215aaeb28ec19015e2e039fefd423a99c64 100644
--- a/pressure-vessel/flatpak-run-wayland-private.h
+++ b/pressure-vessel/flatpak-run-wayland-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
@@ -33,6 +33,10 @@ G_BEGIN_DECLS
 
 gboolean
 flatpak_run_add_wayland_args (FlatpakBwrap *bwrap,
+#if 0
+                              const char   *app_id,
+                              const char   *instance_id,
+#endif
                               gboolean      inherit_wayland_socket);
 
 G_END_DECLS
diff --git a/pressure-vessel/flatpak-run-wayland.c b/pressure-vessel/flatpak-run-wayland.c
index 4904869e5f969827bcc48833e250e754a68509e6..3f11b431c0d28b0f0a62c206c694196537d5e26f 100644
--- a/pressure-vessel/flatpak-run-wayland.c
+++ b/pressure-vessel/flatpak-run-wayland.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
@@ -241,6 +241,10 @@ out:
  */
 gboolean
 flatpak_run_add_wayland_args (FlatpakBwrap *bwrap,
+#if 0
+                              const char   *app_id,
+                              const char   *instance_id,
+#endif
                               gboolean      inherit_wayland_socket)
 {
   const char *wayland_display;
diff --git a/pressure-vessel/flatpak-run-x11-private.h b/pressure-vessel/flatpak-run-x11-private.h
index 996db9c46aafff13561ba9edbfd9e64ddac656aa..a1784dabe68b79d6242b50ea5289e8b33148aa56 100644
--- a/pressure-vessel/flatpak-run-x11-private.h
+++ b/pressure-vessel/flatpak-run-x11-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run-x11.c b/pressure-vessel/flatpak-run-x11.c
index b991e428bf0e6252397e96e218a83615eeb87bd2..d3097ccc22ade4803ba602edaa918c2d01c21930 100644
--- a/pressure-vessel/flatpak-run-x11.c
+++ b/pressure-vessel/flatpak-run-x11.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2014-2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
diff --git a/pressure-vessel/flatpak-run.c b/pressure-vessel/flatpak-run.c
index f41d78876a5e24bae51768601e7c59bde25fe54b..4bad23ff148ed1d57e92e0fa6334c3a74101cb67 100644
--- a/pressure-vessel/flatpak-run.c
+++ b/pressure-vessel/flatpak-run.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Cut-down version of common/flatpak-run.c from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2017-2022 Collabora Ltd.
  * Copyright © 2014-2022 Red Hat, Inc
@@ -62,12 +62,16 @@
 #include <gio/gio.h>
 #include "libglnx.h"
 
+#if 0
+#include "flatpak-dbus-generated.h"
+#endif
 #include "flatpak-run-dbus-private.h"
 #include "flatpak-run-private.h"
 #include "flatpak-run-sockets-private.h"
 #include "flatpak-utils-base-private.h"
 #if 0
 #include "flatpak-dir-private.h"
+#include "flatpak-dir-utils-private.h"
 #include "flatpak-instance-private.h"
 #endif
 #include "flatpak-systemd-dbus-generated.h"
@@ -83,6 +87,12 @@
 
 #if 0
 
+typedef FlatpakSessionHelper AutoFlatpakSessionHelper;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoFlatpakSessionHelper, g_object_unref)
+
+typedef XdpDbusDocuments AutoXdpDbusDocuments;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoXdpDbusDocuments, g_object_unref)
+
 static int
 flatpak_extension_compare_by_path (gconstpointer _a,
                                    gconstpointer _b)
@@ -1629,12 +1639,14 @@ add_tzdata_args (FlatpakBwrap *bwrap,
   /* Check for runtime /usr/share/zoneinfo */
   if (runtime_zoneinfo != NULL && g_file_query_exists (runtime_zoneinfo, NULL))
     {
+      const char *tzdir = flatpak_get_tzdir ();
+
       /* Check for host /usr/share/zoneinfo */
-      if (g_file_test ("/usr/share/zoneinfo", G_FILE_TEST_IS_DIR))
+      if (g_file_test (tzdir, G_FILE_TEST_IS_DIR))
         {
           /* Here we assume the host timezone file exist in the host data */
           flatpak_bwrap_add_args (bwrap,
-                                  "--ro-bind", "/usr/share/zoneinfo", "/usr/share/zoneinfo",
+                                  "--ro-bind", tzdir, "/usr/share/zoneinfo",
                                   "--symlink", localtime_content, "/etc/localtime",
                                   NULL);
         }
@@ -2182,6 +2194,16 @@ flatpak_run_setup_usr_links (FlatpakBwrap *bwrap,
     }
 }
 
+/* Directories in /sys to share with the sandbox if accessible. */
+static const char *const sysfs_dirs[] =
+{
+  "/sys/block",
+  "/sys/bus",
+  "/sys/class",
+  "/sys/dev",
+  "/sys/devices"
+};
+
 gboolean
 flatpak_run_setup_base_argv (FlatpakBwrap   *bwrap,
                              GFile          *runtime_files,
@@ -2201,6 +2223,7 @@ flatpak_run_setup_base_argv (FlatpakBwrap   *bwrap,
   gboolean parent_expose_pids = (flags & FLATPAK_RUN_FLAG_PARENT_EXPOSE_PIDS) != 0;
   gboolean parent_share_pids = (flags & FLATPAK_RUN_FLAG_PARENT_SHARE_PIDS) != 0;
   gboolean bwrap_unprivileged = flatpak_bwrap_is_unprivileged ();
+  gsize i;
 
   /* Disable recursive userns for all flatpak processes, as we need this
    * to guarantee that the sandbox can't restructure the filesystem.
@@ -2269,16 +2292,21 @@ flatpak_run_setup_base_argv (FlatpakBwrap   *bwrap,
                           "--perms", "0700", "--dir", run_dir,
                           "--setenv", "XDG_RUNTIME_DIR", run_dir,
                           "--symlink", "../run", "/var/run",
-                          "--ro-bind", "/sys/block", "/sys/block",
-                          "--ro-bind", "/sys/bus", "/sys/bus",
-                          "--ro-bind", "/sys/class", "/sys/class",
-                          "--ro-bind", "/sys/dev", "/sys/dev",
-                          "--ro-bind", "/sys/devices", "/sys/devices",
                           "--ro-bind-try", "/proc/self/ns/user", "/run/.userns",
                           /* glib uses this like /etc/timezone */
                           "--symlink", "/etc/timezone", "/var/db/zoneinfo",
                           NULL);
 
+  for (i = 0; i < G_N_ELEMENTS (sysfs_dirs); i++)
+    {
+      const char *dir = sysfs_dirs[i];
+
+      if (access (dir, R_OK|X_OK) == 0)
+        flatpak_bwrap_add_args (bwrap, "--ro-bind", dir, dir, NULL);
+      else
+        g_info ("Not sharing %s with sandbox: %s", dir, g_strerror (errno));
+    }
+
   if (flags & FLATPAK_RUN_FLAG_DIE_WITH_PARENT)
     flatpak_bwrap_add_args (bwrap,
                             "--die-with-parent",
diff --git a/pressure-vessel/flatpak-session-helper.h b/pressure-vessel/flatpak-session-helper.h
index ca2611cb385e7418bed6eaa8560e9a67182a3ffc..9414beb80ee17a766b83c2f790807f59e81d2cd0 100644
--- a/pressure-vessel/flatpak-session-helper.h
+++ b/pressure-vessel/flatpak-session-helper.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2021 Collabora Ltd.
  * SPDX-License-Identifier: LGPL-2.1-or-later
diff --git a/pressure-vessel/flatpak-utils-base-private.h b/pressure-vessel/flatpak-utils-base-private.h
index de0db1160c98edffae1b77746fd1416bd12c0b7b..96c25a7c4a669f468bf9d7f37dcf136ea661c2e0 100644
--- a/pressure-vessel/flatpak-utils-base-private.h
+++ b/pressure-vessel/flatpak-utils-base-private.h
@@ -1,6 +1,6 @@
 /*
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
@@ -32,7 +32,9 @@
 # define G_DBUS_METHOD_INVOCATION_UNHANDLED FALSE
 #endif
 
-char *flatpak_get_timezone (void);
+const char * flatpak_get_tzdir (void);
+
+char * flatpak_get_timezone (void);
 
 char * flatpak_readlink (const char *path,
                          GError    **error);
diff --git a/pressure-vessel/flatpak-utils-base.c b/pressure-vessel/flatpak-utils-base.c
index 57c2d00a270f1ef3dc365408c4b61518d3b662dd..c921cb401ab6c6b7171c4acc49f5c80879d2ad5a 100644
--- a/pressure-vessel/flatpak-utils-base.c
+++ b/pressure-vessel/flatpak-utils-base.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
  * Taken from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Last updated: Flatpak 1.15.9
  * Copyright © 2019 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
  *
@@ -31,17 +31,23 @@
 #include <gio/gio.h>
 #include "libglnx.h"
 
-/* To keep this more similar to the original file, we explicitly disable
- * this warning rather than fixing it */
-#pragma GCC diagnostic ignored "-Wshadow"
+const char *
+flatpak_get_tzdir (void)
+{
+  const gchar *tzdir;
+
+  tzdir = getenv ("TZDIR");
+  if (tzdir)
+    return tzdir;
+
+  return "/usr/share/zoneinfo";
+}
 
 char *
 flatpak_get_timezone (void)
 {
   g_autofree gchar *symlink = NULL;
   gchar *etc_timezone = NULL;
-  const gchar *tzdir;
-  const gchar *default_tzdir = "/usr/share/zoneinfo";
 
   symlink = flatpak_resolve_link ("/etc/localtime", NULL);
   if (symlink != NULL)
@@ -49,11 +55,10 @@ flatpak_get_timezone (void)
       /* Resolve relative path */
       g_autofree gchar *canonical = flatpak_canonicalize_filename (symlink);
       char *canonical_suffix;
+      const gchar *tzdir = flatpak_get_tzdir ();
 
       /* Strip the prefix and slashes if possible. */
-
-      tzdir = getenv ("TZDIR");
-      if (tzdir != NULL && g_str_has_prefix (canonical, tzdir))
+      if (g_str_has_prefix (canonical, tzdir))
         {
           canonical_suffix = canonical + strlen (tzdir);
           while (*canonical_suffix == '/')
@@ -61,15 +66,6 @@ flatpak_get_timezone (void)
 
           return g_strdup (canonical_suffix);
         }
-
-      if (g_str_has_prefix (canonical, default_tzdir))
-        {
-          canonical_suffix = canonical + strlen (default_tzdir);
-          while (*canonical_suffix == '/')
-            canonical_suffix++;
-
-          return g_strdup (canonical_suffix);
-        }
     }
 
   if (g_file_get_contents ("/etc/timezone", &etc_timezone,
diff --git a/pressure-vessel/flatpak-utils-private.h b/pressure-vessel/flatpak-utils-private.h
index eddab7c4f78891cbad711c86207c8c8b1622946f..37c02b2c3dad256b5a49a2d9a3987ba3deb712b5 100644
--- a/pressure-vessel/flatpak-utils-private.h
+++ b/pressure-vessel/flatpak-utils-private.h
@@ -1,6 +1,6 @@
 /*
- * A cut-down version of common/flatpak-utils from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Taken from Flatpak
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 2014 Red Hat, Inc
  * SPDX-License-Identifier: LGPL-2.1-or-later
@@ -28,26 +28,13 @@
 #include <string.h>
 
 #include "libglnx.h"
-#include <flatpak-common-types-private.h>
 #include <gio/gio.h>
 #include <gio/gunixfdlist.h>
-#if 0
-#include "flatpak-dbus-generated.h"
-#include "flatpak-document-dbus-generated.h"
-#endif
-#include "flatpak-context-private.h"
 #include "flatpak-error.h"
 #include "flatpak-glib-backports-private.h"
-#if 0
-#include "flatpak-variant-private.h"
-#include "flatpak-dir-private.h"
-#include <ostree.h>
-#endif
 
 #define AUTOFS_SUPER_MAGIC 0x0187
 
-#if 0
-
 #define FLATPAK_XA_CACHE_VERSION 2
 /* version 1 added extra data download size */
 /* version 2 added ot.ts timestamps (to new format) */
@@ -63,10 +50,6 @@
 
 #define FLATPAK_SUMMARY_DIFF_HEADER "xadf"
 
-#define FLATPAK_SUMMARY_HISTORY_LENGTH_DEFAULT 16
-
-#endif
-
 /* https://bugzilla.gnome.org/show_bug.cgi?id=766370 */
 #if !GLIB_CHECK_VERSION (2, 49, 3)
 #define FLATPAK_VARIANT_BUILDER_INITIALIZER {{0, }}
@@ -97,13 +80,13 @@ char * flatpak_get_real_xdg_runtime_dir (void);
 gboolean  flatpak_has_path_prefix (const char *str,
                                    const char *prefix);
 
-#if 0
 const char * flatpak_path_match_prefix (const char *pattern,
                                         const char *path);
 
 const char * flatpak_get_arch (void);
 const char ** flatpak_get_arches (void);
 gboolean flatpak_is_linux32_arch (const char *arch);
+const char *flatpak_get_compat_arch (const char *kernel_arch);
 const char *flatpak_get_compat_arch_reverse (const char *compat_arch);
 
 const char ** flatpak_get_gl_drivers (void);
@@ -133,70 +116,6 @@ gboolean flatpak_variant_save (GFile        *dest,
                                GVariant     *variant,
                                GCancellable *cancellable,
                                GError      **error);
-GVariant *flatpak_repo_load_summary (OstreeRepo *repo,
-                                     GError    **error);
-GVariant *flatpak_repo_load_summary_index (OstreeRepo *repo,
-                                           GError    **error);
-GVariant *flatpak_repo_load_digested_summary (OstreeRepo *repo,
-                                              const char *digest,
-                                              GError    **error);
-GPtrArray *flatpak_summary_match_subrefs (GVariant   *summary,
-                                          const char *collection_id,
-                                          FlatpakDecomposed *ref);
-gboolean flatpak_summary_lookup_ref (GVariant      *summary,
-                                     const char    *collection_id,
-                                     const char    *ref,
-                                     char         **out_checksum,
-                                     VarRefInfoRef *out_info);
-gboolean flatpak_summary_find_ref_map (VarSummaryRef  summary,
-                                       const char    *collection_id,
-                                       VarRefMapRef  *refs_out);
-gboolean flatpak_var_ref_map_lookup_ref (VarRefMapRef   ref_map,
-                                         const char    *ref,
-                                         VarRefInfoRef *out_info);
-
-gboolean flatpak_get_allowed_exports (const char     *source_path,
-                                      const char     *app_id,
-                                      FlatpakContext *context,
-                                      char         ***allowed_extensions_out,
-                                      char         ***allowed_prefixes_out,
-                                      gboolean       *require_exact_match_out);
-
-FlatpakDecomposed *flatpak_find_current_ref (const char   *app_id,
-                                             GCancellable *cancellable,
-                                             GError      **error);
-GFile *flatpak_find_deploy_dir_for_ref (FlatpakDecomposed  *ref,
-                                        FlatpakDir        **dir_out,
-                                        GCancellable       *cancellable,
-                                        GError            **error);
-GFile * flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
-                                        GCancellable      *cancellable,
-                                        GError           **error);
-GFile * flatpak_find_unmaintained_extension_dir_if_exists (const char   *name,
-                                                           const char   *arch,
-                                                           const char   *branch,
-                                                           GCancellable *cancellable);
-FlatpakDeploy * flatpak_find_deploy_for_ref_in (GPtrArray    *dirs,
-                                                const char   *ref,
-                                                const char   *commit,
-                                                GCancellable *cancellable,
-                                                GError      **error);
-FlatpakDeploy * flatpak_find_deploy_for_ref (const char   *ref,
-                                             const char   *commit,
-                                             FlatpakDir   *opt_user_dir,
-                                             GCancellable *cancellable,
-                                             GError      **error);
-char ** flatpak_list_deployed_refs (const char   *type,
-                                    const char   *name_prefix,
-                                    const char   *arch,
-                                    const char   *branch,
-                                    GCancellable *cancellable,
-                                    GError      **error);
-char ** flatpak_list_unmaintained_refs (const char   *name_prefix,
-                                        const char   *branch,
-                                        const char   *arch,
-                                        GCancellable *cancellable,
-                                        GError      **error);
 
 gboolean flatpak_remove_dangling_symlinks (GFile        *dir,
                                            GCancellable *cancellable,
@@ -247,213 +166,24 @@ char *flatpak_keyfile_get_string_non_empty (GKeyFile *keyfile,
                                             const char *group,
                                             const char *key);
 
-GKeyFile * flatpak_parse_repofile (const char   *remote_name,
-                                   gboolean      from_ref,
-                                   GKeyFile     *keyfile,
-                                   GBytes      **gpg_data_out,
-                                   GCancellable *cancellable,
-                                   GError      **error);
-
-gboolean flatpak_repo_set_title (OstreeRepo *repo,
-                                 const char *title,
-                                 GError    **error);
-gboolean flatpak_repo_set_comment (OstreeRepo *repo,
-                                   const char *comment,
-                                   GError    **error);
-gboolean flatpak_repo_set_description (OstreeRepo *repo,
-                                       const char *description,
-                                       GError    **error);
-gboolean flatpak_repo_set_icon (OstreeRepo *repo,
-                                const char *icon,
-                                GError    **error);
-gboolean flatpak_repo_set_homepage (OstreeRepo *repo,
-                                    const char *homepage,
-                                    GError    **error);
-gboolean flatpak_repo_set_redirect_url (OstreeRepo *repo,
-                                        const char *redirect_url,
-                                        GError    **error);
-gboolean flatpak_repo_set_authenticator_name (OstreeRepo *repo,
-                                              const char *authenticator_name,
-                                              GError    **error);
-gboolean flatpak_repo_set_authenticator_install (OstreeRepo *repo,
-                                                 gboolean authenticator_install,
-                                                 GError    **error);
-gboolean flatpak_repo_set_authenticator_option (OstreeRepo *repo,
-                                                const char *key,
-                                                const char *value,
-                                                GError    **error);
-gboolean flatpak_repo_set_default_branch (OstreeRepo *repo,
-                                          const char *branch,
-                                          GError    **error);
-gboolean flatpak_repo_set_collection_id (OstreeRepo *repo,
-                                         const char *collection_id,
-                                         GError    **error);
-gboolean flatpak_repo_set_deploy_collection_id (OstreeRepo *repo,
-                                                gboolean    deploy_collection_id,
-                                                GError    **error);
-gboolean flatpak_repo_set_deploy_sideload_collection_id (OstreeRepo *repo,
-                                                         gboolean    deploy_collection_id,
-                                                         GError    **error);
-gboolean flatpak_repo_set_summary_history_length (OstreeRepo *repo,
-                                                  guint       length,
-                                                  GError    **error);
-guint    flatpak_repo_get_summary_history_length (OstreeRepo *repo);
-gboolean flatpak_repo_set_gpg_keys (OstreeRepo *repo,
-                                    GBytes     *bytes,
-                                    GError    **error);
-
 GBytes *flatpak_zlib_compress_bytes   (GBytes  *bytes,
                                        int      level,
                                        GError **error);
 GBytes *flatpak_zlib_decompress_bytes (GBytes  *bytes,
                                        GError **error);
 
-GBytes *flatpak_summary_apply_diff (GBytes *old,
-                                    GBytes *diff,
-                                    GError **error);
-
-typedef enum {
-  FLATPAK_REPO_UPDATE_FLAG_NONE = 0,
-  FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX = 1 << 0,
-} FlatpakRepoUpdateFlags;
-
-gboolean flatpak_repo_update (OstreeRepo            *repo,
-                              FlatpakRepoUpdateFlags flags,
-                              const char           **gpg_key_ids,
-                              const char            *gpg_homedir,
-                              GCancellable          *cancellable,
-                              GError               **error);
-gboolean flatpak_repo_collect_sizes (OstreeRepo   *repo,
-                                     GFile        *root,
-                                     guint64      *installed_size,
-                                     guint64      *download_size,
-                                     GCancellable *cancellable,
-                                     GError      **error);
-GVariant *flatpak_commit_get_extra_data_sources (GVariant *commitv,
-                                                 GError  **error);
-GVariant *flatpak_repo_get_extra_data_sources (OstreeRepo   *repo,
-                                               const char   *rev,
-                                               GCancellable *cancellable,
-                                               GError      **error);
-void flatpak_repo_parse_extra_data_sources (GVariant      *extra_data_sources,
-                                            int            index,
-                                            const char   **name,
-                                            guint64       *download_size,
-                                            guint64       *installed_size,
-                                            const guchar **sha256,
-                                            const char   **uri);
-gboolean flatpak_mtree_ensure_dir_metadata (OstreeRepo        *repo,
-                                            OstreeMutableTree *mtree,
-                                            GCancellable      *cancellable,
-                                            GError           **error);
-gboolean flatpak_mtree_create_symlink (OstreeRepo         *repo,
-                                       OstreeMutableTree  *parent,
-                                       const char         *name,
-                                       const char         *target,
-                                       GError            **error);
-gboolean flatpak_mtree_add_file_from_bytes (OstreeRepo *repo,
-                                            GBytes *bytes,
-                                            OstreeMutableTree *parent,
-                                            const char *filename,
-                                            GCancellable *cancellable,
-                                            GError      **error);
-gboolean flatpak_mtree_create_dir (OstreeRepo         *repo,
-                                   OstreeMutableTree  *parent,
-                                   const char         *name,
-                                   OstreeMutableTree **dir_out,
-                                   GError            **error);
-
-GVariant *flatpak_bundle_load (GFile              *file,
-                               char              **commit,
-                               FlatpakDecomposed **ref,
-                               char              **origin,
-                               char              **runtime_repo,
-                               char              **app_metadata,
-                               guint64            *installed_size,
-                               GBytes            **gpg_keys,
-                               char              **collection_id,
-                               GError            **error);
-
-gboolean flatpak_pull_from_bundle (OstreeRepo   *repo,
-                                   GFile        *file,
-                                   const char   *remote,
-                                   const char   *ref,
-                                   gboolean      require_gpg_signature,
-                                   GCancellable *cancellable,
-                                   GError      **error);
-
-typedef void (*FlatpakOciPullProgress) (guint64  total_size,
-                                        guint64  pulled_size,
-                                        guint32  n_layers,
-                                        guint32  pulled_layers,
-                                        gpointer data);
-
-char * flatpak_pull_from_oci (OstreeRepo            *repo,
-                              FlatpakOciRegistry    *registry,
-                              const char            *oci_repository,
-                              const char            *digest,
-                              const char            *delta_url,
-                              FlatpakOciManifest    *manifest,
-                              FlatpakOciImage       *image_config,
-                              const char            *remote,
-                              const char            *ref,
-                              FlatpakPullFlags       flags,
-                              FlatpakOciPullProgress progress_cb,
-                              gpointer               progress_data,
-                              GCancellable          *cancellable,
-                              GError               **error);
-
-gboolean flatpak_mirror_image_from_oci (FlatpakOciRegistry    *dst_registry,
-                                        FlatpakOciRegistry    *registry,
-                                        const char            *oci_repository,
-                                        const char            *digest,
-                                        const char            *remote,
-                                        const char            *ref,
-                                        const char            *delta_url,
-                                        OstreeRepo            *repo,
-                                        FlatpakOciPullProgress progress_cb,
-                                        gpointer               progress_data,
-                                        GCancellable          *cancellable,
-                                        GError               **error);
-
-typedef struct
-{
-  char               *id;
-  char               *installed_id;
-  char               *commit;
-  FlatpakDecomposed *ref;
-  char              *directory;
-  char              *files_path;
-  char              *subdir_suffix;
-  char              *add_ld_path;
-  char             **merge_dirs;
-  int                priority;
-  gboolean           needs_tmpfs;
-  gboolean           is_unmaintained;
-} FlatpakExtension;
-
-void flatpak_extension_free (FlatpakExtension *extension);
-
 void flatpak_parse_extension_with_tag (const char *extension,
                                        char      **name,
                                        char      **tag);
 
-GList *flatpak_list_extensions (GKeyFile   *metakey,
-                                const char *arch,
-                                const char *branch);
-#endif
-
 gboolean flatpak_argument_needs_quoting (const char *arg);
 char * flatpak_quote_argv (const char *argv[],
                            gssize      len);
-#if 0
 gboolean flatpak_file_arg_has_suffix (const char *arg,
                                       const char *suffix);
-#endif
 
 const char *flatpak_file_get_path_cached (GFile *file);
 
-#if 0
 GFile *flatpak_build_file_va (GFile  *base,
                               va_list args);
 GFile *flatpak_build_file (GFile *base,
@@ -477,13 +207,11 @@ gboolean   flatpak_cp_a (GFile         *src,
                          FlatpakCpFlags flags,
                          GCancellable  *cancellable,
                          GError       **error);
-#endif
 
 gboolean flatpak_mkdir_p (GFile        *dir,
                           GCancellable *cancellable,
                           GError      **error);
 
-#if 0
 gboolean flatpak_rm_rf (GFile        *dir,
                         GCancellable *cancellable,
                         GError      **error);
@@ -505,7 +233,6 @@ gboolean flatpak_open_in_tmpdir_at (int             tmpdir_fd,
                                     GOutputStream **out_stream,
                                     GCancellable   *cancellable,
                                     GError        **error);
-#endif
 
 gboolean flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
                                                     const char  *name,
@@ -513,7 +240,6 @@ gboolean flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
                                                     size_t       len,
                                                     GError     **error);
 
-#if 0
 static inline void
 flatpak_temp_dir_destroy (void *p)
 {
@@ -528,7 +254,6 @@ flatpak_temp_dir_destroy (void *p)
 
 typedef GFile FlatpakTempDir;
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakTempDir, flatpak_temp_dir_destroy)
-#endif
 
 typedef GMainContext GMainContextPopDefault;
 static inline void
@@ -558,97 +283,8 @@ flatpak_main_context_new_default (void)
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GMainContextPopDefault, flatpak_main_context_pop_default_destroy)
 
-#if 0
-typedef OstreeRepo FlatpakRepoTransaction;
-
-static inline void
-flatpak_repo_transaction_cleanup (void *p)
-{
-  OstreeRepo *repo = p;
-
-  if (repo)
-    {
-      g_autoptr(GError) error = NULL;
-      if (!ostree_repo_abort_transaction (repo, NULL, &error))
-        g_warning ("Error aborting ostree transaction: %s", error->message);
-      g_object_unref (repo);
-    }
-}
-
-static inline FlatpakRepoTransaction *
-flatpak_repo_transaction_start (OstreeRepo   *repo,
-                                GCancellable *cancellable,
-                                GError      **error)
-{
-  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
-    return NULL;
-  return (FlatpakRepoTransaction *) g_object_ref (repo);
-}
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakRepoTransaction, flatpak_repo_transaction_cleanup)
-
 #define AUTOLOCK(name) G_GNUC_UNUSED __attribute__((cleanup (flatpak_auto_unlock_helper))) GMutex * G_PASTE (auto_unlock, __LINE__) = flatpak_auto_lock_helper (&G_LOCK_NAME (name))
 
-/* This uses a weird Auto prefix to avoid conflicts with later added autogenerated autoptr support, per:
- * https://git.gnome.org/browse/glib/commit/?id=1c6cd5f0a3104aa9b62c7f1d3086181f63e71b59
- */
-typedef FlatpakSessionHelper AutoFlatpakSessionHelper;
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoFlatpakSessionHelper, g_object_unref)
-typedef XdpDbusDocuments AutoXdpDbusDocuments;
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (AutoXdpDbusDocuments, g_object_unref)
-
-typedef struct FlatpakXml FlatpakXml;
-
-struct FlatpakXml
-{
-  gchar      *element_name; /* NULL == text */
-  char      **attribute_names;
-  char      **attribute_values;
-  char       *text;
-  FlatpakXml *parent;
-  FlatpakXml *first_child;
-  FlatpakXml *last_child;
-  FlatpakXml *next_sibling;
-};
-
-FlatpakXml *flatpak_xml_new (const gchar *element_name);
-FlatpakXml *flatpak_xml_new_text (const gchar *text);
-void       flatpak_xml_add (FlatpakXml *parent,
-                            FlatpakXml *node);
-void       flatpak_xml_free (FlatpakXml *node);
-FlatpakXml *flatpak_xml_parse (GInputStream * in,
-                               gboolean compressed,
-                               GCancellable *cancellable,
-                               GError      **error);
-void       flatpak_xml_to_string (FlatpakXml *node,
-                                  GString    *res);
-FlatpakXml *flatpak_xml_unlink (FlatpakXml *node,
-                                FlatpakXml *prev_sibling);
-FlatpakXml *flatpak_xml_find (FlatpakXml  *node,
-                              const char  *type,
-                              FlatpakXml **prev_child_out);
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakXml, flatpak_xml_free);
-
-FlatpakXml *flatpak_appstream_xml_new (void);
-gboolean   flatpak_appstream_xml_migrate (FlatpakXml *source,
-                                          FlatpakXml *dest,
-                                          const char *ref,
-                                          const char *id,
-                                          GKeyFile   *metadata);
-gboolean flatpak_appstream_xml_root_to_data (FlatpakXml *appstream_root,
-                                             GBytes    **uncompressed,
-                                             GBytes    **compressed,
-                                             GError    **error);
-gboolean   flatpak_repo_generate_appstream (OstreeRepo   *repo,
-                                            const char  **gpg_key_ids,
-                                            const char   *gpg_homedir,
-                                            guint64       timestamp,
-                                            GCancellable *cancellable,
-                                            GError      **error);
-void flatpak_appstream_xml_filter (FlatpakXml *appstream,
-                                   GRegex *allow_refs,
-                                   GRegex *deny_refs);
-
 char * flatpak_filter_glob_to_regexp (const char *glob, gboolean runtime_only, GError **error);
 gboolean flatpak_parse_filters (const char *data,
                                 GRegex **allow_refs_out,
@@ -668,22 +304,6 @@ gboolean flatpak_allocate_tmpdir (int           tmpdir_dfd,
                                   GCancellable *cancellable,
                                   GError      **error);
 
-static inline void
-flatpak_ostree_progress_finish (OstreeAsyncProgress *progress)
-{
-  if (progress != NULL)
-    {
-      ostree_async_progress_finish (progress);
-      g_object_unref (progress);
-    }
-}
-
-typedef OstreeAsyncProgress OstreeAsyncProgressFinish;
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgressFinish, flatpak_ostree_progress_finish);
-
-
-void flatpak_log_dir_access (FlatpakDir *dir);
-
 gboolean flatpak_check_required_version (const char *ref,
                                          GKeyFile   *metakey,
                                          GError    **error);
@@ -697,15 +317,6 @@ char *   flatpak_dconf_path_for_app_id (const char *app_id);
 gboolean flatpak_dconf_path_is_similar (const char *path1,
                                         const char *path2);
 
-gboolean flatpak_repo_resolve_rev (OstreeRepo    *repo,
-                                   const char    *collection_id, /* nullable */
-                                   const char    *remote_name, /* nullable */
-                                   const char    *ref_name,
-                                   gboolean       allow_noent,
-                                   char         **out_rev,
-                                   GCancellable  *cancellable,
-                                   GError       **error);
-
 static inline void
 null_safe_g_ptr_array_unref (gpointer data)
 {
@@ -715,12 +326,10 @@ null_safe_g_ptr_array_unref (gpointer data)
 GStrv flatpak_parse_env_block (const char  *data,
                                gsize        length,
                                GError     **error);
-#endif
 
 int flatpak_envp_cmp (const void *p1,
                       const void *p2);
 
-#if 0
 gboolean flatpak_str_is_integer (const char *s);
 
 gboolean flatpak_uri_equal (const char *uri1,
@@ -734,8 +343,6 @@ typedef enum {
 
 char * flatpak_escape_string (const char        *s,
                               FlatpakEscapeFlags flags);
-void   flatpak_print_escaped_string (const char        *s,
-                                     FlatpakEscapeFlags flags);
 
 gboolean flatpak_validate_path_characters (const char *path,
                                            GError    **error);
@@ -743,6 +350,5 @@ gboolean flatpak_validate_path_characters (const char *path,
 gboolean running_under_sudo (void);
 
 #define FLATPAK_MESSAGE_ID "c7b39b1e006b464599465e105b361485"
-#endif
 
 #endif /* __FLATPAK_UTILS_H__ */
diff --git a/pressure-vessel/flatpak-utils.c b/pressure-vessel/flatpak-utils.c
index 2b8bb6097dd567c4fd13584d26359723712e8fd9..d7e2169df041673ba3d8d1110d342f49d011bf3d 100644
--- a/pressure-vessel/flatpak-utils.c
+++ b/pressure-vessel/flatpak-utils.c
@@ -1,6 +1,6 @@
 /* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
- * A cut-down version of common/flatpak-utils from Flatpak
- * Last updated: Flatpak 1.15.8
+ * Taken from Flatpak
+ * Last updated: Flatpak 1.15.9
  *
  * Copyright © 1995-1998 Free Software Foundation, Inc.
  * Copyright © 2014-2019 Red Hat, Inc
@@ -47,32 +47,16 @@
 
 #include <glib.h>
 #include <gio/gunixoutputstream.h>
-#include <gio/gunixinputstream.h>
 
-#if 0
-#include "flatpak-dir-private.h"
-#endif
 #include "flatpak-error.h"
-#if 0
-#include "flatpak-oci-registry-private.h"
-#include "flatpak-progress-private.h"
-#endif
-#include "flatpak-run-private.h"
 #include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
-#if 0
-#include "flatpak-variant-impl-private.h"
-#endif
 #include "libglnx.h"
 #if 0
 #include "valgrind-private.h"
-#endif
-
-/* To keep this more similar to the original file, we explicitly disable
- * this warning rather than fixing it */
-#pragma GCC diagnostic ignored "-Wshadow"
-
+#else
 #define RUNNING_ON_VALGRIND 0
+#endif
 
 /* This is also here so the common code can report these errors to the lib */
 static const GDBusErrorEntry flatpak_error_entries[] = {
@@ -103,21 +87,6 @@ static const GDBusErrorEntry flatpak_error_entries[] = {
   {FLATPAK_ERROR_NOT_AUTHORIZED,        "org.freedesktop.Flatpak.Error.NotAuthorized"}, /* Since: 1.7.3 */
 };
 
-#if 0
-
-typedef struct archive FlatpakAutoArchiveRead;
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakAutoArchiveRead, archive_read_free)
-
-static void
-propagate_libarchive_error (GError        **error,
-                            struct archive *a)
-{
-  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-               "%s", archive_error_string (a));
-}
-
-#endif
-
 GQuark
 flatpak_error_quark (void)
 {
@@ -144,8 +113,6 @@ flatpak_fail_error (GError **error, FlatpakError code, const char *fmt, ...)
   return FALSE;
 }
 
-#if 0
-
 GBytes *
 flatpak_zlib_compress_bytes (GBytes *bytes,
                              int level,
@@ -217,8 +184,6 @@ flatpak_read_stream (GInputStream *in,
   return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem_stream));
 }
 
-#endif
-
 gint
 flatpak_strcmp0_ptr (gconstpointer a,
                      gconstpointer b)
@@ -273,8 +238,6 @@ flatpak_has_path_prefix (const char *str,
     }
 }
 
-#if 0
-
 /* Returns end of matching path prefix, or NULL if no match */
 const char *
 flatpak_path_match_prefix (const char *pattern,
@@ -351,7 +314,7 @@ static const char *
 flatpak_get_kernel_arch (void)
 {
   static struct utsname buf;
-  static char *arch = NULL;
+  static const char *arch = NULL;
   char *m;
 
   if (arch != NULL)
@@ -455,7 +418,7 @@ static struct
   { "aarch64", "arm" },
 };
 
-static const char *
+const char *
 flatpak_get_compat_arch (const char *kernel_arch)
 {
   int i;
@@ -651,6 +614,8 @@ flatpak_get_gtk_theme (void)
   return (const char *) gtk_theme;
 }
 
+#if 0
+/* Not used in pressure-vessel, use _srt_check_bwrap() instead */
 const char *
 flatpak_get_bwrap (void)
 {
@@ -673,76 +638,7 @@ flatpak_bwrap_is_unprivileged (void)
     stat (path, &st) == 0 &&
     (st.st_mode & S_ISUID) == 0;
 }
-
-gboolean
-flatpak_get_allowed_exports (const char     *source_path,
-                             const char     *app_id,
-                             FlatpakContext *context,
-                             char         ***allowed_extensions_out,
-                             char         ***allowed_prefixes_out,
-                             gboolean       *require_exact_match_out)
-{
-  g_autoptr(GPtrArray) allowed_extensions = g_ptr_array_new_with_free_func (g_free);
-  g_autoptr(GPtrArray) allowed_prefixes = g_ptr_array_new_with_free_func (g_free);
-  gboolean require_exact_match = FALSE;
-
-  g_ptr_array_add (allowed_prefixes, g_strdup_printf ("%s.*", app_id));
-
-  if (strcmp (source_path, "share/applications") == 0)
-    {
-      g_ptr_array_add (allowed_extensions, g_strdup (".desktop"));
-    }
-  else if (flatpak_has_path_prefix (source_path, "share/icons"))
-    {
-      g_ptr_array_add (allowed_extensions, g_strdup (".svgz"));
-      g_ptr_array_add (allowed_extensions, g_strdup (".png"));
-      g_ptr_array_add (allowed_extensions, g_strdup (".svg"));
-      g_ptr_array_add (allowed_extensions, g_strdup (".ico"));
-    }
-  else if (strcmp (source_path, "share/dbus-1/services") == 0)
-    {
-      g_auto(GStrv) owned_dbus_names =  flatpak_context_get_session_bus_policy_allowed_own_names (context);
-
-      g_ptr_array_add (allowed_extensions, g_strdup (".service"));
-
-      for (GStrv iter = owned_dbus_names; *iter != NULL; ++iter)
-        g_ptr_array_add (allowed_prefixes, g_strdup (*iter));
-
-      /* We need an exact match with no extra garbage, because the filename refers to busnames
-       * and we can *only* match exactly these */
-      require_exact_match = TRUE;
-    }
-  else if (strcmp (source_path, "share/gnome-shell/search-providers") == 0)
-    {
-      g_ptr_array_add (allowed_extensions, g_strdup (".ini"));
-    }
-  else if (strcmp (source_path, "share/mime/packages") == 0)
-    {
-      g_ptr_array_add (allowed_extensions, g_strdup (".xml"));
-    }
-  else if (strcmp (source_path, "share/metainfo") == 0 ||
-           strcmp (source_path, "share/appdata") == 0)
-    {
-      g_ptr_array_add (allowed_extensions, g_strdup (".xml"));
-    }
-  else
-    return FALSE;
-
-  g_ptr_array_add (allowed_extensions, NULL);
-  g_ptr_array_add (allowed_prefixes, NULL);
-
-  if (allowed_extensions_out)
-    *allowed_extensions_out = (char **) g_ptr_array_free (g_steal_pointer (&allowed_extensions), FALSE);
-
-  if (allowed_prefixes_out)
-    *allowed_prefixes_out = (char **) g_ptr_array_free (g_steal_pointer (&allowed_prefixes), FALSE);
-
-  if (require_exact_match_out)
-    *require_exact_match_out = require_exact_match;
-
-  return TRUE;
-}
-
+#endif
 
 static char *
 line_get_word (char **line)
@@ -975,297 +871,6 @@ flatpak_filters_allow_ref (GRegex *allow_refs,
   return FALSE;
 }
 
-char **
-flatpak_list_deployed_refs (const char   *type,
-                            const char   *name_prefix,
-                            const char   *arch,
-                            const char   *branch,
-                            GCancellable *cancellable,
-                            GError      **error)
-{
-  gchar **ret = NULL;
-  g_autoptr(GPtrArray) names = NULL;
-  g_autoptr(GHashTable) hash = NULL;
-  g_autoptr(FlatpakDir) user_dir = NULL;
-  g_autoptr(GPtrArray) system_dirs = NULL;
-  int i;
-
-  hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
-
-  user_dir = flatpak_dir_get_user ();
-  system_dirs = flatpak_dir_get_system_list (cancellable, error);
-  if (system_dirs == NULL)
-    goto out;
-
-  if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix,
-                                          arch, branch, hash, cancellable,
-                                          error))
-    goto out;
-
-  for (i = 0; i < system_dirs->len; i++)
-    {
-      FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
-      if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix,
-                                              arch, branch, hash, cancellable,
-                                              error))
-        goto out;
-    }
-
-  names = g_ptr_array_new ();
-
-  GLNX_HASH_TABLE_FOREACH (hash, FlatpakDecomposed *, ref)
-    {
-      g_ptr_array_add (names, flatpak_decomposed_dup_id (ref));
-    }
-
-  g_ptr_array_sort (names, flatpak_strcmp0_ptr);
-  g_ptr_array_add (names, NULL);
-
-  ret = (char **) g_ptr_array_free (names, FALSE);
-  names = NULL;
-
-out:
-  return ret;
-}
-
-char **
-flatpak_list_unmaintained_refs (const char   *name_prefix,
-                                const char   *arch,
-                                const char   *branch,
-                                GCancellable *cancellable,
-                                GError      **error)
-{
-  gchar **ret = NULL;
-  g_autoptr(GPtrArray) names = NULL;
-  g_autoptr(GHashTable) hash = NULL;
-  g_autoptr(FlatpakDir) user_dir = NULL;
-  const char *key;
-  GHashTableIter iter;
-  g_autoptr(GPtrArray) system_dirs = NULL;
-  int i;
-
-  hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-  user_dir = flatpak_dir_get_user ();
-
-  if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
-                                              arch, branch, hash, cancellable,
-                                              error))
-    return NULL;
-
-  system_dirs = flatpak_dir_get_system_list (cancellable, error);
-  if (system_dirs == NULL)
-    return NULL;
-
-  for (i = 0; i < system_dirs->len; i++)
-    {
-      FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
-
-      if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
-                                                  arch, branch, hash, cancellable,
-                                                  error))
-        return NULL;
-    }
-
-  names = g_ptr_array_new ();
-  g_hash_table_iter_init (&iter, hash);
-  while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
-    g_ptr_array_add (names, g_strdup (key));
-
-  g_ptr_array_sort (names, flatpak_strcmp0_ptr);
-  g_ptr_array_add (names, NULL);
-
-  ret = (char **) g_ptr_array_free (names, FALSE);
-  names = NULL;
-
-  return ret;
-}
-
-GFile *
-flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
-                                 FlatpakDir       **dir_out,
-                                 GCancellable      *cancellable,
-                                 GError           **error)
-{
-  g_autoptr(FlatpakDir) user_dir = NULL;
-  g_autoptr(GPtrArray) system_dirs = NULL;
-  FlatpakDir *dir = NULL;
-  g_autoptr(GFile) deploy = NULL;
-
-  user_dir = flatpak_dir_get_user ();
-  system_dirs = flatpak_dir_get_system_list (cancellable, error);
-  if (system_dirs == NULL)
-    return NULL;
-
-  dir = user_dir;
-  deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
-  if (deploy == NULL)
-    {
-      int i;
-      for (i = 0; deploy == NULL && i < system_dirs->len; i++)
-        {
-          dir = g_ptr_array_index (system_dirs, i);
-          deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
-          if (deploy != NULL)
-            break;
-        }
-    }
-
-  if (deploy == NULL)
-    {
-      flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), flatpak_decomposed_get_ref (ref));
-      return NULL;
-    }
-
-  if (dir_out)
-    *dir_out = g_object_ref (dir);
-  return g_steal_pointer (&deploy);
-}
-
-GFile *
-flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
-                                GCancellable      *cancellable,
-                                GError           **error)
-{
-  g_autoptr(GFile) deploy = NULL;
-
-  deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error);
-  if (deploy == NULL)
-    return NULL;
-
-  return g_file_get_child (deploy, "files");
-}
-
-GFile *
-flatpak_find_unmaintained_extension_dir_if_exists (const char   *name,
-                                                   const char   *arch,
-                                                   const char   *branch,
-                                                   GCancellable *cancellable)
-{
-  g_autoptr(FlatpakDir) user_dir = NULL;
-  g_autoptr(GFile) extension_dir = NULL;
-  g_autoptr(GError) local_error = NULL;
-
-  user_dir = flatpak_dir_get_user ();
-
-  extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable);
-  if (extension_dir == NULL)
-    {
-      g_autoptr(GPtrArray) system_dirs = NULL;
-      int i;
-
-      system_dirs = flatpak_dir_get_system_list (cancellable, &local_error);
-      if (system_dirs == NULL)
-        {
-          g_warning ("Could not get the system installations: %s", local_error->message);
-          return NULL;
-        }
-
-      for (i = 0; i < system_dirs->len; i++)
-        {
-          FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
-          extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable);
-          if (extension_dir != NULL)
-            break;
-        }
-    }
-
-  if (extension_dir == NULL)
-    return NULL;
-
-  return g_steal_pointer (&extension_dir);
-}
-
-FlatpakDecomposed *
-flatpak_find_current_ref (const char   *app_id,
-                          GCancellable *cancellable,
-                          GError      **error)
-{
-  g_autoptr(FlatpakDecomposed) current_ref = NULL;
-  g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
-  int i;
-
-  current_ref = flatpak_dir_current_ref (user_dir, app_id, NULL);
-  if (current_ref == NULL)
-    {
-      g_autoptr(GPtrArray) system_dirs = NULL;
-
-      system_dirs = flatpak_dir_get_system_list (cancellable, error);
-      if (system_dirs == NULL)
-        return FALSE;
-
-      for (i = 0; i < system_dirs->len; i++)
-        {
-          FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
-          current_ref = flatpak_dir_current_ref (dir, app_id, cancellable);
-          if (current_ref != NULL)
-            break;
-        }
-    }
-
-  if (current_ref)
-    return g_steal_pointer (&current_ref);
-
-  flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), app_id);
-  return NULL;
-}
-
-FlatpakDeploy *
-flatpak_find_deploy_for_ref_in (GPtrArray    *dirs,
-                                const char   *ref_str,
-                                const char   *commit,
-                                GCancellable *cancellable,
-                                GError      **error)
-{
-  FlatpakDeploy *deploy = NULL;
-  int i;
-  g_autoptr(GError) my_error = NULL;
-
-  g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, error);
-  if (ref == NULL)
-    return NULL;
-
-  for (i = 0; deploy == NULL && i < dirs->len; i++)
-    {
-      FlatpakDir *dir = g_ptr_array_index (dirs, i);
-
-      flatpak_log_dir_access (dir);
-      g_clear_error (&my_error);
-      deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, &my_error);
-    }
-
-  if (deploy == NULL)
-    g_propagate_error (error, g_steal_pointer (&my_error));
-
-  return deploy;
-}
-
-FlatpakDeploy *
-flatpak_find_deploy_for_ref (const char   *ref,
-                             const char   *commit,
-                             FlatpakDir   *opt_user_dir,
-                             GCancellable *cancellable,
-                             GError      **error)
-{
-  g_autoptr(GPtrArray) dirs = NULL;
-
-  dirs = flatpak_dir_get_system_list (cancellable, error);
-  if (dirs == NULL)
-    return NULL;
-
-  /* If an custom dir was passed, use that instead of the user dir.
-   * This is used when running apply-extra-data where if the target
-   * is a custom installation location the regular user one may not
-   * have the (possibly just installed in this transaction) runtime.
-   */
-  if (opt_user_dir)
-    g_ptr_array_insert (dirs, 0, g_object_ref (opt_user_dir));
-  else
-    g_ptr_array_insert (dirs, 0, flatpak_dir_get_user ());
-
-  return flatpak_find_deploy_for_ref_in (dirs, ref, commit, cancellable, error);
-}
-
 static gboolean
 remove_dangling_symlinks (int           parent_fd,
                           const char   *name,
@@ -1402,8 +1007,6 @@ flatpak_switch_symlink_and_remove (const char *symlink_path,
   return flatpak_fail (error, "flatpak_switch_symlink_and_remove looped too many times");
 }
 
-#endif
-
 gboolean
 flatpak_argument_needs_quoting (const char *arg)
 {
@@ -1450,8 +1053,6 @@ flatpak_quote_argv (const char *argv[],
   return g_string_free (res, FALSE);
 }
 
-#if 0
-
 /* This is useful, because it handles escaped characters in uris, and ? arguments at the end of the uri */
 gboolean
 flatpak_file_arg_has_suffix (const char *arg, const char *suffix)
@@ -1491,12 +1092,6 @@ flatpak_build_file (GFile *base, ...)
   return res;
 }
 
-#endif
-
-#if !GLIB_CHECK_VERSION(2, 34, 0)
-G_LOCK_DEFINE_STATIC (path_cached);
-#endif
-
 const char *
 flatpak_file_get_path_cached (GFile *file)
 {
@@ -1506,7 +1101,6 @@ flatpak_file_get_path_cached (GFile *file)
   if (G_UNLIKELY (_file_path_quark == 0))
     _file_path_quark = g_quark_from_static_string ("flatpak-file-path");
 
-#if GLIB_CHECK_VERSION(2, 34, 0)
   do
     {
       path = g_object_get_qdata ((GObject *) file, _file_path_quark);
@@ -1523,30 +1117,10 @@ flatpak_file_get_path_cached (GFile *file)
         }
     }
   while (path == NULL);
-#else
-  G_LOCK (path_cached);
-    {
-      path = g_object_get_qdata ((GObject *) file, _file_path_quark);
-
-      if (path == NULL)
-        {
-          g_autofree char *new_path = g_file_get_path (file);
-
-          path = new_path;
-
-          if (new_path != NULL)
-            g_object_set_qdata_full ((GObject *) file, _file_path_quark,
-                                     g_steal_pointer (&new_path), g_free);
-        }
-    }
-  G_UNLOCK (path_cached);
-#endif
 
   return path;
 }
 
-#if 0
-
 gboolean
 flatpak_openat_noatime (int           dfd,
                         const char   *name,
@@ -1832,8 +1406,6 @@ flatpak_canonicalize_permissions (int         parent_dfd,
   return _flatpak_canonicalize_permissions (parent_dfd, rel_path, TRUE, uid, gid, error);
 }
 
-#endif
-
 /* Make a directory, and its parent. Don't error if it already exists.
  * If you want a failure mode with EEXIST, use g_file_make_directory_with_parents. */
 gboolean
@@ -1848,8 +1420,6 @@ flatpak_mkdir_p (GFile        *dir,
                                  error);
 }
 
-#if 0
-
 gboolean
 flatpak_rm_rf (GFile        *dir,
                GCancellable *cancellable,
@@ -1879,8 +1449,6 @@ flatpak_file_rename (GFile        *from,
   return TRUE;
 }
 
-#endif
-
 /* If memfd_create() is available, generate a sealed memfd with contents of
  * @str. Otherwise use an O_TMPFILE @tmpf in anonymous mode, write @str to
  * @tmpf, and lseek() back to the start. See also similar uses in e.g.
@@ -1931,8 +1499,6 @@ flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
   return TRUE;
 }
 
-#if 0
-
 gboolean
 flatpak_open_in_tmpdir_at (int             tmpdir_fd,
                            int             mode,
@@ -2033,5230 +1599,121 @@ flatpak_variant_save (GFile        *dest,
   return TRUE;
 }
 
-/* This special cases the ref lookup which by doing a
-   bsearch since the array is sorted */
+char *
+flatpak_keyfile_get_string_non_empty (GKeyFile   *keyfile,
+                                      const char *group,
+                                      const char *key)
+{
+  g_autofree char *value = NULL;
+
+  value = g_key_file_get_string (keyfile, group, key, NULL);
+  if (value != NULL && *value == '\0')
+    g_clear_pointer (&value, g_free);
+
+  return g_steal_pointer (&value);
+}
+
 gboolean
-flatpak_var_ref_map_lookup_ref (VarRefMapRef   ref_map,
-                                const char    *ref,
-                                VarRefInfoRef *out_info)
+flatpak_extension_matches_reason (const char *extension_id,
+                                  const char *reasons,
+                                  gboolean    default_value)
 {
-  gsize imax, imin;
-  gsize imid;
-  gsize n;
+  const char *extension_basename;
+  g_auto(GStrv) reason_list = NULL;
+  size_t i;
 
-  g_return_val_if_fail (out_info != NULL, FALSE);
+  if (reasons == NULL || *reasons == 0)
+    return default_value;
 
-  n = var_ref_map_get_length (ref_map);
-  if (n == 0)
+  extension_basename = strrchr (extension_id, '.');
+  if (extension_basename == NULL)
     return FALSE;
+  extension_basename += 1;
 
-  imax = n - 1;
-  imin = 0;
-  while (imax >= imin)
-    {
-      VarRefMapEntryRef entry;
-      const char *cur;
-      int cmp;
-
-      imid = (imin + imax) / 2;
+  reason_list = g_strsplit (reasons, ";", -1);
 
-      entry = var_ref_map_get_at (ref_map, imid);
-      cur = var_ref_map_entry_get_ref (entry);
+  for (i = 0; reason_list[i]; ++i)
+    {
+      const char *reason = reason_list[i];
 
-      cmp = strcmp (cur, ref);
-      if (cmp < 0)
+      if (strcmp (reason, "active-gl-driver") == 0)
         {
-          imin = imid + 1;
+          /* handled below */
+          const char **gl_drivers = flatpak_get_gl_drivers ();
+          size_t j;
+
+          for (j = 0; gl_drivers[j]; j++)
+            {
+              if (strcmp (gl_drivers[j], extension_basename) == 0)
+                return TRUE;
+            }
         }
-      else if (cmp > 0)
+      else if (strcmp (reason, "active-gtk-theme") == 0)
         {
-          if (imid == 0)
-            break;
-          imax = imid - 1;
-        }
-      else
-        {
-          *out_info = var_ref_map_entry_get_info (entry);
-          return TRUE;
-        }
-    }
-
-  return FALSE;
-}
-
-/* Find the list of refs which belong to the given @collection_id in @summary.
- * If @collection_id is %NULL, the main refs list from the summary will be
- * returned. If @collection_id doesn’t match any collection IDs in the summary
- * file, %FALSE will be returned. */
-gboolean
-flatpak_summary_find_ref_map (VarSummaryRef summary,
-                              const char *collection_id,
-                              VarRefMapRef *refs_out)
-{
-  VarMetadataRef metadata = var_summary_get_metadata (summary);
-  const char *summary_collection_id;
-
-  summary_collection_id = var_metadata_lookup_string (metadata, "ostree.summary.collection-id", NULL);
-
-  if (collection_id == NULL || g_strcmp0 (collection_id, summary_collection_id) == 0)
-    {
-      if (refs_out)
-        *refs_out = var_summary_get_ref_map (summary);
-      return TRUE;
-    }
-  else if (collection_id != NULL)
-    {
-      VarVariantRef collection_map_v;
-      if (var_metadata_lookup (metadata, "ostree.summary.collection-map", NULL, &collection_map_v))
-        {
-          VarCollectionMapRef collection_map = var_collection_map_from_variant (collection_map_v);
-          return var_collection_map_lookup (collection_map, collection_id, NULL, refs_out);
-        }
-    }
-
-  return FALSE;
-}
-
-/* This matches all refs from @collection_id that have ref, followed by '.'  as prefix */
-GPtrArray *
-flatpak_summary_match_subrefs (GVariant          *summary_v,
-                               const char        *collection_id,
-                               FlatpakDecomposed *ref)
-{
-  GPtrArray *res = g_ptr_array_new_with_free_func ((GDestroyNotify)flatpak_decomposed_unref);
-  gsize n, i;
-  g_autofree char *parts_prefix = NULL;
-  g_autofree char *ref_prefix = NULL;
-  g_autofree char *ref_suffix = NULL;
-  VarSummaryRef summary;
-  VarRefMapRef ref_map;
-
-  summary = var_summary_from_gvariant (summary_v);
-
-  /* Work out which refs list to use, based on the @collection_id. */
-  if (flatpak_summary_find_ref_map (summary, collection_id, &ref_map))
-    {
-      /* Match against the refs. */
-      g_autofree char *id = flatpak_decomposed_dup_id (ref);
-      g_autofree char *arch = flatpak_decomposed_dup_arch (ref);
-      g_autofree char *branch = flatpak_decomposed_dup_branch (ref);
-      parts_prefix = g_strconcat (id, ".", NULL);
-
-      ref_prefix = g_strconcat (flatpak_decomposed_get_kind_str (ref), "/", NULL);
-      ref_suffix = g_strconcat ("/", arch, "/", branch, NULL);
-
-      n = var_ref_map_get_length (ref_map);
-      for (i = 0; i < n; i++)
-        {
-          VarRefMapEntryRef entry = var_ref_map_get_at (ref_map, i);
-          const char *cur;
-          const char *id_start;
-          const char *id_suffix;
-          const char *id_end;
-
-          cur = var_ref_map_entry_get_ref (entry);
-
-          /* Must match type */
-          if (!g_str_has_prefix (cur, ref_prefix))
-            continue;
-
-          /* Must match arch & branch */
-          if (!g_str_has_suffix (cur, ref_suffix))
-            continue;
-
-          id_start = strchr (cur, '/');
-          if (id_start == NULL)
-            continue;
-          id_start += 1;
-
-          id_end = strchr (id_start, '/');
-          if (id_end == NULL)
-            continue;
-
-          /* But only prefix of id */
-          if (!g_str_has_prefix (id_start, parts_prefix))
-            continue;
-
-          /* And no dots (we want to install prefix.$ID, but not prefix.$ID.Sources) */
-          id_suffix = id_start + strlen (parts_prefix);
-          if (memchr (id_suffix, '.', id_end - id_suffix) != NULL)
-            continue;
-
-          FlatpakDecomposed *d = flatpak_decomposed_new_from_ref (cur, NULL);
-          if (d)
-            g_ptr_array_add (res, d);
-        }
-    }
-
-  return g_steal_pointer (&res);
-}
-
-gboolean
-flatpak_summary_lookup_ref (GVariant      *summary_v,
-                            const char    *collection_id,
-                            const char    *ref,
-                            char         **out_checksum,
-                            VarRefInfoRef *out_info)
-{
-  VarSummaryRef summary;
-  VarRefMapRef ref_map;
-  VarRefInfoRef info;
-  const guchar *checksum_bytes;
-  gsize checksum_bytes_len;
-
-  summary = var_summary_from_gvariant (summary_v);
-
-  /* Work out which refs list to use, based on the @collection_id. */
-  if (!flatpak_summary_find_ref_map (summary, collection_id, &ref_map))
-    return FALSE;
-
-  if (!flatpak_var_ref_map_lookup_ref (ref_map, ref, &info))
-    return FALSE;
-
-  checksum_bytes = var_ref_info_peek_checksum (info, &checksum_bytes_len);
-  if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
-    return FALSE;
-
-  if (out_checksum)
-    *out_checksum = ostree_checksum_from_bytes (checksum_bytes);
-
-  if (out_info)
-    *out_info = info;
-
-  return TRUE;
-}
-
-char *
-flatpak_keyfile_get_string_non_empty (GKeyFile   *keyfile,
-                                      const char *group,
-                                      const char *key)
-{
-  g_autofree char *value = NULL;
-
-  value = g_key_file_get_string (keyfile, group, key, NULL);
-  if (value != NULL && *value == '\0')
-    g_clear_pointer (&value, g_free);
-
-  return g_steal_pointer (&value);
-}
-
-GKeyFile *
-flatpak_parse_repofile (const char   *remote_name,
-                        gboolean      from_ref,
-                        GKeyFile     *keyfile,
-                        GBytes      **gpg_data_out,
-                        GCancellable *cancellable,
-                        GError      **error)
-{
-  g_autoptr(GBytes) gpg_data = NULL;
-  g_autofree char *uri = NULL;
-  g_autofree char *title = NULL;
-  g_autofree char *gpg_key = NULL;
-  g_autofree char *collection_id = NULL;
-  g_autofree char *default_branch = NULL;
-  g_autofree char *comment = NULL;
-  g_autofree char *description = NULL;
-  g_autofree char *icon = NULL;
-  g_autofree char *homepage = NULL;
-  g_autofree char *filter = NULL;
-  g_autofree char *subset = NULL;
-  g_autofree char *authenticator_name = NULL;
-  gboolean nodeps;
-  const char *source_group;
-  g_autofree char *version = NULL;
-
-  if (from_ref)
-    source_group = FLATPAK_REF_GROUP;
-  else
-    source_group = FLATPAK_REPO_GROUP;
-
-  GKeyFile *config = g_key_file_new ();
-  g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name);
-
-  if (!g_key_file_has_group (keyfile, source_group))
-    {
-      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid %s: Missing group ‘%s’"),
-                          from_ref ? ".flatpakref" : ".flatpakrepo", source_group);
-      return NULL;
-    }
-
-  uri = g_key_file_get_string (keyfile, source_group,
-                               FLATPAK_REPO_URL_KEY, NULL);
-  if (uri == NULL)
-    {
-      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid %s: Missing key ‘%s’"),
-                          from_ref ? ".flatpakref" : ".flatpakrepo", FLATPAK_REPO_URL_KEY);
-      return NULL;
-    }
-
-  version = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                   FLATPAK_REPO_VERSION_KEY, NULL);
-  if (version != NULL && strcmp (version, "1") != 0)
-    {
-      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
-                          _("Invalid version %s, only 1 supported"), version);
-      return NULL;
-    }
-
-  g_key_file_set_string (config, group, "url", uri);
-
-  subset = g_key_file_get_locale_string (keyfile, source_group,
-                                         FLATPAK_REPO_SUBSET_KEY, NULL, NULL);
-  if (subset != NULL)
-    g_key_file_set_string (config, group, "xa.subset", subset);
-
-  /* Don't use the title from flatpakref files; that's the title of the app */
-  if (!from_ref)
-    title = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP,
-                                          FLATPAK_REPO_TITLE_KEY, NULL, NULL);
-  if (title != NULL)
-    g_key_file_set_string (config, group, "xa.title", title);
-
-  default_branch = g_key_file_get_locale_string (keyfile, source_group,
-                                                 FLATPAK_REPO_DEFAULT_BRANCH_KEY, NULL, NULL);
-  if (default_branch != NULL)
-    g_key_file_set_string (config, group, "xa.default-branch", default_branch);
-
-  nodeps = g_key_file_get_boolean (keyfile, source_group,
-                                   FLATPAK_REPO_NODEPS_KEY, NULL);
-  if (nodeps)
-    g_key_file_set_boolean (config, group, "xa.nodeps", TRUE);
-
-  gpg_key = g_key_file_get_string (keyfile, source_group,
-                                   FLATPAK_REPO_GPGKEY_KEY, NULL);
-  if (gpg_key != NULL)
-    {
-      guchar *decoded;
-      gsize decoded_len;
-
-      gpg_key = g_strstrip (gpg_key);
-      decoded = g_base64_decode (gpg_key, &decoded_len);
-      if (decoded_len < 10) /* Check some minimal size so we don't get crap */
-        {
-          g_free (decoded);
-          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid gpg key"));
-          return NULL;
-        }
-
-      gpg_data = g_bytes_new_take (decoded, decoded_len);
-      g_key_file_set_boolean (config, group, "gpg-verify", TRUE);
-    }
-  else
-    {
-      g_key_file_set_boolean (config, group, "gpg-verify", FALSE);
-    }
-
-  /* We have a hierarchy of keys for setting the collection ID, which all have
-   * the same effect. The only difference is which versions of Flatpak support
-   * them, and therefore what P2P implementation is enabled by them:
-   * DeploySideloadCollectionID: supported by Flatpak >= 1.12.8 (1.7.1
-   *   introduced sideload support but this key was added late)
-   * DeployCollectionID: supported by Flatpak >= 1.0.6 (but fully supported in
-   *   >= 1.2.0)
-   * CollectionID: supported by Flatpak >= 0.9.8
-   */
-  collection_id = flatpak_keyfile_get_string_non_empty (keyfile, source_group,
-                                                        FLATPAK_REPO_DEPLOY_SIDELOAD_COLLECTION_ID_KEY);
-  if (collection_id == NULL)
-    collection_id = flatpak_keyfile_get_string_non_empty (keyfile, source_group,
-                                                          FLATPAK_REPO_DEPLOY_COLLECTION_ID_KEY);
-  if (collection_id == NULL)
-    collection_id = flatpak_keyfile_get_string_non_empty (keyfile, source_group,
-                                                          FLATPAK_REPO_COLLECTION_ID_KEY);
-  if (collection_id != NULL)
-    {
-      if (gpg_key == NULL)
-        {
-          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Collection ID requires GPG key to be provided"));
-          return NULL;
-        }
-
-      g_key_file_set_string (config, group, "collection-id", collection_id);
-    }
-
-  g_key_file_set_boolean (config, group, "gpg-verify-summary",
-                          (gpg_key != NULL));
-
-  authenticator_name = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                              FLATPAK_REPO_AUTHENTICATOR_NAME_KEY, NULL);
-  if (authenticator_name)
-    g_key_file_set_string (config, group, "xa.authenticator-name", authenticator_name);
-
-  if (g_key_file_has_key (keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_AUTHENTICATOR_INSTALL_KEY, NULL))
-    {
-      gboolean authenticator_install = g_key_file_get_boolean (keyfile, FLATPAK_REPO_GROUP,
-                                                               FLATPAK_REPO_AUTHENTICATOR_INSTALL_KEY, NULL);
-      g_key_file_set_boolean (config, group, "xa.authenticator-install", authenticator_install);
-    }
-
-  comment = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                   FLATPAK_REPO_COMMENT_KEY, NULL);
-  if (comment)
-    g_key_file_set_string (config, group, "xa.comment", comment);
-
-  description = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                       FLATPAK_REPO_DESCRIPTION_KEY, NULL);
-  if (description)
-    g_key_file_set_string (config, group, "xa.description", description);
-
-  icon = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                FLATPAK_REPO_ICON_KEY, NULL);
-  if (icon)
-    g_key_file_set_string (config, group, "xa.icon", icon);
-
-  homepage  = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                     FLATPAK_REPO_HOMEPAGE_KEY, NULL);
-  if (homepage)
-    g_key_file_set_string (config, group, "xa.homepage", homepage);
-
-  filter = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP,
-                                   FLATPAK_REPO_FILTER_KEY, NULL);
-  if (filter)
-    g_key_file_set_string (config, group, "xa.filter", filter);
-  else
-    g_key_file_set_string (config, group, "xa.filter", ""); /* Default to override any pre-existing filters */
-
-  *gpg_data_out = g_steal_pointer (&gpg_data);
-
-  return g_steal_pointer (&config);
-}
-
-gboolean
-flatpak_repo_set_title (OstreeRepo *repo,
-                        const char *title,
-                        GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (title)
-    g_key_file_set_string (config, "flatpak", "title", title);
-  else
-    g_key_file_remove_key (config, "flatpak", "title", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_comment (OstreeRepo *repo,
-                          const char *comment,
-                          GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (comment)
-    g_key_file_set_string (config, "flatpak", "comment", comment);
-  else
-    g_key_file_remove_key (config, "flatpak", "comment", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_description (OstreeRepo *repo,
-                              const char *description,
-                              GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (description)
-    g_key_file_set_string (config, "flatpak", "description", description);
-  else
-    g_key_file_remove_key (config, "flatpak", "description", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-
-gboolean
-flatpak_repo_set_icon (OstreeRepo *repo,
-                       const char *icon,
-                       GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (icon)
-    g_key_file_set_string (config, "flatpak", "icon", icon);
-  else
-    g_key_file_remove_key (config, "flatpak", "icon", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_homepage (OstreeRepo *repo,
-                           const char *homepage,
-                           GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (homepage)
-    g_key_file_set_string (config, "flatpak", "homepage", homepage);
-  else
-    g_key_file_remove_key (config, "flatpak", "homepage", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_redirect_url (OstreeRepo *repo,
-                               const char *redirect_url,
-                               GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (redirect_url)
-    g_key_file_set_string (config, "flatpak", "redirect-url", redirect_url);
-  else
-    g_key_file_remove_key (config, "flatpak", "redirect-url", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_authenticator_name (OstreeRepo *repo,
-                                     const char *authenticator_name,
-                                     GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (authenticator_name)
-    g_key_file_set_string (config, "flatpak", "authenticator-name", authenticator_name);
-  else
-    g_key_file_remove_key (config, "flatpak", "authenticator-name", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_authenticator_install (OstreeRepo *repo,
-                                        gboolean authenticator_install,
-                                        GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  g_key_file_set_boolean (config, "flatpak", "authenticator-install", authenticator_install);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_authenticator_option (OstreeRepo *repo,
-                                       const char *key,
-                                       const char *value,
-                                       GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-  g_autofree char *full_key = g_strdup_printf ("authenticator-options.%s", key);
-
-  config = ostree_repo_copy_config (repo);
-
-  if (value)
-    g_key_file_set_string (config, "flatpak", full_key, value);
-  else
-    g_key_file_remove_key (config, "flatpak", full_key, NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_deploy_collection_id (OstreeRepo *repo,
-                                       gboolean    deploy_collection_id,
-                                       GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-  g_key_file_set_boolean (config, "flatpak", "deploy-collection-id", deploy_collection_id);
-  return ostree_repo_write_config (repo, config, error);
-}
-
-gboolean
-flatpak_repo_set_deploy_sideload_collection_id (OstreeRepo *repo,
-                                           gboolean    deploy_collection_id,
-                                           GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-  g_key_file_set_boolean (config, "flatpak", "deploy-sideload-collection-id", deploy_collection_id);
-  return ostree_repo_write_config (repo, config, error);
-}
-
-gboolean
-flatpak_repo_set_gpg_keys (OstreeRepo *repo,
-                           GBytes     *bytes,
-                           GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-  g_autofree char *value_base64 = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  value_base64 = g_base64_encode (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
-
-  g_key_file_set_string (config, "flatpak", "gpg-keys", value_base64);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_default_branch (OstreeRepo *repo,
-                                 const char *branch,
-                                 GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (branch)
-    g_key_file_set_string (config, "flatpak", "default-branch", branch);
-  else
-    g_key_file_remove_key (config, "flatpak", "default-branch", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_collection_id (OstreeRepo *repo,
-                                const char *collection_id,
-                                GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  if (!ostree_repo_set_collection_id (repo, collection_id, error))
-    return FALSE;
-
-  config = ostree_repo_copy_config (repo);
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_set_summary_history_length (OstreeRepo *repo,
-                                         guint       length,
-                                         GError    **error)
-{
-  g_autoptr(GKeyFile) config = NULL;
-
-  config = ostree_repo_copy_config (repo);
-
-  if (length)
-    g_key_file_set_integer (config, "flatpak", "summary-history-length", length);
-  else
-    g_key_file_remove_key (config, "flatpak", "summary-history-length", NULL);
-
-  if (!ostree_repo_write_config (repo, config, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-guint
-flatpak_repo_get_summary_history_length (OstreeRepo *repo)
-{
-  GKeyFile *config = ostree_repo_get_config (repo);
-  int length;
-
-  length = g_key_file_get_integer (config, "flatpak", "sumary-history-length", NULL);
-
-  if (length <= 0)
-    return FLATPAK_SUMMARY_HISTORY_LENGTH_DEFAULT;
-
-  return length;
-}
-
-GVariant *
-flatpak_commit_get_extra_data_sources (GVariant *commitv,
-                                       GError  **error)
-{
-  g_autoptr(GVariant) commit_metadata = NULL;
-  g_autoptr(GVariant) extra_data_sources = NULL;
-
-  commit_metadata = g_variant_get_child_value (commitv, 0);
-  extra_data_sources = g_variant_lookup_value (commit_metadata,
-                                               "xa.extra-data-sources",
-                                               G_VARIANT_TYPE ("a(ayttays)"));
-
-  if (extra_data_sources == NULL)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   _("No extra data sources"));
-      return NULL;
-    }
-
-  return g_steal_pointer (&extra_data_sources);
-}
-
-
-GVariant *
-flatpak_repo_get_extra_data_sources (OstreeRepo   *repo,
-                                     const char   *rev,
-                                     GCancellable *cancellable,
-                                     GError      **error)
-{
-  g_autoptr(GVariant) commitv = NULL;
-
-  if (!ostree_repo_load_variant (repo,
-                                 OSTREE_OBJECT_TYPE_COMMIT,
-                                 rev, &commitv, error))
-    return NULL;
-
-  return flatpak_commit_get_extra_data_sources (commitv, error);
-}
-
-void
-flatpak_repo_parse_extra_data_sources (GVariant      *extra_data_sources,
-                                       int            index,
-                                       const char   **name,
-                                       guint64       *download_size,
-                                       guint64       *installed_size,
-                                       const guchar **sha256,
-                                       const char   **uri)
-{
-  g_autoptr(GVariant) sha256_v = NULL;
-  g_variant_get_child (extra_data_sources, index, "(^aytt@ay&s)",
-                       name,
-                       download_size,
-                       installed_size,
-                       &sha256_v,
-                       uri);
-
-  if (download_size)
-    *download_size = GUINT64_FROM_BE (*download_size);
-
-  if (installed_size)
-    *installed_size = GUINT64_FROM_BE (*installed_size);
-
-  if (sha256)
-    *sha256 = ostree_checksum_bytes_peek (sha256_v);
-}
-
-#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \
-                                   "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev")
-
-static gboolean
-_flatpak_repo_collect_sizes (OstreeRepo   *repo,
-                             GFile        *file,
-                             GFileInfo    *file_info,
-                             guint64      *installed_size,
-                             guint64      *download_size,
-                             GCancellable *cancellable,
-                             GError      **error)
-{
-  g_autoptr(GFileEnumerator) dir_enum = NULL;
-  GFileInfo *child_info_tmp;
-  g_autoptr(GError) temp_error = NULL;
-
-  if (file_info != NULL && g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
-    {
-      const char *checksum = ostree_repo_file_get_checksum (OSTREE_REPO_FILE (file));
-      guint64 obj_size;
-      guint64 file_size = g_file_info_get_size (file_info);
-
-      if (installed_size)
-        *installed_size += ((file_size + 511) / 512) * 512;
-
-      if (download_size)
-        {
-          g_autoptr(GInputStream) input = NULL;
-          GInputStream *base_input;
-          g_autoptr(GError) local_error = NULL;
-
-          if (!ostree_repo_query_object_storage_size (repo,
-                                                      OSTREE_OBJECT_TYPE_FILE, checksum,
-                                                      &obj_size, cancellable, &local_error))
-            {
-              int fd;
-              struct stat stbuf;
-
-              /* Ostree does not look at the staging directory when querying storage
-                 size, so may return a NOT_FOUND error here. We work around this
-                 by loading the object and walking back until we find the original
-                 fd which we can fstat(). */
-              if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-                return FALSE;
-
-              if (!ostree_repo_load_file (repo, checksum,  &input, NULL, NULL, NULL, error))
-                return FALSE;
-
-              base_input = input;
-              while (G_IS_FILTER_INPUT_STREAM (base_input))
-                base_input = g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (base_input));
-
-              if (!G_IS_UNIX_INPUT_STREAM (base_input))
-                return flatpak_fail (error, "Unable to find size of commit %s, not an unix stream", checksum);
-
-              fd = g_unix_input_stream_get_fd (G_UNIX_INPUT_STREAM (base_input));
-
-              if (fstat (fd, &stbuf) != 0)
-                return glnx_throw_errno_prefix (error, "Can't find commit size: ");
-
-              obj_size = stbuf.st_size;
-            }
-
-          *download_size += obj_size;
-        }
-    }
-
-  if (file_info == NULL || g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
-    {
-      dir_enum = g_file_enumerate_children (file, OSTREE_GIO_FAST_QUERYINFO,
-                                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                            cancellable, error);
-      if (!dir_enum)
-        return FALSE;
-
-
-      while ((child_info_tmp = g_file_enumerator_next_file (dir_enum, cancellable, &temp_error)))
-        {
-          g_autoptr(GFileInfo) child_info = child_info_tmp;
-          const char *name = g_file_info_get_name (child_info);
-          g_autoptr(GFile) child = g_file_get_child (file, name);
-
-          if (!_flatpak_repo_collect_sizes (repo, child, child_info, installed_size, download_size, cancellable, error))
-            return FALSE;
-        }
-    }
-
-  return TRUE;
-}
-
-gboolean
-flatpak_repo_collect_sizes (OstreeRepo   *repo,
-                            GFile        *root,
-                            guint64      *installed_size,
-                            guint64      *download_size,
-                            GCancellable *cancellable,
-                            GError      **error)
-{
-  /* Initialize the sums */
-  if (installed_size)
-    *installed_size = 0;
-  if (download_size)
-    *download_size = 0;
-  return _flatpak_repo_collect_sizes (repo, root, NULL, installed_size, download_size, cancellable, error);
-}
-
-
-static void
-flatpak_repo_collect_extra_data_sizes (OstreeRepo *repo,
-                                       const char *rev,
-                                       guint64    *installed_size,
-                                       guint64    *download_size)
-{
-  g_autoptr(GVariant) extra_data_sources = NULL;
-  gsize n_extra_data;
-  int i;
-
-  extra_data_sources = flatpak_repo_get_extra_data_sources (repo, rev, NULL, NULL);
-  if (extra_data_sources == NULL)
-    return;
-
-  n_extra_data = g_variant_n_children (extra_data_sources);
-  if (n_extra_data == 0)
-    return;
-
-  for (i = 0; i < n_extra_data; i++)
-    {
-      guint64 extra_download_size;
-      guint64 extra_installed_size;
-
-      flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
-                                             NULL,
-                                             &extra_download_size,
-                                             &extra_installed_size,
-                                             NULL, NULL);
-      if (installed_size)
-        *installed_size += extra_installed_size;
-      if (download_size)
-        *download_size += extra_download_size;
-    }
-}
-
-/* Loads the old compat summary file from a local repo */
-GVariant *
-flatpak_repo_load_summary (OstreeRepo *repo,
-                           GError    **error)
-{
-  glnx_autofd int fd = -1;
-  g_autoptr(GMappedFile) mfile = NULL;
-  g_autoptr(GBytes) bytes = NULL;
-
-  fd = openat (ostree_repo_get_dfd (repo), "summary", O_RDONLY | O_CLOEXEC);
-  if (fd < 0)
-    {
-      glnx_set_error_from_errno (error);
-      return NULL;
-    }
-
-  mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
-  if (!mfile)
-    return NULL;
-
-  bytes = g_mapped_file_get_bytes (mfile);
-
-  return g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, TRUE));
-}
-
-GVariant *
-flatpak_repo_load_summary_index (OstreeRepo *repo,
-                                 GError    **error)
-{
-  glnx_autofd int fd = -1;
-  g_autoptr(GMappedFile) mfile = NULL;
-  g_autoptr(GBytes) bytes = NULL;
-
-  fd = openat (ostree_repo_get_dfd (repo), "summary.idx", O_RDONLY | O_CLOEXEC);
-  if (fd < 0)
-    {
-      glnx_set_error_from_errno (error);
-      return NULL;
-    }
-
-  mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
-  if (!mfile)
-    return NULL;
-
-  bytes = g_mapped_file_get_bytes (mfile);
-
-  return g_variant_ref_sink (g_variant_new_from_bytes (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT, bytes, TRUE));
-}
-
-static gboolean
-flatpak_repo_save_compat_summary (OstreeRepo   *repo,
-                                  GVariant     *summary,
-                                  time_t       *out_old_sig_mtime,
-                                  GCancellable *cancellable,
-                                  GError      **error)
-{
-  int repo_dfd = ostree_repo_get_dfd (repo);
-  struct stat stbuf;
-  time_t old_sig_mtime = 0;
-  GLnxFileReplaceFlags flags;
-
-  flags = GLNX_FILE_REPLACE_INCREASING_MTIME;
-  if (ostree_repo_get_disable_fsync (repo))
-    flags |= GLNX_FILE_REPLACE_NODATASYNC;
-  else
-    flags |= GLNX_FILE_REPLACE_DATASYNC_NEW;
-
-  if (!glnx_file_replace_contents_at (repo_dfd, "summary",
-                                      g_variant_get_data (summary),
-                                      g_variant_get_size (summary),
-                                      flags,
-                                      cancellable, error))
-    return FALSE;
-
-  if (fstatat (repo_dfd, "summary.sig", &stbuf, AT_SYMLINK_NOFOLLOW) == 0)
-    old_sig_mtime = stbuf.st_mtime;
-
-  if (unlinkat (repo_dfd, "summary.sig", 0) != 0 &&
-      G_UNLIKELY (errno != ENOENT))
-    {
-      glnx_set_error_from_errno (error);
-      return FALSE;
-    }
-
-  *out_old_sig_mtime = old_sig_mtime;
-  return TRUE;
-}
-
-static gboolean
-flatpak_repo_save_summary_index (OstreeRepo   *repo,
-                                 GVariant     *index,
-                                 const char   *index_digest,
-                                 GBytes       *index_sig,
-                                 GCancellable *cancellable,
-                                 GError      **error)
-{
-  int repo_dfd = ostree_repo_get_dfd (repo);
-  GLnxFileReplaceFlags  flags;
-
-  if (index == NULL)
-    {
-      if (unlinkat (repo_dfd, "summary.idx", 0) != 0 &&
-          G_UNLIKELY (errno != ENOENT))
-        {
-          glnx_set_error_from_errno (error);
-          return FALSE;
-        }
-      if (unlinkat (repo_dfd, "summary.idx.sig", 0) != 0 &&
-          G_UNLIKELY (errno != ENOENT))
-        {
-          glnx_set_error_from_errno (error);
-          return FALSE;
-        }
-
-      return TRUE;
-    }
-
-  flags = GLNX_FILE_REPLACE_INCREASING_MTIME;
-  if (ostree_repo_get_disable_fsync (repo))
-    flags |= GLNX_FILE_REPLACE_NODATASYNC;
-  else
-    flags |= GLNX_FILE_REPLACE_DATASYNC_NEW;
-
-  if (index_sig)
-    {
-      g_autofree char *path = g_strconcat ("summaries/", index_digest, ".idx.sig", NULL);
-
-      if (!glnx_shutil_mkdir_p_at (repo_dfd, "summaries",
-                                   0775, cancellable, error))
-        return FALSE;
-
-      if (!glnx_file_replace_contents_at (repo_dfd, path,
-                                          g_bytes_get_data (index_sig, NULL),
-                                          g_bytes_get_size (index_sig),
-                                          flags,
-                                          cancellable, error))
-        return FALSE;
-    }
-
-  if (!glnx_file_replace_contents_at (repo_dfd, "summary.idx",
-                                      g_variant_get_data (index),
-                                      g_variant_get_size (index),
-                                      flags,
-                                      cancellable, error))
-    return FALSE;
-
-  /* Update the non-indexed summary.idx.sig file that was introduced in 1.9.1 but
-   * was made unnecessary in 1.9.3. Lets keep it for a while until everyone updates
-   */
-  if (index_sig)
-    {
-      if (!glnx_file_replace_contents_at (repo_dfd, "summary.idx.sig",
-                                          g_bytes_get_data (index_sig, NULL),
-                                          g_bytes_get_size (index_sig),
-                                          flags,
-                                          cancellable, error))
-        return FALSE;
-    }
-  else
-    {
-      if (unlinkat (repo_dfd, "summary.idx.sig", 0) != 0 &&
-          G_UNLIKELY (errno != ENOENT))
-        {
-          glnx_set_error_from_errno (error);
-          return FALSE;
-        }
-    }
-
-  return TRUE;
-}
-
-GVariant *
-flatpak_repo_load_digested_summary (OstreeRepo *repo,
-                                   const char *digest,
-                                   GError    **error)
-{
-  glnx_autofd int fd = -1;
-  g_autoptr(GMappedFile) mfile = NULL;
-  g_autoptr(GBytes) bytes = NULL;
-  g_autoptr(GBytes) compressed_bytes = NULL;
-  g_autofree char *path = NULL;
-  g_autofree char *filename = NULL;
-
-  filename = g_strconcat (digest, ".gz", NULL);
-  path = g_build_filename ("summaries", filename, NULL);
-
-  fd = openat (ostree_repo_get_dfd (repo), path, O_RDONLY | O_CLOEXEC);
-  if (fd < 0)
-    {
-      glnx_set_error_from_errno (error);
-      return NULL;
-    }
-
-  mfile = g_mapped_file_new_from_fd (fd, FALSE, error);
-  if (!mfile)
-    return NULL;
-
-  compressed_bytes = g_mapped_file_get_bytes (mfile);
-  bytes = flatpak_zlib_decompress_bytes (compressed_bytes, error);
-  if (bytes == NULL)
-    return NULL;
-
-  return g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, TRUE));
-}
-
-static char *
-flatpak_repo_save_digested_summary (OstreeRepo   *repo,
-                                    const char   *name,
-                                    GVariant     *summary,
-                                    GCancellable *cancellable,
-                                    GError      **error)
-{
-  int repo_dfd = ostree_repo_get_dfd (repo);
-  g_autofree char *digest = NULL;
-  g_autofree char *filename = NULL;
-  g_autofree char *path = NULL;
-  g_autoptr(GBytes) data = NULL;
-  g_autoptr(GBytes) compressed_data = NULL;
-  struct stat stbuf;
-
-  if (!glnx_shutil_mkdir_p_at (repo_dfd, "summaries",
-                               0775,
-                               cancellable,
-                               error))
-    return NULL;
-
-  digest = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
-                                        g_variant_get_data (summary),
-                                        g_variant_get_size (summary));
-  filename = g_strconcat (digest, ".gz", NULL);
-
-  path = g_build_filename ("summaries", filename, NULL);
-
-  /* Check for pre-existing (non-truncated) copy and avoid re-writing it */
-  if (fstatat (repo_dfd, path, &stbuf, 0) == 0 &&
-      stbuf.st_size != 0)
-    {
-      g_info ("Reusing digested summary at %s for %s", path, name);
-      return g_steal_pointer (&digest);
-    }
-
-  data = g_variant_get_data_as_bytes (summary);
-  compressed_data = flatpak_zlib_compress_bytes (data, -1, error);
-  if (compressed_data == NULL)
-    return NULL;
-
-  if (!glnx_file_replace_contents_at (repo_dfd, path,
-                                      g_bytes_get_data (compressed_data, NULL),
-                                      g_bytes_get_size (compressed_data),
-                                      ostree_repo_get_disable_fsync (repo) ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
-                                      cancellable, error))
-    return NULL;
-
-  g_info ("Wrote digested summary at %s for %s", path, name);
-  return g_steal_pointer (&digest);
-}
-
-static gboolean
-flatpak_repo_save_digested_summary_delta (OstreeRepo   *repo,
-                                          const char   *from_digest,
-                                          const char   *to_digest,
-                                          GBytes       *delta,
-                                          GCancellable *cancellable,
-                                          GError      **error)
-{
-  int repo_dfd = ostree_repo_get_dfd (repo);
-  g_autofree char *path = NULL;
-  g_autofree char *filename = g_strconcat (from_digest, "-", to_digest, ".delta", NULL);
-  struct stat stbuf;
-
-  if (!glnx_shutil_mkdir_p_at (repo_dfd, "summaries",
-                               0775,
-                               cancellable,
-                               error))
-    return FALSE;
-
-  path = g_build_filename ("summaries", filename, NULL);
-
-  /* Check for pre-existing copy of same size and avoid re-writing it */
-  if (fstatat (repo_dfd, path, &stbuf, 0) == 0 &&
-      stbuf.st_size == g_bytes_get_size (delta))
-    {
-      g_info ("Reusing digested summary-diff for %s", filename);
-      return TRUE;
-    }
-
-  if (!glnx_file_replace_contents_at (repo_dfd, path,
-                                      g_bytes_get_data (delta, NULL),
-                                      g_bytes_get_size (delta),
-                                      ostree_repo_get_disable_fsync (repo) ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
-                                      cancellable, error))
-    return FALSE;
-
-  g_info ("Wrote digested summary delta at %s", path);
-  return TRUE;
-}
-
-
-typedef struct
-{
-  guint64    installed_size;
-  guint64    download_size;
-  char      *metadata_contents;
-  GPtrArray *subsets;
-  GVariant  *sparse_data;
-  gsize      commit_size;
-  guint64    commit_timestamp;
-} CommitData;
-
-static void
-commit_data_free (gpointer data)
-{
-  CommitData *rev_data = data;
-
-  if (rev_data->subsets)
-    g_ptr_array_unref (rev_data->subsets);
-  g_free (rev_data->metadata_contents);
-  if (rev_data->sparse_data)
-    g_variant_unref (rev_data->sparse_data);
-  g_free (rev_data);
-}
-
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (CommitData, commit_data_free);
-
-static GHashTable *
-commit_data_cache_new (void)
-{
-  return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, commit_data_free);
-}
-
-static GHashTable *
-populate_commit_data_cache (OstreeRepo *repo,
-                            GVariant *index_v)
-{
-
-  VarSummaryIndexRef index = var_summary_index_from_gvariant (index_v);
-  VarMetadataRef index_metadata = var_summary_index_get_metadata (index);
-  VarSummaryIndexSubsummariesRef subsummaries = var_summary_index_get_subsummaries (index);
-  gsize n_subsummaries = var_summary_index_subsummaries_get_length (subsummaries);
-  guint32 cache_version;
-  g_autoptr(GHashTable) commit_data_cache = commit_data_cache_new ();
-
-  cache_version = GUINT32_FROM_LE (var_metadata_lookup_uint32 (index_metadata, "xa.cache-version", 0));
-  if (cache_version < FLATPAK_XA_CACHE_VERSION)
-    {
-      /* Need to re-index to get all data */
-      g_info ("Old summary cache version %d, not using cache", cache_version);
-      return NULL;
-    }
-
-  for (gsize i = 0; i < n_subsummaries; i++)
-    {
-      VarSummaryIndexSubsummariesEntryRef entry = var_summary_index_subsummaries_get_at (subsummaries, i);
-      const char *name = var_summary_index_subsummaries_entry_get_key (entry);
-      const char *s;
-      g_autofree char *subset = NULL;
-      VarSubsummaryRef subsummary = var_summary_index_subsummaries_entry_get_value (entry);
-      gsize checksum_bytes_len;
-      const guchar *checksum_bytes;
-      g_autofree char *digest = NULL;
-      g_autoptr(GVariant) summary_v = NULL;
-      VarSummaryRef summary;
-      VarRefMapRef ref_map;
-      gsize n_refs;
-
-      checksum_bytes = var_subsummary_peek_checksum (subsummary, &checksum_bytes_len);
-      if (G_UNLIKELY (checksum_bytes_len != OSTREE_SHA256_DIGEST_LEN))
-        {
-          g_info ("Invalid checksum for digested summary, not using cache");
-          return NULL;
-        }
-      digest = ostree_checksum_from_bytes (checksum_bytes);
-
-      s = strrchr (name, '-');
-      if (s != NULL)
-        subset = g_strndup (name, s - name);
-      else
-        subset = g_strdup ("");
-
-      summary_v = flatpak_repo_load_digested_summary (repo, digest, NULL);
-      if (summary_v == NULL)
-        {
-          g_info ("Failed to load digested summary %s, not using cache", digest);
-          return NULL;
-        }
-
-      /* Note that all summaries refered to by the index is in new format */
-      summary = var_summary_from_gvariant (summary_v);
-      ref_map = var_summary_get_ref_map (summary);
-      n_refs = var_ref_map_get_length (ref_map);
-      for (gsize j = 0; j < n_refs; j++)
-        {
-          VarRefMapEntryRef e = var_ref_map_get_at (ref_map, j);
-          const char *ref = var_ref_map_entry_get_ref (e);
-          VarRefInfoRef info = var_ref_map_entry_get_info (e);
-          VarMetadataRef commit_metadata = var_ref_info_get_metadata (info);
-          guint64 commit_size = var_ref_info_get_commit_size (info);
-          const guchar *commit_bytes;
-          gsize commit_bytes_len;
-          g_autofree char *rev = NULL;
-          CommitData *rev_data;
-          VarVariantRef xa_data_v;
-          VarCacheDataRef xa_data;
-
-          if (!flatpak_is_app_runtime_or_appstream_ref (ref))
-            continue;
-
-          commit_bytes = var_ref_info_peek_checksum (info, &commit_bytes_len);
-          if (G_UNLIKELY (commit_bytes_len != OSTREE_SHA256_DIGEST_LEN))
-            continue;
-
-          if (!var_metadata_lookup (commit_metadata, "xa.data", NULL, &xa_data_v) ||
-              !var_variant_is_type (xa_data_v, G_VARIANT_TYPE ("(tts)")))
-            {
-              g_info ("Missing xa.data for ref %s, not using cache", ref);
-              return NULL;
-            }
-
-          xa_data = var_cache_data_from_variant (xa_data_v);
-
-          rev = ostree_checksum_from_bytes (commit_bytes);
-          rev_data = g_hash_table_lookup (commit_data_cache, rev);
-          if (rev_data == NULL)
-            {
-              g_auto(GVariantBuilder) sparse_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
-              g_variant_builder_init (&sparse_builder, G_VARIANT_TYPE_VARDICT);
-              gboolean has_sparse = FALSE;
-
-              rev_data = g_new0 (CommitData, 1);
-              rev_data->installed_size = var_cache_data_get_installed_size (xa_data);
-              rev_data->download_size = var_cache_data_get_download_size (xa_data);
-              rev_data->metadata_contents = g_strdup (var_cache_data_get_metadata (xa_data));
-              rev_data->commit_size = commit_size;
-              rev_data->commit_timestamp = GUINT64_FROM_BE (var_metadata_lookup_uint64 (commit_metadata, OSTREE_COMMIT_TIMESTAMP2, 0));
-
-              /* Get sparse data */
-              gsize len = var_metadata_get_length (commit_metadata);
-              for (gsize k = 0; k < len; k++)
-                {
-                  VarMetadataEntryRef m = var_metadata_get_at (commit_metadata, k);
-                  const char *m_key = var_metadata_entry_get_key (m);
-                  if (!g_str_has_prefix (m_key, "ot.") &&
-                      !g_str_has_prefix (m_key, "ostree.") &&
-                      strcmp (m_key, "xa.data") != 0)
-                    {
-                      VarVariantRef v = var_metadata_entry_get_value (m);
-                      g_autoptr(GVariant) vv = g_variant_ref_sink (var_variant_dup_to_gvariant (v));
-                      g_autoptr(GVariant) child = g_variant_get_child_value (vv, 0);
-                      g_variant_builder_add (&sparse_builder, "{sv}", m_key, child);
-                      has_sparse = TRUE;
-                    }
-                }
-
-              if (has_sparse)
-                rev_data->sparse_data = g_variant_ref_sink (g_variant_builder_end (&sparse_builder));
-
-              g_hash_table_insert (commit_data_cache, g_strdup (rev), (CommitData *)rev_data);
-            }
-
-          if (*subset != 0)
-            {
-              if (rev_data->subsets == NULL)
-                rev_data->subsets = g_ptr_array_new_with_free_func (g_free);
-
-              if (!flatpak_g_ptr_array_contains_string (rev_data->subsets, subset))
-                g_ptr_array_add (rev_data->subsets, g_strdup (subset));
-            }
-        }
-    }
-
-  return g_steal_pointer (&commit_data_cache);
-}
-
-static CommitData *
-read_commit_data (OstreeRepo   *repo,
-                  const char   *ref,
-                  const char   *rev,
-                  GCancellable *cancellable,
-                  GError      **error)
-{
-  g_autoptr(GFile) root = NULL;
-  g_autoptr(GFile) metadata = NULL;
-  guint64 installed_size = 0;
-  guint64 download_size = 0;
-  g_autofree char *metadata_contents = NULL;
-  g_autofree char *commit = NULL;
-  g_autoptr(GVariant) commit_v = NULL;
-  g_autoptr(GVariant) commit_metadata = NULL;
-  g_autoptr(GPtrArray) subsets = NULL;
-  CommitData *rev_data;
-  const char *eol = NULL;
-  const char *eol_rebase = NULL;
-  int token_type = -1;
-  g_autoptr(GVariant) extra_data_sources = NULL;
-  guint32 n_extra_data = 0;
-  guint64 total_extra_data_download_size = 0;
-  g_autoptr(GVariantIter) subsets_iter = NULL;
-
-  if (!ostree_repo_read_commit (repo, rev, &root, &commit, NULL, error))
-    return NULL;
-
-  if (!ostree_repo_load_commit (repo, commit, &commit_v, NULL, error))
-    return NULL;
-
-  commit_metadata = g_variant_get_child_value (commit_v, 0);
-  if (!g_variant_lookup (commit_metadata, "xa.metadata", "s", &metadata_contents))
-    {
-      metadata = g_file_get_child (root, "metadata");
-      if (!g_file_load_contents (metadata, cancellable, &metadata_contents, NULL, NULL, NULL))
-        metadata_contents = g_strdup ("");
-    }
-
-  if (g_variant_lookup (commit_metadata, "xa.installed-size", "t", &installed_size) &&
-      g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
-    {
-      installed_size = GUINT64_FROM_BE (installed_size);
-      download_size = GUINT64_FROM_BE (download_size);
-    }
-  else
-    {
-      if (!flatpak_repo_collect_sizes (repo, root, &installed_size, &download_size, cancellable, error))
-        return NULL;
-    }
-
-  if (g_variant_lookup (commit_metadata, "xa.subsets", "as", &subsets_iter))
-    {
-      const char *subset;
-      subsets = g_ptr_array_new_with_free_func (g_free);
-      while (g_variant_iter_next (subsets_iter, "&s", &subset))
-        g_ptr_array_add (subsets, g_strdup (subset));
-    }
-
-  flatpak_repo_collect_extra_data_sizes (repo, rev, &installed_size, &download_size);
-
-  rev_data = g_new0 (CommitData, 1);
-  rev_data->installed_size = installed_size;
-  rev_data->download_size = download_size;
-  rev_data->metadata_contents = g_steal_pointer (&metadata_contents);
-  rev_data->subsets = g_steal_pointer (&subsets);
-  rev_data->commit_size = g_variant_get_size (commit_v);
-  rev_data->commit_timestamp = ostree_commit_get_timestamp (commit_v);
-
-  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, "&s", &eol);
-  g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, "&s", &eol_rebase);
-  if (g_variant_lookup (commit_metadata, "xa.token-type", "i", &token_type))
-    token_type = GINT32_FROM_LE(token_type);
-
-  extra_data_sources = flatpak_commit_get_extra_data_sources (commit_v, NULL);
-  if (extra_data_sources)
-    {
-      n_extra_data = g_variant_n_children (extra_data_sources);
-      for (int i = 0; i < n_extra_data; i++)
-        {
-          guint64 extra_download_size;
-          flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
-                                                 NULL,
-                                                 &extra_download_size,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL);
-          total_extra_data_download_size += extra_download_size;
-        }
-    }
-
-  if (eol || eol_rebase || token_type >= 0 || n_extra_data > 0)
-    {
-      g_auto(GVariantBuilder) sparse_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
-      g_variant_builder_init (&sparse_builder, G_VARIANT_TYPE_VARDICT);
-      if (eol)
-        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_ENDOFLINE, g_variant_new_string (eol));
-      if (eol_rebase)
-        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_ENDOFLINE_REBASE, g_variant_new_string (eol_rebase));
-      if (token_type >= 0)
-        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE, g_variant_new_int32 (GINT32_TO_LE(token_type)));
-      if (n_extra_data > 0)
-        g_variant_builder_add (&sparse_builder, "{sv}", FLATPAK_SPARSE_CACHE_KEY_EXTRA_DATA_SIZE,
-                               g_variant_new ("(ut)", GUINT32_TO_LE(n_extra_data), GUINT64_TO_LE(total_extra_data_download_size)));
-
-      rev_data->sparse_data = g_variant_ref_sink (g_variant_builder_end (&sparse_builder));
-    }
-
-  return rev_data;
-}
-
-static void
-_ostree_parse_delta_name (const char *delta_name,
-                          char      **out_from,
-                          char      **out_to)
-{
-  g_auto(GStrv) parts = g_strsplit (delta_name, "-", 2);
-
-  if (parts[0] && parts[1])
-    {
-      *out_from = g_steal_pointer (&parts[0]);
-      *out_to = g_steal_pointer (&parts[1]);
-    }
-  else
-    {
-      *out_from = NULL;
-      *out_to = g_steal_pointer (&parts[0]);
-    }
-}
-
-static GString *
-static_delta_path_base (const char *dir,
-                        const char *from,
-                        const char *to)
-{
-  guint8 csum_to[OSTREE_SHA256_DIGEST_LEN];
-  char to_b64[44];
-  guint8 csum_to_copy[OSTREE_SHA256_DIGEST_LEN];
-  GString *ret = g_string_new (dir);
-
-  ostree_checksum_inplace_to_bytes (to, csum_to);
-  ostree_checksum_b64_inplace_from_bytes (csum_to, to_b64);
-  ostree_checksum_b64_inplace_to_bytes (to_b64, csum_to_copy);
-
-  g_assert (memcmp (csum_to, csum_to_copy, OSTREE_SHA256_DIGEST_LEN) == 0);
-
-  if (from != NULL)
-    {
-      guint8 csum_from[OSTREE_SHA256_DIGEST_LEN];
-      char from_b64[44];
-
-      ostree_checksum_inplace_to_bytes (from, csum_from);
-      ostree_checksum_b64_inplace_from_bytes (csum_from, from_b64);
-
-      g_string_append_c (ret, from_b64[0]);
-      g_string_append_c (ret, from_b64[1]);
-      g_string_append_c (ret, '/');
-      g_string_append (ret, from_b64 + 2);
-      g_string_append_c (ret, '-');
-    }
-
-  g_string_append_c (ret, to_b64[0]);
-  g_string_append_c (ret, to_b64[1]);
-  if (from == NULL)
-    g_string_append_c (ret, '/');
-  g_string_append (ret, to_b64 + 2);
-
-  return ret;
-}
-
-static char *
-_ostree_get_relative_static_delta_path (const char *from,
-                                        const char *to,
-                                        const char *target)
-{
-  GString *ret = static_delta_path_base ("deltas/", from, to);
-
-  if (target != NULL)
-    {
-      g_string_append_c (ret, '/');
-      g_string_append (ret, target);
-    }
-
-  return g_string_free (ret, FALSE);
-}
-
-static char *
-_ostree_get_relative_static_delta_superblock_path (const char        *from,
-                                                   const char        *to)
-{
-  return _ostree_get_relative_static_delta_path (from, to, "superblock");
-}
-
-static GVariant *
-_ostree_repo_static_delta_superblock_digest (OstreeRepo    *repo,
-                                             const char    *from,
-                                             const char    *to,
-                                             GCancellable  *cancellable,
-                                             GError       **error)
-{
-  g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to);
-  glnx_autofd int fd = -1;
-  guint8 digest[OSTREE_SHA256_DIGEST_LEN];
-  gsize len;
-  gpointer data = NULL;
-
-  if (!glnx_openat_rdonly (ostree_repo_get_dfd (repo), superblock, TRUE, &fd, error))
-    return NULL;
-
-  g_autoptr(GBytes) superblock_content = glnx_fd_readall_bytes (fd, cancellable, error);
-  if (!superblock_content)
-    return NULL;
-
-  g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
-  g_checksum_update (checksum, g_bytes_get_data (superblock_content, NULL), g_bytes_get_size (superblock_content));
-  len = sizeof digest;
-  g_checksum_get_digest (checksum, digest, &len);
-
-  data = g_memdup2 (digest, len);
-  return g_variant_new_from_data (G_VARIANT_TYPE ("ay"),
-                                  data, len,
-                                  FALSE, g_free, data);
-}
-
-static char *
-appstream_ref_get_subset (const char *ref)
-{
-  if (!g_str_has_prefix (ref, "appstream2/"))
-    return NULL;
-
-  const char *rest = ref + strlen ("appstream2/");
-  const char *dash = strrchr (rest, '-');
-  if (dash == NULL)
-    return NULL;
-
-  return g_strndup (rest, dash - rest);
-}
-
-char *
-flatpak_get_arch_for_ref (const char *ref)
-{
-  if (g_str_has_prefix (ref, "appstream/") ||
-      g_str_has_prefix (ref, "appstream2/"))
-    {
-      const char *rest = strchr (ref, '/') + 1; /* Guaranteed to exist per above check */
-      const char *dash = strrchr (rest, '-'); /*  Subset appstream refs are appstream2/$subset-$arch */
-      if (dash != NULL)
-        rest = dash + 1;
-      return g_strdup (rest);
-    }
-    else if (g_str_has_prefix (ref, "app/") ||
-      g_str_has_prefix (ref, "runtime/"))
-    {
-      const char *slash;
-      const char *arch;
-
-      slash = strchr (ref, '/') + 1; /* Guaranteed to exist per above check */
-      slash = strchr (slash, '/'); /* Skip id */
-      if (slash == NULL)
-        return NULL;
-      arch = slash + 1;
-
-      slash = strchr (arch, '/'); /* skip to end arch */
-      if (slash == NULL)
-        return NULL;
-
-      return g_strndup (arch, slash - arch);
-    }
-
-  return NULL;
-}
-
-typedef enum {
-  DIFF_OP_KIND_RESUSE_OLD,
-  DIFF_OP_KIND_SKIP_OLD,
-  DIFF_OP_KIND_DATA,
-} DiffOpKind;
-
-typedef struct {
-  DiffOpKind kind;
-  gsize size;
-} DiffOp;
-
-typedef struct {
-  const guchar *old_data;
-  const guchar *new_data;
-
-  GArray *ops;
-  GArray *data;
-
-  gsize last_old_offset;
-  gsize last_new_offset;
-} DiffData;
-
-static gsize
-match_bytes_at_start (const guchar *data1,
-                      gsize data1_len,
-                      const guchar *data2,
-                      gsize data2_len)
-{
-  gsize len = 0;
-  gsize max_len = MIN (data1_len, data2_len);
-
-  while (len < max_len)
-    {
-      if (*data1 != *data2)
-        break;
-      data1++;
-      data2++;
-      len++;
-    }
-  return len;
-}
-
-static gsize
-match_bytes_at_end (const guchar *data1,
-                    gsize data1_len,
-                    const guchar *data2,
-                    gsize data2_len)
-{
-  gsize len = 0;
-  gsize max_len = MIN (data1_len, data2_len);
-
-  data1 += data1_len - 1;
-  data2 += data2_len - 1;
-
-  while (len < max_len)
-    {
-      if (*data1 != *data2)
-        break;
-      data1--;
-      data2--;
-      len++;
-    }
-  return len;
-}
-
-static DiffOp *
-diff_ensure_op (DiffData *data,
-                DiffOpKind kind)
-{
-  if (data->ops->len == 0 ||
-      g_array_index (data->ops, DiffOp, data->ops->len-1).kind != kind)
-    {
-      DiffOp op = {kind, 0};
-      g_array_append_val (data->ops, op);
-    }
-
-  return &g_array_index (data->ops, DiffOp, data->ops->len-1);
-}
-
-static void
-diff_emit_reuse (DiffData *data,
-                 gsize size)
-{
-  DiffOp *op;
-
-  if (size == 0)
-    return;
-
-  op = diff_ensure_op (data, DIFF_OP_KIND_RESUSE_OLD);
-  op->size += size;
-}
-
-static void
-diff_emit_skip (DiffData *data,
-                gsize size)
-{
-  DiffOp *op;
-
-  if (size == 0)
-    return;
-
-  op = diff_ensure_op (data, DIFF_OP_KIND_SKIP_OLD);
-  op->size += size;
-}
-
-static void
-diff_emit_data (DiffData *data,
-                gsize size,
-                const guchar *new_data)
-{
-  DiffOp *op;
-
-  if (size == 0)
-    return;
-
-  op = diff_ensure_op (data, DIFF_OP_KIND_DATA);
-  op->size += size;
-
-  g_array_append_vals (data->data, new_data, size);
-}
-
-static GBytes *
-diff_encode (DiffData *data, GError **error)
-{
-  g_autoptr(GOutputStream) mem = g_memory_output_stream_new_resizable ();
-  g_autoptr(GDataOutputStream) out = g_data_output_stream_new (mem);
-  gsize ops_count = 0;
-
-  g_data_output_stream_set_byte_order (out, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
-
-  /* Header */
-  if (!g_output_stream_write_all (G_OUTPUT_STREAM (out),
-                                  FLATPAK_SUMMARY_DIFF_HEADER, 4,
-                                  NULL, NULL, error))
-    return NULL;
-
-  /* Write the ops count placeholder */
-  if (!g_data_output_stream_put_uint32 (out, 0, NULL, error))
-    return NULL;
-
-  for (gsize i = 0; i < data->ops->len; i++)
-    {
-      DiffOp *op = &g_array_index (data->ops, DiffOp, i);
-      gsize size = op->size;
-
-      while (size > 0)
-        {
-          /* We leave a nibble at the top for the op */
-          guint32 opdata = (guint64)size & 0x0fffffff;
-          size -= opdata;
-
-          opdata = opdata | ((0xf & op->kind) << 28);
-
-          if (!g_data_output_stream_put_uint32 (out, opdata, NULL, error))
-            return NULL;
-          ops_count++;
-        }
-    }
-
-  /* Then add the data */
-  if (data->data->len > 0 &&
-      !g_output_stream_write_all (G_OUTPUT_STREAM (out),
-                                  data->data->data, data->data->len,
-                                  NULL, NULL, error))
-    return NULL;
-
-  /* Back-patch in the ops count */
-  if (!g_seekable_seek (G_SEEKABLE(out), 4, G_SEEK_SET, NULL, error))
-    return NULL;
-
-  if (!g_data_output_stream_put_uint32 (out, ops_count, NULL, error))
-    return NULL;
-
-  if (!g_output_stream_close (G_OUTPUT_STREAM (out), NULL, error))
-    return NULL;
-
-  return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mem));
-}
-
-static void
-diff_consume_block2 (DiffData *data,
-                     gsize consume_old_offset,
-                     gsize consume_old_size,
-                     gsize produce_new_offset,
-                     gsize produce_new_size)
-{
-  /* We consumed $consume_old_size bytes from $consume_old_offset to
-     produce $produce_new_size bytes at $produce_new_size */
-
-  /* First we copy old data for any matching prefix of the block */
-
-  gsize prefix_len = match_bytes_at_start (data->old_data + consume_old_offset, consume_old_size,
-                                           data->new_data + produce_new_offset, produce_new_size);
-  diff_emit_reuse (data, prefix_len);
-
-  consume_old_size -= prefix_len;
-  consume_old_offset += prefix_len;
-
-  produce_new_size -= prefix_len;
-  produce_new_offset += prefix_len;
-
-  /* Then we find the matching suffix for the rest */
-  gsize suffix_len = match_bytes_at_end (data->old_data + consume_old_offset, consume_old_size,
-                                         data->new_data + produce_new_offset, produce_new_size);
-
-  /* Skip source data until suffix match */
-  diff_emit_skip (data, consume_old_size - suffix_len);
-
-  /* Copy new data until suffix match */
-  diff_emit_data (data, produce_new_size - suffix_len, data->new_data + produce_new_offset);
-
-  diff_emit_reuse (data, suffix_len);
-}
-
-static void
-diff_consume_block (DiffData *data,
-                    gssize consume_old_offset,
-                    gsize consume_old_size,
-                    gssize produce_new_offset,
-                    gsize produce_new_size)
-{
-  if (consume_old_offset == -1)
-    consume_old_offset = data->last_old_offset;
-  if (produce_new_offset == -1)
-    produce_new_offset = data->last_new_offset;
-
-  /* We consumed $consume_old_size bytes from $consume_old_offset to
-   * produce $produce_new_size bytes at $produce_new_size, however
-   * while the emitted blocks are in order they may not cover the
-   * every byte, so we emit the inbetwen blocks separately. */
-
-  if (consume_old_offset != data->last_old_offset ||
-      produce_new_offset != data->last_new_offset)
-    diff_consume_block2 (data,
-                         data->last_old_offset, consume_old_offset - data->last_old_offset ,
-                         data->last_new_offset, produce_new_offset - data->last_new_offset);
-
-  diff_consume_block2 (data,
-                       consume_old_offset, consume_old_size,
-                       produce_new_offset, produce_new_size);
-
-  data->last_old_offset = consume_old_offset + consume_old_size;
-  data->last_new_offset = produce_new_offset + produce_new_size;
-}
-
-GBytes *
-flatpak_summary_apply_diff (GBytes *old,
-                            GBytes *diff,
-                            GError **error)
-{
-  g_autoptr(GBytes) uncompressed = NULL;
-  const guchar *diffdata;
-  gsize diff_size;
-  guint32 *ops;
-  guint32 n_ops;
-  gsize data_offset;
-  gsize data_size;
-  const guchar *data;
-  const guchar *old_data = g_bytes_get_data (old, NULL);
-  gsize old_size = g_bytes_get_size (old);
-  g_autoptr(GByteArray) res = g_byte_array_new ();
-
-  uncompressed = flatpak_zlib_decompress_bytes (diff, error);
-  if (uncompressed == NULL)
-    {
-      g_prefix_error (error, "Invalid summary diff: ");
-      return NULL;
-    }
-
-  diffdata = g_bytes_get_data (uncompressed, NULL);
-  diff_size = g_bytes_get_size (uncompressed);
-
-  if (diff_size < 8 ||
-      memcmp (diffdata, FLATPAK_SUMMARY_DIFF_HEADER, 4) != 0)
-    {
-      flatpak_fail (error, "Invalid summary diff");
-      return NULL;
-    }
-
-  n_ops = GUINT32_FROM_LE (*(guint32 *)(diffdata+4));
-  ops = (guint32 *)(diffdata+8);
-
-  data_offset = 4 + 4 + 4 * n_ops;
-
-  /* All ops must fit in diff, and avoid wrapping the multiply */
-  if (data_offset > diff_size ||
-      (data_offset - 4 - 4) / 4 != n_ops)
-    {
-      flatpak_fail (error, "Invalid summary diff");
-      return NULL;
-    }
-
-  data = diffdata + data_offset;
-  data_size = diff_size - data_offset;
-
-  for (gsize i = 0; i < n_ops; i++)
-    {
-      guint32 opdata = GUINT32_FROM_LE (ops[i]);
-      guint32 kind = (opdata & 0xf0000000) >> 28;
-      guint32 size = opdata & 0x0fffffff;
-
-      switch (kind)
-        {
-        case DIFF_OP_KIND_RESUSE_OLD:
-          if (size > old_size)
-            {
-              flatpak_fail (error, "Invalid summary diff");
-              return NULL;
-            }
-          g_byte_array_append (res, old_data, size);
-          old_data += size;
-          old_size -= size;
-          break;
-        case DIFF_OP_KIND_SKIP_OLD:
-          if (size > old_size)
-            {
-              flatpak_fail (error, "Invalid summary diff");
-              return NULL;
-            }
-          old_data += size;
-          old_size -= size;
-          break;
-        case DIFF_OP_KIND_DATA:
-          if (size > data_size)
-            {
-              flatpak_fail (error, "Invalid summary diff");
-              return NULL;
-            }
-          g_byte_array_append (res, data, size);
-          data += size;
-          data_size -= size;
-          break;
-        default:
-          flatpak_fail (error, "Invalid summary diff");
-          return NULL;
-        }
-    }
-
-  return g_byte_array_free_to_bytes (g_steal_pointer (&res));
-}
-
-
-static GBytes *
-flatpak_summary_generate_diff (GVariant *old_v,
-                               GVariant *new_v,
-                               GError **error)
-{
-  VarSummaryRef new, old;
-  VarRefMapRef new_refs, old_refs;
-  VarRefMapEntryRef new_entry, old_entry;
-  gsize new_len, old_len;
-  int new_i, old_i;
-  const char *old_ref, *new_ref;
-  g_autoptr(GArray) ops = g_array_new (FALSE, TRUE, sizeof (DiffOp));
-  g_autoptr(GArray) data_bytes = g_array_new (FALSE, TRUE, 1);
-  g_autoptr(GBytes) diff_uncompressed = NULL;
-  g_autoptr(GBytes) diff_compressed = NULL;
-  DiffData data = {
-    g_variant_get_data (old_v),
-    g_variant_get_data (new_v),
-    ops,
-    data_bytes,
-  };
-
-  new = var_summary_from_gvariant (new_v);
-  old = var_summary_from_gvariant (old_v);
-
-  new_refs = var_summary_get_ref_map (new);
-  old_refs = var_summary_get_ref_map (old);
-
-  new_len = var_ref_map_get_length (new_refs);
-  old_len = var_ref_map_get_length (old_refs);
-
-  new_i = old_i = 0;
-  while (new_i < new_len && old_i < old_len)
-    {
-      if (new_i == new_len)
-        {
-          /* Just old left */
-          old_entry = var_ref_map_get_at (old_refs, old_i);
-          old_ref = var_ref_map_entry_get_ref (old_entry);
-          old_i++;
-          diff_consume_block (&data,
-                              -1, 0,
-                              (const guchar *)new_entry.base - (const guchar *)new.base, new_entry.size);
-        }
-      else if (old_i == old_len)
-        {
-          /* Just new left */
-          new_entry = var_ref_map_get_at (new_refs, new_i);
-          new_ref = var_ref_map_entry_get_ref (new_entry);
-          diff_consume_block (&data,
-                              (const guchar *)old_entry.base - (const guchar *)old.base, old_entry.size,
-                              -1, 0);
-
-          new_i++;
-        }
-      else
-        {
-          new_entry = var_ref_map_get_at (new_refs, new_i);
-          new_ref = var_ref_map_entry_get_ref (new_entry);
-
-          old_entry = var_ref_map_get_at (old_refs, old_i);
-          old_ref = var_ref_map_entry_get_ref (old_entry);
-
-          int cmp = strcmp (new_ref, old_ref);
-          if (cmp == 0)
-            {
-              /* same ref */
-              diff_consume_block (&data,
-                                  (const guchar *)old_entry.base - (const guchar *)old.base, old_entry.size,
-                                  (const guchar *)new_entry.base - (const guchar *)new.base, new_entry.size);
-              old_i++;
-              new_i++;
-            }
-          else if (cmp < 0)
-            {
-              /* new added */
-              diff_consume_block (&data,
-                                  -1, 0,
-                                  (const guchar *)new_entry.base - (const guchar *)new.base, new_entry.size);
-              new_i++;
-            }
-          else
-            {
-              /* old removed */
-              diff_consume_block (&data,
-                                  (const guchar *)old_entry.base - (const guchar *)old.base, old_entry.size,
-                                  -1, 0);
-              old_i++;
-            }
-        }
-    }
-
-  /* Flush till the end */
-  diff_consume_block2 (&data,
-                       data.last_old_offset, old.size - data.last_old_offset,
-                       data.last_new_offset, new.size - data.last_new_offset);
-
-  diff_uncompressed = diff_encode (&data, error);
-  if (diff_uncompressed == NULL)
-    return NULL;
-
-  diff_compressed = flatpak_zlib_compress_bytes (diff_uncompressed, 9, error);
-  if (diff_compressed == NULL)
-    return NULL;
-
-#ifdef VALIDATE_DIFF
-  {
-    g_autoptr(GError) apply_error = NULL;
-    g_autoptr(GBytes) old_bytes = g_variant_get_data_as_bytes (old_v);
-    g_autoptr(GBytes) new_bytes = g_variant_get_data_as_bytes (new_v);
-    g_autoptr(GBytes) applied = flatpak_summary_apply_diff (old_bytes, diff_compressed, &apply_error);
-    g_assert (applied != NULL);
-    g_assert (g_bytes_equal (applied, new_bytes));
-  }
-#endif
-
-  return g_steal_pointer (&diff_compressed);
-}
-
-static void
-variant_dict_merge (GVariantDict *dict,
-                    GVariant *to_merge)
-{
-  GVariantIter iter;
-  gchar *key;
-  GVariant *value;
-
-  if (to_merge)
-    {
-      g_variant_iter_init (&iter, to_merge);
-      while (g_variant_iter_next (&iter, "{sv}", &key, &value))
-        {
-          g_variant_dict_insert_value (dict, key, value);
-          g_variant_unref (value);
-          g_free (key);
-        }
-    }
-}
-
-static void
-add_summary_metadata (OstreeRepo   *repo,
-                      GVariantBuilder *metadata_builder)
-{
-  GKeyFile *config;
-  g_autofree char *title = NULL;
-  g_autofree char *comment = NULL;
-  g_autofree char *description = NULL;
-  g_autofree char *homepage = NULL;
-  g_autofree char *icon = NULL;
-  g_autofree char *redirect_url = NULL;
-  g_autofree char *default_branch = NULL;
-  g_autofree char *remote_mode_str = NULL;
-  g_autofree char *authenticator_name = NULL;
-  g_autofree char *gpg_keys = NULL;
-  g_auto(GStrv) config_keys = NULL;
-  int authenticator_install = -1;
-  const char *collection_id;
-  gboolean deploy_collection_id = FALSE;
-  gboolean deploy_sideload_collection_id = FALSE;
-  gboolean tombstone_commits = FALSE;
-
-  config = ostree_repo_get_config (repo);
-
-  if (config)
-    {
-      remote_mode_str = g_key_file_get_string (config, "core", "mode", NULL);
-      tombstone_commits = g_key_file_get_boolean (config, "core", "tombstone-commits", NULL);
-
-      title = g_key_file_get_string (config, "flatpak", "title", NULL);
-      comment = g_key_file_get_string (config, "flatpak", "comment", NULL);
-      description = g_key_file_get_string (config, "flatpak", "description", NULL);
-      homepage = g_key_file_get_string (config, "flatpak", "homepage", NULL);
-      icon = g_key_file_get_string (config, "flatpak", "icon", NULL);
-      default_branch = g_key_file_get_string (config, "flatpak", "default-branch", NULL);
-      gpg_keys = g_key_file_get_string (config, "flatpak", "gpg-keys", NULL);
-      redirect_url = g_key_file_get_string (config, "flatpak", "redirect-url", NULL);
-      deploy_sideload_collection_id = g_key_file_get_boolean (config, "flatpak", "deploy-sideload-collection-id", NULL);
-      deploy_collection_id = g_key_file_get_boolean (config, "flatpak", "deploy-collection-id", NULL);
-      authenticator_name = g_key_file_get_string (config, "flatpak", "authenticator-name", NULL);
-      if (g_key_file_has_key (config, "flatpak", "authenticator-install", NULL))
-        authenticator_install = g_key_file_get_boolean (config, "flatpak", "authenticator-install", NULL);
-
-      config_keys = g_key_file_get_keys (config, "flatpak", NULL, NULL);
-    }
-
-  collection_id = ostree_repo_get_collection_id (repo);
-
-  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.mode",
-                         g_variant_new_string (remote_mode_str ? remote_mode_str : "bare"));
-  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.tombstone-commits",
-                         g_variant_new_boolean (tombstone_commits));
-  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.indexed-deltas",
-                         g_variant_new_boolean (TRUE));
-  g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.last-modified",
-                         g_variant_new_uint64 (GUINT64_TO_BE (g_get_real_time () / G_USEC_PER_SEC)));
-
-  if (collection_id)
-    g_variant_builder_add (metadata_builder, "{sv}", "ostree.summary.collection-id",
-                           g_variant_new_string (collection_id));
-
-  if (title)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.title",
-                           g_variant_new_string (title));
-
-  if (comment)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.comment",
-                           g_variant_new_string (comment));
-
-  if (description)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.description",
-                           g_variant_new_string (description));
-
-  if (homepage)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.homepage",
-                           g_variant_new_string (homepage));
-
-  if (icon)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.icon",
-                           g_variant_new_string (icon));
-
-  if (redirect_url)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.redirect-url",
-                           g_variant_new_string (redirect_url));
-
-  if (default_branch)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.default-branch",
-                           g_variant_new_string (default_branch));
-
-  if (deploy_collection_id && collection_id != NULL)
-    g_variant_builder_add (metadata_builder, "{sv}", OSTREE_META_KEY_DEPLOY_COLLECTION_ID,
-                           g_variant_new_string (collection_id));
-  else if (deploy_sideload_collection_id && collection_id != NULL)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.deploy-collection-id",
-                           g_variant_new_string (collection_id));
-  else if (deploy_collection_id)
-    g_info ("Ignoring deploy-collection-id=true because no collection ID is set.");
-
-  if (authenticator_name)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.authenticator-name",
-                           g_variant_new_string (authenticator_name));
-
-  if (authenticator_install != -1)
-    g_variant_builder_add (metadata_builder, "{sv}", "xa.authenticator-install",
-                           g_variant_new_boolean (authenticator_install));
-
-  g_variant_builder_add (metadata_builder, "{sv}", "xa.cache-version",
-                         g_variant_new_uint32 (GUINT32_TO_LE (FLATPAK_XA_CACHE_VERSION)));
-
-  if (config_keys != NULL)
-    {
-      for (int i = 0; config_keys[i] != NULL; i++)
-        {
-          const char *key = config_keys[i];
-          g_autofree char *xa_key = NULL;
-          g_autofree char *value = NULL;
-
-          if (!g_str_has_prefix (key, "authenticator-options."))
-            continue;
-
-          value = g_key_file_get_string (config, "flatpak", key, NULL);
-          if (value == NULL)
-            continue;
-
-          xa_key = g_strconcat ("xa.", key, NULL);
-          g_variant_builder_add (metadata_builder, "{sv}", xa_key,
-                                 g_variant_new_string (value));
-        }
-    }
-
-  if (gpg_keys)
-    {
-      guchar *decoded;
-      gsize decoded_len;
-
-      gpg_keys = g_strstrip (gpg_keys);
-      decoded = g_base64_decode (gpg_keys, &decoded_len);
-
-      g_variant_builder_add (metadata_builder, "{sv}", "xa.gpg-keys",
-                             g_variant_new_from_data (G_VARIANT_TYPE ("ay"), decoded, decoded_len,
-                                                      TRUE, (GDestroyNotify) g_free, decoded));
-    }
-}
-
-static GVariant *
-generate_summary (OstreeRepo   *repo,
-                  gboolean      compat_format,
-                  GHashTable   *refs,
-                  GHashTable   *commit_data_cache,
-                  GPtrArray    *delta_names,
-                  const char   *subset,
-                  const char  **summary_arches,
-                  GCancellable *cancellable,
-                  GError      **error)
-{
-  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
-  g_autoptr(GVariantBuilder) ref_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{s(tts)}"));
-  g_autoptr(GVariantBuilder) ref_sparse_data_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sa{sv}}"));
-  g_autoptr(GVariantBuilder) refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))"));
-  g_autoptr(GVariantBuilder) summary_builder = g_variant_builder_new (OSTREE_SUMMARY_GVARIANT_FORMAT);
-  g_autoptr(GHashTable) summary_arches_ht = NULL;
-  g_autoptr(GHashTable) commits = NULL;
-  g_autoptr(GList) ordered_keys = NULL;
-  GList *l = NULL;
-
-  /* In the new format this goes in the summary index instead */
-  if (compat_format)
-    add_summary_metadata (repo, metadata_builder);
-
-  ordered_keys = g_hash_table_get_keys (refs);
-  ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp);
-
-  if (summary_arches)
-    {
-      summary_arches_ht = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
-      for (int i = 0; summary_arches[i] != NULL; i++)
-        {
-          const char *arch = summary_arches[i];
-
-          g_hash_table_add (summary_arches_ht, (char *)arch);
-        }
-    }
-
-  /* Compute which commits to keep */
-  commits = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); /* strings owned by ref */
-  for (l = ordered_keys; l; l = l->next)
-    {
-      const char *ref = l->data;
-      const char *rev = g_hash_table_lookup (refs, ref);
-      g_autofree char *arch = NULL;
-      const CommitData *rev_data = NULL;
-
-      if (summary_arches)
-        {
-          /* NOTE: Non-arched (unknown) refs get into all summary versions */
-          arch = flatpak_get_arch_for_ref (ref);
-          if (arch != NULL && !g_hash_table_contains (summary_arches_ht, arch))
-            continue; /* Filter this ref by arch */
-        }
-
-      rev_data = g_hash_table_lookup (commit_data_cache, rev);
-      if (*subset != 0)
-        {
-          /* Subset summaries keep the appstream2/$subset-$arch, and have no appstream/ compat branch */
-
-          if (g_str_has_prefix (ref, "appstream/"))
-            {
-              continue; /* No compat branch in subsets */
-            }
-          else if (g_str_has_prefix (ref, "appstream2/"))
-            {
-              g_autofree char *ref_subset = appstream_ref_get_subset (ref);
-              if (ref_subset == NULL)
-                continue; /* Non-subset, ignore */
-
-              if (strcmp (subset, ref_subset) != 0)
-                continue; /* Different subset, ignore */
-
-              /* Otherwise, keep */
-            }
-          else if (rev_data)
-            {
-              if (rev_data->subsets == NULL ||
-                  !flatpak_g_ptr_array_contains_string (rev_data->subsets, subset))
-                continue; /* Ref is not in this subset */
-            }
-        }
-      else
-        {
-          /* non-subset, keep everything but subset appstream refs */
-
-          g_autofree char *ref_subset = appstream_ref_get_subset (ref);
-          if (ref_subset != NULL)
-            continue; /* Subset appstream ref, ignore */
-        }
-
-      g_hash_table_add (commits, (char *)rev);
-    }
-
-  /* Create refs list, metadata and sparse_data */
-  for (l = ordered_keys; l; l = l->next)
-    {
-      const char *ref = l->data;
-      const char *rev = g_hash_table_lookup (refs, ref);
-      const CommitData *rev_data = NULL;
-      g_auto(GVariantDict) commit_metadata_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
-      guint64 commit_size;
-      guint64 commit_timestamp;
-
-      if (!g_hash_table_contains (commits, rev))
-        continue; /* Filter out commit (by arch & subset) */
-
-      if (flatpak_is_app_runtime_or_appstream_ref (ref))
-        rev_data = g_hash_table_lookup (commit_data_cache, rev);
-
-      if (rev_data != NULL)
-        {
-          commit_size = rev_data->commit_size;
-          commit_timestamp = rev_data->commit_timestamp;
-        }
-      else
-        {
-          g_autoptr(GVariant) commit_obj = NULL;
-          if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, rev, &commit_obj, error))
-            return NULL;
-          commit_size = g_variant_get_size (commit_obj);
-          commit_timestamp = ostree_commit_get_timestamp (commit_obj);
-        }
-
-      g_variant_dict_init (&commit_metadata_builder, NULL);
-      if (!compat_format && rev_data)
-        {
-          g_variant_dict_insert (&commit_metadata_builder, "xa.data", "(tts)",
-                                 GUINT64_TO_BE (rev_data->installed_size),
-                                 GUINT64_TO_BE (rev_data->download_size),
-                                 rev_data->metadata_contents);
-          variant_dict_merge (&commit_metadata_builder, rev_data->sparse_data);
-        }
-
-      /* For the new format summary we use a shorter name for the timestamp to save space */
-      g_variant_dict_insert_value (&commit_metadata_builder,
-                                   compat_format ? OSTREE_COMMIT_TIMESTAMP  : OSTREE_COMMIT_TIMESTAMP2,
-                                   g_variant_new_uint64 (GUINT64_TO_BE (commit_timestamp)));
-
-      g_variant_builder_add_value (refs_builder,
-                                   g_variant_new ("(s(t@ay@a{sv}))", ref,
-                                                  commit_size,
-                                                  ostree_checksum_to_bytes_v (rev),
-                                                  g_variant_dict_end (&commit_metadata_builder)));
-
-      if (compat_format && rev_data)
-        {
-          g_variant_builder_add (ref_data_builder, "{s(tts)}",
-                                 ref,
-                                 GUINT64_TO_BE (rev_data->installed_size),
-                                 GUINT64_TO_BE (rev_data->download_size),
-                                 rev_data->metadata_contents);
-          if (rev_data->sparse_data)
-            g_variant_builder_add (ref_sparse_data_builder, "{s@a{sv}}",
-                                   ref, rev_data->sparse_data);
-        }
-    }
-
-  if (delta_names)
-    {
-      g_auto(GVariantDict) deltas_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
-
-      g_variant_dict_init (&deltas_builder, NULL);
-      for (guint i = 0; i < delta_names->len; i++)
-        {
-          g_autofree char *from = NULL;
-          g_autofree char *to = NULL;
-          GVariant *digest;
-
-          _ostree_parse_delta_name (delta_names->pdata[i], &from, &to);
-
-          /* Only keep deltas going to a ref that is in the summary
-           * (i.e. not arch filtered or random) */
-          if (!g_hash_table_contains (commits, to))
-            continue;
-
-          digest = _ostree_repo_static_delta_superblock_digest (repo,
-                                                                (from && from[0]) ? from : NULL,
-                                                                to, cancellable, error);
-          if (digest == NULL)
-            return FALSE;
-
-          g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], digest);
-        }
-
-      if (delta_names->len > 0)
-        g_variant_builder_add (metadata_builder, "{sv}", "ostree.static-deltas", g_variant_dict_end (&deltas_builder));
-    }
-
-  if (compat_format)
-    {
-      /* Note: xa.cache doesn’t need to support collection IDs for the refs listed
-       * in it, because the xa.cache metadata is stored on the ostree-metadata ref,
-       * which is itself strongly bound to a collection ID — so that collection ID
-       * is bound to all the refs in xa.cache. If a client is using the xa.cache
-       * data from a summary file (rather than an ostree-metadata branch), they are
-       * too old to care about collection IDs anyway. */
-      g_variant_builder_add (metadata_builder, "{sv}", "xa.cache",
-                             g_variant_new_variant (g_variant_builder_end (ref_data_builder)));
-      g_variant_builder_add (metadata_builder, "{sv}", "xa.sparse-cache",
-                             g_variant_builder_end (ref_sparse_data_builder));
-    }
-  else
-    {
-      g_variant_builder_add (metadata_builder, "{sv}", "xa.summary-version",
-                             g_variant_new_uint32 (GUINT32_TO_LE (FLATPAK_XA_SUMMARY_VERSION)));
-    }
-
-  g_variant_builder_add_value (summary_builder, g_variant_builder_end (refs_builder));
-  g_variant_builder_add_value (summary_builder, g_variant_builder_end (metadata_builder));
-
-  return g_variant_ref_sink (g_variant_builder_end (summary_builder));
-}
-
-static GVariant *
-read_digested_summary (OstreeRepo   *repo,
-                       const char   *digest,
-                       GHashTable   *digested_summary_cache,
-                       GCancellable *cancellable,
-                       GError      **error)
-{
-  GVariant *cached;
-  g_autoptr(GVariant) loaded = NULL;
-
-  cached = g_hash_table_lookup (digested_summary_cache, digest);
-  if (cached)
-    return g_variant_ref (cached);
-
-  loaded = flatpak_repo_load_digested_summary (repo, digest, error);
-  if (loaded == NULL)
-    return NULL;
-
-  g_hash_table_insert (digested_summary_cache, g_strdup (digest), g_variant_ref (loaded));
-
-  return g_steal_pointer (&loaded);
-}
-
-static gboolean
-add_to_history (OstreeRepo      *repo,
-                GVariantBuilder *history_builder,
-                VarChecksumRef   old_digest_vv,
-                GVariant        *current_digest_v,
-                GVariant        *current_content,
-                GHashTable      *digested_summary_cache,
-                guint           *history_len,
-                guint            max_history_length,
-                GCancellable    *cancellable,
-                GError         **error)
-{
-  g_autoptr(GVariant) old_digest_v = g_variant_ref_sink (var_checksum_dup_to_gvariant (old_digest_vv));
-  g_autofree char *old_digest = NULL;
-  g_autoptr(GVariant) old_content = NULL;
-  g_autofree char *current_digest = NULL;
-  g_autoptr(GBytes) subsummary_diff = NULL;
-
-  /* Limit history length */
-  if (*history_len >= max_history_length)
-    return TRUE;
-
-  /* Avoid repeats in the history (in case nothing changed in subsummary) */
-  if (g_variant_equal (old_digest_v, current_digest_v))
-    return TRUE;
-
-  old_digest = ostree_checksum_from_bytes_v (old_digest_v);
-  old_content = read_digested_summary (repo, old_digest, digested_summary_cache, cancellable, NULL);
-  if  (old_content == NULL)
-    return TRUE; /* Only add parents that still exist */
-
-  subsummary_diff = flatpak_summary_generate_diff (old_content, current_content, error);
-  if  (subsummary_diff == NULL)
-    return FALSE;
-
-  current_digest = ostree_checksum_from_bytes_v (current_digest_v);
-
-  if (!flatpak_repo_save_digested_summary_delta (repo, old_digest, current_digest,
-                                                 subsummary_diff, cancellable, error))
-    return FALSE;
-
-  *history_len += 1;
-  g_variant_builder_add_value (history_builder, old_digest_v);
-
-  return TRUE;
-}
-
-static GVariant *
-generate_summary_index (OstreeRepo   *repo,
-                        GVariant     *old_index_v,
-                        GHashTable   *summaries,
-                        GHashTable   *digested_summaries,
-                        GHashTable   *digested_summary_cache,
-                        const char  **gpg_key_ids,
-                        const char   *gpg_homedir,
-                        GCancellable *cancellable,
-                        GError      **error)
-{
-  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE_VARDICT);
-  g_autoptr(GVariantBuilder) subsummary_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{s(ayaaya{sv})}"));
-  g_autoptr(GVariantBuilder) index_builder = g_variant_builder_new (FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT);
-  g_autoptr(GVariant) index = NULL;
-  g_autoptr(GList) ordered_summaries = NULL;
-  guint max_history_length = flatpak_repo_get_summary_history_length (repo);
-  GList *l;
-
-  add_summary_metadata (repo, metadata_builder);
-
-  ordered_summaries = g_hash_table_get_keys (summaries);
-  ordered_summaries = g_list_sort (ordered_summaries, (GCompareFunc) strcmp);
-  for (l = ordered_summaries; l; l = l->next)
-    {
-      g_auto(GVariantDict) subsummary_metadata_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER;
-      const char *subsummary = l->data;
-      const char *digest = g_hash_table_lookup (summaries, subsummary);
-      g_autoptr(GVariant) digest_v = g_variant_ref_sink (ostree_checksum_to_bytes_v (digest));
-      g_autoptr(GVariantBuilder) history_builder = g_variant_builder_new (G_VARIANT_TYPE ("aay"));
-      g_autoptr(GVariant) subsummary_content = NULL;
-
-      subsummary_content = read_digested_summary (repo, digest, digested_summary_cache, cancellable, error);
-      if  (subsummary_content == NULL)
-        return NULL;  /* This really should always be there as we're supposed to index it */
-
-      if (old_index_v)
-        {
-          VarSummaryIndexRef old_index = var_summary_index_from_gvariant (old_index_v);
-          VarSummaryIndexSubsummariesRef old_subsummaries = var_summary_index_get_subsummaries (old_index);
-          VarSubsummaryRef old_subsummary;
-          guint history_len = 0;
-
-          if (var_summary_index_subsummaries_lookup (old_subsummaries, subsummary, NULL, &old_subsummary))
-            {
-              VarChecksumRef parent = var_subsummary_get_checksum (old_subsummary);
-
-              /* Add current as first in history */
-              if (!add_to_history (repo, history_builder, parent, digest_v, subsummary_content, digested_summary_cache,
-                                   &history_len, max_history_length, cancellable, error))
-                return FALSE;
-
-              /* Add previous history */
-              VarArrayofChecksumRef history = var_subsummary_get_history (old_subsummary);
-              gsize len = var_arrayof_checksum_get_length (history);
-              for (gsize i = 0; i < len; i++)
-                {
-                  VarChecksumRef c = var_arrayof_checksum_get_at (history, i);
-                  if (!add_to_history (repo, history_builder, c, digest_v, subsummary_content, digested_summary_cache,
-                                       &history_len, max_history_length, cancellable, error))
-                    return FALSE;
-                }
-            }
-        }
-
-      g_variant_dict_init (&subsummary_metadata_builder, NULL);
-      g_variant_builder_add (subsummary_builder, "{s(@ay@aay@a{sv})}",
-                             subsummary,
-                             digest_v,
-                             g_variant_builder_end (history_builder),
-                             g_variant_dict_end (&subsummary_metadata_builder));
-    }
-
-  g_variant_builder_add_value (index_builder, g_variant_builder_end (subsummary_builder));
-  g_variant_builder_add_value (index_builder, g_variant_builder_end (metadata_builder));
-
-  index = g_variant_ref_sink (g_variant_builder_end (index_builder));
-
-  return g_steal_pointer (&index);
-}
-
-static gboolean
-flatpak_repo_gc_digested_summaries (OstreeRepo *repo,
-                                    const char *index_digest,           /* The digest of the current (new) index (if any) */
-                                    const char *old_index_digest,       /* The digest of the previous index (if any) */
-                                    GHashTable *digested_summaries,     /* generated */
-                                    GHashTable *digested_summary_cache, /* generated + referenced */
-                                    GCancellable *cancellable,
-                                    GError **error)
-{
-  g_auto(GLnxDirFdIterator) iter = {0};
-  int repo_fd = ostree_repo_get_dfd (repo);
-  struct dirent *dent;
-  const char *ext;
-  g_autoptr(GError) local_error = NULL;
-
-  if (!glnx_dirfd_iterator_init_at (repo_fd, "summaries", FALSE, &iter, &local_error))
-    {
-      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-        return TRUE;
-
-      g_propagate_error (error, g_steal_pointer (&local_error));
-      return FALSE;
-    }
-
-  while (TRUE)
-    {
-      gboolean remove = FALSE;
-
-      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, cancellable, error))
-        return FALSE;
-
-      if (dent == NULL)
-        break;
-
-      if (dent->d_type != DT_REG)
-        continue;
-
-      /* Keep it if its an unexpected type */
-      ext = strchr (dent->d_name, '.');
-      if (ext != NULL)
-        {
-          if (strcmp (ext, ".gz") == 0 && strlen (dent->d_name) == 64 + 3)
-            {
-              g_autofree char *sha256 = g_strndup (dent->d_name, 64);
-
-              /* Keep all the referenced summaries */
-              if (g_hash_table_contains (digested_summary_cache, sha256))
-                {
-                  g_info ("Keeping referenced summary %s", dent->d_name);
-                  continue;
-                }
-              /* Remove rest */
-              remove = TRUE;
-            }
-          else if (strcmp (ext, ".delta") == 0)
-            {
-              const char *dash = strchr (dent->d_name, '-');
-              if (dash != NULL && dash < ext && (ext - dash) == 1 + 64)
-                {
-                  g_autofree char *to_sha256 = g_strndup (dash + 1, 64);
-
-                  /* Only keep deltas going to a generated summary */
-                  if (g_hash_table_contains (digested_summaries, to_sha256))
-                    {
-                      g_info ("Keeping delta to generated summary %s", dent->d_name);
-                      continue;
-                    }
-                  /* Remove rest */
-                  remove = TRUE;
-                }
-            }
-          else if (strcmp (ext, ".idx.sig") == 0)
-            {
-              g_autofree char *digest = g_strndup (dent->d_name, strlen (dent->d_name) - strlen (".idx.sig"));
-
-              if (g_strcmp0 (digest, index_digest) == 0)
-                continue; /* Always keep current */
-
-              if (g_strcmp0 (digest, old_index_digest) == 0)
-                continue; /* Always keep previous one, to avoid some races */
-
-              /* Remove the rest */
-              remove = TRUE;
-            }
-        }
-
-      if (remove)
-        {
-          g_info ("Removing old digested summary file %s", dent->d_name);
-          if (unlinkat (iter.fd, dent->d_name, 0) != 0)
-            {
-              glnx_set_error_from_errno (error);
-              return FALSE;
-            }
-        }
-      else
-        g_info ("Keeping unexpected summary file %s", dent->d_name);
-    }
-
-  return TRUE;
-}
-
-
-/* Update the metadata in the summary file for @repo, and then re-sign the file.
- * If the repo has a collection ID set, additionally store the metadata on a
- * contentless commit in a well-known branch, which is the preferred way of
- * broadcasting per-repo metadata (putting it in the summary file is deprecated,
- * but kept for backwards compatibility).
- *
- * Note that there are two keys for the collection ID: collection-id, and
- * ostree.deploy-collection-id. If a client does not currently have a
- * collection ID configured for this remote, it will *only* update its
- * configuration from ostree.deploy-collection-id.  This allows phased
- * deployment of collection-based repositories. Clients will only update their
- * configuration from an unset to a set collection ID once (otherwise the
- * security properties of collection IDs are broken). */
-gboolean
-flatpak_repo_update (OstreeRepo   *repo,
-                     FlatpakRepoUpdateFlags flags,
-                     const char  **gpg_key_ids,
-                     const char   *gpg_homedir,
-                     GCancellable *cancellable,
-                     GError      **error)
-{
-  g_autoptr(GHashTable) commit_data_cache = NULL;
-  g_autoptr(GVariant) compat_summary = NULL;
-  g_autoptr(GVariant) summary_index = NULL;
-  g_autoptr(GVariant) old_index = NULL;
-  g_autoptr(GPtrArray) delta_names = NULL;
-  g_auto(GStrv) summary_arches = NULL;
-  g_autoptr(GHashTable) refs = NULL;
-  g_autoptr(GHashTable) arches = NULL;
-  g_autoptr(GHashTable) subsets = NULL;
-  g_autoptr(GHashTable) summaries = NULL;
-  g_autoptr(GHashTable) digested_summaries = NULL;
-  g_autoptr(GHashTable) digested_summary_cache = NULL;
-  g_autoptr(GBytes) index_sig = NULL;
-  time_t old_compat_sig_mtime;
-  GKeyFile *config;
-  gboolean disable_index = (flags & FLATPAK_REPO_UPDATE_FLAG_DISABLE_INDEX) != 0;
-  g_autofree char *index_digest = NULL;
-  g_autofree char *old_index_digest = NULL;
-
-  config = ostree_repo_get_config (repo);
-
-  if (!ostree_repo_list_refs_ext (repo, NULL, &refs,
-                                  OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES | OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS,
-                                  cancellable, error))
-    return FALSE;
-
-  old_index = flatpak_repo_load_summary_index (repo, NULL);
-  if (old_index)
-    commit_data_cache = populate_commit_data_cache (repo, old_index);
-
-  if (commit_data_cache == NULL) /* No index or failed to load it */
-    commit_data_cache = commit_data_cache_new ();
-
-  if (!ostree_repo_list_static_delta_names (repo, &delta_names, cancellable, error))
-    return FALSE;
-
-  if (config)
-    summary_arches = g_key_file_get_string_list (config, "flatpak", "summary-arches", NULL, NULL);
-
-  summaries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-  /* These are the ones we generated */
-  digested_summaries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
-  /* These are the ones generated or references */
-  digested_summary_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
-
-  arches = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-  subsets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-  g_hash_table_add (subsets, g_strdup ("")); /* Always have everything subset */
-
-  GLNX_HASH_TABLE_FOREACH_KV (refs, const char *, ref, const char *, rev)
-    {
-      g_autofree char *arch = flatpak_get_arch_for_ref (ref);
-      CommitData *rev_data = NULL;
-
-      if (arch != NULL &&
-          !g_hash_table_contains (arches, arch))
-        g_hash_table_add (arches, g_steal_pointer (&arch));
-
-      /* Add CommitData for flatpak refs that we didn't already pre-populate */
-      if (flatpak_is_app_runtime_or_appstream_ref (ref))
-        {
-          rev_data = g_hash_table_lookup (commit_data_cache, rev);
-          if (rev_data == NULL)
-            {
-              rev_data = read_commit_data (repo, ref, rev, cancellable, error);
-              if (rev_data == NULL)
-                return FALSE;
-
-              g_hash_table_insert (commit_data_cache, g_strdup (rev), (CommitData *)rev_data);
-            }
-
-          for (int i = 0; rev_data->subsets != NULL && i < rev_data->subsets->len; i++)
-            {
-              const char *subset = g_ptr_array_index (rev_data->subsets, i);
-              if (!g_hash_table_contains (subsets, subset))
-                g_hash_table_add (subsets, g_strdup (subset));
-            }
-        }
-    }
-
-  compat_summary = generate_summary (repo, TRUE, refs, commit_data_cache, delta_names,
-                                     "", (const char **)summary_arches,
-                                     cancellable, error);
-  if (compat_summary == NULL)
-    return FALSE;
-
-  if (!disable_index)
-    {
-      GLNX_HASH_TABLE_FOREACH (subsets, const char *, subset)
-        {
-          GLNX_HASH_TABLE_FOREACH (arches, const char *, arch)
-            {
-              const char *arch_v[] = { arch, NULL };
-              g_autofree char *name = NULL;
-              g_autofree char *digest = NULL;
-
-              if (*subset == 0)
-                name = g_strdup (arch);
-              else
-                name = g_strconcat (subset, "-", arch, NULL);
-
-              g_autoptr(GVariant) arch_summary = generate_summary (repo, FALSE, refs, commit_data_cache, NULL, subset, arch_v,
-                                                                   cancellable, error);
-              if (arch_summary == NULL)
-                return FALSE;
-
-              digest = flatpak_repo_save_digested_summary (repo, name, arch_summary, cancellable, error);
-              if (digest == NULL)
-                return FALSE;
-
-              g_hash_table_insert (digested_summaries, g_strdup (digest), g_variant_ref (arch_summary));
-              /* Prime summary cache with generated summaries */
-              g_hash_table_insert (digested_summary_cache, g_strdup (digest), g_variant_ref (arch_summary));
-              g_hash_table_insert (summaries, g_steal_pointer (&name), g_steal_pointer (&digest));
-            }
-        }
-
-      summary_index = generate_summary_index (repo, old_index, summaries, digested_summaries, digested_summary_cache,
-                                              gpg_key_ids, gpg_homedir,
-                                              cancellable, error);
-      if (summary_index == NULL)
-        return FALSE;
-    }
-
-  if (!ostree_repo_static_delta_reindex (repo, 0, NULL, cancellable, error))
-    return FALSE;
-
-  if (summary_index && gpg_key_ids)
-    {
-      g_autoptr(GBytes) index_bytes = g_variant_get_data_as_bytes (summary_index);
-
-      if (!ostree_repo_gpg_sign_data (repo, index_bytes,
-                                      NULL,
-                                      gpg_key_ids,
-                                      gpg_homedir,
-                                      &index_sig,
-                                      cancellable,
-                                      error))
-        return FALSE;
-    }
-
-  if (summary_index)
-    index_digest = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
-                                                g_variant_get_data (summary_index),
-                                                g_variant_get_size (summary_index));
-  if (old_index)
-    old_index_digest = g_compute_checksum_for_data (G_CHECKSUM_SHA256,
-                                                    g_variant_get_data (old_index),
-                                                    g_variant_get_size (old_index));
-
-  /* Release the memory-mapped summary index file before replacing it,
-     to avoid failure on filesystems like cifs */
-  g_clear_pointer (&old_index, g_variant_unref);
-
-  if (!flatpak_repo_save_summary_index (repo, summary_index, index_digest, index_sig, cancellable, error))
-    return FALSE;
-
-  if (!flatpak_repo_save_compat_summary (repo, compat_summary, &old_compat_sig_mtime, cancellable, error))
-    return FALSE;
-
-  if (gpg_key_ids)
-    {
-      if (!ostree_repo_add_gpg_signature_summary (repo,
-                                                  gpg_key_ids,
-                                                  gpg_homedir,
-                                                  cancellable,
-                                                  error))
-        return FALSE;
-
-
-      if (old_compat_sig_mtime != 0)
-        {
-          int repo_dfd = ostree_repo_get_dfd (repo);
-          struct stat stbuf;
-
-          /* Ensure we increase (in sec precision) */
-          if (fstatat (repo_dfd, "summary.sig", &stbuf, AT_SYMLINK_NOFOLLOW) == 0 &&
-              stbuf.st_mtime <= old_compat_sig_mtime)
-            {
-              struct timespec ts[2] = { {0, UTIME_OMIT}, {old_compat_sig_mtime + 1, 0} };
-              (void) utimensat (repo_dfd, "summary.sig", ts, AT_SYMLINK_NOFOLLOW);
-            }
-        }
-    }
-
-  if (!disable_index &&
-      !flatpak_repo_gc_digested_summaries (repo, index_digest, old_index_digest, digested_summaries, digested_summary_cache, cancellable, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_mtree_create_dir (OstreeRepo         *repo,
-                          OstreeMutableTree  *parent,
-                          const char         *name,
-                          OstreeMutableTree **dir_out,
-                          GError            **error)
-{
-  g_autoptr(OstreeMutableTree) dir = NULL;
-
-  if (!ostree_mutable_tree_ensure_dir (parent, name, &dir, error))
-    return FALSE;
-
-  if (!flatpak_mtree_ensure_dir_metadata (repo, dir, NULL, error))
-    return FALSE;
-
-  *dir_out = g_steal_pointer (&dir);
-  return TRUE;
-}
-
-gboolean
-flatpak_mtree_create_symlink (OstreeRepo         *repo,
-                              OstreeMutableTree  *parent,
-                              const char         *filename,
-                              const char         *target,
-                              GError            **error)
-{
-  g_autoptr(GFileInfo) file_info = g_file_info_new ();
-  g_autoptr(GInputStream) content_stream = NULL;
-  g_autofree guchar *raw_checksum = NULL;
-  g_autofree char *checksum = NULL;
-  guint64 length;
-
-  g_file_info_set_name (file_info, filename);
-  g_file_info_set_file_type (file_info, G_FILE_TYPE_SYMBOLIC_LINK);
-  g_file_info_set_size (file_info, 0);
-  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
-  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);
-  g_file_info_set_attribute_uint32 (file_info, "unix::mode", S_IFLNK | 0777);
-
-  g_file_info_set_attribute_boolean (file_info, "standard::is-symlink", TRUE);
-  g_file_info_set_attribute_byte_string (file_info, "standard::symlink-target", target);
-
-  if (!ostree_raw_file_to_content_stream (NULL, file_info, NULL,
-                                          &content_stream, &length,
-                                          NULL, error))
-    return FALSE;
-
-  if (!ostree_repo_write_content (repo, NULL, content_stream, length,
-                                  &raw_checksum, NULL, error))
-    return FALSE;
-
-  checksum = ostree_checksum_from_bytes (raw_checksum);
-
-  if (!ostree_mutable_tree_replace_file (parent, filename, checksum, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_mtree_add_file_from_bytes (OstreeRepo *repo,
-                                   GBytes *bytes,
-                                   OstreeMutableTree *parent,
-                                   const char *filename,
-                                   GCancellable *cancellable,
-                                   GError      **error)
-{
-  g_autoptr(GFileInfo) info = g_file_info_new ();
-  g_autoptr(GInputStream) memstream = NULL;
-  g_autoptr(GInputStream) content_stream = NULL;
-  g_autofree guchar *raw_checksum = NULL;
-  g_autofree char *checksum = NULL;
-  guint64 length;
-
-  g_file_info_set_attribute_uint32 (info, "standard::type", G_FILE_TYPE_REGULAR);
-  g_file_info_set_attribute_uint64 (info, "standard::size", g_bytes_get_size (bytes));
-  g_file_info_set_attribute_uint32 (info, "unix::uid", 0);
-  g_file_info_set_attribute_uint32 (info, "unix::gid", 0);
-  g_file_info_set_attribute_uint32 (info, "unix::mode", S_IFREG | 0644);
-
-  memstream = g_memory_input_stream_new_from_bytes (bytes);
-
-  if (!ostree_raw_file_to_content_stream (memstream, info, NULL,
-                                          &content_stream, &length,
-                                          cancellable, error))
-    return FALSE;
-
-  if (!ostree_repo_write_content (repo, NULL, content_stream, length,
-                                  &raw_checksum, cancellable, error))
-    return FALSE;
-
-  checksum = ostree_checksum_from_bytes (raw_checksum);
-
-  if (!ostree_mutable_tree_replace_file (parent, filename, checksum, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-gboolean
-flatpak_mtree_ensure_dir_metadata (OstreeRepo        *repo,
-                                   OstreeMutableTree *mtree,
-                                   GCancellable      *cancellable,
-                                   GError           **error)
-{
-  g_autoptr(GVariant) dirmeta = NULL;
-  g_autoptr(GFileInfo) file_info = g_file_info_new ();
-  g_autofree guchar *csum = NULL;
-  g_autofree char *checksum = NULL;
-
-  g_file_info_set_name (file_info, "/");
-  g_file_info_set_file_type (file_info, G_FILE_TYPE_DIRECTORY);
-  g_file_info_set_attribute_uint32 (file_info, "unix::uid", 0);
-  g_file_info_set_attribute_uint32 (file_info, "unix::gid", 0);
-  g_file_info_set_attribute_uint32 (file_info, "unix::mode", 040755);
-
-  dirmeta = ostree_create_directory_metadata (file_info, NULL);
-  if (!ostree_repo_write_metadata (repo, OSTREE_OBJECT_TYPE_DIR_META, NULL,
-                                   dirmeta, &csum, cancellable, error))
-    return FALSE;
-
-  checksum = ostree_checksum_from_bytes (csum);
-  ostree_mutable_tree_set_metadata_checksum (mtree, checksum);
-
-  return TRUE;
-}
-
-static gboolean
-validate_component (FlatpakXml *component,
-                    const char *ref,
-                    const char *id,
-                    char      **tags,
-                    const char *runtime,
-                    const char *sdk)
-{
-  FlatpakXml *bundle, *text, *prev, *id_node, *id_text_node, *metadata, *value;
-  g_autofree char *id_text = NULL;
-  int i;
-
-  if (g_strcmp0 (component->element_name, "component") != 0)
-    return FALSE;
-
-  id_node = flatpak_xml_find (component, "id", NULL);
-  if (id_node == NULL)
-    return FALSE;
-
-  id_text_node = flatpak_xml_find (id_node, NULL, NULL);
-  if (id_text_node == NULL || id_text_node->text == NULL)
-    return FALSE;
-
-  id_text = g_strstrip (g_strdup (id_text_node->text));
-
-  /* Drop .desktop file suffix (unless the actual app id ends with .desktop) */
-  if (g_str_has_suffix (id_text, ".desktop") &&
-      !g_str_has_suffix (id, ".desktop"))
-    id_text[strlen (id_text) - strlen (".desktop")] = 0;
-
-  if (!g_str_has_prefix (id_text, id))
-    {
-      g_warning ("Invalid id %s", id_text);
-      return FALSE;
-    }
-
-  while ((bundle = flatpak_xml_find (component, "bundle", &prev)) != NULL)
-    flatpak_xml_free (flatpak_xml_unlink (bundle, prev));
-
-  bundle = flatpak_xml_new ("bundle");
-  bundle->attribute_names = g_new0 (char *, 2 * 4);
-  bundle->attribute_values = g_new0 (char *, 2 * 4);
-  bundle->attribute_names[0] = g_strdup ("type");
-  bundle->attribute_values[0] = g_strdup ("flatpak");
-
-  i = 1;
-  if (runtime && !g_str_has_prefix (runtime, "runtime/"))
-    {
-      bundle->attribute_names[i] = g_strdup ("runtime");
-      bundle->attribute_values[i] = g_strdup (runtime);
-      i++;
-    }
-
-  if (sdk)
-    {
-      bundle->attribute_names[i] = g_strdup ("sdk");
-      bundle->attribute_values[i] = g_strdup (sdk);
-      i++;
-    }
-
-  text = flatpak_xml_new (NULL);
-  text->text = g_strdup (ref);
-  flatpak_xml_add (bundle, text);
-
-  flatpak_xml_add (component, flatpak_xml_new_text ("  "));
-  flatpak_xml_add (component, bundle);
-  flatpak_xml_add (component, flatpak_xml_new_text ("\n  "));
-
-  if (tags != NULL && tags[0] != NULL)
-    {
-      metadata = flatpak_xml_find (component, "metadata", NULL);
-      if (metadata == NULL)
-        {
-          metadata = flatpak_xml_new ("metadata");
-          metadata->attribute_names = g_new0 (char *, 1);
-          metadata->attribute_values = g_new0 (char *, 1);
-
-          flatpak_xml_add (component, flatpak_xml_new_text ("  "));
-          flatpak_xml_add (component, metadata);
-          flatpak_xml_add (component, flatpak_xml_new_text ("\n  "));
-        }
-
-      value = flatpak_xml_new ("value");
-      value->attribute_names = g_new0 (char *, 2);
-      value->attribute_values = g_new0 (char *, 2);
-      value->attribute_names[0] = g_strdup ("key");
-      value->attribute_values[0] = g_strdup ("X-Flatpak-Tags");
-      flatpak_xml_add (metadata, flatpak_xml_new_text ("\n       "));
-      flatpak_xml_add (metadata, value);
-      flatpak_xml_add (metadata, flatpak_xml_new_text ("\n    "));
-
-      text = flatpak_xml_new (NULL);
-      text->text = g_strjoinv (",", tags);
-      flatpak_xml_add (value, text);
-    }
-
-  return TRUE;
-}
-
-gboolean
-flatpak_appstream_xml_migrate (FlatpakXml *source,
-                               FlatpakXml *dest,
-                               const char *ref,
-                               const char *id,
-                               GKeyFile   *metadata)
-{
-  FlatpakXml *source_components;
-  FlatpakXml *dest_components;
-  FlatpakXml *component;
-  FlatpakXml *prev_component;
-  gboolean migrated = FALSE;
-  g_auto(GStrv) tags = NULL;
-  g_autofree const char *runtime = NULL;
-  g_autofree const char *sdk = NULL;
-  const char *group;
-
-  if (source->first_child == NULL ||
-      source->first_child->next_sibling != NULL ||
-      g_strcmp0 (source->first_child->element_name, "components") != 0)
-    return FALSE;
-
-  if (g_str_has_prefix (ref, "app/"))
-    group = FLATPAK_METADATA_GROUP_APPLICATION;
-  else
-    group = FLATPAK_METADATA_GROUP_RUNTIME;
-
-  tags = g_key_file_get_string_list (metadata, group, FLATPAK_METADATA_KEY_TAGS,
-                                     NULL, NULL);
-  runtime = g_key_file_get_string (metadata, group,
-                                   FLATPAK_METADATA_KEY_RUNTIME, NULL);
-  sdk = g_key_file_get_string (metadata, group, FLATPAK_METADATA_KEY_SDK, NULL);
-
-  source_components = source->first_child;
-  dest_components = dest->first_child;
-
-  component = source_components->first_child;
-  prev_component = NULL;
-  while (component != NULL)
-    {
-      FlatpakXml *next = component->next_sibling;
-
-      if (validate_component (component, ref, id, tags, runtime, sdk))
-        {
-          flatpak_xml_add (dest_components,
-                           flatpak_xml_unlink (component, prev_component));
-          migrated = TRUE;
-        }
-      else
-        {
-          prev_component = component;
-        }
-
-      component = next;
-    }
-
-  return migrated;
-}
-
-static gboolean
-copy_icon (const char        *id,
-           GFile             *icons_dir,
-           OstreeRepo        *repo,
-           OstreeMutableTree *size_mtree,
-           const char        *size,
-           GError           **error)
-{
-  g_autofree char *icon_name = g_strconcat (id, ".png", NULL);
-  g_autoptr(GFile) size_dir = g_file_get_child (icons_dir, size);
-  g_autoptr(GFile) icon_file = g_file_get_child (size_dir, icon_name);
-  const char *checksum;
-
-  if (!ostree_repo_file_ensure_resolved (OSTREE_REPO_FILE(icon_file), NULL))
-    {
-      g_info ("No icon at size %s for %s", size, id);
-      return TRUE;
-    }
-
-  checksum = ostree_repo_file_get_checksum (OSTREE_REPO_FILE(icon_file));
-  if (!ostree_mutable_tree_replace_file (size_mtree, icon_name, checksum, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-extract_appstream (OstreeRepo        *repo,
-                   FlatpakXml        *appstream_root,
-                   FlatpakDecomposed *ref,
-                   const char        *id,
-                   OstreeMutableTree *size1_mtree,
-                   OstreeMutableTree *size2_mtree,
-                   GCancellable       *cancellable,
-                   GError            **error)
-{
-  g_autoptr(GFile) root = NULL;
-  g_autoptr(GFile) app_info_dir = NULL;
-  g_autoptr(GFile) xmls_dir = NULL;
-  g_autoptr(GFile) icons_dir = NULL;
-  g_autoptr(GFile) appstream_file = NULL;
-  g_autoptr(GFile) metadata = NULL;
-  g_autofree char *appstream_basename = NULL;
-  g_autoptr(GInputStream) in = NULL;
-  g_autoptr(FlatpakXml) xml_root = NULL;
-  g_autoptr(GKeyFile) keyfile = NULL;
-
-  if (!ostree_repo_read_commit (repo, flatpak_decomposed_get_ref (ref), &root, NULL, NULL, error))
-    return FALSE;
-
-  keyfile = g_key_file_new ();
-  metadata = g_file_get_child (root, "metadata");
-  if (g_file_query_exists (metadata, cancellable))
-    {
-      g_autofree char *content = NULL;
-      gsize len;
-
-      if (!g_file_load_contents (metadata, cancellable, &content, &len, NULL, error))
-        return FALSE;
-
-      if (!g_key_file_load_from_data (keyfile, content, len, G_KEY_FILE_NONE, error))
-        return FALSE;
-    }
-
-  app_info_dir = g_file_resolve_relative_path (root, "files/share/app-info");
-
-  xmls_dir = g_file_resolve_relative_path (app_info_dir, "xmls");
-  icons_dir = g_file_resolve_relative_path (app_info_dir, "icons/flatpak");
-
-  appstream_basename = g_strconcat (id, ".xml.gz", NULL);
-  appstream_file = g_file_get_child (xmls_dir, appstream_basename);
-
-  in = (GInputStream *) g_file_read (appstream_file, cancellable, error);
-  if (!in)
-    return FALSE;
-
-  xml_root = flatpak_xml_parse (in, TRUE, cancellable, error);
-  if (xml_root == NULL)
-    return FALSE;
-
-  if (flatpak_appstream_xml_migrate (xml_root, appstream_root,
-                                     flatpak_decomposed_get_ref (ref), id, keyfile))
-    {
-      g_autoptr(GError) my_error = NULL;
-      FlatpakXml *components = appstream_root->first_child;
-      FlatpakXml *component = components->first_child;
-
-      while (component != NULL)
-        {
-          FlatpakXml *component_id, *component_id_text_node;
-          g_autofree char *component_id_text = NULL;
-          char *component_id_suffix;
-
-          if (g_strcmp0 (component->element_name, "component") != 0)
-            {
-              component = component->next_sibling;
-              continue;
-            }
-
-          component_id = flatpak_xml_find (component, "id", NULL);
-          component_id_text_node = flatpak_xml_find (component_id, NULL, NULL);
-
-          component_id_text = g_strstrip (g_strdup (component_id_text_node->text));
-
-          /* We're looking for a component that matches the app-id (id), but it
-             may have some further elements (separated by dot) and can also have
-             ".desktop" at the end which we need to strip out. Further complicating
-             things, some actual app ids ends in .desktop, such as org.telegram.desktop. */
-
-          component_id_suffix = component_id_text + strlen (id); /* Don't deref before we check for prefix match! */
-          if (!g_str_has_prefix (component_id_text, id) ||
-              (component_id_suffix[0] != 0 && component_id_suffix[0] != '.'))
-            {
-              component = component->next_sibling;
-              continue;
-            }
-
-          if (g_str_has_suffix (component_id_suffix, ".desktop"))
-            component_id_suffix[strlen (component_id_suffix) - strlen (".desktop")] = 0;
-
-          if (!copy_icon (component_id_text, icons_dir, repo, size1_mtree, "64x64", &my_error))
-            {
-              g_print (_("Error copying 64x64 icon for component %s: %s\n"), component_id_text, my_error->message);
-              g_clear_error (&my_error);
-            }
-
-          if (!copy_icon (component_id_text, icons_dir, repo, size2_mtree, "128x128", &my_error))
-             {
-               g_print (_("Error copying 128x128 icon for component %s: %s\n"), component_id_text, my_error->message);
-               g_clear_error (&my_error);
-             }
-
-
-          /* We might match other prefixes, so keep on going */
-          component = component->next_sibling;
-        }
-    }
-
-  return TRUE;
-}
-
-FlatpakXml *
-flatpak_appstream_xml_new (void)
-{
-  FlatpakXml *appstream_root = NULL;
-  FlatpakXml *appstream_components;
-
-  appstream_root = flatpak_xml_new ("root");
-  appstream_components = flatpak_xml_new ("components");
-  flatpak_xml_add (appstream_root, appstream_components);
-  flatpak_xml_add (appstream_components, flatpak_xml_new_text ("\n  "));
-
-  appstream_components->attribute_names = g_new0 (char *, 3);
-  appstream_components->attribute_values = g_new0 (char *, 3);
-  appstream_components->attribute_names[0] = g_strdup ("version");
-  appstream_components->attribute_values[0] = g_strdup ("0.8");
-  appstream_components->attribute_names[1] = g_strdup ("origin");
-  appstream_components->attribute_values[1] = g_strdup ("flatpak");
-
-  return appstream_root;
-}
-
-gboolean
-flatpak_appstream_xml_root_to_data (FlatpakXml *appstream_root,
-                                    GBytes    **uncompressed,
-                                    GBytes    **compressed,
-                                    GError    **error)
-{
-  g_autoptr(GString) xml = NULL;
-  g_autoptr(GZlibCompressor) compressor = NULL;
-  g_autoptr(GOutputStream) out2 = NULL;
-  g_autoptr(GOutputStream) out = NULL;
-
-  flatpak_xml_add (appstream_root->first_child, flatpak_xml_new_text ("\n"));
-
-  xml = g_string_new ("");
-  flatpak_xml_to_string (appstream_root, xml);
-
-  if (compressed)
-    {
-      compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1);
-      out = g_memory_output_stream_new_resizable ();
-      out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor));
-      if (!g_output_stream_write_all (out2, xml->str, xml->len,
-                                      NULL, NULL, error))
-        return FALSE;
-      if (!g_output_stream_close (out2, NULL, error))
-        return FALSE;
-    }
-
-  if (uncompressed)
-    *uncompressed = g_string_free_to_bytes (g_steal_pointer (&xml));
-
-  if (compressed)
-    *compressed = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (out));
-
-  return TRUE;
-}
-
-void
-flatpak_appstream_xml_filter (FlatpakXml *appstream,
-                              GRegex *allow_refs,
-                              GRegex *deny_refs)
-{
-  FlatpakXml *components;
-  FlatpakXml *component;
-  FlatpakXml *prev_component, *old;
-
-  for (components = appstream->first_child;
-       components != NULL;
-       components = components->next_sibling)
-    {
-      if (g_strcmp0 (components->element_name, "components") != 0)
-        continue;
-
-
-      prev_component = NULL;
-      component = components->first_child;
-      while (component != NULL)
-        {
-          FlatpakXml *bundle;
-          gboolean allow = FALSE;
-
-          if (g_strcmp0 (component->element_name, "component") == 0)
-            {
-              bundle = flatpak_xml_find (component, "bundle", NULL);
-              if (bundle && bundle->first_child && bundle->first_child->text)
-                allow = flatpak_filters_allow_ref (allow_refs, deny_refs, bundle->first_child->text);
-            }
-
-          if (allow)
-            {
-              prev_component = component;
-              component = component->next_sibling;
-            }
-          else
-            {
-              old = component;
-
-              /* prev_component is same as before */
-              component = component->next_sibling;
-
-              flatpak_xml_unlink (old, prev_component);
-              flatpak_xml_free (old);
-            }
-        }
-    }
-}
-
-/* This is similar to ostree_repo_list_refs(), but returns only valid flatpak
- * refs, as FlatpakDecomposed. */
-static GHashTable *
-flatpak_repo_list_flatpak_refs (OstreeRepo   *repo,
-                                GCancellable *cancellable,
-                                GError      **error)
-{
-  g_autoptr(GHashTable) refspecs = NULL;
-  g_autoptr(GHashTable) refs = NULL;
-  GHashTableIter iter;
-  gpointer key, value;
-
-  if (!ostree_repo_list_refs_ext (repo, NULL, &refspecs,
-                                  OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES | OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS,
-                                  cancellable, error))
-    return NULL;
-
-  refs = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, g_free);
-
-  g_hash_table_iter_init (&iter, refspecs);
-  while (g_hash_table_iter_next (&iter, &key, &value))
-    {
-      const char *refstr = key;
-      const char *checksum = value;
-      FlatpakDecomposed *ref = NULL;
-
-      ref = flatpak_decomposed_new_from_ref_take ((char *)refstr, NULL);
-      if (ref)
-        {
-          g_hash_table_iter_steal (&iter);
-          g_hash_table_insert (refs, ref, (char *)checksum);
-        }
-    }
-
-  return g_steal_pointer (&refs);
-}
-
-static gboolean
-_flatpak_repo_generate_appstream (OstreeRepo   *repo,
-                                  const char  **gpg_key_ids,
-                                  const char   *gpg_homedir,
-                                  FlatpakDecomposed **all_refs_keys,
-                                  guint         n_keys,
-                                  GHashTable   *all_commits,
-                                  const char   *arch,
-                                  const char   *subset,
-                                  guint64       timestamp,
-                                  GCancellable *cancellable,
-                                  GError      **error)
-{
-  g_autoptr(FlatpakXml) appstream_root = NULL;
-  g_autoptr(GBytes) xml_data = NULL;
-  g_autoptr(GBytes) xml_gz_data = NULL;
-  g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new ();
-  g_autoptr(OstreeMutableTree) icons_mtree = NULL;
-  g_autoptr(OstreeMutableTree) icons_flatpak_mtree = NULL;
-  g_autoptr(OstreeMutableTree) size1_mtree = NULL;
-  g_autoptr(OstreeMutableTree) size2_mtree = NULL;
-  const char *compat_arch;
-  compat_arch = flatpak_get_compat_arch (arch);
-  const char *branch_names[] = { "appstream", "appstream2" };
-  const char *collection_id;
-
-  if (subset != NULL && *subset != 0)
-    g_info ("Generating appstream for %s, subset %s", arch, subset);
-  else
-    g_info ("Generating appstream for %s", arch);
-
-  collection_id = ostree_repo_get_collection_id (repo);
-
-  if (!flatpak_mtree_ensure_dir_metadata (repo, mtree, cancellable, error))
-    return FALSE;
-
-  if (!flatpak_mtree_create_dir (repo, mtree, "icons", &icons_mtree, error))
-    return FALSE;
-
-  if (!flatpak_mtree_create_dir (repo, icons_mtree, "64x64", &size1_mtree, error))
-    return FALSE;
-
-  if (!flatpak_mtree_create_dir (repo, icons_mtree, "128x128", &size2_mtree, error))
-    return FALSE;
-
-  /* For compatibility with libappstream we create a $origin ("flatpak") subdirectory with symlinks
-   * to the size directories thus matching the standard merged appstream layout if we assume the
-   * appstream has origin=flatpak, which flatpak-builder creates.
-   *
-   * See https://github.com/ximion/appstream/pull/224 for details.
-   */
-  if (!flatpak_mtree_create_dir (repo, icons_mtree, "flatpak", &icons_flatpak_mtree, error))
-    return FALSE;
-  if (!flatpak_mtree_create_symlink (repo, icons_flatpak_mtree, "64x64", "../64x64", error))
-    return FALSE;
-  if (!flatpak_mtree_create_symlink (repo, icons_flatpak_mtree, "128x128", "../128x128", error))
-    return FALSE;
-
-  appstream_root = flatpak_appstream_xml_new ();
-
-  for (int i = 0; i < n_keys; i++)
-    {
-      FlatpakDecomposed *ref = all_refs_keys[i];
-      GVariant *commit_v = NULL;
-      VarMetadataRef commit_metadata;
-      g_autoptr(GError) my_error = NULL;
-      g_autofree char *id = NULL;
-
-      if (!flatpak_decomposed_is_arch (ref, arch))
-        {
-          g_autoptr(FlatpakDecomposed) main_ref = NULL;
-
-          /* Include refs that don't match the main arch (e.g. x86_64), if they match
-             the compat arch (e.g. i386) and the main arch version is not in the repo */
-          if (compat_arch != NULL && flatpak_decomposed_is_arch (ref, compat_arch))
-            main_ref = flatpak_decomposed_new_from_decomposed (ref, 0, NULL, compat_arch, NULL, NULL);
-
-          if (main_ref == NULL ||
-              g_hash_table_lookup (all_commits, main_ref))
-            continue;
-        }
-
-      commit_v = g_hash_table_lookup (all_commits, ref);
-      g_assert (commit_v != NULL);
-
-      commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (commit_v));
-      if (var_metadata_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, NULL, NULL) ||
-          var_metadata_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, NULL, NULL))
-        {
-          g_info (_("%s is end-of-life, ignoring for appstream"), flatpak_decomposed_get_ref (ref));
-          continue;
-        }
-
-      if (*subset != 0)
-        {
-          VarVariantRef xa_subsets_v;
-          gboolean in_subset = FALSE;
-
-          if (var_metadata_lookup (commit_metadata, "xa.subsets", NULL, &xa_subsets_v))
-            {
-              VarArrayofstringRef xa_subsets = var_arrayofstring_from_variant (xa_subsets_v);
-              gsize len = var_arrayofstring_get_length (xa_subsets);
-
-              for (gsize j = 0; j < len; j++)
-                {
-                  const char *xa_subset = var_arrayofstring_get_at (xa_subsets, j);
-                  if (strcmp (subset, xa_subset) == 0)
-                    {
-                      in_subset = TRUE;
-                      break;
-                    }
-                }
-            }
-
-          if (!in_subset)
-            continue;
-        }
-
-      id = flatpak_decomposed_dup_id (ref);
-      if (!extract_appstream (repo, appstream_root,
-                              ref, id, size1_mtree, size2_mtree,
-                              cancellable, &my_error))
-        {
-          if (flatpak_decomposed_is_app (ref))
-            g_print (_("No appstream data for %s: %s\n"), flatpak_decomposed_get_ref (ref), my_error->message);
-          continue;
-        }
-    }
-
-  if (!flatpak_appstream_xml_root_to_data (appstream_root, &xml_data, &xml_gz_data, error))
-    return FALSE;
-
-  for (int i = 0; i < G_N_ELEMENTS (branch_names); i++)
-    {
-      gboolean skip_commit = FALSE;
-      const char *branch_prefix = branch_names[i];
-      g_autoptr(GFile) root = NULL;
-      g_autofree char *branch = NULL;
-      g_autofree char *parent = NULL;
-      g_autofree char *commit_checksum = NULL;
-
-      if (*subset != 0 && i == 0)
-        continue; /* No old-style branch for subsets */
-
-      if (*subset != 0)
-        branch = g_strdup_printf ("%s/%s-%s", branch_prefix, subset, arch);
-      else
-        branch = g_strdup_printf ("%s/%s", branch_prefix, arch);
-
-      if (!flatpak_repo_resolve_rev (repo, collection_id, NULL, branch, TRUE,
-                                     &parent, cancellable, error))
-        return FALSE;
-
-      if (i == 0)
-        {
-          if (!flatpak_mtree_add_file_from_bytes (repo, xml_gz_data, mtree, "appstream.xml.gz", cancellable, error))
-            return FALSE;
-        }
-      else
-        {
-          if (!ostree_mutable_tree_remove (mtree, "appstream.xml.gz", TRUE, error))
-            return FALSE;
-
-          if (!flatpak_mtree_add_file_from_bytes (repo, xml_data, mtree, "appstream.xml", cancellable, error))
-            return FALSE;
-        }
-
-      if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error))
-        return FALSE;
-
-      /* No need to commit if nothing changed */
-      if (parent)
-        {
-          g_autoptr(GFile) parent_root = NULL;
-
-          if (!ostree_repo_read_commit (repo, parent, &parent_root, NULL, cancellable, error))
-            return FALSE;
-
-          if (g_file_equal (root, parent_root))
-            {
-              skip_commit = TRUE;
-              g_info ("Not updating %s, no change", branch);
-            }
-        }
-
-      if (!skip_commit)
-        {
-          g_autoptr(GVariantDict) metadata_dict = NULL;
-          g_autoptr(GVariant) metadata = NULL;
-
-          /* Add bindings to the metadata. Do this even if P2P support is not
-           * enabled, as it might be enable for other flatpak builds. */
-          metadata_dict = g_variant_dict_new (NULL);
-          g_variant_dict_insert (metadata_dict, "ostree.collection-binding",
-                                 "s", (collection_id != NULL) ? collection_id : "");
-          g_variant_dict_insert_value (metadata_dict, "ostree.ref-binding",
-                                       g_variant_new_strv ((const gchar * const *) &branch, 1));
-          metadata = g_variant_ref_sink (g_variant_dict_end (metadata_dict));
-
-          if (timestamp > 0)
-            {
-              if (!ostree_repo_write_commit_with_time (repo, parent, "Update", NULL, metadata,
-                                                       OSTREE_REPO_FILE (root),
-                                                       timestamp,
-                                                       &commit_checksum,
-                                                       cancellable, error))
-                return FALSE;
-            }
-          else
-            {
-              if (!ostree_repo_write_commit (repo, parent, "Update", NULL, metadata,
-                                             OSTREE_REPO_FILE (root),
-                                             &commit_checksum, cancellable, error))
-                return FALSE;
-            }
-
-          if (gpg_key_ids)
-            {
-              for (int j = 0; gpg_key_ids[j] != NULL; j++)
-                {
-                  const char *keyid = gpg_key_ids[j];
-
-                  if (!ostree_repo_sign_commit (repo,
-                                                commit_checksum,
-                                                keyid,
-                                                gpg_homedir,
-                                                cancellable,
-                                                error))
-                    return FALSE;
-                }
-            }
-
-          g_info ("Creating appstream branch %s", branch);
-          if (collection_id != NULL)
-            {
-              const OstreeCollectionRef collection_ref = { (char *) collection_id, branch };
-              ostree_repo_transaction_set_collection_ref (repo, &collection_ref, commit_checksum);
-            }
-          else
-            {
-              ostree_repo_transaction_set_ref (repo, NULL, branch, commit_checksum);
-            }
-        }
-    }
-
-  return TRUE;
-}
-
-
-gboolean
-flatpak_repo_generate_appstream (OstreeRepo   *repo,
-                                 const char  **gpg_key_ids,
-                                 const char   *gpg_homedir,
-                                 guint64       timestamp,
-                                 GCancellable *cancellable,
-                                 GError      **error)
-{
-  g_autoptr(GHashTable) all_refs = NULL;
-  g_autoptr(GHashTable) all_commits = NULL;
-  g_autofree FlatpakDecomposed **all_refs_keys = NULL;
-  guint n_keys;
-  g_autoptr(GPtrArray) arches = NULL;  /* (element-type utf8 utf8) */
-  g_autoptr(GPtrArray) subsets = NULL;  /* (element-type utf8 utf8) */
-  g_autoptr(FlatpakRepoTransaction) transaction = NULL;
-  OstreeRepoTransactionStats stats;
-
-  arches = g_ptr_array_new_with_free_func (g_free);
-  subsets = g_ptr_array_new_with_free_func (g_free);
-
-  g_ptr_array_add (subsets, g_strdup (""));
-
-  all_refs = flatpak_repo_list_flatpak_refs (repo, cancellable, error);
-  if (all_refs == NULL)
-    return FALSE;
-
-  all_commits = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, (GDestroyNotify)g_variant_unref);
-
-  GLNX_HASH_TABLE_FOREACH_KV (all_refs, FlatpakDecomposed *, ref, const char *, commit)
-    {
-      VarMetadataRef commit_metadata;
-      VarVariantRef xa_subsets_v;
-      const char *reverse_compat_arch;
-      char *new_arch = NULL;
-      g_autoptr(GVariant) commit_v = NULL;
-
-      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit, &commit_v, NULL))
-        {
-          g_warning ("Couldn't load commit %s (ref %s)", commit, flatpak_decomposed_get_ref (ref));
-          continue;
-        }
-
-      g_hash_table_insert (all_commits, flatpak_decomposed_ref (ref), g_variant_ref (commit_v));
-
-      /* Compute list of subsets */
-      commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (commit_v));
-      if (var_metadata_lookup (commit_metadata, "xa.subsets", NULL, &xa_subsets_v))
-        {
-          VarArrayofstringRef xa_subsets = var_arrayofstring_from_variant (xa_subsets_v);
-          gsize len = var_arrayofstring_get_length (xa_subsets);
-          for (gsize j = 0; j < len; j++)
-            {
-              const char *subset = var_arrayofstring_get_at (xa_subsets, j);
-
-              if (!flatpak_g_ptr_array_contains_string (subsets, subset))
-                g_ptr_array_add (subsets, g_strdup (subset));
-            }
-        }
-
-      /* Compute list of arches */
-      if (!flatpak_decomposed_is_arches (ref, arches->len, (const char **) arches->pdata))
-        {
-          new_arch = flatpak_decomposed_dup_arch (ref);
-          g_ptr_array_add (arches, new_arch);
-
-          /* If repo contains e.g. i386, also generated x86-64 appdata */
-          reverse_compat_arch = flatpak_get_compat_arch_reverse (new_arch);
-          if (reverse_compat_arch != NULL &&
-              !flatpak_g_ptr_array_contains_string (arches, reverse_compat_arch))
-            g_ptr_array_add (arches, g_strdup (reverse_compat_arch));
-        }
-    }
-
-  g_ptr_array_sort (subsets, flatpak_strcmp0_ptr);
-  g_ptr_array_sort (arches, flatpak_strcmp0_ptr);
-
-  all_refs_keys = (FlatpakDecomposed **) g_hash_table_get_keys_as_array (all_refs, &n_keys);
-
-  /* Sort refs so that appdata order is stable for e.g. deltas */
-  g_qsort_with_data (all_refs_keys, n_keys, sizeof (FlatpakDecomposed *), (GCompareDataFunc) flatpak_decomposed_strcmp_p, NULL);
-
-  transaction = flatpak_repo_transaction_start (repo, cancellable, error);
-  if (transaction == NULL)
-    return FALSE;
-
-  for (int l = 0; l < subsets->len; l++)
-    {
-      const char *subset = g_ptr_array_index (subsets, l);
-
-      for (int k = 0; k < arches->len; k++)
-        {
-          const char *arch = g_ptr_array_index (arches, k);
-
-          if (!_flatpak_repo_generate_appstream (repo,
-                                                 gpg_key_ids,
-                                                 gpg_homedir,
-                                                 all_refs_keys,
-                                                 n_keys,
-                                                 all_commits,
-                                                 arch,
-                                                 subset,
-                                                 timestamp,
-                                                 cancellable,
-                                                 error))
-            return FALSE;
-        }
-    }
-
-  if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error))
-    return FALSE;
-
-  return TRUE;
-}
-
-void
-flatpak_extension_free (FlatpakExtension *extension)
-{
-  g_free (extension->id);
-  g_free (extension->installed_id);
-  g_free (extension->commit);
-  flatpak_decomposed_unref (extension->ref);
-  g_free (extension->directory);
-  g_free (extension->files_path);
-  g_free (extension->add_ld_path);
-  g_free (extension->subdir_suffix);
-  g_strfreev (extension->merge_dirs);
-  g_free (extension);
-}
-
-static int
-flatpak_extension_compare (gconstpointer _a,
-                           gconstpointer _b)
-{
-  const FlatpakExtension *a = _a;
-  const FlatpakExtension *b = _b;
-
-  return b->priority - a->priority;
-}
-
-static FlatpakExtension *
-flatpak_extension_new (const char        *id,
-                       const char        *extension,
-                       FlatpakDecomposed *ref,
-                       const char        *directory,
-                       const char        *add_ld_path,
-                       const char        *subdir_suffix,
-                       char             **merge_dirs,
-                       GFile             *files,
-                       GFile             *deploy_dir,
-                       gboolean           is_unmaintained,
-                       OstreeRepo        *repo)
-{
-  FlatpakExtension *ext = g_new0 (FlatpakExtension, 1);
-  g_autoptr(GBytes) deploy_data = NULL;
-
-  ext->id = g_strdup (id);
-  ext->installed_id = g_strdup (extension);
-  ext->ref = flatpak_decomposed_ref (ref);
-  ext->directory = g_strdup (directory);
-  ext->files_path = g_file_get_path (files);
-  ext->add_ld_path = g_strdup (add_ld_path);
-  ext->subdir_suffix = g_strdup (subdir_suffix);
-  ext->merge_dirs = g_strdupv (merge_dirs);
-  ext->is_unmaintained = is_unmaintained;
-
-  /* Unmaintained extensions won't have a deploy or commit; see
-   * https://github.com/flatpak/flatpak/issues/167 */
-  if (deploy_dir && !is_unmaintained)
-    {
-      deploy_data = flatpak_load_deploy_data (deploy_dir, ref, repo, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
-      if (deploy_data)
-        ext->commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
-    }
-
-  if (is_unmaintained)
-    ext->priority = 1000;
-  else
-    {
-      g_autoptr(GKeyFile) keyfile = g_key_file_new ();
-      g_autofree char *metadata_path = g_build_filename (ext->files_path, "../metadata", NULL);
-
-      if (g_key_file_load_from_file (keyfile, metadata_path, G_KEY_FILE_NONE, NULL))
-        ext->priority = g_key_file_get_integer (keyfile,
-                                                FLATPAK_METADATA_GROUP_EXTENSION_OF,
-                                                FLATPAK_METADATA_KEY_PRIORITY,
-                                                NULL);
-    }
-
-  return ext;
-}
-
-gboolean
-flatpak_extension_matches_reason (const char *extension_id,
-                                  const char *reasons,
-                                  gboolean    default_value)
-{
-  const char *extension_basename;
-  g_auto(GStrv) reason_list = NULL;
-  size_t i;
-
-  if (reasons == NULL || *reasons == 0)
-    return default_value;
-
-  extension_basename = strrchr (extension_id, '.');
-  if (extension_basename == NULL)
-    return FALSE;
-  extension_basename += 1;
-
-  reason_list = g_strsplit (reasons, ";", -1);
-
-  for (i = 0; reason_list[i]; ++i)
-    {
-      const char *reason = reason_list[i];
-
-      if (strcmp (reason, "active-gl-driver") == 0)
-        {
-          /* handled below */
-          const char **gl_drivers = flatpak_get_gl_drivers ();
-          size_t j;
-
-          for (j = 0; gl_drivers[j]; j++)
-            {
-              if (strcmp (gl_drivers[j], extension_basename) == 0)
-                return TRUE;
-            }
-        }
-      else if (strcmp (reason, "active-gtk-theme") == 0)
-        {
-          const char *gtk_theme = flatpak_get_gtk_theme ();
-          if (strcmp (gtk_theme, extension_basename) == 0)
-            return TRUE;
-        }
-      else if (strcmp (reason, "have-intel-gpu") == 0)
-        {
-          /* Used for Intel VAAPI driver extension */
-          if (flatpak_get_have_intel_gpu ())
-            return TRUE;
-        }
-      else if (g_str_has_prefix (reason, "have-kernel-module-"))
-        {
-          const char *module_name = reason + strlen ("have-kernel-module-");
-
-          if (flatpak_get_have_kernel_module (module_name))
-            return TRUE;
-        }
-      else if (g_str_has_prefix (reason, "on-xdg-desktop-"))
-        {
-          const char *desktop_name = reason + strlen ("on-xdg-desktop-");
-          const char *current_desktop_var = g_getenv ("XDG_CURRENT_DESKTOP");
-          g_auto(GStrv) current_desktop_names = NULL;
-          size_t j;
-
-          if (!current_desktop_var)
-            continue;
-
-          current_desktop_names = g_strsplit (current_desktop_var, ":", -1);
-
-          for (j = 0; current_desktop_names[j]; ++j)
-            {
-              if (g_ascii_strcasecmp (desktop_name, current_desktop_names[j]) == 0)
-                return TRUE;
-            }
-        }
-    }
-
-  return FALSE;
-}
-
-static GList *
-add_extension (GKeyFile   *metakey,
-               const char *group,
-               const char *extension,
-               const char *arch,
-               const char *branch,
-               GList      *res)
-{
-  FlatpakExtension *ext;
-  g_autofree char *directory = g_key_file_get_string (metakey, group,
-                                                      FLATPAK_METADATA_KEY_DIRECTORY,
-                                                      NULL);
-  g_autofree char *add_ld_path = g_key_file_get_string (metakey, group,
-                                                        FLATPAK_METADATA_KEY_ADD_LD_PATH,
-                                                        NULL);
-  g_auto(GStrv) merge_dirs = g_key_file_get_string_list (metakey, group,
-                                                         FLATPAK_METADATA_KEY_MERGE_DIRS,
-                                                         NULL, NULL);
-  g_autofree char *enable_if = g_key_file_get_string (metakey, group,
-                                                      FLATPAK_METADATA_KEY_ENABLE_IF,
-                                                      NULL);
-  g_autofree char *subdir_suffix = g_key_file_get_string (metakey, group,
-                                                          FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
-                                                          NULL);
-  g_autoptr(FlatpakDecomposed) ref = NULL;
-  gboolean is_unmaintained = FALSE;
-  g_autoptr(GFile) files = NULL;
-  g_autoptr(GFile) deploy_dir = NULL;
-  g_autoptr(FlatpakDir) dir = NULL;
-
-  if (directory == NULL)
-    return res;
-
-  ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, extension, arch, branch, NULL);
-  if (ref == NULL)
-    return res;
-
-  files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL);
-
-  if (files == NULL)
-    {
-      deploy_dir = flatpak_find_deploy_dir_for_ref (ref, &dir, NULL, NULL);
-      if (deploy_dir)
-        files = g_file_get_child (deploy_dir, "files");
-    }
-  else
-    is_unmaintained = TRUE;
-
-  /* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */
-  if (files != NULL)
-    {
-      if (flatpak_extension_matches_reason (extension, enable_if, TRUE))
-        {
-          ext = flatpak_extension_new (extension, extension, ref, directory,
-                                       add_ld_path, subdir_suffix, merge_dirs,
-                                       files, deploy_dir, is_unmaintained,
-                                       is_unmaintained ? NULL : flatpak_dir_get_repo (dir));
-          res = g_list_prepend (res, ext);
-        }
-    }
-  else if (g_key_file_get_boolean (metakey, group,
-                                   FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL))
-    {
-      g_autofree char *prefix = g_strconcat (extension, ".", NULL);
-      g_auto(GStrv) ids = NULL;
-      g_auto(GStrv) unmaintained_refs = NULL;
-      int j;
-
-      ids = flatpak_list_deployed_refs ("runtime", prefix, arch, branch,
-                                        NULL, NULL);
-      for (j = 0; ids != NULL && ids[j] != NULL; j++)
-        {
-          const char *id = ids[j];
-          g_autofree char *extended_dir = g_build_filename (directory, id + strlen (prefix), NULL);
-          g_autoptr(FlatpakDecomposed) dir_ref = NULL;
-          g_autoptr(GFile) subdir_deploy_dir = NULL;
-          g_autoptr(GFile) subdir_files = NULL;
-          g_autoptr(FlatpakDir) subdir_dir = NULL;
-
-          dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, id, arch, branch, NULL);
-          if (dir_ref == NULL)
-            continue;
-
-          subdir_deploy_dir = flatpak_find_deploy_dir_for_ref (dir_ref, &subdir_dir, NULL, NULL);
-          if (subdir_deploy_dir)
-            subdir_files = g_file_get_child (subdir_deploy_dir, "files");
-
-          if (subdir_files && flatpak_extension_matches_reason (id, enable_if, TRUE))
-            {
-              ext = flatpak_extension_new (extension, id, dir_ref, extended_dir,
-                                           add_ld_path, subdir_suffix, merge_dirs,
-                                           subdir_files, subdir_deploy_dir, FALSE,
-                                           flatpak_dir_get_repo (subdir_dir));
-              ext->needs_tmpfs = TRUE;
-              res = g_list_prepend (res, ext);
-            }
-        }
-
-      unmaintained_refs = flatpak_list_unmaintained_refs (prefix, arch, branch,
-                                                          NULL, NULL);
-      for (j = 0; unmaintained_refs != NULL && unmaintained_refs[j] != NULL; j++)
-        {
-          g_autofree char *extended_dir = g_build_filename (directory, unmaintained_refs[j] + strlen (prefix), NULL);
-          g_autoptr(FlatpakDecomposed) dir_ref = NULL;
-          g_autoptr(GFile) subdir_files = flatpak_find_unmaintained_extension_dir_if_exists (unmaintained_refs[j], arch, branch, NULL);
-
-          dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, unmaintained_refs[j], arch, branch, NULL);
-          if (dir_ref == NULL)
-            continue;
-
-          if (subdir_files && flatpak_extension_matches_reason (unmaintained_refs[j], enable_if, TRUE))
-            {
-              ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref,
-                                           extended_dir, add_ld_path, subdir_suffix,
-                                           merge_dirs, subdir_files, NULL, TRUE, NULL);
-              ext->needs_tmpfs = TRUE;
-              res = g_list_prepend (res, ext);
-            }
-        }
-    }
-
-  return res;
-}
-
-void
-flatpak_parse_extension_with_tag (const char *extension,
-                                  char      **name,
-                                  char      **tag)
-{
-  const char *tag_chr = strchr (extension, '@');
-
-  if (tag_chr)
-    {
-      if (name != NULL)
-        *name = g_strndup (extension, tag_chr - extension);
-
-      /* Everything after the @ */
-      if (tag != NULL)
-        *tag = g_strdup (tag_chr + 1);
-
-      return;
-    }
-
-  if (name != NULL)
-    *name = g_strdup (extension);
-
-  if (tag != NULL)
-    *tag = NULL;
-}
-
-GList *
-flatpak_list_extensions (GKeyFile   *metakey,
-                         const char *arch,
-                         const char *default_branch)
-{
-  g_auto(GStrv) groups = NULL;
-  int i, j;
-  GList *res;
-
-  res = NULL;
-
-  if (arch == NULL)
-    arch = flatpak_get_arch ();
-
-  groups = g_key_file_get_groups (metakey, NULL);
-  for (i = 0; groups[i] != NULL; i++)
-    {
-      char *extension;
-
-      if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
-          *(extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
-        {
-          g_autofree char *version = g_key_file_get_string (metakey, groups[i],
-                                                            FLATPAK_METADATA_KEY_VERSION,
-                                                            NULL);
-          g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
-                                                               FLATPAK_METADATA_KEY_VERSIONS,
-                                                               NULL, NULL);
-          g_autofree char *name = NULL;
-          const char *default_branches[] = { default_branch, NULL};
-          const char **branches;
-
-          flatpak_parse_extension_with_tag (extension, &name, NULL);
-
-          if (versions)
-            branches = (const char **) versions;
-          else
-            {
-              if (version)
-                default_branches[0] = version;
-              branches = default_branches;
-            }
-
-          for (j = 0; branches[j] != NULL; j++)
-            res = add_extension (metakey, groups[i], name, arch, branches[j], res);
-        }
-    }
-
-  return g_list_sort (g_list_reverse (res), flatpak_extension_compare);
-}
-
-typedef struct
-{
-  FlatpakXml *current;
-} XmlData;
-
-FlatpakXml *
-flatpak_xml_new (const gchar *element_name)
-{
-  FlatpakXml *node = g_new0 (FlatpakXml, 1);
-
-  node->element_name = g_strdup (element_name);
-  return node;
-}
-
-FlatpakXml *
-flatpak_xml_new_text (const gchar *text)
-{
-  FlatpakXml *node = g_new0 (FlatpakXml, 1);
-
-  node->text = g_strdup (text);
-  return node;
-}
-
-void
-flatpak_xml_add (FlatpakXml *parent, FlatpakXml *node)
-{
-  node->parent = parent;
-
-  if (parent->first_child == NULL)
-    parent->first_child = node;
-  else
-    parent->last_child->next_sibling = node;
-  parent->last_child = node;
-}
-
-static void
-xml_start_element (GMarkupParseContext *context,
-                   const gchar         *element_name,
-                   const gchar        **attribute_names,
-                   const gchar        **attribute_values,
-                   gpointer             user_data,
-                   GError             **error)
-{
-  XmlData *data = user_data;
-  FlatpakXml *node;
-
-  node = flatpak_xml_new (element_name);
-  node->attribute_names = g_strdupv ((char **) attribute_names);
-  node->attribute_values = g_strdupv ((char **) attribute_values);
-
-  flatpak_xml_add (data->current, node);
-  data->current = node;
-}
-
-static void
-xml_end_element (GMarkupParseContext *context,
-                 const gchar         *element_name,
-                 gpointer             user_data,
-                 GError             **error)
-{
-  XmlData *data = user_data;
-
-  data->current = data->current->parent;
-}
-
-static void
-xml_text (GMarkupParseContext *context,
-          const gchar         *text,
-          gsize                text_len,
-          gpointer             user_data,
-          GError             **error)
-{
-  XmlData *data = user_data;
-  FlatpakXml *node;
-
-  node = flatpak_xml_new (NULL);
-  node->text = g_strndup (text, text_len);
-  flatpak_xml_add (data->current, node);
-}
-
-static void
-xml_passthrough (GMarkupParseContext *context,
-                 const gchar         *passthrough_text,
-                 gsize                text_len,
-                 gpointer             user_data,
-                 GError             **error)
-{
-}
-
-static GMarkupParser xml_parser = {
-  xml_start_element,
-  xml_end_element,
-  xml_text,
-  xml_passthrough,
-  NULL
-};
-
-void
-flatpak_xml_free (FlatpakXml *node)
-{
-  FlatpakXml *child;
-
-  if (node == NULL)
-    return;
-
-  child = node->first_child;
-  while (child != NULL)
-    {
-      FlatpakXml *next = child->next_sibling;
-      flatpak_xml_free (child);
-      child = next;
-    }
-
-  g_free (node->element_name);
-  g_free (node->text);
-  g_strfreev (node->attribute_names);
-  g_strfreev (node->attribute_values);
-  g_free (node);
-}
-
-
-void
-flatpak_xml_to_string (FlatpakXml *node, GString *res)
-{
-  int i;
-  FlatpakXml *child;
-
-  if (node->parent == NULL)
-    g_string_append (res, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-
-  if (node->element_name)
-    {
-      if (node->parent != NULL)
-        {
-          g_string_append (res, "<");
-          g_string_append (res, node->element_name);
-          if (node->attribute_names)
-            {
-              for (i = 0; node->attribute_names[i] != NULL; i++)
-                {
-                  g_string_append_printf (res, " %s=\"%s\"",
-                                          node->attribute_names[i],
-                                          node->attribute_values[i]);
-                }
-            }
-          if (node->first_child == NULL)
-            g_string_append (res, "/>");
-          else
-            g_string_append (res, ">");
-        }
-
-      child = node->first_child;
-      while (child != NULL)
-        {
-          flatpak_xml_to_string (child, res);
-          child = child->next_sibling;
-        }
-      if (node->parent != NULL)
-        {
-          if (node->first_child != NULL)
-            g_string_append_printf (res, "</%s>", node->element_name);
-        }
-    }
-  else if (node->text)
-    {
-      g_autofree char *escaped = g_markup_escape_text (node->text, -1);
-      g_string_append (res, escaped);
-    }
-}
-
-FlatpakXml *
-flatpak_xml_unlink (FlatpakXml *node,
-                    FlatpakXml *prev_sibling)
-{
-  FlatpakXml *parent = node->parent;
-
-  if (parent == NULL)
-    return node;
-
-  if (parent->first_child == node)
-    parent->first_child = node->next_sibling;
-
-  if (parent->last_child == node)
-    parent->last_child = prev_sibling;
-
-  if (prev_sibling)
-    prev_sibling->next_sibling = node->next_sibling;
-
-  node->parent = NULL;
-  node->next_sibling = NULL;
-
-  return node;
-}
-
-FlatpakXml *
-flatpak_xml_find (FlatpakXml  *node,
-                  const char  *type,
-                  FlatpakXml **prev_child_out)
-{
-  FlatpakXml *child = NULL;
-  FlatpakXml *prev_child = NULL;
-
-  child = node->first_child;
-  prev_child = NULL;
-  while (child != NULL)
-    {
-      FlatpakXml *next = child->next_sibling;
-
-      if (g_strcmp0 (child->element_name, type) == 0)
-        {
-          if (prev_child_out)
-            *prev_child_out = prev_child;
-          return child;
-        }
-
-      prev_child = child;
-      child = next;
-    }
-
-  return NULL;
-}
-
-
-FlatpakXml *
-flatpak_xml_parse (GInputStream *in,
-                   gboolean      compressed,
-                   GCancellable *cancellable,
-                   GError      **error)
-{
-  g_autoptr(GInputStream) real_in = NULL;
-  g_autoptr(FlatpakXml) xml_root = NULL;
-  XmlData data = { 0 };
-  char buffer[32 * 1024];
-  gssize len;
-  g_autoptr(GMarkupParseContext) ctx = NULL;
-
-  if (compressed)
-    {
-      g_autoptr(GZlibDecompressor) decompressor = NULL;
-      decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
-      real_in = g_converter_input_stream_new (in, G_CONVERTER (decompressor));
-    }
-  else
-    {
-      real_in = g_object_ref (in);
-    }
-
-  xml_root = flatpak_xml_new ("root");
-  data.current = xml_root;
-
-  ctx = g_markup_parse_context_new (&xml_parser,
-                                    G_MARKUP_PREFIX_ERROR_POSITION,
-                                    &data,
-                                    NULL);
-
-  while ((len = g_input_stream_read (real_in, buffer, sizeof (buffer),
-                                     cancellable, error)) > 0)
-    {
-      if (!g_markup_parse_context_parse (ctx, buffer, len, error))
-        return NULL;
-    }
-
-  if (len < 0)
-    return NULL;
-
-  return g_steal_pointer (&xml_root);
-}
-
-#define OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "(uayttay)"
-#define OSTREE_STATIC_DELTA_FALLBACK_FORMAT "(yaytt)"
-#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")"
-
-static inline guint64
-maybe_swap_endian_u64 (gboolean swap,
-                       guint64  v)
-{
-  if (!swap)
-    return v;
-  return GUINT64_SWAP_LE_BE (v);
-}
-
-static guint64
-flatpak_bundle_get_installed_size (GVariant *bundle, gboolean byte_swap)
-{
-  guint64 total_usize = 0;
-  g_autoptr(GVariant) meta_entries = NULL;
-  guint i, n_parts;
-
-  g_variant_get_child (bundle, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries);
-  n_parts = g_variant_n_children (meta_entries);
-
-  for (i = 0; i < n_parts; i++)
-    {
-      guint32 version;
-      guint64 size, usize;
-      g_autoptr(GVariant) objects = NULL;
-
-      g_variant_get_child (meta_entries, i, "(u@aytt@ay)",
-                           &version, NULL, &size, &usize, &objects);
-
-      total_usize += maybe_swap_endian_u64 (byte_swap, usize);
-    }
-
-  return total_usize;
-}
-
-GVariant *
-flatpak_bundle_load (GFile              *file,
-                     char              **commit,
-                     FlatpakDecomposed **ref,
-                     char              **origin,
-                     char              **runtime_repo,
-                     char              **app_metadata,
-                     guint64            *installed_size,
-                     GBytes            **gpg_keys,
-                     char              **collection_id,
-                     GError             **error)
-{
-  g_autoptr(GVariant) delta = NULL;
-  g_autoptr(GVariant) metadata = NULL;
-  g_autoptr(GBytes) bytes = NULL;
-  g_autoptr(GBytes) copy = NULL;
-  g_autoptr(GVariant) to_csum_v = NULL;
-
-  guint8 endianness_char;
-  gboolean byte_swap = FALSE;
-
-  GMappedFile *mfile = g_mapped_file_new (flatpak_file_get_path_cached (file), FALSE, error);
-
-  if (mfile == NULL)
-    return NULL;
-
-  bytes = g_mapped_file_get_bytes (mfile);
-  g_mapped_file_unref (mfile);
-
-  delta = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE);
-  g_variant_ref_sink (delta);
-
-  to_csum_v = g_variant_get_child_value (delta, 3);
-  if (!ostree_validate_structureof_csum_v (to_csum_v, error))
-    return NULL;
-
-  metadata = g_variant_get_child_value (delta, 0);
-
-  if (g_variant_lookup (metadata, "ostree.endianness", "y", &endianness_char))
-    {
-      int file_byte_order = G_BYTE_ORDER;
-      switch (endianness_char)
-        {
-        case 'l':
-          file_byte_order = G_LITTLE_ENDIAN;
-          break;
-
-        case 'B':
-          file_byte_order = G_BIG_ENDIAN;
-          break;
-
-        default:
-          break;
-        }
-      byte_swap = (G_BYTE_ORDER != file_byte_order);
-    }
-
-  if (commit)
-    *commit = ostree_checksum_from_bytes_v (to_csum_v);
-
-  if (installed_size)
-    *installed_size = flatpak_bundle_get_installed_size (delta, byte_swap);
-
-  if (ref != NULL)
-    {
-      FlatpakDecomposed *the_ref = NULL;
-      g_autofree char *ref_str = NULL;
-
-      if (!g_variant_lookup (metadata, "ref", "s", &ref_str))
-        {
-          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid bundle, no ref in metadata"));
-          return NULL;
-        }
-
-      the_ref = flatpak_decomposed_new_from_ref (ref_str, error);
-      if (the_ref == NULL)
-        return NULL;
-
-      g_clear_pointer (ref, flatpak_decomposed_unref);
-      *ref = the_ref;
-    }
-
-  if (origin != NULL)
-    {
-      if (!g_variant_lookup (metadata, "origin", "s", origin))
-        *origin = NULL;
-    }
-
-  if (runtime_repo != NULL)
-    {
-      if (!g_variant_lookup (metadata, "runtime-repo", "s", runtime_repo))
-        *runtime_repo = NULL;
-    }
-
-  if (collection_id != NULL)
-    {
-      if (!g_variant_lookup (metadata, "collection-id", "s", collection_id))
-        {
-          *collection_id = NULL;
-        }
-      else if (**collection_id == '\0')
-        {
-          g_free (*collection_id);
-          *collection_id = NULL;
+          const char *gtk_theme = flatpak_get_gtk_theme ();
+          if (strcmp (gtk_theme, extension_basename) == 0)
+            return TRUE;
         }
-    }
-
-  if (app_metadata != NULL)
-    {
-      if (!g_variant_lookup (metadata, "metadata", "s", app_metadata))
-        *app_metadata = NULL;
-    }
-
-  if (gpg_keys != NULL)
-    {
-      g_autoptr(GVariant) gpg_value = g_variant_lookup_value (metadata, "gpg-keys",
-                                                              G_VARIANT_TYPE ("ay"));
-      if (gpg_value)
+      else if (strcmp (reason, "have-intel-gpu") == 0)
         {
-          gsize n_elements;
-          const char *data = g_variant_get_fixed_array (gpg_value, &n_elements, 1);
-          *gpg_keys = g_bytes_new (data, n_elements);
+          /* Used for Intel VAAPI driver extension */
+          if (flatpak_get_have_intel_gpu ())
+            return TRUE;
         }
-      else
+      else if (g_str_has_prefix (reason, "have-kernel-module-"))
         {
-          *gpg_keys = NULL;
-        }
-    }
-
-  /* Make a copy of the data so we can return it after freeing the file */
-  copy = g_bytes_new (g_variant_get_data (metadata),
-                      g_variant_get_size (metadata));
-  return g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (metadata),
-                                                       copy,
-                                                       FALSE));
-}
-
-gboolean
-flatpak_pull_from_bundle (OstreeRepo   *repo,
-                          GFile        *file,
-                          const char   *remote,
-                          const char   *ref,
-                          gboolean      require_gpg_signature,
-                          GCancellable *cancellable,
-                          GError      **error)
-{
-  gsize metadata_size = 0;
-  g_autofree char *metadata_contents = NULL;
-  g_autofree char *to_checksum = NULL;
-  g_autoptr(GFile) root = NULL;
-  g_autoptr(GFile) metadata_file = NULL;
-  g_autoptr(GInputStream) in = NULL;
-  g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
-  g_autoptr(GError) my_error = NULL;
-  g_autoptr(GVariant) metadata = NULL;
-  gboolean metadata_valid;
-  g_autofree char *remote_collection_id = NULL;
-  g_autofree char *collection_id = NULL;
-
-  metadata = flatpak_bundle_load (file, &to_checksum, NULL, NULL, NULL, &metadata_contents, NULL, NULL, &collection_id, error);
-  if (metadata == NULL)
-    return FALSE;
-
-  if (metadata_contents != NULL)
-    metadata_size = strlen (metadata_contents);
-
-  if (!ostree_repo_get_remote_option (repo, remote, "collection-id", NULL,
-                                      &remote_collection_id, NULL))
-    remote_collection_id = NULL;
-
-  if (remote_collection_id != NULL && collection_id != NULL &&
-      strcmp (remote_collection_id, collection_id) != 0)
-    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Collection ‘%s’ of bundle doesn’t match collection ‘%s’ of remote"),
-                               collection_id, remote_collection_id);
-
-  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
-    return FALSE;
-
-  /* Don’t need to set the collection ID here, since the remote binds this ref to the collection. */
-  ostree_repo_transaction_set_ref (repo, remote, ref, to_checksum);
-
-  if (!ostree_repo_static_delta_execute_offline (repo,
-                                                 file,
-                                                 FALSE,
-                                                 cancellable,
-                                                 error))
-    return FALSE;
+          const char *module_name = reason + strlen ("have-kernel-module-");
 
-  gpg_result = ostree_repo_verify_commit_ext (repo, to_checksum,
-                                              NULL, NULL, cancellable, &my_error);
-  if (gpg_result == NULL)
-    {
-      /* no gpg signature, we ignore this *if* there is no gpg key
-       * specified in the bundle or by the user */
-      if (g_error_matches (my_error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE) &&
-          !require_gpg_signature)
-        {
-          g_clear_error (&my_error);
-        }
-      else
-        {
-          g_propagate_error (error, g_steal_pointer (&my_error));
-          return FALSE;
+          if (flatpak_get_have_kernel_module (module_name))
+            return TRUE;
         }
-    }
-  else
-    {
-      /* If there is no valid gpg signature we fail, unless there is no gpg
-         key specified (on the command line or in the file) because then we
-         trust the source bundle. */
-      if (ostree_gpg_verify_result_count_valid (gpg_result) == 0  &&
-          require_gpg_signature)
-        return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("GPG signatures found, but none are in trusted keyring"));
-    }
-
-  if (!ostree_repo_read_commit (repo, to_checksum, &root, NULL, NULL, error))
-    return FALSE;
-
-  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
-    return FALSE;
-
-  /* We ensure that the actual installed metadata matches the one in the
-     header, because you may have made decisions on whether to install it or not
-     based on that data. */
-  metadata_file = g_file_resolve_relative_path (root, "metadata");
-  in = (GInputStream *) g_file_read (metadata_file, cancellable, NULL);
-  if (in != NULL)
-    {
-      g_autoptr(GMemoryOutputStream) data_stream = (GMemoryOutputStream *) g_memory_output_stream_new_resizable ();
-
-      if (g_output_stream_splice (G_OUTPUT_STREAM (data_stream), in,
-                                  G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
-                                  cancellable, error) < 0)
-        return FALSE;
-
-      metadata_valid =
-        metadata_contents != NULL &&
-        metadata_size == g_memory_output_stream_get_data_size (data_stream) &&
-        memcmp (metadata_contents, g_memory_output_stream_get_data (data_stream), metadata_size) == 0;
-    }
-  else
-    {
-      metadata_valid = (metadata_contents == NULL);
-    }
-
-  if (!metadata_valid)
-    {
-      /* Immediately remove this broken commit */
-      ostree_repo_set_ref_immediate (repo, remote, ref, NULL, cancellable, error);
-      return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Metadata in header and app are inconsistent"));
-    }
-
-  return TRUE;
-}
-
-typedef struct
-{
-  FlatpakOciPullProgress progress_cb;
-  gpointer               progress_user_data;
-  guint64                total_size;
-  guint64                previous_layers_size;
-  guint32                n_layers;
-  guint32                pulled_layers;
-} FlatpakOciPullProgressData;
-
-static void
-oci_layer_progress (guint64  downloaded_bytes,
-                    gpointer user_data)
-{
-  FlatpakOciPullProgressData *progress_data = user_data;
-
-  if (progress_data->progress_cb)
-    progress_data->progress_cb (progress_data->total_size, progress_data->previous_layers_size + downloaded_bytes,
-                                progress_data->n_layers, progress_data->pulled_layers,
-                                progress_data->progress_user_data);
-}
-
-gboolean
-flatpak_mirror_image_from_oci (FlatpakOciRegistry    *dst_registry,
-                               FlatpakOciRegistry    *registry,
-                               const char            *oci_repository,
-                               const char            *digest,
-                               const char            *remote,
-                               const char            *ref,
-                               const char            *delta_url,
-                               OstreeRepo            *repo,
-                               FlatpakOciPullProgress progress_cb,
-                               gpointer               progress_user_data,
-                               GCancellable          *cancellable,
-                               GError               **error)
-{
-  FlatpakOciPullProgressData progress_data = { progress_cb, progress_user_data };
-  g_autoptr(FlatpakOciVersioned) versioned = NULL;
-  FlatpakOciManifest *manifest = NULL;
-  g_autoptr(FlatpakOciDescriptor) manifest_desc = NULL;
-  g_autoptr(FlatpakOciManifest) delta_manifest = NULL;
-  g_autofree char *old_checksum = NULL;
-  g_autoptr(GVariant) old_commit = NULL;
-  g_autoptr(GFile) old_root = NULL;
-  OstreeRepoCommitState old_state = 0;
-  g_autofree char *old_diffid = NULL;
-  gsize versioned_size;
-  g_autoptr(FlatpakOciIndex) index = NULL;
-  g_autoptr(FlatpakOciImage) image_config = NULL;
-  int n_layers;
-  int i;
-
-  if (!flatpak_oci_registry_mirror_blob (dst_registry, registry, oci_repository, TRUE, digest, NULL, NULL, NULL, cancellable, error))
-    return FALSE;
-
-  versioned = flatpak_oci_registry_load_versioned (dst_registry, NULL, digest, NULL, &versioned_size, cancellable, error);
-  if (versioned == NULL)
-    return FALSE;
-
-  if (!FLATPAK_IS_OCI_MANIFEST (versioned))
-    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Image is not a manifest"));
-
-  manifest = FLATPAK_OCI_MANIFEST (versioned);
-
-  if (manifest->config.digest == NULL)
-    return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Image is not a manifest"));
-
-  if (!flatpak_oci_registry_mirror_blob (dst_registry, registry, oci_repository, FALSE, manifest->config.digest, (const char **)manifest->config.urls, NULL, NULL, cancellable, error))
-    return FALSE;
-
-  image_config = flatpak_oci_registry_load_image_config (dst_registry, NULL,
-                                                         manifest->config.digest, NULL,
-                                                         NULL, cancellable, error);
-  if (image_config == NULL)
-    return FALSE;
-
-  /* For deltas we ensure that the diffid and regular layers exists and match up */
-  n_layers = flatpak_oci_manifest_get_n_layers (manifest);
-  if (n_layers == 0 || n_layers != flatpak_oci_image_get_n_layers (image_config))
-    return flatpak_fail (error, _("Invalid OCI image config"));
-
-  /* Look for delta manifest, and if it exists, the current (old) commit and its recorded diffid */
-  if (flatpak_repo_resolve_rev (repo, NULL, remote, ref, FALSE, &old_checksum, NULL, NULL) &&
-      ostree_repo_load_commit (repo, old_checksum, &old_commit, &old_state, NULL) &&
-      (old_state == OSTREE_REPO_COMMIT_STATE_NORMAL) &&
-      ostree_repo_read_commit (repo, old_checksum, &old_root, NULL, NULL, NULL))
-    {
-      delta_manifest = flatpak_oci_registry_find_delta_manifest (registry, oci_repository, digest, delta_url, cancellable);
-      if (delta_manifest)
+      else if (g_str_has_prefix (reason, "on-xdg-desktop-"))
         {
-          VarMetadataRef commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (old_commit));
-          const char *raw_old_diffid = var_metadata_lookup_string (commit_metadata, "xa.diff-id", NULL);
-          if (raw_old_diffid != NULL)
-            old_diffid = g_strconcat ("sha256:", raw_old_diffid, NULL);
-        }
-    }
-
-  for (i = 0; manifest->layers[i] != NULL; i++)
-    {
-      FlatpakOciDescriptor *layer = manifest->layers[i];
-      FlatpakOciDescriptor *delta_layer = NULL;
-
-      if (delta_manifest)
-        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);
-
-      if (delta_layer)
-        progress_data.total_size += delta_layer->size;
-      else
-        progress_data.total_size += layer->size;
-      progress_data.n_layers++;
-    }
-
-  if (progress_cb)
-    progress_cb (progress_data.total_size, 0,
-                 progress_data.n_layers, progress_data.pulled_layers,
-                 progress_user_data);
-
-  for (i = 0; manifest->layers[i] != NULL; i++)
-    {
-      FlatpakOciDescriptor *layer = manifest->layers[i];
-      FlatpakOciDescriptor *delta_layer = NULL;
-
-      if (delta_manifest)
-        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);
+          const char *desktop_name = reason + strlen ("on-xdg-desktop-");
+          const char *current_desktop_var = g_getenv ("XDG_CURRENT_DESKTOP");
+          g_auto(GStrv) current_desktop_names = NULL;
+          size_t j;
 
-      if (delta_layer)
-        {
-          g_info ("Using OCI delta %s for layer %s", delta_layer->digest, layer->digest);
-          g_autofree char *delta_digest = NULL;
-          glnx_autofd int delta_fd = flatpak_oci_registry_download_blob (registry, oci_repository, FALSE,
-                                                                         delta_layer->digest, (const char **)delta_layer->urls,
-                                                                         oci_layer_progress, &progress_data,
-                                                                         cancellable, error);
-          if (delta_fd == -1)
-            return FALSE;
+          if (!current_desktop_var)
+            continue;
 
-          delta_digest = flatpak_oci_registry_apply_delta_to_blob (dst_registry, delta_fd, old_root, cancellable, error);
-          if (delta_digest == NULL)
-            return FALSE;
+          current_desktop_names = g_strsplit (current_desktop_var, ":", -1);
 
-          if (g_strcmp0 (delta_digest, image_config->rootfs.diff_ids[i]) != 0)
-            return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong layer checksum, expected %s, was %s"), image_config->rootfs.diff_ids[i], delta_digest);
-        }
-      else
-        {
-          if (!flatpak_oci_registry_mirror_blob (dst_registry, registry, oci_repository, FALSE, layer->digest, (const char **)layer->urls,
-                                                 oci_layer_progress, &progress_data,
-                                                 cancellable, error))
-            return FALSE;
+          for (j = 0; current_desktop_names[j]; ++j)
+            {
+              if (g_ascii_strcasecmp (desktop_name, current_desktop_names[j]) == 0)
+                return TRUE;
+            }
         }
-
-      progress_data.pulled_layers++;
-      progress_data.previous_layers_size += delta_layer ? delta_layer->size : layer->size;
     }
 
-  index = flatpak_oci_registry_load_index (dst_registry, NULL, NULL);
-  if (index == NULL)
-    index = flatpak_oci_index_new ();
-
-  manifest_desc = flatpak_oci_descriptor_new (versioned->mediatype, digest, versioned_size);
-
-  flatpak_oci_index_add_manifest (index, ref, manifest_desc);
-
-  if (!flatpak_oci_registry_save_index (dst_registry, index, cancellable, error))
-    return FALSE;
-
-  return TRUE;
+  return FALSE;
 }
 
-char *
-flatpak_pull_from_oci (OstreeRepo            *repo,
-                       FlatpakOciRegistry    *registry,
-                       const char            *oci_repository,
-                       const char            *digest,
-                       const char            *delta_url,
-                       FlatpakOciManifest    *manifest,
-                       FlatpakOciImage       *image_config,
-                       const char            *remote,
-                       const char            *ref,
-                       FlatpakPullFlags       flags,
-                       FlatpakOciPullProgress progress_cb,
-                       gpointer               progress_user_data,
-                       GCancellable          *cancellable,
-                       GError               **error)
+void
+flatpak_parse_extension_with_tag (const char *extension,
+                                  char      **name,
+                                  char      **tag)
 {
-  gboolean force_disable_deltas = (flags & FLATPAK_PULL_FLAGS_NO_STATIC_DELTAS) != 0;
-  g_autoptr(OstreeMutableTree) archive_mtree = NULL;
-  g_autoptr(GFile) archive_root = NULL;
-  g_autoptr(FlatpakOciManifest) delta_manifest = NULL;
-  g_autofree char *old_checksum = NULL;
-  g_autoptr(GVariant) old_commit = NULL;
-  g_autoptr(GFile) old_root = NULL;
-  OstreeRepoCommitState old_state = 0;
-  g_autofree char *old_diffid = NULL;
-  g_autofree char *commit_checksum = NULL;
-  const char *parent = NULL;
-  g_autofree char *subject = NULL;
-  g_autofree char *body = NULL;
-  g_autofree char *manifest_ref = NULL;
-  g_autofree char *full_ref = NULL;
-  const char *diffid;
-  guint64 timestamp = 0;
-  FlatpakOciPullProgressData progress_data = { progress_cb, progress_user_data };
-  g_autoptr(GVariantBuilder) metadata_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
-  g_autoptr(GVariant) metadata = NULL;
-  GHashTable *labels;
-  int n_layers;
-  int i;
-
-  g_assert (ref != NULL);
-  g_assert (g_str_has_prefix (digest, "sha256:"));
-
-  labels = flatpak_oci_image_get_labels (image_config);
-  if (labels)
-    flatpak_oci_parse_commit_labels (labels, &timestamp,
-                                     &subject, &body,
-                                     &manifest_ref, NULL, NULL,
-                                     metadata_builder);
-
-  if (manifest_ref == NULL)
-    {
-      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("No ref specified for OCI image %s"), digest);
-      return NULL;
-    }
-
-  if (strcmp (manifest_ref, ref) != 0)
-    {
-      flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong ref (%s) specified for OCI image %s, expected %s"), manifest_ref, digest, ref);
-      return NULL;
-    }
-
-  g_variant_builder_add (metadata_builder, "{s@v}", "xa.alt-id",
-                         g_variant_new_variant (g_variant_new_string (digest + strlen ("sha256:"))));
-
-  /* For deltas we ensure that the diffid and regular layers exists and match up */
-  n_layers = flatpak_oci_manifest_get_n_layers (manifest);
-  if (n_layers == 0 || n_layers != flatpak_oci_image_get_n_layers (image_config))
-    {
-      flatpak_fail (error, _("Invalid OCI image config"));
-      return NULL;
-    }
-
-  /* Assuming everyting looks good, we record the uncompressed checksum (the diff-id) of the last layer,
-     because that is what we can read back easily from the deploy dir, and thus is easy to use for applying deltas */
-  diffid = image_config->rootfs.diff_ids[n_layers-1];
-  if (diffid != NULL && g_str_has_prefix (diffid, "sha256:"))
-    g_variant_builder_add (metadata_builder, "{s@v}", "xa.diff-id",
-                           g_variant_new_variant (g_variant_new_string (diffid + strlen ("sha256:"))));
-
-  /* Look for delta manifest, and if it exists, the current (old) commit and its recorded diffid */
-  if (!force_disable_deltas &&
-      !flatpak_oci_registry_is_local (registry) &&
-      flatpak_repo_resolve_rev (repo, NULL, remote, ref, FALSE, &old_checksum, NULL, NULL) &&
-      ostree_repo_load_commit (repo, old_checksum, &old_commit, &old_state, NULL) &&
-      (old_state == OSTREE_REPO_COMMIT_STATE_NORMAL) &&
-      ostree_repo_read_commit (repo, old_checksum, &old_root, NULL, NULL, NULL))
-    {
-      delta_manifest = flatpak_oci_registry_find_delta_manifest (registry, oci_repository, digest, delta_url, cancellable);
-      if (delta_manifest)
-        {
-          VarMetadataRef commit_metadata = var_commit_get_metadata (var_commit_from_gvariant (old_commit));
-          const char *raw_old_diffid = var_metadata_lookup_string (commit_metadata, "xa.diff-id", NULL);
-          if (raw_old_diffid != NULL)
-            old_diffid = g_strconcat ("sha256:", raw_old_diffid, NULL);
-        }
-    }
-
-  if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
-    return NULL;
-
-  /* There is no way to write a subset of the archive to a mtree, so instead
-     we write all of it and then build a new mtree with the subset */
-  archive_mtree = ostree_mutable_tree_new ();
-
-  for (i = 0; manifest->layers[i] != NULL; i++)
-    {
-      FlatpakOciDescriptor *layer = manifest->layers[i];
-      FlatpakOciDescriptor *delta_layer = NULL;
-
-      if (delta_manifest)
-        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);
-
-      if (delta_layer)
-        progress_data.total_size += delta_layer->size;
-      else
-        progress_data.total_size += layer->size;
-
-      progress_data.n_layers++;
-    }
-
-  if (progress_cb)
-    progress_cb (progress_data.total_size, 0,
-                 progress_data.n_layers, progress_data.pulled_layers,
-                 progress_user_data);
+  const char *tag_chr = strchr (extension, '@');
 
-  for (i = 0; manifest->layers[i] != NULL; i++)
+  if (tag_chr)
     {
-      FlatpakOciDescriptor *layer = manifest->layers[i];
-      FlatpakOciDescriptor *delta_layer = NULL;
-      OstreeRepoImportArchiveOptions opts = { 0, };
-      g_autoptr(FlatpakAutoArchiveRead) a = NULL;
-      glnx_autofd int layer_fd = -1;
-      glnx_autofd int blob_fd = -1;
-      g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
-      g_autoptr(GError) local_error = NULL;
-      const char *layer_checksum;
-      const char *expected_digest;
-
-      if (delta_manifest)
-        delta_layer = flatpak_oci_manifest_find_delta_for (delta_manifest, old_diffid, image_config->rootfs.diff_ids[i]);
-
-      opts.autocreate_parents = TRUE;
-      opts.ignore_unsupported_content = TRUE;
-
-      if (delta_layer)
-        {
-          g_info ("Using OCI delta %s for layer %s", delta_layer->digest, layer->digest);
-          expected_digest = image_config->rootfs.diff_ids[i]; /* The delta recreates the uncompressed tar so use that digest */
-        }
-      else
-        {
-          layer_fd = g_steal_fd (&blob_fd);
-          expected_digest = layer->digest;
-        }
-
-      blob_fd = flatpak_oci_registry_download_blob (registry, oci_repository, FALSE,
-                                                    delta_layer ? delta_layer->digest : layer->digest,
-                                                    (const char **)(delta_layer ? delta_layer->urls : layer->urls),
-                                                    oci_layer_progress, &progress_data,
-                                                    cancellable, &local_error);
-
-      if (blob_fd == -1 && delta_layer == NULL &&
-          flatpak_oci_registry_is_local (registry) &&
-          g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-        {
-          /* Pulling regular layer from local repo and its not there, try the uncompressed version.
-           * This happens when we deploy via system helper using oci deltas */
-          expected_digest = image_config->rootfs.diff_ids[i];
-          blob_fd = flatpak_oci_registry_download_blob (registry, oci_repository, FALSE,
-                                                        image_config->rootfs.diff_ids[i], NULL,
-                                                        oci_layer_progress, &progress_data,
-                                                        cancellable, NULL); /* No error here, we report the first error if this failes */
-        }
-
-      if (blob_fd == -1)
-        {
-          g_propagate_error (error, g_steal_pointer (&local_error));
-          goto error;
-        }
-
-      g_clear_error (&local_error);
-
-      if (delta_layer)
-        {
-          layer_fd = flatpak_oci_registry_apply_delta (registry, blob_fd, old_root, cancellable, error);
-          if (layer_fd == -1)
-            goto error;
-        }
-      else
-        {
-          layer_fd = g_steal_fd (&blob_fd);
-        }
-
-      a = archive_read_new ();
-#ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL
-      archive_read_support_filter_all (a);
-#else
-      archive_read_support_compression_all (a);
-#endif
-      archive_read_support_format_all (a);
-
-      if (!flatpak_archive_read_open_fd_with_checksum (a, layer_fd, checksum, error))
-        goto error;
-
-      if (!ostree_repo_import_archive_to_mtree (repo, &opts, a, archive_mtree, NULL, cancellable, error))
-        goto error;
-
-      if (archive_read_close (a) != ARCHIVE_OK)
-        {
-          propagate_libarchive_error (error, a);
-          goto error;
-        }
+      if (name != NULL)
+        *name = g_strndup (extension, tag_chr - extension);
 
-      layer_checksum = g_checksum_get_string (checksum);
-      if (!g_str_has_prefix (expected_digest, "sha256:") ||
-          strcmp (expected_digest + strlen ("sha256:"), layer_checksum) != 0)
-        {
-          flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Wrong layer checksum, expected %s, was %s"), expected_digest, layer_checksum);
-          goto error;
-        }
+      /* Everything after the @ */
+      if (tag != NULL)
+        *tag = g_strdup (tag_chr + 1);
 
-      progress_data.pulled_layers++;
-      progress_data.previous_layers_size += delta_layer ? delta_layer->size : layer->size;
+      return;
     }
 
-  if (!ostree_repo_write_mtree (repo, archive_mtree, &archive_root, cancellable, error))
-    goto error;
-
-  if (!ostree_repo_file_ensure_resolved ((OstreeRepoFile *) archive_root, error))
-    goto error;
-
-  metadata = g_variant_ref_sink (g_variant_builder_end (metadata_builder));
-  if (!ostree_repo_write_commit_with_time (repo,
-                                           parent,
-                                           subject,
-                                           body,
-                                           metadata,
-                                           OSTREE_REPO_FILE (archive_root),
-                                           timestamp,
-                                           &commit_checksum,
-                                           cancellable, error))
-    goto error;
-
-  if (remote)
-    full_ref = g_strdup_printf ("%s:%s", remote, ref);
-  else
-    full_ref = g_strdup (ref);
-
-  /* Don’t need to set the collection ID here, since the ref is bound to a
-   * collection via its remote. */
-  ostree_repo_transaction_set_ref (repo, NULL, full_ref, commit_checksum);
-
-  if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
-    return NULL;
-
-  return g_steal_pointer (&commit_checksum);
-
-error:
+  if (name != NULL)
+    *name = g_strdup (extension);
 
-  ostree_repo_abort_transaction (repo, cancellable, NULL);
-  return NULL;
+  if (tag != NULL)
+    *tag = NULL;
 }
 
 /* This allocates and locks a subdir of the tmp dir, using an existing
@@ -7487,23 +1944,7 @@ flatpak_g_ptr_array_contains_string (GPtrArray *array, const char *str)
   return FALSE;
 }
 
-void
-flatpak_log_dir_access (FlatpakDir *dir)
-{
-  if (dir != NULL)
-    {
-      GFile *dir_path = NULL;
-      g_autofree char *dir_path_str = NULL;
-      g_autofree char *dir_name = NULL;
-
-      dir_path = flatpak_dir_get_path (dir);
-      if (dir_path != NULL)
-        dir_path_str = g_file_get_path (dir_path);
-      dir_name = flatpak_dir_get_name (dir);
-      g_info ("Opening %s flatpak installation at path %s", dir_name, dir_path_str);
-    }
-}
-
+#if 0
 gboolean
 flatpak_check_required_version (const char *ref,
                                 GKeyFile   *metakey,
@@ -7584,6 +2025,7 @@ flatpak_check_required_version (const char *ref,
 
   return TRUE;
 }
+#endif
 
 static int
 dist (const char *s, int ls, const char *t, int lt, int i, int j, int *d)
@@ -7640,69 +2082,6 @@ flatpak_levenshtein_distance (const char *s,
   return dist (s, ls, t, lt, 0, 0, d);
 }
 
-/* Wrapper that uses ostree_repo_resolve_collection_ref() and on failure falls
- * back to using ostree_repo_resolve_rev() for backwards compatibility. This
- * means we support refs/heads/, refs/remotes/, and refs/mirrors/. */
-gboolean
-flatpak_repo_resolve_rev (OstreeRepo    *repo,
-                          const char    *collection_id, /* nullable */
-                          const char    *remote_name, /* nullable */
-                          const char    *ref_name,
-                          gboolean       allow_noent,
-                          char         **out_rev,
-                          GCancellable  *cancellable,
-                          GError       **error)
-{
-  g_autoptr(GError) local_error = NULL;
-
-  if (collection_id != NULL)
-    {
-      /* Do a version check to ensure we have these:
-       * https://github.com/ostreedev/ostree/pull/1821
-       * https://github.com/ostreedev/ostree/pull/1825 */
-#if OSTREE_CHECK_VERSION (2019, 2)
-      const OstreeCollectionRef c_r =
-        {
-          .collection_id = (char *) collection_id,
-          .ref_name = (char *) ref_name,
-        };
-      OstreeRepoResolveRevExtFlags flags = remote_name == NULL ?
-                                           OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY :
-                                           OSTREE_REPO_RESOLVE_REV_EXT_NONE;
-      if (ostree_repo_resolve_collection_ref (repo, &c_r,
-                                              allow_noent,
-                                              flags,
-                                              out_rev,
-                                              cancellable, NULL))
-        return TRUE;
-#endif
-    }
-
-  /* There may be several remotes with the same branch (if we for
-   * instance changed the origin) so prepend the current origin to
-   * make sure we get the right one */
-  if (remote_name != NULL)
-    {
-      g_autofree char *refspec = g_strdup_printf ("%s:%s", remote_name, ref_name);
-      ostree_repo_resolve_rev (repo, refspec, allow_noent, out_rev, &local_error);
-    }
-  else
-    ostree_repo_resolve_rev_ext (repo, ref_name, allow_noent,
-                                 OSTREE_REPO_RESOLVE_REV_EXT_NONE, out_rev, &local_error);
-
-  if (local_error != NULL)
-    {
-      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-        flatpak_fail_error (error, FLATPAK_ERROR_REF_NOT_FOUND, "%s", local_error->message);
-      else
-        g_propagate_error (error, g_steal_pointer (&local_error));
-
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
 /* Convert an app id to a dconf path in the obvious way.
  */
 char *
@@ -7845,8 +2224,6 @@ flatpak_parse_env_block (const char  *data,
   return (GStrv) g_ptr_array_free (g_steal_pointer (&env_vars), FALSE);
 }
 
-#endif
-
 /**
  * flatpak_envp_cmp:
  * @p1: a `const char * const *`
@@ -7916,8 +2293,6 @@ flatpak_envp_cmp (const void *p1,
   return ret;
 }
 
-#if 0
-
 /*
  * Return %TRUE if @s consists of one or more digits.
  * This is the same as Python bytes.isdigit().
@@ -8092,5 +2467,3 @@ running_under_sudo (void)
 
   return FALSE;
 }
-
-#endif