[gnome-software/wip/mak/libas: 1/2] Port to appstream




commit 60c16ea83074c9c59aaf3624635b0389db163a7b
Author: Matthias Klumpp <matthias tenstral net>
Date:   Thu Jan 7 04:14:47 2021 +0100

    Port to appstream
    
    This commit replaces appstream-glib with libappstream from the AppStream
    project. Libappstream most notably does not offer graphical stuff like
    image blurring, so this particular code has been added to GNOME Software
    directly (the experimental libappstream-compose has this support though,
    and we may depend on it in future).
    Libappstream also only supports features defined in the AppStream
    specification, so a few GNOME Software-isms have changed as well.

 doc/api/gnome-software-docs.xml                    |   6 +-
 lib/gs-app-list.c                                  |  17 +-
 lib/gs-app.c                                       | 189 +++--
 lib/gs-app.h                                       |  19 +-
 lib/gs-cmd.c                                       |   2 +-
 lib/gs-plugin-event.c                              |  11 +-
 lib/gs-plugin-loader.c                             |  54 +-
 lib/gs-plugin-private.h                            |   2 +-
 lib/gs-plugin-vfuncs.h                             |  14 +-
 lib/gs-plugin.c                                    |   6 +-
 lib/gs-plugin.h                                    |   2 +-
 lib/gs-self-test.c                                 |  11 +-
 lib/gs-utils.c                                     | 159 ++++-
 lib/gs-utils.h                                     |   4 +
 meson.build                                        |   2 +-
 plugins/core/gs-appstream.c                        | 131 ++--
 plugins/core/gs-plugin-appstream.c                 |  52 +-
 plugins/core/gs-plugin-generic-updates.c           |   8 +-
 plugins/core/gs-plugin-icons.c                     |  43 +-
 plugins/core/gs-plugin-key-colors-metadata.c       |   2 +-
 plugins/core/gs-plugin-os-release.c                |   2 +-
 plugins/core/gs-self-test.c                        |  18 +-
 plugins/dpkg/gs-plugin-dpkg.c                      |   2 +-
 plugins/dummy/gs-plugin-dummy.c                    |  42 +-
 plugins/dummy/gs-self-test.c                       |  20 +-
 plugins/eos-updater/gs-plugin-eos-updater.c        |   4 +-
 .../fedora-langpacks/gs-plugin-fedora-langpacks.c  |   4 +-
 plugins/fedora-langpacks/gs-self-test.c            |   2 +-
 .../gs-plugin-fedora-pkgdb-collections.c           |   6 +-
 plugins/flatpak/gs-flatpak-utils.c                 |   4 +-
 plugins/flatpak/gs-flatpak.c                       |  73 +-
 plugins/flatpak/gs-flatpak.h                       |   2 +-
 plugins/flatpak/gs-plugin-flatpak.c                |  26 +-
 plugins/flatpak/gs-self-test.c                     |  50 +-
 plugins/fwupd/gs-fwupd-app.c                       |   6 +-
 plugins/fwupd/gs-plugin-fwupd.c                    |  31 +-
 plugins/fwupd/gs-self-test.c                       |   2 +-
 plugins/malcontent/gs-plugin-malcontent.c          |  36 +-
 plugins/modalias/gs-plugin-modalias.c              |  32 +-
 plugins/modalias/gs-self-test.c                    |   2 +-
 plugins/odrs/gs-plugin-odrs.c                      |  53 +-
 plugins/packagekit/gs-plugin-packagekit-history.c  |   4 +-
 plugins/packagekit/gs-plugin-packagekit-local.c    |   6 +-
 plugins/packagekit/gs-plugin-packagekit-offline.c  |   4 +-
 .../packagekit/gs-plugin-packagekit-refine-repos.c |   2 +-
 plugins/packagekit/gs-plugin-packagekit-refine.c   |  12 +-
 plugins/packagekit/gs-plugin-packagekit-upgrade.c  |   4 +-
 .../packagekit/gs-plugin-packagekit-url-to-app.c   |   2 +-
 plugins/packagekit/gs-plugin-packagekit.c          |  10 +-
 plugins/packagekit/packagekit-common.c             |   4 +-
 plugins/repos/gs-plugin-repos.c                    |   4 +-
 plugins/rpm-ostree/gs-plugin-rpm-ostree.c          |  44 +-
 plugins/snap/gs-plugin-snap.c                      |  12 +-
 src/gs-app-addon-row.c                             |   2 +-
 src/gs-app-row.c                                   |   2 +-
 src/gs-application.c                               |   6 +-
 src/gs-common.c                                    |  29 +-
 src/gs-common.h                                    |   4 +-
 src/gs-content-rating.c                            | 784 ---------------------
 src/gs-content-rating.h                            |  76 --
 src/gs-css.c                                       |   4 +-
 src/gs-details-page.c                              |  86 ++-
 src/gs-extras-page.c                               |   2 +-
 src/gs-installed-page.c                            |  26 +-
 src/gs-origin-popover-row.c                        |   8 +-
 src/gs-page.c                                      |  14 +-
 src/gs-repos-dialog.c                              |  12 +-
 src/gs-screenshot-image.c                          | 117 ++-
 src/gs-search-page.c                               |   6 +-
 src/gs-self-test.c                                 |   1 -
 src/gs-shell-search-provider.c                     |   8 +-
 src/gs-update-dialog.c                             |  24 +-
 src/gs-update-monitor.c                            |   6 +-
 src/gs-updates-page.c                              |   6 +-
 src/gs-updates-section.c                           |  18 +-
 src/meson.build                                    |   2 -
 76 files changed, 967 insertions(+), 1535 deletions(-)
---
diff --git a/doc/api/gnome-software-docs.xml b/doc/api/gnome-software-docs.xml
index 5c660055e..33a1228cf 100644
--- a/doc/api/gnome-software-docs.xml
+++ b/doc/api/gnome-software-docs.xml
@@ -203,7 +203,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
   /* the trigger exists, so create a fake app */
   app = gs_app_new ("chiron.desktop");
   gs_app_set_management_plugin (app, "example");
-  gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+  gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
   gs_app_set_state (app, GS_APP_STATE_INSTALLED);
   gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron");
   gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A teaching application");
@@ -246,7 +246,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
           </listitem>
           <listitem>
             <para>
-              Most applications want a kind of <code>AS_APP_KIND_DESKTOP</code>
+              Most applications want a kind of <code>AS_COMPONENT_KIND_DESKTOP_APP</code>
               to be visible as an application.
             </para>
           </listitem>
@@ -531,7 +531,7 @@ gs_plugin_refine (GsPlugin *plugin,
 void
 gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
 {
-  if (gs_app_get_kind (app) == AS_APP_KIND_FIRMWARE)
+  if (gs_app_get_kind (app) == AS_COMPONENT_KIND_FIRMWARE)
     gs_app_set_management_plugin (app, "fwupd");
 }
           </programlisting>
diff --git a/lib/gs-app-list.c b/lib/gs-app-list.c
index f2ceff40b..e702844d7 100644
--- a/lib/gs-app-list.c
+++ b/lib/gs-app-list.c
@@ -248,7 +248,7 @@ gs_app_list_lookup_safe (GsAppList *list, const gchar *unique_id)
 {
        for (guint i = 0; i < list->array->len; i++) {
                GsApp *app = g_ptr_array_index (list->array, i);
-               if (as_utils_unique_id_equal (gs_app_get_unique_id (app), unique_id))
+               if (as_utils_data_id_equal (gs_app_get_unique_id (app), unique_id))
                        return app;
        }
        return NULL;
@@ -738,15 +738,18 @@ gs_app_list_filter_app_get_keys (GsApp *app, GsAppListFilterFlags flags)
                return keys;
        }
 
-       /* use the ID and any provides */
+       /* use the ID and any provided items */
        if (flags & GS_APP_LIST_FILTER_FLAG_KEY_ID_PROVIDES) {
-               GPtrArray *provides = gs_app_get_provides (app);
+               GPtrArray *provided = gs_app_get_provided (app);
                g_ptr_array_add (keys, g_strdup (gs_app_get_id (app)));
-               for (guint i = 0; i < provides->len; i++) {
-                       AsProvide *prov = g_ptr_array_index (provides, i);
-                       if (as_provide_get_kind (prov) != AS_PROVIDE_KIND_ID)
+               for (guint i = 0; i < provided->len; i++) {
+                       AsProvided *prov = g_ptr_array_index (provided, i);
+                       GPtrArray *items;
+                       if (as_provided_get_kind (prov) != AS_PROVIDED_KIND_ID)
                                continue;
-                       g_ptr_array_add (keys, g_strdup (as_provide_get_value (prov)));
+                       items = as_provided_get_items (prov);
+                       for (guint j = 0; j < items->len; j++)
+                               g_ptr_array_add (keys, g_strdup (g_ptr_array_index (items, j)));
                }
                return keys;
        }
diff --git a/lib/gs-app.c b/lib/gs-app.c
index c9f02ca7f..1be4e236b 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -17,9 +17,9 @@
  *
  * This object represents a 1:1 mapping to a .desktop file. The design is such
  * so you can't have different GsApp's for different versions or architectures
- * of a package. This rule really only applies to GsApps of kind %AS_APP_KIND_DESKTOP
- * and %AS_APP_KIND_GENERIC. We allow GsApps of kind %AS_APP_KIND_OS_UPDATE or
- * %AS_APP_KIND_GENERIC, which don't correspond to desktop files, but instead
+ * of a package. This rule really only applies to GsApps of kind %AS_COMPONENT_KIND_DESKTOP_APP
+ * and %AS_COMPONENT_KIND_GENERIC. We allow GsApps of kind %AS_COMPONENT_KIND_OS_UPDATE or
+ * %AS_COMPONENT_KIND_GENERIC, which don't correspond to desktop files, but instead
  * represent a system update and its individual components.
  *
  * The #GsPluginLoader de-duplicates the GsApp instances that are produced by
@@ -91,13 +91,13 @@ typedef struct
        gint                     rating;
        GArray                  *review_ratings;
        GPtrArray               *reviews; /* of AsReview */
-       GPtrArray               *provides; /* of AsProvide */
+       GPtrArray               *provided; /* of AsProvided */
        guint64                  size_installed;
        guint64                  size_download;
-       AsAppKind                kind;
+       AsComponentKind          kind;
        GsAppState               state;
        GsAppState               state_recover;
-       AsAppScope               scope;
+       AsComponentScope         scope;
        AsBundleKind             bundle_kind;
        guint                    progress;  /* integer 0–100 (inclusive), or %GS_APP_PROGRESS_UNKNOWN */
        gboolean                 allow_cancel;
@@ -258,7 +258,7 @@ gs_app_kv_printf (GString *str, const gchar *key, const gchar *fmt, ...)
 }
 
 static const gchar *
-_as_app_quirk_flag_to_string (GsAppQuirk quirk)
+_as_component_quirk_flag_to_string (GsAppQuirk quirk)
 {
        switch (quirk) {
        case GS_APP_QUIRK_PROVENANCE:
@@ -315,12 +315,11 @@ gs_app_get_unique_id_unlocked (GsApp *app)
        /* hmm, do what we can */
        if (priv->unique_id == NULL || !priv->unique_id_valid) {
                g_free (priv->unique_id);
-               priv->unique_id = as_utils_unique_id_build (priv->scope,
-                                                           priv->bundle_kind,
-                                                           priv->origin,
-                                                           priv->kind,
-                                                           priv->id,
-                                                           priv->branch);
+               priv->unique_id = as_utils_build_data_id (priv->scope,
+                                                         priv->bundle_kind,
+                                                         priv->origin,
+                                                         priv->id,
+                                                         priv->branch);
                priv->unique_id_valid = TRUE;
        }
        return priv->unique_id;
@@ -387,7 +386,7 @@ gs_app_quirk_to_string (GsAppQuirk quirk)
                if ((quirk & i) == 0)
                        continue;
                g_string_append_printf (str, "%s,",
-                                       _as_app_quirk_flag_to_string (i));
+                                       _as_component_quirk_flag_to_string (i));
        }
 
        /* nothing recognised */
@@ -487,7 +486,7 @@ gs_app_to_string_append (GsApp *app, GString *str)
        klass = GS_APP_GET_CLASS (app);
 
        g_string_append_printf (str, " [%p]\n", app);
-       gs_app_kv_lpad (str, "kind", as_app_kind_to_string (priv->kind));
+       gs_app_kv_lpad (str, "kind", as_component_kind_to_string (priv->kind));
        gs_app_kv_lpad (str, "state", gs_app_state_to_string (priv->state));
        if (priv->quirk > 0) {
                g_autofree gchar *qstr = gs_app_quirk_to_string (priv->quirk);
@@ -501,8 +500,8 @@ gs_app_to_string_append (GsApp *app, GString *str)
                gs_app_kv_lpad (str, "id", priv->id);
        if (priv->unique_id != NULL)
                gs_app_kv_lpad (str, "unique-id", gs_app_get_unique_id (app));
-       if (priv->scope != AS_APP_SCOPE_UNKNOWN)
-               gs_app_kv_lpad (str, "scope", as_app_scope_to_string (priv->scope));
+       if (priv->scope != AS_COMPONENT_SCOPE_UNKNOWN)
+               gs_app_kv_lpad (str, "scope", as_component_scope_to_string (priv->scope));
        if (priv->bundle_kind != AS_BUNDLE_KIND_UNKNOWN) {
                gs_app_kv_lpad (str, "bundle-kind",
                                as_bundle_kind_to_string (priv->bundle_kind));
@@ -522,21 +521,29 @@ gs_app_to_string_append (GsApp *app, GString *str)
                gs_app_kv_printf (str, "action-screenshot", "%p", priv->action_screenshot);
        for (i = 0; i < priv->icons->len; i++) {
                AsIcon *icon = g_ptr_array_index (priv->icons, i);
+               const gchar *icon_fname;
                gs_app_kv_lpad (str, "icon-kind",
                                as_icon_kind_to_string (as_icon_get_kind (icon)));
-               if (as_icon_get_pixbuf (icon) != NULL) {
-                       gs_app_kv_printf (str, "icon-pixbuf", "%p",
-                                         as_icon_get_pixbuf (icon));
+
+               icon_fname = as_icon_get_filename (icon);
+               if (icon_fname != NULL) {
+                       g_autoptr(GdkPixbuf) pixbuf = NULL;
+                       pixbuf = gdk_pixbuf_new_from_file_at_size (icon_fname,
+                                                                  (gint) as_icon_get_width (icon),
+                                                                  (gint) as_icon_get_height (icon),
+                                                                  NULL);
+                       if (pixbuf != NULL)
+                               gs_app_kv_printf (str, "icon-pixbuf", "%p", pixbuf);
                }
                if (as_icon_get_name (icon) != NULL)
                        gs_app_kv_lpad (str, "icon-name",
                                        as_icon_get_name (icon));
-               if (as_icon_get_prefix (icon) != NULL)
-                       gs_app_kv_lpad (str, "icon-prefix",
-                                       as_icon_get_prefix (icon));
                if (as_icon_get_filename (icon) != NULL)
                        gs_app_kv_lpad (str, "icon-filename",
                                        as_icon_get_filename (icon));
+               if (as_icon_get_url (icon) != NULL)
+                       gs_app_kv_lpad (str, "icon-url",
+                                       as_icon_get_url (icon));
        }
        if (priv->match_value != 0)
                gs_app_kv_printf (str, "match-value", "%05x", priv->match_value);
@@ -563,7 +570,7 @@ gs_app_to_string_append (GsApp *app, GString *str)
        for (i = 0; i < priv->screenshots->len; i++) {
                AsScreenshot *ss = g_ptr_array_index (priv->screenshots, i);
                g_autofree gchar *key = NULL;
-               tmp = as_screenshot_get_caption (ss, NULL);
+               tmp = as_screenshot_get_caption (ss);
                im = as_screenshot_get_image (ss, 0, 0);
                if (im == NULL)
                        continue;
@@ -642,8 +649,12 @@ gs_app_to_string_append (GsApp *app, GString *str)
        }
        if (priv->reviews != NULL)
                gs_app_kv_printf (str, "reviews", "%u", priv->reviews->len);
-       if (priv->provides != NULL)
-               gs_app_kv_printf (str, "provides", "%u", priv->provides->len);
+       if (priv->provided != NULL) {
+               guint total = 0;
+               for (i = 0; i < priv->provided->len; i++)
+                       total += as_provided_get_items (AS_PROVIDED (g_ptr_array_index (priv->provided, 
i)))->len;
+               gs_app_kv_printf (str, "provided", "%u", total);
+       }
        if (priv->install_date != 0) {
                gs_app_kv_printf (str, "install-date", "%"
                                  G_GUINT64_FORMAT "",
@@ -791,29 +802,29 @@ gs_app_set_id (GsApp *app, const gchar *id)
  *
  * Gets the scope of the application.
  *
- * Returns: the #AsAppScope, e.g. %AS_APP_SCOPE_USER
+ * Returns: the #AsComponentScope, e.g. %AS_COMPONENT_SCOPE_USER
  *
  * Since: 3.22
  **/
-AsAppScope
+AsComponentScope
 gs_app_get_scope (GsApp *app)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
-       g_return_val_if_fail (GS_IS_APP (app), AS_APP_SCOPE_UNKNOWN);
+       g_return_val_if_fail (GS_IS_APP (app), AS_COMPONENT_SCOPE_UNKNOWN);
        return priv->scope;
 }
 
 /**
  * gs_app_set_scope:
  * @app: a #GsApp
- * @scope: a #AsAppScope, e.g. AS_APP_SCOPE_SYSTEM
+ * @scope: a #AsComponentScope, e.g. AS_COMPONENT_SCOPE_SYSTEM
  *
  * This sets the scope of the application.
  *
  * Since: 3.22
  **/
 void
-gs_app_set_scope (GsApp *app, AsAppScope scope)
+gs_app_set_scope (GsApp *app, AsComponentScope scope)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
 
@@ -835,7 +846,7 @@ gs_app_set_scope (GsApp *app, AsAppScope scope)
  *
  * Gets the bundle kind of the application.
  *
- * Returns: the #AsAppScope, e.g. %AS_BUNDLE_KIND_FLATPAK
+ * Returns: the #AsComponentScope, e.g. %AS_BUNDLE_KIND_FLATPAK
  *
  * Since: 3.22
  **/
@@ -850,7 +861,7 @@ gs_app_get_bundle_kind (GsApp *app)
 /**
  * gs_app_set_bundle_kind:
  * @app: a #GsApp
- * @bundle_kind: a #AsAppScope, e.g. AS_BUNDLE_KIND_FLATPAK
+ * @bundle_kind: a #AsComponentScope, e.g. AS_BUNDLE_KIND_FLATPAK
  *
  * This sets the bundle kind of the application.
  *
@@ -1206,26 +1217,26 @@ gs_app_set_state (GsApp *app, GsAppState state)
  *
  * Gets the kind of the application.
  *
- * Returns: the #AsAppKind, e.g. %AS_APP_KIND_UNKNOWN
+ * Returns: the #AsComponentKind, e.g. %AS_COMPONENT_KIND_UNKNOWN
  *
  * Since: 3.22
  **/
-AsAppKind
+AsComponentKind
 gs_app_get_kind (GsApp *app)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
-       g_return_val_if_fail (GS_IS_APP (app), AS_APP_KIND_UNKNOWN);
+       g_return_val_if_fail (GS_IS_APP (app), AS_COMPONENT_KIND_UNKNOWN);
        return priv->kind;
 }
 
 /**
  * gs_app_set_kind:
  * @app: a #GsApp
- * @kind: a #AsAppKind, e.g. #AS_APP_KIND_DESKTOP
+ * @kind: a #AsComponentKind, e.g. #AS_COMPONENT_KIND_DESKTOP_APP
  *
  * This sets the kind of the application.
  * The following state diagram explains the typical states.
- * All applications start with kind %AS_APP_KIND_UNKNOWN.
+ * All applications start with kind %AS_COMPONENT_KIND_UNKNOWN.
  *
  * |[
  * PACKAGE --> NORMAL
@@ -1236,7 +1247,7 @@ gs_app_get_kind (GsApp *app)
  * Since: 3.22
  **/
 void
-gs_app_set_kind (GsApp *app, AsAppKind kind)
+gs_app_set_kind (GsApp *app, AsComponentKind kind)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
        gboolean state_change_ok = FALSE;
@@ -1251,26 +1262,26 @@ gs_app_set_kind (GsApp *app, AsAppKind kind)
                return;
 
        /* trying to change */
-       if (priv->kind != AS_APP_KIND_UNKNOWN &&
-           kind == AS_APP_KIND_UNKNOWN) {
+       if (priv->kind != AS_COMPONENT_KIND_UNKNOWN &&
+           kind == AS_COMPONENT_KIND_UNKNOWN) {
                g_warning ("automatically prevented from changing "
                           "kind on %s from %s to %s!",
                           gs_app_get_unique_id_unlocked (app),
-                          as_app_kind_to_string (priv->kind),
-                          as_app_kind_to_string (kind));
+                          as_component_kind_to_string (priv->kind),
+                          as_component_kind_to_string (kind));
                return;
        }
 
        /* check the state change is allowed */
        switch (priv->kind) {
-       case AS_APP_KIND_UNKNOWN:
-       case AS_APP_KIND_GENERIC:
+       case AS_COMPONENT_KIND_UNKNOWN:
+       case AS_COMPONENT_KIND_GENERIC:
                /* all others derive from generic */
                state_change_ok = TRUE;
                break;
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                /* desktop has to be reset to override */
-               if (kind == AS_APP_KIND_UNKNOWN)
+               if (kind == AS_COMPONENT_KIND_UNKNOWN)
                        state_change_ok = TRUE;
                break;
        default:
@@ -1282,8 +1293,8 @@ gs_app_set_kind (GsApp *app, AsAppKind kind)
        if (!state_change_ok) {
                g_warning ("Kind change on %s from %s to %s is not OK",
                           priv->id,
-                          as_app_kind_to_string (priv->kind),
-                          as_app_kind_to_string (kind));
+                          as_component_kind_to_string (priv->kind),
+                          as_component_kind_to_string (kind));
                return;
        }
 
@@ -1334,7 +1345,7 @@ gs_app_set_unique_id (GsApp *app, const gchar *unique_id)
        locker = g_mutex_locker_new (&priv->mutex);
 
        /* check for sanity */
-       if (!as_utils_unique_id_valid (unique_id))
+       if (!as_utils_data_id_valid (unique_id))
                g_warning ("unique_id %s not valid", unique_id);
 
        g_free (priv->unique_id);
@@ -2460,7 +2471,7 @@ gs_app_set_license (GsApp *app, GsAppQuality quality, const gchar *license)
 
        /* assume free software until we find a nonfree SPDX token */
        priv->license_is_free = TRUE;
-       tokens = as_utils_spdx_license_tokenize (license);
+       tokens = as_spdx_license_tokenize (license);
        for (i = 0; tokens[i] != NULL; i++) {
                if (g_strcmp0 (tokens[i], "&") == 0 ||
                    g_strcmp0 (tokens[i], "+") == 0 ||
@@ -3114,41 +3125,73 @@ gs_app_remove_review (GsApp *app, AsReview *review)
 }
 
 /**
- * gs_app_get_provides:
+ * gs_app_get_provided:
  * @app: a #GsApp
  *
- * Gets all the provides for the application.
+ * Gets all the provided item sets for the application.
  *
- * Returns: (element-type AsProvide) (transfer none): the list of provides
+ * Returns: (element-type AsProvided) (transfer none): the list of provided items
  *
- * Since: 3.22
+ * Since: 40
  **/
-GPtrArray *
-gs_app_get_provides (GsApp *app)
+GPtrArray*
+gs_app_get_provided (GsApp *app)
+{
+       GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_return_val_if_fail (GS_IS_APP (app), NULL);
+       return priv->provided;
+}
+
+/**
+ * gs_app_get_provided_for_kind:
+ * @cpt: a #AsComponent instance.
+ * @kind: kind of the provided item, e.g. %AS_PROVIDED_KIND_MIMETYPE
+ *
+ * Get an #AsProvided object for the given interface type, or %NULL if
+ * none was found.
+ *
+ * Since: 40
+ */
+AsProvided*
+gs_app_get_provided_for_kind (GsApp *app, AsProvidedKind kind)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
        g_return_val_if_fail (GS_IS_APP (app), NULL);
-       return priv->provides;
+
+       for (guint i = 0; i < priv->provided->len; i++) {
+               AsProvided *prov = AS_PROVIDED (g_ptr_array_index (priv->provided, i));
+               if (as_provided_get_kind (prov) == kind)
+                       return prov;
+       }
+       return NULL;
 }
 
 /**
- * gs_app_add_provide:
+ * gs_app_add_provided:
  * @app: a #GsApp
- * @provide: a #AsProvide
+ * @kind: the kind of the provided item, e.g. %AS_PROVIDED_KIND_MEDIATYPE
+ * @item: the item to add.
  *
- * Adds a provide to the application.
+ * Adds a provided items of the given kind to the application.
  *
- * Since: 3.22
+ * Since: 40
  **/
 void
-gs_app_add_provide (GsApp *app, AsProvide *provide)
+gs_app_add_provided_item (GsApp *app, AsProvidedKind kind, const gchar *item)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
+       AsProvided *prov;
        g_autoptr(GMutexLocker) locker = NULL;
        g_return_if_fail (GS_IS_APP (app));
-       g_return_if_fail (AS_IS_PROVIDE (provide));
+
        locker = g_mutex_locker_new (&priv->mutex);
-       g_ptr_array_add (priv->provides, g_object_ref (provide));
+       prov = gs_app_get_provided_for_kind (app, kind);
+       if (prov == NULL) {
+               prov = as_provided_new ();
+               as_provided_set_kind (prov, kind);
+               g_ptr_array_add (priv->provided, prov);
+       }
+       as_provided_add_item (prov, item);
 }
 
 /**
@@ -3637,7 +3680,7 @@ gs_app_is_updatable (GsApp *app)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
        g_return_val_if_fail (GS_IS_APP (app), FALSE);
-       if (priv->kind == AS_APP_KIND_OS_UPGRADE)
+       if (priv->kind == AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
        return (priv->state == GS_APP_STATE_UPDATABLE) ||
               (priv->state == GS_APP_STATE_UPDATABLE_LIVE);
@@ -4379,7 +4422,7 @@ gs_app_dispose (GObject *object)
        g_clear_pointer (&priv->screenshots, g_ptr_array_unref);
        g_clear_pointer (&priv->review_ratings, g_array_unref);
        g_clear_pointer (&priv->reviews, g_ptr_array_unref);
-       g_clear_pointer (&priv->provides, g_ptr_array_unref);
+       g_clear_pointer (&priv->provided, g_ptr_array_unref);
        g_clear_pointer (&priv->icons, g_ptr_array_unref);
 
        G_OBJECT_CLASS (gs_app_parent_class)->dispose (object);
@@ -4489,9 +4532,9 @@ gs_app_class_init (GsAppClass *klass)
         * GsApp:kind:
         */
        obj_props[PROP_KIND] = g_param_spec_uint ("kind", NULL, NULL,
-                                  AS_APP_KIND_UNKNOWN,
-                                  AS_APP_KIND_LAST,
-                                  AS_APP_KIND_UNKNOWN,
+                                  AS_COMPONENT_KIND_UNKNOWN,
+                                  AS_COMPONENT_KIND_LAST,
+                                  AS_COMPONENT_KIND_UNKNOWN,
                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
 
        /**
@@ -4585,7 +4628,7 @@ gs_app_init (GsApp *app)
        priv->history = gs_app_list_new ();
        priv->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        priv->reviews = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
-       priv->provides = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+       priv->provided = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        priv->icons = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        priv->metadata = g_hash_table_new_full (g_str_hash,
                                                g_str_equal,
@@ -4659,13 +4702,13 @@ gs_app_set_from_unique_id (GsApp *app, const gchar *unique_id)
        if (g_strv_length (split) != 6)
                return;
        if (g_strcmp0 (split[0], "*") != 0)
-               gs_app_set_scope (app, as_app_scope_from_string (split[0]));
+               gs_app_set_scope (app, as_component_scope_from_string (split[0]));
        if (g_strcmp0 (split[1], "*") != 0)
                gs_app_set_bundle_kind (app, as_bundle_kind_from_string (split[1]));
        if (g_strcmp0 (split[2], "*") != 0)
                gs_app_set_origin (app, split[2]);
        if (g_strcmp0 (split[3], "*") != 0)
-               gs_app_set_kind (app, as_app_kind_from_string (split[3]));
+               gs_app_set_kind (app, as_component_kind_from_string (split[3]));
        if (g_strcmp0 (split[4], "*") != 0)
                gs_app_set_id (app, split[4]);
        if (g_strcmp0 (split[5], "*") != 0)
diff --git a/lib/gs-app.h b/lib/gs-app.h
index d5cc87798..64ad98862 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -12,7 +12,7 @@
 #include <glib-object.h>
 #include <gdk/gdk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include <appstream-glib.h>
+#include <appstream.h>
 
 G_BEGIN_DECLS
 
@@ -222,15 +222,15 @@ void               gs_app_to_string_append        (GsApp          *app,
 const gchar    *gs_app_get_id                  (GsApp          *app);
 void            gs_app_set_id                  (GsApp          *app,
                                                 const gchar    *id);
-AsAppKind       gs_app_get_kind                (GsApp          *app);
+AsComponentKind         gs_app_get_kind                (GsApp          *app);
 void            gs_app_set_kind                (GsApp          *app,
-                                                AsAppKind       kind);
+                                                AsComponentKind kind);
 GsAppState      gs_app_get_state               (GsApp          *app);
 void            gs_app_set_state               (GsApp          *app,
                                                 GsAppState      state);
-AsAppScope      gs_app_get_scope               (GsApp          *app);
+AsComponentScope gs_app_get_scope              (GsApp          *app);
 void            gs_app_set_scope               (GsApp          *app,
-                                                AsAppScope      scope);
+                                                AsComponentScope scope);
 AsBundleKind    gs_app_get_bundle_kind         (GsApp          *app);
 void            gs_app_set_bundle_kind         (GsApp          *app,
                                                 AsBundleKind    bundle_kind);
@@ -372,9 +372,12 @@ void                gs_app_add_review              (GsApp          *app,
                                                 AsReview       *review);
 void            gs_app_remove_review           (GsApp          *app,
                                                 AsReview       *review);
-GPtrArray      *gs_app_get_provides            (GsApp          *app);
-void            gs_app_add_provide             (GsApp          *app,
-                                                AsProvide      *provide);
+GPtrArray      *gs_app_get_provided            (GsApp          *app);
+AsProvided     *gs_app_get_provided_for_kind   (GsApp          *app,
+                                                AsProvidedKind kind);
+void            gs_app_add_provided_item       (GsApp          *app,
+                                                AsProvidedKind kind,
+                                                const gchar    *item);
 guint64                 gs_app_get_size_installed      (GsApp          *app);
 void            gs_app_set_size_installed      (GsApp          *app,
                                                 guint64         size_installed);
diff --git a/lib/gs-cmd.c b/lib/gs-cmd.c
index bc01c9533..0c83f6e91 100644
--- a/lib/gs-cmd.c
+++ b/lib/gs-cmd.c
@@ -454,7 +454,7 @@ main (int argc, char **argv)
        } else if (argc == 3 && g_strcmp0 (argv[1], "action-upgrade-download") == 0) {
                g_autoptr(GsPluginJob) plugin_job = NULL;
                app = gs_app_new (argv[2]);
-               gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM);
                plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPGRADE_DOWNLOAD,
                                                 "app", app,
                                                 NULL);
diff --git a/lib/gs-plugin-event.c b/lib/gs-plugin-event.c
index 8d1fc83ee..89787626a 100644
--- a/lib/gs-plugin-event.c
+++ b/lib/gs-plugin-event.c
@@ -173,12 +173,11 @@ gs_plugin_event_get_unique_id (GsPluginEvent *event)
                        g_autofree gchar *id = NULL;
                        id = g_strdup_printf ("%s.error",
                                              gs_plugin_error_to_string (event->error->code));
-                       event->unique_id = as_utils_unique_id_build (AS_APP_SCOPE_UNKNOWN,
-                                                                    AS_BUNDLE_KIND_UNKNOWN,
-                                                                    NULL,
-                                                                    AS_APP_KIND_UNKNOWN,
-                                                                    id,
-                                                                    NULL);
+                       event->unique_id = as_utils_build_data_id (AS_COMPONENT_SCOPE_UNKNOWN,
+                                                                  AS_BUNDLE_KIND_UNKNOWN,
+                                                                  NULL,
+                                                                  id,
+                                                                  NULL);
                }
                return event->unique_id;
        }
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index 067b6a04d..6f6aa0c49 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -11,7 +11,7 @@
 
 #include <locale.h>
 #include <glib/gi18n.h>
-#include <appstream-glib.h>
+#include <appstream.h>
 #include <math.h>
 
 #ifdef HAVE_SYSPROF
@@ -43,6 +43,7 @@ typedef struct
        SoupSession             *soup_session;
        GPtrArray               *file_monitors;
        GsPluginStatus           global_status_last;
+       AsPool                  *as_pool;
 
        GMutex                   pending_apps_mutex;
        GPtrArray               *pending_apps;
@@ -427,7 +428,7 @@ gs_plugin_error_handle_failure (GsPluginLoaderHelper *helper,
        event = gs_plugin_job_to_failed_event (helper->plugin_job, error_local_copy);
 
        /* set the app and origin IDs if we managed to scrape them from the error above */
-       if (as_utils_unique_id_valid (app_id)) {
+       if (as_utils_data_id_valid (app_id)) {
                g_autoptr(GsApp) app = gs_plugin_cache_lookup (plugin, app_id);
                if (app != NULL) {
                        g_debug ("found app %s in error", origin_id);
@@ -436,7 +437,7 @@ gs_plugin_error_handle_failure (GsPluginLoaderHelper *helper,
                        g_debug ("no unique ID found for app %s", app_id);
                }
        }
-       if (as_utils_unique_id_valid (origin_id)) {
+       if (as_utils_data_id_valid (origin_id)) {
                g_autoptr(GsApp) origin = gs_plugin_cache_lookup (plugin, origin_id);
                if (origin != NULL) {
                        g_debug ("found origin %s in error", origin_id);
@@ -1209,11 +1210,11 @@ gs_plugin_loader_app_is_valid_installed (GsApp *app, gpointer user_data)
        }
 
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_OS_UPGRADE:
-       case AS_APP_KIND_CODEC:
-       case AS_APP_KIND_FONT:
+       case AS_COMPONENT_KIND_OPERATING_SYSTEM:
+       case AS_COMPONENT_KIND_CODEC:
+       case AS_COMPONENT_KIND_FONT:
                g_debug ("app invalid as %s: %s",
-                        as_app_kind_to_string (gs_app_get_kind (app)),
+                        as_component_kind_to_string (gs_app_get_kind (app)),
                         gs_plugin_loader_get_app_str (app));
                return FALSE;
                break;
@@ -1237,14 +1238,14 @@ gs_plugin_loader_app_is_valid (GsApp *app, gpointer user_data)
        GsPluginLoaderHelper *helper = (GsPluginLoaderHelper *) user_data;
 
        /* never show addons */
-       if (gs_app_get_kind (app) == AS_APP_KIND_ADDON) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_ADDON) {
                g_debug ("app invalid as addon %s",
                         gs_plugin_loader_get_app_str (app));
                return FALSE;
        }
 
        /* never show CLI apps */
-       if (gs_app_get_kind (app) == AS_APP_KIND_CONSOLE) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_CONSOLE_APP) {
                g_debug ("app invalid as console %s",
                         gs_plugin_loader_get_app_str (app));
                return FALSE;
@@ -1258,7 +1259,7 @@ gs_plugin_loader_app_is_valid (GsApp *app, gpointer user_data)
        }
 
        /* don't show unconverted unavailables */
-       if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN &&
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_UNKNOWN &&
                gs_app_get_state (app) == GS_APP_STATE_UNAVAILABLE) {
                g_debug ("app invalid as unconverted unavailable %s",
                         gs_plugin_loader_get_app_str (app));
@@ -1290,14 +1291,14 @@ gs_plugin_loader_app_is_valid (GsApp *app, gpointer user_data)
        }
 
        /* don't show sources */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) {
                g_debug ("app invalid as source %s",
                         gs_plugin_loader_get_app_str (app));
                return FALSE;
        }
 
        /* don't show unknown kind */
-       if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_UNKNOWN) {
                g_debug ("app invalid as kind unknown %s",
                         gs_plugin_loader_get_app_str (app));
                return FALSE;
@@ -1306,9 +1307,9 @@ gs_plugin_loader_app_is_valid (GsApp *app, gpointer user_data)
        /* don't show unconverted packages in the application view */
        if (!gs_plugin_job_has_refine_flags (helper->plugin_job,
                                                 GS_PLUGIN_REFINE_FLAGS_ALLOW_PACKAGES) &&
-           (gs_app_get_kind (app) == AS_APP_KIND_GENERIC)) {
+           (gs_app_get_kind (app) == AS_COMPONENT_KIND_GENERIC)) {
                g_debug ("app invalid as only a %s: %s",
-                        as_app_kind_to_string (gs_app_get_kind (app)),
+                        as_component_kind_to_string (gs_app_get_kind (app)),
                         gs_plugin_loader_get_app_str (app));
                return FALSE;
        }
@@ -1413,9 +1414,9 @@ gs_plugin_loader_featured_debug (GsApp *app, gpointer user_data)
 static gint
 gs_plugin_loader_app_sort_kind_cb (GsApp *app1, GsApp *app2, gpointer user_data)
 {
-       if (gs_app_get_kind (app1) == AS_APP_KIND_DESKTOP)
+       if (gs_app_get_kind (app1) == AS_COMPONENT_KIND_DESKTOP_APP)
                return -1;
-       if (gs_app_get_kind (app2) == AS_APP_KIND_DESKTOP)
+       if (gs_app_get_kind (app2) == AS_COMPONENT_KIND_DESKTOP_APP)
                return 1;
        return 0;
 }
@@ -1439,14 +1440,8 @@ gs_plugin_loader_app_sort_prio_cb (GsApp *app1, GsApp *app2, gpointer user_data)
 static gint
 gs_plugin_loader_app_sort_version_cb (GsApp *app1, GsApp *app2, gpointer user_data)
 {
-#if AS_CHECK_VERSION(0,7,15)
-       return as_utils_vercmp_full (gs_app_get_version (app1),
-                                    gs_app_get_version (app2),
-                                    AS_VERSION_COMPARE_FLAG_NONE);
-#else
-       return as_utils_vercmp (gs_app_get_version (app1),
-                               gs_app_get_version (app2));
-#endif
+       return as_utils_compare_versions (gs_app_get_version (app1),
+                                         gs_app_get_version (app2));
 }
 
 /******************************************************************************/
@@ -2446,6 +2441,7 @@ gs_plugin_loader_setup (GsPluginLoader *plugin_loader,
        for (i = 0; i < priv->locations->len; i++) {
                GFileMonitor *monitor;
                const gchar *location = g_ptr_array_index (priv->locations, i);
+               g_debug ("monitoring plugin location %s", location);
                g_autoptr(GFile) plugin_dir = g_file_new_for_path (location);
                monitor = g_file_monitor_directory (plugin_dir,
                                                    G_FILE_MONITOR_NONE,
@@ -2791,6 +2787,7 @@ gs_plugin_loader_finalize (GObject *object)
        g_ptr_array_unref (priv->file_monitors);
        g_hash_table_unref (priv->events_by_id);
        g_hash_table_unref (priv->disallow_updates);
+       g_object_unref (priv->as_pool);
 
        g_mutex_clear (&priv->pending_apps_mutex);
        g_mutex_clear (&priv->events_by_id_mutex);
@@ -2919,11 +2916,14 @@ gs_plugin_loader_init (GsPluginLoader *plugin_loader)
        priv->settings = g_settings_new ("org.gnome.software");
        g_signal_connect (priv->settings, "changed",
                          G_CALLBACK (gs_plugin_loader_settings_changed_cb), plugin_loader);
-       priv->events_by_id = g_hash_table_new_full ((GHashFunc) as_utils_unique_id_hash,
-                                                   (GEqualFunc) as_utils_unique_id_equal,
+       priv->events_by_id = g_hash_table_new_full ((GHashFunc) as_utils_data_id_hash,
+                                                   (GEqualFunc) as_utils_data_id_equal,
                                                    g_free,
                                                    (GDestroyNotify) g_object_unref);
 
+       /* AppStream metadata pool, we only need it uninitialized for some helper functions */
+       priv->as_pool = as_pool_new ();
+
        /* share a soup session (also disable the double-compression) */
        priv->soup_session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, gs_user_agent (),
                                                            SOUP_SESSION_TIMEOUT, 10,
@@ -3804,7 +3804,7 @@ gs_plugin_loader_job_process_async (GsPluginLoader *plugin_loader,
        /* pre-tokenize search */
        if (action == GS_PLUGIN_ACTION_SEARCH) {
                const gchar *search = gs_plugin_job_get_search (plugin_job);
-               helper->tokens = as_utils_search_tokenize (search);
+               helper->tokens = as_pool_build_search_tokens (priv->as_pool, search);
                if (helper->tokens == NULL) {
                        g_task_return_new_error (task,
                                                 GS_PLUGIN_ERROR,
diff --git a/lib/gs-plugin-private.h b/lib/gs-plugin-private.h
index 1defc98a0..a703bea0e 100644
--- a/lib/gs-plugin-private.h
+++ b/lib/gs-plugin-private.h
@@ -8,7 +8,7 @@
 
 #pragma once
 
-#include <appstream-glib.h>
+#include <appstream.h>
 #include <glib-object.h>
 #include <gmodule.h>
 #include <libsoup/soup.h>
diff --git a/lib/gs-plugin-vfuncs.h b/lib/gs-plugin-vfuncs.h
index a88f9819c..6ed7a0377 100644
--- a/lib/gs-plugin-vfuncs.h
+++ b/lib/gs-plugin-vfuncs.h
@@ -16,7 +16,7 @@
  * @short_description: Vfuncs that plugins can implement
  */
 
-#include <appstream-glib.h>
+#include <appstream.h>
 #include <glib-object.h>
 #include <gmodule.h>
 #include <gio/gio.h>
@@ -222,7 +222,7 @@ gboolean     gs_plugin_add_updates                  (GsPlugin       *plugin,
  * should not be downloaded until the user has explicitly opted-in.
  *
  * Plugins are expected to add new apps using gs_app_list_add() of type
- * %AS_APP_KIND_OS_UPGRADE.
+ * %AS_COMPONENT_KIND_OPERATING_SYSTEM.
  *
  * Returns: %TRUE for success or if not relevant
  **/
@@ -242,7 +242,7 @@ gboolean     gs_plugin_add_distro_upgrades          (GsPlugin       *plugin,
  * or the remotes configured in flatpak.
  *
  * Plugins are expected to add new apps using gs_app_list_add() of type
- * %AS_APP_KIND_SOURCE.
+ * %AS_COMPONENT_KIND_REPOSITORY.
  *
  * Returns: %TRUE for success or if not relevant
  **/
@@ -684,7 +684,7 @@ gboolean     gs_plugin_download                     (GsPlugin       *plugin,
 /**
  * gs_plugin_app_upgrade_download:
  * @plugin: a #GsPlugin
- * @app: a #GsApp, with kind %AS_APP_KIND_OS_UPGRADE
+ * @app: a #GsApp, with kind %AS_COMPONENT_KIND_OPERATING_SYSTEM
  * @cancellable: a #GCancellable, or %NULL
  * @error: a #GError, or %NULL
  *
@@ -704,7 +704,7 @@ gboolean     gs_plugin_app_upgrade_download         (GsPlugin       *plugin,
 /**
  * gs_plugin_app_upgrade_trigger:
  * @plugin: a #GsPlugin
- * @app: a #GsApp, with kind %AS_APP_KIND_OS_UPGRADE
+ * @app: a #GsApp, with kind %AS_COMPONENT_KIND_OPERATING_SYSTEM
  * @cancellable: a #GCancellable, or %NULL
  * @error: a #GError, or %NULL
  *
@@ -867,8 +867,8 @@ gboolean     gs_plugin_refresh                      (GsPlugin       *plugin,
  * list. If no plugins can handle the file, the list will be empty.
  *
  * For example, the PackageKit plugin can turn a .rpm file into a application
- * of kind %AS_APP_KIND_UNKNOWN but that in some cases it will be further refined
- * into a %AS_APP_KIND_DESKTOP (with all the extra metadata) by the appstream
+ * of kind %AS_COMPONENT_KIND_UNKNOWN but that in some cases it will be further refined
+ * into a %AS_COMPONENT_KIND_DESKTOP_APP (with all the extra metadata) by the appstream
  * plugin.
  *
  * Plugins are expected to add new apps using gs_app_list_add().
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index c517de0fa..6af91cacf 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -1328,7 +1328,7 @@ gs_plugin_download_rewrite_resource (GsPlugin *plugin,
        g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
        /* replace datadir */
-       as_utils_string_replace (resource_str, "@datadir@", DATADIR);
+       as_gstring_replace (resource_str, "@datadir@", DATADIR);
        resource = resource_str->str;
 
        /* look in string for any url() links */
@@ -2039,8 +2039,8 @@ gs_plugin_init (GsPlugin *plugin)
 
        priv->enabled = TRUE;
        priv->scale = 1;
-       priv->cache = g_hash_table_new_full ((GHashFunc) as_utils_unique_id_hash,
-                                            (GEqualFunc) as_utils_unique_id_equal,
+       priv->cache = g_hash_table_new_full ((GHashFunc) as_utils_data_id_hash,
+                                            (GEqualFunc) as_utils_data_id_equal,
                                             g_free,
                                             (GDestroyNotify) g_object_unref);
        priv->vfuncs = g_hash_table_new_full (g_str_hash, g_str_equal,
diff --git a/lib/gs-plugin.h b/lib/gs-plugin.h
index e2119317d..0f60fc783 100644
--- a/lib/gs-plugin.h
+++ b/lib/gs-plugin.h
@@ -9,7 +9,7 @@
 
 #pragma once
 
-#include <appstream-glib.h>
+#include <appstream.h>
 #include <glib-object.h>
 #include <gmodule.h>
 #include <gio/gio.h>
diff --git a/lib/gs-self-test.c b/lib/gs-self-test.c
index 5c353987f..2e0d0b792 100644
--- a/lib/gs-self-test.c
+++ b/lib/gs-self-test.c
@@ -274,7 +274,6 @@ gs_plugin_func (void)
        GsAppList *list_dup;
        GsAppList *list_remove;
        GsApp *app;
-       g_autoptr(AsProvide) prov = as_provide_new ();
 
        /* check enums converted */
        for (guint i = 0; i < GS_PLUGIN_ACTION_LAST; i++) {
@@ -454,9 +453,9 @@ gs_plugin_func (void)
        gs_app_list_add (list, app);
        g_object_unref (app);
        app = gs_app_new ("org.gimp.GIMP");
-       as_provide_set_kind (prov, AS_PROVIDE_KIND_ID);
-       as_provide_set_value (prov, "gimp.desktop");
-       gs_app_add_provide (app, prov);
+       gs_app_add_provided_item (app,
+                                 AS_PROVIDED_KIND_ID,
+                                 "gimp.desktop");
        gs_app_set_unique_id (app, "user/flathub/*/*/org.gimp.GIMP/*");
        gs_app_set_priority (app, 100);
        gs_app_list_add (list, app);
@@ -608,10 +607,10 @@ gs_app_unique_id_func (void)
        unique_id = "system/flatpak/gnome/desktop/org.gnome.Software.desktop/master";
        gs_app_set_from_unique_id (app, unique_id);
        g_assert (GS_IS_APP (app));
-       g_assert_cmpint (gs_app_get_scope (app), ==, AS_APP_SCOPE_SYSTEM);
+       g_assert_cmpint (gs_app_get_scope (app), ==, AS_COMPONENT_SCOPE_SYSTEM);
        g_assert_cmpint (gs_app_get_bundle_kind (app), ==, AS_BUNDLE_KIND_FLATPAK);
        g_assert_cmpstr (gs_app_get_origin (app), ==, "gnome");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.gnome.Software.desktop");
        g_assert_cmpstr (gs_app_get_branch (app), ==, "master");
 }
diff --git a/lib/gs-utils.c b/lib/gs-utils.c
index 1ba5976aa..c52b37633 100644
--- a/lib/gs-utils.c
+++ b/lib/gs-utils.c
@@ -973,26 +973,21 @@ gs_utils_error_convert_appstream (GError **perror)
                return TRUE;
 
        /* custom to this plugin */
-       if (error->domain == AS_UTILS_ERROR) {
+       if (error->domain == AS_METADATA_ERROR) {
                switch (error->code) {
-               case AS_UTILS_ERROR_INVALID_TYPE:
+               case AS_METADATA_ERROR_PARSE:
+               case AS_METADATA_ERROR_FORMAT_UNEXPECTED:
+               case AS_METADATA_ERROR_NO_COMPONENT:
                        error->code = GS_PLUGIN_ERROR_INVALID_FORMAT;
                        break;
-               case AS_UTILS_ERROR_FAILED:
+               case AS_METADATA_ERROR_FAILED:
                default:
                        error->code = GS_PLUGIN_ERROR_FAILED;
                        break;
                }
-       } else if (error->domain == AS_STORE_ERROR) {
+       } else if (error->domain == AS_POOL_ERROR) {
                switch (error->code) {
-               case AS_UTILS_ERROR_FAILED:
-               default:
-                       error->code = GS_PLUGIN_ERROR_FAILED;
-                       break;
-               }
-       } else if (error->domain == AS_ICON_ERROR) {
-               switch (error->code) {
-               case AS_ICON_ERROR_FAILED:
+               case AS_POOL_ERROR_FAILED:
                default:
                        error->code = GS_PLUGIN_ERROR_FAILED;
                        break;
@@ -1223,4 +1218,144 @@ gs_utils_set_online_updates_timestamp (GSettings *settings)
        g_settings_set (settings, "online-updates-timestamp", "x", g_date_time_to_unix (now));
 }
 
+static void
+gs_pixbuf_blur_private (GdkPixbuf *src, GdkPixbuf *dest, gint radius, guchar *div_kernel_size)
+{
+       gint width, height, src_rowstride, dest_rowstride, n_channels;
+       guchar *p_src, *p_dest, *c1, *c2;
+       gint x, y, i, i1, i2, width_minus_1, height_minus_1, radius_plus_1;
+       gint r, g, b, a;
+       guchar *p_dest_row, *p_dest_col;
+
+       width = gdk_pixbuf_get_width (src);
+       height = gdk_pixbuf_get_height (src);
+       n_channels = gdk_pixbuf_get_n_channels (src);
+       radius_plus_1 = radius + 1;
+
+       /* horizontal blur */
+       p_src = gdk_pixbuf_get_pixels (src);
+       p_dest = gdk_pixbuf_get_pixels (dest);
+       src_rowstride = gdk_pixbuf_get_rowstride (src);
+       dest_rowstride = gdk_pixbuf_get_rowstride (dest);
+       width_minus_1 = width - 1;
+       for (y = 0; y < height; y++) {
+
+               /* calc the initial sums of the kernel */
+               r = g = b = a = 0;
+               for (i = -radius; i <= radius; i++) {
+                       c1 = p_src + (CLAMP (i, 0, width_minus_1) * n_channels);
+                       r += c1[0];
+                       g += c1[1];
+                       b += c1[2];
+               }
+
+               p_dest_row = p_dest;
+               for (x = 0; x < width; x++) {
+                       /* set as the mean of the kernel */
+                       p_dest_row[0] = div_kernel_size[r];
+                       p_dest_row[1] = div_kernel_size[g];
+                       p_dest_row[2] = div_kernel_size[b];
+                       p_dest_row += n_channels;
+
+                       /* the pixel to add to the kernel */
+                       i1 = x + radius_plus_1;
+                       if (i1 > width_minus_1)
+                               i1 = width_minus_1;
+                       c1 = p_src + (i1 * n_channels);
+
+                       /* the pixel to remove from the kernel */
+                       i2 = x - radius;
+                       if (i2 < 0)
+                               i2 = 0;
+                       c2 = p_src + (i2 * n_channels);
+
+                       /* calc the new sums of the kernel */
+                       r += c1[0] - c2[0];
+                       g += c1[1] - c2[1];
+                       b += c1[2] - c2[2];
+               }
+
+               p_src += src_rowstride;
+               p_dest += dest_rowstride;
+       }
+
+       /* vertical blur */
+       p_src = gdk_pixbuf_get_pixels (dest);
+       p_dest = gdk_pixbuf_get_pixels (src);
+       src_rowstride = gdk_pixbuf_get_rowstride (dest);
+       dest_rowstride = gdk_pixbuf_get_rowstride (src);
+       height_minus_1 = height - 1;
+       for (x = 0; x < width; x++) {
+
+               /* calc the initial sums of the kernel */
+               r = g = b = a = 0;
+               for (i = -radius; i <= radius; i++) {
+                       c1 = p_src + (CLAMP (i, 0, height_minus_1) * src_rowstride);
+                       r += c1[0];
+                       g += c1[1];
+                       b += c1[2];
+               }
+
+               p_dest_col = p_dest;
+               for (y = 0; y < height; y++) {
+                       /* set as the mean of the kernel */
+
+                       p_dest_col[0] = div_kernel_size[r];
+                       p_dest_col[1] = div_kernel_size[g];
+                       p_dest_col[2] = div_kernel_size[b];
+                       p_dest_col += dest_rowstride;
+
+                       /* the pixel to add to the kernel */
+                       i1 = y + radius_plus_1;
+                       if (i1 > height_minus_1)
+                               i1 = height_minus_1;
+                       c1 = p_src + (i1 * src_rowstride);
+
+                       /* the pixel to remove from the kernel */
+                       i2 = y - radius;
+                       if (i2 < 0)
+                               i2 = 0;
+                       c2 = p_src + (i2 * src_rowstride);
+
+                       /* calc the new sums of the kernel */
+                       r += c1[0] - c2[0];
+                       g += c1[1] - c2[1];
+                       b += c1[2] - c2[2];
+               }
+
+               p_src += n_channels;
+               p_dest += n_channels;
+       }
+}
+
+/**
+ * as_pixbuf_blur:
+ * @src: the GdkPixbuf.
+ * @radius: the pixel radius for the gaussian blur, typical values are 1..3
+ * @iterations: Amount to blur the image, typical values are 1..5
+ *
+ * Blurs an image. Warning, this method is s..l..o..w... for large images.
+ **/
+void
+gs_utils_pixbuf_blur (GdkPixbuf *src, gint radius, gint iterations)
+{
+       gint kernel_size;
+       gint i;
+       g_autofree guchar *div_kernel_size = NULL;
+       g_autoptr(GdkPixbuf) tmp = NULL;
+
+       tmp = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
+                             gdk_pixbuf_get_has_alpha (src),
+                             gdk_pixbuf_get_bits_per_sample (src),
+                             gdk_pixbuf_get_width (src),
+                             gdk_pixbuf_get_height (src));
+       kernel_size = 2 * radius + 1;
+       div_kernel_size = g_new (guchar, 256 * kernel_size);
+       for (i = 0; i < 256 * kernel_size; i++)
+               div_kernel_size[i] = (guchar) (i / kernel_size);
+
+       while (iterations-- > 0)
+               gs_pixbuf_blur_private (src, tmp, radius, div_kernel_size);
+}
+
 /* vim: set noexpandtab: */
diff --git a/lib/gs-utils.h b/lib/gs-utils.h
index dc4576ac3..feda5e2f5 100644
--- a/lib/gs-utils.h
+++ b/lib/gs-utils.h
@@ -93,6 +93,10 @@ gboolean      gs_utils_parse_evr             (const gchar     *evr,
                                                 gchar          **out_release);
 void            gs_utils_set_online_updates_timestamp (GSettings *settings);
 
+void            gs_utils_pixbuf_blur           (GdkPixbuf      *src,
+                                                gint           radius,
+                                                gint           iterations);
+
 #if !GLIB_CHECK_VERSION(2, 64, 0)
 typedef void GsMainContextPusher;
 
diff --git a/meson.build b/meson.build
index fcf80f8c4..a30b8a37d 100644
--- a/meson.build
+++ b/meson.build
@@ -12,7 +12,7 @@ conf.set_quoted('PACKAGE_VERSION', meson.project_version())
 
 # this refers to the gnome-software plugin API version
 # this is not in any way related to a package or soname version
-gs_plugin_api_version = '13'
+gs_plugin_api_version = '14'
 conf.set_quoted('GS_PLUGIN_API_VERSION', gs_plugin_api_version)
 
 # install docs
diff --git a/plugins/core/gs-appstream.c b/plugins/core/gs-appstream.c
index 866013d6a..db8c63fe6 100644
--- a/plugins/core/gs-appstream.c
+++ b/plugins/core/gs-appstream.c
@@ -32,7 +32,7 @@ gs_appstream_create_app (GsPlugin *plugin, XbSilo *silo, XbNode *component, GErr
                return g_steal_pointer (&app_new);
 
        /* no longer supported */
-       if (gs_app_get_kind (app_new) == AS_APP_KIND_SHELL_EXTENSION) {
+       if (gs_app_get_kind (app_new) == AS_COMPONENT_KIND_SHELL_EXTENSION) {
                g_set_error (error,
                             GS_PLUGIN_ERROR,
                             GS_PLUGIN_ERROR_NOT_SUPPORTED,
@@ -149,6 +149,9 @@ gs_appstream_new_icon (XbNode *component, XbNode *n, AsIconKind icon_kind, guint
        g_autofree gchar *icon_path = NULL;
        as_icon_set_kind (icon, icon_kind);
        switch (icon_kind) {
+       case AS_ICON_KIND_LOCAL:
+               as_icon_set_filename (icon, xb_node_get_text (n));
+               break;
        case AS_ICON_KIND_REMOTE:
                as_icon_set_url (icon, xb_node_get_text (n));
                break;
@@ -161,9 +164,12 @@ gs_appstream_new_icon (XbNode *component, XbNode *n, AsIconKind icon_kind, guint
                as_icon_set_width (icon, sz);
                as_icon_set_height (icon, sz);
        }
-       icon_path = gs_appstream_build_icon_prefix (component);
-       if (icon_path != NULL)
-               as_icon_set_prefix (icon, icon_path);
+
+       if ((icon_kind != AS_ICON_KIND_LOCAL) && (icon_kind != AS_ICON_KIND_REMOTE)) {
+               /* add partial filename for now, we will compose the full one later */
+               icon_path = gs_appstream_build_icon_prefix (component);
+               as_icon_set_filename (icon, icon_path);
+       }
        return icon;
 }
 
@@ -373,10 +379,9 @@ gs_appstream_refine_add_provides (GsApp *app, XbNode *component, GError **error)
        }
        for (guint i = 0; i < provides->len; i++) {
                XbNode *provide = g_ptr_array_index (provides, i);
-               g_autoptr(AsProvide) pr = as_provide_new ();
-               as_provide_set_kind (pr, as_provide_kind_from_string (xb_node_get_element (provide)));
-               as_provide_set_value (pr, xb_node_get_text (provide));
-               gs_app_add_provide (app, pr);
+               gs_app_add_provided_item (app,
+                                         as_provided_kind_from_string (xb_node_get_element (provide)),
+                                         xb_node_get_text (provide));
        }
 
        /* success */
@@ -596,7 +601,7 @@ gs_appstream_is_valid_project_group (const gchar *project_group)
 {
        if (project_group == NULL)
                return FALSE;
-       return as_utils_is_environment_id (project_group);
+       return as_utils_is_desktop_environment (project_group);
 }
 
 static gboolean
@@ -694,14 +699,8 @@ gs_appstream_refine_app (GsPlugin *plugin,
                                   "requires/id[@type='id']"
                                   "[text()='org.gnome.Software.desktop']", NULL);
        if (req != NULL) {
-#if AS_CHECK_VERSION(0,7,15)
-               gint rc = as_utils_vercmp_full (xb_node_get_attr (req, "version"),
-                                               PACKAGE_VERSION,
-                                               AS_VERSION_COMPARE_FLAG_NONE);
-#else
-               gint rc = as_utils_vercmp (xb_node_get_attr (req, "version"),
-                                          PACKAGE_VERSION);
-#endif
+               gint rc = as_utils_compare_versions (xb_node_get_attr (req, "version"),
+                                                    PACKAGE_VERSION);
                if (rc > 0) {
                        g_set_error (error,
                                     GS_PLUGIN_ERROR,
@@ -713,18 +712,18 @@ gs_appstream_refine_app (GsPlugin *plugin,
 
        /* types we can never launch */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_ADDON:
-       case AS_APP_KIND_CODEC:
-       case AS_APP_KIND_DRIVER:
-       case AS_APP_KIND_FIRMWARE:
-       case AS_APP_KIND_FONT:
-       case AS_APP_KIND_GENERIC:
-       case AS_APP_KIND_INPUT_METHOD:
-       case AS_APP_KIND_LOCALIZATION:
-       case AS_APP_KIND_OS_UPDATE:
-       case AS_APP_KIND_OS_UPGRADE:
-       case AS_APP_KIND_RUNTIME:
-       case AS_APP_KIND_SOURCE:
+       case AS_COMPONENT_KIND_ADDON:
+       case AS_COMPONENT_KIND_CODEC:
+       case AS_COMPONENT_KIND_DRIVER:
+       case AS_COMPONENT_KIND_FIRMWARE:
+       case AS_COMPONENT_KIND_FONT:
+       case AS_COMPONENT_KIND_GENERIC:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_LOCALIZATION:
+       case AS_COMPONENT_KIND_OS_UPDATE:
+       case AS_COMPONENT_KIND_OPERATING_SYSTEM:
+       case AS_COMPONENT_KIND_RUNTIME:
+       case AS_COMPONENT_KIND_REPOSITORY:
                gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
                break;
        default:
@@ -769,7 +768,7 @@ gs_appstream_refine_app (GsPlugin *plugin,
        /* set scope */
        tmp = xb_node_query_text (component, "../info/scope", NULL);
        if (tmp != NULL)
-               gs_app_set_scope (app, as_app_scope_from_string (tmp));
+               gs_app_set_scope (app, as_component_scope_from_string (tmp));
 
        /* set content rating */
        if (TRUE) {
@@ -885,10 +884,10 @@ gs_appstream_refine_app (GsPlugin *plugin,
        }
 
        /* set id kind */
-       if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN ||
-           gs_app_get_kind (app) == AS_APP_KIND_GENERIC) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_UNKNOWN ||
+           gs_app_get_kind (app) == AS_COMPONENT_KIND_GENERIC) {
                tmp = xb_node_get_attr (component, "type");
-               gs_app_set_kind (app, as_app_kind_from_string (tmp));
+               gs_app_set_kind (app, as_component_kind_from_string (tmp));
        }
 
        /* set the release date */
@@ -1010,34 +1009,6 @@ gs_appstream_refine_app (GsPlugin *plugin,
                        gs_app_add_kudo (app, GS_APP_KUDO_FEATURED_RECOMMENDED);
                if (xb_node_query_text (component, "categories/category[text()='Featured']", NULL) != NULL)
                        gs_app_add_kudo (app, GS_APP_KUDO_FEATURED_RECOMMENDED);
-
-               /* add new-style kudos */
-               kudos = xb_node_query (component, "kudos/kudo", 0, NULL);
-               for (guint i = 0; kudos != NULL && i < kudos->len; i++) {
-                       XbNode *kudo = g_ptr_array_index (kudos, i);
-                       switch (as_kudo_kind_from_string (xb_node_get_text (kudo))) {
-                       case AS_KUDO_KIND_SEARCH_PROVIDER:
-                               gs_app_add_kudo (app, GS_APP_KUDO_SEARCH_PROVIDER);
-                               break;
-                       case AS_KUDO_KIND_USER_DOCS:
-                               gs_app_add_kudo (app, GS_APP_KUDO_INSTALLS_USER_DOCS);
-                               break;
-                       case AS_KUDO_KIND_MODERN_TOOLKIT:
-                               gs_app_add_kudo (app, GS_APP_KUDO_MODERN_TOOLKIT);
-                               break;
-                       case AS_KUDO_KIND_NOTIFICATIONS:
-                               gs_app_add_kudo (app, GS_APP_KUDO_USES_NOTIFICATIONS);
-                               break;
-                       case AS_KUDO_KIND_HIGH_CONTRAST:
-                               gs_app_add_kudo (app, GS_APP_KUDO_HIGH_CONTRAST);
-                               break;
-                       case AS_KUDO_KIND_HI_DPI_ICON:
-                               gs_app_add_kudo (app, GS_APP_KUDO_HI_DPI_ICON);
-                               break;
-                       default:
-                               break;
-                       }
-               }
        }
 
        /* we have an origin in the XML */
@@ -1065,7 +1036,7 @@ gs_appstream_refine_app (GsPlugin *plugin,
 }
 
 typedef struct {
-       AsAppSearchMatch         match_value;
+       AsSearchTokenMatch       match_value;
        XbQuery                 *query;
 } GsAppstreamSearchHelper;
 
@@ -1127,18 +1098,18 @@ gs_appstream_search (GsPlugin *plugin,
        g_autoptr(GPtrArray) components = NULL;
        g_autoptr(GTimer) timer = g_timer_new ();
        const struct {
-               AsAppSearchMatch         match_value;
+               AsSearchTokenMatch      match_value;
                const gchar             *xpath;
        } queries[] = {
-               { AS_APP_SEARCH_MATCH_MIMETYPE, "mimetypes/mimetype[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_PKGNAME,  "pkgname[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_COMMENT,  "summary[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_NAME,     "name[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_KEYWORD,  "keywords/keyword[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_ID,       "id[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_ID,       "launchable[text()~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_ORIGIN,   "../components[@origin~=stem(?)]" },
-               { AS_APP_SEARCH_MATCH_NONE,     NULL }
+               { AS_SEARCH_TOKEN_MATCH_MIMETYPE,       "mimetypes/mimetype[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_PKGNAME,        "pkgname[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_SUMMARY,        "summary[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_NAME,   "name[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_KEYWORD,        "keywords/keyword[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_ID,     "id[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_ID,     "launchable[text()~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_ORIGIN, "../components[@origin~=stem(?)]" },
+               { AS_SEARCH_TOKEN_MATCH_NONE,   NULL }
        };
 
        /* add some weighted queries */
@@ -1560,36 +1531,36 @@ gs_appstream_component_add_extra_info (GsPlugin *plugin, XbBuilderNode *componen
 
        /* add the gnome-software-specific 'Addon' group and ensure they
         * all have an icon set */
-       switch (as_app_kind_from_string (kind)) {
-       case AS_APP_KIND_WEB_APP:
+       switch (as_component_kind_from_string (kind)) {
+       case AS_COMPONENT_KIND_WEB_APP:
                gs_appstream_component_add_keyword (component, kind);
                break;
-       case AS_APP_KIND_FONT:
+       case AS_COMPONENT_KIND_FONT:
                gs_appstream_component_add_category (component, "Addon");
                gs_appstream_component_add_category (component, "Font");
                break;
-       case AS_APP_KIND_DRIVER:
+       case AS_COMPONENT_KIND_DRIVER:
                gs_appstream_component_add_category (component, "Addon");
                gs_appstream_component_add_category (component, "Driver");
                gs_appstream_component_add_icon (component, "application-x-firmware-symbolic");
                break;
-       case AS_APP_KIND_LOCALIZATION:
+       case AS_COMPONENT_KIND_LOCALIZATION:
                gs_appstream_component_add_category (component, "Addon");
                gs_appstream_component_add_category (component, "Localization");
                gs_appstream_component_add_icon (component, "accessories-dictionary-symbolic");
                break;
-       case AS_APP_KIND_CODEC:
+       case AS_COMPONENT_KIND_CODEC:
                gs_appstream_component_add_category (component, "Addon");
                gs_appstream_component_add_category (component, "Codec");
                gs_appstream_component_add_icon (component, "application-x-addon");
                break;
-       case AS_APP_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
                gs_appstream_component_add_keyword (component, kind);
                gs_appstream_component_add_category (component, "Addon");
                gs_appstream_component_add_category (component, "InputSource");
                gs_appstream_component_add_icon (component, "system-run-symbolic");
                break;
-       case AS_APP_KIND_FIRMWARE:
+       case AS_COMPONENT_KIND_FIRMWARE:
                gs_appstream_component_add_icon (component, "system-run-symbolic");
                break;
        default:
diff --git a/plugins/core/gs-plugin-appstream.c b/plugins/core/gs-plugin-appstream.c
index f8fa1864e..44564ae77 100644
--- a/plugins/core/gs-plugin-appstream.c
+++ b/plugins/core/gs-plugin-appstream.c
@@ -214,20 +214,28 @@ gs_plugin_appstream_load_desktop_cb (XbBuilderSource *self,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       GString *xml;
-       g_autoptr(AsApp) app = as_app_new ();
+       gchar *xml;
+       g_autoptr(AsComponent) cpt = as_component_new ();
+       g_autoptr(AsContext) actx = as_context_new ();
        g_autoptr(GBytes) bytes = NULL;
+       gboolean ret;
+
        bytes = xb_builder_source_ctx_get_bytes (ctx, cancellable, error);
        if (bytes == NULL)
                return NULL;
-       as_app_set_id (app, xb_builder_source_ctx_get_filename (ctx));
-       if (!as_app_parse_data (app, bytes, AS_APP_PARSE_FLAG_USE_FALLBACKS, error))
+
+       as_component_set_id (cpt, xb_builder_source_ctx_get_filename (ctx));
+       ret = as_component_load_from_data (cpt,
+                                          actx,
+                                          AS_FORMAT_KIND_DESKTOP_ENTRY,
+                                          g_bytes_get_data (bytes, NULL),
+                                          error);
+       if (!ret)
                return NULL;
-       xml = as_app_to_xml (app, error);
+       xml = as_component_to_xml_data (cpt, actx, error);
        if (xml == NULL)
                return NULL;
-       g_string_prepend (xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-       return g_memory_input_stream_new_from_data (g_string_free (xml, FALSE), -1, g_free);
+       return g_memory_input_stream_new_from_data (xml, -1, g_free);
 }
 
 static gboolean
@@ -312,19 +320,29 @@ gs_plugin_appstream_load_dep11_cb (XbBuilderSource *self,
                                   GCancellable *cancellable,
                                   GError **error)
 {
-       GString *xml;
-       g_autoptr(AsStore) store = as_store_new ();
+       g_autoptr(AsMetadata) mdata = as_metadata_new ();
        g_autoptr(GBytes) bytes = NULL;
+       GError *tmp_error = NULL;
+       gchar *xml;
+
        bytes = xb_builder_source_ctx_get_bytes (ctx, cancellable, error);
        if (bytes == NULL)
                return NULL;
-       if (!as_store_from_bytes (store, bytes, cancellable, error))
-               return FALSE;
-       xml = as_store_to_xml (store, AS_NODE_INSERT_FLAG_NONE);
+
+       as_metadata_set_format_style (mdata, AS_FORMAT_STYLE_COLLECTION);
+       as_metadata_parse (mdata,
+                          g_bytes_get_data (bytes, NULL),
+                          AS_FORMAT_KIND_YAML,
+                          &tmp_error);
+       if (tmp_error != NULL) {
+               g_propagate_error (error, tmp_error);
+               return NULL;
+       }
+
+       xml = as_metadata_components_to_collection (mdata, AS_FORMAT_KIND_XML, error);
        if (xml == NULL)
                return NULL;
-       g_string_prepend (xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-       return g_memory_input_stream_new_from_data (g_string_free (xml, FALSE), -1, g_free);
+       return g_memory_input_stream_new_from_data (xml, -1, g_free);
 }
 
 static gboolean
@@ -655,7 +673,7 @@ gs_plugin_url_to_app (GsPlugin *plugin,
        app = gs_appstream_create_app (plugin, priv->silo, component, error);
        if (app == NULL)
                return FALSE;
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_list_add (list, app);
        return TRUE;
 }
@@ -908,7 +926,7 @@ gs_plugin_refine_wildcard (GsPlugin *plugin,
                new = gs_appstream_create_app (plugin, priv->silo, component, error);
                if (new == NULL)
                        return FALSE;
-               gs_app_set_scope (new, AS_APP_SCOPE_SYSTEM);
+               gs_app_set_scope (new, AS_COMPONENT_SCOPE_SYSTEM);
                gs_app_subsume_metadata (new, app);
                if (!gs_appstream_refine_app (plugin, new, priv->silo, component,
                                              refine_flags, error))
@@ -990,7 +1008,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
                if (app == NULL)
                        return FALSE;
                gs_app_set_state (app, GS_APP_STATE_INSTALLED);
-               gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+               gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
                gs_app_list_add (list, app);
        }
        return TRUE;
diff --git a/plugins/core/gs-plugin-generic-updates.c b/plugins/core/gs-plugin-generic-updates.c
index c42cddc14..2a45a4585 100644
--- a/plugins/core/gs-plugin-generic-updates.c
+++ b/plugins/core/gs-plugin-generic-updates.c
@@ -25,12 +25,12 @@ gs_plugin_generic_updates_merge_os_update (GsApp *app)
 {
        /* this is only for grouping system-installed packages */
        if (gs_app_get_bundle_kind (app) != AS_BUNDLE_KIND_PACKAGE ||
-           gs_app_get_scope (app) != AS_APP_SCOPE_SYSTEM)
+           gs_app_get_scope (app) != AS_COMPONENT_SCOPE_SYSTEM)
                return FALSE;
 
-       if (gs_app_get_kind (app) == AS_APP_KIND_GENERIC)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_GENERIC)
                return TRUE;
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return TRUE;
 
        return FALSE;
@@ -47,7 +47,7 @@ gs_plugin_generic_updates_get_os_update (GsPlugin *plugin)
        app = gs_app_new (id);
        gs_app_add_quirk (app, GS_APP_QUIRK_IS_PROXY);
        gs_app_set_management_plugin (app, "");
-       gs_app_set_kind (app, AS_APP_KIND_OS_UPDATE);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_OS_UPDATE);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE);
        gs_app_set_name (app,
                         GS_APP_QUALITY_NORMAL,
diff --git a/plugins/core/gs-plugin-icons.c b/plugins/core/gs-plugin-icons.c
index 112f1d253..59fb0a3e0 100644
--- a/plugins/core/gs-plugin-icons.c
+++ b/plugins/core/gs-plugin-icons.c
@@ -218,6 +218,7 @@ gs_plugin_icons_add_theme_path (GsPlugin *plugin, const gchar *path)
        GsPluginData *priv = gs_plugin_get_data (plugin);
        if (path == NULL)
                return;
+
        if (!g_hash_table_contains (priv->icon_theme_paths, path)) {
                gtk_icon_theme_prepend_search_path (priv->icon_theme, path);
                g_hash_table_add (priv->icon_theme_paths, g_strdup (path));
@@ -240,7 +241,8 @@ gs_plugin_icons_load_stock (GsPlugin *plugin, AsIcon *icon, GError **error)
                                     "icon has no name");
                return NULL;
        }
-       gs_plugin_icons_add_theme_path (plugin, as_icon_get_prefix (icon));
+
+       gs_plugin_icons_add_theme_path (plugin, as_icon_get_filename (icon));
        size = (gint) (64 * gs_plugin_get_scale (plugin));
        pixbuf = gtk_icon_theme_load_icon (priv->icon_theme,
                                           as_icon_get_name (icon),
@@ -258,12 +260,43 @@ gs_plugin_icons_load_stock (GsPlugin *plugin, AsIcon *icon, GError **error)
 static GdkPixbuf *
 gs_plugin_icons_load_cached (GsPlugin *plugin, AsIcon *icon, GError **error)
 {
-       if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, error)) {
-               gs_utils_error_convert_gdk_pixbuf (error);
-               gs_utils_error_convert_appstream (error);
+       const gchar *fname = as_icon_get_filename (icon);
+       const gchar *icon_fname = as_icon_get_name (icon);
+
+       if ((fname == NULL) || (icon_fname == NULL)) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "Icon %s has no full filename - can not load pixbuf.",
+                            icon_fname);
                return NULL;
        }
-       return g_object_ref (as_icon_get_pixbuf (icon));
+
+       if (!g_str_has_suffix (fname, icon_fname)) {
+               g_autofree gchar *full_fname = NULL;
+               if (as_icon_get_scale (icon) <= 1) {
+                       full_fname = g_strdup_printf ("%s/%ux%u/%s",
+                                                       fname,
+                                                       as_icon_get_width (icon),
+                                                       as_icon_get_height (icon),
+                                                       icon_fname);
+               } else {
+                       full_fname = g_strdup_printf ("%s/%ux%u@%u/%s",
+                                                       fname,
+                                                       as_icon_get_width (icon),
+                                                       as_icon_get_height (icon),
+                                                       as_icon_get_scale (icon),
+                                                       icon_fname);
+               }
+               /* cache new filename, overriding the incomplete one */
+               as_icon_set_filename (icon, full_fname);
+               fname = as_icon_get_filename (icon);
+       }
+
+       return gdk_pixbuf_new_from_file_at_size (fname,
+                                                (gint) as_icon_get_width (icon),
+                                                (gint) as_icon_get_height (icon),
+                                                error);
 }
 
 static gboolean
diff --git a/plugins/core/gs-plugin-key-colors-metadata.c b/plugins/core/gs-plugin-key-colors-metadata.c
index 2b8fa2135..7e31e5ae8 100644
--- a/plugins/core/gs-plugin-key-colors-metadata.c
+++ b/plugins/core/gs-plugin-key-colors-metadata.c
@@ -58,7 +58,7 @@ refine_app (GsPlugin             *plugin,
                                                 color->red * 255.f,
                                                 color->green * 255.f,
                                                 color->blue * 255.f);
-                       as_utils_string_replace (css_new, key, value);
+                       as_gstring_replace (css_new, key, value);
                }
 
                /* only replace if it's different */
diff --git a/plugins/core/gs-plugin-os-release.c b/plugins/core/gs-plugin-os-release.c
index 378748040..03aee6fcd 100644
--- a/plugins/core/gs-plugin-os-release.c
+++ b/plugins/core/gs-plugin-os-release.c
@@ -19,7 +19,7 @@ gs_plugin_initialize (GsPlugin *plugin)
 {
        GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
        priv->app_system = gs_app_new ("system");
-       gs_app_set_kind (priv->app_system, AS_APP_KIND_OS_UPGRADE);
+       gs_app_set_kind (priv->app_system, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        gs_app_set_state (priv->app_system, GS_APP_STATE_INSTALLED);
 }
 
diff --git a/plugins/core/gs-self-test.c b/plugins/core/gs-self-test.c
index 364c6c20c..f2c285890 100644
--- a/plugins/core/gs-self-test.c
+++ b/plugins/core/gs-self-test.c
@@ -46,7 +46,7 @@ gs_plugins_core_search_repo_name_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "arachne.desktop");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
 }
 
 static void
@@ -76,7 +76,7 @@ gs_plugins_core_os_release_func (GsPluginLoader *plugin_loader)
 
        /* make sure there is valid content */
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.fedoraproject.Fedora-25");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_OS_UPGRADE);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED);
        g_assert_cmpstr (gs_app_get_name (app), ==, "Fedora");
        g_assert_cmpstr (gs_app_get_version (app), ==, "25");
@@ -117,12 +117,12 @@ gs_plugins_core_generic_updates_func (GsPluginLoader *plugin_loader)
        list = gs_app_list_new ();
        app1 = gs_app_new ("package1");
        app2 = gs_app_new ("package2");
-       gs_app_set_kind (app1, AS_APP_KIND_GENERIC);
-       gs_app_set_kind (app2, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app1, AS_COMPONENT_KIND_GENERIC);
+       gs_app_set_kind (app2, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app1, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_bundle_kind (app2, AS_BUNDLE_KIND_PACKAGE);
-       gs_app_set_scope (app1, AS_APP_SCOPE_SYSTEM);
-       gs_app_set_scope (app2, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app1, AS_COMPONENT_SCOPE_SYSTEM);
+       gs_app_set_scope (app2, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_set_state (app1, GS_APP_STATE_UPDATABLE);
        gs_app_set_state (app2, GS_APP_STATE_UPDATABLE);
        gs_app_add_source (app1, "package1");
@@ -146,7 +146,7 @@ gs_plugins_core_generic_updates_func (GsPluginLoader *plugin_loader)
 
        /* make sure the os update is valid */
        g_assert_cmpstr (gs_app_get_id (os_update), ==, "org.gnome.Software.OsUpdate");
-       g_assert_cmpint (gs_app_get_kind (os_update), ==, AS_APP_KIND_OS_UPDATE);
+       g_assert_cmpint (gs_app_get_kind (os_update), ==, AS_COMPONENT_KIND_OS_UPDATE);
        g_assert (gs_app_has_quirk (os_update, GS_APP_QUIRK_IS_PROXY));
 
        /* must have two related apps, the ones we added earlier */
@@ -157,7 +157,7 @@ gs_plugins_core_generic_updates_func (GsPluginLoader *plugin_loader)
        list_wildcard = gs_app_list_new ();
        app_wildcard = gs_app_new ("nosuchapp.desktop");
        gs_app_add_quirk (app_wildcard, GS_APP_QUIRK_IS_WILDCARD);
-       gs_app_set_kind (app_wildcard, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app_wildcard, AS_COMPONENT_KIND_GENERIC);
        gs_app_list_add (list_wildcard, app_wildcard);
        plugin_job2 = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE,
                                          "list", list_wildcard,
@@ -171,7 +171,7 @@ gs_plugins_core_generic_updates_func (GsPluginLoader *plugin_loader)
        /* no OsUpdate item created */
        for (guint i = 0; i < gs_app_list_length (list_wildcard); i++) {
                GsApp *app_tmp = gs_app_list_index (list_wildcard, i);
-               g_assert_cmpint (gs_app_get_kind (app_tmp), !=, AS_APP_KIND_OS_UPDATE);
+               g_assert_cmpint (gs_app_get_kind (app_tmp), !=, AS_COMPONENT_KIND_OS_UPDATE);
                g_assert (!gs_app_has_quirk (app_tmp, GS_APP_QUIRK_IS_PROXY));
        }
 }
diff --git a/plugins/dpkg/gs-plugin-dpkg.c b/plugins/dpkg/gs-plugin-dpkg.c
index a41c7c931..eb386a127 100644
--- a/plugins/dpkg/gs-plugin-dpkg.c
+++ b/plugins/dpkg/gs-plugin-dpkg.c
@@ -84,7 +84,7 @@ gs_plugin_file_to_app (GsPlugin *plugin,
        gs_app_set_size_installed (app, 1024 * g_ascii_strtoull (tokens[2], NULL, 10));
        gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, tokens[3]);
        gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, tokens[4]);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_metadata (app, "GnomeSoftware::Creator",
                             gs_plugin_get_name (plugin));
diff --git a/plugins/dummy/gs-plugin-dummy.c b/plugins/dummy/gs-plugin-dummy.c
index 87d3401c6..c8176e9ae 100644
--- a/plugins/dummy/gs-plugin-dummy.c
+++ b/plugins/dummy/gs-plugin-dummy.c
@@ -55,7 +55,7 @@ gs_plugin_initialize (GsPlugin *plugin)
 
        /* add source */
        priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin));
-       gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (priv->cached_origin, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_origin_hostname (priv->cached_origin, "http://www.bbc.co.uk/";);
 
        /* add the source to the plugin cache which allows us to match the
@@ -316,7 +316,7 @@ gs_plugin_add_search (GsPlugin *plugin,
        gs_app_add_icon (app, ic);
        gs_app_set_size_installed (app, 42 * 1024 * 1024);
        gs_app_set_size_download (app, 50 * 1024 * 1024);
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_state (app, GS_APP_STATE_INSTALLED);
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_set_metadata (app, "GnomeSoftware::Creator",
@@ -358,7 +358,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
        gs_app_set_update_details (app, "Do not crash when using libvirt.");
        gs_app_set_update_urgency (app, AS_URGENCY_KIND_HIGH);
        gs_app_add_icon (app, ic);
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE);
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_list_add (list, app);
@@ -370,9 +370,9 @@ gs_plugin_add_updates (GsPlugin *plugin,
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Development files for libvirt");
        gs_app_set_update_details (app, "Fix several memory leaks.");
        gs_app_set_update_urgency (app, AS_URGENCY_KIND_LOW);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE);
        gs_app_add_source (app, "libvirt-glib-devel");
        gs_app_add_source_id (app, "libvirt-glib-devel;0.0.1;noarch;fedora");
@@ -386,9 +386,9 @@ gs_plugin_add_updates (GsPlugin *plugin,
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "library for chiron");
        gs_app_set_update_details (app, "Do not crash when using libvirt.");
        gs_app_set_update_urgency (app, AS_URGENCY_KIND_HIGH);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE);
        gs_app_add_source (app, "chiron-libs");
        gs_app_add_source_id (app, "chiron-libs;0.0.1;i386;updates-testing");
@@ -403,7 +403,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
        gs_app_set_update_details (proxy, "Update all related apps.");
        gs_app_set_update_urgency (proxy, AS_URGENCY_KIND_HIGH);
        gs_app_add_icon (proxy, ic);
-       gs_app_set_kind (proxy, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (proxy, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_add_quirk (proxy, GS_APP_QUIRK_IS_PROXY);
        gs_app_set_state (proxy, GS_APP_STATE_UPDATABLE_LIVE);
        gs_app_set_management_plugin (proxy, gs_plugin_get_name (plugin));
@@ -414,7 +414,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
        app = gs_app_new ("proxy-related-app.desktop");
        gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Related app");
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A related app");
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE);
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_add_related (proxy, app);
@@ -424,7 +424,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
        app = gs_app_new ("proxy-another-related-app.desktop");
        gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Another Related app");
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A related app");
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE_LIVE);
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_add_related (proxy, app);
@@ -448,7 +448,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
                g_autoptr(GsApp) app = gs_app_new (NULL);
                gs_app_add_source (app, packages[i]);
                gs_app_set_state (app, GS_APP_STATE_INSTALLED);
-               gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
                gs_app_set_origin (app, "london-west");
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
                gs_app_list_add (list, app);
@@ -458,7 +458,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
        for (i = 0; app_ids[i] != NULL; i++) {
                g_autoptr(GsApp) app = gs_app_new (app_ids[i]);
                gs_app_set_state (app, GS_APP_STATE_INSTALLED);
-               gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
                gs_app_list_add (list, app);
        }
@@ -484,7 +484,7 @@ gs_plugin_add_popular (GsPlugin *plugin,
 
        /* add again, this time with a prefix so it gets deduplicated */
        app2 = gs_app_new ("zeus.desktop");
-       gs_app_set_scope (app2, AS_APP_SCOPE_USER);
+       gs_app_set_scope (app2, AS_COMPONENT_SCOPE_USER);
        gs_app_set_bundle_kind (app2, AS_BUNDLE_KIND_SNAP);
        gs_app_set_metadata (app2, "GnomeSoftware::Creator",
                             gs_plugin_get_name (plugin));
@@ -618,8 +618,8 @@ refine_app (GsPlugin *plugin,
            g_strcmp0 (gs_app_get_id (app), "mate-spell.desktop") == 0 ||
            g_strcmp0 (gs_app_get_id (app), "com.hughski.ColorHug2.driver") == 0 ||
            g_strcmp0 (gs_app_get_id (app), "zeus.desktop") == 0) {
-               if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN)
-                       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+               if (gs_app_get_kind (app) == AS_COMPONENT_KIND_UNKNOWN)
+                       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        }
 
        /* license */
@@ -741,10 +741,10 @@ gs_plugin_add_category_apps (GsPlugin *plugin,
        gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron");
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "View and use virtual machines");
        gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, "http://www.box.org";);
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
        gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file 
("/usr/share/icons/hicolor/48x48/apps/chiron.desktop.png", NULL));
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_list_add (list, app);
        return TRUE;
@@ -761,10 +761,10 @@ gs_plugin_add_recent (GsPlugin *plugin,
        gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron");
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "View and use virtual machines");
        gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, "http://www.box.org";);
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
        gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file 
("/usr/share/icons/hicolor/48x48/apps/chiron.desktop.png", NULL));
-       gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_list_add (list, app);
        return TRUE;
@@ -792,8 +792,8 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
        }
 
        app = gs_app_new ("org.fedoraproject.release-rawhide.upgrade");
-       gs_app_set_scope (app, AS_APP_SCOPE_USER);
-       gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_USER);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
        gs_app_set_name (app, GS_APP_QUALITY_LOWEST, "Fedora");
diff --git a/plugins/dummy/gs-self-test.c b/plugins/dummy/gs-self-test.c
index bc8da5015..de0e91959 100644
--- a/plugins/dummy/gs-self-test.c
+++ b/plugins/dummy/gs-self-test.c
@@ -267,7 +267,7 @@ gs_plugins_dummy_updates_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 3);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "chiron.desktop");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_UPDATABLE_LIVE);
        g_assert_cmpstr (gs_app_get_update_details (app), ==, "Do not crash when using libvirt.");
        g_assert_cmpint (gs_app_get_update_urgency (app), ==, AS_URGENCY_KIND_HIGH);
@@ -277,7 +277,7 @@ gs_plugins_dummy_updates_func (GsPluginLoader *plugin_loader)
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.gnome.Software.OsUpdate");
        g_assert_cmpstr (gs_app_get_name (app), ==, "OS Updates");
        g_assert_cmpstr (gs_app_get_summary (app), ==, "Includes performance, stability and security 
improvements.");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_OS_UPDATE);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_OS_UPDATE);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_UPDATABLE);
        g_assert_cmpint (gs_app_list_length (gs_app_get_related (app)), ==, 2);
 
@@ -309,7 +309,7 @@ gs_plugins_dummy_distro_upgrades_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.fedoraproject.release-rawhide.upgrade");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_OS_UPGRADE);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE);
 
        /* this should be set with a higher priority by AppStream */
@@ -369,7 +369,7 @@ gs_plugins_dummy_installed_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "zeus.desktop");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED);
        g_assert_cmpstr (gs_app_get_name (app), ==, "Zeus");
        g_assert_cmpstr (gs_app_get_source_default (app), ==, "zeus");
@@ -396,7 +396,7 @@ gs_plugins_dummy_installed_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (addons), ==, 1);
        addon = gs_app_list_index (addons, 0);
        g_assert_cmpstr (gs_app_get_id (addon), ==, "zeus-spell.addon");
-       g_assert_cmpint (gs_app_get_kind (addon), ==, AS_APP_KIND_ADDON);
+       g_assert_cmpint (gs_app_get_kind (addon), ==, AS_COMPONENT_KIND_ADDON);
        g_assert_cmpint (gs_app_get_state (addon), ==, GS_APP_STATE_AVAILABLE);
        g_assert_cmpstr (gs_app_get_name (addon), ==, "Spell Check");
        g_assert_cmpstr (gs_app_get_source_default (addon), ==, "zeus-spell");
@@ -427,7 +427,7 @@ gs_plugins_dummy_search_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "zeus.desktop");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
 }
 
 static void
@@ -454,10 +454,10 @@ gs_plugins_dummy_search_alternate_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 2);
        app_tmp = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app_tmp), ==, "chiron.desktop");
-       g_assert_cmpint (gs_app_get_kind (app_tmp), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app_tmp), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        app_tmp = gs_app_list_index (list, 1);
        g_assert_cmpstr (gs_app_get_id (app_tmp), ==, "zeus.desktop");
-       g_assert_cmpint (gs_app_get_kind (app_tmp), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app_tmp), ==, AS_COMPONENT_KIND_DESKTOP_APP);
 }
 
 static void
@@ -516,7 +516,7 @@ gs_plugins_dummy_url_to_app_func (GsPluginLoader *plugin_loader)
        g_assert_no_error (error);
        g_assert (app != NULL);
        g_assert_cmpstr (gs_app_get_id (app), ==, "chiron.desktop");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
 }
 
 static void
@@ -633,7 +633,7 @@ gs_plugins_dummy_limit_parallel_ops_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app1 = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app1), ==, "org.fedoraproject.release-rawhide.upgrade");
-       g_assert_cmpint (gs_app_get_kind (app1), ==, AS_APP_KIND_OS_UPGRADE);
+       g_assert_cmpint (gs_app_get_kind (app1), ==, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        g_assert_cmpint (gs_app_get_state (app1), ==, GS_APP_STATE_AVAILABLE);
 
        /* allow only one operation at a time */
diff --git a/plugins/eos-updater/gs-plugin-eos-updater.c b/plugins/eos-updater/gs-plugin-eos-updater.c
index 903a2528b..a8d7127a7 100644
--- a/plugins/eos-updater/gs-plugin-eos-updater.c
+++ b/plugins/eos-updater/gs-plugin-eos-updater.c
@@ -556,8 +556,8 @@ gs_plugin_setup (GsPlugin *plugin,
        /* create the OS upgrade */
        app = gs_app_new ("com.endlessm.EOS.upgrade");
        gs_app_add_icon (app, ic);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
-       gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        /* TRANSLATORS: ‘Endless OS’ is a brand name; https://endlessos.com/ */
        gs_app_set_name (app, GS_APP_QUALITY_LOWEST, _("Endless OS"));
        gs_app_set_summary (app, GS_APP_QUALITY_NORMAL,
diff --git a/plugins/fedora-langpacks/gs-plugin-fedora-langpacks.c 
b/plugins/fedora-langpacks/gs-plugin-fedora-langpacks.c
index ea673b10c..26534548b 100644
--- a/plugins/fedora-langpacks/gs-plugin-fedora-langpacks.c
+++ b/plugins/fedora-langpacks/gs-plugin-fedora-langpacks.c
@@ -86,9 +86,9 @@ gs_plugin_add_langpacks (GsPlugin *plugin,
        if (!g_file_test (cachefn, G_FILE_TEST_EXISTS)) {
                g_autoptr(GsApp) app = gs_app_new (NULL);
                gs_app_set_metadata (app, "GnomeSoftware::Creator", gs_plugin_get_name (plugin));
-               gs_app_set_kind (app, AS_APP_KIND_LOCALIZATION);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_LOCALIZATION);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-               gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+               gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
                gs_app_add_source (app, langpack_pkgname);
                gs_app_list_add (list, app);
 
diff --git a/plugins/fedora-langpacks/gs-self-test.c b/plugins/fedora-langpacks/gs-self-test.c
index ae2344ced..df15e33d5 100644
--- a/plugins/fedora-langpacks/gs-self-test.c
+++ b/plugins/fedora-langpacks/gs-self-test.c
@@ -52,7 +52,7 @@ gs_plugins_fedora_langpacks_func (GsPluginLoader *plugin_loader)
        /* check app's source and kind */
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_source_default (app), ==, "langpacks-ja");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_LOCALIZATION);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_LOCALIZATION);
 }
 
 int
diff --git a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c 
b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c
index e5abbd1d0..c26f846c8 100644
--- a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c
+++ b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c
@@ -153,7 +153,7 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
 
        /* add source */
        priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin));
-       gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (priv->cached_origin, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_origin_hostname (priv->cached_origin,
                                    FEDORA_PKGDB_COLLECTIONS_API_URI);
 
@@ -275,7 +275,7 @@ _create_upgrade_from_info (GsPlugin *plugin, PkgdbItem *item)
        /* create */
        app = gs_app_new (app_id);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE);
-       gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_name (app, GS_APP_QUALITY_LOWEST, item->name);
        gs_app_set_summary (app, GS_APP_QUALITY_LOWEST,
@@ -514,7 +514,7 @@ refine_app_locked (GsPlugin             *plugin,
        const gchar *cpe_name;
 
        /* not for us */
-       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE)
+       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
 
        /* not enough metadata */
diff --git a/plugins/flatpak/gs-flatpak-utils.c b/plugins/flatpak/gs-flatpak-utils.c
index ce530bd32..2a475c7d1 100644
--- a/plugins/flatpak/gs-flatpak-utils.c
+++ b/plugins/flatpak/gs-flatpak-utils.c
@@ -66,7 +66,7 @@ gs_flatpak_app_new_from_remote (FlatpakRemote *xremote)
        g_autoptr(GsApp) app = NULL;
 
        app = gs_flatpak_app_new (flatpak_remote_get_name (xremote));
-       gs_app_set_kind (app, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_state (app, flatpak_remote_get_disabled (xremote) ?
                          GS_APP_STATE_AVAILABLE : GS_APP_STATE_INSTALLED);
        gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
@@ -164,7 +164,7 @@ gs_flatpak_app_new_from_repo_file (GFile *file,
        /* create source */
        app = gs_flatpak_app_new (repo_id);
        gs_flatpak_app_set_file_kind (app, GS_FLATPAK_APP_FILE_KIND_REPO);
-       gs_app_set_kind (app, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE_LOCAL);
        gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
        gs_app_set_name (app, GS_APP_QUALITY_NORMAL, repo_title);
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 52027d786..e72aca8dc 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -33,7 +33,7 @@ struct _GsFlatpak {
        GHashTable              *broken_remotes;
        GMutex                   broken_remotes_mutex;
        GFileMonitor            *monitor;
-       AsAppScope               scope;
+       AsComponentScope                 scope;
        GsPlugin                *plugin;
        XbSilo                  *silo;
        GRWLock                  silo_lock;
@@ -52,9 +52,9 @@ gs_flatpak_refresh_appstream (GsFlatpak *self, guint cache_age,
 static void
 gs_plugin_refine_item_scope (GsFlatpak *self, GsApp *app)
 {
-       if (gs_app_get_scope (app) == AS_APP_SCOPE_UNKNOWN) {
+       if (gs_app_get_scope (app) == AS_COMPONENT_SCOPE_UNKNOWN) {
                gboolean is_user = flatpak_installation_get_is_user (self->installation);
-               gs_app_set_scope (app, is_user ? AS_APP_SCOPE_USER : AS_APP_SCOPE_SYSTEM);
+               gs_app_set_scope (app, is_user ? AS_COMPONENT_SCOPE_USER : AS_COMPONENT_SCOPE_SYSTEM);
        }
 }
 
@@ -86,20 +86,20 @@ static void
 gs_flatpak_set_kind_from_flatpak (GsApp *app, FlatpakRef *xref)
 {
        if (flatpak_ref_get_kind (xref) == FLATPAK_REF_KIND_APP) {
-               gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
        } else if (flatpak_ref_get_kind (xref) == FLATPAK_REF_KIND_RUNTIME) {
                const gchar *id = gs_app_get_id (app);
                /* this is anything that's not an app, including locales
                 * sources and debuginfo */
                if (g_str_has_suffix (id, ".Locale")) {
-                       gs_app_set_kind (app, AS_APP_KIND_LOCALIZATION);
+                       gs_app_set_kind (app, AS_COMPONENT_KIND_LOCALIZATION);
                } else if (g_str_has_suffix (id, ".Debug") ||
                           g_str_has_suffix (id, ".Sources") ||
                           g_str_has_prefix (id, "org.freedesktop.Platform.Icontheme.") ||
                           g_str_has_prefix (id, "org.gtk.Gtk3theme.")) {
-                       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+                       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
                } else {
-                       gs_app_set_kind (app, AS_APP_KIND_RUNTIME);
+                       gs_app_set_kind (app, AS_COMPONENT_KIND_RUNTIME);
                }
        }
 }
@@ -231,8 +231,8 @@ gs_flatpak_set_metadata (GsFlatpak *self, GsApp *app, FlatpakRef *xref)
        gs_flatpak_app_set_commit (app, flatpak_ref_get_commit (xref));
 
        /* map the flatpak kind to the gnome-software kind */
-       if (gs_app_get_kind (app) == AS_APP_KIND_UNKNOWN ||
-           gs_app_get_kind (app) == AS_APP_KIND_GENERIC) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_UNKNOWN ||
+           gs_app_get_kind (app) == AS_COMPONENT_KIND_GENERIC) {
                gs_flatpak_set_kind_from_flatpak (app, xref);
        }
 }
@@ -270,8 +270,8 @@ gs_flatpak_create_app (GsFlatpak *self, const gchar *origin, FlatpakRef *xref)
 
        /* Don't add NULL origin apps to the cache. If the app is later set to
         * origin x the cache may return it as a match for origin y since the cache
-        * hash table uses as_utils_unique_id_equal() as the equal func and a NULL
-        * origin becomes a "*" in as_utils_unique_id_build().
+        * hash table uses as_utils_data_id_equal() as the equal func and a NULL
+        * origin becomes a "*" in as_utils_build_data_id().
         */
        if (origin != NULL)
                gs_plugin_cache_add (self->plugin, NULL, app);
@@ -573,7 +573,7 @@ gs_flatpak_add_apps_from_xremote (GsFlatpak *self,
        /* add metadata */
        icon_prefix = g_build_filename (appstream_dir_fn, "icons", NULL);
        info = xb_builder_node_insert (NULL, "info", NULL);
-       xb_builder_node_insert_text (info, "scope", as_app_scope_to_string (self->scope), NULL);
+       xb_builder_node_insert_text (info, "scope", as_component_scope_to_string (self->scope), NULL);
        xb_builder_node_insert_text (info, "icon-prefix", icon_prefix, NULL);
        xb_builder_source_set_info (source, info);
 
@@ -627,20 +627,29 @@ gs_plugin_appstream_load_desktop_cb (XbBuilderSource *self,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       GString *xml;
-       g_autoptr(AsApp) app = as_app_new ();
+       gchar *xml;
+       g_autoptr(AsComponent) cpt = as_component_new ();
+       g_autoptr(AsContext) actx = as_context_new ();
        g_autoptr(GBytes) bytes = NULL;
+       gboolean ret;
+
        bytes = xb_builder_source_ctx_get_bytes (ctx, cancellable, error);
        if (bytes == NULL)
                return NULL;
-       as_app_set_id (app, xb_builder_source_ctx_get_filename (ctx));
-       if (!as_app_parse_data (app, bytes, AS_APP_PARSE_FLAG_USE_FALLBACKS, error))
+
+       as_component_set_id (cpt, xb_builder_source_ctx_get_filename (ctx));
+       ret = as_component_load_from_data (cpt,
+                                          actx,
+                                          AS_FORMAT_KIND_DESKTOP_ENTRY,
+                                          g_bytes_get_data (bytes, NULL),
+                                          error);
+       if (!ret)
                return NULL;
-       xml = as_app_to_xml (app, error);
+       xml = as_component_to_xml_data (cpt, actx, error);
        if (xml == NULL)
                return NULL;
-       g_string_prepend (xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-       return g_memory_input_stream_new_from_data (g_string_free (xml, FALSE), -1, g_free);
+
+       return g_memory_input_stream_new_from_data (xml, -1, g_free);
 }
 
 static gboolean
@@ -669,7 +678,7 @@ gs_flatpak_load_desktop_fn (GsFlatpak *self,
 
        /* set the component metadata */
        info = xb_builder_node_insert (NULL, "info", NULL);
-       xb_builder_node_insert_text (info, "scope", as_app_scope_to_string (self->scope), NULL);
+       xb_builder_node_insert_text (info, "scope", as_component_scope_to_string (self->scope), NULL);
        xb_builder_node_insert_text (info, "icon-prefix", icon_prefix, NULL);
        xb_builder_source_set_info (source, info);
 
@@ -1059,8 +1068,8 @@ gs_flatpak_set_metadata_installed (GsFlatpak *self, GsApp *app,
        }
 
        /* If it's a runtime, check if the main-app info should be set. Note that
-        * checking the app for AS_APP_KIND_RUNTIME is not good enough because it
-        * could be e.g. AS_APP_KIND_LOCALIZATION and still be a runtime from
+        * checking the app for AS_COMPONENT_KIND_RUNTIME is not good enough because it
+        * could be e.g. AS_COMPONENT_KIND_LOCALIZATION and still be a runtime from
         * Flatpak's perspective.
         */
        if (gs_flatpak_app_get_ref_kind (app) == FLATPAK_REF_KIND_RUNTIME &&
@@ -1657,7 +1666,7 @@ gs_refine_item_metadata (GsFlatpak *self, GsApp *app,
                return TRUE;
 
        /* not a valid type */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return TRUE;
 
        /* AppStream sets the source to appname/arch/branch, if this isn't set
@@ -1907,7 +1916,7 @@ gs_flatpak_create_runtime (GsFlatpak *self, GsApp *parent, const gchar *runtime)
        gs_flatpak_claim_app (self, app);
        source = g_strdup_printf ("runtime/%s", runtime);
        gs_app_add_source (app, source);
-       gs_app_set_kind (app, AS_APP_KIND_RUNTIME);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_RUNTIME);
        gs_app_set_branch (app, split[2]);
 
        /* search in the cache */
@@ -1922,8 +1931,8 @@ gs_flatpak_create_runtime (GsFlatpak *self, GsApp *parent, const gchar *runtime)
        }
 
        /* if the app is per-user we can also use the installed system runtime */
-       if (gs_app_get_scope (parent) == AS_APP_SCOPE_USER) {
-               gs_app_set_scope (app, AS_APP_SCOPE_UNKNOWN);
+       if (gs_app_get_scope (parent) == AS_COMPONENT_SCOPE_USER) {
+               gs_app_set_scope (app, AS_COMPONENT_SCOPE_UNKNOWN);
                app_cache = gs_plugin_cache_lookup (self->plugin, gs_app_get_unique_id (app));
                if (app_cache != NULL)
                        return g_steal_pointer (&app_cache);
@@ -2059,7 +2068,7 @@ gs_plugin_refine_item_metadata (GsFlatpak *self,
        g_autoptr(GFile) installation_path = NULL;
 
        /* not applicable */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return TRUE;
        if (gs_flatpak_app_get_ref_kind (app) != FLATPAK_REF_KIND_APP)
                return TRUE;
@@ -2129,7 +2138,7 @@ gs_plugin_refine_item_size (GsFlatpak *self,
        /* not applicable */
        if (gs_app_get_state (app) == GS_APP_STATE_AVAILABLE_LOCAL)
                return TRUE;
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return TRUE;
 
        /* already set */
@@ -2326,7 +2335,7 @@ gs_flatpak_refine_appstream_from_bytes (GsFlatpak *self,
                g_autofree char *icon_prefix = NULL;
 
                info = xb_builder_node_insert (NULL, "info", NULL);
-               xb_builder_node_insert_text (info, "scope", as_app_scope_to_string (self->scope), NULL);
+               xb_builder_node_insert_text (info, "scope", as_component_scope_to_string (self->scope), NULL);
                icon_prefix = g_build_filename (flatpak_installed_ref_get_deploy_dir (installed_ref),
                                                "files", "share", "app-info", "icons", "flatpak", NULL);
                xb_builder_node_insert_text (info, "icon-prefix", icon_prefix, NULL);
@@ -3234,7 +3243,7 @@ gs_flatpak_get_id (GsFlatpak *self)
        if (self->id == NULL) {
                GString *str = g_string_new ("flatpak");
                g_string_append_printf (str, "-%s",
-                                       as_app_scope_to_string (self->scope));
+                                       as_component_scope_to_string (self->scope));
                if (flatpak_installation_get_id (self->installation) != NULL) {
                        g_string_append_printf (str, "-%s",
                                                flatpak_installation_get_id (self->installation));
@@ -3246,7 +3255,7 @@ gs_flatpak_get_id (GsFlatpak *self)
        return self->id;
 }
 
-AsAppScope
+AsComponentScope
 gs_flatpak_get_scope (GsFlatpak *self)
 {
        return self->scope;
@@ -3316,7 +3325,7 @@ gs_flatpak_new (GsPlugin *plugin, FlatpakInstallation *installation, GsFlatpakFl
        self = g_object_new (GS_TYPE_FLATPAK, NULL);
        self->installation = g_object_ref (installation);
        self->scope = flatpak_installation_get_is_user (installation)
-                               ? AS_APP_SCOPE_USER : AS_APP_SCOPE_SYSTEM;
+                               ? AS_COMPONENT_SCOPE_USER : AS_COMPONENT_SCOPE_SYSTEM;
        self->plugin = g_object_ref (plugin);
        self->flags = flags;
        return GS_FLATPAK (self);
diff --git a/plugins/flatpak/gs-flatpak.h b/plugins/flatpak/gs-flatpak.h
index e5af289eb..40ab24f71 100644
--- a/plugins/flatpak/gs-flatpak.h
+++ b/plugins/flatpak/gs-flatpak.h
@@ -32,7 +32,7 @@ FlatpakInstallation *gs_flatpak_get_installation (GsFlatpak           *self);
 
 GsApp  *gs_flatpak_ref_to_app (GsFlatpak *self, const gchar *ref, GCancellable *cancellable, GError **error);
 
-AsAppScope     gs_flatpak_get_scope            (GsFlatpak              *self);
+AsComponentScope       gs_flatpak_get_scope            (GsFlatpak              *self);
 const gchar    *gs_flatpak_get_id              (GsFlatpak              *self);
 gboolean       gs_flatpak_setup                (GsFlatpak              *self,
                                                 GCancellable           *cancellable,
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index fd862b80a..0279b011f 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -71,11 +71,11 @@ gs_plugin_initialize (GsPlugin *plugin)
 }
 
 static gboolean
-_as_app_scope_is_compatible (AsAppScope scope1, AsAppScope scope2)
+_as_component_scope_is_compatible (AsComponentScope scope1, AsComponentScope scope2)
 {
-       if (scope1 == AS_APP_SCOPE_UNKNOWN)
+       if (scope1 == AS_COMPONENT_SCOPE_UNKNOWN)
                return TRUE;
-       if (scope2 == AS_APP_SCOPE_UNKNOWN)
+       if (scope2 == AS_COMPONENT_SCOPE_UNKNOWN)
                return TRUE;
        return scope1 == scope2;
 }
@@ -262,7 +262,7 @@ gs_plugin_flatpak_get_handler (GsPlugin *plugin, GsApp *app)
        /* find a scope that matches */
        for (guint i = 0; i < priv->flatpaks->len; i++) {
                GsFlatpak *flatpak = g_ptr_array_index (priv->flatpaks, i);
-               if (_as_app_scope_is_compatible (gs_flatpak_get_scope (flatpak),
+               if (_as_component_scope_is_compatible (gs_flatpak_get_scope (flatpak),
                                                 gs_app_get_scope (app)))
                        return flatpak;
        }
@@ -286,7 +286,7 @@ gs_plugin_flatpak_refine_app (GsPlugin *plugin,
        }
 
        /* we have to look for the app in all GsFlatpak stores */
-       if (gs_app_get_scope (app) == AS_APP_SCOPE_UNKNOWN) {
+       if (gs_app_get_scope (app) == AS_COMPONENT_SCOPE_UNKNOWN) {
                for (guint i = 0; i < priv->flatpaks->len; i++) {
                        GsFlatpak *flatpak_tmp = g_ptr_array_index (priv->flatpaks, i);
                        g_autoptr(GError) error_local = NULL;
@@ -733,7 +733,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                return TRUE;
 
        /* is a source */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return gs_flatpak_app_remove_source (flatpak, app, cancellable, error);
 
        /* build and run transaction */
@@ -809,19 +809,19 @@ gs_plugin_app_install (GsPlugin *plugin,
        }
 
        /* set the app scope */
-       if (gs_app_get_scope (app) == AS_APP_SCOPE_UNKNOWN) {
+       if (gs_app_get_scope (app) == AS_COMPONENT_SCOPE_UNKNOWN) {
                g_autoptr(GSettings) settings = g_settings_new ("org.gnome.software");
 
                /* get the new GsFlatpak for handling of local files */
                gs_app_set_scope (app, g_settings_get_boolean (settings, "install-bundles-system-wide") ?
-                                       AS_APP_SCOPE_SYSTEM : AS_APP_SCOPE_USER);
+                                       AS_COMPONENT_SCOPE_SYSTEM : AS_COMPONENT_SCOPE_USER);
                if (!priv->has_system_helper) {
                        g_info ("no flatpak system helper is available, using user");
-                       gs_app_set_scope (app, AS_APP_SCOPE_USER);
+                       gs_app_set_scope (app, AS_COMPONENT_SCOPE_USER);
                }
                if (priv->destdir_for_tests != NULL) {
                        g_debug ("in self tests, using user");
-                       gs_app_set_scope (app, AS_APP_SCOPE_USER);
+                       gs_app_set_scope (app, AS_COMPONENT_SCOPE_USER);
                }
        }
 
@@ -831,7 +831,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                return TRUE;
 
        /* is a source */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return gs_flatpak_app_install_source (flatpak, app, cancellable, error);
 
        if (!gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_INTERACTIVE)) {
@@ -1148,7 +1148,7 @@ gs_plugin_flatpak_file_to_app_bundle (GsPlugin *plugin,
                return g_steal_pointer (&app_tmp);
 
        /* force this to be 'any' scope for installation */
-       gs_app_set_scope (app, AS_APP_SCOPE_UNKNOWN);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_UNKNOWN);
 
        /* this is new */
        return g_steal_pointer (&app);
@@ -1183,7 +1183,7 @@ gs_plugin_flatpak_file_to_app_ref (GsPlugin *plugin,
                return g_steal_pointer (&app_tmp);
 
        /* force this to be 'any' scope for installation */
-       gs_app_set_scope (app, AS_APP_SCOPE_UNKNOWN);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_UNKNOWN);
 
        /* do we have a system runtime available */
        runtime = gs_app_get_runtime (app);
diff --git a/plugins/flatpak/gs-self-test.c b/plugins/flatpak/gs-self-test.c
index f07dc65fd..99e879dc0 100644
--- a/plugins/flatpak/gs-self-test.c
+++ b/plugins/flatpak/gs-self-test.c
@@ -139,7 +139,7 @@ gs_plugins_flatpak_repo_func (GsPluginLoader *plugin_loader)
        gs_test_flush_main_context ();
        g_assert_no_error (error);
        g_assert_true (app != NULL);
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_SOURCE);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_REPOSITORY);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE_LOCAL);
        g_assert_cmpstr (gs_app_get_id (app), ==, "example");
        g_assert_cmpstr (gs_app_get_management_plugin (app), ==, "flatpak");
@@ -278,7 +278,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        if (testdir == NULL)
                return;
        testdir_repourl = g_strdup_printf ("file://%s/repo", testdir);
-       gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app_source, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_management_plugin (app_source, "flatpak");
        gs_app_set_state (app_source, GS_APP_STATE_AVAILABLE);
        gs_flatpak_app_set_repo_url (app_source, testdir_repourl);
@@ -308,7 +308,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (sources), ==, 1);
        app = gs_app_list_index (sources, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "test");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_SOURCE);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_REPOSITORY);
 
        /* refresh the appstream metadata */
        g_object_unref (plugin_job);
@@ -349,7 +349,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.test.Chiron");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE);
        g_assert_cmpint ((gint64) gs_app_get_kudos (app), ==,
                         GS_APP_KUDO_MY_LANGUAGE |
@@ -542,7 +542,7 @@ gs_plugins_flatpak_app_missing_runtime_func (GsPluginLoader *plugin_loader)
        if (testdir == NULL)
                return;
        testdir_repourl = g_strdup_printf ("file://%s/repo", testdir);
-       gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app_source, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_management_plugin (app_source, "flatpak");
        gs_app_set_state (app_source, GS_APP_STATE_AVAILABLE);
        gs_flatpak_app_set_repo_url (app_source, testdir_repourl);
@@ -700,10 +700,10 @@ gs_plugins_flatpak_runtime_repo_func (GsPluginLoader *plugin_loader)
        gs_test_flush_main_context ();
        g_assert_no_error (error);
        g_assert_true (app != NULL);
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE_LOCAL);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.test.Chiron");
-       g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+       g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                        "user/flatpak/*/desktop/org.test.Chiron/master"));
        g_assert_true (gs_app_get_local_file (app) != NULL);
 
@@ -825,7 +825,7 @@ gs_plugins_flatpak_runtime_repo_redundant_func (GsPluginLoader *plugin_loader)
        gs_test_flush_main_context ();
        g_assert_no_error (error);
        g_assert_true (app_src != NULL);
-       g_assert_cmpint (gs_app_get_kind (app_src), ==, AS_APP_KIND_SOURCE);
+       g_assert_cmpint (gs_app_get_kind (app_src), ==, AS_COMPONENT_KIND_REPOSITORY);
        g_assert_cmpint (gs_app_get_state (app_src), ==, GS_APP_STATE_AVAILABLE_LOCAL);
        g_assert_cmpstr (gs_app_get_id (app_src), ==, "test");
        g_assert_cmpstr (gs_app_get_unique_id (app_src), ==, "*/*/*/source/test/master");
@@ -863,10 +863,10 @@ gs_plugins_flatpak_runtime_repo_redundant_func (GsPluginLoader *plugin_loader)
        gs_test_flush_main_context ();
        g_assert_no_error (error);
        g_assert_true (app != NULL);
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE_LOCAL);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.test.Chiron");
-       g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+       g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                        "user/flatpak/*/desktop/org.test.Chiron/master"));
        g_assert_true (gs_app_get_local_file (app) != NULL);
 
@@ -971,7 +971,7 @@ gs_plugins_flatpak_broken_remote_func (GsPluginLoader *plugin_loader)
        testdir = gs_test_get_filename (TESTDATADIR, "only-runtime");
        if (testdir == NULL)
                return;
-       gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app_source, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_management_plugin (app_source, "flatpak");
        gs_app_set_state (app_source, GS_APP_STATE_AVAILABLE);
        gs_flatpak_app_set_repo_url (app_source, "file:///wont/work");
@@ -1008,14 +1008,14 @@ gs_plugins_flatpak_broken_remote_func (GsPluginLoader *plugin_loader)
        app = gs_plugin_loader_job_process_app (plugin_loader, plugin_job, NULL, &error);
        g_assert_no_error (error);
        g_assert_true (app != NULL);
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE_LOCAL);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.test.Chiron");
 #if FLATPAK_CHECK_VERSION(1,1,2)
-       g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+       g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                        "user/flatpak/chiron-origin/desktop/org.test.Chiron/master"));
 #else
-       g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+       g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                        "user/flatpak/org.test.Chiron-origin/desktop/org.test.Chiron/master"));
 #endif
        g_assert_cmpstr (gs_app_get_url (app, AS_URL_KIND_HOMEPAGE), ==, "http://127.0.0.1/";);
@@ -1071,7 +1071,7 @@ flatpak_bundle_or_ref_helper (GsPluginLoader *plugin_loader,
        if (testdir == NULL)
                return;
        testdir_repourl = g_strdup_printf ("file://%s/repo", testdir);
-       gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app_source, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_management_plugin (app_source, "flatpak");
        gs_app_set_state (app_source, GS_APP_STATE_AVAILABLE);
        gs_flatpak_app_set_repo_url (app_source, testdir_repourl);
@@ -1164,7 +1164,7 @@ flatpak_bundle_or_ref_helper (GsPluginLoader *plugin_loader,
        app = gs_plugin_loader_job_process_app (plugin_loader, plugin_job, NULL, &error);
        g_assert_no_error (error);
        g_assert_true (app != NULL);
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DESKTOP_APP);
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE_LOCAL);
        g_assert_cmpstr (gs_app_get_id (app), ==, "org.test.Chiron");
        g_assert_cmpstr (gs_app_get_name (app), ==, "Chiron");
@@ -1175,15 +1175,15 @@ flatpak_bundle_or_ref_helper (GsPluginLoader *plugin_loader,
                /* Note: The origin is set to "flatpak" here because an origin remote
                 * won't be created until the app is installed.
                 */
-               g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+               g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                                "user/flatpak/flatpak/desktop/org.test.Chiron/master"));
                g_assert_true (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_BUNDLE);
        } else {
 #if FLATPAK_CHECK_VERSION(1,1,2)
-               g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+               g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                                "user/flatpak/chiron-origin/desktop/org.test.Chiron/master"));
 #else
-               g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app),
+               g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app),
                                "user/flatpak/org.test.Chiron-origin/desktop/org.test.Chiron/master"));
 #endif
                g_assert_true (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_REF);
@@ -1236,17 +1236,17 @@ flatpak_bundle_or_ref_helper (GsPluginLoader *plugin_loader,
        g_assert_cmpint (gs_app_get_state (app2), ==, GS_APP_STATE_INSTALLED);
        if (is_bundle) {
 #if FLATPAK_CHECK_VERSION(1,1,2)
-               g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app2),
+               g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app2),
                                "user/flatpak/chiron-origin/desktop/org.test.Chiron/master"));
 #else
-               g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app2),
+               g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app2),
                                "user/flatpak/org.test.Chiron-origin/desktop/org.test.Chiron/master"));
 #endif
        } else {
                /* Note: the origin is now test-1 because that remote was created from the
                 * RuntimeRepo= setting
                 */
-               g_assert_true (as_utils_unique_id_equal (gs_app_get_unique_id (app2),
+               g_assert_true (as_utils_data_id_equal (gs_app_get_unique_id (app2),
                          "user/flatpak/test-1/desktop/org.test.Chiron/master"));
        }
 
@@ -1280,7 +1280,7 @@ flatpak_bundle_or_ref_helper (GsPluginLoader *plugin_loader,
        if (!is_bundle) {
                /* remove remote added by RuntimeRepo= in flatpakref */
                g_autoptr(GsApp) runtime_source = gs_flatpak_app_new ("test-1");
-               gs_app_set_kind (runtime_source, AS_APP_KIND_SOURCE);
+               gs_app_set_kind (runtime_source, AS_COMPONENT_KIND_REPOSITORY);
                gs_app_set_management_plugin (runtime_source, "flatpak");
                gs_app_set_state (runtime_source, GS_APP_STATE_INSTALLED);
                g_object_unref (plugin_job);
@@ -1388,7 +1388,7 @@ gs_plugins_flatpak_app_update_func (GsPluginLoader *plugin_loader)
 
        /* add a remote */
        app_source = gs_flatpak_app_new ("test");
-       gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app_source, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_management_plugin (app_source, "flatpak");
        gs_app_set_state (app_source, GS_APP_STATE_AVAILABLE);
        repo_url = g_strdup_printf ("file://%s", repo_path);
@@ -1638,7 +1638,7 @@ gs_plugins_flatpak_runtime_extension_func (GsPluginLoader *plugin_loader)
 
        /* add a remote */
        app_source = gs_flatpak_app_new ("test");
-       gs_app_set_kind (app_source, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (app_source, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_management_plugin (app_source, "flatpak");
        gs_app_set_state (app_source, GS_APP_STATE_AVAILABLE);
        repo_url = g_strdup_printf ("file://%s", repo_path);
diff --git a/plugins/fwupd/gs-fwupd-app.c b/plugins/fwupd/gs-fwupd-app.c
index 670f580bb..f95dff7f2 100644
--- a/plugins/fwupd/gs-fwupd-app.c
+++ b/plugins/fwupd/gs-fwupd-app.c
@@ -108,8 +108,7 @@ gs_fwupd_app_set_from_device (GsApp *app, FwupdDevice *dev)
                gs_app_set_install_date (app, fwupd_device_get_created (dev));
        if (fwupd_device_get_description (dev) != NULL) {
                g_autofree gchar *tmp = NULL;
-               tmp = as_markup_convert (fwupd_device_get_description (dev),
-                                        AS_MARKUP_CONVERT_FORMAT_SIMPLE, NULL);
+               tmp = as_markup_convert_simple (fwupd_device_get_description (dev), NULL);
                if (tmp != NULL)
                        gs_app_set_description (app, GS_APP_QUALITY_NORMAL, tmp);
        }
@@ -221,8 +220,7 @@ gs_fwupd_app_set_from_release (GsApp *app, FwupdRelease *rel)
        }
        if (fwupd_release_get_description (rel) != NULL) {
                g_autofree gchar *tmp = NULL;
-               tmp = as_markup_convert (fwupd_release_get_description (rel),
-                                        AS_MARKUP_CONVERT_FORMAT_SIMPLE, NULL);
+               tmp = as_markup_convert_simple (fwupd_release_get_description (rel), NULL);
                if (tmp != NULL)
                        gs_app_set_update_details (app, tmp);
        }
diff --git a/plugins/fwupd/gs-plugin-fwupd.c b/plugins/fwupd/gs-plugin-fwupd.c
index 3b2fc3875..8fd1f4f30 100644
--- a/plugins/fwupd/gs-plugin-fwupd.c
+++ b/plugins/fwupd/gs-plugin-fwupd.c
@@ -112,7 +112,7 @@ gs_plugin_destroy (GsPlugin *plugin)
 void
 gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
 {
-       if (gs_app_get_kind (app) == AS_APP_KIND_FIRMWARE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_FIRMWARE)
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
 }
 
@@ -246,7 +246,7 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
 
        /* add source */
        priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin));
-       gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (priv->cached_origin, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_bundle_kind (priv->cached_origin, AS_BUNDLE_KIND_CABINET);
 
        /* add the source to the plugin cache which allows us to match the
@@ -285,12 +285,11 @@ gs_plugin_fwupd_new_app_from_device (GsPlugin *plugin, FwupdDevice *dev)
                return NULL;
 
        /* get from cache */
-       id = as_utils_unique_id_build (AS_APP_SCOPE_SYSTEM,
-                                      AS_BUNDLE_KIND_UNKNOWN,
-                                      NULL, /* origin */
-                                      AS_APP_KIND_FIRMWARE,
-                                      fwupd_release_get_appstream_id (rel),
-                                      NULL);
+       id = as_utils_build_data_id (AS_COMPONENT_SCOPE_SYSTEM,
+                                    AS_BUNDLE_KIND_UNKNOWN,
+                                    NULL, /* origin */
+                                    fwupd_release_get_appstream_id (rel),
+                                    NULL);
        app = gs_plugin_cache_lookup (plugin, id);
        if (app == NULL) {
                app = gs_app_new (id);
@@ -298,7 +297,7 @@ gs_plugin_fwupd_new_app_from_device (GsPlugin *plugin, FwupdDevice *dev)
        }
 
        /* default stuff */
-       gs_app_set_kind (app, AS_APP_KIND_FIRMWARE);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_FIRMWARE);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_CABINET);
        gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
        gs_app_add_quirk (app, GS_APP_QUIRK_DO_NOT_AUTO_UPDATE);
@@ -344,8 +343,8 @@ gs_plugin_fwupd_new_app_from_device_raw (GsPlugin *plugin, FwupdDevice *device)
        /* create a GsApp based on the device, not the release */
        id = gs_plugin_fwupd_build_device_id (device);
        app = gs_app_new (id);
-       gs_app_set_kind (app, AS_APP_KIND_FIRMWARE);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_FIRMWARE);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_set_state (app, GS_APP_STATE_INSTALLED);
        gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
        gs_app_add_quirk (app, GS_APP_QUIRK_DO_NOT_AUTO_UPDATE);
@@ -616,9 +615,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
                                g_autofree gchar *desc = NULL;
                                if (fwupd_release_get_description (rel) == NULL)
                                        continue;
-                               desc = as_markup_convert (fwupd_release_get_description (rel),
-                                                         AS_MARKUP_CONVERT_FORMAT_SIMPLE,
-                                                         NULL);
+                               desc = as_markup_convert_simple (fwupd_release_get_description (rel), NULL);
                                if (desc == NULL)
                                        continue;
                                g_string_append_printf (update_desc,
@@ -962,7 +959,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                return TRUE;
 
        /* source -> remote */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY) {
                return gs_plugin_fwupd_modify_source (plugin, app, TRUE,
                                                      cancellable, error);
        }
@@ -1161,8 +1158,8 @@ gs_plugin_add_sources (GsPlugin *plugin,
                /* create something that we can use to enable/disable */
                id = g_strdup_printf ("org.fwupd.%s.remote", fwupd_remote_get_id (remote));
                app = gs_app_new (id);
-               gs_app_set_kind (app, AS_APP_KIND_SOURCE);
-               gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_REPOSITORY);
+               gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
                gs_app_set_state (app, fwupd_remote_get_enabled (remote) ?
                                  GS_APP_STATE_INSTALLED : GS_APP_STATE_AVAILABLE);
                gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
diff --git a/plugins/fwupd/gs-self-test.c b/plugins/fwupd/gs-self-test.c
index ffd308493..2c0bf10b2 100644
--- a/plugins/fwupd/gs-self-test.c
+++ b/plugins/fwupd/gs-self-test.c
@@ -38,7 +38,7 @@ gs_plugins_fwupd_func (GsPluginLoader *plugin_loader)
        gs_test_flush_main_context ();
        g_assert_no_error (error);
        g_assert (app != NULL);
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_FIRMWARE);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_FIRMWARE);
        g_assert (gs_app_get_license (app) != NULL);
        g_assert (gs_app_has_category (app, "System"));
        g_assert_cmpstr (gs_app_get_id (app), ==, "com.test.chiron.firmware");
diff --git a/plugins/malcontent/gs-plugin-malcontent.c b/plugins/malcontent/gs-plugin-malcontent.c
index d474168c0..9972a6911 100644
--- a/plugins/malcontent/gs-plugin-malcontent.c
+++ b/plugins/malcontent/gs-plugin-malcontent.c
@@ -62,24 +62,24 @@ app_is_expected_to_have_content_rating (GsApp *app)
                return FALSE;
 
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_ADDON:
-       case AS_APP_KIND_CODEC:
-       case AS_APP_KIND_DRIVER:
-       case AS_APP_KIND_FIRMWARE:
-       case AS_APP_KIND_FONT:
-       case AS_APP_KIND_GENERIC:
-       case AS_APP_KIND_INPUT_METHOD:
-       case AS_APP_KIND_LOCALIZATION:
-       case AS_APP_KIND_OS_UPDATE:
-       case AS_APP_KIND_OS_UPGRADE:
-       case AS_APP_KIND_RUNTIME:
-       case AS_APP_KIND_SOURCE:
+       case AS_COMPONENT_KIND_ADDON:
+       case AS_COMPONENT_KIND_CODEC:
+       case AS_COMPONENT_KIND_DRIVER:
+       case AS_COMPONENT_KIND_FIRMWARE:
+       case AS_COMPONENT_KIND_FONT:
+       case AS_COMPONENT_KIND_GENERIC:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_LOCALIZATION:
+       case AS_COMPONENT_KIND_OS_UPDATE:
+       case AS_COMPONENT_KIND_OPERATING_SYSTEM:
+       case AS_COMPONENT_KIND_RUNTIME:
+       case AS_COMPONENT_KIND_REPOSITORY:
                return FALSE;
-       case AS_APP_KIND_UNKNOWN:
-       case AS_APP_KIND_DESKTOP:
-       case AS_APP_KIND_WEB_APP:
-       case AS_APP_KIND_SHELL_EXTENSION:
-       case AS_APP_KIND_CONSOLE:
+       case AS_COMPONENT_KIND_UNKNOWN:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
+       case AS_COMPONENT_KIND_WEB_APP:
+       case AS_COMPONENT_KIND_SHELL_EXTENSION:
+       case AS_COMPONENT_KIND_CONSOLE_APP:
        default:
                break;
        }
@@ -340,4 +340,4 @@ gs_plugin_destroy (GsPlugin *plugin)
                priv->manager_app_filter_changed_id = 0;
        }
        g_clear_object (&priv->manager);
-}
\ No newline at end of file
+}
diff --git a/plugins/modalias/gs-plugin-modalias.c b/plugins/modalias/gs-plugin-modalias.c
index d4e27a24f..288ea96f3 100644
--- a/plugins/modalias/gs-plugin-modalias.c
+++ b/plugins/modalias/gs-plugin-modalias.c
@@ -106,29 +106,33 @@ refine_app (GsPlugin             *plugin,
            GCancellable         *cancellable,
            GError              **error)
 {
-       GPtrArray *provides;
+       GPtrArray *provided;
        guint i;
 
        /* not required */
        if (gs_app_get_icons(app)->len > 0)
                return TRUE;
-       if (gs_app_get_kind (app) != AS_APP_KIND_DRIVER)
+       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_DRIVER)
                return TRUE;
 
        /* do any of the modaliases match any installed hardware */
-       provides = gs_app_get_provides (app);
-       for (i = 0 ; i < provides->len; i++) {
-               AsProvide *prov = g_ptr_array_index (provides, i);
-               if (as_provide_get_kind (prov) != AS_PROVIDE_KIND_MODALIAS)
+       provided = gs_app_get_provided (app);
+       for (i = 0 ; i < provided->len; i++) {
+               GPtrArray *items;
+               AsProvided *prov = g_ptr_array_index (provided, i);
+               if (as_provided_get_kind (prov) != AS_PROVIDED_KIND_MODALIAS)
                        continue;
-               if (gs_plugin_modalias_matches (plugin, as_provide_get_value (prov))) {
-                       g_autoptr(AsIcon) ic = NULL;
-                       ic = as_icon_new ();
-                       as_icon_set_kind (ic, AS_ICON_KIND_STOCK);
-                       as_icon_set_name (ic, "emblem-system-symbolic");
-                       gs_app_add_icon (app, ic);
-                       gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
-                       break;
+               items = as_provided_get_items (prov);
+               for (guint j = 0; j < items->len; j++) {
+                       if (gs_plugin_modalias_matches (plugin, (const gchar*) g_ptr_array_index (items, j))) 
{
+                               g_autoptr(AsIcon) ic = NULL;
+                               ic = as_icon_new ();
+                               as_icon_set_kind (ic, AS_ICON_KIND_STOCK);
+                               as_icon_set_name (ic, "emblem-system-symbolic");
+                               gs_app_add_icon (app, ic);
+                               gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
+                               break;
+                       }
                }
        }
        return TRUE;
diff --git a/plugins/modalias/gs-self-test.c b/plugins/modalias/gs-self-test.c
index 5cbb39c34..92bf88f00 100644
--- a/plugins/modalias/gs-self-test.c
+++ b/plugins/modalias/gs-self-test.c
@@ -34,7 +34,7 @@ gs_plugins_modalias_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_list_length (list), ==, 1);
        app = gs_app_list_index (list, 0);
        g_assert_cmpstr (gs_app_get_id (app), ==, "com.hughski.ColorHug2.driver");
-       g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DRIVER);
+       g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_DRIVER);
        g_assert (gs_app_has_category (app, "Addon"));
        g_assert (gs_app_has_category (app, "Driver"));
 }
diff --git a/plugins/odrs/gs-plugin-odrs.c b/plugins/odrs/gs-plugin-odrs.c
index 65e250734..2f92d5a5b 100644
--- a/plugins/odrs/gs-plugin-odrs.c
+++ b/plugins/odrs/gs-plugin-odrs.c
@@ -159,7 +159,7 @@ gs_plugin_initialize (GsPlugin *plugin)
 
        /* add source */
        priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin));
-       gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE);
+       gs_app_set_kind (priv->cached_origin, AS_COMPONENT_KIND_REPOSITORY);
        gs_app_set_origin_hostname (priv->cached_origin, priv->review_server);
 
        /* add the source to the plugin cache which allows us to match the
@@ -595,17 +595,24 @@ static GPtrArray *
 _gs_app_get_reviewable_ids (GsApp *app)
 {
        GPtrArray *ids = g_ptr_array_new_with_free_func (g_free);
-       GPtrArray *provides = gs_app_get_provides (app);
+       GPtrArray *provided = gs_app_get_provided (app);
 
        /* add the main component id */
        g_ptr_array_add (ids, g_strdup (gs_app_get_id (app)));
 
        /* add any ID provides */
-       for (guint i = 0; i < provides->len; i++) {
-               AsProvide *provide = g_ptr_array_index (provides, i);
-               if (as_provide_get_kind (provide) == AS_PROVIDE_KIND_ID &&
-                   as_provide_get_value (provide) != NULL) {
-                       g_ptr_array_add (ids, g_strdup (as_provide_get_value (provide)));
+       for (guint i = 0; i < provided->len; i++) {
+               GPtrArray *items;
+               AsProvided *prov = g_ptr_array_index (provided, i);
+               if (as_provided_get_kind (prov) != AS_PROVIDED_KIND_ID)
+                       continue;
+
+               items = as_provided_get_items (prov);
+               for (guint j = 0; j < items->len; j++) {
+                       const gchar *value = (const gchar *) g_ptr_array_index (items, j);
+                       if (value == NULL)
+                               continue;
+                       g_ptr_array_add (ids, g_strdup (value));
                }
        }
        return ids;
@@ -695,22 +702,30 @@ gs_plugin_odrs_refine_ratings (GsPlugin *plugin,
 static JsonNode *
 gs_plugin_odrs_get_compat_ids (GsApp *app)
 {
-       GPtrArray *provides = gs_app_get_provides (app);
+       GPtrArray *provided = gs_app_get_provided (app);
        g_autoptr(GHashTable) ids = NULL;
        g_autoptr(JsonArray) json_array = json_array_new ();
        g_autoptr(JsonNode) json_node = json_node_new (JSON_NODE_ARRAY);
 
        ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-       for (guint i = 0; i < provides->len; i++) {
-               AsProvide *provide = g_ptr_array_index (provides, i);
-               if (as_provide_get_kind (provide) != AS_PROVIDE_KIND_ID)
-                       continue;
-               if (as_provide_get_value (provide) == NULL)
-                       continue;
-               if (g_hash_table_lookup (ids, as_provide_get_value (provide)) != NULL)
+       for (guint i = 0; i < provided->len; i++) {
+               GPtrArray *items;
+               AsProvided *prov = g_ptr_array_index (provided, i);
+
+               if (as_provided_get_kind (prov) != AS_PROVIDED_KIND_ID)
                        continue;
-               g_hash_table_add (ids, g_strdup (as_provide_get_value (provide)));
-               json_array_add_string_element (json_array, as_provide_get_value (provide));
+
+               items = as_provided_get_items (prov);
+               for (guint j = 0; j < items->len; j++) {
+                       const gchar *value = g_ptr_array_index (items, j);
+                       if (value == NULL)
+                               continue;
+
+                       if (g_hash_table_lookup (ids, value) != NULL)
+                               continue;
+                       g_hash_table_add (ids, g_strdup (value));
+                       json_array_add_string_element (json_array, value);
+               }
        }
        if (json_array_get_length (json_array) == 0)
                return NULL;
@@ -879,7 +894,7 @@ refine_app (GsPlugin             *plugin,
            GError              **error)
 {
        /* not valid */
-       if (gs_app_get_kind (app) == AS_APP_KIND_ADDON)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_ADDON)
                return TRUE;
        if (gs_app_get_id (app) == NULL)
                return TRUE;
@@ -1172,7 +1187,7 @@ gs_plugin_create_app_dummy (const gchar *id)
        GsApp *app = gs_app_new (id);
        g_autoptr(GString) str = NULL;
        str = g_string_new (id);
-       as_utils_string_replace (str, ".desktop", "");
+       as_gstring_replace (str, ".desktop", "");
        g_string_prepend (str, "No description is available for ");
        gs_app_set_name (app, GS_APP_QUALITY_LOWEST, "Unknown Application");
        gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, "Application not found");
diff --git a/plugins/packagekit/gs-plugin-packagekit-history.c 
b/plugins/packagekit/gs-plugin-packagekit-history.c
index 3a8e32cbf..c244b196d 100644
--- a/plugins/packagekit/gs-plugin-packagekit-history.c
+++ b/plugins/packagekit/gs-plugin-packagekit-history.c
@@ -55,7 +55,7 @@ gs_plugin_packagekit_refine_add_history (GsApp *app, GVariant *dict)
 
        /* create new history item with same ID as parent */
        history = gs_app_new (gs_app_get_id (app));
-       gs_app_set_kind (history, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (history, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_name (history, GS_APP_QUALITY_NORMAL, gs_app_get_name (app));
 
@@ -201,7 +201,7 @@ gs_plugin_packagekit_refine (GsPlugin *plugin,
                                gs_app_set_metadata (app_dummy, "GnomeSoftware::Creator",
                                                     gs_plugin_get_name (plugin));
                                gs_app_set_install_date (app_dummy, GS_APP_INSTALL_DATE_UNKNOWN);
-                               gs_app_set_kind (app_dummy, AS_APP_KIND_GENERIC);
+                               gs_app_set_kind (app_dummy, AS_COMPONENT_KIND_GENERIC);
                                gs_app_set_state (app_dummy, GS_APP_STATE_INSTALLED);
                                gs_app_set_version (app_dummy, gs_app_get_version (app));
                                gs_app_add_history (app, app_dummy);
diff --git a/plugins/packagekit/gs-plugin-packagekit-local.c b/plugins/packagekit/gs-plugin-packagekit-local.c
index dec1c89a9..5d3da3175 100644
--- a/plugins/packagekit/gs-plugin-packagekit-local.c
+++ b/plugins/packagekit/gs-plugin-packagekit-local.c
@@ -97,7 +97,7 @@ gs_plugin_packagekit_refresh_guess_app_id (GsPlugin *plugin,
                }
        }
        if (basename_best->len > 0) {
-               gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
                gs_app_set_id (app, basename_best->str);
        }
 
@@ -233,7 +233,7 @@ gs_plugin_file_to_app (GsPlugin *plugin,
                return FALSE;
        }
        gs_app_set_management_plugin (app, "packagekit");
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE_LOCAL);
        gs_app_set_name (app, GS_APP_QUALITY_LOWEST, split[PK_PACKAGE_ID_NAME]);
@@ -247,7 +247,7 @@ gs_plugin_file_to_app (GsPlugin *plugin,
        gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, pk_details_get_url (item));
        gs_app_set_size_installed (app, pk_details_get_size (item));
        gs_app_set_size_download (app, 0);
-       license_spdx = as_utils_license_to_spdx (pk_details_get_license (item));
+       license_spdx = as_license_to_spdx_id (pk_details_get_license (item));
        gs_app_set_license (app, GS_APP_QUALITY_LOWEST, license_spdx);
        add_quirks_from_package_name (app, split[PK_PACKAGE_ID_NAME]);
 
diff --git a/plugins/packagekit/gs-plugin-packagekit-offline.c 
b/plugins/packagekit/gs-plugin-packagekit-offline.c
index b9fda86d3..7d70796af 100644
--- a/plugins/packagekit/gs-plugin-packagekit-offline.c
+++ b/plugins/packagekit/gs-plugin-packagekit-offline.c
@@ -143,7 +143,7 @@ gs_plugin_add_updates_historical (GsPlugin *plugin,
                gs_app_set_management_plugin (app, "packagekit");
                gs_app_add_quirk (app, GS_APP_QUIRK_IS_WILDCARD);
                gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
-               gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_OPERATING_SYSTEM);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
                gs_app_set_install_date (app, mtime);
                gs_app_set_metadata (app, "GnomeSoftware::Creator",
@@ -170,7 +170,7 @@ gs_plugin_add_updates_historical (GsPlugin *plugin,
                gs_app_set_management_plugin (app, "packagekit");
                gs_app_add_source_id (app, package_id);
                gs_app_set_state (app, GS_APP_STATE_UPDATABLE);
-               gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
                gs_app_set_install_date (app, mtime);
                gs_app_set_metadata (app, "GnomeSoftware::Creator",
diff --git a/plugins/packagekit/gs-plugin-packagekit-refine-repos.c 
b/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
index 4b41c446d..39c262c8a 100644
--- a/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
+++ b/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
@@ -102,7 +102,7 @@ gs_plugin_refine (GsPlugin *plugin,
                const gchar *fn;
                if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD))
                        continue;
-               if (gs_app_get_kind (app) != AS_APP_KIND_SOURCE)
+               if (gs_app_get_kind (app) != AS_COMPONENT_KIND_REPOSITORY)
                        continue;
                if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0)
                        continue;
diff --git a/plugins/packagekit/gs-plugin-packagekit-refine.c 
b/plugins/packagekit/gs-plugin-packagekit-refine.c
index 5e09c5d0c..b2f14df06 100644
--- a/plugins/packagekit/gs-plugin-packagekit-refine.c
+++ b/plugins/packagekit/gs-plugin-packagekit-refine.c
@@ -76,7 +76,7 @@ void
 gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
 {
        if (gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE &&
-           gs_app_get_scope (app) == AS_APP_SCOPE_SYSTEM) {
+           gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM) {
                gs_app_set_management_plugin (app, "packagekit");
                gs_plugin_packagekit_set_packaging_format (plugin, app);
                return;
@@ -698,10 +698,10 @@ gs_plugin_packagekit_refine_filename_to_id (GsPlugin *plugin,
                if (tmp == NULL)
                        continue;
                switch (gs_app_get_kind (app)) {
-               case AS_APP_KIND_DESKTOP:
+               case AS_COMPONENT_KIND_DESKTOP_APP:
                        fn = g_strdup_printf ("/usr/share/applications/%s", tmp);
                        break;
-               case AS_APP_KIND_ADDON:
+               case AS_COMPONENT_KIND_ADDON:
                        fn = g_strdup_printf ("/usr/share/metainfo/%s.metainfo.xml", tmp);
                        if (!g_file_test (fn, G_FILE_TEST_EXISTS)) {
                                g_free (fn);
@@ -773,7 +773,7 @@ gs_plugin_refine (GsPlugin *plugin,
        if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_UPGRADE_REMOVED) {
                for (guint i = 0; i < gs_app_list_length (list); i++) {
                        GsApp *app = gs_app_list_index (list, i);
-                       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE)
+                       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                                continue;
                        if (!gs_plugin_packagekit_refine_distro_upgrade (plugin,
                                                                         app,
@@ -811,8 +811,8 @@ gs_plugin_refine (GsPlugin *plugin,
                        continue;
 
                /* the scope is always system-wide */
-               if (gs_app_get_scope (app) == AS_APP_SCOPE_UNKNOWN)
-                       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+               if (gs_app_get_scope (app) == AS_COMPONENT_SCOPE_UNKNOWN)
+                       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
                if (gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_UNKNOWN)
                        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        }
diff --git a/plugins/packagekit/gs-plugin-packagekit-upgrade.c 
b/plugins/packagekit/gs-plugin-packagekit-upgrade.c
index 012f7d4a3..c09af98c0 100644
--- a/plugins/packagekit/gs-plugin-packagekit-upgrade.c
+++ b/plugins/packagekit/gs-plugin-packagekit-upgrade.c
@@ -44,7 +44,7 @@ gs_plugin_destroy (GsPlugin *plugin)
 void
 gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
 {
-       if (gs_app_get_kind (app) == AS_APP_KIND_OS_UPGRADE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_OPERATING_SYSTEM)
                gs_app_set_management_plugin (app, "packagekit");
 }
 
@@ -63,7 +63,7 @@ gs_plugin_app_upgrade_download (GsPlugin *plugin,
                return TRUE;
 
        /* check is distro-upgrade */
-       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE)
+       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
 
        /* ask PK to download enough packages to upgrade the system */
diff --git a/plugins/packagekit/gs-plugin-packagekit-url-to-app.c 
b/plugins/packagekit/gs-plugin-packagekit-url-to-app.c
index 041892048..e3d52d607 100644
--- a/plugins/packagekit/gs-plugin-packagekit-url-to-app.c
+++ b/plugins/packagekit/gs-plugin-packagekit-url-to-app.c
@@ -81,7 +81,7 @@ gs_plugin_url_to_app (GsPlugin *plugin,
        app = gs_app_new (NULL);
        gs_plugin_packagekit_set_packaging_format (plugin, app);
        gs_app_add_source (app, path);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
 
        package_ids = g_new0 (gchar *, 2);
diff --git a/plugins/packagekit/gs-plugin-packagekit.c b/plugins/packagekit/gs-plugin-packagekit.c
index 7f158ed25..afe5da2ec 100644
--- a/plugins/packagekit/gs-plugin-packagekit.c
+++ b/plugins/packagekit/gs-plugin-packagekit.c
@@ -151,7 +151,7 @@ gs_plugin_add_sources (GsPlugin *plugin,
                id = pk_repo_detail_get_id (rd);
                app = gs_app_new (id);
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
-               gs_app_set_kind (app, AS_APP_KIND_SOURCE);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_REPOSITORY);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
                gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
                gs_app_set_state (app, pk_repo_detail_get_enabled (rd) ?
@@ -286,7 +286,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                return TRUE;
 
        /* enable repo */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return gs_plugin_repo_enable (plugin, app, cancellable, error);
 
        /* queue for install if installation needs the network */
@@ -524,7 +524,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                return TRUE;
 
        /* disable repo */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return gs_plugin_repo_disable (plugin, app, cancellable, error);
 
        /* get the list of available package ids to install */
@@ -594,8 +594,8 @@ gs_plugin_packagekit_build_update_app (GsPlugin *plugin, PkPackage *package)
                             gs_plugin_get_name (plugin));
        gs_app_set_management_plugin (app, "packagekit");
        gs_app_set_update_version (app, pk_package_get_version (package));
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
        gs_app_set_state (app, GS_APP_STATE_UPDATABLE);
        gs_plugin_cache_add (plugin, pk_package_get_id (package), app);
diff --git a/plugins/packagekit/packagekit-common.c b/plugins/packagekit/packagekit-common.c
index d55a610c1..8fd2cc4c5 100644
--- a/plugins/packagekit/packagekit-common.c
+++ b/plugins/packagekit/packagekit-common.c
@@ -280,7 +280,7 @@ gs_plugin_packagekit_add_results (GsPlugin *plugin,
                        g_warning ("unknown info state of %s",
                                   pk_info_enum_to_string (pk_package_get_info (package)));
                }
-               gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
                gs_app_list_add (list, app);
        }
@@ -491,7 +491,7 @@ gs_plugin_packagekit_refine_details_app (GsPlugin *plugin,
 
                if (gs_app_get_license (app) == NULL) {
                        g_autofree gchar *license_spdx = NULL;
-                       license_spdx = as_utils_license_to_spdx (pk_details_get_license (details));
+                       license_spdx = as_license_to_spdx_id (pk_details_get_license (details));
                        if (license_spdx != NULL) {
                                gs_app_set_license (app,
                                                    GS_APP_QUALITY_LOWEST,
diff --git a/plugins/repos/gs-plugin-repos.c b/plugins/repos/gs-plugin-repos.c
index a35fc800d..0a5f7e8b9 100644
--- a/plugins/repos/gs-plugin-repos.c
+++ b/plugins/repos/gs-plugin-repos.c
@@ -191,7 +191,7 @@ refine_app_locked (GsPlugin             *plugin,
 
        /* find hostname */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_SOURCE:
+       case AS_COMPONENT_KIND_REPOSITORY:
                if (gs_app_get_id (app) == NULL)
                        return TRUE;
                tmp = g_hash_table_lookup (priv->urls, gs_app_get_id (app));
@@ -209,7 +209,7 @@ refine_app_locked (GsPlugin             *plugin,
 
        /* find filename */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_SOURCE:
+       case AS_COMPONENT_KIND_REPOSITORY:
                if (gs_app_get_id (app) == NULL)
                        return TRUE;
                tmp = g_hash_table_lookup (priv->fns, gs_app_get_id (app));
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index 38c3d9906..c799cd77d 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -222,13 +222,13 @@ void
 gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
 {
        if (gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE &&
-           gs_app_get_scope (app) == AS_APP_SCOPE_SYSTEM) {
+           gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM) {
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
                gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
                app_set_rpm_ostree_packaging_format (app);
        }
 
-       if (gs_app_get_kind (app) == AS_APP_KIND_OS_UPGRADE) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_OPERATING_SYSTEM) {
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
                gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
        }
@@ -454,9 +454,9 @@ app_from_modified_pkg_variant (GsPlugin *plugin, GVariant *variant)
        gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
        app_set_rpm_ostree_packaging_format (app);
        gs_app_set_size_download (app, 0);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
 
        /* update or downgrade */
        gs_app_add_source (app, name);
@@ -493,9 +493,9 @@ app_from_single_pkg_variant (GsPlugin *plugin, GVariant *variant, gboolean addit
        gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
        app_set_rpm_ostree_packaging_format (app);
        gs_app_set_size_download (app, 0);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
 
        if (addition) {
                /* addition */
@@ -1011,7 +1011,7 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
                return TRUE;
 
        /* check is distro-upgrade */
-       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE)
+       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
 
        /* construct new refspec based on the distro version we're upgrading to */
@@ -1133,7 +1133,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                return TRUE;
 
        /* enable repo */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return gs_plugin_repo_enable (plugin, app, TRUE, cancellable, error);
 
        switch (gs_app_get_state (app)) {
@@ -1233,7 +1233,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                return TRUE;
 
        /* disable repo */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
                return gs_plugin_repo_enable (plugin, app, FALSE, cancellable, error);
 
        gs_app_set_state (app, GS_APP_STATE_REMOVING);
@@ -1370,9 +1370,9 @@ resolve_available_packages_app (GsPlugin *plugin,
                /* set hide-from-search quirk for available apps we don't want to show */
                if (!gs_app_is_installed (app)) {
                        switch (gs_app_get_kind (app)) {
-                       case AS_APP_KIND_DESKTOP:
-                       case AS_APP_KIND_WEB_APP:
-                       case AS_APP_KIND_CONSOLE:
+                       case AS_COMPONENT_KIND_DESKTOP_APP:
+                       case AS_COMPONENT_KIND_WEB_APP:
+                       case AS_COMPONENT_KIND_CONSOLE_APP:
                                gs_app_add_quirk (app, GS_APP_QUIRK_HIDE_FROM_SEARCH);
                                break;
                        default:
@@ -1491,7 +1491,7 @@ gs_plugin_refine (GsPlugin *plugin,
                /* set management plugin for apps where appstream just added the source package name in 
refine() */
                if (gs_app_get_management_plugin (app) == NULL &&
                    gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE &&
-                   gs_app_get_scope (app) == AS_APP_SCOPE_SYSTEM &&
+                   gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM &&
                    gs_app_get_source_default (app) != NULL) {
                        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
                        gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
@@ -1500,7 +1500,7 @@ gs_plugin_refine (GsPlugin *plugin,
                /* resolve the source package name based on installed appdata/desktop file name */
                if (gs_app_get_management_plugin (app) == NULL &&
                    gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_UNKNOWN &&
-                   gs_app_get_scope (app) == AS_APP_SCOPE_SYSTEM &&
+                   gs_app_get_scope (app) == AS_COMPONENT_SCOPE_SYSTEM &&
                    gs_app_get_source_default (app) == NULL) {
                        if (!resolve_appstream_source_file_to_package_name (plugin, app, flags, cancellable, 
error))
                                return FALSE;
@@ -1544,7 +1544,7 @@ gs_plugin_app_upgrade_download (GsPlugin *plugin,
                return TRUE;
 
        /* check is distro-upgrade */
-       if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE)
+       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
 
        /* construct new refspec based on the distro version we're upgrading to */
@@ -1611,7 +1611,7 @@ gs_plugin_launch (GsPlugin *plugin,
                return TRUE;
 
        /* these are handled by the shell extensions plugin */
-       if (gs_app_get_kind (app) == AS_APP_KIND_SHELL_EXTENSION)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_SHELL_EXTENSION)
                return TRUE;
 
        return gs_plugin_app_launch (plugin, app, error);
@@ -1694,9 +1694,9 @@ gs_plugin_file_to_app (GsPlugin *plugin,
        gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
        gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
        app_set_rpm_ostree_packaging_format (app);
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-       gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+       gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
        gs_app_set_state (app, GS_APP_STATE_AVAILABLE_LOCAL);
 
        /* add default source */
@@ -1726,7 +1726,7 @@ gs_plugin_file_to_app (GsPlugin *plugin,
        license = headerGetString (h, RPMTAG_LICENSE);
        if (license != NULL) {
                g_autofree gchar *license_spdx = NULL;
-               license_spdx = as_utils_license_to_spdx (license);
+               license_spdx = as_license_to_spdx_id (license);
                gs_app_set_license (app, GS_APP_QUALITY_NORMAL, license_spdx);
                g_debug ("rpm: setting license to %s", license_spdx);
        }
@@ -1797,9 +1797,9 @@ gs_plugin_add_search_what_provides (GsPlugin *plugin,
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
                gs_app_add_quirk (app, GS_APP_QUIRK_NEEDS_REBOOT);
                app_set_rpm_ostree_packaging_format (app);
-               gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
-               gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
+               gs_app_set_scope (app, AS_COMPONENT_SCOPE_SYSTEM);
                gs_app_add_source (app, dnf_package_get_name (pkg));
 
                gs_plugin_cache_add (plugin, dnf_package_get_nevra (pkg), app);
@@ -1840,7 +1840,7 @@ gs_plugin_add_sources (GsPlugin *plugin,
 
                app = gs_app_new (dnf_repo_get_id (repo));
                gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
-               gs_app_set_kind (app, AS_APP_KIND_SOURCE);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_REPOSITORY);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
                gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
 
diff --git a/plugins/snap/gs-plugin-snap.c b/plugins/snap/gs-plugin-snap.c
index b24ed8442..5a4718b5e 100644
--- a/plugins/snap/gs-plugin-snap.c
+++ b/plugins/snap/gs-plugin-snap.c
@@ -344,7 +344,7 @@ snap_to_app (GsPlugin *plugin, SnapdSnap *snap)
 
        gs_app_set_management_plugin (app, "snap");
        gs_app_add_quirk (app, GS_APP_QUIRK_DO_NOT_AUTO_UPDATE);
-       if (gs_app_get_kind (app) != AS_APP_KIND_DESKTOP)
+       if (gs_app_get_kind (app) != AS_COMPONENT_KIND_DESKTOP_APP)
                gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE);
        if (gs_plugin_check_distro_id (plugin, "ubuntu"))
                gs_app_add_quirk (app, GS_APP_QUIRK_PROVENANCE);
@@ -870,8 +870,8 @@ static gchar *
 gs_plugin_snap_get_description_safe (SnapdSnap *snap)
 {
        GString *str = g_string_new (snapd_snap_get_description (snap));
-       as_utils_string_replace (str, "\r", "");
-       as_utils_string_replace (str, "  ", " ");
+       as_gstring_replace (str, "\r", "");
+       as_gstring_replace (str, "  ", " ");
        return g_string_free (str, FALSE);
 }
 
@@ -1040,16 +1040,16 @@ refine_app_with_client (GsPlugin             *plugin,
 
        switch (snapd_snap_get_snap_type (snap)) {
        case SNAPD_SNAP_TYPE_APP:
-               gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_DESKTOP_APP);
                break;
        case SNAPD_SNAP_TYPE_KERNEL:
        case SNAPD_SNAP_TYPE_GADGET:
        case SNAPD_SNAP_TYPE_OS:
-               gs_app_set_kind (app, AS_APP_KIND_RUNTIME);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_RUNTIME);
                break;
        default:
        case SNAPD_SNAP_TYPE_UNKNOWN:
-               gs_app_set_kind (app, AS_APP_KIND_UNKNOWN);
+               gs_app_set_kind (app, AS_COMPONENT_KIND_UNKNOWN);
                break;
        }
 
diff --git a/src/gs-app-addon-row.c b/src/gs-app-addon-row.c
index 9763e22aa..1c31a1c0a 100644
--- a/src/gs-app-addon-row.c
+++ b/src/gs-app-addon-row.c
@@ -71,7 +71,7 @@ gs_app_addon_row_refresh (GsAppAddonRow *row)
 
        /* join the lines */
        str = gs_app_addon_row_get_summary (row);
-       as_utils_string_replace (str, "\n", " ");
+       as_gstring_replace (str, "\n", " ");
        gtk_label_set_markup (GTK_LABEL (row->description_label), str->str);
        gtk_label_set_label (GTK_LABEL (row->name_label),
                             gs_app_get_name (row->app));
diff --git a/src/gs-app-row.c b/src/gs-app-row.c
index b523f1bee..938f98279 100644
--- a/src/gs-app-row.c
+++ b/src/gs-app-row.c
@@ -269,7 +269,7 @@ gs_app_row_actually_refresh (GsAppRow *app_row)
        /* join the description lines */
        str = gs_app_row_get_description (app_row);
        if (str != NULL) {
-               as_utils_string_replace (str, "\n", " ");
+               as_gstring_replace (str, "\n", " ");
                gtk_label_set_label (GTK_LABEL (priv->description_label), str->str);
                g_string_free (str, TRUE);
        } else {
diff --git a/src/gs-application.c b/src/gs-application.c
index 95afc030c..f6fdfa828 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -176,7 +176,7 @@ gs_application_initialize_plugins (GsApplication *app)
                                     plugin_blocklist,
                                     NULL,
                                     &error)) {
-               g_warning ("Failed to setup plugins: %s", error->message);
+               g_error ("Failed to setup plugins: %s", error->message);
                exit (1);
        }
 
@@ -594,7 +594,7 @@ details_activated (GSimpleAction *action,
                gs_shell_show_search_result (app->shell, id, search);
        } else {
                g_autoptr(GsPluginJob) plugin_job = NULL;
-               if (as_utils_unique_id_valid (id)) {
+               if (as_utils_data_id_valid (id)) {
                        g_autoptr(GsApp) a = gs_plugin_loader_app_create (app->plugin_loader, id);
                        gs_shell_reset_state (app->shell);
                        gs_shell_show_app (app->shell, a);
@@ -668,7 +668,7 @@ install_activated (GSimpleAction *action,
        g_autoptr (GsApp) a = NULL;
 
        g_variant_get (parameter, "(&su)", &id, &interaction);
-       if (!as_utils_unique_id_valid (id)) {
+       if (!as_utils_data_id_valid (id)) {
                g_warning ("Need to use a valid unique-id: %s", id);
                return;
        }
diff --git a/src/gs-common.c b/src/gs-common.c
index 1e5358bfe..2573e7912 100644
--- a/src/gs-common.c
+++ b/src/gs-common.c
@@ -118,7 +118,7 @@ gs_app_notify_installed (GsApp *app)
        g_autoptr(GNotification) n = NULL;
 
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_OS_UPDATE:
+       case AS_COMPONENT_KIND_OS_UPDATE:
                /* TRANSLATORS: this is the summary of a notification that OS updates
                 * have been successfully installed */
                summary = g_strdup (_("OS updates are now installed"));
@@ -126,7 +126,7 @@ gs_app_notify_installed (GsApp *app)
                 * have been successfully installed */
                body = _("Recently installed updates are available to review");
                break;
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                /* TRANSLATORS: this is the summary of a notification that an application
                 * has been successfully installed */
                summary = g_strdup_printf (_("%s is now installed"), gs_app_get_name (app));
@@ -159,7 +159,7 @@ gs_app_notify_installed (GsApp *app)
                /* TRANSLATORS: button text */
                g_notification_add_button_with_target (n, _("Restart"),
                                                       "app.reboot", NULL);
-       } else if (gs_app_get_kind (app) == AS_APP_KIND_DESKTOP) {
+       } else if (gs_app_get_kind (app) == AS_COMPONENT_KIND_DESKTOP_APP) {
                /* TRANSLATORS: this is button that opens the newly installed application */
                g_notification_add_button_with_target (n, _("Launch"),
                                                       "app.launch", "(ss)",
@@ -266,7 +266,7 @@ gs_app_notify_unavailable (GsApp *app, GtkWindow *parent)
        /* be aware of patent clauses */
        if (hint & GS_APP_LICENSE_PATENT_CONCERN) {
                g_string_append (body, "\n\n");
-               if (gs_app_get_kind (app) != AS_APP_KIND_CODEC) {
+               if (gs_app_get_kind (app) != AS_COMPONENT_KIND_CODEC) {
                        g_string_append_printf (body,
                                                /* TRANSLATORS: Laws are geographical, urgh... */
                                                _("It may be illegal to install "
@@ -557,7 +557,7 @@ gs_utils_get_error_value (const GError *error)
 
 /**
  * gs_utils_build_unique_id_kind:
- * @kind: A #AsAppKind
+ * @kind: A #AsComponentKind
  * @id: An application ID
  *
  * Converts the ID valid into a wildcard unique ID of a specific kind.
@@ -566,20 +566,19 @@ gs_utils_get_error_value (const GError *error)
  * Returns: (transfer full): a unique ID, or %NULL
  */
 gchar *
-gs_utils_build_unique_id_kind (AsAppKind kind, const gchar *id)
+gs_utils_build_unique_id_kind (AsComponentKind kind, const gchar *id)
 {
-       if (as_utils_unique_id_valid (id))
+       if (as_utils_data_id_valid (id))
                return g_strdup (id);
-       return as_utils_unique_id_build (AS_APP_SCOPE_UNKNOWN,
-                                        AS_BUNDLE_KIND_UNKNOWN,
-                                        NULL,
-                                        kind,
-                                        id,
-                                        NULL);
+       return as_utils_build_data_id (AS_COMPONENT_SCOPE_UNKNOWN,
+                                      AS_BUNDLE_KIND_UNKNOWN,
+                                      NULL,
+                                      id,
+                                      NULL);
 }
 
 /**
- * gs_utils_list_has_app_fuzzy:
+ * gs_utils_list_has_component_fuzzy:
  * @list: A #GsAppList
  * @app: A #GsApp
  *
@@ -593,7 +592,7 @@ gs_utils_build_unique_id_kind (AsAppKind kind, const gchar *id)
  * Returns: %TRUE if the app is visually the "same"
  */
 gboolean
-gs_utils_list_has_app_fuzzy (GsAppList *list, GsApp *app)
+gs_utils_list_has_component_fuzzy (GsAppList *list, GsApp *app)
 {
        guint i;
        GsApp *tmp;
diff --git a/src/gs-common.h b/src/gs-common.h
index 7540aef74..63c8e86bf 100644
--- a/src/gs-common.h
+++ b/src/gs-common.h
@@ -42,9 +42,9 @@ void           gs_utils_show_error_dialog     (GtkWindow      *parent,
                                                 const gchar    *title,
                                                 const gchar    *msg,
                                                 const gchar    *details);
-gchar          *gs_utils_build_unique_id_kind  (AsAppKind       kind,
+gchar          *gs_utils_build_unique_id_kind  (AsComponentKind kind,
                                                 const gchar    *id);
-gboolean        gs_utils_list_has_app_fuzzy    (GsAppList      *list,
+gboolean        gs_utils_list_has_component_fuzzy      (GsAppList      *list,
                                                 GsApp          *app);
 void            gs_utils_reboot_notify         (GsAppList      *list);
 
diff --git a/src/gs-css.c b/src/gs-css.c
index 923ac1a83..0f9564319 100644
--- a/src/gs-css.c
+++ b/src/gs-css.c
@@ -16,7 +16,7 @@
 #include "config.h"
 
 #include <gtk/gtk.h>
-#include <appstream-glib.h>
+#include <appstream.h>
 
 #include "gs-css.h"
 
@@ -64,7 +64,7 @@ gs_css_parse (GsCss *self, const gchar *markup, GError **error)
 
        /* old style, no IDs */
        markup_str = g_string_new (markup);
-       as_utils_string_replace (markup_str, "@datadir@", DATADIR);
+       as_gstring_replace (markup_str, "@datadir@", DATADIR);
        if (!g_str_has_prefix (markup_str->str, "#")) {
                g_hash_table_insert (self->ids,
                                     g_strdup ("tile"),
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index b6d332f8c..9eb0c1e52 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -15,7 +15,6 @@
 #include <glib/gi18n.h>
 
 #include "gs-common.h"
-#include "gs-content-rating.h"
 #include "gs-utils.h"
 
 #include "gs-details-page.h"
@@ -206,7 +205,7 @@ gs_details_page_update_shortcut_button (GsDetailsPage *self)
        gtk_widget_set_visible (self->button_details_remove_shortcut,
                                FALSE);
 
-       if (gs_app_get_kind (self->app) != AS_APP_KIND_DESKTOP)
+       if (gs_app_get_kind (self->app) != AS_COMPONENT_KIND_DESKTOP_APP)
                return;
 
        /* Leave the button hidden if the app can’t be launched by the current
@@ -562,7 +561,7 @@ gs_details_page_refresh_screenshots (GsDetailsPage *self)
        gtk_widget_show (self->box_details_screenshot);
 
        /* treat screenshots differently */
-       if (gs_app_get_kind (self->app) == AS_APP_KIND_FONT) {
+       if (gs_app_get_kind (self->app) == AS_COMPONENT_KIND_FONT) {
                gs_container_remove_all (GTK_CONTAINER (self->box_details_screenshot_thumbnails));
                gs_container_remove_all (GTK_CONTAINER (self->box_details_screenshot_main));
                screenshots = gs_app_get_screenshots (self->app);
@@ -570,7 +569,7 @@ gs_details_page_refresh_screenshots (GsDetailsPage *self)
                        ss = g_ptr_array_index (screenshots, i);
 
                        /* set caption */
-                       label = gtk_label_new (as_screenshot_get_caption (ss, NULL));
+                       label = gtk_label_new (as_screenshot_get_caption (ss));
                        g_object_set (label,
                                      "xalign", 0.0,
                                      "max-width-chars", 10,
@@ -599,15 +598,15 @@ gs_details_page_refresh_screenshots (GsDetailsPage *self)
        /* fallback warning */
        screenshots = gs_app_get_screenshots (self->app);
        switch (gs_app_get_kind (self->app)) {
-       case AS_APP_KIND_GENERIC:
-       case AS_APP_KIND_CODEC:
-       case AS_APP_KIND_ADDON:
-       case AS_APP_KIND_SOURCE:
-       case AS_APP_KIND_FIRMWARE:
-       case AS_APP_KIND_DRIVER:
-       case AS_APP_KIND_INPUT_METHOD:
-       case AS_APP_KIND_LOCALIZATION:
-       case AS_APP_KIND_RUNTIME:
+       case AS_COMPONENT_KIND_GENERIC:
+       case AS_COMPONENT_KIND_CODEC:
+       case AS_COMPONENT_KIND_ADDON:
+       case AS_COMPONENT_KIND_REPOSITORY:
+       case AS_COMPONENT_KIND_FIRMWARE:
+       case AS_COMPONENT_KIND_DRIVER:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_LOCALIZATION:
+       case AS_COMPONENT_KIND_RUNTIME:
                gtk_widget_set_visible (self->box_details_screenshot_fallback, FALSE);
                break;
        default:
@@ -750,7 +749,7 @@ gs_details_page_set_description (GsDetailsPage *self, const gchar *tmp)
        }
 
        /* show the webapp warning */
-       if (gs_app_get_kind (self->app) == AS_APP_KIND_WEB_APP) {
+       if (gs_app_get_kind (self->app) == AS_COMPONENT_KIND_WEB_APP) {
                GtkWidget *label;
                /* TRANSLATORS: this is the warning box */
                label = gtk_label_new (_("This application can only be used when there is an active internet 
connection."));
@@ -954,7 +953,7 @@ gs_details_page_refresh_buttons (GsDetailsPage *self)
                gtk_widget_set_visible (self->button_install, FALSE);
                break;
        case GS_APP_STATE_UPDATABLE_LIVE:
-               if (gs_app_get_kind (self->app) == AS_APP_KIND_FIRMWARE) {
+               if (gs_app_get_kind (self->app) == AS_COMPONENT_KIND_FIRMWARE) {
                        gtk_widget_set_visible (self->button_install, TRUE);
                        /* TRANSLATORS: button text in the header when firmware
                         * can be live-installed */
@@ -984,7 +983,7 @@ gs_details_page_refresh_buttons (GsDetailsPage *self)
        /* update button */
        switch (state) {
        case GS_APP_STATE_UPDATABLE_LIVE:
-               if (gs_app_get_kind (self->app) == AS_APP_KIND_FIRMWARE) {
+               if (gs_app_get_kind (self->app) == AS_COMPONENT_KIND_FIRMWARE) {
                        gtk_widget_set_visible (self->button_update, FALSE);
                } else {
                        gtk_widget_set_visible (self->button_update, TRUE);
@@ -1009,7 +1008,7 @@ gs_details_page_refresh_buttons (GsDetailsPage *self)
 
        /* remove button */
        if (gs_app_has_quirk (self->app, GS_APP_QUIRK_COMPULSORY) ||
-           gs_app_get_kind (self->app) == AS_APP_KIND_FIRMWARE) {
+           gs_app_get_kind (self->app) == AS_COMPONENT_KIND_FIRMWARE) {
                gtk_widget_set_visible (self->button_remove, FALSE);
        } else {
                switch (state) {
@@ -1364,7 +1363,7 @@ gs_details_page_refresh_all (GsDetailsPage *self)
 
        /* hide the kudo details for non-desktop software */
        switch (gs_app_get_kind (self->app)) {
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                gtk_widget_set_visible (self->grid_details_kudo, TRUE);
                break;
        default:
@@ -1374,7 +1373,7 @@ gs_details_page_refresh_all (GsDetailsPage *self)
 
        /* only show permissions for flatpak apps */
        if (gs_app_get_bundle_kind (self->app) == AS_BUNDLE_KIND_FLATPAK &&
-           gs_app_get_kind (self->app) == AS_APP_KIND_DESKTOP) {
+           gs_app_get_kind (self->app) == AS_COMPONENT_KIND_DESKTOP_APP) {
                GsAppPermissions permissions = gs_app_get_permissions (self->app);
 
                populate_permission_details (self, permissions);
@@ -1405,7 +1404,7 @@ gs_details_page_refresh_all (GsDetailsPage *self)
                                gs_app_get_state (self->app) == GS_APP_STATE_AVAILABLE_LOCAL);
 
        switch (gs_app_get_kind (self->app)) {
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                /* installing an app with a repo file */
                gtk_widget_set_visible (self->infobar_details_app_repo,
                                        gs_app_has_quirk (self->app,
@@ -1413,7 +1412,7 @@ gs_details_page_refresh_all (GsDetailsPage *self)
                                        gs_app_get_state (self->app) == GS_APP_STATE_AVAILABLE_LOCAL);
                gtk_widget_set_visible (self->infobar_details_repo, FALSE);
                break;
-       case AS_APP_KIND_GENERIC:
+       case AS_COMPONENT_KIND_GENERIC:
                /* installing a repo-release package */
                gtk_widget_set_visible (self->infobar_details_app_repo, FALSE);
                gtk_widget_set_visible (self->infobar_details_repo,
@@ -1429,8 +1428,8 @@ gs_details_page_refresh_all (GsDetailsPage *self)
 
        /* installing a app without a repo file */
        switch (gs_app_get_kind (self->app)) {
-       case AS_APP_KIND_DESKTOP:
-               if (gs_app_get_kind (self->app) == AS_APP_KIND_FIRMWARE) {
+       case AS_COMPONENT_KIND_DESKTOP_APP:
+               if (gs_app_get_kind (self->app) == AS_COMPONENT_KIND_FIRMWARE) {
                        gtk_widget_set_visible (self->infobar_details_app_norepo, FALSE);
                } else {
                        gtk_widget_set_visible (self->infobar_details_app_norepo,
@@ -1458,7 +1457,7 @@ gs_details_page_refresh_all (GsDetailsPage *self)
 
        /* hide fields that don't make sense for sources */
        switch (gs_app_get_kind (self->app)) {
-       case AS_APP_KIND_SOURCE:
+       case AS_COMPONENT_KIND_REPOSITORY:
                gtk_widget_set_visible (self->label_details_license_title, FALSE);
                gtk_widget_set_visible (self->box_details_license_value, FALSE);
                gtk_widget_set_visible (self->label_details_version_title, FALSE);
@@ -1624,11 +1623,11 @@ gs_details_page_refresh_reviews (GsDetailsPage *self)
 
        /* show or hide the entire reviews section */
        switch (gs_app_get_kind (self->app)) {
-       case AS_APP_KIND_DESKTOP:
-       case AS_APP_KIND_FONT:
-       case AS_APP_KIND_INPUT_METHOD:
-       case AS_APP_KIND_WEB_APP:
-       case AS_APP_KIND_SHELL_EXTENSION:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
+       case AS_COMPONENT_KIND_FONT:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_WEB_APP:
+       case AS_COMPONENT_KIND_SHELL_EXTENSION:
                /* don't show a missing rating on a local file */
                if (gs_app_get_state (self->app) != GS_APP_STATE_AVAILABLE_LOCAL &&
                    self->enable_reviews)
@@ -1788,23 +1787,23 @@ static void
 gs_details_page_refresh_content_rating (GsDetailsPage *self)
 {
        AsContentRating *content_rating;
-       GsContentRatingSystem system;
+       AsContentRatingSystem system;
        guint age = 0;
        g_autofree gchar *display = NULL;
        const gchar *locale;
 
        /* get the content rating system from the locale */
        locale = setlocale (LC_MESSAGES, NULL);
-       system = gs_utils_content_rating_system_from_locale (locale);
+       system = as_content_rating_system_from_locale (locale);
        g_debug ("content rating system is guessed as %s from %s",
-                gs_content_rating_system_to_str (system),
+                as_content_rating_system_to_string (system),
                 locale);
 
        /* only show the button if a game and has a content rating */
        content_rating = gs_app_get_content_rating (self->app);
        if (content_rating != NULL) {
                age = as_content_rating_get_minimum_age (content_rating);
-               display = gs_utils_content_rating_age_to_str (system, age);
+               display = as_content_rating_system_format_age (system, age);
        }
        if (display != NULL) {
                gtk_button_set_label (GTK_BUTTON (self->button_details_rating_value), display);
@@ -1922,7 +1921,7 @@ gs_details_page_load_stage1_cb (GObject *source,
                           gs_app_get_id (self->app),
                           error->message);
        }
-       if (gs_app_get_kind (self->app) == AS_APP_KIND_UNKNOWN ||
+       if (gs_app_get_kind (self->app) == AS_COMPONENT_KIND_UNKNOWN ||
            gs_app_get_state (self->app) == GS_APP_STATE_UNKNOWN) {
                g_autofree gchar *str = NULL;
                const gchar *id = gs_app_get_id (self->app);
@@ -2401,12 +2400,7 @@ static guint
 content_rating_get_age (AsContentRating *content_rating, const gchar *id)
 {
        AsContentRatingValue value = as_content_rating_get_value (content_rating, id);
-#if AS_CHECK_VERSION (0, 7, 15)
        return as_content_rating_attribute_to_csm_age (id, value);
-#else
-       /* Hackily treat the value as an age; it should compare the same */
-       return (guint) value;
-#endif
 }
 
 static void
@@ -2444,7 +2438,7 @@ gs_details_page_content_rating_button_cb (GtkWidget *widget, GsDetailsPage *self
        if (cr == NULL)
                return;
 
-       ids = gs_content_rating_get_all_rating_ids ();
+       ids = as_content_rating_get_all_rating_ids ();
 
        /* get the worst thing */
        for (gsize i = 0; ids[i] != NULL; i++) {
@@ -2493,7 +2487,7 @@ gs_details_page_content_rating_button_cb (GtkWidget *widget, GsDetailsPage *self
                            content_rating_get_age (cr, coalesce_groups[0]) == age)
                                continue;
 
-                       tmp = gs_content_rating_key_value_to_str (ids[i], as_content_rating_get_value (cr, 
ids[i]));
+                       tmp = as_content_rating_attribute_get_description (ids[i], 
as_content_rating_get_value (cr, ids[i]));
                        g_string_append_printf (str, "• %s\n", tmp);
                }
        }
@@ -2503,7 +2497,7 @@ gs_details_page_content_rating_button_cb (GtkWidget *widget, GsDetailsPage *self
                age = content_rating_get_age (cr, violence_group[i]);
                if (age < age_bad)
                        continue;
-               tmp = gs_content_rating_key_value_to_str (violence_group[i], as_content_rating_get_value (cr, 
violence_group[i]));
+               tmp = as_content_rating_attribute_get_description (violence_group[i], 
as_content_rating_get_value (cr, violence_group[i]));
                g_string_append_printf (str, "• %s\n", tmp);
                break;
        }
@@ -2513,7 +2507,7 @@ gs_details_page_content_rating_button_cb (GtkWidget *widget, GsDetailsPage *self
                age = content_rating_get_age (cr, social_group[i]);
                if (age < age_bad)
                        continue;
-               tmp = gs_content_rating_key_value_to_str (social_group[i], as_content_rating_get_value (cr, 
social_group[i]));
+               tmp = as_content_rating_attribute_get_description (social_group[i], 
as_content_rating_get_value (cr, social_group[i]));
                g_string_append_printf (str, "• %s\n", tmp);
                break;
        }
@@ -2604,7 +2598,7 @@ gs_details_page_license_widget_for_token (GsDetailsPage *self, const gchar *toke
        }
 
        /* new SPDX value the extractor didn't know about */
-       if (as_utils_is_spdx_license_id (token)) {
+       if (as_is_spdx_license_id (token)) {
                g_autofree gchar *uri = NULL;
                uri = g_strdup_printf ("http://spdx.org/licenses/%s";,
                                       token);
@@ -2624,7 +2618,7 @@ gs_details_page_license_free_cb (GtkWidget *widget, GsDetailsPage *self)
 
        /* URLify any SPDX IDs */
        gs_container_remove_all (GTK_CONTAINER (self->box_details_license_list));
-       tokens = as_utils_spdx_license_tokenize (gs_app_get_license (self->app));
+       tokens = as_spdx_license_tokenize (gs_app_get_license (self->app));
        for (i = 0; tokens[i] != NULL; i++) {
                GtkWidget *w = NULL;
 
@@ -2665,7 +2659,7 @@ gs_details_page_license_nonfree_cb (GtkWidget *widget, GsDetailsPage *self)
        g_auto(GStrv) tokens = NULL;
 
        /* license specified as a link */
-       tokens = as_utils_spdx_license_tokenize (gs_app_get_license (self->app));
+       tokens = as_spdx_license_tokenize (gs_app_get_license (self->app));
        for (guint i = 0; tokens[i] != NULL; i++) {
                if (g_str_has_prefix (tokens[i], "@LicenseRef-proprietary=")) {
                        uri = g_strdup (tokens[i] + 24);
diff --git a/src/gs-extras-page.c b/src/gs-extras-page.c
index 4e723aa94..21af40ce3 100644
--- a/src/gs-extras-page.c
+++ b/src/gs-extras-page.c
@@ -448,7 +448,7 @@ create_missing_app (SearchData *search_data)
        }
        gs_app_set_summary_missing (app, g_string_free (summary_missing, FALSE));
 
-       gs_app_set_kind (app, AS_APP_KIND_GENERIC);
+       gs_app_set_kind (app, AS_COMPONENT_KIND_GENERIC);
        gs_app_set_state (app, GS_APP_STATE_UNAVAILABLE);
        gs_app_set_url (app, AS_URL_KIND_MISSING, search_data->url_not_found);
 
diff --git a/src/gs-installed-page.c b/src/gs-installed-page.c
index 1fd8a843c..721a966c1 100644
--- a/src/gs-installed-page.c
+++ b/src/gs-installed-page.c
@@ -159,7 +159,7 @@ gs_installed_page_add_app (GsInstalledPage *self, GsAppList *list, GsApp *app)
        app_row = g_object_new (GS_TYPE_APP_ROW,
                                "app", app,
                                "show-buttons", TRUE,
-                               "show-source", gs_utils_list_has_app_fuzzy (list, app),
+                               "show-source", gs_utils_list_has_component_fuzzy (list, app),
                                "show-installed-size", !gs_app_has_quirk (app, GS_APP_QUIRK_COMPULSORY) && 
should_show_installed_size (self),
                                NULL);
 
@@ -336,31 +336,31 @@ gs_installed_page_get_app_sort_key (GsApp *app)
 
        /* sort apps by kind */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_OS_UPDATE:
+       case AS_COMPONENT_KIND_OS_UPDATE:
                g_string_append (key, "1:");
                break;
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                g_string_append (key, "2:");
                break;
-       case AS_APP_KIND_WEB_APP:
+       case AS_COMPONENT_KIND_WEB_APP:
                g_string_append (key, "3:");
                break;
-       case AS_APP_KIND_RUNTIME:
+       case AS_COMPONENT_KIND_RUNTIME:
                g_string_append (key, "4:");
                break;
-       case AS_APP_KIND_ADDON:
+       case AS_COMPONENT_KIND_ADDON:
                g_string_append (key, "5:");
                break;
-       case AS_APP_KIND_CODEC:
+       case AS_COMPONENT_KIND_CODEC:
                g_string_append (key, "6:");
                break;
-       case AS_APP_KIND_FONT:
+       case AS_COMPONENT_KIND_FONT:
                g_string_append (key, "6:");
                break;
-       case AS_APP_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
                g_string_append (key, "7:");
                break;
-       case AS_APP_KIND_SHELL_EXTENSION:
+       case AS_COMPONENT_KIND_SHELL_EXTENSION:
                g_string_append (key, "8:");
                break;
        default:
@@ -417,8 +417,8 @@ typedef enum {
 static GsInstalledPageSection
 gs_installed_page_get_app_section (GsApp *app)
 {
-       if (gs_app_get_kind (app) == AS_APP_KIND_DESKTOP ||
-           gs_app_get_kind (app) == AS_APP_KIND_WEB_APP) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_DESKTOP_APP ||
+           gs_app_get_kind (app) == AS_COMPONENT_KIND_WEB_APP) {
                if (gs_app_has_quirk (app, GS_APP_QUIRK_COMPULSORY))
                        return GS_UPDATE_LIST_SECTION_SYSTEM_APPS;
                return GS_UPDATE_LIST_SECTION_REMOVABLE_APPS;
@@ -515,7 +515,7 @@ gs_installed_page_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
 
                /* never show OS upgrades, we handle the scheduling and
                 * cancellation in GsUpgradeBanner */
-               if (gs_app_get_kind (app) == AS_APP_KIND_OS_UPGRADE)
+               if (gs_app_get_kind (app) == AS_COMPONENT_KIND_OPERATING_SYSTEM)
                        continue;
 
                /* do not to add pending apps more than once. */
diff --git a/src/gs-origin-popover-row.c b/src/gs-origin-popover-row.c
index f5ee8c5a3..325668ca3 100644
--- a/src/gs-origin-popover-row.c
+++ b/src/gs-origin-popover-row.c
@@ -77,12 +77,12 @@ refresh_ui (GsOriginPopoverRow *row)
        }
 
        if (gs_app_get_bundle_kind (priv->app) == AS_BUNDLE_KIND_FLATPAK &&
-           gs_app_get_scope (priv->app) != AS_APP_SCOPE_UNKNOWN) {
-               AsAppScope scope = gs_app_get_scope (priv->app);
-               if (scope == AS_APP_SCOPE_SYSTEM) {
+           gs_app_get_scope (priv->app) != AS_COMPONENT_SCOPE_UNKNOWN) {
+               AsComponentScope scope = gs_app_get_scope (priv->app);
+               if (scope == AS_COMPONENT_SCOPE_SYSTEM) {
                        /* TRANSLATORS: the installation location for flatpaks */
                        gtk_label_set_text (GTK_LABEL (priv->installation_label), _("system"));
-               } else if (scope == AS_APP_SCOPE_USER) {
+               } else if (scope == AS_COMPONENT_SCOPE_USER) {
                        /* TRANSLATORS: the installation location for flatpaks */
                        gtk_label_set_text (GTK_LABEL (priv->installation_label), _("user"));
                }
diff --git a/src/gs-page.c b/src/gs-page.c
index 1bcd27c7b..52f1fcdab 100644
--- a/src/gs-page.c
+++ b/src/gs-page.c
@@ -81,7 +81,7 @@ gs_page_show_update_message (GsPageHelper *helper, AsScreenshot *ss)
                                         GTK_MESSAGE_INFO,
                                         GTK_BUTTONS_OK,
                                         "%s", gs_app_get_name (helper->app));
-       escaped = g_markup_escape_text (as_screenshot_get_caption (ss, NULL), -1);
+       escaped = g_markup_escape_text (as_screenshot_get_caption (ss), -1);
        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                                  "%s", escaped);
 
@@ -152,10 +152,10 @@ gs_page_app_installed_cb (GObject *source,
        }
 
        /* tell the user what they have to do */
-       if (gs_app_get_kind (helper->app) == AS_APP_KIND_FIRMWARE &&
+       if (gs_app_get_kind (helper->app) == AS_COMPONENT_KIND_FIRMWARE &&
            gs_app_has_quirk (helper->app, GS_APP_QUIRK_NEEDS_USER_ACTION)) {
                AsScreenshot *ss = gs_app_get_action_screenshot (helper->app);
-               if (ss != NULL && as_screenshot_get_caption (ss, NULL) != NULL)
+               if (ss != NULL && as_screenshot_get_caption (ss) != NULL)
                        gs_page_show_update_message (helper, ss);
        }
 
@@ -328,7 +328,7 @@ gs_page_needs_user_action (GsPageHelper *helper, AsScreenshot *ss)
                                          * '%s' is an application summary, e.g. 'GNOME Clocks' */
                                         _("Prepare %s"),
                                         gs_app_get_name (helper->app));
-       escaped = g_markup_escape_text (as_screenshot_get_caption (ss, NULL), -1);
+       escaped = g_markup_escape_text (as_screenshot_get_caption (ss), -1);
        gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
                                                    "%s", escaped);
 
@@ -378,10 +378,10 @@ gs_page_update_app (GsPage *page, GsApp *app, GCancellable *cancellable)
        helper->cancellable = g_object_ref (cancellable);
 
        /* tell the user what they have to do */
-       if (gs_app_get_kind (app) == AS_APP_KIND_FIRMWARE &&
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_FIRMWARE &&
            gs_app_has_quirk (app, GS_APP_QUIRK_NEEDS_USER_ACTION)) {
                AsScreenshot *ss = gs_app_get_action_screenshot (app);
-               if (ss != NULL && as_screenshot_get_caption (ss, NULL) != NULL) {
+               if (ss != NULL && as_screenshot_get_caption (ss) != NULL) {
                        gs_page_needs_user_action (helper, ss);
                        return;
                }
@@ -459,7 +459,7 @@ gs_page_remove_app (GsPage *page, GsApp *app, GCancellable *cancellable)
 
        /* use different name and summary */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_SOURCE:
+       case AS_COMPONENT_KIND_REPOSITORY:
                /* TRANSLATORS: this is a prompt message, and '%s' is an
                 * repository name, e.g. 'GNOME Nightly' */
                title = g_strdup_printf (_("Are you sure you want to remove "
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
index f4dbb46f0..2389313d4 100644
--- a/src/gs-repos-dialog.c
+++ b/src/gs-repos-dialog.c
@@ -74,14 +74,14 @@ get_repo_installed_text (GsApp *repo)
        for (guint i = 0; i < gs_app_list_length (related); i++) {
                GsApp *app_tmp = gs_app_list_index (related, i);
                switch (gs_app_get_kind (app_tmp)) {
-               case AS_APP_KIND_WEB_APP:
-               case AS_APP_KIND_DESKTOP:
+               case AS_COMPONENT_KIND_WEB_APP:
+               case AS_COMPONENT_KIND_DESKTOP_APP:
                        cnt_apps++;
                        break;
-               case AS_APP_KIND_FONT:
-               case AS_APP_KIND_CODEC:
-               case AS_APP_KIND_INPUT_METHOD:
-               case AS_APP_KIND_ADDON:
+               case AS_COMPONENT_KIND_FONT:
+               case AS_COMPONENT_KIND_CODEC:
+               case AS_COMPONENT_KIND_INPUT_METHOD:
+               case AS_COMPONENT_KIND_ADDON:
                        cnt_addon++;
                        break;
                default:
diff --git a/src/gs-screenshot-image.c b/src/gs-screenshot-image.c
index c816a84d3..72534ccb2 100644
--- a/src/gs-screenshot-image.c
+++ b/src/gs-screenshot-image.c
@@ -118,21 +118,108 @@ as_screenshot_show_image (GsScreenshotImage *ssimg)
        gs_screenshot_image_stop_spinner (ssimg);
 }
 
+static GdkPixbuf *
+gs_pixbuf_resample (GdkPixbuf *original,
+                   guint width,
+                   guint height,
+                   gboolean blurred)
+{
+       GdkPixbuf *pixbuf = NULL;
+       guint tmp_height;
+       guint tmp_width;
+       guint pixbuf_height;
+       guint pixbuf_width;
+       g_autoptr(GdkPixbuf) pixbuf_tmp = NULL;
+
+       /* never set */
+       if (original == NULL)
+               return NULL;
+
+       /* 0 means 'default' */
+       if (width == 0)
+               width = (guint) gdk_pixbuf_get_width (original);
+       if (height == 0)
+               height = (guint) gdk_pixbuf_get_height (original);
+
+       /* don't do anything to an image with the correct size */
+       pixbuf_width = (guint) gdk_pixbuf_get_width (original);
+       pixbuf_height = (guint) gdk_pixbuf_get_height (original);
+       if (width == pixbuf_width && height == pixbuf_height)
+               return g_object_ref (original);
+
+       /* is the aspect ratio of the source perfectly 16:9 */
+       if ((pixbuf_width / 16) * 9 == pixbuf_height) {
+               pixbuf = gdk_pixbuf_scale_simple (original,
+                                                 (gint) width, (gint) height,
+                                                 GDK_INTERP_HYPER);
+               if (blurred)
+                       gs_utils_pixbuf_blur (pixbuf, 5, 3);
+               return pixbuf;
+       }
+
+       /* create new 16:9 pixbuf with alpha padding */
+       pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+                                TRUE, 8,
+                                (gint) width,
+                                (gint) height);
+       gdk_pixbuf_fill (pixbuf, 0x00000000);
+       /* check the ratio to see which property needs to be fitted and which needs
+        * to be reduced */
+       if (pixbuf_width * 9 > pixbuf_height * 16) {
+               tmp_width = width;
+               tmp_height = width * pixbuf_height / pixbuf_width;
+       } else {
+               tmp_width = height * pixbuf_width / pixbuf_height;
+               tmp_height = height;
+       }
+       pixbuf_tmp = gdk_pixbuf_scale_simple (original,
+                                             (gint) tmp_width,
+                                             (gint) tmp_height,
+                                             GDK_INTERP_HYPER);
+       if (blurred)
+               gs_utils_pixbuf_blur (pixbuf_tmp, 5, 3);
+       gdk_pixbuf_copy_area (pixbuf_tmp,
+                             0, 0, /* of src */
+                             (gint) tmp_width,
+                             (gint) tmp_height,
+                             pixbuf,
+                             (gint) (width - tmp_width) / 2,
+                             (gint) (height - tmp_height) / 2);
+       return pixbuf;
+}
+
+static gboolean
+gs_pixbuf_save_filename (GdkPixbuf *pixbuf,
+                        const gchar *filename,
+                        guint width,
+                        guint height,
+                        GError **error)
+{
+       g_autoptr(GdkPixbuf) pb = NULL;
+
+       /* resample & save pixbuf */
+       pb = gs_pixbuf_resample (pixbuf, width, height, FALSE);
+       return gdk_pixbuf_save (pb,
+                               filename,
+                               "png",
+                               error,
+                               NULL);
+}
+
 static void
 gs_screenshot_image_show_blurred (GsScreenshotImage *ssimg,
                                  const gchar *filename_thumb)
 {
-       g_autoptr(AsImage) im = NULL;
+       g_autoptr(GdkPixbuf) pb_src = NULL;
        g_autoptr(GdkPixbuf) pb = NULL;
 
-       /* create an helper which can do the blurring for us */
-       im = as_image_new ();
-       if (!as_image_load_filename (im, filename_thumb, NULL))
+       pb_src = gdk_pixbuf_new_from_file (filename_thumb, NULL);
+       if (pb_src == NULL)
                return;
-       pb = as_image_save_pixbuf (im,
-                                  ssimg->width * ssimg->scale,
-                                  ssimg->height * ssimg->scale,
-                                  AS_IMAGE_SAVE_FLAG_BLUR);
+       pb = gs_pixbuf_resample (pb_src,
+                                ssimg->width * ssimg->scale,
+                                ssimg->height * ssimg->scale,
+                                TRUE /* blurred */);
        if (pb == NULL)
                return;
 
@@ -150,7 +237,6 @@ gs_screenshot_image_save_downloaded_img (GsScreenshotImage *ssimg,
                                         GdkPixbuf *pixbuf,
                                         GError **error)
 {
-       g_autoptr(AsImage) im = NULL;
        gboolean ret;
        const GPtrArray *images;
        g_autoptr(GError) error_local = NULL;
@@ -161,14 +247,9 @@ gs_screenshot_image_save_downloaded_img (GsScreenshotImage *ssimg,
        guint width = ssimg->width;
        guint height = ssimg->height;
 
-       /* save to file, using the same code as the AppStream builder
-        * so the preview looks the same */
-       im = as_image_new ();
-       as_image_set_pixbuf (im, pixbuf);
-       ret = as_image_save_filename (im, ssimg->filename,
+       ret = gs_pixbuf_save_filename (pixbuf, ssimg->filename,
                                      ssimg->width * ssimg->scale,
                                      ssimg->height * ssimg->scale,
-                                     AS_IMAGE_SAVE_FLAG_PAD_16_9,
                                      error);
 
        if (!ret)
@@ -209,9 +290,9 @@ gs_screenshot_image_save_downloaded_img (GsScreenshotImage *ssimg,
                 return TRUE;
         }
 
-       ret = as_image_save_filename (im, filename, width, height,
-                                     AS_IMAGE_SAVE_FLAG_PAD_16_9,
-                                     &error_local);
+       ret = gs_pixbuf_save_filename (pixbuf, filename,
+                                       width, height,
+                                       &error_local);
 
        if (!ret) {
                /* if we cannot save this screenshot, warn about that but do not
diff --git a/src/gs-search-page.c b/src/gs-search-page.c
index ef79c85b6..48f31dba5 100644
--- a/src/gs-search-page.c
+++ b/src/gs-search-page.c
@@ -160,7 +160,7 @@ gs_search_page_get_search_cb (GObject *source_object,
 
        if (self->appid_to_show != NULL) {
                g_autoptr (GsApp) a = NULL;
-               if (as_utils_unique_id_valid (self->appid_to_show)) {
+               if (as_utils_data_id_valid (self->appid_to_show)) {
                        a = gs_plugin_loader_app_create (self->plugin_loader,
                                                         self->appid_to_show);
                } else {
@@ -190,8 +190,8 @@ gs_search_page_get_app_sort_key (GsApp *app)
 
        /* sort apps before runtimes and extensions */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_DESKTOP:
-       case AS_APP_KIND_SHELL_EXTENSION:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
+       case AS_COMPONENT_KIND_SHELL_EXTENSION:
                g_string_append (key, "9:");
                break;
        default:
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 43d94c5e6..b664656c0 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -10,7 +10,6 @@
 
 #include "gnome-software-private.h"
 
-#include "gs-content-rating.h"
 #include "gs-css.h"
 #include "gs-test.h"
 
diff --git a/src/gs-shell-search-provider.c b/src/gs-shell-search-provider.c
index 806ec3d3f..98ddc9215 100644
--- a/src/gs-shell-search-provider.c
+++ b/src/gs-shell-search-provider.c
@@ -117,7 +117,7 @@ gs_shell_search_provider_get_app_sort_key (GsApp *app)
 
        /* sort apps before runtimes and extensions */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                g_string_append (key, "9:");
                break;
        default:
@@ -252,7 +252,7 @@ handle_get_result_metas (GsShellSearchProvider2     *skeleton,
                if (pixbuf != NULL)
                        g_variant_builder_add (&meta, "{sv}", "icon", g_icon_serialize (G_ICON (pixbuf)));
 
-               if (gs_utils_list_has_app_fuzzy (self->search_results, app) &&
+               if (gs_utils_list_has_component_fuzzy (self->search_results, app) &&
                    gs_app_get_origin_hostname (app) != NULL) {
                        /* TRANSLATORS: this refers to where the app came from */
                        g_autofree gchar *source_text = g_strdup_printf (_("Source: %s"),
@@ -361,8 +361,8 @@ search_provider_dispose (GObject *obj)
 static void
 gs_shell_search_provider_init (GsShellSearchProvider *self)
 {
-       self->metas_cache = g_hash_table_new_full ((GHashFunc) as_utils_unique_id_hash,
-                                                  (GEqualFunc) as_utils_unique_id_equal,
+       self->metas_cache = g_hash_table_new_full ((GHashFunc) as_utils_data_id_hash,
+                                                  (GEqualFunc) as_utils_data_id_equal,
                                                   g_free,
                                                   (GDestroyNotify) g_variant_unref);
 
diff --git a/src/gs-update-dialog.c b/src/gs-update-dialog.c
index 2ff50ea00..ebed476ec 100644
--- a/src/gs-update-dialog.c
+++ b/src/gs-update-dialog.c
@@ -156,13 +156,13 @@ populate_permissions_section (GsUpdateDialog *dialog, GsAppPermissions permissio
 static void
 set_updates_description_ui (GsUpdateDialog *dialog, GsApp *app)
 {
-       AsAppKind kind;
+       AsComponentKind kind;
        const GdkPixbuf *pixbuf;
        const gchar *update_details;
 
        /* set window title */
        kind = gs_app_get_kind (app);
-       if (kind == AS_APP_KIND_OS_UPDATE) {
+       if (kind == AS_COMPONENT_KIND_OS_UPDATE) {
                gtk_window_set_title (GTK_WINDOW (dialog), gs_app_get_name (app));
        } else if (gs_app_get_source_default (app) != NULL &&
                   gs_app_get_update_version (app) != NULL) {
@@ -180,7 +180,7 @@ set_updates_description_ui (GsUpdateDialog *dialog, GsApp *app)
        }
 
        /* set update header */
-       gtk_widget_set_visible (dialog->box_header, kind == AS_APP_KIND_DESKTOP);
+       gtk_widget_set_visible (dialog->box_header, kind == AS_COMPONENT_KIND_DESKTOP_APP);
        update_details = gs_app_get_update_details (app);
        if (update_details == NULL) {
                /* TRANSLATORS: this is where the packager did not write
@@ -457,22 +457,12 @@ is_downgrade (const gchar *evr1,
         * part of the semantic version */
 
        /* check version */
-#if AS_CHECK_VERSION(0,7,15)
-       rc = as_utils_vercmp_full (version1, version2,
-                                  AS_VERSION_COMPARE_FLAG_NONE);
-#else
-       rc = as_utils_vercmp (version1, version2);
-#endif
+       rc = as_utils_compare_versions (version1, version2);
        if (rc != 0)
                return rc > 0;
 
        /* check release */
-#if AS_CHECK_VERSION(0,7,15)
-       rc = as_utils_vercmp_full (release1, release2,
-                                  AS_VERSION_COMPARE_FLAG_NONE);
-#else
-       rc = as_utils_vercmp (release1, release2);
-#endif
+       rc = as_utils_compare_versions (release1, release2);
        if (rc != 0)
                return rc > 0;
 
@@ -630,7 +620,7 @@ create_section (GsUpdateDialog *dialog, GsUpdateDialogSection section)
 void
 gs_update_dialog_show_update_details (GsUpdateDialog *dialog, GsApp *app)
 {
-       AsAppKind kind;
+       AsComponentKind kind;
        g_autofree gchar *str = NULL;
 
        /* debug */
@@ -646,7 +636,7 @@ gs_update_dialog_show_update_details (GsUpdateDialog *dialog, GsApp *app)
 
        /* set update description */
        kind = gs_app_get_kind (app);
-       if (kind == AS_APP_KIND_OS_UPDATE) {
+       if (kind == AS_COMPONENT_KIND_OS_UPDATE) {
                GsAppList *related;
                GsApp *app_related;
                GsUpdateDialogSection section;
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
index 56a52d92a..76bd97265 100644
--- a/src/gs-update-monitor.c
+++ b/src/gs-update-monitor.c
@@ -192,7 +192,7 @@ should_download_updates (GsUpdateMonitor *monitor)
 static gboolean
 _filter_by_app_kind (GsApp *app, gpointer user_data)
 {
-       AsAppKind kind = GPOINTER_TO_UINT (user_data);
+       AsComponentKind kind = GPOINTER_TO_UINT (user_data);
        return gs_app_get_kind (app) == kind;
 }
 
@@ -219,7 +219,7 @@ _build_autoupdated_notification (GsUpdateMonitor *monitor, GsAppList *list)
        list_apps = gs_app_list_copy (list);
        gs_app_list_filter (list_apps,
                            _filter_by_app_kind,
-                           GUINT_TO_POINTER(AS_APP_KIND_DESKTOP));
+                           GUINT_TO_POINTER(AS_COMPONENT_KIND_DESKTOP_APP));
        gs_app_list_sort (list_apps, _sort_by_rating_cb, NULL);
        /* FIXME: add the applications that are currently active that use one
         * of the updated runtimes */
@@ -1005,7 +1005,7 @@ get_updates_historical_cb (GObject *object, GAsyncResult *res, gpointer data)
        if (time_last_notified >= gs_app_get_install_date (app))
                return;
 
-       if (gs_app_get_kind (app) == AS_APP_KIND_OS_UPGRADE) {
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_OPERATING_SYSTEM) {
                /* TRANSLATORS: Notification title when we've done a distro upgrade */
                notification = g_notification_new (_("System Upgrade Complete"));
 
diff --git a/src/gs-updates-page.c b/src/gs-updates-page.c
index 9c04975d8..37919fc53 100644
--- a/src/gs-updates-page.c
+++ b/src/gs-updates-page.c
@@ -141,11 +141,11 @@ static GsUpdatesSectionKind
 _get_app_section (GsApp *app)
 {
        if (gs_app_get_state (app) == GS_APP_STATE_UPDATABLE_LIVE) {
-               if (gs_app_get_kind (app) == AS_APP_KIND_FIRMWARE)
+               if (gs_app_get_kind (app) == AS_COMPONENT_KIND_FIRMWARE)
                        return GS_UPDATES_SECTION_KIND_ONLINE_FIRMWARE;
                return GS_UPDATES_SECTION_KIND_ONLINE;
        }
-       if (gs_app_get_kind (app) == AS_APP_KIND_FIRMWARE)
+       if (gs_app_get_kind (app) == AS_COMPONENT_KIND_FIRMWARE)
                return GS_UPDATES_SECTION_KIND_OFFLINE_FIRMWARE;
        return GS_UPDATES_SECTION_KIND_OFFLINE;
 }
@@ -1238,7 +1238,7 @@ gs_updates_page_status_changed_cb (GsPluginLoader *plugin_loader,
        case GS_PLUGIN_STATUS_INSTALLING:
        case GS_PLUGIN_STATUS_REMOVING:
                if (app == NULL ||
-                   (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE &&
+                   (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM &&
                     gs_app_get_id (app) != NULL)) {
                        /* if we do a install or remove then make sure all new
                         * packages are downloaded */
diff --git a/src/gs-updates-section.c b/src/gs-updates-section.c
index 16c99331b..c87f75125 100644
--- a/src/gs-updates-section.c
+++ b/src/gs-updates-section.c
@@ -142,31 +142,31 @@ _get_app_sort_key (GsApp *app)
 
        /* sort apps by kind */
        switch (gs_app_get_kind (app)) {
-       case AS_APP_KIND_OS_UPDATE:
+       case AS_COMPONENT_KIND_OS_UPDATE:
                g_string_append (key, "1:");
                break;
-       case AS_APP_KIND_DESKTOP:
+       case AS_COMPONENT_KIND_DESKTOP_APP:
                g_string_append (key, "2:");
                break;
-       case AS_APP_KIND_WEB_APP:
+       case AS_COMPONENT_KIND_WEB_APP:
                g_string_append (key, "3:");
                break;
-       case AS_APP_KIND_RUNTIME:
+       case AS_COMPONENT_KIND_RUNTIME:
                g_string_append (key, "4:");
                break;
-       case AS_APP_KIND_ADDON:
+       case AS_COMPONENT_KIND_ADDON:
                g_string_append (key, "5:");
                break;
-       case AS_APP_KIND_CODEC:
+       case AS_COMPONENT_KIND_CODEC:
                g_string_append (key, "6:");
                break;
-       case AS_APP_KIND_FONT:
+       case AS_COMPONENT_KIND_FONT:
                g_string_append (key, "6:");
                break;
-       case AS_APP_KIND_INPUT_METHOD:
+       case AS_COMPONENT_KIND_INPUT_METHOD:
                g_string_append (key, "7:");
                break;
-       case AS_APP_KIND_SHELL_EXTENSION:
+       case AS_COMPONENT_KIND_SHELL_EXTENSION:
                g_string_append (key, "8:");
                break;
        default:
diff --git a/src/meson.build b/src/meson.build
index fde5fbdc5..c6e280476 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -25,7 +25,6 @@ gnome_software_sources = [
   'gs-category-tile.c',
   'gs-common.c',
   'gs-css.c',
-  'gs-content-rating.c',
   'gs-details-page.c',
   'gs-extras-page.c',
   'gs-feature-tile.c',
@@ -230,7 +229,6 @@ if get_option('tests')
     sources : [
       'gs-css.c',
       'gs-common.c',
-      'gs-content-rating.c',
       'gs-self-test.c',
     ],
     include_directories : [


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]