[gthumb] Utility functions refactoring



commit 62b059b5591baba80b46b17f1042a5065b43deaa
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Thu Dec 5 12:57:25 2019 +0100

    Utility functions refactoring
    
    * renamed some functions to improve consinstency
    * delete unused functions
    * splitted in more files
    * reimplemented some functions
    * added tests

 extensions/burn_disc/gth-burn-task.c               |    8 +-
 extensions/catalogs/dlg-catalog-properties.c       |    7 +-
 extensions/catalogs/gth-catalog.c                  |    4 +-
 extensions/catalogs/gth-file-source-catalogs.c     |   84 +-
 extensions/catalogs/gth-organize-task.c            |   14 +-
 extensions/contact_sheet/dlg-contact-sheet.c       |    4 +-
 extensions/contact_sheet/dlg-image-wall.c          |    2 +-
 .../contact_sheet/gth-contact-sheet-creator.c      |   62 +-
 extensions/desktop_background/actions.c            |    2 +-
 extensions/exiv2_tools/exiv2-utils.cpp             |   12 +-
 extensions/facebook/facebook-album.c               |   10 +-
 extensions/facebook/facebook-photo.c               |   12 +-
 extensions/facebook/facebook-service.c             |    7 +-
 extensions/file_manager/actions.c                  |    2 +-
 extensions/file_manager/gth-duplicate-task.c       |   26 +-
 extensions/file_tools/gth-file-tool-crop.c         |    8 +-
 extensions/file_tools/gth-file-tool-curves.c       |    4 +-
 extensions/file_tools/gth-file-tool-resize.c       |   48 +-
 extensions/flicker_utils/flickr-account.c          |    2 +-
 extensions/flicker_utils/flickr-photo.c            |   18 +-
 extensions/flicker_utils/flickr-photoset.c         |   16 +-
 extensions/gstreamer_tools/actions.c               |    2 +-
 extensions/gstreamer_tools/gth-media-viewer-page.c |    4 +-
 extensions/image_print/gth-image-print-job.c       |    6 +-
 extensions/image_viewer/gth-image-viewer-page.c    |    6 +-
 extensions/list_tools/gth-script.c                 |   16 +-
 extensions/oauth/oauth-account.c                   |   18 +-
 extensions/oauth/oauth-service.c                   |    6 +-
 extensions/oauth/web-service.c                     |    6 +-
 extensions/photo_importer/actions.c                |    2 +-
 extensions/photo_importer/dlg-photo-importer.c     |    2 +-
 extensions/picasaweb/picasa-web-album.c            |   16 +-
 extensions/picasaweb/picasa-web-photo.c            |   26 +-
 extensions/picasaweb/picasa-web-service.c          |   18 +-
 extensions/rename_series/dlg-rename-series.c       |    6 +-
 extensions/rename_series/gth-rename-task.c         |    2 +-
 extensions/search/gth-search-source-selector.c     |    2 +-
 extensions/selections/actions.c                    |    2 +-
 extensions/selections/gth-file-source-selections.c |   19 +-
 extensions/webalbums/dlg-web-exporter.c            |    2 +-
 extensions/webalbums/gth-web-exporter.c            |  118 +-
 gthumb/dlg-preferences-general.c                   |    2 +-
 gthumb/gio-utils.c                                 |  643 +------
 gthumb/gio-utils.h                                 |  326 ++--
 gthumb/glib-utils.c                                | 1810 +++-----------------
 gthumb/glib-utils.h                                |  496 +++---
 gthumb/gth-application.c                           |    2 +-
 gthumb/gth-browser.c                               |   20 +-
 gthumb/gth-color-scale.c                           |    3 +-
 gthumb/gth-delete-task.c                           |   12 +-
 gthumb/gth-extensions.c                            |    2 +-
 gthumb/gth-file-chooser-dialog.c                   |   12 +-
 gthumb/gth-file-data.c                             |   12 +-
 gthumb/gth-file-list.c                             |    4 +-
 gthumb/gth-file-properties.c                       |    2 +-
 gthumb/gth-file-source-vfs.c                       |   47 +-
 gthumb/gth-file-source.c                           |   11 +-
 gthumb/gth-filter-grid.c                           |    6 +-
 gthumb/gth-filter.c                                |    4 +-
 gthumb/gth-grid-view.c                             |   10 +-
 gthumb/gth-image-list-task.c                       |    2 +-
 gthumb/gth-image-viewer.c                          |   16 +-
 gthumb/gth-location-chooser-dialog.c               |    2 +-
 gthumb/gth-location-chooser.c                      |    2 +-
 gthumb/gth-main-default-hooks.c                    |    2 +-
 gthumb/gth-main.c                                  |    2 +-
 gthumb/gth-metadata-provider-file.c                |    2 +-
 gthumb/gth-metadata-provider.c                     |   19 +-
 gthumb/gth-metadata.c                              |   10 +-
 gthumb/gth-preferences.c                           |    4 +-
 gthumb/gth-thumb-loader.c                          |    2 +-
 gthumb/gth-time-selector.c                         |    2 +-
 gthumb/gth-time.c                                  |    2 +-
 gthumb/gth-trash-task.c                            |    8 +-
 gthumb/gth-uri-list.c                              |   14 +-
 gthumb/main-migrate-catalogs.c                     |    4 +-
 gthumb/meson.build                                 |    6 +-
 gthumb/str-utils.c                                 |  974 +++++++++++
 gthumb/str-utils.h                                 |  100 ++
 gthumb/test-glib-utils.c                           |  864 +++++++++-
 gthumb/uri-utils.c                                 | 1122 ++++++++++++
 gthumb/uri-utils.h                                 |   89 +
 82 files changed, 4276 insertions(+), 3027 deletions(-)
---
diff --git a/extensions/burn_disc/gth-burn-task.c b/extensions/burn_disc/gth-burn-task.c
index c4ec5638..a28c555a 100644
--- a/extensions/burn_disc/gth-burn-task.c
+++ b/extensions/burn_disc/gth-burn-task.c
@@ -122,13 +122,17 @@ add_file_to_track (GthBurnTask *task,
                        if ((strcmp (subfolder, "") != 0) && g_hash_table_lookup (task->priv->parents, 
subfolder) == NULL) {
                                GtkTreePath *subfolder_parent_tpath;
                                GtkTreePath *subfolder_tpath;
+                               char        *basename;
 
                                if (subfolder_parent != NULL)
                                        subfolder_parent_tpath = g_hash_table_lookup (task->priv->parents, 
subfolder_parent);
                                else
                                        subfolder_parent_tpath = NULL;
-                               subfolder_tpath = brasero_track_data_cfg_add_empty_directory 
(task->priv->track, _g_uri_get_basename (subfolder), subfolder_parent_tpath);
+                               basename = _g_uri_get_basename (subfolder);
+                               subfolder_tpath = brasero_track_data_cfg_add_empty_directory 
(task->priv->track, basename, subfolder_parent_tpath);
                                g_hash_table_insert (task->priv->parents, g_strdup (subfolder), 
subfolder_tpath);
+
+                               g_free (basename);
                        }
 
                        g_free (subfolder_parent);
@@ -325,7 +329,7 @@ start_dir_func (GFile      *directory,
        g_free (task->priv->current_directory);
 
        parent = g_file_get_parent (directory);
-       escaped = _g_replace (g_file_info_get_display_name (info), "/", "-");
+       escaped = _g_utf8_replace_str (g_file_info_get_display_name (info), "/", "-");
        destination = g_file_get_child_for_display_name (parent, escaped, NULL);
        uri = g_file_get_uri (destination);
        task->priv->current_directory = g_uri_unescape_string (uri, NULL);
diff --git a/extensions/catalogs/dlg-catalog-properties.c b/extensions/catalogs/dlg-catalog-properties.c
index 1622b1d2..28ba05a1 100644
--- a/extensions/catalogs/dlg-catalog-properties.c
+++ b/extensions/catalogs/dlg-catalog-properties.c
@@ -96,19 +96,22 @@ save_button_clicked_cb (GtkButton  *button,
                GFile *parent;
                char  *uri;
                char  *clean_name;
+               char  *ext;
                char  *display_name;
                GFile *new_file;
 
                parent = g_file_get_parent (data->original_file);
                uri = g_file_get_uri (data->original_file);
                clean_name = _g_filename_clear_for_file (gtk_entry_get_text (GTK_ENTRY (GET_WIDGET 
("name_entry"))));
-               display_name = g_strconcat (clean_name, _g_uri_get_file_extension (uri), NULL);
+               ext = _g_uri_get_extension (uri);
+               display_name = g_strconcat (clean_name, ext, NULL);
                new_file = g_file_get_child_for_display_name (parent, display_name, NULL);
                if ((new_file != NULL) && ! g_file_equal (new_file, data->original_file))
                        gth_file_data_set_file (data->file_data, new_file);
 
                _g_object_unref (new_file);
                g_free (display_name);
+               g_free (ext);
                g_free (clean_name);
                g_free (uri);
                g_object_unref (parent);
@@ -164,7 +167,7 @@ catalog_ready_cb (GObject  *object,
                char *utf8_name;
 
                basename = g_file_get_basename (data->file_data->file);
-               name = _g_uri_remove_extension (basename);
+               name = _g_path_remove_extension (basename);
                utf8_name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
                gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("name_entry")), utf8_name);
 
diff --git a/extensions/catalogs/gth-catalog.c b/extensions/catalogs/gth-catalog.c
index 85ae38c1..b99a125e 100644
--- a/extensions/catalogs/gth-catalog.c
+++ b/extensions/catalogs/gth-catalog.c
@@ -622,7 +622,7 @@ get_display_name (GFile       *file,
                        char *name;
                        char *utf8_name;
 
-                       name = _g_uri_remove_extension (basename);
+                       name = _g_path_remove_extension (basename);
                        utf8_name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
                        g_string_append (display_name, utf8_name);
 
@@ -673,7 +673,7 @@ get_edit_name (GFile       *file,
                        char *name;
                        char *utf8_name;
 
-                       name = _g_uri_remove_extension (basename);
+                       name = _g_path_remove_extension (basename);
                        utf8_name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
                        g_string_append (display_name, utf8_name);
 
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index 85d12cf7..aa45a021 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -435,6 +435,7 @@ gth_file_source_catalogs_rename (GthFileSource *file_source,
        if (catalog != NULL) {
                char  *uri;
                char  *clean_name;
+               char  *ext;
                char  *name;
                GFile *gio_new_file;
                char  *data;
@@ -443,7 +444,8 @@ gth_file_source_catalogs_rename (GthFileSource *file_source,
 
                uri = g_file_get_uri (file);
                clean_name = _g_filename_clear_for_file (edit_name);
-               name = g_strconcat (clean_name, _g_uri_get_file_extension (uri), NULL);
+               ext = _g_uri_get_extension (uri);
+               name = g_strconcat (clean_name, ext, NULL);
                new_file = g_file_get_child_for_display_name (parent, name, &error);
                gth_catalog_set_file (catalog, new_file);
                gth_catalog_set_name (catalog, edit_name);
@@ -477,6 +479,7 @@ gth_file_source_catalogs_rename (GthFileSource *file_source,
                g_free (data);
                g_object_unref (gio_new_file);
                g_free (clean_name);
+               g_free (ext);
                g_free (name);
                g_free (uri);
        }
@@ -682,7 +685,7 @@ for_each_child__visit_file (ForEachChildData *data,
                                        data);
        }
        else
-               g_directory_foreach_child (gio_file,
+               _g_directory_foreach_child (gio_file,
                                           FALSE,
                                           TRUE,
                                           GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE,
@@ -944,13 +947,13 @@ copy_catalog_ready_cb (GError   *error,
        first_file = ccd->file_list->data;
 
        if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
-               char       *uri;
-               const char *extension;
-               char       *msg;
-               GtkWidget  *d;
+               char      *uri;
+               char      *extension;
+               char      *msg;
+               GtkWidget *d;
 
                uri = g_file_get_uri (first_file);
-               extension = _g_uri_get_file_extension (uri);
+               extension = _g_uri_get_extension (uri);
                if ((g_strcmp0 (extension, ".catalog") == 0) || (g_strcmp0 (extension, ".search") == 0))
                        msg = g_strdup_printf (_("The catalog “%s” already exists, do you want to overwrite 
it?"), g_file_info_get_display_name (ccd->destination->info));
                else
@@ -972,6 +975,7 @@ copy_catalog_ready_cb (GError   *error,
                gtk_widget_show (d);
 
                g_free (msg);
+               g_free (extension);
                g_free (uri);
 
                return;
@@ -1020,19 +1024,19 @@ _gth_file_source_catalogs_copy_catalog (CopyCatalogData      *ccd,
        gio_list = gth_file_source_to_gio_file_list (ccd->file_source, ccd->file_list);
        gio_destination = gth_file_source_to_gio_file (ccd->file_source, ccd->destination->file);
 
-       _g_copy_files_async (gio_list,
-                            gio_destination,
-                            ccd->move,
-                            GTH_FILE_COPY_DEFAULT,
-                            default_response,
-                            G_PRIORITY_DEFAULT,
-                            gth_file_source_get_cancellable (ccd->file_source),
-                            ccd->progress_callback,
-                            ccd->user_data,
-                            ccd->dialog_callback,
-                            ccd->user_data,
-                            copy_catalog_ready_cb,
-                            ccd);
+       _g_file_list_copy_async (gio_list,
+                                gio_destination,
+                                ccd->move,
+                                GTH_FILE_COPY_DEFAULT,
+                                default_response,
+                                G_PRIORITY_DEFAULT,
+                                gth_file_source_get_cancellable (ccd->file_source),
+                                ccd->progress_callback,
+                                ccd->user_data,
+                                ccd->dialog_callback,
+                                ccd->user_data,
+                                copy_catalog_ready_cb,
+                                ccd);
 
        g_object_unref (gio_destination);
        _g_object_list_unref (gio_list);
@@ -1140,12 +1144,12 @@ gth_file_source_catalogs_copy (GthFileSource    *file_source,
                        g_free (message);
                }
 
-               _g_query_info_async (cod->file_list,
-                                    GTH_LIST_DEFAULT,
-                                    GFILE_NAME_TYPE_ATTRIBUTES,
-                                    gth_file_source_get_cancellable (file_source),
-                                    copy__file_list_info_ready_cb,
-                                    cod);
+               _g_file_list_query_info_async (cod->file_list,
+                                              GTH_LIST_DEFAULT,
+                                              GFILE_NAME_TYPE_ATTRIBUTES,
+                                              gth_file_source_get_cancellable (file_source),
+                                              copy__file_list_info_ready_cb,
+                                              cod);
        }
 }
 
@@ -1453,50 +1457,54 @@ gth_file_source_catalogs_get_drop_actions (GthFileSource *file_source,
        GdkDragAction  actions = 0;
        char          *dest_uri;
        char          *dest_scheme;
-       const char    *dest_ext;
+       char          *dest_ext;
        gboolean       dest_is_catalog;
        char          *file_uri;
        char          *file_scheme;
-       const char    *file_ext;
+       char          *file_ext;
        gboolean       file_is_catalog;
 
        dest_uri = g_file_get_uri (destination);
        dest_scheme = _g_uri_get_scheme (dest_uri);
-       dest_ext = _g_uri_get_file_extension (dest_uri);
-       dest_is_catalog = (g_strcmp0 (dest_ext, ".catalog") == 0) || (g_strcmp0 (dest_ext, ".search") == 0);
+       dest_ext = _g_uri_get_extension (dest_uri);
+       dest_is_catalog = _g_str_equal (dest_ext, ".catalog") || _g_str_equal (dest_ext, ".search");
 
        file_uri = g_file_get_uri (file);
        file_scheme = _g_uri_get_scheme (file_uri);
-       file_ext = _g_uri_get_file_extension (file_uri);
-       file_is_catalog = (g_strcmp0 (file_ext, ".catalog") == 0) || (g_strcmp0 (file_ext, ".search") == 0);
+       file_ext = _g_uri_get_extension (file_uri);
+       file_is_catalog = _g_str_equal (file_ext, ".catalog") || _g_str_equal (file_ext, ".search");
 
-       if ((g_strcmp0 (dest_scheme, "catalog://") == 0)
+       if (_g_str_equal (dest_scheme, "catalog")
                && dest_is_catalog
-               && (g_strcmp0 (file_scheme, "file://") == 0))
+               && _g_str_equal (file_scheme, "file"))
        {
                /* Copy files into a catalog. */
                actions = GDK_ACTION_COPY;
        }
 
-       else if ((g_strcmp0 (file_scheme, "catalog://") == 0)
+       else if (_g_str_equal (file_scheme, "catalog")
                && file_is_catalog
-               && (g_strcmp0 (dest_scheme, "catalog://") == 0)
+               && _g_str_equal (dest_scheme, "catalog")
                && ! dest_is_catalog)
        {
                /* Move a catalog into a library. */
                actions = GDK_ACTION_MOVE;
        }
 
-       else if ((g_strcmp0 (file_scheme, "catalog://") == 0)
+       else if (_g_str_equal (file_scheme, "catalog")
                && ! file_is_catalog
-               && (g_strcmp0 (dest_scheme, "catalog://") == 0)
+               && _g_str_equal (dest_scheme, "catalog")
                && ! dest_is_catalog)
        {
                /* Move a library into another library. */
                actions = GDK_ACTION_MOVE;
        }
 
+       g_free (file_ext);
+       g_free (file_scheme);
        g_free (file_uri);
+       g_free (dest_ext);
+       g_free (dest_scheme);
        g_free (dest_uri);
 
        return actions;
diff --git a/extensions/catalogs/gth-organize-task.c b/extensions/catalogs/gth-organize-task.c
index d91595dc..263797c6 100644
--- a/extensions/catalogs/gth-organize-task.c
+++ b/extensions/catalogs/gth-organize-task.c
@@ -571,7 +571,7 @@ gth_organize_task_exec (GthTask *base)
                break;
        }
 
-       g_directory_foreach_child (self->priv->folder,
+       _g_directory_foreach_child (self->priv->folder,
                                   self->priv->recursive,
                                   TRUE,
                                   attributes,
@@ -738,12 +738,12 @@ organization_treeview_selection_changed_cb (GtkTreeSelection *treeselection,
                gtk_widget_show (GET_WIDGET ("preview_box"));
 
                file_list = gth_catalog_get_file_list (catalog);
-               _g_query_info_async (file_list,
-                                    GTH_LIST_DEFAULT,
-                                    GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE,
-                                    NULL,
-                                    file_list_info_ready_cb,
-                                    self);
+               _g_file_list_query_info_async (file_list,
+                                              GTH_LIST_DEFAULT,
+                                              GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE,
+                                              NULL,
+                                              file_list_info_ready_cb,
+                                              self);
        }
 
        g_free (key);
diff --git a/extensions/contact_sheet/dlg-contact-sheet.c b/extensions/contact_sheet/dlg-contact-sheet.c
index c284c9e6..3752214a 100644
--- a/extensions/contact_sheet/dlg-contact-sheet.c
+++ b/extensions/contact_sheet/dlg-contact-sheet.c
@@ -333,7 +333,7 @@ add_themes_from_dir (DialogData *data,
                        continue;
                }
 
-               if (g_strcmp0 (_g_uri_get_file_extension (g_file_info_get_name (file_info)), ".cst") != 0) {
+               if (g_strcmp0 (_g_uri_get_extension (g_file_info_get_name (file_info)), ".cst") != 0) {
                        g_object_unref (file_info);
                        continue;
                }
@@ -743,7 +743,7 @@ dlg_contact_sheet (GthBrowser *browser,
        else
                s_value = _g_settings_get_uri (data->settings, PREF_CONTACT_SHEET_DESTINATION);
        if (s_value == NULL)
-               s_value = g_strdup (get_home_uri ());
+               s_value = g_strdup (_g_uri_get_home ());
        gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), s_value);
        g_free (s_value);
 
diff --git a/extensions/contact_sheet/dlg-image-wall.c b/extensions/contact_sheet/dlg-image-wall.c
index 67634af4..9a397e8a 100644
--- a/extensions/contact_sheet/dlg-image-wall.c
+++ b/extensions/contact_sheet/dlg-image-wall.c
@@ -265,7 +265,7 @@ dlg_image_wall (GthBrowser *browser,
        else
                s_value = _g_settings_get_uri (data->settings, PREF_IMAGE_WALL_DESTINATION);
        if (s_value == NULL)
-               s_value = g_strdup (get_home_uri ());
+               s_value = g_strdup (_g_uri_get_home ());
        gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), s_value);
        g_free (s_value);
 
diff --git a/extensions/contact_sheet/gth-contact-sheet-creator.c 
b/extensions/contact_sheet/gth-contact-sheet-creator.c
index c3824c97..980177b0 100644
--- a/extensions/contact_sheet/gth-contact-sheet-creator.c
+++ b/extensions/contact_sheet/gth-contact-sheet-creator.c
@@ -231,6 +231,47 @@ get_page_height (GthContactSheetCreator *self,
 }
 
 
+static char *
+_g_get_name_from_template (char **utf8_template,
+                          int    n)
+{
+       GString *s;
+       int      i;
+       char    *result;
+
+       s = g_string_new (NULL);
+
+       for (i = 0; utf8_template[i] != NULL; i++) {
+               const char *chunk = utf8_template[i];
+               gunichar    ch = g_utf8_get_char (chunk);
+
+               if (ch != '#')
+                       g_string_append (s, chunk);
+               else {
+                       char *s_n;
+                       int   s_n_len;
+                       int   sharps_len = g_utf8_strlen (chunk, -1);
+
+                       s_n = g_strdup_printf ("%d", n);
+                       s_n_len = strlen (s_n);
+
+                       while (s_n_len < sharps_len) {
+                               g_string_append_c (s, '0');
+                               sharps_len--;
+                       }
+
+                       g_string_append (s, s_n);
+                       g_free (s_n);
+               }
+       }
+
+       result = s->str;
+       g_string_free (s, FALSE);
+
+       return result;
+}
+
+
 static void
 begin_page (GthContactSheetCreator *self,
            int                     page_n)
@@ -559,7 +600,6 @@ paint_frame (GthContactSheetCreator *self,
        if (self->priv->imagemap_stream != NULL) {
                char   *file;
                char   *destination;
-               char   *relative_uri;
                char   *relative_path;
                char   *alt_attribute;
                char   *line;
@@ -567,9 +607,8 @@ paint_frame (GthContactSheetCreator *self,
 
                file = g_file_get_uri (file_data->file);
                destination = g_file_get_uri (self->priv->destination);
-               relative_uri = _g_uri_get_relative_path (file, destination);
-               relative_path = g_uri_unescape_string (relative_uri, "");
-               alt_attribute = _g_escape_for_html (relative_path, -1);
+               relative_path = _g_uri_get_relative_path (file, destination);
+               alt_attribute = _g_utf8_escape_xml (relative_path);
 
                line = g_strdup_printf ("      <area shape=\"rect\" coords=\"%d,%d,%d,%d\" href=\"%s\" 
alt=\"%s\" />\n",
                                        frame_rect->x,
@@ -586,7 +625,6 @@ paint_frame (GthContactSheetCreator *self,
                g_free (line);
                g_free (alt_attribute);
                g_free (relative_path);
-               g_free (relative_uri);
                g_free (destination);
                g_free (file);
        }
@@ -1127,7 +1165,7 @@ void
 gth_contact_sheet_creator_set_header (GthContactSheetCreator *self,
                                      const char             *value)
 {
-       _g_strset (&self->priv->header, value);
+       _g_str_set (&self->priv->header, value);
 }
 
 
@@ -1135,7 +1173,7 @@ void
 gth_contact_sheet_creator_set_footer (GthContactSheetCreator *self,
                                      const char             *value)
 {
-       _g_strset (&self->priv->footer, value);
+       _g_str_set (&self->priv->footer, value);
 }
 
 
@@ -1152,10 +1190,10 @@ void
 gth_contact_sheet_creator_set_filename_template (GthContactSheetCreator *self,
                                                 const char             *filename_template)
 {
-       _g_strset (&self->priv->template, filename_template);
+       _g_str_set (&self->priv->template, filename_template);
        if (self->priv->template_v != NULL)
                g_strfreev (self->priv->template_v);
-       self->priv->template_v = _g_get_template_from_text (self->priv->template);
+       self->priv->template_v = _g_utf8_split_template (self->priv->template);
 }
 
 
@@ -1164,8 +1202,8 @@ gth_contact_sheet_creator_set_mime_type (GthContactSheetCreator *self,
                                         const char             *mime_type,
                                         const char             *file_extension)
 {
-       _g_strset (&self->priv->mime_type, mime_type);
-       _g_strset (&self->priv->file_extension, file_extension);
+       _g_str_set (&self->priv->mime_type, mime_type);
+       _g_str_set (&self->priv->file_extension, file_extension);
 }
 
 
@@ -1249,6 +1287,6 @@ void
 gth_contact_sheet_creator_set_thumbnail_caption (GthContactSheetCreator *self,
                                                 const char             *caption)
 {
-       _g_strset (&self->priv->thumbnail_caption, caption);
+       _g_str_set (&self->priv->thumbnail_caption, caption);
        self->priv->thumbnail_caption_v = g_strsplit (self->priv->thumbnail_caption, ",", -1);
 }
diff --git a/extensions/desktop_background/actions.c b/extensions/desktop_background/actions.c
index e991fcea..e0ac853a 100644
--- a/extensions/desktop_background/actions.c
+++ b/extensions/desktop_background/actions.c
@@ -212,7 +212,7 @@ get_new_wallpaper_file_async (GCancellable        *cancellable,
        task = g_task_new (NULL, cancellable, callback, user_data);
        g_task_set_task_data (task, nw_data, (GDestroyNotify) new_wallpaper_data_free);
 
-       g_directory_foreach_child (nw_data->folder,
+       _g_directory_foreach_child (nw_data->folder,
                                   FALSE,
                                   FALSE,
                                   GFILE_NAME_TYPE_ATTRIBUTES,
diff --git a/extensions/exiv2_tools/exiv2-utils.cpp b/extensions/exiv2_tools/exiv2-utils.cpp
index aeb927d3..ddab1918 100644
--- a/extensions/exiv2_tools/exiv2-utils.cpp
+++ b/extensions/exiv2_tools/exiv2-utils.cpp
@@ -216,14 +216,14 @@ const char *stupid_comment_filter[] = {
 inline static char *
 exiv2_key_from_attribute (const char *attribute)
 {
-       return _g_replace (attribute, "::", ".");
+       return _g_utf8_replace_str (attribute, "::", ".");
 }
 
 
 inline static char *
 exiv2_key_to_attribute (const char *key)
 {
-       return _g_replace (key, ".", "::");
+       return _g_utf8_replace_str (key, ".", "::");
 }
 
 
@@ -274,11 +274,11 @@ create_metadata (const char *key,
                        formatted_value_utf8 = g_locale_to_utf8 (formatted_value, -1, NULL, NULL, NULL);
        }
        else if (_g_utf8_has_prefix (formatted_value_utf8, "lang=")) {
-               int   pos;
-               char *formatted_clean;
+               const char *after_space;
+               char       *formatted_clean;
 
-               pos = _g_utf8_first_ascii_space (formatted_value_utf8);
-               formatted_clean = _g_utf8_remove_prefix (formatted_value_utf8, pos + 1);
+               after_space = _g_utf8_after_ascii_space (formatted_value_utf8);
+               formatted_clean = g_strdup (after_space);
                g_free (formatted_value_utf8);
                formatted_value_utf8 = formatted_clean;
        }
diff --git a/extensions/facebook/facebook-album.c b/extensions/facebook/facebook-album.c
index 9d54b87d..2206fc05 100644
--- a/extensions/facebook/facebook-album.c
+++ b/extensions/facebook/facebook-album.c
@@ -70,19 +70,19 @@ facebook_album_set_property (GObject      *object,
 
        switch (property_id) {
        case PROP_ID:
-               _g_strset (&self->id, g_value_get_string (value));
+               _g_str_set (&self->id, g_value_get_string (value));
                break;
        case PROP_NAME:
-               _g_strset (&self->name, g_value_get_string (value));
+               _g_str_set (&self->name, g_value_get_string (value));
                break;
        case PROP_DESCRIPTION:
-               _g_strset (&self->description, g_value_get_string (value));
+               _g_str_set (&self->description, g_value_get_string (value));
                break;
        case PROP_LINK:
-               _g_strset (&self->link, g_value_get_string (value));
+               _g_str_set (&self->link, g_value_get_string (value));
                break;
        case PROP_PRIVACY:
-               _g_strset (&self->privacy, g_value_get_string (value));
+               _g_str_set (&self->privacy, g_value_get_string (value));
                break;
        case PROP_COUNT:
                self->count = g_value_get_int (value);
diff --git a/extensions/facebook/facebook-photo.c b/extensions/facebook/facebook-photo.c
index 760faa0e..8ac72f41 100644
--- a/extensions/facebook/facebook-photo.c
+++ b/extensions/facebook/facebook-photo.c
@@ -74,7 +74,7 @@ facebook_image_copy (FacebookImage *source)
        FacebookImage *dest;
 
        dest = facebook_image_new ();
-       _g_strset (&dest->source, source->source);
+       _g_str_set (&dest->source, source->source);
        dest->width = source->width;
        dest->height = source->height;
 
@@ -131,13 +131,13 @@ facebook_photo_set_property (GObject      *object,
 
        switch (property_id) {
        case PROP_ID:
-               _g_strset (&self->id, g_value_get_string (value));
+               _g_str_set (&self->id, g_value_get_string (value));
                break;
        case PROP_PICTURE:
-               _g_strset (&self->picture, g_value_get_string (value));
+               _g_str_set (&self->picture, g_value_get_string (value));
                break;
        case PROP_SOURCE:
-               _g_strset (&self->source, g_value_get_string (value));
+               _g_str_set (&self->source, g_value_get_string (value));
                break;
        case PROP_WIDTH:
                self->width = g_value_get_int (value);
@@ -146,7 +146,7 @@ facebook_photo_set_property (GObject      *object,
                self->height = g_value_get_int (value);
                break;
        case PROP_LINK:
-               _g_strset (&self->link, g_value_get_string (value));
+               _g_str_set (&self->link, g_value_get_string (value));
                break;
        case PROP_CREATED_TIME:
                gth_datetime_free (self->created_time);
@@ -353,7 +353,7 @@ facebook_photo_deserialize_property (JsonSerializable *serializable,
                                FacebookImage *image;
 
                                image = facebook_image_new ();
-                               _g_strset (&image->source, json_object_get_string_member (image_obj, 
"source"));
+                               _g_str_set (&image->source, json_object_get_string_member (image_obj, 
"source"));
                                image->width = json_object_get_int_member (image_obj, "width");
                                image->height = json_object_get_int_member (image_obj, "height");
 
diff --git a/extensions/facebook/facebook-service.c b/extensions/facebook/facebook-service.c
index d141a6e7..b5df7b94 100644
--- a/extensions/facebook/facebook-service.c
+++ b/extensions/facebook/facebook-service.c
@@ -111,7 +111,7 @@ static void
 _facebook_service_set_access_token (FacebookService *self,
                                    const char      *token)
 {
-       _g_strset (&self->priv->token, token);
+       _g_str_set (&self->priv->token, token);
 }
 
 
@@ -753,6 +753,7 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
        GthFileData     *file_data;
        SoupMultipart   *multipart;
        char            *uri;
+       char            *basename;
        SoupBuffer      *body;
        SoupMessage     *msg;
 
@@ -858,14 +859,16 @@ upload_photo_file_buffer_ready_cb (void     **buffer,
        }
 
        uri = g_file_get_uri (file_data->file);
+       basename = _g_uri_get_basename (uri);
        body = soup_buffer_new (SOUP_MEMORY_TEMPORARY, *buffer, count);
        soup_multipart_append_form_file (multipart,
                                         "source",
-                                        _g_uri_get_basename (uri),
+                                        basename,
                                         gth_file_data_get_mime_type (file_data),
                                         body);
 
        soup_buffer_free (body);
+       g_free (basename);
        g_free (uri);
 
        /* send the file */
diff --git a/extensions/file_manager/actions.c b/extensions/file_manager/actions.c
index fbf8778b..d5258008 100644
--- a/extensions/file_manager/actions.c
+++ b/extensions/file_manager/actions.c
@@ -748,7 +748,7 @@ copy_to_folder_dialog (GthBrowser *browser,
        start_uri = g_settings_get_string (settings, PREF_FILE_MANAGER_COPY_LAST_FOLDER);
        if ((start_uri == NULL) || (strcmp (start_uri, "") == 0)) {
                g_free (start_uri);
-               start_uri = g_strdup (get_home_uri ());
+               start_uri = g_strdup (_g_uri_get_home ());
        }
        gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (dialog), start_uri);
        g_free(start_uri);
diff --git a/extensions/file_manager/gth-duplicate-task.c b/extensions/file_manager/gth-duplicate-task.c
index 3853b178..63ff23bd 100644
--- a/extensions/file_manager/gth-duplicate-task.c
+++ b/extensions/file_manager/gth-duplicate-task.c
@@ -122,19 +122,19 @@ duplicate_current_file (GthDuplicateTask *self)
                g_object_unref (tmp);
        }
 
-       _g_copy_file_async (file_data,
-                           self->priv->destination,
-                           FALSE,
-                           GTH_FILE_COPY_ALL_METADATA,
-                           GTH_OVERWRITE_RESPONSE_ALWAYS_NO,
-                           G_PRIORITY_DEFAULT,
-                           gth_task_get_cancellable (GTH_TASK (self)),
-                           copy_progress_cb,
-                           self,
-                           copy_dialog_cb,
-                           self,
-                           copy_ready_cb,
-                           self);
+       _gth_file_data_copy_async (file_data,
+                                  self->priv->destination,
+                                  FALSE,
+                                  GTH_FILE_COPY_ALL_METADATA,
+                                  GTH_OVERWRITE_RESPONSE_ALWAYS_NO,
+                                  G_PRIORITY_DEFAULT,
+                                  gth_task_get_cancellable (GTH_TASK (self)),
+                                  copy_progress_cb,
+                                  self,
+                                  copy_dialog_cb,
+                                  self,
+                                  copy_ready_cb,
+                                  self);
 }
 
 
diff --git a/extensions/file_tools/gth-file-tool-crop.c b/extensions/file_tools/gth-file-tool-crop.c
index 2a5457e0..160f8adf 100644
--- a/extensions/file_tools/gth-file-tool-crop.c
+++ b/extensions/file_tools/gth-file-tool-crop.c
@@ -149,10 +149,10 @@ set_spin_range_value (GthFileToolCrop *self,
                      int              max,
                      int              x)
 {
-       g_signal_handlers_block_by_data (G_OBJECT (spin), self);
+       _g_signal_handlers_block_by_data (G_OBJECT (spin), self);
        gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), min, max);
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), x);
-       g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
+       _g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
 }
 
 
@@ -190,9 +190,9 @@ set_spin_value (GthFileToolCrop *self,
                GtkWidget       *spin,
                int              x)
 {
-       g_signal_handlers_block_by_data (G_OBJECT (spin), self);
+       _g_signal_handlers_block_by_data (G_OBJECT (spin), self);
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), x);
-       g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
+       _g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
 }
 
 
diff --git a/extensions/file_tools/gth-file-tool-curves.c b/extensions/file_tools/gth-file-tool-curves.c
index a35b48b6..ff329d8e 100644
--- a/extensions/file_tools/gth-file-tool-curves.c
+++ b/extensions/file_tools/gth-file-tool-curves.c
@@ -452,9 +452,9 @@ _gth_file_tool_curves_set_view_original (GthFileToolCurves *self,
 {
        self->priv->view_original = view_original;
 
-       g_signal_handlers_block_by_data (self->priv->preview_button, self);
+       _g_signal_handlers_block_by_data (self->priv->preview_button, self);
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->preview_button), ! 
self->priv->view_original);
-       g_signal_handlers_unblock_by_data (self->priv->preview_button, self);
+       _g_signal_handlers_unblock_by_data (self->priv->preview_button, self);
 
        gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (self->priv->preview_channel_button), 
self->priv->view_original);
        gtk_widget_set_sensitive (self->priv->preview_channel_button, ! self->priv->view_original);
diff --git a/extensions/file_tools/gth-file-tool-resize.c b/extensions/file_tools/gth-file-tool-resize.c
index 12b326b4..b7478ebd 100644
--- a/extensions/file_tools/gth-file-tool-resize.c
+++ b/extensions/file_tools/gth-file-tool-resize.c
@@ -222,13 +222,13 @@ selection_width_value_changed_cb (GtkSpinButton     *spin,
                self->priv->new_width = MAX ((int) round ((gtk_spin_button_get_value (spin) / 100.0) * 
self->priv->original_width), 1);
 
        if (self->priv->fixed_aspect_ratio) {
-               g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+               _g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
                self->priv->new_height = MAX ((int) round ((double) self->priv->new_width / 
self->priv->aspect_ratio), 1);
                if (self->priv->unit == GTH_UNIT_PIXELS)
                        gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 
self->priv->new_height);
                else if (self->priv->unit == GTH_UNIT_PERCENTAGE)
                        gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 
((double) self->priv->new_height) / self->priv->original_height * 100.0);
-               g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+               _g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
        }
 
        update_image_size (self);
@@ -245,13 +245,13 @@ selection_height_value_changed_cb (GtkSpinButton     *spin,
                self->priv->new_height = MAX ((int) round ((gtk_spin_button_get_value (spin) / 100.0) * 
self->priv->original_height), 1);
 
        if (self->priv->fixed_aspect_ratio) {
-               g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+               _g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
                self->priv->new_width = MAX ((int) round ((double) self->priv->new_height * 
self->priv->aspect_ratio), 1);
                if (self->priv->unit == GTH_UNIT_PIXELS)
                        gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 
self->priv->new_width);
                else if (self->priv->unit == GTH_UNIT_PERCENTAGE)
                        gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 
((double) self->priv->new_width) / self->priv->original_width * 100.0);
-               g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+               _g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
        }
 
        update_image_size (self);
@@ -270,8 +270,8 @@ high_quality_checkbutton_toggled_cb (GtkToggleButton   *button,
 static void
 update_size_spin_buttons_from_unit_value (GthFileToolResize *self)
 {
-       g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
-       g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
 
        if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
                double p;
@@ -291,8 +291,8 @@ update_size_spin_buttons_from_unit_value (GthFileToolResize *self)
                gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 
self->priv->new_height);
        }
 
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
 }
 
 
@@ -312,9 +312,9 @@ set_spin_value (GthFileToolResize *self,
                GtkWidget         *spin,
                int                x)
 {
-       g_signal_handlers_block_by_data (G_OBJECT (spin), self);
+       _g_signal_handlers_block_by_data (G_OBJECT (spin), self);
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), x);
-       g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
+       _g_signal_handlers_unblock_by_data (G_OBJECT (spin), self);
 }
 
 
@@ -450,13 +450,13 @@ set_image_size (GthFileToolResize *self,
 
        update_size_spin_buttons_from_unit_value (self);
 
-       g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
-       g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
-       g_signal_handlers_block_by_data (GET_WIDGET ("unit_combobox"), self);
-       g_signal_handlers_block_by_data (self->priv->ratio_combobox, self);
-       g_signal_handlers_block_by_data (GET_WIDGET ("invert_ratio_checkbutton"), self);
-       g_signal_handlers_block_by_data (GET_WIDGET ("ratio_w_spinbutton"), self);
-       g_signal_handlers_block_by_data (GET_WIDGET ("ratio_h_spinbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("unit_combobox"), self);
+       _g_signal_handlers_block_by_data (self->priv->ratio_combobox, self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("invert_ratio_checkbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("ratio_w_spinbutton"), self);
+       _g_signal_handlers_block_by_data (GET_WIDGET ("ratio_h_spinbutton"), self);
 
        gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")), PIXELS_UNIT_POSITION);
        gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->ratio_combobox), ratio);
@@ -466,13 +466,13 @@ set_image_size (GthFileToolResize *self,
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_w_spinbutton")), w);
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_h_spinbutton")), h);
 
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("unit_combobox"), self);
-       g_signal_handlers_unblock_by_data (self->priv->ratio_combobox, self);
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("invert_ratio_checkbutton"), self);
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("ratio_w_spinbutton"), self);
-       g_signal_handlers_unblock_by_data (GET_WIDGET ("ratio_h_spinbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_width_spinbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("resize_height_spinbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("unit_combobox"), self);
+       _g_signal_handlers_unblock_by_data (self->priv->ratio_combobox, self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("invert_ratio_checkbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("ratio_w_spinbutton"), self);
+       _g_signal_handlers_unblock_by_data (GET_WIDGET ("ratio_h_spinbutton"), self);
 
        update_image_size (self);
 }
diff --git a/extensions/flicker_utils/flickr-account.c b/extensions/flicker_utils/flickr-account.c
index a9ed6b8e..c26c1d0e 100644
--- a/extensions/flicker_utils/flickr-account.c
+++ b/extensions/flicker_utils/flickr-account.c
@@ -116,7 +116,7 @@ void
 flickr_account_set_accountname (FlickrAccount *self,
                                const char    *value)
 {
-       _g_strset (&self->accountname, value);
+       _g_str_set (&self->accountname, value);
 }
 
 
diff --git a/extensions/flicker_utils/flickr-photo.c b/extensions/flicker_utils/flickr-photo.c
index 32deed18..3d859d67 100644
--- a/extensions/flicker_utils/flickr-photo.c
+++ b/extensions/flicker_utils/flickr-photo.c
@@ -181,7 +181,7 @@ void
 flickr_photo_set_id (FlickrPhoto *self,
                     const char  *value)
 {
-       _g_strset (&self->id, value);
+       _g_str_set (&self->id, value);
 }
 
 
@@ -189,7 +189,7 @@ void
 flickr_photo_set_secret (FlickrPhoto *self,
                         const char  *value)
 {
-       _g_strset (&self->secret, value);
+       _g_str_set (&self->secret, value);
 }
 
 
@@ -197,7 +197,7 @@ void
 flickr_photo_set_server (FlickrPhoto *self,
                         const char  *value)
 {
-       _g_strset (&self->server, value);
+       _g_str_set (&self->server, value);
 }
 
 
@@ -205,7 +205,7 @@ void
 flickr_photo_set_farm (FlickrPhoto *self,
                       const char  *value)
 {
-       _g_strset (&self->farm, value);
+       _g_str_set (&self->farm, value);
 }
 
 
@@ -213,7 +213,7 @@ void
 flickr_photo_set_title (FlickrPhoto *self,
                        const char  *value)
 {
-       _g_strset (&self->title, value);
+       _g_str_set (&self->title, value);
 }
 
 
@@ -273,7 +273,7 @@ flickr_photo_set_url (FlickrPhoto *self,
                      FlickrUrl    size,
                      const char  *value)
 {
-       _g_strset (&(self->url[size]), value);
+       _g_str_set (&(self->url[size]), value);
        if (self->url[size] == NULL)
                self->url[size] = flickr_get_static_url (self, size);
 
@@ -281,7 +281,7 @@ flickr_photo_set_url (FlickrPhoto *self,
                int other_size;
                for (other_size = FLICKR_URL_O - 1; other_size >= 0; other_size--) {
                        if (self->url[other_size] != NULL) {
-                               _g_strset (&(self->url[size]), self->url[other_size]);
+                               _g_str_set (&(self->url[size]), self->url[other_size]);
                                break;
                        }
                }
@@ -293,7 +293,7 @@ void
 flickr_photo_set_original_format (FlickrPhoto *self,
                                  const char  *value)
 {
-       _g_strset (&self->original_format, value);
+       _g_str_set (&self->original_format, value);
 
        g_free (self->mime_type);
        self->mime_type = NULL;
@@ -306,5 +306,5 @@ void
 flickr_photo_set_original_secret (FlickrPhoto *self,
                                  const char  *value)
 {
-       _g_strset (&self->original_secret, value);
+       _g_str_set (&self->original_secret, value);
 }
diff --git a/extensions/flicker_utils/flickr-photoset.c b/extensions/flicker_utils/flickr-photoset.c
index d44d3ce9..d056a738 100644
--- a/extensions/flicker_utils/flickr-photoset.c
+++ b/extensions/flicker_utils/flickr-photoset.c
@@ -161,7 +161,7 @@ void
 flickr_photoset_set_id (FlickrPhotoset *self,
                        const char     *value)
 {
-       _g_strset (&self->id, value);
+       _g_str_set (&self->id, value);
 }
 
 
@@ -169,7 +169,7 @@ void
 flickr_photoset_set_title (FlickrPhotoset *self,
                           const char     *value)
 {
-       _g_strset (&self->title, value);
+       _g_str_set (&self->title, value);
 }
 
 
@@ -177,7 +177,7 @@ void
 flickr_photoset_set_description (FlickrPhotoset *self,
                                 const char     *value)
 {
-       _g_strset (&self->description, value);
+       _g_str_set (&self->description, value);
 }
 
 
@@ -196,7 +196,7 @@ void
 flickr_photoset_set_primary (FlickrPhotoset *self,
                             const char     *value)
 {
-       _g_strset (&self->primary, value);
+       _g_str_set (&self->primary, value);
 }
 
 
@@ -204,7 +204,7 @@ void
 flickr_photoset_set_secret (FlickrPhotoset *self,
                            const char     *value)
 {
-       _g_strset (&self->secret, value);
+       _g_str_set (&self->secret, value);
 }
 
 
@@ -212,7 +212,7 @@ void
 flickr_photoset_set_server (FlickrPhotoset *self,
                            const char     *value)
 {
-       _g_strset (&self->server, value);
+       _g_str_set (&self->server, value);
 }
 
 
@@ -220,7 +220,7 @@ void
 flickr_photoset_set_farm (FlickrPhotoset *self,
                          const char     *value)
 {
-       _g_strset (&self->farm, value);
+       _g_str_set (&self->farm, value);
 }
 
 
@@ -228,5 +228,5 @@ void
 flickr_photoset_set_url (FlickrPhotoset *self,
                         const char     *value)
 {
-       _g_strset (&self->url, value);
+       _g_str_set (&self->url, value);
 }
diff --git a/extensions/gstreamer_tools/actions.c b/extensions/gstreamer_tools/actions.c
index b03607c6..590af5ab 100644
--- a/extensions/gstreamer_tools/actions.c
+++ b/extensions/gstreamer_tools/actions.c
@@ -96,7 +96,7 @@ get_screenshot_file (SaveData  *save_data,
        uri = _g_settings_get_uri_or_special_dir (save_data->settings, 
PREF_GSTREAMER_TOOLS_SCREESHOT_LOCATION, G_USER_DIRECTORY_PICTURES);
        folder = g_file_new_for_uri (uri);
        file_data = gth_media_viewer_page_get_file_data (save_data->page);
-       prefix = _g_utf8_remove_extension (g_file_info_get_display_name (file_data->info));
+       prefix = _g_path_remove_extension (g_file_info_get_display_name (file_data->info));
        if (prefix == NULL)
                prefix = g_strdup (C_("Filename", "Screenshot"));
 
diff --git a/extensions/gstreamer_tools/gth-media-viewer-page.c 
b/extensions/gstreamer_tools/gth-media-viewer-page.c
index 68aba19d..abfb31ea 100644
--- a/extensions/gstreamer_tools/gth-media-viewer-page.c
+++ b/extensions/gstreamer_tools/gth-media-viewer-page.c
@@ -1037,8 +1037,8 @@ gth_media_viewer_page_real_deactivate (GthViewerPage *base)
        if (self->priv->playbin != NULL) {
                save_volume (self);
 
-               g_signal_handlers_disconnect_by_data (self->priv->playbin, self);
-               g_signal_handlers_disconnect_by_data (self->priv->video_area, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->playbin, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->video_area, self);
 
                gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
                wait_playbin_state_change_to_complete (self);
diff --git a/extensions/image_print/gth-image-print-job.c b/extensions/image_print/gth-image-print-job.c
index aeb12b0e..11b99684 100644
--- a/extensions/image_print/gth-image-print-job.c
+++ b/extensions/image_print/gth-image-print-job.c
@@ -1230,7 +1230,7 @@ header_entry_changed_cb (GtkEditable *editable,
 {
        GthImagePrintJob *self = user_data;
 
-       _g_strset (&self->priv->header_template, gtk_entry_get_text (GTK_ENTRY (editable)));
+       _g_str_set (&self->priv->header_template, gtk_entry_get_text (GTK_ENTRY (editable)));
        if (g_strcmp0 (self->priv->header_template, "") == 0) {
                g_free (self->priv->header_template);
                self->priv->header_template = NULL;
@@ -1246,7 +1246,7 @@ footer_entry_changed_cb (GtkEditable *editable,
 {
        GthImagePrintJob *self = user_data;
 
-       _g_strset (&self->priv->footer_template, gtk_entry_get_text (GTK_ENTRY (editable)));
+       _g_str_set (&self->priv->footer_template, gtk_entry_get_text (GTK_ENTRY (editable)));
        if (g_strcmp0 (self->priv->footer_template, "") == 0) {
                g_free (self->priv->footer_template);
                self->priv->footer_template = NULL;
@@ -1788,7 +1788,7 @@ _gth_image_print_job_set_output_uri (GthImagePrintJob *self,
        char       *uri;
 
        if (self->priv->n_images == 1)
-               basename = _g_uri_remove_extension (g_file_info_get_name 
(self->priv->images[0]->file_data->info));
+               basename = _g_path_remove_extension (g_file_info_get_name 
(self->priv->images[0]->file_data->info));
        else
                basename = g_strdup (g_file_info_get_edit_name (gth_browser_get_location_data 
(self->priv->browser)->info));
        default_dir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index ddec2092..23392708 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -467,7 +467,7 @@ update_quality_cb (gpointer user_data)
                self->priv->update_quality_id = 0;
        }
 
-       file_changed = ! _g_file_equal_uris (data->file_data->file, self->priv->file_data->file);
+       file_changed = ! _g_file_equal (data->file_data->file, self->priv->file_data->file);
        update_quality_data_free (data);
 
        if (file_changed)
@@ -685,10 +685,10 @@ update_zoom_info (GthImageViewerPage *self)
 
        GtkWidget *scale = _gtk_builder_get_widget (self->priv->builder, "zoom_level_scale");
 
-       g_signal_handlers_block_by_data (scale, self);
+       _g_signal_handlers_block_by_data (scale, self);
        x = (zoom - MIN_ZOOM_LEVEL) / (MAX_ZOOM_LEVEL - MIN_ZOOM_LEVEL) * 100.0;
        gtk_range_set_value (GTK_RANGE (scale), CLAMP (x, 0, 100));
-       g_signal_handlers_unblock_by_data (scale, self);
+       _g_signal_handlers_unblock_by_data (scale, self);
 }
 
 
diff --git a/extensions/list_tools/gth-script.c b/extensions/list_tools/gth-script.c
index cca9191e..023e2adf 100644
--- a/extensions/list_tools/gth-script.c
+++ b/extensions/list_tools/gth-script.c
@@ -370,7 +370,7 @@ gth_script_new (void)
        GthScript *script;
        char      *id;
 
-       id = _g_rand_string (ID_LENGTH);
+       id = _g_str_random (ID_LENGTH);
        script = (GthScript *) g_object_new (GTH_TYPE_SCRIPT, "id", id, NULL);
        g_free (id);
 
@@ -578,7 +578,7 @@ get_basename_wo_ext_func (GthFileData *file_data)
        char *basename_wo_ext;
 
        basename = g_file_get_basename (file_data->file);
-       basename_wo_ext = _g_uri_remove_extension (basename);
+       basename_wo_ext = _g_path_remove_extension (basename);
 
        g_free (basename);
 
@@ -593,7 +593,7 @@ get_ext_func (GthFileData *file_data)
        char *ext;
 
        path = g_file_get_path (file_data->file);
-       ext = g_strdup (_g_uri_get_file_extension (path));
+       ext = g_strdup (_g_path_get_extension (path));
 
        g_free (path);
 
@@ -682,7 +682,7 @@ create_attribute_list (GList    *file_list,
                if (value != NULL) {
                        char *tmp_value;
 
-                       tmp_value = _g_utf8_replace (value, "[\r\n]", " ");
+                       tmp_value = _g_utf8_replace_pattern (value, "[\r\n]", " ");
                        g_free (value);
                        value = tmp_value;
                }
@@ -890,7 +890,7 @@ _split_command_for_quotation (char *string)
        int          n;
 
        remainder = string;
-       s = _g_utf8_strstr (remainder, delimiter);
+       s = _g_utf8_find_str (remainder, delimiter);
        if (s != NULL) {
                gsize delimiter_size = strlen (delimiter);
 
@@ -915,7 +915,7 @@ _split_command_for_quotation (char *string)
                                string_list = g_slist_prepend (string_list, new_string);
 
                                remainder = s + 1 /* strlen("}") */;
-                               s = _g_utf8_strstr (remainder, delimiter);
+                               s = _g_utf8_find_str (remainder, delimiter);
                        }
                }
        }
@@ -981,10 +981,10 @@ gth_script_get_command_line (GthScript  *script,
 
                                        if (n_param == 1) {
                                                g_free (asked_value->prompt);
-                                               asked_value->prompt = _g_utf8_strstrip (value);
+                                               asked_value->prompt = _g_utf8_strip (value);
                                        }
                                        else if (n_param == 2)
-                                               asked_value->default_value = _g_utf8_strstrip (value);
+                                               asked_value->default_value = _g_utf8_strip (value);
                                        else
                                                g_assert_not_reached ();
 
diff --git a/extensions/oauth/oauth-account.c b/extensions/oauth/oauth-account.c
index 4f381b9b..feb87ffd 100644
--- a/extensions/oauth/oauth-account.c
+++ b/extensions/oauth/oauth-account.c
@@ -82,21 +82,21 @@ oauth_account_set_property (GObject      *object,
 
        switch (property_id) {
        case PROP_ID:
-               _g_strset (&self->id, g_value_get_string (value));
+               _g_str_set (&self->id, g_value_get_string (value));
                break;
        case PROP_USERNAME:
-               _g_strset (&self->username, g_value_get_string (value));
+               _g_str_set (&self->username, g_value_get_string (value));
                if (self->name == NULL)
-                       _g_strset (&self->name, g_value_get_string (value));
+                       _g_str_set (&self->name, g_value_get_string (value));
                break;
        case PROP_NAME:
-               _g_strset (&self->name, g_value_get_string (value));
+               _g_str_set (&self->name, g_value_get_string (value));
                break;
        case PROP_TOKEN:
-               _g_strset (&self->token, g_value_get_string (value));
+               _g_str_set (&self->token, g_value_get_string (value));
                break;
        case PROP_TOKEN_SECRET:
-               _g_strset (&self->token_secret, g_value_get_string (value));
+               _g_str_set (&self->token_secret, g_value_get_string (value));
                break;
        case PROP_IS_DEFAULT:
                self->is_default = g_value_get_boolean (value);
@@ -286,7 +286,7 @@ void
 oauth_account_set_username (OAuthAccount *self,
                            const char    *value)
 {
-       _g_strset (&self->username, value);
+       _g_str_set (&self->username, value);
 }
 
 
@@ -294,7 +294,7 @@ void
 oauth_account_set_token (OAuthAccount *self,
                         const char    *value)
 {
-       _g_strset (&self->token, value);
+       _g_str_set (&self->token, value);
 }
 
 
@@ -302,7 +302,7 @@ void
 oauth_account_set_token_secret (OAuthAccount *self,
                                const char   *value)
 {
-       _g_strset (&self->token_secret, value);
+       _g_str_set (&self->token_secret, value);
 }
 
 
diff --git a/extensions/oauth/oauth-service.c b/extensions/oauth/oauth-service.c
index 0e896953..596b0b85 100644
--- a/extensions/oauth/oauth-service.c
+++ b/extensions/oauth/oauth-service.c
@@ -307,7 +307,7 @@ ask_authorization_dialog_load_request_cb (OAuthAskAuthorizationDialog *dialog,
                uri_data = uri + strlen (OAUTH_CALLBACK "?");
 
                data = soup_form_decode (uri_data);
-               _g_strset (&self->priv->token, g_hash_table_lookup (data, "oauth_token"));
+               _g_str_set (&self->priv->token, g_hash_table_lookup (data, "oauth_token"));
 
                if (self->priv->token != NULL) {
                        gtk_widget_hide (GTK_WIDGET (dialog));
@@ -518,7 +518,7 @@ void
 oauth_service_set_token (OAuthService *self,
                         const char   *token)
 {
-       _g_strset (&self->priv->token, token);
+       _g_str_set (&self->priv->token, token);
 }
 
 
@@ -533,7 +533,7 @@ void
 oauth_service_set_token_secret (OAuthService *self,
                                const char   *token_secret)
 {
-       _g_strset (&self->priv->token_secret, token_secret);
+       _g_str_set (&self->priv->token_secret, token_secret);
 }
 
 
diff --git a/extensions/oauth/web-service.c b/extensions/oauth/web-service.c
index 56e12641..b41f139b 100644
--- a/extensions/oauth/web-service.c
+++ b/extensions/oauth/web-service.c
@@ -122,13 +122,13 @@ web_service_set_property (GObject      *object,
 
        switch (property_id) {
        case PROP_SERVICE_NAME:
-               _g_strset (&self->priv->service_name, g_value_get_string (value));
+               _g_str_set (&self->priv->service_name, g_value_get_string (value));
                break;
        case PROP_SERVICE_ADDRESS:
-               _g_strset (&self->priv->service_address, g_value_get_string (value));
+               _g_str_set (&self->priv->service_address, g_value_get_string (value));
                break;
        case PROP_SERVICE_PROTOCOL:
-               _g_strset (&self->priv->service_protocol, g_value_get_string (value));
+               _g_str_set (&self->priv->service_protocol, g_value_get_string (value));
                break;
        case PROP_ACCOUNT_TYPE:
                self->priv->account_type = g_value_get_gtype (value);
diff --git a/extensions/photo_importer/actions.c b/extensions/photo_importer/actions.c
index 9f7c2ccb..d89d3b7d 100644
--- a/extensions/photo_importer/actions.c
+++ b/extensions/photo_importer/actions.c
@@ -81,7 +81,7 @@ gth_browser_activate_import_folder (GSimpleAction     *action,
        if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser)))
                folder = _g_object_ref (gth_browser_get_location (browser));
        if (folder == NULL)
-               folder = g_file_new_for_uri (get_home_uri ());
+               folder = g_file_new_for_uri (_g_uri_get_home ());
        gtk_file_chooser_set_file (GTK_FILE_CHOOSER (chooser), folder, NULL);
 
        g_signal_connect (chooser,
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index b34f523b..60140900 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -620,7 +620,7 @@ dlg_photo_importer (GthBrowser            *browser,
                        if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser)))
                                data->source = _g_object_ref (gth_browser_get_location (browser));
                        if (data->source == NULL)
-                               data->source = g_file_new_for_uri (get_home_uri ());
+                               data->source = g_file_new_for_uri (_g_uri_get_home ());
                }
 
                gtk_window_set_title (GTK_WINDOW (data->dialog), _("Import from Folder"));
diff --git a/extensions/picasaweb/picasa-web-album.c b/extensions/picasaweb/picasa-web-album.c
index 429e3234..3465d3e3 100644
--- a/extensions/picasaweb/picasa-web-album.c
+++ b/extensions/picasaweb/picasa-web-album.c
@@ -201,7 +201,7 @@ void
 picasa_web_album_set_etag (PicasaWebAlbum *self,
                           const char     *value)
 {
-       _g_strset (&self->etag, value);
+       _g_str_set (&self->etag, value);
 }
 
 
@@ -209,7 +209,7 @@ void
 picasa_web_album_set_id (PicasaWebAlbum *self,
                         const char     *value)
 {
-       _g_strset (&self->id, value);
+       _g_str_set (&self->id, value);
 }
 
 
@@ -217,7 +217,7 @@ void
 picasa_web_album_set_title (PicasaWebAlbum *self,
                            const char     *value)
 {
-       _g_strset (&self->title, value);
+       _g_str_set (&self->title, value);
 }
 
 
@@ -225,7 +225,7 @@ void
 picasa_web_album_set_summary (PicasaWebAlbum *self,
                              const char     *value)
 {
-       _g_strset (&self->summary, value);
+       _g_str_set (&self->summary, value);
 }
 
 
@@ -233,7 +233,7 @@ void
 picasa_web_album_set_location (PicasaWebAlbum *self,
                               const char     *value)
 {
-       _g_strset (&self->location, value);
+       _g_str_set (&self->location, value);
 }
 
 
@@ -241,7 +241,7 @@ void
 picasa_web_album_set_alternate_url (PicasaWebAlbum *self,
                                    const char     *value)
 {
-       _g_strset (&self->alternate_url, value);
+       _g_str_set (&self->alternate_url, value);
 }
 
 
@@ -249,7 +249,7 @@ void
 picasa_web_album_set_edit_url (PicasaWebAlbum *self,
                               const char     *value)
 {
-       _g_strset (&self->edit_url, value);
+       _g_str_set (&self->edit_url, value);
 }
 
 
@@ -306,5 +306,5 @@ void
 picasa_web_album_set_keywords (PicasaWebAlbum *self,
                               const char     *value)
 {
-       _g_strset (&self->keywords, value);
+       _g_str_set (&self->keywords, value);
 }
diff --git a/extensions/picasaweb/picasa-web-photo.c b/extensions/picasaweb/picasa-web-photo.c
index 31870ff0..d064bc46 100644
--- a/extensions/picasaweb/picasa-web-photo.c
+++ b/extensions/picasaweb/picasa-web-photo.c
@@ -234,7 +234,7 @@ void
 picasa_web_photo_set_etag (PicasaWebPhoto *self,
                           const char    *value)
 {
-       _g_strset (&self->etag, value);
+       _g_str_set (&self->etag, value);
 }
 
 
@@ -242,7 +242,7 @@ void
 picasa_web_photo_set_id (PicasaWebPhoto *self,
                        const char    *value)
 {
-       _g_strset (&self->id, value);
+       _g_str_set (&self->id, value);
 }
 
 
@@ -250,7 +250,7 @@ void
 picasa_web_photo_set_album_id (PicasaWebPhoto *self,
                               const char    *value)
 {
-       _g_strset (&self->album_id, value);
+       _g_str_set (&self->album_id, value);
 }
 
 
@@ -258,7 +258,7 @@ void
 picasa_web_photo_set_title (PicasaWebPhoto *self,
                            const char     *value)
 {
-       _g_strset (&self->title, value);
+       _g_str_set (&self->title, value);
 }
 
 
@@ -266,7 +266,7 @@ void
 picasa_web_photo_set_summary (PicasaWebPhoto *self,
                              const char     *value)
 {
-       _g_strset (&self->summary, value);
+       _g_str_set (&self->summary, value);
 }
 
 
@@ -274,7 +274,7 @@ void
 picasa_web_photo_set_uri (PicasaWebPhoto *self,
                          const char     *value)
 {
-       _g_strset (&self->uri, value);
+       _g_str_set (&self->uri, value);
 }
 
 
@@ -282,7 +282,7 @@ void
 picasa_web_photo_set_mime_type (PicasaWebPhoto *self,
                                const char     *value)
 {
-       _g_strset (&self->mime_type, value);
+       _g_str_set (&self->mime_type, value);
 }
 
 
@@ -309,7 +309,7 @@ void
 picasa_web_photo_set_credit (PicasaWebPhoto *self,
                             const char     *value)
 {
-       _g_strset (&self->credit, value);
+       _g_str_set (&self->credit, value);
 }
 
 
@@ -317,7 +317,7 @@ void
 picasa_web_photo_set_description (PicasaWebPhoto *self,
                                  const char     *value)
 {
-       _g_strset (&self->description, value);
+       _g_str_set (&self->description, value);
 }
 
 
@@ -325,7 +325,7 @@ void
 picasa_web_photo_set_keywords (PicasaWebPhoto *self,
                               const char     *value)
 {
-       _g_strset (&self->keywords, value);
+       _g_str_set (&self->keywords, value);
 }
 
 
@@ -333,7 +333,7 @@ void
 picasa_web_photo_set_thumbnail_72 (PicasaWebPhoto *self,
                                   const char     *value)
 {
-       _g_strset (&self->thumbnail_72, value);
+       _g_str_set (&self->thumbnail_72, value);
 }
 
 
@@ -341,7 +341,7 @@ void
 picasa_web_photo_set_thumbnail_144 (PicasaWebPhoto *self,
                                    const char     *value)
 {
-       _g_strset (&self->thumbnail_144, value);
+       _g_str_set (&self->thumbnail_144, value);
 }
 
 
@@ -349,7 +349,7 @@ void
 picasa_web_photo_set_thumbnail_288 (PicasaWebPhoto *self,
                                    const char     *value)
 {
-       _g_strset (&self->thumbnail_288, value);
+       _g_str_set (&self->thumbnail_288, value);
 }
 
 
diff --git a/extensions/picasaweb/picasa-web-service.c b/extensions/picasaweb/picasa-web-service.c
index 8189f157..fc7618a7 100644
--- a/extensions/picasaweb/picasa-web-service.c
+++ b/extensions/picasaweb/picasa-web-service.c
@@ -196,8 +196,8 @@ _picasa_web_service_get_refresh_token_ready_cb (SoupSession *session,
                JsonObject *obj;
 
                obj = json_node_get_object (node);
-               _g_strset (&self->priv->access_token, json_object_get_string_member (obj, "access_token"));
-               _g_strset (&self->priv->refresh_token, json_object_get_string_member (obj, "refresh_token"));
+               _g_str_set (&self->priv->access_token, json_object_get_string_member (obj, "access_token"));
+               _g_str_set (&self->priv->refresh_token, json_object_get_string_member (obj, "refresh_token"));
 
                g_task_return_boolean (task, TRUE);
        }
@@ -336,8 +336,8 @@ picasa_web_service_ask_authorization (WebService *base)
        PicasaWebService *self = PICASA_WEB_SERVICE (base);
        GtkWidget        *dialog;
 
-       _g_strset (&self->priv->refresh_token, NULL);
-       _g_strset (&self->priv->access_token, NULL);
+       _g_str_set (&self->priv->refresh_token, NULL);
+       _g_str_set (&self->priv->access_token, NULL);
 
        dialog = oauth_ask_authorization_dialog_new (picasa_web_service_get_authorization_url (self));
        gtk_window_set_default_size (GTK_WINDOW (dialog), 680, 580);
@@ -378,7 +378,7 @@ _picasa_web_service_get_access_token_ready_cb (SoupSession *session,
                                      "token", json_object_get_string_member (obj, "access_token"),
                                      NULL);
                else
-                       _g_strset (&self->priv->access_token, json_object_get_string_member (obj, 
"access_token"));
+                       _g_str_set (&self->priv->access_token, json_object_get_string_member (obj, 
"access_token"));
 
                g_task_return_boolean (task, TRUE);
        }
@@ -397,7 +397,7 @@ _picasa_web_service_get_access_token (PicasaWebService    *self,
        GHashTable  *data_set;
        SoupMessage *msg;
 
-       _g_strset (&self->priv->access_token, NULL);
+       _g_str_set (&self->priv->access_token, NULL);
 
        data_set = g_hash_table_new (g_str_hash, g_str_equal);
        g_hash_table_insert (data_set, "refresh_token", (gpointer) refresh_token);
@@ -491,7 +491,7 @@ picasa_web_service_get_user_info_ready_cb (SoupSession *session,
 
                                account = web_service_get_current_account (WEB_SERVICE (self));
                                if (account != NULL)
-                                       _g_strset (&account->token, NULL);
+                                       _g_str_set (&account->token, NULL);
 
                                picasa_web_service_get_user_info (WEB_SERVICE (self),
                                                                  data->cancellable,
@@ -559,8 +559,8 @@ picasa_web_service_get_user_info (WebService          *base,
 
        account = web_service_get_current_account (WEB_SERVICE (self));
        if (account != NULL) {
-               _g_strset (&self->priv->refresh_token, account->token_secret);
-               _g_strset (&self->priv->access_token, account->token);
+               _g_str_set (&self->priv->refresh_token, account->token_secret);
+               _g_str_set (&self->priv->access_token, account->token);
        }
 
        data = g_new0 (AccessTokenData, 1);
diff --git a/extensions/rename_series/dlg-rename-series.c b/extensions/rename_series/dlg-rename-series.c
index 03b306c1..08a1c2d6 100644
--- a/extensions/rename_series/dlg-rename-series.c
+++ b/extensions/rename_series/dlg-rename-series.c
@@ -164,7 +164,7 @@ get_attribute_value (GthFileData *file_data,
                if (value != NULL) {
                        char *tmp_value;
 
-                       tmp_value = _g_utf8_replace (value, "[\r\n]", " ");
+                       tmp_value = _g_utf8_replace_pattern (value, "[\r\n]", " ");
                        g_free (value);
                        value = tmp_value;
                }
@@ -205,7 +205,7 @@ template_eval_cb (const GMatchInfo *info,
                char *uri;
 
                uri = g_file_get_uri (template_data->file_data->file);
-               r = g_strdup (_g_uri_get_file_extension (uri));
+               r = _g_uri_get_extension (uri);
 
                g_free (uri);
        }
@@ -213,7 +213,7 @@ template_eval_cb (const GMatchInfo *info,
                char *basename;
 
                basename = g_file_get_basename (template_data->file_data->file);
-               r = _g_uri_remove_extension (basename);
+               r = _g_path_remove_extension (basename);
 
                g_free (basename);
        }
diff --git a/extensions/rename_series/gth-rename-task.c b/extensions/rename_series/gth-rename-task.c
index 4be302d1..9f505675 100644
--- a/extensions/rename_series/gth-rename-task.c
+++ b/extensions/rename_series/gth-rename-task.c
@@ -178,7 +178,7 @@ _gth_rename_task_try_rename (GthRenameTask   *self,
        if (self->priv->default_response == GTH_OVERWRITE_RESPONSE_ALWAYS_YES)
                copy_flags = G_FILE_COPY_OVERWRITE;
 
-       if (! _g_move_file (source,
+       if (! _g_file_move (source,
                            destination,
                            G_FILE_COPY_ALL_METADATA | copy_flags,
                            gth_task_get_cancellable (GTH_TASK (self)),
diff --git a/extensions/search/gth-search-source-selector.c b/extensions/search/gth-search-source-selector.c
index 7b28c3b4..9f80183e 100644
--- a/extensions/search/gth-search-source-selector.c
+++ b/extensions/search/gth-search-source-selector.c
@@ -205,7 +205,7 @@ gth_search_source_selector_set_source (GthSearchSourceSelector *self,
        }
 
        if (folder == NULL)
-               folder = g_file_new_for_uri (get_home_uri ());
+               folder = g_file_new_for_uri (_g_uri_get_home ());
 
        gth_location_chooser_set_current (GTH_LOCATION_CHOOSER (self->priv->location_chooser), folder);
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->recursive_checkbutton), recursive);
diff --git a/extensions/selections/actions.c b/extensions/selections/actions.c
index 3e3d0fd8..3ef1e0ad 100644
--- a/extensions/selections/actions.c
+++ b/extensions/selections/actions.c
@@ -36,7 +36,7 @@ gth_browser_show_selection (GthBrowser *browser,
        uri = g_strdup_printf ("selection:///%d", n_selection);
        location = g_file_new_for_uri (uri);
 
-       if (_g_file_equal_uris (location, gth_browser_get_location (browser))) {
+       if (_g_file_equal (location, gth_browser_get_location (browser))) {
                if (! gth_browser_restore_state (browser))
                        gth_browser_load_location (browser, location);
        }
diff --git a/extensions/selections/gth-file-source-selections.c 
b/extensions/selections/gth-file-source-selections.c
index 45c96c04..42a42275 100644
--- a/extensions/selections/gth-file-source-selections.c
+++ b/extensions/selections/gth-file-source-selections.c
@@ -289,28 +289,15 @@ gth_file_source_selections_get_drop_actions (GthFileSource *file_source,
                                             GFile         *destination,
                                             GFile         *file)
 {
-       GdkDragAction  actions = 0;
-       char          *dest_uri;
-       char          *dest_scheme;
-       char          *file_uri;
-       char          *file_scheme;
+       GdkDragAction actions = 0;
 
-       dest_uri = g_file_get_uri (destination);
-       dest_scheme = _g_uri_get_scheme (dest_uri);
-
-       file_uri = g_file_get_uri (file);
-       file_scheme = _g_uri_get_scheme (file_uri);
-
-       if ((g_strcmp0 (dest_scheme, "selection://") == 0)
-               && (g_strcmp0 (file_scheme, "file://") == 0))
+       if (_g_file_has_scheme (destination, "selection")
+               && _g_file_has_scheme (file, "file"))
        {
                /* Copy files into a selection. */
                actions = GDK_ACTION_COPY;
        }
 
-       g_free (file_uri);
-       g_free (dest_uri);
-
        return actions;
 }
 
diff --git a/extensions/webalbums/dlg-web-exporter.c b/extensions/webalbums/dlg-web-exporter.c
index f72eb2a4..17f92f6d 100644
--- a/extensions/webalbums/dlg-web-exporter.c
+++ b/extensions/webalbums/dlg-web-exporter.c
@@ -479,7 +479,7 @@ dlg_web_exporter (GthBrowser *browser,
 
                destination = _g_settings_get_uri (data->settings, PREF_WEBALBUMS_DESTINATION);
                if (destination == NULL)
-                       destination = g_strdup (get_home_uri ());
+                       destination = g_strdup (_g_uri_get_home ());
                gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("destination_filechooserbutton")), 
destination);
 
                g_free (destination);
diff --git a/extensions/webalbums/gth-web-exporter.c b/extensions/webalbums/gth-web-exporter.c
index 969c17f7..cce2c5c6 100644
--- a/extensions/webalbums/gth-web-exporter.c
+++ b/extensions/webalbums/gth-web-exporter.c
@@ -701,7 +701,7 @@ write_markup_escape_line (GFileOutputStream  *ostream,
        if (line_is_void (line))
                return;
 
-       e_line = _g_escape_for_html (line, -1);
+       e_line = _g_utf8_text_escape_xml (line);
        _write_line (ostream, e_line, error);
 
        g_free (e_line);
@@ -718,7 +718,7 @@ write_markup_escape_locale_line (GFileOutputStream  *ostream,
        if ((line == NULL) || (*line == 0))
                return;
 
-       e_line = _g_escape_for_html (line, -1);
+       e_line = _g_utf8_text_escape_xml (line);
        _write_locale_line (ostream, e_line, error);
 
        g_free (e_line);
@@ -764,40 +764,24 @@ get_image_attribute (GthWebExporter    *self,
 
 
 static char *
-gfile_get_relative_uri (GFile *file,
-                       GFile *relative_to)
+gfile_get_relative_path (GFile *file,
+                        GFile *base)
 {
-       char *escaped;
-       char *relative_uri;
+       char *uri;
+       char *base_uri;
        char *result;
 
-       escaped = g_file_get_uri (file);
-       relative_uri = g_file_get_uri (relative_to);
-       result = _g_uri_get_relative_path (escaped, relative_uri);
+       uri = g_file_get_uri (file);
+       base_uri = g_file_get_uri (base);
+       result = _g_uri_get_relative_path (uri, base_uri);
 
-       g_free (relative_uri);
-       g_free (escaped);
+       g_free (base_uri);
+       g_free (uri);
 
        return result;
 }
 
 
-static char *
-gfile_get_relative_path (GFile *file,
-                        GFile *relative_to)
-{
-       char *escaped;
-       char *unescaped;
-
-       escaped = gfile_get_relative_uri (file, relative_to);
-       unescaped = g_uri_unescape_string (escaped, NULL);
-
-       g_free (escaped);
-
-       return unescaped;
-}
-
-
 /* construct a GFile for a GthWebExporter */
 
 
@@ -1178,7 +1162,7 @@ gth_parsed_doc_print (GthWebExporter      *self,
                        if (src == NULL)
                                break;
                        file = get_theme_file (self, self->priv->target_dir, src);
-                       line = gfile_get_relative_uri (file, relative_to);
+                       line = gfile_get_relative_path (file, relative_to);
                        write_markup_escape_line (ostream, line, error);
                        g_object_unref (file);
                        break;
@@ -1208,8 +1192,8 @@ gth_parsed_doc_print (GthWebExporter      *self,
                                break;
                        }
 
-                       image_src = gfile_get_relative_uri (file, relative_to);
-                       src_attr = _g_escape_for_html (image_src, -1);
+                       image_src = gfile_get_relative_path (file, relative_to);
+                       src_attr = _g_utf8_escape_xml (image_src);
 
                        class = gth_tag_get_attribute_string (self, tag, "class");
                        if (class)
@@ -1233,7 +1217,7 @@ gth_parsed_doc_print (GthWebExporter      *self,
                                char *unescaped_path;
 
                                unescaped_path = g_uri_unescape_string (image_src, NULL);
-                               alt_attr = _g_escape_for_html (unescaped_path, -1);
+                               alt_attr = _g_utf8_escape_xml (unescaped_path);
                                g_free (unescaped_path);
                        }
 
@@ -1264,7 +1248,7 @@ gth_parsed_doc_print (GthWebExporter      *self,
                        idx = get_image_idx (tag, self);
                        idata = g_list_nth (self->priv->file_list, idx)->data;
                        file = get_html_image_file (self, idata, self->priv->target_dir);
-                       line = gfile_get_relative_uri (file, relative_to);
+                       line = gfile_get_relative_path (file, relative_to);
                        write_markup_escape_line (ostream, line, error);
                        g_object_unref (file);
                        break;
@@ -1326,7 +1310,7 @@ gth_parsed_doc_print (GthWebExporter      *self,
                                line = unescaped_path;
                        }
                        else {
-                               line = g_strdup (_g_uri_get_basename (unescaped_path));
+                               line = _g_uri_get_basename (unescaped_path);
                                g_free (unescaped_path);
                        }
 
@@ -1398,7 +1382,7 @@ gth_parsed_doc_print (GthWebExporter      *self,
                                idx = get_page_idx (tag, self);
 
                        file = get_html_index_file (self, idx, self->priv->target_dir);
-                       line = gfile_get_relative_uri (file, relative_to);
+                       line = gfile_get_relative_path (file, relative_to);
                        write_markup_escape_line (ostream, line, error);
 
                        g_object_unref (file);
@@ -1868,12 +1852,12 @@ cleanup_and_terminate (GthWebExporter *self,
                GList *file_list;
 
                file_list = g_list_append (NULL, self->priv->tmp_dir);
-               _g_delete_files_async (file_list,
-                                      TRUE,
-                                      TRUE,
-                                      NULL,
-                                      delete_temp_dir_ready_cb,
-                                      self);
+               _g_file_list_delete_async (file_list,
+                                          TRUE,
+                                          TRUE,
+                                          NULL,
+                                          delete_temp_dir_ready_cb,
+                                          self);
 
                g_list_free (file_list);
        }
@@ -1951,19 +1935,19 @@ save_other_files_ready_cb (GError   *error,
        g_object_unref (enumerator);
 
        if (error == NULL)
-               _g_copy_files_async (files,
-                                    self->priv->target_dir,
-                                    FALSE,
-                                    GTH_FILE_COPY_DEFAULT,
-                                    GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
-                                    G_PRIORITY_DEFAULT,
-                                    gth_task_get_cancellable (GTH_TASK (self)),
-                                    save_files_progress_cb,
-                                    self,
-                                    save_files_dialog_cb,
-                                    self,
-                                    copy_to_destination_ready_cb,
-                                    self);
+               _g_file_list_copy_async (files,
+                                        self->priv->target_dir,
+                                        FALSE,
+                                        GTH_FILE_COPY_DEFAULT,
+                                        GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
+                                        G_PRIORITY_DEFAULT,
+                                        gth_task_get_cancellable (GTH_TASK (self)),
+                                        save_files_progress_cb,
+                                        self,
+                                        save_files_dialog_cb,
+                                        self,
+                                        copy_to_destination_ready_cb,
+                                        self);
        else
                cleanup_and_terminate (self, error);
 
@@ -2026,19 +2010,19 @@ save_other_files (GthWebExporter *self)
                GFile *theme_dir;
 
                theme_dir = get_theme_file (self, self->priv->tmp_dir, NULL);
-               _g_copy_files_async (files,
-                                    theme_dir,
-                                    FALSE,
-                                    GTH_FILE_COPY_DEFAULT,
-                                    GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
-                                    G_PRIORITY_DEFAULT,
-                                    gth_task_get_cancellable (GTH_TASK (self)),
-                                    save_files_progress_cb,
-                                    self,
-                                    save_files_dialog_cb,
-                                    self,
-                                    save_other_files_ready_cb,
-                                    self);
+               _g_file_list_copy_async (files,
+                                        theme_dir,
+                                        FALSE,
+                                        GTH_FILE_COPY_DEFAULT,
+                                        GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
+                                        G_PRIORITY_DEFAULT,
+                                        gth_task_get_cancellable (GTH_TASK (self)),
+                                        save_files_progress_cb,
+                                        self,
+                                        save_files_dialog_cb,
+                                        self,
+                                        save_other_files_ready_cb,
+                                        self);
 
                g_object_unref (theme_dir);
        }
@@ -2430,7 +2414,7 @@ save_resized_image (gpointer data)
 
                /* change the file extension to jpeg */
 
-               filename_no_ext = _g_uri_remove_extension (image_data->dest_filename);
+               filename_no_ext = _g_path_remove_extension (image_data->dest_filename);
                g_free (image_data->dest_filename);
                image_data->dest_filename = g_strconcat(filename_no_ext, ".jpeg", NULL);
                g_free (filename_no_ext);
diff --git a/gthumb/dlg-preferences-general.c b/gthumb/dlg-preferences-general.c
index e71a09ba..77d94164 100644
--- a/gthumb/dlg-preferences-general.c
+++ b/gthumb/dlg-preferences-general.c
@@ -162,7 +162,7 @@ general__dlg_preferences_construct_cb (GtkWidget  *dialog,
 
        startup_location = _g_settings_get_uri (data->browser_settings, PREF_BROWSER_STARTUP_LOCATION);
        if (startup_location == NULL)
-               startup_location = g_strdup (get_home_uri ());
+               startup_location = g_strdup (_g_uri_get_home ());
        file_source = gth_main_get_file_source_for_uri (startup_location);
        if (GTH_IS_FILE_SOURCE_VFS (file_source)) {
                GFile *location;
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 17ce81ca..794860fd 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -34,99 +34,7 @@
 #define N_FILES_PER_REQUEST 128
 
 
-/* -- filter -- */
-
-
-typedef enum {
-       FILTER_DEFAULT = 0,
-       FILTER_NODOTFILES = 1 << 1,
-       FILTER_IGNORECASE = 1 << 2,
-       FILTER_NOBACKUPFILES = 1 << 3
-} FilterOptions;
-
-
-typedef struct {
-       char           *pattern;
-       FilterOptions   options;
-       GRegex        **regexps;
-} Filter;
-
-
-static Filter *
-filter_new (const char    *pattern,
-           FilterOptions  options)
-{
-       Filter             *filter;
-       GRegexCompileFlags  flags;
-
-       filter = g_new0 (Filter, 1);
-
-       if ((pattern != NULL) && (strcmp (pattern, "*") != 0))
-               filter->pattern = g_strdup (pattern);
-
-       filter->options = options;
-       if (filter->options & FILTER_IGNORECASE)
-               flags = G_REGEX_CASELESS;
-       else
-               flags = 0;
-       filter->regexps = get_regexps_from_pattern (pattern, flags);
-
-       return filter;
-}
-
-
-static void
-filter_destroy (Filter *filter)
-{
-       if (filter == NULL)
-               return;
-
-       g_free (filter->pattern);
-       if (filter->regexps != NULL)
-               free_regexps (filter->regexps);
-       g_free (filter);
-}
-
-
-static gboolean
-filter_matches (Filter     *filter,
-               const char *name)
-{
-       const char *file_name;
-       char       *utf8_name;
-       gboolean    matched;
-
-       g_return_val_if_fail (name != NULL, FALSE);
-
-       file_name = _g_uri_get_basename (name);
-
-       if ((filter->options & FILTER_NODOTFILES)
-           && ((file_name[0] == '.') || (strstr (file_name, "/.") != NULL)))
-               return FALSE;
-
-       if ((filter->options & FILTER_NOBACKUPFILES)
-           && (file_name[strlen (file_name) - 1] == '~'))
-               return FALSE;
-
-       if (filter->pattern == NULL)
-               return TRUE;
-
-       utf8_name = g_filename_to_utf8 (file_name, -1, NULL, NULL, NULL);
-       matched = string_matches_regexps (filter->regexps, utf8_name, 0);
-       g_free (utf8_name);
-
-       return matched;
-}
-
-
-static gboolean
-filter_empty (Filter *filter)
-{
-       return ((filter->pattern == NULL) || (strcmp (filter->pattern, "*") == 0));
-}
-
-
-/* -- g_directory_foreach_child -- */
+/* -- _g_directory_foreach_child -- */
 
 
 typedef struct {
@@ -520,7 +428,7 @@ directory_info_ready_cb (GObject      *source_object,
 
 
 /**
- * g_directory_foreach_child:
+ * _g_directory_foreach_child:
  * @directory: The directory to visit.
  * @recursive: Whether to traverse the @directory recursively.
  * @follow_links: Whether to dereference the symbolic links.
@@ -544,7 +452,7 @@ directory_info_ready_cb (GObject      *source_object,
  * Each callback uses the same @user_data additional parameter.
  */
 void
-g_directory_foreach_child (GFile                *directory,
+_g_directory_foreach_child (GFile                *directory,
                           gboolean              recursive,
                           gboolean              follow_links,
                           const char           *attributes,
@@ -584,291 +492,7 @@ g_directory_foreach_child (GFile                *directory,
                                 fec);
 }
 
-
-/* -- get_file_list_data -- */
-
-
-typedef struct {
-       GList             *files;
-       GList             *dirs;
-       GFile             *directory;
-       char              *base_dir;
-       GCancellable      *cancellable;
-       ListReadyCallback  done_func;
-       gpointer           done_data;
-       GList             *to_visit;
-       GList             *current_dir;
-       Filter            *include_filter;
-       Filter            *exclude_filter;
-       Filter            *exclude_folders_filter;
-       guint              visit_timeout;
-} GetFileListData;
-
-
-static void
-get_file_list_data_free (GetFileListData *gfl)
-{
-       if (gfl == NULL)
-               return;
-
-       filter_destroy (gfl->include_filter);
-       filter_destroy (gfl->exclude_filter);
-       filter_destroy (gfl->exclude_folders_filter);
-       _g_string_list_free (gfl->files);
-       _g_string_list_free (gfl->dirs);
-       _g_string_list_free (gfl->to_visit);
-       g_object_unref (gfl->directory);
-       g_free (gfl->base_dir);
-       g_free (gfl);
-}
-
-
-/* -- g_directory_list_async -- */
-
-
-static GList*
-get_relative_file_list (GList      *rel_list,
-                       GList      *file_list,
-                       const char *base_dir)
-{
-       GList *scan;
-       int    base_len;
-
-       if (base_dir == NULL)
-               return NULL;
-
-       base_len = 0;
-       if (strcmp (base_dir, "/") != 0)
-               base_len = strlen (base_dir);
-
-       for (scan = file_list; scan; scan = scan->next) {
-               char *uri = scan->data;
-               if (_g_uri_parent_of_uri (base_dir, uri)) {
-                       char *rel_uri = g_strdup (uri + base_len + 1);
-                       rel_list = g_list_prepend (rel_list, rel_uri);
-               }
-       }
-
-       return rel_list;
-}
-
-
-static GList*
-get_dir_list_from_file_list (GHashTable *h_dirs,
-                            const char *base_dir,
-                            GList      *files,
-                            gboolean    is_dir_list)
-{
-       GList *scan;
-       GList *dir_list = NULL;
-       int    base_dir_len;
-
-       if (base_dir == NULL)
-               base_dir = "";
-       base_dir_len = strlen (base_dir);
-
-       for (scan = files; scan; scan = scan->next) {
-               char *filename = scan->data;
-               char *dir_name;
-
-               if (strlen (filename) <= base_dir_len)
-                       continue;
-
-               if (is_dir_list)
-                       dir_name = g_strdup (filename + base_dir_len + 1);
-               else
-                       dir_name = _g_uri_get_parent (filename + base_dir_len + 1);
-
-               while ((dir_name != NULL) && (dir_name[0] != '\0') && (strcmp (dir_name, "/") != 0)) {
-                       char *tmp;
-                       char *dir;
-
-                       /* avoid to insert duplicated folders */
-
-                       dir = g_strconcat (base_dir, "/", dir_name, NULL);
-                       if (g_hash_table_lookup (h_dirs, dir) == NULL) {
-                               g_hash_table_insert (h_dirs, dir, GINT_TO_POINTER (1));
-                               dir_list = g_list_prepend (dir_list, dir);
-                       }
-                       else
-                               g_free (dir);
-
-                       tmp = dir_name;
-                       dir_name = _g_uri_get_parent (tmp);
-                       g_free (tmp);
-               }
-
-               g_free (dir_name);
-       }
-
-       return dir_list;
-}
-
-
-static void
-get_file_list_done (GError   *error,
-                   gpointer  user_data)
-{
-       GetFileListData *gfl = user_data;
-       GHashTable      *h_dirs;
-       GList           *scan;
-
-       gfl->files = g_list_reverse (gfl->files);
-       gfl->dirs = g_list_reverse (gfl->dirs);
-
-       if (! filter_empty (gfl->include_filter) || (gfl->exclude_filter->pattern != NULL)) {
-               _g_string_list_free (gfl->dirs);
-               gfl->dirs = NULL;
-       }
-
-       h_dirs = g_hash_table_new (g_str_hash, g_str_equal);
-
-       /* Always include the base directory, this way empty base
-        * directories are added to the archive as well.  */
-
-       if (gfl->base_dir != NULL) {
-               char *dir;
-
-               dir = g_strdup (gfl->base_dir);
-               gfl->dirs = g_list_prepend (gfl->dirs, dir);
-               g_hash_table_insert (h_dirs, dir, GINT_TO_POINTER (1));
-       }
-
-       /* Add all the parent directories in gfl->files/gfl->dirs to the
-        * gfl->dirs list, the hash table is used to avoid duplicated
-        * entries. */
-
-       for (scan = gfl->dirs; scan; scan = scan->next)
-               g_hash_table_insert (h_dirs, (char*)scan->data, GINT_TO_POINTER (1));
-
-       gfl->dirs = g_list_concat (gfl->dirs, get_dir_list_from_file_list (h_dirs, gfl->base_dir, gfl->files, 
FALSE));
-
-       if (filter_empty (gfl->include_filter))
-               gfl->dirs = g_list_concat (gfl->dirs, get_dir_list_from_file_list (h_dirs, gfl->base_dir, 
gfl->dirs, TRUE));
-
-       /**/
-
-       if (error == NULL) {
-               GList *rel_files, *rel_dirs;
-
-               if (gfl->base_dir != NULL) {
-                       rel_files = get_relative_file_list (NULL, gfl->files, gfl->base_dir);
-                       rel_dirs = get_relative_file_list (NULL, gfl->dirs, gfl->base_dir);
-               }
-               else {
-                       rel_files = gfl->files;
-                       rel_dirs = gfl->dirs;
-                       gfl->files = NULL;
-                       gfl->dirs = NULL;
-               }
-
-               /* rel_files/rel_dirs must be deallocated in done_func */
-               gfl->done_func (rel_files, rel_dirs, NULL, gfl->done_data);
-       }
-       else
-               gfl->done_func (NULL, NULL, error, gfl->done_data);
-
-       g_hash_table_destroy (h_dirs);
-       get_file_list_data_free (gfl);
-}
-
-
-static void
-get_file_list_for_each_file (GFile     *file,
-                            GFileInfo *info,
-                            gpointer   user_data)
-{
-       GetFileListData *gfl = user_data;
-       char            *uri;
-
-       uri = g_file_get_uri (file);
-
-       switch (g_file_info_get_file_type (info)) {
-       case G_FILE_TYPE_REGULAR:
-               if (filter_matches (gfl->include_filter, uri))
-                       if ((gfl->exclude_filter->pattern == NULL) || ! filter_matches (gfl->exclude_filter, 
uri))
-                               gfl->files = g_list_prepend (gfl->files, g_strdup (uri));
-               break;
-       default:
-               break;
-       }
-
-       g_free (uri);
-}
-
-
-static DirOp
-get_file_list_start_dir (GFile       *directory,
-                        GFileInfo   *info,
-                        GError     **error,
-                        gpointer     user_data)
-{
-       DirOp            dir_op = DIR_OP_CONTINUE;
-       GetFileListData *gfl = user_data;
-       char            *uri;
-
-       uri = g_file_get_uri (directory);
-       if ((gfl->exclude_folders_filter->pattern == NULL) || ! filter_matches (gfl->exclude_folders_filter, 
uri)) {
-               gfl->dirs = g_list_prepend (gfl->dirs, g_strdup (uri));
-               dir_op = DIR_OP_CONTINUE;
-       }
-       else
-               dir_op = DIR_OP_SKIP;
-
-       g_free (uri);
-
-       return dir_op;
-}
-
-
-void
-g_directory_list_async (GFile             *directory,
-                       const char        *base_dir,
-                       gboolean           recursive,
-                       gboolean           follow_links,
-                       gboolean           no_backup_files,
-                       gboolean           no_dot_files,
-                       const char        *include_files,
-                       const char        *exclude_files,
-                       const char        *exclude_folders,
-                       gboolean           ignorecase,
-                       GCancellable      *cancellable,
-                       ListReadyCallback  done_func,
-                       gpointer           done_data)
-{
-       GetFileListData *gfl;
-       FilterOptions    filter_options;
-
-       gfl = g_new0 (GetFileListData, 1);
-       gfl->directory = g_file_dup (directory);
-       gfl->base_dir = g_strdup (base_dir);
-       gfl->done_func = done_func;
-       gfl->done_data = done_data;
-
-       filter_options = FILTER_DEFAULT;
-       if (no_backup_files)
-               filter_options |= FILTER_NOBACKUPFILES;
-       if (no_dot_files)
-               filter_options |= FILTER_NODOTFILES;
-       if (ignorecase)
-               filter_options |= FILTER_IGNORECASE;
-       gfl->include_filter = filter_new (include_files, filter_options);
-       gfl->exclude_filter = filter_new (exclude_files, ignorecase ? FILTER_IGNORECASE : FILTER_DEFAULT);
-       gfl->exclude_folders_filter = filter_new (exclude_folders, ignorecase ? FILTER_IGNORECASE : 
FILTER_DEFAULT);
-
-       g_directory_foreach_child (directory,
-                                  recursive,
-                                  follow_links,
-                                  "standard::name,standard::type",
-                                  cancellable,
-                                  get_file_list_start_dir,
-                                  get_file_list_for_each_file,
-                                  get_file_list_done,
-                                  gfl);
-}
-
-
-/* -- _g_query_info_async -- */
+/* -- _g_file_list_query_info_async -- */
 
 
 typedef struct {
@@ -975,7 +599,7 @@ query_data_info_ready_cb (GObject      *source_object,
        }
 
        if ((query_data->flags & GTH_LIST_RECURSIVE) && (g_file_info_get_file_type (info) == 
G_FILE_TYPE_DIRECTORY)) {
-               g_directory_foreach_child ((GFile *) query_data->current->data,
+               _g_directory_foreach_child ((GFile *) query_data->current->data,
                                           TRUE,
                                           (query_data->flags & GTH_LIST_NO_FOLLOW_LINKS) == 0,
                                           query_data->attributes,
@@ -1021,12 +645,12 @@ query_info__query_current (QueryInfoData *query_data)
 
 
 void
-_g_query_info_async (GList             *file_list,
-                    GthListFlags       flags,
-                    const char        *attributes,
-                    GCancellable      *cancellable,
-                    InfoReadyCallback  ready_callback,
-                    gpointer           user_data)
+_g_file_list_query_info_async (GList             *file_list,
+                              GthListFlags       flags,
+                              const char        *attributes,
+                              GCancellable      *cancellable,
+                              InfoReadyCallback  ready_callback,
+                              gpointer           user_data)
 {
        QueryInfoData *query_data;
 
@@ -1046,49 +670,6 @@ _g_query_info_async (GList             *file_list,
 }
 
 
-/* -- _g_dummy_file_op_async  -- */
-
-
-typedef struct {
-       ReadyFunc callback;
-       gpointer  user_data;
-       gulong    dummy_event;
-} DummyFileCopy;
-
-
-static gboolean
-_g_dummy_file_op_completed (gpointer data)
-{
-       DummyFileCopy *dfd = data;
-
-       if (dfd->dummy_event != 0) {
-               g_source_remove (dfd->dummy_event);
-               dfd->dummy_event = 0;
-       }
-
-       if (dfd->callback)
-               dfd->callback (NULL, dfd->user_data);
-
-       g_free (dfd);
-
-       return FALSE;
-}
-
-
-void
-_g_dummy_file_op_async (ReadyFunc callback,
-                       gpointer  user_data)
-{
-       DummyFileCopy *dfd;
-
-       dfd = g_new0 (DummyFileCopy, 1);
-       dfd->callback = callback;
-       dfd->user_data = user_data;
-       dfd->dummy_event = g_idle_add (_g_dummy_file_op_completed, dfd);
-}
-
-
-
 /* -- _g_copy_file_async -- */
 
 
@@ -1576,19 +1157,19 @@ _g_copy_file_async_private (GthFileData           *source,
 
 
 void
-_g_copy_file_async (GthFileData           *source,
-                   GFile                 *destination,
-                   gboolean               move,
-                   GthFileCopyFlags       flags,
-                   GthOverwriteResponse   default_response,
-                   int                    io_priority,
-                   GCancellable          *cancellable,
-                   ProgressCallback       progress_callback,
-                   gpointer               progress_callback_data,
-                   DialogCallback         dialog_callback,
-                   gpointer               dialog_callback_data,
-                   CopyReadyCallback      ready_callback,
-                   gpointer               user_data)
+_gth_file_data_copy_async (GthFileData           *source,
+                          GFile                 *destination,
+                          gboolean               move,
+                          GthFileCopyFlags       flags,
+                          GthOverwriteResponse   default_response,
+                          int                    io_priority,
+                          GCancellable          *cancellable,
+                          ProgressCallback       progress_callback,
+                          gpointer               progress_callback_data,
+                          DialogCallback         dialog_callback,
+                          gpointer               dialog_callback_data,
+                          CopyReadyCallback      ready_callback,
+                          gpointer               user_data)
 {
        _g_copy_file_async_private (source,
                                    destination,
@@ -1609,7 +1190,7 @@ _g_copy_file_async (GthFileData           *source,
 }
 
 
-/* -- _g_copy_files_async -- */
+/* -- _g_file_list_copy_async -- */
 
 
 typedef struct {
@@ -1843,19 +1424,19 @@ copy_files__sources_info_ready_cb (GList    *files,
 
 
 void
-_g_copy_files_async (GList                *sources, /* GFile list */
-                    GFile                *destination,
-                    gboolean              move,
-                    GthFileCopyFlags      flags,
-                    GthOverwriteResponse  default_response,
-                    int                   io_priority,
-                    GCancellable         *cancellable,
-                    ProgressCallback      progress_callback,
-                    gpointer              progress_callback_data,
-                    DialogCallback        dialog_callback,
-                    gpointer              dialog_callback_data,
-                    ReadyFunc             done_callback,
-                    gpointer              user_data)
+_g_file_list_copy_async (GList                *sources, /* GFile list */
+                        GFile                *destination,
+                        gboolean              move,
+                        GthFileCopyFlags      flags,
+                        GthOverwriteResponse  default_response,
+                        int                   io_priority,
+                        GCancellable         *cancellable,
+                        ProgressCallback      progress_callback,
+                        gpointer              progress_callback_data,
+                        DialogCallback        dialog_callback,
+                        gpointer              dialog_callback_data,
+                        ReadyFunc             done_callback,
+                        gpointer              user_data)
 {
        CopyData *copy_data;
        GList    *scan;
@@ -1890,17 +1471,17 @@ _g_copy_files_async (GList                *sources, /* GFile list */
 
        /* for each directory in 'sources' this query will add all of its content
         * to the file list. */
-       _g_query_info_async (sources,
-                            GTH_LIST_RECURSIVE,
-                            "standard::name,standard::display-name,standard::type,standard::size",
-                            copy_data->cancellable,
-                            copy_files__sources_info_ready_cb,
-                            copy_data);
+       _g_file_list_query_info_async (sources,
+                                      GTH_LIST_RECURSIVE,
+                                      "standard::name,standard::display-name,standard::type,standard::size",
+                                      copy_data->cancellable,
+                                      copy_files__sources_info_ready_cb,
+                                      copy_data);
 }
 
 
 gboolean
-_g_move_file (GFile                 *source,
+_g_file_move (GFile                 *source,
               GFile                 *destination,
               GFileCopyFlags         flags,
               GCancellable          *cancellable,
@@ -1953,9 +1534,9 @@ _g_move_file (GFile                 *source,
 
 
 gboolean
-_g_delete_files (GList     *file_list,
-                gboolean   include_metadata,
-                GError   **error)
+_g_file_list_delete (GList     *file_list,
+                    gboolean   include_metadata,
+                    GError   **error)
 {
        GList *scan;
 
@@ -2073,12 +1654,12 @@ delete_files__info_ready_cb (GList    *files,
 
 
 void
-_g_delete_files_async (GList        *file_list,
-                      gboolean      recursive,
-                      gboolean      include_metadata,
-                      GCancellable *cancellable,
-                      ReadyFunc     callback,
-                      gpointer      user_data)
+_g_file_list_delete_async (GList        *file_list,
+                          gboolean      recursive,
+                          gboolean      include_metadata,
+                          GCancellable *cancellable,
+                          ReadyFunc     callback,
+                          gpointer      user_data)
 {
        DeleteData   *delete_data;
        GthListFlags  flags;
@@ -2094,12 +1675,12 @@ _g_delete_files_async (GList        *file_list,
        if (recursive)
                flags |= GTH_LIST_RECURSIVE;
 
-       _g_query_info_async (file_list,
-                            flags,
-                            GFILE_NAME_TYPE_ATTRIBUTES,
-                            delete_data->cancellable,
-                            delete_files__info_ready_cb,
-                            delete_data);
+       _g_file_list_query_info_async (file_list,
+                                      flags,
+                                      GFILE_NAME_TYPE_ATTRIBUTES,
+                                      delete_data->cancellable,
+                                      delete_files__info_ready_cb,
+                                      delete_data);
 }
 
 
@@ -2165,10 +1746,10 @@ trash_files__delete_current (TrashData *tdata)
 
 
 void
-_g_trash_files_async (GList        *file_list, /* GFile list */
-                     GCancellable *cancellable,
-                     ReadyFunc     callback,
-                     gpointer      user_data)
+_g_file_list_trash_async (GList        *file_list, /* GFile list */
+                         GCancellable *cancellable,
+                         ReadyFunc     callback,
+                         gpointer      user_data)
 {
        TrashData *tdata;
 
@@ -2575,77 +2156,23 @@ _g_file_create_unique (GFile       *parent,
 }
 
 
-GFile *
-_g_directory_create_unique (GFile       *parent,
-                           const char  *display_name,
-                           const char  *suffix,
-                           GError     **error)
-{
-       GFile    *file = NULL;
-       gboolean  created = FALSE;
-       GError   *local_error = NULL;
-       int       n;
-
-       file = g_file_get_child_for_display_name (parent, display_name, &local_error);
-       if (file == NULL) {
-               g_propagate_error (error, local_error);
-               return NULL;
-       }
-
-       n = 0;
-       do {
-               char *new_display_name;
-
-               if (file != NULL)
-                       g_object_unref (file);
-
-               n++;
-               if (n == 1)
-                       new_display_name = g_strdup_printf ("%s%s", display_name, suffix);
-               else
-                       new_display_name = g_strdup_printf ("%s %d%s", display_name, n, suffix);
-
-               file = g_file_get_child_for_display_name (parent, new_display_name, &local_error);
-               if (local_error == NULL)
-                       created = g_file_make_directory (file, NULL, &local_error);
-
-               if (! created && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
-                       g_clear_error (&local_error);
-
-               g_free (new_display_name);
-       }
-       while (! created && (local_error == NULL));
-
-       if (local_error != NULL) {
-               g_object_unref (file);
-               file = NULL;
-       }
-
-       if (local_error != NULL)
-               g_propagate_error (error, local_error);
-
-       return file;
-}
-
-
-#define MAX_ATTEMPS 10
-
-
 GFile *
 _g_directory_create_tmp (void)
 {
-       GFile *tmp_dir;
-       GFile *dir = NULL;
-       int    n;
+       const int  max_attemps = 10;
+       const int  name_len = 12;
+       GFile     *tmp_dir;
+       GFile     *dir = NULL;
+       int        n;
 
        tmp_dir = g_file_new_for_path (g_get_tmp_dir ());
        if (tmp_dir == NULL)
                return NULL;
 
-       for (n = 0; n < MAX_ATTEMPS; n++) {
+       for (n = 0; n < max_attemps; n++) {
                char  *name;
 
-               name = _g_rand_string (12);
+               name = _g_str_random (name_len);
                dir = g_file_get_child (tmp_dir, name);
                g_free (name);
 
@@ -2688,26 +2215,6 @@ _g_file_write (GFile             *file,
 }
 
 
-gboolean
-_g_directory_make (GFile    *file,
-                  guint32   unix_mode,
-                  GError  **error)
-{
-       if (! g_file_make_directory (file, NULL, error)) {
-               if ((*error)->code != G_IO_ERROR_EXISTS)
-                       return FALSE;
-               g_clear_error (error);
-       }
-
-       return g_file_set_attribute_uint32 (file,
-                                           G_FILE_ATTRIBUTE_UNIX_MODE,
-                                           unix_mode,
-                                           G_FILE_QUERY_INFO_NONE,
-                                           NULL,
-                                           error);
-}
-
-
 gboolean
 _g_file_set_modification_time (GFile         *file,
                               GTimeVal      *timeval,
@@ -2718,10 +2225,10 @@ _g_file_set_modification_time (GFile         *file,
        gboolean   result;
 
        info = g_file_info_new ();
-        g_file_info_set_modification_time (info, timeval);
-        result = g_file_set_attributes_from_info (file, info, G_FILE_QUERY_INFO_NONE, cancellable, error);
+       g_file_info_set_modification_time (info, timeval);
+       result = g_file_set_attributes_from_info (file, info, G_FILE_QUERY_INFO_NONE, cancellable, error);
 
-        g_object_unref (info);
+       g_object_unref (info);
 
-        return result;
+       return result;
 }
diff --git a/gthumb/gio-utils.h b/gthumb/gio-utils.h
index 8184fd0a..3031b3f7 100644
--- a/gthumb/gio-utils.h
+++ b/gthumb/gio-utils.h
@@ -3,7 +3,7 @@
 /*
  *  GThumb
  *
- *  Copyright (C) 2008 Free Software Foundation, Inc.
+ *  Copyright (C) 2008-2019 Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -30,8 +30,6 @@
 
 G_BEGIN_DECLS
 
-/* callback types */
-
 typedef enum { /*< skip >*/
        DIR_OP_CONTINUE,
        DIR_OP_SKIP,
@@ -39,188 +37,156 @@ typedef enum { /*< skip >*/
 } DirOp;
 
 typedef enum {
-       GTH_LIST_DEFAULT = 0,
-       GTH_LIST_RECURSIVE = 1 << 0,
-       GTH_LIST_NO_FOLLOW_LINKS = 1 << 1,
-       GTH_LIST_NO_BACKUP_FILES = 1 << 2,
-       GTH_LIST_NO_HIDDEN_FILES = 1 << 3
+       GTH_LIST_DEFAULT                = 0,
+       GTH_LIST_RECURSIVE              = 1 << 0,
+       GTH_LIST_NO_FOLLOW_LINKS        = 1 << 1,
+       GTH_LIST_NO_BACKUP_FILES        = 1 << 2,
+       GTH_LIST_NO_HIDDEN_FILES        = 1 << 3
 } GthListFlags;
 
 typedef enum { /*< skip >*/
-  GTH_FILE_COPY_DEFAULT            = 0,
-  GTH_FILE_COPY_ALL_METADATA       = (1 << 1),
-  GTH_FILE_COPY_RENAME_SAME_FILE   = (1 << 2)
+       GTH_FILE_COPY_DEFAULT           = 0,
+       GTH_FILE_COPY_ALL_METADATA      = 1 << 1,
+       GTH_FILE_COPY_RENAME_SAME_FILE  = 1 << 2
 } GthFileCopyFlags;
 
-typedef DirOp (*StartDirCallback)    (GFile                *directory,
-                                     GFileInfo            *info,
-                                     GError              **error,
-                                     gpointer              user_data);
-typedef void (*ForEachChildCallback) (GFile                *file,
-                                     GFileInfo            *info,
-                                     gpointer              user_data);
-typedef void (*ListReadyCallback)    (GList                *files,
-                                     GList                *dirs,
-                                     GError               *error,
-                                     gpointer              user_data);
-typedef void (*BufferReadyCallback)  (void                **buffer,
-                                     gsize                 count,
-                                     GError               *error,
-                                     gpointer              user_data);
-typedef void (*InfoReadyCallback)    (GList                *files,
-                                     GError               *error,
-                                     gpointer              user_data);
-typedef void (*CopyReadyCallback)    (GthOverwriteResponse  default_response,
-                                     GList                *other_files,
-                                     GError               *error,
-                                     gpointer              user_data);
-
-/* asynchronous recursive list functions */
-
-void   g_directory_foreach_child     (GFile                 *directory,
-                                     gboolean               recursive,
-                                     gboolean               follow_links,
-                                     const char            *attributes,
-                                     GCancellable          *cancellable,
-                                     StartDirCallback       start_dir_func,
-                                     ForEachChildCallback   for_each_file_func,
-                                     ReadyFunc              done_func,
-                                     gpointer               user_data);
-void   g_directory_list_async        (GFile                 *directory,
-                                     const char            *base_dir,
-                                     gboolean               recursive,
-                                     gboolean               follow_links,
-                                     gboolean               no_backup_files,
-                                     gboolean               no_dot_files,
-                                     const char            *include_files,
-                                     const char            *exclude_files,
-                                     const char            *exclude_folders,
-                                     gboolean               ignorecase,
-                                     GCancellable          *cancellable,
-                                     ListReadyCallback      done_func,
-                                     gpointer               done_data);
-void   _g_query_info_async           (GList                 *file_list,    /* GFile * list */
-                                     GthListFlags           flags,
-                                     const char            *attributes,
-                                     GCancellable          *cancellable,
-                                     InfoReadyCallback      ready_callback,
-                                     gpointer               user_data);
-
-/* asynchronous copy functions */
-
-void     _g_dummy_file_op_async      (ReadyFunc              callback,
-                                     gpointer               user_data);
-void     _g_copy_file_async          (GthFileData           *source,
-                                     GFile                 *destination,
-                                     gboolean               move,
-                                     GthFileCopyFlags       flags,
-                                     GthOverwriteResponse   default_response,
-                                     int                    io_priority,
-                                     GCancellable          *cancellable,
-                                     ProgressCallback       progress_callback,
-                                     gpointer               progress_callback_data,
-                                     DialogCallback         dialog_callback,
-                                     gpointer               dialog_callback_data,
-                                     CopyReadyCallback      ready_callback,
-                                     gpointer               user_data);
-void     _g_copy_files_async         (GList                 *sources,
-                                     GFile                 *destination,
-                                     gboolean               move,
-                                     GthFileCopyFlags       flags,
-                                     GthOverwriteResponse   default_response,
-                                     int                    io_priority,
-                                     GCancellable          *cancellable,
-                                     ProgressCallback       progress_callback,
-                                     gpointer               progress_callback_data,
-                                     DialogCallback         dialog_callback,
-                                     gpointer               dialog_callback_data,
-                                     ReadyFunc              callback,
-                                     gpointer               user_data);
-gboolean _g_move_file                (GFile                 *source,
-                                      GFile                 *destination,
-                                      GFileCopyFlags         flags,
-                                      GCancellable          *cancellable,
-                                      GFileProgressCallback  progress_callback,
-                                      gpointer               progress_callback_data,
-                                      GError               **error);
-gboolean _g_delete_files             (GList                 *file_list,
-                                     gboolean               include_metadata,
-                                     GError               **error);
-void     _g_delete_files_async       (GList                  *file_list,
-                                     gboolean               recursive,
-                                     gboolean               include_metadata,
-                                     GCancellable          *cancellable,
-                                     ReadyFunc              callback,
-                                     gpointer               user_data);
-void     _g_trash_files_async        (GList                 *file_list,
-                                     GCancellable          *cancellable,
-                                     ReadyFunc              callback,
-                                     gpointer               user_data);
-
-/* -- load/write/create file  -- */
-
-gboolean _g_input_stream_read_all    (GInputStream          *istream,
-                                     void                 **buffer,
-                                     gsize                 *size,
-                                     GCancellable          *cancellable,
-                                     GError               **error);
-gboolean _g_file_load_in_buffer      (GFile                 *file,
-                                     void                 **buffer,
-                                     gsize                 *size,
-                                     GCancellable          *cancellable,
-                                     GError               **error);
-void     _g_file_load_async          (GFile                 *file,
-                                     int                    io_priority,
-                                     GCancellable          *cancellable,
-                                     BufferReadyCallback    callback,
-                                     gpointer               user_data);
-gboolean _g_file_write               (GFile                 *file,
-                                     gboolean               make_backup,
-                                     GFileCreateFlags       flags,
-                                     void                  *buffer,
-                                     gsize                  count,
-                                     GCancellable          *cancellable,
-                                     GError               **error);
-void     _g_file_write_async         (GFile                 *file,
-                                     void                  *buffer,
-                                     gsize                  count,
-                                     gboolean               replace,
-                                     int                    io_priority,
-                                     GCancellable          *cancellable,
-                                     BufferReadyCallback    callback,
-                                     gpointer               user_data);
-GFile * _g_file_create_unique        (GFile                 *parent,
-                                     const char            *display_name,
-                                     const char            *suffix,
-                                     GError               **error);
-GFile * _g_directory_create_unique   (GFile                 *parent,
-                                     const char            *display_name,
-                                     const char            *suffix,
-                                     GError               **error);
-GFile * _g_directory_create_tmp      (void);
-gboolean _g_file_set_modification_time (GFile               *file,
-                                       GTimeVal            *timeval,
-                                       GCancellable        *cancellable,
-                                       GError             **error);
-
-/* convenience macros */
-
-/**
- * g_directory_list_all_async:
- * @directory:
- * @base_dir:
- * @recursive:
- * @cancellable:
- * @done_func:
- * @done_data:
- *
- */
-#define g_directory_list_all_async(directory, base_dir, recursive, cancellable, done_func, done_data) \
-    g_directory_list_async ((directory), (base_dir), (recursive), TRUE, FALSE, FALSE, NULL, NULL, NULL, 
FALSE, (cancellable), (done_func), (done_data))
-
-gboolean _g_directory_make (GFile    *file,
-                           guint32   unix_mode,
-                           GError  **error);
+/* Callback types */
+
+typedef DirOp  (*StartDirCallback)             (GFile                   *directory,
+                                                GFileInfo               *info,
+                                                GError                 **error,
+                                                gpointer                 user_data);
+typedef void   (*ForEachChildCallback)         (GFile                   *file,
+                                                GFileInfo               *info,
+                                                gpointer                 user_data);
+typedef void   (*ListReadyCallback)            (GList                   *files,
+                                                GList                   *dirs,
+                                                GError                  *error,
+                                                gpointer                 user_data);
+typedef void   (*BufferReadyCallback)          (void                   **buffer,
+                                                gsize                    count,
+                                                GError                  *error,
+                                                gpointer                 user_data);
+typedef void   (*InfoReadyCallback)            (GList                   *files,
+                                                GError                  *error,
+                                                gpointer                 user_data);
+typedef void   (*CopyReadyCallback)            (GthOverwriteResponse     default_response,
+                                                GList                   *other_files,
+                                                GError                  *error,
+                                                gpointer                 user_data);
+
+/* GFile utils */
+
+gboolean       _g_file_move                    (GFile                   *source,
+                                                GFile                   *destination,
+                                                GFileCopyFlags           flags,
+                                                GCancellable            *cancellable,
+                                                GFileProgressCallback    progress_callback,
+                                                gpointer                 progress_callback_data,
+                                                GError                 **error);
+
+gboolean       _g_file_load_in_buffer          (GFile                   *file,
+                                                void                   **buffer,
+                                                gsize                   *size,
+                                                GCancellable            *cancellable,
+                                                GError                 **error);
+void           _g_file_load_async              (GFile                   *file,
+                                                int                      io_priority,
+                                                GCancellable            *cancellable,
+                                                BufferReadyCallback      callback,
+                                                gpointer                 user_data);
+gboolean       _g_file_write                   (GFile                   *file,
+                                                gboolean                 make_backup,
+                                                GFileCreateFlags         flags,
+                                                void                    *buffer,
+                                                gsize                    count,
+                                                GCancellable            *cancellable,
+                                                GError                 **error);
+void           _g_file_write_async             (GFile                   *file,
+                                                void                    *buffer,
+                                                gsize                    count,
+                                                gboolean                 replace,
+                                                int                      io_priority,
+                                                GCancellable            *cancellable,
+                                                BufferReadyCallback      callback,
+                                                gpointer                 user_data);
+GFile *                _g_file_create_unique           (GFile                   *parent,
+                                                const char              *display_name,
+                                                const char              *suffix,
+                                                GError                 **error);
+gboolean       _g_file_set_modification_time   (GFile                   *file,
+                                                GTimeVal                *timeval,
+                                                GCancellable            *cancellable,
+                                                GError                 **error);
+
+/* Directory utils */
+
+void           _g_directory_foreach_child      (GFile                   *directory,
+                                                gboolean                 recursive,
+                                                gboolean                 follow_links,
+                                                const char              *attributes,
+                                                GCancellable            *cancellable,
+                                                StartDirCallback         start_dir_func,
+                                                ForEachChildCallback     for_each_file_func,
+                                                ReadyFunc                done_func,
+                                                gpointer                 user_data);
+GFile *                _g_directory_create_tmp         (void);
+
+/* GFile list utils */
+
+void           _g_file_list_query_info_async   (GList                   *file_list, /* GFile list */
+                                                GthListFlags             flags,
+                                                const char              *attributes,
+                                                GCancellable            *cancellable,
+                                                InfoReadyCallback        ready_callback,
+                                                gpointer                 user_data);
+void           _g_file_list_copy_async         (GList                   *sources, /* GFile list */
+                                                GFile                   *destination,
+                                                gboolean                 move,
+                                                GthFileCopyFlags         flags,
+                                                GthOverwriteResponse     default_response,
+                                                int                      io_priority,
+                                                GCancellable            *cancellable,
+                                                ProgressCallback         progress_callback,
+                                                gpointer                 progress_callback_data,
+                                                DialogCallback           dialog_callback,
+                                                gpointer                 dialog_callback_data,
+                                                ReadyFunc                callback,
+                                                gpointer                 user_data);
+gboolean       _g_file_list_delete             (GList                   *file_list, /* GFile list */
+                                                gboolean                 include_metadata,
+                                                GError                 **error);
+void           _g_file_list_delete_async       (GList                   *file_list, /* GFile list */
+                                                gboolean                 recursive,
+                                                gboolean                 include_metadata,
+                                                GCancellable            *cancellable,
+                                                ReadyFunc                callback,
+                                                gpointer                 user_data);
+void           _g_file_list_trash_async        (GList                   *file_list, /* GFile list */
+                                                GCancellable            *cancellable,
+                                                ReadyFunc                callback,
+                                                gpointer                 user_data);
+
+/* Misc utils */
+
+void           _gth_file_data_copy_async       (GthFileData             *source,
+                                                GFile                   *destination,
+                                                gboolean                 move,
+                                                GthFileCopyFlags         flags,
+                                                GthOverwriteResponse     default_response,
+                                                int                      io_priority,
+                                                GCancellable            *cancellable,
+                                                ProgressCallback         progress_callback,
+                                                gpointer                 progress_callback_data,
+                                                DialogCallback           dialog_callback,
+                                                gpointer                 dialog_callback_data,
+                                                CopyReadyCallback        ready_callback,
+                                                gpointer                 user_data);
+gboolean       _g_input_stream_read_all        (GInputStream            *istream,
+                                                void                   **buffer,
+                                                gsize                   *size,
+                                                GCancellable            *cancellable,
+                                                GError                 **error);
 
 G_END_DECLS
 
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index e2c179f1..b15da74d 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -3,7 +3,7 @@
 /*
  *  GThumb
  *
- *  Copyright (C) 2001-2008 Free Software Foundation, Inc.
+ *  Copyright (C) 2001-2019 Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 #include <glib/gprintf.h>
 #include <gio/gio.h>
 #include "glib-utils.h"
+#include "uri-utils.h"
 
 #define MAX_PATTERNS 128
 #define BUFFER_SIZE_FOR_SNIFFING 32
@@ -330,8 +331,8 @@ performance (const char *file,
 
 /* taken from the glib function g_date_strftime */
 char *
-struct_tm_strftime (struct tm   *tm,
-                   const char  *format)
+_g_struct_tm_strftime (struct tm   *tm,
+                      const char  *format)
 {
        gsize   locale_format_len = 0;
        char   *locale_format;
@@ -587,7 +588,8 @@ _g_time_val_strftime (GTimeVal   *time_,
 
        secs = time_->tv_sec;
        tm = localtime (&secs);
-       return struct_tm_strftime (tm, format);
+
+       return _g_struct_tm_strftime (tm, format);
 }
 
 
@@ -628,495 +630,57 @@ _g_bookmark_file_set_uris (GBookmarkFile *bookmark,
 }
 
 
-/* String utils */
-
-
-void
-_g_strset (char       **s,
-          const char  *value)
-{
-       if (*s == value)
-               return;
-
-       if (*s != NULL) {
-               g_free (*s);
-               *s = NULL;
-       }
-
-       if (value != NULL)
-               *s = g_strdup (value);
-}
-
-
-char *
-_g_strdup_with_max_size (const char *s,
-                        int         max_size)
-{
-       char *result;
-       int   l = strlen (s);
-
-       if (l > max_size) {
-               char *first_half;
-               char *second_half;
-               int   offset;
-               int   half_max_size = max_size / 2 + 1;
-
-               first_half = g_strndup (s, half_max_size);
-               offset = half_max_size + l - max_size;
-               second_half = g_strndup (s + offset, half_max_size);
-
-               result = g_strconcat (first_half, "…", second_half, NULL);
-
-               g_free (first_half);
-               g_free (second_half);
-       } else
-               result = g_strdup (s);
-
-       return result;
-}
-
-
-/**
- * example 1 : "xxx##yy#" --> [0] = xxx
- *                            [1] = ##
- *                            [2] = yy
- *                            [3] = #
- *                            [4] = NULL
- *
- * example 2 : ""         --> [0] = NULL
- **/
-char **
-_g_get_template_from_text (const char *utf8_template)
-{
-       const char  *chunk_start = utf8_template;
-       char       **str_vect;
-       GList       *str_list = NULL, *scan;
-       int          n = 0;
-
-       if (utf8_template == NULL)
-               return NULL;
-
-       while (*chunk_start != 0) {
-               gunichar    ch;
-               gboolean    reading_sharps;
-               char       *chunk;
-               const char *chunk_end;
-               int         chunk_len = 0;
-
-               reading_sharps = (g_utf8_get_char (chunk_start) == '#');
-               chunk_end = chunk_start;
-
-               ch = g_utf8_get_char (chunk_end);
-               while (reading_sharps
-                      && (*chunk_end != 0)
-                      && (ch == '#')) {
-                       chunk_end = g_utf8_next_char (chunk_end);
-                       ch = g_utf8_get_char (chunk_end);
-                       chunk_len++;
-               }
-
-               ch = g_utf8_get_char (chunk_end);
-               while (! reading_sharps
-                      && (*chunk_end != 0)
-                      && (*chunk_end != '#')) {
-                       chunk_end = g_utf8_next_char (chunk_end);
-                       ch = g_utf8_get_char (chunk_end);
-                       chunk_len++;
-               }
-
-               chunk = _g_utf8_strndup (chunk_start, chunk_len);
-               str_list = g_list_prepend (str_list, chunk);
-               n++;
-
-               chunk_start = chunk_end;
-       }
-
-       str_vect = g_new (char*, n + 1);
-
-       str_vect[n--] = NULL;
-       for (scan = str_list; scan; scan = scan->next)
-               str_vect[n--] = scan->data;
-
-       g_list_free (str_list);
-
-       return str_vect;
-}
-
-
-char *
-_g_get_name_from_template (char **utf8_template,
-                          int    n)
-{
-       GString *s;
-       int      i;
-       char    *result;
-
-       s = g_string_new (NULL);
-
-       for (i = 0; utf8_template[i] != NULL; i++) {
-               const char *chunk = utf8_template[i];
-               gunichar    ch = g_utf8_get_char (chunk);
-
-               if (ch != '#')
-                       g_string_append (s, chunk);
-               else {
-                       char *s_n;
-                       int   s_n_len;
-                       int   sharps_len = g_utf8_strlen (chunk, -1);
-
-                       s_n = g_strdup_printf ("%d", n);
-                       s_n_len = strlen (s_n);
-
-                       while (s_n_len < sharps_len) {
-                               g_string_append_c (s, '0');
-                               sharps_len--;
-                       }
-
-                       g_string_append (s, s_n);
-                       g_free (s_n);
-               }
-       }
-
-       result = s->str;
-       g_string_free (s, FALSE);
-
-       return result;
-}
-
-
-char *
-_g_replace (const char *str,
-           const char *from_str,
-           const char *to_str)
-{
-       char    **tokens;
-       int       i;
-       GString  *gstr;
-
-       if (str == NULL)
-               return NULL;
-
-       if (from_str == NULL)
-               return g_strdup (str);
-
-       if (strcmp (str, from_str) == 0)
-               return g_strdup (to_str);
-
-       tokens = g_strsplit (str, from_str, -1);
-
-       gstr = g_string_new (NULL);
-       for (i = 0; tokens[i] != NULL; i++) {
-               g_string_append (gstr, tokens[i]);
-               if ((to_str != NULL) && (tokens[i+1] != NULL))
-                       g_string_append (gstr, to_str);
-       }
-
-       g_strfreev (tokens);
-
-       return g_string_free (gstr, FALSE);
-}
-
-
-char *
-_g_replace_pattern (const char *utf8_text,
-                   gunichar    pattern,
-                   const char *value)
-{
-       const char *s;
-       GString    *r;
-       char       *r_str;
-
-       if (utf8_text == NULL)
-               return NULL;
-
-       if (g_utf8_strchr (utf8_text, -1, '%') == NULL)
-               return g_strdup (utf8_text);
-
-       r = g_string_new (NULL);
-       for (s = utf8_text; *s != 0; s = g_utf8_next_char (s)) {
-               gunichar ch = g_utf8_get_char (s);
-
-               if (ch == '%') {
-                       s = g_utf8_next_char (s);
-
-                       if (*s == 0) {
-                               g_string_append_unichar (r, ch);
-                               break;
-                       }
-
-                       ch = g_utf8_get_char (s);
-                       if (ch == pattern) {
-                               if (value)
-                                       g_string_append (r, value);
-                       }
-                       else {
-                               g_string_append (r, "%");
-                               g_string_append_unichar (r, ch);
-                       }
-
-               } else
-                       g_string_append_unichar (r, ch);
-       }
-
-       r_str = r->str;
-       g_string_free (r, FALSE);
-
-       return r_str;
-}
-
-
-int
-_g_utf8_first_ascii_space (const char *str)
-{
-       const char *pos;
-
-       pos = str;
-       while (pos != NULL) {
-               gunichar c = g_utf8_get_char (pos);
-               if (c == 0)
-                       break;
-               if (g_ascii_isspace (c))
-                       return g_utf8_pointer_to_offset (str, pos);
-               pos = g_utf8_next_char (pos);
-       }
-
-       return -1;
-}
-
-
-gboolean
-_g_utf8_has_prefix (const char  *string,
-                   const char  *prefix)
-{
-       char     *substring;
-       gboolean  result;
-
-       if (string == NULL)
-               return FALSE;
-       if (prefix == NULL)
-               return TRUE;
-
-       substring = g_utf8_substring (string, 0, g_utf8_strlen (prefix, -1));
-       if (substring == NULL)
-               return FALSE;
-
-       result = g_utf8_collate (substring, prefix) == 0;
-       g_free (substring);
-
-       return result;
-}
-
-
-char *
-_g_utf8_remove_prefix (const char *string,
-                      int         prefix_length)
-{
-       int str_length;
-
-       str_length = g_utf8_strlen (string, -1);
-       if (str_length <= prefix_length)
-               return NULL;
-
-       return g_utf8_substring (string, prefix_length, str_length);
-}
+/* GList utils */
 
 
-char *
-_g_utf8_replace (const char  *string,
-                const char  *pattern,
-                const char  *replacement)
+GList *
+_g_list_prepend_link (GList *list,
+                     GList *link)
 {
-       GRegex *regex;
-       char   *result;
-
-       if (string == NULL)
-               return NULL;
-
-       regex = g_regex_new (pattern, 0, 0, NULL);
-       if (regex == NULL)
-               return NULL;
-
-       result = g_regex_replace_literal (regex, string, -1, 0, replacement, 0, NULL);
-
-       g_regex_unref (regex);
-
-       return result;
+       link->next = list;
+       if (list != NULL) list->prev = link;
+       return link;
 }
 
 
-char *
-_g_utf8_strndup (const char *str,
-                gsize       n)
+GList *
+_g_list_insert_list_before (GList *list1,
+                           GList *sibling,
+                           GList *list2)
 {
-       const char *s = str;
-       char       *result;
-
-       while (n && *s) {
-               s = g_utf8_next_char (s);
-               n--;
-       }
-
-       result = g_strndup (str, s - str);
-
-       return result;
-}
-
-
-const char *
-_g_utf8_strstr (const char *haystack,
-               const char *needle)
-{
-       const char *s;
-       glong       i;
-       glong       haystack_len = g_utf8_strlen (haystack, -1);
-       glong       needle_len = g_utf8_strlen (needle, -1);
-       int         needle_size = strlen (needle);
-
-       s = haystack;
-       for (i = 0; i <= haystack_len - needle_len; i++) {
-               if (strncmp (s, needle, needle_size) == 0)
-                       return s;
-               s = g_utf8_next_char(s);
-       }
-
-       return NULL;
-}
-
-
-char **
-_g_utf8_strsplit (const char *string,
-                 const char *delimiter,
-                 int         max_tokens)
-{
-       GSList      *string_list = NULL, *slist;
-       char       **str_array;
-       const char  *s;
-       guint        n = 0;
-       const char  *remainder;
-
-       g_return_val_if_fail (string != NULL, NULL);
-       g_return_val_if_fail (delimiter != NULL, NULL);
-       g_return_val_if_fail (delimiter[0] != '\0', NULL);
-
-       if (max_tokens < 1)
-               max_tokens = G_MAXINT;
-
-       remainder = string;
-       s = _g_utf8_strstr (remainder, delimiter);
-       if (s != NULL) {
-               gsize delimiter_size = strlen (delimiter);
-
-               while (--max_tokens && (s != NULL)) {
-                       gsize  size = s - remainder;
-                       char  *new_string;
-
-                       new_string = g_new (char, size + 1);
-                       strncpy (new_string, remainder, size);
-                       new_string[size] = 0;
-
-                       string_list = g_slist_prepend (string_list, new_string);
-                       n++;
-                       remainder = s + delimiter_size;
-                       s = _g_utf8_strstr (remainder, delimiter);
-               }
-       }
-       if (*string) {
-               n++;
-               string_list = g_slist_prepend (string_list, g_strdup (remainder));
+  if (!list2)
+    {
+      return list1;
+    }
+  else if (!list1)
+    {
+      return list2;
+    }
+  else if (sibling)
+    {
+      GList *list2_last = g_list_last (list2);
+      if (sibling->prev)
+       {
+         sibling->prev->next = list2;
+         list2->prev = sibling->prev;
+         sibling->prev = list2_last;
+         list2_last->next = sibling;
+         return list1;
        }
-
-       str_array = g_new (char*, n + 1);
-
-       str_array[n--] = NULL;
-       for (slist = string_list; slist; slist = slist->next)
-               str_array[n--] = slist->data;
-
-       g_slist_free (string_list);
-
-       return str_array;
-}
-
-
-char *
-_g_utf8_strstrip (const char *str)
-{
-       if (str == NULL)
-               return NULL;
-       return g_strstrip (g_strdup (str));
-}
-
-
-gboolean
-_g_utf8_all_spaces (const char *utf8_string)
-{
-       gunichar c;
-
-       if (utf8_string == NULL)
-               return TRUE;
-
-       c = g_utf8_get_char (utf8_string);
-       while (c != 0) {
-               if (! g_unichar_isspace (c))
-                       return FALSE;
-               utf8_string = g_utf8_next_char (utf8_string);
-               c = g_utf8_get_char (utf8_string);
+      else
+       {
+         sibling->prev = list2_last;
+         list2_last->next = sibling;
+         return list2;
        }
-
-       return TRUE;
-}
-
-
-char *
-_g_utf8_remove_extension (const char *str)
-{
-       char *p;
-       char *ext;
-       char *dest;
-
-       if ((str == NULL) || ! g_utf8_validate (str, -1, NULL))
-               return NULL;
-
-       p = (char *) str;
-       ext = g_utf8_strrchr (p, -1, g_utf8_get_char ("."));
-       dest = g_strdup (p);
-       g_utf8_strncpy (dest, p, g_utf8_strlen (p, -1) - g_utf8_strlen (ext, -1));
-
-       return dest;
-}
-
-
-char *
-_g_utf8_try_from_any (const char *str)
-{
-       char *utf8_str;
-
-       if (str == NULL)
-               return NULL;
-
-       if (! g_utf8_validate (str, -1, NULL))
-               utf8_str = g_locale_to_utf8 (str, -1, NULL, NULL, NULL);
-       else
-               utf8_str = g_strdup (str);
-
-       return utf8_str;
+    }
+  else
+    {
+      return g_list_concat (list1, list2);
+    }
 }
 
 
-char *
-_g_utf8_from_any (const char *str)
-{
-       char *utf8_str;
-
-       if (str == NULL)
-               return NULL;
-
-       utf8_str = _g_utf8_try_from_any (str);
-       if (utf8_str == NULL)
-               utf8_str = g_strdup (_("(invalid value)"));
-
-       return utf8_str;
-}
-
 
 static int
 remove_from_file_list_and_get_position (GList **file_list,
@@ -1215,457 +779,11 @@ _g_list_reorder (GList  *all_files,
 }
 
 
-GList *
-_g_list_insert_list_before (GList *list1,
-                           GList *sibling,
-                           GList *list2)
-{
-  if (!list2)
-    {
-      return list1;
-    }
-  else if (!list1)
-    {
-      return list2;
-    }
-  else if (sibling)
-    {
-      GList *list2_last = g_list_last (list2);
-      if (sibling->prev)
-       {
-         sibling->prev->next = list2;
-         list2->prev = sibling->prev;
-         sibling->prev = list2_last;
-         list2_last->next = sibling;
-         return list1;
-       }
-      else
-       {
-         sibling->prev = list2_last;
-         list2_last->next = sibling;
-         return list2;
-       }
-    }
-  else
-    {
-      return g_list_concat (list1, list2);
-    }
-}
-
-
-GHashTable *static_strings = NULL;
-static GMutex static_strings_mutex;
-
-
-const char *
-get_static_string (const char *s)
-{
-       const char *result;
-
-       if (s == NULL)
-               return NULL;
-
-       g_mutex_lock (&static_strings_mutex);
-
-       if (static_strings == NULL)
-               static_strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-       if (! g_hash_table_lookup_extended (static_strings, s, (gpointer) &result, NULL)) {
-               result = g_strdup (s);
-               g_hash_table_insert (static_strings,
-                                    (gpointer) result,
-                                    GINT_TO_POINTER (1));
-       }
-
-       g_mutex_unlock (&static_strings_mutex);
-
-       return result;
-}
-
-
-char *
-_g_rand_string (int len)
-{
-       static char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
-       static int   letters_only = 52;
-       static int   whole_alphabet = 62;
-       char        *s;
-       GRand       *rand_gen;
-       int          i;
-
-       s = g_malloc (sizeof (char) * (len + 1));
-       rand_gen = g_rand_new ();
-       for (i = 0; i < len; i++)
-               s[i] = alphabet[g_rand_int_range (rand_gen, 0, (i == 0) ? letters_only : whole_alphabet)];
-       g_rand_free (rand_gen);
-       s[len] = 0;
-
-       return s;
-}
-
-
-int
-_g_strv_find (char       **v,
-             const char  *s)
-{
-       int i;
-
-       for (i = 0; v[i] != NULL; i++) {
-               if (strcmp (v[i], s) == 0)
-                       return i;
-       }
-
-       return -1;
-}
-
-
-gboolean
-_g_strv_contains (char       **v,
-                 const char  *s)
-{
-       return (_g_strv_find (v, s) >= 0);
-}
-
-
-char **
-_g_strv_prepend (char       **str_array,
-                 const char  *str)
-{
-       char **result;
-       int    i;
-       int    j;
-
-       result = g_new (char *, g_strv_length (str_array) + 1);
-       i = 0;
-       result[i++] = g_strdup (str);
-       for (j = 0; str_array[j] != NULL; j++)
-               result[i++] = g_strdup (str_array[j]);
-       result[i] = NULL;
-
-       return result;
-}
-
-
-char **
-_g_strv_concat (char **strv1,
-               char **strv2)
-{
-       char **result;
-       int    i, j;
-
-       result = g_new (char *, g_strv_length (strv1) + g_strv_length (strv2) + 1);
-       i = 0;
-       for (j = 0; strv1[j] != NULL; j++)
-               result[i++] = g_strdup (strv1[j]);
-       for (j = 0; strv2[j] != NULL; j++)
-               result[i++] = g_strdup (strv2[j]);
-       result[i] = NULL;
-
-       return result;
-}
-
-
-gboolean
-_g_strv_remove (char       **str_array,
-                const char  *str)
-{
-       int i;
-       int j;
-
-       if (str == NULL)
-               return FALSE;
-
-       for (i = 0; str_array[i] != NULL; i++)
-               if (strcmp (str_array[i], str) == 0)
-                       break;
-
-       if (str_array[i] == NULL)
-               return FALSE;
-
-       for (j = i; str_array[j] != NULL; j++)
-               str_array[j] = str_array[j + 1];
-
-       return TRUE;
-}
-
-
-char *
-_g_str_remove_suffix (const char *s,
-                     const char *suffix)
-{
-       int s_len;
-       int suffix_len;
-
-       if (s == NULL)
-               return NULL;
-       if (suffix == NULL)
-               return g_strdup (s);
-
-       s_len = strlen (s);
-       suffix_len = strlen (suffix);
-
-       if (suffix_len >= s_len)
-               return g_strdup ("");
-       else
-               return g_strndup (s, s_len - suffix_len);
-}
-
-
-/* based on glib/glib/gmarkup.c (Copyright 2000, 2003 Red Hat, Inc.)
- * This version does not escape ' and ''. Needed  because IE does not recognize
- * &apos; and &quot; */
-void
-_g_string_append_for_html (GString    *str,
-                          const char *text,
-                          gssize      length)
-{
-       const gchar *p;
-       const gchar *end;
-       gunichar     ch;
-       int          state = 0;
-
-       p = text;
-       end = text + length;
-
-       while (p != end) {
-               const char *next;
-
-               next = g_utf8_next_char (p);
-               ch = g_utf8_get_char (p);
-
-               switch (state) {
-               case 1: /* escaped */
-                       if ((ch > 127) || ! g_ascii_isprint ((char) ch))
-                               g_string_append_printf (str, "\\&#%d;", ch);
-                       else
-                               g_string_append_unichar (str, ch);
-                       state = 0;
-                       break;
-
-               default: /* not escaped */
-                       switch (*p) {
-                       case '\\':
-                               state = 1; /* next character is escaped */
-                               break;
-
-                       case '&':
-                               g_string_append (str, "&amp;");
-                               break;
-
-                       case '<':
-                               g_string_append (str, "&lt;");
-                               break;
-
-                       case '>':
-                               g_string_append (str, "&gt;");
-                               break;
-
-                       case '\n':
-                               g_string_append (str, "<br />");
-                               break;
-
-                       default:
-                               if ((ch > 127) ||  ! g_ascii_isprint ((char)ch))
-                                       g_string_append_printf (str, "&#%d;", ch);
-                               else
-                                       g_string_append_unichar (str, ch);
-                               state = 0;
-                               break;
-                       }
-                       break;
-               }
-
-               p = next;
-       }
-}
-
-
-char *
-_g_escape_for_html (const char *text,
-                   gssize      length)
-{
-        GString *str;
-
-        g_return_val_if_fail (text != NULL, NULL);
-
-        if (length < 0)
-                length = strlen (text);
-
-        /* prealloc at least as long as original text */
-        str = g_string_sized_new (length);
-        _g_string_append_for_html (str, text, length);
-
-        return g_string_free (str, FALSE);
-}
-
-
-/* Array utils*/
-
-
-char *
-_g_string_array_join (GPtrArray  *array,
-                     const char *separator)
-{
-       GString *s;
-       int      i;
-
-       s = g_string_new ("");
-       for (i = 0; i < array->len; i++) {
-               if ((i > 0) && (separator != NULL))
-                       g_string_append (s, separator);
-               g_string_append (s, g_ptr_array_index (array, i));
-       }
-
-       return g_string_free (s, FALSE);
-}
-
-
-/* Regexp utils */
-
-static char **
-get_patterns_from_pattern (const char *pattern_string)
-{
-       char **patterns;
-       int    i;
-
-       if (pattern_string == NULL)
-               return NULL;
-
-       patterns = _g_utf8_strsplit (pattern_string, ";", MAX_PATTERNS);
-       for (i = 0; patterns[i] != NULL; i++) {
-               char *p1, *p2;
-
-               p1 = _g_utf8_strstrip (patterns[i]);
-               p2 = _g_replace (p1, ".", "\\.");
-               patterns[i] = _g_replace (p2, "*", ".*");
-
-               g_free (p2);
-               g_free (p1);
-       }
-
-       return patterns;
-}
-
-
-GRegex **
-get_regexps_from_pattern (const char         *pattern_string,
-                         GRegexCompileFlags  compile_options)
-{
-       char   **patterns;
-       GRegex **regexps;
-       int      i;
-
-       patterns = get_patterns_from_pattern (pattern_string);
-       if (patterns == NULL)
-               return NULL;
-
-       regexps = g_new0 (GRegex*, g_strv_length (patterns) + 1);
-       for (i = 0; patterns[i] != NULL; i++)
-               regexps[i] = g_regex_new (patterns[i],
-                                         G_REGEX_OPTIMIZE | compile_options,
-                                         G_REGEX_MATCH_NOTEMPTY,
-                                         NULL);
-       g_strfreev (patterns);
-
-       return regexps;
-}
-
-
-gboolean
-string_matches_regexps (GRegex           **regexps,
-                       const char        *string,
-                       GRegexMatchFlags   match_options)
-{
-       gboolean matched;
-       int      i;
-
-       if ((regexps == NULL) || (regexps[0] == NULL))
-               return TRUE;
-
-       if (string == NULL)
-               return FALSE;
-
-       matched = FALSE;
-       for (i = 0; regexps[i] != NULL; i++)
-               if (g_regex_match (regexps[i], string, match_options, NULL)) {
-                       matched = TRUE;
-                       break;
-       }
-
-       return matched;
-}
-
-
-void
-free_regexps (GRegex **regexps)
-{
-       int i;
-
-       if (regexps == NULL)
-               return;
-
-       for (i = 0; regexps[i] != NULL; i++)
-               g_regex_unref (regexps[i]);
-       g_free (regexps);
-}
-
-
-/* URI utils  */
-
-
-const char *
-get_home_uri (void)
-{
-       static char *home_uri = NULL;
-
-       if (home_uri == NULL) {
-               const char *path;
-               char       *uri;
-
-               path = g_get_home_dir ();
-               uri = g_uri_escape_string (path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
-
-               home_uri = g_strconcat ("file://", uri, NULL);
-
-               g_free (uri);
-       }
-
-       return home_uri;
-}
-
-
-int
-uricmp (const char *uri1,
-       const char *uri2)
-{
-       if (uri1 == NULL) {
-               if (uri2 == NULL)
-                       return 0;
-               else
-                       return -1;
-       }
-
-       if (uri2 == NULL) {
-               if (uri1 == NULL)
-                       return 0;
-               else
-                       return 1;
-       }
-
-       return g_strcmp0 (uri1, uri2);
-}
-
-
-gboolean
-same_uri (const char *uri1,
-         const char *uri2)
-{
-       return uricmp (uri1, uri2) == 0;
-}
-
-
-void
-_g_string_list_free (GList *string_list)
+/* GStringList */
+
+
+void
+_g_string_list_free (GList *string_list)
 {
        if (string_list == NULL)
                return;
@@ -1697,7 +815,7 @@ _g_string_list_to_strv (GList *string_list)
 
        strv = g_new0 (char *, g_list_length (string_list) + 1);
        for (scan = string_list, i = 0; scan; scan = scan->next)
-               strv[i++] = g_strdup ((char *)scan->data);
+               strv[i++] = g_strdup ((char *) scan->data);
        strv[i++] = NULL;
 
        return strv;
@@ -1713,381 +831,201 @@ G_DEFINE_BOXED_TYPE (GStringList,
                     (GBoxedFreeFunc) _g_string_list_free)
 
 
-GList *
-get_file_list_from_url_list (char *url_list)
-{
-       GList *list = NULL;
-       int    i;
-       char  *url_start, *url_end;
-
-       url_start = url_list;
-       while (url_start[0] != '\0') {
-               char *url;
-
-               if (strncmp (url_start, "file:", 5) == 0) {
-                       url_start += 5;
-                       if ((url_start[0] == '/')
-                           && (url_start[1] == '/')) url_start += 2;
-               }
-
-               i = 0;
-               while ((url_start[i] != '\0')
-                      && (url_start[i] != '\r')
-                      && (url_start[i] != '\n')) i++;
-               url_end = url_start + i;
-
-               url = g_strndup (url_start, url_end - url_start);
-               list = g_list_prepend (list, url);
-
-               url_start = url_end;
-               i = 0;
-               while ((url_start[i] != '\0')
-                      && ((url_start[i] == '\r')
-                          || (url_start[i] == '\n'))) i++;
-               url_start += i;
-       }
-
-       return g_list_reverse (list);
-}
-
-
-const char *
-_g_uri_get_basename (const char *uri)
-{
-       register char   *base;
-       register gssize  last_char;
-
-       if (uri == NULL)
-               return NULL;
-
-       if (uri[0] == '\0')
-               return "";
-
-       last_char = strlen (uri) - 1;
-
-       if (uri[last_char] == G_DIR_SEPARATOR)
-               return "";
-
-       base = g_utf8_strrchr (uri, -1, G_DIR_SEPARATOR);
-       if (! base)
-               return uri;
-
-       return base + 1;
-}
-
-
-const char *
-_g_uri_get_file_extension (const char *uri)
-{
-       char *p;
-
-       if (uri == NULL)
-               return NULL;
-
-       p = strrchr (uri, '.');
-       if (p == NULL)
-               return NULL;
-
-       if (p != uri) {
-               char *p2;
-
-               p2 = p - 1;
-               while ((*p2 != '.') && (p2 != uri))
-                       p2--;
-               if (strncmp (p2, ".tar.", 5) == 0)
-                       p = p2;
-       }
-
-       return p;
-}
-
-
-static gboolean
-uri_is_filetype (const char *uri,
-                GFileType   file_type)
-{
-       gboolean   result = FALSE;
-       GFile     *file;
-       GFileInfo *info;
-       GError    *error = NULL;
-
-       file = g_file_new_for_uri (uri);
-
-       if (! g_file_query_exists (file, NULL)) {
-               g_object_unref (file);
-               return FALSE;
-       }
-
-       info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, 0, NULL, &error);
-       if (error == NULL) {
-               result = (g_file_info_get_file_type (info) == file_type);
-       }
-       else {
-               g_warning ("Failed to get file type for uri %s: %s", uri, error->message);
-               g_error_free (error);
-       }
-
-       g_object_unref (info);
-       g_object_unref (file);
-
-       return result;
-}
-
-
-gboolean
-_g_uri_is_file (const char *uri)
-{
-       return uri_is_filetype (uri, G_FILE_TYPE_REGULAR);
-}
-
-
-gboolean
-_g_uri_is_dir (const char *uri)
-{
-       return uri_is_filetype (uri, G_FILE_TYPE_DIRECTORY);
-}
-
-
-gboolean
-_g_uri_parent_of_uri (const char *dirname,
-                     const char *filename)
-{
-       int dirname_l, filename_l, separator_position;
-
-       if ((dirname == NULL) || (filename == NULL))
-               return FALSE;
-
-       dirname_l = strlen (dirname);
-       filename_l = strlen (filename);
-
-       if ((dirname_l == filename_l + 1)
-           && (dirname[dirname_l - 1] == '/'))
-               return FALSE;
-
-       if ((filename_l == dirname_l + 1)
-           && (filename[filename_l - 1] == '/'))
-               return FALSE;
-
-       if (dirname[dirname_l - 1] == '/')
-               separator_position = dirname_l - 1;
-       else
-               separator_position = dirname_l;
-
-       return ((filename_l > dirname_l)
-               && (strncmp (dirname, filename, dirname_l) == 0)
-               && (filename[separator_position] == '/'));
-}
+/* Array utils*/
 
 
 char *
-_g_uri_get_parent (const char *uri)
+_g_string_array_join (GPtrArray  *array,
+                     const char *separator)
 {
-       int         p;
-       const char *ptr = uri;
-       char       *new_uri;
-
-       if (uri == NULL)
-               return NULL;
-
-       p = strlen (uri) - 1;
-       if (p < 0)
-               return NULL;
+       GString *s;
+       int      i;
 
-       while ((p > 0) && (ptr[p] != '/'))
-               p--;
-       if ((p == 0) && (ptr[p] == '/'))
-               p++;
-       new_uri = g_strndup (uri, (guint)p);
+       s = g_string_new ("");
+       for (i = 0; i < array->len; i++) {
+               if ((i > 0) && (separator != NULL))
+                       g_string_append (s, separator);
+               g_string_append (s, g_ptr_array_index (array, i));
+       }
 
-       return new_uri;
+       return g_string_free (s, FALSE);
 }
 
 
-char *
-_g_uri_remove_extension (const char *uri)
+/* Regexp utils */
+
+
+/* A pattern is a simpler version of a regexp, where
+ * dots are literal and asterisks mean any sequence of characters. */
+static char *
+_pattern_to_regexp (const char *pattern)
 {
-       const char *ext;
+       char *tmp;
+       char *regexp;
 
-       if (uri == NULL)
-               return NULL;
+       tmp = _g_utf8_strip (pattern);
+       regexp = _g_utf8_translate (tmp,
+                       ".", "\\.",
+                       "*", ".*",
+                       NULL);
 
-       ext = _g_uri_get_file_extension (uri);
-       if (ext == NULL)
-               return g_strdup (uri);
-       else
-               return g_strndup (uri, strlen (uri) - strlen (ext));
+       g_free (tmp);
+
+       return regexp;
 }
 
 
-char *
-_g_build_uri (const char *base, ...)
+static char **
+_split_patterns (const char *pattern,
+                int        *p_size)
 {
-       va_list     args;
-       const char *child;
-       GString    *uri;
+       char **strv;
+       int    i;
+       int    size;
 
-       uri = g_string_new (base);
+       if (pattern == NULL)
+               return NULL;
 
-       va_start (args, base);
-       while ((child = va_arg (args, const char *)) != NULL) {
-               if (! g_str_has_suffix (uri->str, "/") && ! g_str_has_prefix (child, "/"))
-                       g_string_append (uri, "/");
-               g_string_append (uri, child);
-       }
-       va_end (args);
+       strv = _g_utf8_split (pattern, ";", MAX_PATTERNS);
+       size = 0;
+       for (i = 0; strv[i] != NULL; i++) {
+               char *tmp;
 
-       return g_string_free (uri, FALSE);
-}
+               tmp = strv[i];
+               strv[i] = _pattern_to_regexp (strv[i]);
+               size++;
 
+               g_free (tmp);
+       }
 
-char *
-_g_uri_get_scheme (const char *uri)
-{
-       const char *idx;
+       if (p_size != NULL) *p_size = size;
 
-       idx = strstr (uri, "://");
-       if (idx == NULL)
-               return NULL;
-       else
-               return g_strndup (uri, (idx - uri) + 3);
+       return strv;
 }
 
 
-const char *
-_g_uri_remove_host (const char *uri)
+GRegex **
+_g_regex_v_from_pattern (const char         *pattern,
+                        GRegexCompileFlags  compile_options)
 {
-       const char *idx, *sep;
+       char   **patternv;
+       int      size;
+       GRegex **regexps;
+       int      i;
 
-       if (uri == NULL)
+       patternv = _split_patterns (pattern, &size);
+       if (patternv == NULL)
                return NULL;
 
-       idx = strstr (uri, "://");
-       if (idx == NULL)
-               return uri;
-
-       idx += 3;
-       if (*idx == '\0')
-               return "/";
-
-       sep = strstr (idx, "/");
-       if (sep == NULL)
-               return idx;
+       regexps = g_new0 (GRegex*, size + 1);
+       for (i = 0; patternv[i] != NULL; i++) {
+               regexps[i] = g_regex_new (patternv[i],
+                                         G_REGEX_OPTIMIZE | compile_options,
+                                         G_REGEX_MATCH_NOTEMPTY,
+                                         NULL);
+       }
+       g_strfreev (patternv);
 
-       return sep;
+       return regexps;
 }
 
 
-char *
-_g_uri_get_host (const char *uri)
+gboolean
+_g_regex_v_match (GRegex           **regexps,
+                 const char        *str,
+                 GRegexMatchFlags   match_options)
 {
-       const char *idx;
+       gboolean matched;
+       int      i;
 
-       idx = strstr (uri, "://");
-       if (idx == NULL)
-               return g_strdup ("file://");
+       if ((regexps == NULL) || (regexps[0] == NULL))
+               return TRUE;
 
-       idx = strstr (idx + 3, "/");
-       if (idx == NULL) {
-               char *scheme;
+       if (str == NULL)
+               return FALSE;
 
-               scheme = _g_uri_get_scheme (uri);
-               if (scheme == NULL)
-                       scheme = g_strdup ("file://");
-               return scheme;
+       matched = FALSE;
+       for (i = 0; regexps[i] != NULL; i++)
+               if (g_regex_match (regexps[i], str, match_options, NULL)) {
+                       matched = TRUE;
+                       break;
        }
 
-       return g_strndup (uri, (idx - uri));
+       return matched;
 }
 
 
-/* example 1 : uri      = file:///xxx/yyy/zzz/foo
- *             base     = file:///xxx/www
- *             return   : ../yyy/zzz/foo
- *
- * example 2 : uri      = file:///xxx/yyy/foo
- *             base     = file:///xxx
- *             return   : yyy/foo
- *
- * example 3 : uri      = smb:///xxx/yyy/foo
- *             base     = file://hhh/xxx
- *             return   : smb:///xxx/yyy/foo
- *
- * example 4 : uri      = file://hhh/xxx
- *             base     = file://hhh/xxx
- *             return   : ./
- */
-char *
-_g_uri_get_relative_path (const char *uri,
-                         const char *base)
-{
-       char      *uri_host;
-       char      *base_host;
-       gboolean   same_host;
-       char      *source_dir;
-       char     **source_dir_v;
-       char     **base_v;
-       GString   *relative_path;
-       int        i, j;
-
-       if ((uri == NULL) || (base == NULL))
-               return NULL;
+void
+_g_regex_v_free (GRegex **regexps)
+{
+       int i;
+
+       if (regexps == NULL)
+               return;
+
+       for (i = 0; regexps[i] != NULL; i++)
+               g_regex_unref (regexps[i]);
+       g_free (regexps);
+}
 
-       if (strcmp (uri, base) == 0)
-               return g_strdup ("./");
 
-       uri_host = _g_uri_get_host (uri);
-       base_host = _g_uri_get_host (base);
-       same_host = g_str_equal (uri_host, base_host);
+/* URI utils  */
 
-       g_free (base_host);
-       g_free (uri_host);
 
-       if (! same_host)
-               return g_strdup (uri);
+static gboolean
+_g_uri_query_is_filetype (const char *uri,
+                         GFileType   file_type)
+{
+       gboolean   result = FALSE;
+       GFile     *file;
+       GFileInfo *info;
+       GError    *error = NULL;
 
-       source_dir = _g_uri_get_parent (_g_uri_remove_host (uri));
-       source_dir_v = g_strsplit (source_dir, "/", 0);
-       base_v = g_strsplit (_g_uri_remove_host (base), "/", 0);
+       file = g_file_new_for_uri (uri);
 
-       relative_path = g_string_new (NULL);
+       if (! g_file_query_exists (file, NULL)) {
+               g_object_unref (file);
+               return FALSE;
+       }
 
-       i = 0;
-       while ((source_dir_v[i] != NULL)
-              && (base_v[i] != NULL)
-              && (strcmp (source_dir_v[i], base_v[i]) == 0))
-       {
-               i++;
+       info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, 0, NULL, &error);
+       if (error == NULL) {
+               result = (g_file_info_get_file_type (info) == file_type);
+       }
+       else {
+               g_warning ("Failed to get file type for uri %s: %s", uri, error->message);
+               g_error_free (error);
        }
 
-       j = i;
+       g_object_unref (info);
+       g_object_unref (file);
 
-       while (base_v[i++] != NULL)
-               g_string_append (relative_path, "../");
+       return result;
+}
 
-       while (source_dir_v[j] != NULL) {
-               g_string_append (relative_path, source_dir_v[j]);
-               g_string_append_c (relative_path, '/');
-               j++;
-       }
 
-       g_string_append (relative_path, _g_uri_get_basename (uri));
+gboolean
+_g_uri_query_is_file (const char *uri)
+{
+       return _g_uri_query_is_filetype (uri, G_FILE_TYPE_REGULAR);
+}
 
-       g_strfreev (base_v);
-       g_strfreev (source_dir_v);
-       g_free (source_dir);
 
-       return g_string_free (relative_path, FALSE);
+gboolean
+_g_uri_query_is_dir (const char *uri)
+{
+       return _g_uri_query_is_filetype (uri, G_FILE_TYPE_DIRECTORY);
 }
 
 
 char *
 _g_filename_clear_for_file (const char *display_name)
 {
-       return _g_utf8_replace (display_name, "/", "_");
+       return _g_utf8_replace_str (display_name, "/", "_");
 }
 
 
-/* GIO utils */
+/* GFile utils */
 
 
 GFile *
@@ -2102,7 +1040,7 @@ _g_file_new_for_display_name (const char *base_uri,
 
        base = g_file_new_for_uri (base_uri);
        name = g_strdup_printf ("%s%s", display_name, extension);
-       name_escaped = _g_utf8_replace (name, "/", ".");
+       name_escaped = _g_utf8_replace_str (name, "/", ".");
        catalog_file = g_file_get_child_for_display_name (base, name_escaped, NULL);
 
        g_free (name_escaped);
@@ -2127,50 +1065,35 @@ _g_file_equal (GFile *file1,
 
 
 char *
-_g_file_get_display_name_no_io (GFile *file)
+_g_file_get_display_name (GFile *file)
 {
-       char       *name;
-       char       *uri;
-       const char *basename;
+       char     *name = NULL;
+       char     *uri;
+       UriParts  parts;
 
-       name = NULL;
        uri = g_file_get_uri (file);
-       basename = _g_uri_get_basename (uri);
-       if (basename != NULL)
-               name = g_uri_unescape_string (basename, NULL);
-       else
-               name = g_strdup ("/");
-
-       g_free (uri);
-
-       return name;
-}
-
+       if (_g_uri_split (uri, &parts)) {
+               name = g_strdup (_g_path_get_basename (parts.path));
+               if (name == NULL) {
+                       if (parts.host != NULL)
+                               name = g_strdup (parts.host);
+                       else
+                               name = g_strdup ("/");
+               }
 
-char *
-_g_file_get_display_name (GFile *file)
-{
-       char      *name = NULL;
-       GFileInfo *file_info;
-
-       file_info = g_file_query_info (file,
-                                      G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
-                                      G_FILE_QUERY_INFO_NONE,
-                                      NULL,
-                                      NULL);
-       if (file_info != NULL) {
-               name = g_strdup (g_file_info_get_attribute_string (file_info, 
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME));
-               g_object_unref (file_info);
+               _g_uri_parts_clear (&parts);
        }
        else
-               name = g_file_get_parse_name (file);
+               name = g_strdup (_("(invalid value)"));
+
+       g_free (uri);
 
        return name;
 }
 
 
 GFileType
-_g_file_get_standard_type (GFile *file)
+_g_file_query_standard_type (GFile *file)
 {
        GFileType  result;
        GFileInfo *info;
@@ -2194,16 +1117,18 @@ _g_file_get_standard_type (GFile *file)
 
 GFile *
 _g_file_get_destination (GFile *source,
-                        GFile *source_base,
-                        GFile *destination_folder)
+                        GFile *source_base,
+                        GFile *destination_folder)
 {
        char       *source_uri;
+       char       *basename;
        const char *source_suffix;
        char       *destination_folder_uri;
        char       *destination_uri;
        GFile      *destination;
 
        source_uri = g_file_get_uri (source);
+       basename = _g_uri_get_basename (source_uri);
        if (source_base != NULL) {
                char *source_base_uri;
 
@@ -2213,7 +1138,7 @@ _g_file_get_destination (GFile *source,
                g_free (source_base_uri);
        }
        else
-               source_suffix = _g_uri_get_basename (source_uri);
+               source_suffix = basename;
 
        destination_folder_uri = g_file_get_uri (destination_folder);
        destination_uri = g_strconcat (destination_folder_uri, "/", source_suffix, NULL);
@@ -2221,6 +1146,7 @@ _g_file_get_destination (GFile *source,
 
        g_free (destination_uri);
        g_free (destination_folder_uri);
+       g_free (basename);
        g_free (source_uri);
 
        return destination;
@@ -2236,6 +1162,7 @@ _g_file_get_duplicated (GFile *file)
        GRegex     *regex;
        GMatchInfo *match_info;
        GFile      *duplicated;
+       char       *ext;
 
        new_uri = g_string_new ("");
        uri = g_file_get_uri (file);
@@ -2262,9 +1189,11 @@ _g_file_get_duplicated (GFile *file)
                g_string_append (new_uri, "%20(2)");
        }
 
-       g_string_append (new_uri, _g_uri_get_file_extension (uri));
+       ext = _g_uri_get_extension (uri);
+       g_string_append (new_uri, ext);
        duplicated = g_file_new_for_uri (new_uri->str);
 
+       g_free (ext);
        g_match_info_free (match_info);
        g_regex_unref (regex);
        g_free (uri_noext);
@@ -2299,51 +1228,6 @@ _g_file_get_child (GFile *file,
 }
 
 
-GIcon *
-_g_file_get_icon (GFile *file)
-{
-       GIcon     *icon = NULL;
-       GFileInfo *file_info;
-
-       file_info = g_file_query_info (file,
-                                      G_FILE_ATTRIBUTE_STANDARD_ICON,
-                                      G_FILE_QUERY_INFO_NONE,
-                                      NULL,
-                                      NULL);
-       if (file_info != NULL) {
-               icon = (GIcon*) g_object_ref (g_file_info_get_attribute_object (file_info, 
G_FILE_ATTRIBUTE_STANDARD_ICON));
-               g_object_unref (file_info);
-       }
-
-       if (icon == NULL)
-               icon = g_themed_icon_new ("file");
-
-       return icon;
-}
-
-GIcon *
-_g_file_get_symbolic_icon (GFile *file)
-{
-       GIcon     *icon = NULL;
-       GFileInfo *file_info;
-
-       file_info = g_file_query_info (file,
-                                      G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON,
-                                      G_FILE_QUERY_INFO_NONE,
-                                      NULL,
-                                      NULL);
-       if (file_info != NULL) {
-               icon = (GIcon*) g_object_ref (g_file_info_get_attribute_object (file_info, 
G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON));
-               g_object_unref (file_info);
-       }
-
-       if (icon == NULL)
-               icon = g_themed_icon_new ("text-x-generic-symbolic");
-
-       return icon;
-}
-
-
 GList *
 _g_file_list_dup (GList *l)
 {
@@ -2364,16 +1248,6 @@ _g_file_list_free (GList *l)
 }
 
 
-GList *
-_g_file_list_new_from_uri_list (GList *uris)
-{
-       GList *r = NULL, *scan;
-       for (scan = uris; scan; scan = scan->next)
-               r = g_list_prepend (r, g_file_new_for_uri ((char*)scan->data));
-       return g_list_reverse (r);
-}
-
-
 GList *
 _g_file_list_new_from_uriv (char **uris)
 {
@@ -2403,9 +1277,9 @@ _g_file_list_find_file (GList *l,
 }
 
 
-const char*
-_g_file_get_mime_type (GFile    *file,
-                      gboolean  fast_file_type)
+const char *
+_g_file_query_mime_type (GFile    *file,
+                        gboolean  fast_file_type)
 {
        GFileInfo  *info;
        GError     *err = NULL;
@@ -2425,7 +1299,7 @@ _g_file_get_mime_type (GFile    *file,
                g_clear_error (&err);
        }
        else {
-               result = get_static_string (g_content_type_get_mime_type (g_file_info_get_content_type 
(info)));
+               result = _g_str_get_static (g_content_type_get_mime_type (g_file_info_get_content_type 
(info)));
                g_object_unref (info);
        }
 
@@ -2433,46 +1307,6 @@ _g_file_get_mime_type (GFile    *file,
 }
 
 
-void
-_g_file_get_modification_time (GFile    *file,
-                              GTimeVal *result)
-{
-       GFileInfo *info;
-       GError    *err = NULL;
-
-       result->tv_sec = 0;
-       result->tv_usec = 0;
-
-       info = g_file_query_info (file,
-                                 G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
-                                 0,
-                                 NULL,
-                                 &err);
-       if (info != NULL) {
-               g_file_info_get_modification_time (info, result);
-               g_object_unref (info);
-       }
-       else {
-               char *uri;
-
-               uri = g_file_get_uri (file);
-               g_warning ("could not get modification time for %s: %s", uri, err->message);
-               g_free (uri);
-               g_clear_error (&err);
-       }
-}
-
-
-time_t
-_g_file_get_mtime (GFile *file)
-{
-       GTimeVal timeval;
-
-       _g_file_get_modification_time (file, &timeval);
-       return (time_t) timeval.tv_sec;
-}
-
-
 int
 _g_file_cmp_uris (GFile *a,
                  GFile *b)
@@ -2493,201 +1327,63 @@ _g_file_cmp_uris (GFile *a,
 
 
 gboolean
-_g_file_equal_uris (GFile *a,
-                   GFile *b)
-{
-       return _g_file_cmp_uris (a, b) == 0;
-}
-
-
-int
-_g_file_cmp_modification_time (GFile *file_a,
-                              GFile *file_b)
-{
-       GTimeVal timeval_a;
-       GTimeVal timeval_b;
-
-       _g_file_get_modification_time (file_a, &timeval_a);
-       _g_file_get_modification_time (file_b, &timeval_b);
-
-       return _g_time_val_cmp (&timeval_a, &timeval_b);
-}
-
-
-goffset
-_g_file_get_size (GFile *file)
-{
-       GFileInfo *info;
-       GError    *err = NULL;
-       goffset    size = 0;
-
-       info = g_file_query_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_SIZE, 0, NULL, &err);
-       if (info != NULL) {
-               size = g_file_info_get_size (info);
-               g_object_unref (info);
-       }
-       else {
-               char *uri;
-
-               uri = g_file_get_uri (file);
-               g_warning ("could not get size for %s: %s", uri, err->message);
-               g_free (uri);
-               g_clear_error (&err);
-       }
-
-       return size;
-}
-
-
-#define MAX_SYMLINKS 32
-
-
-static GFile *
-resolve_symlinks (GFile   *file,
-                 GError **error,
-                 int      level)
+_g_file_has_scheme (GFile      *file,
+                   const char *scheme)
 {
-       GFile *resolved;
-       char  *path;
-       char **names;
-       int    i;
-
-       if (level > MAX_SYMLINKS) {
-               char *uri;
-
-               uri = g_file_get_uri (file);
-               *error = g_error_new (G_IO_ERROR, G_IO_ERROR_TOO_MANY_LINKS, "Too many symbolic links for 
file: %s.", uri);
-               g_free (uri);
-
-               return NULL;
-       }
-
-       path = g_file_get_path (file);
-       if (path == NULL)
-               return g_file_dup (file);
-
-       resolved = g_file_new_for_path (G_DIR_SEPARATOR_S);
-
-       names = g_strsplit (path, G_DIR_SEPARATOR_S, -1);
-       for (i = 0; names[i] != NULL; i++) {
-               GFile     *child;
-               GFileInfo *info;
-               GFile     *new_resolved;
-
-               if (strcmp (names[i], "") == 0)
-                       continue;
-
-               child = g_file_get_child (resolved, names[i]);
-               info = g_file_query_info (child, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "," 
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, 0, NULL, error);
-               if (info == NULL) {
-                       g_object_unref (child);
-                       g_object_unref (resolved);
-                       resolved = NULL;
-                       break;
-               }
-
-               /* if names[i] isn't a symbolic link add it to the resolved path and continue */
-
-               if (! g_file_info_get_is_symlink (info)) {
-                       g_object_unref (info);
-                       g_object_unref (resolved);
-                       resolved = child;
-                       continue;
-               }
-
-               g_object_unref (child);
-
-               /* names[i] is a symbolic link */
-
-               new_resolved = g_file_resolve_relative_path (resolved, g_file_info_get_symlink_target (info));
-
-               g_object_unref (resolved);
-               g_object_unref (info);
-
-               resolved = resolve_symlinks (new_resolved, error, level + 1);
-
-               g_object_unref (new_resolved);
-       }
-
-       g_strfreev (names);
-       g_free (path);
+       char     *file_scheme;
+       gboolean  result;
 
-       return resolved;
-}
+       file_scheme = g_file_get_uri_scheme (file);
+       result = _g_str_equal (file_scheme, scheme);
 
+       g_free (file_scheme);
 
-GFile *
-_g_file_resolve_all_symlinks (GFile   *file,
-                             GError **error)
-{
-       return resolve_symlinks (file, error, 0);
+       return result;
 }
 
 
 gboolean
-_g_file_has_prefix (GFile *file,
-                   GFile *prefix)
+_g_file_is_parent (GFile *dir,
+                  GFile *file)
 {
+       char     *dir_uri;
        char     *file_uri;
-       char     *prefix_uri;
        gboolean  result;
 
+       dir_uri = g_file_get_uri (dir);
        file_uri = g_file_get_uri (file);
-       prefix_uri = g_file_get_uri (prefix);
-       if (! g_str_has_suffix (prefix_uri, "/")) {
-               char *tmp;
-
-               tmp = g_strconcat (prefix_uri, "/", NULL);
-               g_free (prefix_uri);
-               prefix_uri = tmp;
-       }
-       result = g_str_has_prefix (file_uri, prefix_uri);
+       result = _g_uri_is_parent (dir_uri, file_uri);
 
-       g_free (prefix_uri);
        g_free (file_uri);
+       g_free (dir_uri);
 
        return result;
 }
 
 
-GFile *
-_g_file_append_prefix (GFile      *file,
-                      const char *prefix)
-{
-       char  *uri;
-       char  *new_uri;
-       GFile *new_file;
-
-       uri = g_file_get_uri (file);
-       new_uri = g_strconcat (prefix, uri, NULL);
-       new_file = g_file_new_for_uri (new_uri);
-
-       g_free (new_uri);
-       g_free (uri);
-
-       return new_file;
-}
-
-
 GFile *
 _g_file_append_path (GFile      *file,
                     const char *path)
 {
-       char  *uri;
-       char  *escaped;
-       char  *new_uri;
-       GFile *new_file;
+       char     *uri;
+       UriParts  parts;
+       char     *new_path;
+       char     *new_uri;
+       GFile    *new_file;
 
        if (path == NULL)
                return g_file_dup (file);
 
        uri = g_file_get_uri (file);
-       escaped = g_uri_escape_string (path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE);
-       new_uri = _g_build_uri (uri, escaped, NULL);
+       _g_uri_split (uri, &parts);
+       new_path = _g_path_join (parts.path, path, NULL);
+       _g_str_set (&parts.path, new_path);
+       new_uri = _g_uri_join (&parts);
        new_file = g_file_new_for_uri (new_uri);
 
        g_free (new_uri);
-       g_free (escaped);
+       _g_uri_parts_clear (&parts);
+       g_free (new_path);
        g_free (uri);
 
        return new_file;
@@ -3010,12 +1706,10 @@ _g_content_type_guess_from_name (const char *filename)
                return NULL;
 
 #if WEBP_IS_UNKNOWN_TO_GLIB
-       const char *ext;
-
-       ext = _g_uri_get_file_extension (filename);
-       if (g_strcmp0 (ext, ".webp") == 0)
+       if (_g_str_equal (_g_path_get_extension (filename), ".webp"))
                return "image/webp";
 #endif
+
        return g_content_type_guess (filename, NULL, 0, NULL);
 }
 
@@ -3144,15 +1838,17 @@ gboolean
 _g_mime_type_is_image (const char *mime_type)
 {
        g_return_val_if_fail (mime_type != NULL, FALSE);
-       return (g_content_type_is_a (mime_type, "image/*"));
+
+       return g_content_type_is_a (mime_type, "image/*");
 }
 
 
 gboolean
 _g_mime_type_is_raw (const char *mime_type)
 {
-        g_return_val_if_fail (mime_type != NULL, FALSE);
-        return (g_content_type_is_a (mime_type, "image/x-dcraw"));
+       g_return_val_if_fail (mime_type != NULL, FALSE);
+
+       return g_content_type_is_a (mime_type, "image/x-dcraw");
 }
 
 
@@ -3201,7 +1897,7 @@ _g_settings_get_uri (GSettings  *settings,
                return NULL;
        }
 
-       uri = _g_replace (value, "file://~", get_home_uri ());
+       uri = _g_utf8_replace_str (value, "file://~", _g_uri_get_home ());
 
        g_free (value);
 
@@ -3227,11 +1923,11 @@ _g_settings_get_uri_or_special_dir (GSettings      *settings,
                if (dir != NULL)
                        uri = g_filename_to_uri (dir, NULL, NULL);
                if (uri == NULL)
-                       uri = g_strdup (get_home_uri ());
+                       uri = g_strdup (_g_uri_get_home ());
        }
        else {
                char *tmp = uri;
-               uri = _g_replace (tmp, "file://~", get_home_uri ());
+               uri = _g_utf8_replace_str (tmp, "file://~", _g_uri_get_home ());
                g_free (tmp);
        }
 
@@ -3340,16 +2036,6 @@ _g_format_duration_for_display (gint64 msecs)
 }
 
 
-GList *
-_g_list_prepend_link (GList *list,
-                     GList *link)
-{
-       link->next = list;
-       if (list != NULL) list->prev = link;
-       return link;
-}
-
-
 void
 _g_error_free (GError *error)
 {
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 17472263..9ac6c107 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -3,7 +3,7 @@
 /*
  *  GThumb
  *
- *  Copyright (C) 2001-2008 Free Software Foundation, Inc.
+ *  Copyright (C) 2001-2019 Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -26,15 +26,17 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 #include "typedefs.h"
+#include "str-utils.h"
+#include "uri-utils.h"
 
 G_BEGIN_DECLS
 
 /* Math */
 
-#define GDOUBLE_ROUND_TO_INT(x)        ((int) floor ((x) + 0.5))
-#define SQR(x)                 ((x) * (x))
-#define MIN3(x,y,z)            ((y) <= (z) ? MIN ((x), (y)) : MIN ((x), (z)))
-#define MAX3(x,y,z)            ((y) >= (z) ? MAX ((x), (y)) : MAX ((x), (z)))
+#define GDOUBLE_ROUND_TO_INT(x) ((int) floor ((x) + 0.5))
+#define SQR(x) ((x) * (x))
+#define MIN3(x,y,z) ((y) <= (z) ? MIN ((x), (y)) : MIN ((x), (z)))
+#define MAX3(x,y,z) ((y) >= (z) ? MAX ((x), (y)) : MAX ((x), (z)))
 
 /* GFile attributes */
 
@@ -42,7 +44,7 @@ G_BEGIN_DECLS
 #define GFILE_DISPLAY_ATTRIBUTES "standard::display-name,standard::icon,standard::symbolic-icon"
 #define GFILE_BASIC_ATTRIBUTES GFILE_DISPLAY_ATTRIBUTES ",standard::name,standard::type"
 
-#define DEFINE_STANDARD_ATTRIBUTES(a) ( \
+#define DEFINE_STANDARD_ATTRIBUTES(rest) \
        "standard::type," \
        "standard::is-hidden," \
        "standard::is-backup," \
@@ -58,52 +60,73 @@ G_BEGIN_DECLS
        "time::modified," \
        "time::modified-usec," \
        "access::*" \
-       a)
-#define GFILE_STANDARD_ATTRIBUTES (DEFINE_STANDARD_ATTRIBUTES(""))
-#define GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE 
(DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type"))
-#define GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE 
(DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type,standard::content-type"))
-#define GIO_ATTRIBUTES 
("standard::*,etag::*,id::*,access::*,mountable::*,time::*,unix::*,dos::*,owner::*,thumbnail::*,filesystem::*,gvfs::*,xattr::*,xattr-sys::*,selinux::*")
+       rest
+
+#define GFILE_STANDARD_ATTRIBUTES DEFINE_STANDARD_ATTRIBUTES("")
+#define GFILE_STANDARD_ATTRIBUTES_WITH_FAST_CONTENT_TYPE 
DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type")
+#define GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE 
DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type,standard::content-type")
+#define GIO_ATTRIBUTES 
"standard::*,etag::*,id::*,access::*,mountable::*,time::*,unix::*,dos::*,owner::*,thumbnail::*,filesystem::*,gvfs::*,xattr::*,xattr-sys::*,selinux::*"
 #define GTH_FILE_ATTRIBUTE_EMBLEMS "gth::file::emblems"
 
-#define GNOME_COPIED_FILES (gdk_atom_intern_static_string ("x-special/gnome-copied-files"))
+#define GNOME_COPIED_FILES gdk_atom_intern_static_string ("x-special/gnome-copied-files")
 #define IROUND(x) ((int)floor(((double)x) + 0.5))
 #define FLOAT_EQUAL(a,b) (fabs (a - b) < 1e-6)
 #define ID_LENGTH 8
-#define G_TYPE_OBJECT_LIST (g_object_list_get_type ())
-#define G_TYPE_STRING_LIST (g_string_list_get_type ())
-#ifndef G_TYPE_ERROR
-#define NEED_G_TYPE_ERROR 1
-#define G_TYPE_ERROR (g_error_get_type ())
-#endif
+#define G_TYPE_OBJECT_LIST g_object_list_get_type ()
+#define G_TYPE_STRING_LIST g_string_list_get_type ()
 
 #define DEFAULT_STRFTIME_FORMAT "%Y-%m-%d--%H.%M.%S"
-#define DEF_ACTION_CALLBACK(x) void x (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+#define DEF_ACTION_CALLBACK(name) void name (GSimpleAction *action, GVariant *parameter, gpointer user_data);
 
 /* signals */
 
-#define g_signal_handlers_disconnect_by_data(instance, data) \
-    g_signal_handlers_disconnect_matched ((instance), G_SIGNAL_MATCH_DATA, \
-                                         0, 0, NULL, NULL, (data))
-#define g_signal_handlers_block_by_data(instance, data) \
-    g_signal_handlers_block_matched ((instance), G_SIGNAL_MATCH_DATA, \
-                                    0, 0, NULL, NULL, (data))
-#define g_signal_handlers_unblock_by_data(instance, data) \
-    g_signal_handlers_unblock_matched ((instance), G_SIGNAL_MATCH_DATA, \
-                                      0, 0, NULL, NULL, (data))
-
-/* gobject utils */
-
-gpointer      _g_object_ref                  (gpointer     object);
-void          _g_object_unref                (gpointer     object);
-void          _g_clear_object                (gpointer     object_p);
-GList *       _g_object_list_ref             (GList       *list);
-void          _g_object_list_unref           (GList       *list);
-GType         g_object_list_get_type         (void);
-GType         g_error_get_type               (void);
-GEnumValue *  _g_enum_type_get_value         (GType        enum_type,
-                                             int          value);
-GEnumValue *  _g_enum_type_get_value_by_nick (GType        enum_type,
-                                             const char  *nick);
+#define _g_signal_handlers_disconnect_by_data(instance, data) \
+       g_signal_handlers_disconnect_matched ( \
+               (instance), \
+               G_SIGNAL_MATCH_DATA, \
+               0, \
+               0, \
+               NULL, \
+               NULL, \
+               (data))
+
+#define _g_signal_handlers_block_by_data(instance, data) \
+       g_signal_handlers_block_matched ( \
+               (instance), \
+               G_SIGNAL_MATCH_DATA, \
+               0, \
+               0, \
+               NULL, \
+               NULL, \
+               (data))
+
+#define _g_signal_handlers_unblock_by_data(instance, data) \
+       g_signal_handlers_unblock_matched ((instance), \
+               G_SIGNAL_MATCH_DATA, \
+               0, \
+               0, \
+               NULL, \
+               NULL, \
+               (data))
+
+/* GObject utils */
+
+gpointer       _g_object_ref                   (gpointer         object);
+void           _g_object_unref                 (gpointer         object);
+void           _g_clear_object                 (gpointer         object_p);
+
+/* GObjectList */
+
+GList *                _g_object_list_ref              (GList           *list);
+void           _g_object_list_unref            (GList           *list);
+GType          g_object_list_get_type          (void);
+
+/* Enum type utils*/
+
+GEnumValue *   _g_enum_type_get_value          (GType            enum_type,
+                                                int              value);
+GEnumValue *   _g_enum_type_get_value_by_nick  (GType            enum_type,
+                                                const char      *nick);
 
 /* idle callback */
 
@@ -113,264 +136,187 @@ typedef struct {
 } IdleCall;
 
 
-IdleCall* idle_call_new           (DataFunc       func,
-                                  gpointer       data);
-void      idle_call_free          (IdleCall      *call);
-guint     idle_call_exec          (IdleCall      *call,
-                                  gboolean       use_idle_cb);
-guint     call_when_idle          (DataFunc       func,
-                                  gpointer       data);
-void      object_ready_with_error (gpointer       object,
-                                  ReadyCallback  ready_func,
-                                  gpointer       user_data,
-                                  GError        *error);
-void      ready_with_error        (ReadyFunc      ready_func,
-                                  gpointer       user_data,
-                                  GError        *error);
+IdleCall *     idle_call_new                   (DataFunc         func,
+                                                gpointer         data);
+void           idle_call_free                  (IdleCall        *call);
+guint          idle_call_exec                  (IdleCall        *call,
+                                                gboolean         use_idle_cb);
+guint          call_when_idle                  (DataFunc         func,
+                                                gpointer         data);
+void           object_ready_with_error         (gpointer         object,
+                                                ReadyCallback    ready_func,
+                                                gpointer         user_data,
+                                                GError          *error);
+void           ready_with_error                (ReadyFunc        ready_func,
+                                                gpointer         user_data,
+                                                GError          *error);
 
 /* debug */
 
-void debug       (const char *file,
-                 int         line,
-                 const char *function,
-                 const char *format,
-                 ...);
-void performance (const char *file,
-                 int         line,
-                 const char *function,
-                 const char *format,
-                 ...);
+void           debug                           (const char      *file,
+                                                int              line,
+                                                const char      *function,
+                                                const char      *format,
+                                                ...) G_GNUC_PRINTF (4, 5);
+void           performance                     (const char      *file,
+                                                int              line,
+                                                const char      *function,
+                                                const char      *format,
+                                                ...) G_GNUC_PRINTF (4, 5);
 
 #define DEBUG_INFO __FILE__, __LINE__, G_STRFUNC
 
 /* GTimeVal utils */
 
-char *          struct_tm_strftime               (struct tm  *tm,
-                                                 const char *format);
-int             _g_time_val_cmp                  (GTimeVal   *a,
-                                                 GTimeVal   *b);
-void            _g_time_val_reset                (GTimeVal   *time_);
-gboolean        _g_time_val_from_exif_date       (const char *exif_date,
-                                                 GTimeVal   *time_);
-char *          _g_time_val_to_exif_date         (GTimeVal   *time_);
-char *          _g_time_val_to_xmp_date          (GTimeVal   *time_);
-char *          _g_time_val_strftime             (GTimeVal   *time_,
-                                                 const char *format);
+char *         _g_struct_tm_strftime           (struct tm       *tm,
+                                                const char      *format);
+int            _g_time_val_cmp                 (GTimeVal        *a,
+                                                GTimeVal        *b);
+void           _g_time_val_reset               (GTimeVal        *time_);
+gboolean       _g_time_val_from_exif_date      (const char      *exif_date,
+                                                GTimeVal        *time_);
+char *         _g_time_val_to_exif_date        (GTimeVal        *time_);
+char *         _g_time_val_to_xmp_date         (GTimeVal        *time_);
+char *         _g_time_val_strftime            (GTimeVal        *time_,
+                                                const char      *format);
 
 /* Bookmark file utils */
 
-void            _g_bookmark_file_clear           (GBookmarkFile  *bookmark);
-void            _g_bookmark_file_add_uri         (GBookmarkFile  *bookmark,
-                                                 const char     *uri);
-void            _g_bookmark_file_set_uris        (GBookmarkFile  *bookmark,
-                                                 GList          *uri_list);
-
-/* String utils */
-
-void            _g_strset                        (char       **s,
-                                                 const char  *value);
-char *          _g_strdup_with_max_size          (const char  *s,
-                                                 int          max_size);
-char **         _g_get_template_from_text        (const char  *s_template);
-char *          _g_get_name_from_template        (char       **s_template,
-                                                 int          num);
-char *          _g_replace                       (const char  *str,
-                                                 const char  *from_str,
-                                                 const char  *to_str);
-char *          _g_replace_pattern               (const char  *utf8_text,
-                                                 gunichar     pattern,
-                                                 const char  *value);
-int             _g_utf8_first_ascii_space        (const char  *string);
-gboolean        _g_utf8_has_prefix               (const char  *string,
-                                                 const char  *prefix);
-char *         _g_utf8_remove_prefix            (const char  *string,
-                                                 int         prefix_length);
-char *          _g_utf8_replace                  (const char  *string,
-                                                 const char  *pattern,
-                                                 const char  *replacement);
-char *          _g_utf8_strndup                  (const char  *str,
-                                                 gsize        n);
-const char *   _g_utf8_strstr                   (const char  *haystack,
-                                                 const char  *needle);
-char **         _g_utf8_strsplit                 (const char  *string,
-                                                 const char  *delimiter,
-                                                 int          max_tokens);
-char *          _g_utf8_strstrip                 (const char  *str);
-gboolean        _g_utf8_all_spaces               (const char  *utf8_string);
-char *          _g_utf8_remove_extension         (const char  *str);
-char *          _g_utf8_try_from_any             (const char  *str);
-char *          _g_utf8_from_any                 (const char  *str);
-GList *         _g_list_insert_list_before       (GList       *list1,
-                                                 GList       *sibling,
-                                                 GList       *list2);
-void            _g_list_reorder                  (GList       *all_files,
-                                                 GList       *visible_files,
-                                                 GList       *files_to_move,
-                                                 int          dest_pos,
-                                                 int        **new_order_p,
-                                                 GList      **new_file_list_p);
-const char *    get_static_string                (const char  *s);
-char *          _g_rand_string                   (int          len);
-int             _g_strv_find                     (char       **v,
-                                                 const char  *s);
-gboolean        _g_strv_contains                 (char       **v,
-                                                 const char  *s);
-char **         _g_strv_prepend                  (char       **str_array,
-                                                 const char  *str);
-char **         _g_strv_concat                   (char       **strv1,
-                                                 char       **strv2);
-gboolean        _g_strv_remove                   (char       **str_array,
-                                                 const char  *str);
-char *          _g_str_remove_suffix             (const char  *s,
-                                                 const char  *suffix);
-void            _g_string_append_for_html        (GString     *str,
-                                                 const char  *text,
-                                                 gssize       length);
-char *          _g_escape_for_html               (const char  *text,
-                                                 gssize       length);
-
-/* Array utils*/
-
-char *          _g_string_array_join             (GPtrArray    *array,
-                                                 const char   *separator);
+void           _g_bookmark_file_clear          (GBookmarkFile   *bookmark);
+void           _g_bookmark_file_add_uri        (GBookmarkFile   *bookmark,
+                                                const char      *uri);
+void           _g_bookmark_file_set_uris       (GBookmarkFile   *bookmark,
+                                                GList           *uri_list);
+
+/* GList utils */
+
+GList *                _g_list_prepend_link            (GList           *list,
+                                                GList           *link);
+GList *                _g_list_insert_list_before      (GList           *list1,
+                                                GList           *sibling,
+                                                GList           *list2);
+void           _g_list_reorder                 (GList           *all_files,
+                                                GList           *visible_files,
+                                                GList           *files_to_move,
+                                                int              dest_pos,
+                                                int            **new_order_p,
+                                                GList          **new_file_list_p);
+
+/* GStringList */
+
+void           _g_string_list_free             (GList           *string_list);
+GList *                _g_string_list_dup              (GList           *string_list);
+char **                _g_string_list_to_strv          (GList           *string_list);
+GType          g_string_list_get_type          (void);
+
+/* Array utils */
+
+char *         _g_string_array_join            (GPtrArray       *array,
+                                                const char      *separator);
 
 /* Regexp utils */
 
-GRegex **       get_regexps_from_pattern         (const char  *pattern_string,
-                                                 GRegexCompileFlags  compile_options);
-gboolean        string_matches_regexps           (GRegex     **regexps,
-                                                 const char  *string,
-                                                 GRegexMatchFlags match_options);
-void            free_regexps                     (GRegex     **regexps);
+GRegex **      _g_regex_v_from_pattern         (const char      *pattern_string,
+                                                GRegexCompileFlags
+                                                                 compile_options);
+gboolean       _g_regex_v_match                (GRegex         **regexps,
+                                                const char      *string,
+                                                GRegexMatchFlags
+                                                                 match_options);
+void           _g_regex_v_free                 (GRegex         **regexps);
 
 
 /* URI utils */
 
-const char *    get_home_uri                     (void);
-int             uricmp                           (const char *uri1,
-                                                 const char *uri2);
-gboolean        same_uri                         (const char *uri1,
-                                                 const char *uri2);
-void            _g_string_list_free              (GList      *string_list);
-GList *         _g_string_list_dup               (GList      *string_list);
-char **         _g_string_list_to_strv           (GList      *string_list);
-GType           g_string_list_get_type           (void);
-GList *         get_file_list_from_url_list      (char       *url_list);
-const char *    _g_uri_get_basename              (const char *uri);
-const char *    _g_uri_get_file_extension        (const char *uri);
-gboolean        _g_uri_is_file                   (const char *uri);
-gboolean        _g_uri_is_dir                    (const char *uri);
-gboolean        _g_uri_parent_of_uri             (const char *dir,
-                                                 const char *file);
-char *          _g_uri_get_parent                (const char *uri);
-char *          _g_uri_remove_extension          (const char *uri);
-char *          _g_build_uri                     (const char *base,
-                                                 ...) G_GNUC_NULL_TERMINATED;
-char *          _g_uri_get_scheme                (const char *uri);
-const char *    _g_uri_remove_host               (const char *uri);
-char *          _g_uri_get_host                  (const char *uri);
-char *          _g_uri_get_relative_path         (const char *uri,
-                                                 const char *base);
-char *          _g_filename_clear_for_file       (const char *display_name);
-
-/* GIO utils */
-
-GFile *         _g_file_new_for_display_name     (const char *base_uri,
-                                                 const char *display_name,
-                                                 const char *extension);
-gboolean        _g_file_equal                    (GFile      *file1,
-                                                 GFile      *file2);
-char *          _g_file_get_display_name_no_io   (GFile      *file);
-char *          _g_file_get_display_name         (GFile      *file);
-GFileType      _g_file_get_standard_type        (GFile      *file);
-GFile *         _g_file_get_destination          (GFile      *source,
-                                                 GFile      *source_base,
-                                                 GFile      *destination_folder);
-GFile *         _g_file_get_duplicated           (GFile      *file);
-GFile *         _g_file_get_child                (GFile      *file,
-                                                 ...) G_GNUC_NULL_TERMINATED;
-GIcon *         _g_file_get_icon                 (GFile      *file);
-GIcon *                _g_file_get_symbolic_icon        (GFile      *file);
-GList *         _g_file_list_dup                 (GList      *l);
-void            _g_file_list_free                (GList      *l);
-GList *         _g_file_list_new_from_uri_list   (GList      *uris);
-GList *         _g_file_list_new_from_uriv       (char      **uris);
-GList *         _g_file_list_find_file           (GList      *l,
-                                                 GFile      *file);
-const char*     _g_file_get_mime_type            (GFile      *file,
-                                                 gboolean    fast_file_type);
-void            _g_file_get_modification_time    (GFile      *file,
-                                                 GTimeVal   *result);
-time_t          _g_file_get_mtime                (GFile      *file);
-int             _g_file_cmp_uris                 (GFile      *a,
-                                                 GFile      *b);
-gboolean        _g_file_equal_uris               (GFile      *a,
-                                                 GFile      *b);
-int             _g_file_cmp_modification_time    (GFile      *a,
-                                                 GFile      *b);
-goffset         _g_file_get_size                 (GFile      *info);
-GFile *         _g_file_resolve_all_symlinks     (GFile      *file,
-                                                 GError    **error);
-gboolean        _g_file_has_prefix               (GFile      *file,
-                                                 GFile      *prefix);
-GFile *         _g_file_append_prefix            (GFile      *file,
-                                                 const char *prefix);
-GFile *         _g_file_append_path              (GFile      *file,
-                                                 const char *path);
-gboolean        _g_file_attributes_matches_all   (const char *attributes,
-                                                 const char *mask);
-gboolean        _g_file_attributes_matches_any   (const char *attributes,
-                                                 const char *mask);
-gboolean        _g_file_attributes_matches_any_v (const char *attributes,
-                                                 char      **attribute_v);
-void            _g_file_info_swap_attributes     (GFileInfo  *info,
-                                                 const char *attr1,
-                                                 const char *attr2);
-void            _g_file_info_set_secondary_sort_order
-                                                (GFileInfo  *info,
-                                                 gint32      sort_order);
-gint32          _g_file_info_get_secondary_sort_order
-                                                (GFileInfo  *info);
-void            _g_file_info_update              (GFileInfo  *dest_info,
-                                                 GFileInfo  *src_info);
-const char *    _g_content_type_guess_from_name  (const char *filename);
-gboolean        _g_content_type_is_a             (const char *type,
-                                                 const char *supertype);
-const char *    _g_content_type_get_from_stream  (GInputStream  *istream,
-                                                 GFile         *file, /* optional */
-                                                 GCancellable  *cancellable,
-                                                 GError       **error);
-gboolean        _g_mime_type_is_image            (const char *mime_type);
-gboolean        _g_mime_type_is_raw              (const char *mime_type);
-gboolean        _g_mime_type_is_video            (const char *mime_type);
-gboolean        _g_mime_type_is_audio            (const char *mime_type);
-gboolean        _g_mime_type_has_transparency    (const char *mime_type);
+gboolean       _g_uri_query_is_file            (const char      *uri);
+gboolean       _g_uri_query_is_dir             (const char      *uri);
+char *         _g_filename_clear_for_file      (const char      *display_name);
+
+/* GFile utils */
+
+GFile *                _g_file_new_for_display_name    (const char      *base_uri,
+                                                const char      *display_name,
+                                                const char      *extension);
+gboolean       _g_file_equal                   (GFile           *file1,
+                                                GFile           *file2);
+char *         _g_file_get_display_name        (GFile           *file);
+GFileType      _g_file_query_standard_type     (GFile           *file);
+GFile *                _g_file_get_destination         (GFile           *source,
+                                                GFile           *source_base,
+                                                GFile           *destination_folder);
+GFile *                _g_file_get_duplicated          (GFile           *file);
+GFile *                _g_file_get_child               (GFile           *file,
+                                                ...) G_GNUC_NULL_TERMINATED;
+GList *                _g_file_list_dup                (GList           *l);
+void           _g_file_list_free               (GList           *l);
+GList *                _g_file_list_new_from_uriv      (char           **uris);
+GList *                _g_file_list_find_file          (GList           *l,
+                                                GFile           *file);
+const char *   _g_file_query_mime_type         (GFile           *file,
+                                                gboolean         fast_file_type);
+int            _g_file_cmp_uris                (GFile           *a,
+                                                GFile           *b);
+gboolean       _g_file_has_scheme              (GFile           *file,
+                                                const char      *scheme);
+gboolean       _g_file_is_parent               (GFile           *dir,
+                                                GFile           *file);
+GFile *                _g_file_append_path             (GFile           *file,
+                                                const char      *path);
+gboolean       _g_file_attributes_matches_all  (const char      *attributes,
+                                                const char      *mask);
+gboolean       _g_file_attributes_matches_any  (const char      *attributes,
+                                                const char      *mask);
+gboolean       _g_file_attributes_matches_any_v(const char      *attributes,
+                                                char           **attribute_v);
+void           _g_file_info_swap_attributes    (GFileInfo       *info,
+                                                const char      *attr1,
+                                                const char      *attr2);
+void           _g_file_info_set_secondary_sort_order
+                                               (GFileInfo       *info,
+                                                gint32           sort_order);
+gint32         _g_file_info_get_secondary_sort_order
+                                               (GFileInfo       *info);
+void           _g_file_info_update             (GFileInfo       *dest_info,
+                                                GFileInfo       *src_info);
+
+/* MIME type utils */
+
+const char *   _g_content_type_guess_from_name (const char      *filename);
+gboolean       _g_content_type_is_a            (const char      *type,
+                                                const char      *supertype);
+const char *   _g_content_type_get_from_stream (GInputStream    *istream,
+                                                GFile           *file, /* optional */
+                                                GCancellable    *cancellable,
+                                                GError         **error);
+gboolean       _g_mime_type_is_image           (const char      *mime_type);
+gboolean       _g_mime_type_is_raw             (const char      *mime_type);
+gboolean       _g_mime_type_is_video           (const char      *mime_type);
+gboolean       _g_mime_type_is_audio           (const char      *mime_type);
+gboolean       _g_mime_type_has_transparency   (const char      *mime_type);
 
 /* GSettings utils */
 
-char *          _g_settings_get_uri              (GSettings  *settings,
-                                                 const char *key);
-char *          _g_settings_get_uri_or_special_dir
-                                                (GSettings      *settings,
-                                                 const char     *key,
-                                                 GUserDirectory  directory);
-void            _g_settings_set_uri              (GSettings  *settings,
-                                                 const char *key,
-                                                 const char *uri);
-void            _g_settings_set_string_list      (GSettings  *settings,
-                                                 const char *key,
-                                                 GList      *list);
-GList *         _g_settings_get_string_list      (GSettings  *settings,
-                                                 const char *key);
+char *         _g_settings_get_uri             (GSettings       *settings,
+                                                const char      *key);
+char *         _g_settings_get_uri_or_special_dir
+                                               (GSettings       *settings,
+                                                const char      *key,
+                                                GUserDirectory   directory);
+void           _g_settings_set_uri             (GSettings       *settings,
+                                                const char      *key,
+                                                const char      *uri);
+void           _g_settings_set_string_list     (GSettings       *settings,
+                                                const char      *key,
+                                                GList           *list);
+GList *                _g_settings_get_string_list     (GSettings       *settings,
+                                                const char      *key);
 GSettings *    _g_settings_new_if_schema_installed
-                                                (const char *schema_name);
+                                               (const char      *schema_name);
 
 /* Other */
 
-char *          _g_format_duration_for_display   (gint64      msecs);
-GList *         _g_list_prepend_link             (GList      *list,
-                                                 GList      *link);
-void            _g_error_free                    (GError     *error);
+char *         _g_format_duration_for_display  (gint64           msecs);
+void           _g_error_free                   (GError          *error);
 
 DEF_ACTION_CALLBACK (toggle_action_activated)
 
diff --git a/gthumb/gth-application.c b/gthumb/gth-application.c
index 6bee7c89..5c994a60 100644
--- a/gthumb/gth-application.c
+++ b/gthumb/gth-application.c
@@ -315,7 +315,7 @@ gth_application_command_line (GApplication            *application,
                GFileType  file_type;
 
                location = g_file_new_for_commandline_arg (arg);
-               file_type = _g_file_get_standard_type (location);
+               file_type = _g_file_query_standard_type (location);
                if (file_type == G_FILE_TYPE_REGULAR)
                        files = g_list_prepend (files, location);
                else
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index aaca5182..5dede431 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -455,9 +455,9 @@ gth_browser_update_extra_widget (GthBrowser *browser)
        _gtk_container_remove_children (GTK_CONTAINER (gth_location_bar_get_action_area (GTH_LOCATION_BAR 
(browser->priv->location_bar))), NULL, NULL);
 
        location_chooser = gth_location_bar_get_chooser (GTH_LOCATION_BAR (browser->priv->location_bar));
-       g_signal_handlers_block_by_data (location_chooser, browser);
+       _g_signal_handlers_block_by_data (location_chooser, browser);
        gth_location_chooser_set_current (GTH_LOCATION_CHOOSER (location_chooser), 
browser->priv->location->file);
-       g_signal_handlers_unblock_by_data (location_chooser, browser);
+       _g_signal_handlers_unblock_by_data (location_chooser, browser);
 
        gth_hook_invoke ("gth-browser-update-extra-widget", browser);
 }
@@ -2067,9 +2067,9 @@ _gth_browser_real_close (GthBrowser *browser)
 
        /* disconnect from the settings */
 
-       g_signal_handlers_disconnect_by_data (browser->priv->browser_settings, browser);
-       g_signal_handlers_disconnect_by_data (browser->priv->messages_settings, browser);
-       g_signal_handlers_disconnect_by_data (browser->priv->desktop_interface_settings, browser);
+       _g_signal_handlers_disconnect_by_data (browser->priv->browser_settings, browser);
+       _g_signal_handlers_disconnect_by_data (browser->priv->messages_settings, browser);
+       _g_signal_handlers_disconnect_by_data (browser->priv->desktop_interface_settings, browser);
 
        /* disconnect from the monitor */
 
@@ -3209,13 +3209,13 @@ folder_changed_cb (GthMonitor      *monitor,
 
                        if (update_file_list) {
                                if (current_file_deleted)
-                                       g_signal_handlers_block_by_data (gth_browser_get_file_list_view 
(browser), browser);
+                                       _g_signal_handlers_block_by_data (gth_browser_get_file_list_view 
(browser), browser);
                                gth_file_list_delete_files (GTH_FILE_LIST (browser->priv->file_list), list);
                                gth_file_list_delete_files (GTH_FILE_LIST (browser->priv->thumbnail_list), 
list);
                                if (event == GTH_MONITOR_EVENT_DELETED)
                                        gth_file_source_deleted_from_disk (browser->priv->location_source, 
browser->priv->location, list);
                                if (current_file_deleted)
-                                       g_signal_handlers_unblock_by_data (gth_browser_get_file_list_view 
(browser), browser);
+                                       _g_signal_handlers_unblock_by_data (gth_browser_get_file_list_view 
(browser), browser);
                        }
 
                        if (current_file_deleted && ! gth_browser_get_file_modified (browser)) {
@@ -5154,7 +5154,7 @@ gth_browser_go_home (GthBrowser *browser)
        if (g_settings_get_boolean (browser->priv->browser_settings, PREF_BROWSER_USE_STARTUP_LOCATION))
                location = g_file_new_for_uri (gth_pref_get_startup_location ());
        else
-               location = g_file_new_for_uri (get_home_uri ());
+               location = g_file_new_for_uri (_g_uri_get_home ());
 
        gth_browser_go_to (browser, location, NULL);
 
@@ -6495,7 +6495,7 @@ load_file_attributes_ready_cb (GObject  *object,
        else if (browser->priv->location == NULL) {
                GFile *home;
 
-               home = g_file_new_for_uri (get_home_uri ());
+               home = g_file_new_for_uri (_g_uri_get_home ());
                gth_browser_load_location (browser, home);
 
                g_object_unref (home);
@@ -6965,7 +6965,7 @@ _g_menu_item_new_for_file (GFile      *file,
                char  *uri;
                GIcon *icon;
 
-               name = _g_file_get_display_name_no_io (file);
+               name = _g_file_get_display_name (file);
                uri = g_file_get_uri (file);
                icon = g_themed_icon_new (g_str_has_prefix (uri, "file://") ? "folder-symbolic" : 
"folder-remote-symbolic");
                g_menu_item_set_label (item, (custom_label != NULL) ? custom_label : name);
diff --git a/gthumb/gth-color-scale.c b/gthumb/gth-color-scale.c
index 8b34c853..b09dce77 100644
--- a/gthumb/gth-color-scale.c
+++ b/gthumb/gth-color-scale.c
@@ -21,6 +21,7 @@
 
 #include <config.h>
 #include "cairo-utils.h"
+#include "glib-utils.h"
 #include "gth-color-scale.h"
 #include "gth-enum-types.h"
 
@@ -484,7 +485,7 @@ notify_adjustment_cb (GObject    *gobject,
        GtkAdjustment *adj;
 
        if (self->priv->adj != NULL) {
-               g_signal_handlers_disconnect_by_data (self->priv->adj, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->adj, self);
                g_object_unref (self->priv->adj);
                self->priv->adj = NULL;
        }
diff --git a/gthumb/gth-delete-task.c b/gthumb/gth-delete-task.c
index d728fe30..25998800 100644
--- a/gthumb/gth-delete-task.c
+++ b/gthumb/gth-delete-task.c
@@ -66,12 +66,12 @@ gth_delete_task_exec (GthTask *task)
 
        gth_task_progress (task, _("Deleting files"), NULL, TRUE, 0.0);
 
-       _g_delete_files_async (self->priv->file_list,
-                              TRUE,
-                              TRUE,
-                              gth_task_get_cancellable (task),
-                              delete_ready_cb,
-                              self);
+       _g_file_list_delete_async (self->priv->file_list,
+                                  TRUE,
+                                  TRUE,
+                                  gth_task_get_cancellable (task),
+                                  delete_ready_cb,
+                                  self);
 }
 
 
diff --git a/gthumb/gth-extensions.c b/gthumb/gth-extensions.c
index c1eeca3c..2fa29d5c 100644
--- a/gthumb/gth-extensions.c
+++ b/gthumb/gth-extensions.c
@@ -470,7 +470,7 @@ gth_extension_description_load_from_file (GthExtensionDescription *desc,
        }
 
        basename = g_file_get_basename (file);
-       desc->id = _g_uri_remove_extension (basename);
+       desc->id = _g_path_remove_extension (basename);
        desc->name = g_key_file_get_locale_string (key_file, "Extension", "Name", NULL, NULL);
        desc->description = g_key_file_get_locale_string (key_file, "Extension", "Comment", NULL, NULL);
        if (desc->description == NULL)
diff --git a/gthumb/gth-file-chooser-dialog.c b/gthumb/gth-file-chooser-dialog.c
index 9c88820d..57f7d3db 100644
--- a/gthumb/gth-file-chooser-dialog.c
+++ b/gthumb/gth-file-chooser-dialog.c
@@ -219,10 +219,10 @@ static Format *
 get_format_from_extension (GthFileChooserDialog *self,
                           const char           *filename)
 {
-       const char *ext;
-       GList      *scan;
+       char  *ext;
+       GList *scan;
 
-       ext = _g_uri_get_file_extension (filename);
+       ext = _g_uri_get_extension (filename);
        if (ext == NULL)
                return NULL;
 
@@ -234,10 +234,14 @@ get_format_from_extension (GthFileChooserDialog *self,
                int     i;
 
                for (i = 0; format->extensions[i] != NULL; i++)
-                       if (g_ascii_strcasecmp (ext, format->extensions[i]) == 0)
+                       if (g_ascii_strcasecmp (ext, format->extensions[i]) == 0) {
+                               g_free (ext);
                                return format;
+                       }
        }
 
+       g_free (ext);
+
        return NULL;
 }
 
diff --git a/gthumb/gth-file-data.c b/gthumb/gth-file-data.c
index caf840d6..b60aab3b 100644
--- a/gthumb/gth-file-data.c
+++ b/gthumb/gth-file-data.c
@@ -193,9 +193,9 @@ gth_file_data_set_mime_type (GthFileData *self,
                             const char  *mime_type)
 {
        if (mime_type != NULL) {
-               g_file_info_set_content_type (self->info, get_static_string (mime_type));
-               g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 
get_static_string (mime_type));
-               g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, 
get_static_string (mime_type));
+               g_file_info_set_content_type (self->info, _g_str_get_static (mime_type));
+               g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 
_g_str_get_static (mime_type));
+               g_file_info_set_attribute_string (self->info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, 
_g_str_get_static (mime_type));
        }
 }
 
@@ -228,7 +228,7 @@ gth_file_data_get_mime_type (GthFileData *self)
                g_free (filename);
        }
 
-       return get_static_string (content_type);
+       return _g_str_get_static (content_type);
 }
 
 
@@ -262,7 +262,7 @@ gth_file_data_get_mime_type_from_content (GthFileData  *self,
                g_object_unref (istream);
        }
 
-       return get_static_string (content_type);
+       return _g_str_get_static (content_type);
 }
 
 
@@ -362,7 +362,7 @@ void
 gth_file_data_update_mime_type (GthFileData *fd,
                                gboolean     fast)
 {
-       gth_file_data_set_mime_type (fd, _g_file_get_mime_type (fd->file, fast || ! g_file_is_native 
(fd->file)));
+       gth_file_data_set_mime_type (fd, _g_file_query_mime_type (fd->file, fast || ! g_file_is_native 
(fd->file)));
 }
 
 
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index 0ba243d1..bcc0ba83 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -878,7 +878,7 @@ gfl_add_files (GthFileList *file_list,
 
        file_store = (GthFileStore*) gth_file_view_get_model (GTH_FILE_VIEW (file_list->priv->view));
 
-       cache_base_uri = g_strconcat (get_home_uri (), "/.thumbnails", NULL);
+       cache_base_uri = g_strconcat (_g_uri_get_home (), "/.thumbnails", NULL);
        for (scan = files; scan; scan = scan->next) {
                GthFileData     *file_data = scan->data;
                char            *uri;
@@ -897,7 +897,7 @@ gfl_add_files (GthFileList *file_list,
                thumb_data = thumb_data_new ();
                /* files in the .thumbnails directory are already thumbnails,
                 * set them as created. */
-               thumb_data->thumb_created = _g_uri_parent_of_uri (cache_base_uri, uri);
+               thumb_data->thumb_created = _g_uri_is_parent (cache_base_uri, uri);
 
                g_hash_table_insert (file_list->priv->thumb_data,
                                     g_object_ref (file_data->file),
diff --git a/gthumb/gth-file-properties.c b/gthumb/gth-file-properties.c
index 6acff9cb..cfea4a2e 100644
--- a/gthumb/gth-file-properties.c
+++ b/gthumb/gth-file-properties.c
@@ -193,7 +193,7 @@ gth_file_properties_real_set_file (GthPropertyView *base,
                        utf8_value = _g_utf8_from_any (value);
                        if (g_utf8_strlen (utf8_value, -1) > MAX_ATTRIBUTE_LENGTH)
                                g_utf8_strncpy (g_utf8_offset_to_pointer (utf8_value, MAX_ATTRIBUTE_LENGTH - 
1), "…", 1);
-                       tmp_value = _g_utf8_replace (utf8_value, "[\r\n]", " ");
+                       tmp_value = _g_utf8_replace_pattern (utf8_value, "[\r\n]", " ");
                        g_free (value);
                        value = tmp_value;
 
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index 3780c581..c0850940 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -125,7 +125,7 @@ gth_file_source_vfs_get_entry_points (GthFileSource *file_source)
 
        list = NULL;
 
-       list = gth_file_source_vfs_add_uri (list, file_source, get_home_uri ());
+       list = gth_file_source_vfs_add_uri (list, file_source, _g_uri_get_home ());
        list = gth_file_source_vfs_add_special_dir (list, file_source, G_USER_DIRECTORY_PICTURES);
        list = gth_file_source_vfs_add_special_dir (list, file_source, G_USER_DIRECTORY_VIDEOS);
        list = gth_file_source_vfs_add_special_dir (list, file_source, G_USER_DIRECTORY_DOWNLOAD);
@@ -231,7 +231,7 @@ gth_file_source_vfs_get_file_info (GthFileSource *file_source,
 
                g_object_unref (icon);
        }
-       else if (g_strcmp0 (uri, get_home_uri ()) == 0)
+       else if (g_strcmp0 (uri, _g_uri_get_home ()) == 0)
                g_file_info_set_display_name (file_info, _("Home Folder"));
 
        g_free (uri);
@@ -337,7 +337,7 @@ gth_file_source_vfs_for_each_child (GthFileSource        *file_source,
        file_source_vfs->priv->check_hidden_files = _g_file_attributes_matches_any (attributes, 
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
 
        gio_folder = gth_file_source_to_gio_file (file_source, parent);
-       g_directory_foreach_child (gio_folder,
+       _g_directory_foreach_child (gio_folder,
                                   recursive,
                                   TRUE,
                                   attributes,
@@ -392,19 +392,19 @@ gth_file_source_vfs_copy (GthFileSource    *file_source,
        cod->ready_callback = ready_callback;
        cod->user_data = data;
 
-       _g_copy_files_async (file_list,
-                            destination->file,
-                            move,
-                            GTH_FILE_COPY_ALL_METADATA | GTH_FILE_COPY_RENAME_SAME_FILE,
-                            GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
-                            G_PRIORITY_DEFAULT,
-                            gth_file_source_get_cancellable (file_source),
-                            progress_callback,
-                            data,
-                            dialog_callback,
-                            data,
-                            copy_done_cb,
-                            cod);
+       _g_file_list_copy_async (file_list,
+                                destination->file,
+                                move,
+                                GTH_FILE_COPY_ALL_METADATA | GTH_FILE_COPY_RENAME_SAME_FILE,
+                                GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
+                                G_PRIORITY_DEFAULT,
+                                gth_file_source_get_cancellable (file_source),
+                                progress_callback,
+                                data,
+                                dialog_callback,
+                                data,
+                                copy_done_cb,
+                                cod);
 }
 
 
@@ -889,16 +889,15 @@ gth_file_source_vfs_get_drop_actions (GthFileSource *file_source,
                                      GFile         *destination,
                                      GFile         *file)
 {
-       char *dest_scheme;
-       char *file_scheme;
+       GdkDragAction actions = 0;
 
-       dest_scheme = g_file_get_uri_scheme(destination);
-       file_scheme = g_file_get_uri_scheme(file);
+       if (_g_file_has_scheme (destination, "file")
+               && _g_file_has_scheme (file, "file"))
+       {
+               actions = GDK_ACTION_COPY | GDK_ACTION_MOVE;
+       }
 
-       if ((g_strcmp0 (dest_scheme, "file") == 0) && (g_strcmp0 (file_scheme, "file") == 0))
-               return GDK_ACTION_COPY | GDK_ACTION_MOVE;
-       else
-               return 0;
+       return actions;
 }
 
 
diff --git a/gthumb/gth-file-source.c b/gthumb/gth-file-source.c
index 504de529..704cabe3 100644
--- a/gthumb/gth-file-source.c
+++ b/gthumb/gth-file-source.c
@@ -974,19 +974,16 @@ gboolean
 gth_file_source_supports_scheme (GthFileSource *file_source,
                                 const char    *uri)
 {
-       gboolean  result = FALSE;
-       GList    *scan;
+       GList *scan;
 
        for (scan = file_source->priv->schemes; scan; scan = scan->next) {
                const char *scheme = scan->data;
 
-               if (strncmp (uri, scheme, strlen (scheme)) == 0) {
-                       result = TRUE;
-                       break;
-               }
+               if (g_str_has_prefix (uri, scheme))
+                       return TRUE;
        }
 
-       return result;
+       return FALSE;
 }
 
 
diff --git a/gthumb/gth-filter-grid.c b/gthumb/gth-filter-grid.c
index b27d5594..7797f4d9 100644
--- a/gthumb/gth-filter-grid.c
+++ b/gthumb/gth-filter-grid.c
@@ -257,9 +257,9 @@ button_toggled_cb (GtkWidget *toggle_button,
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_button))) {
                if (self->priv->active_button != toggle_button) {
                        if (self->priv->active_button != NULL) {
-                               g_signal_handlers_block_by_data (self->priv->active_button, self);
+                               _g_signal_handlers_block_by_data (self->priv->active_button, self);
                                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->active_button), 
FALSE);
-                               g_signal_handlers_unblock_by_data (self->priv->active_button, self);
+                               _g_signal_handlers_unblock_by_data (self->priv->active_button, self);
                        }
                        self->priv->active_button = toggle_button;
                }
@@ -464,7 +464,7 @@ image_preview_completed_cb (GthTask    *task,
        current_task = (PreviewTask *) data->current_task->data;
        g_return_if_fail (task == current_task->image_task);
 
-       g_signal_handlers_disconnect_by_data (task, data);
+       _g_signal_handlers_disconnect_by_data (task, data);
 
        if ((error != NULL) || (data->self == NULL)) {
                generate_preview_data_free (data);
diff --git a/gthumb/gth-filter.c b/gthumb/gth-filter.c
index c1586a1e..6da42842 100644
--- a/gthumb/gth-filter.c
+++ b/gthumb/gth-filter.c
@@ -490,7 +490,7 @@ gth_filter_new (void)
        GthFilter *filter;
        char      *id;
 
-       id = _g_rand_string (ID_LENGTH);
+       id = _g_str_random (ID_LENGTH);
        filter = (GthFilter *) g_object_new (GTH_TYPE_FILTER, "id", id, NULL);
        g_free (id);
 
@@ -507,7 +507,7 @@ gth_filter_set_limit (GthFilter    *filter,
 {
        filter->priv->limit_type = type;
        filter->priv->limit = value;
-       filter->priv->sort_name = get_static_string (sort_name);
+       filter->priv->sort_name = _g_str_get_static (sort_name);
        filter->priv->sort_direction = sort_direction;
 }
 
diff --git a/gthumb/gth-grid-view.c b/gthumb/gth-grid-view.c
index 4030fac4..92b08305 100644
--- a/gthumb/gth-grid-view.c
+++ b/gthumb/gth-grid-view.c
@@ -430,13 +430,13 @@ gth_grid_view_finalize (GObject *object)
        g_list_free (self->priv->selection);
 
        if (self->priv->hadjustment != NULL) {
-               g_signal_handlers_disconnect_by_data (self->priv->hadjustment, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->hadjustment, self);
                g_object_unref (self->priv->hadjustment);
                self->priv->hadjustment = NULL;
        }
 
        if (self->priv->vadjustment != NULL) {
-               g_signal_handlers_disconnect_by_data (self->priv->vadjustment, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->vadjustment, self);
                g_object_unref (self->priv->vadjustment);
                self->priv->vadjustment = NULL;
        }
@@ -2357,7 +2357,7 @@ gth_grid_view_set_model (GthFileView  *file_view,
        if (model != NULL)
                g_object_ref (model);
        if (self->priv->model != NULL) {
-               g_signal_handlers_disconnect_by_data (self->priv->model, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->model, self);
                g_object_unref (self->priv->model);
        }
        self->priv->model = model;
@@ -3502,7 +3502,7 @@ _gth_grid_view_set_hadjustment (GthGridView   *self,
                adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
 
        if (self->priv->hadjustment != NULL) {
-               g_signal_handlers_disconnect_by_data (self->priv->hadjustment, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->hadjustment, self);
                g_object_unref (self->priv->hadjustment);
        }
 
@@ -3528,7 +3528,7 @@ _gth_grid_view_set_vadjustment (GthGridView   *self,
                adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
 
        if (self->priv->vadjustment != NULL) {
-               g_signal_handlers_disconnect_by_data (self->priv->vadjustment, self);
+               _g_signal_handlers_disconnect_by_data (self->priv->vadjustment, self);
                g_object_unref (self->priv->vadjustment);
        }
 
diff --git a/gthumb/gth-image-list-task.c b/gthumb/gth-image-list-task.c
index 4dc7f004..9eff2bce 100644
--- a/gthumb/gth-image-list-task.c
+++ b/gthumb/gth-image-list-task.c
@@ -308,7 +308,7 @@ set_current_destination_file (GthImageListTask *self)
                char          *no_ext;
                GthImageSaver *saver;
 
-               no_ext = _g_uri_remove_extension (g_file_info_get_display_name 
(self->priv->destination_file_data->info));
+               no_ext = _g_path_remove_extension (g_file_info_get_display_name 
(self->priv->destination_file_data->info));
                saver = gth_main_get_image_saver (self->priv->mime_type);
                g_return_if_fail (saver != NULL);
 
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index f19044f2..ca7160f6 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -160,12 +160,12 @@ gth_image_viewer_finalize (GObject *object)
                g_object_unref (self->priv->cursor_void);
 
        if (self->hadj != NULL) {
-               g_signal_handlers_disconnect_by_data (G_OBJECT (self->hadj), self);
+               _g_signal_handlers_disconnect_by_data (G_OBJECT (self->hadj), self);
                g_object_unref (self->hadj);
        }
 
        if (self->vadj != NULL) {
-               g_signal_handlers_disconnect_by_data (G_OBJECT (self->vadj), self);
+               _g_signal_handlers_disconnect_by_data (G_OBJECT (self->vadj), self);
                g_object_unref (self->vadj);
        }
 
@@ -1101,7 +1101,7 @@ _gth_image_viewer_set_hadjustment (GthImageViewer *self,
                hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
 
        if ((self->hadj != NULL) && (self->hadj != hadj)) {
-               g_signal_handlers_disconnect_by_data (G_OBJECT (self->hadj), self);
+               _g_signal_handlers_disconnect_by_data (G_OBJECT (self->hadj), self);
                g_object_unref (self->hadj);
                self->hadj = NULL;
        }
@@ -1131,7 +1131,7 @@ _gth_image_viewer_set_vadjustment (GthImageViewer *self,
                vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
 
        if ((self->vadj != NULL) && (self->vadj != vadj)) {
-               g_signal_handlers_disconnect_by_data (G_OBJECT (self->vadj), self);
+               _g_signal_handlers_disconnect_by_data (G_OBJECT (self->vadj), self);
                g_object_unref (self->vadj);
                self->vadj = NULL;
        }
@@ -2330,12 +2330,12 @@ gth_image_viewer_scroll_to (GthImageViewer *self,
 
        /* update the adjustments value */
 
-       g_signal_handlers_block_by_data (G_OBJECT (self->hadj), self);
-       g_signal_handlers_block_by_data (G_OBJECT (self->vadj), self);
+       _g_signal_handlers_block_by_data (G_OBJECT (self->hadj), self);
+       _g_signal_handlers_block_by_data (G_OBJECT (self->vadj), self);
        gtk_adjustment_set_value (self->hadj, self->visible_area.x);
        gtk_adjustment_set_value (self->vadj, self->visible_area.y);
-       g_signal_handlers_unblock_by_data (G_OBJECT (self->hadj), self);
-       g_signal_handlers_unblock_by_data (G_OBJECT (self->vadj), self);
+       _g_signal_handlers_unblock_by_data (G_OBJECT (self->hadj), self);
+       _g_signal_handlers_unblock_by_data (G_OBJECT (self->vadj), self);
 }
 
 
diff --git a/gthumb/gth-location-chooser-dialog.c b/gthumb/gth-location-chooser-dialog.c
index 63a7d689..285a5327 100644
--- a/gthumb/gth-location-chooser-dialog.c
+++ b/gthumb/gth-location-chooser-dialog.c
@@ -118,7 +118,7 @@ location_entry_changed_cb (GthLocationChooser *entry,
        GFile                    *folder;
 
        folder = gth_location_chooser_get_current (entry);
-       if (_g_file_equal_uris (folder, gth_folder_tree_get_root (GTH_FOLDER_TREE 
(self->priv->folder_tree)))) {
+       if (_g_file_equal (folder, gth_folder_tree_get_root (GTH_FOLDER_TREE (self->priv->folder_tree)))) {
                gtk_tree_view_collapse_all (GTK_TREE_VIEW (self->priv->folder_tree));
                _set_folder (self, NULL);
        }
diff --git a/gthumb/gth-location-chooser.c b/gthumb/gth-location-chooser.c
index fa470a18..8cd58a09 100644
--- a/gthumb/gth-location-chooser.c
+++ b/gthumb/gth-location-chooser.c
@@ -226,7 +226,7 @@ get_iter_from_current_file_entries (GthLocationChooser *self,
                                    -1);
                if (item_type == ITEM_TYPE_SEPARATOR)
                        break;
-               if (same_uri (uri, list_uri)) {
+               if (_g_str_equal (uri, list_uri)) {
                        found = TRUE;
                        g_free (list_uri);
                        break;
diff --git a/gthumb/gth-main-default-hooks.c b/gthumb/gth-main-default-hooks.c
index 5396b15c..4e01a1f1 100644
--- a/gthumb/gth-main-default-hooks.c
+++ b/gthumb/gth-main-default-hooks.c
@@ -213,7 +213,7 @@ gth_main_register_default_hooks (void)
        /**
         * Called when copying files in _g_copy_files_async with the
         * GTH_FILE_COPY_ALL_METADATA flag activated and when deleting file
-        * with _g_delete_files.  Used to add sidecar files that contain
+        * with _g_file_list_delete.  Used to add sidecar files that contain
         * file metadata.
         *
         * @file (GFile *): the original file.
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index b827b7cd..3316b089 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -335,7 +335,7 @@ gth_main_get_nearest_entry_point (GFile *file)
        for (scan = list; scan; scan = scan->next) {
                GthFileData *entry_point = scan->data;
 
-               if (g_file_equal (file, entry_point->file) || _g_file_has_prefix (file, entry_point->file))
+               if (_g_file_is_parent (entry_point->file, file))
                        entries = g_list_prepend (entries, g_file_get_uri (entry_point->file));
        }
 
diff --git a/gthumb/gth-metadata-provider-file.c b/gthumb/gth-metadata-provider-file.c
index 31f93caa..2f90a200 100644
--- a/gthumb/gth-metadata-provider-file.c
+++ b/gthumb/gth-metadata-provider-file.c
@@ -68,7 +68,7 @@ gth_metadata_provider_file_read (GthMetadataProvider *self,
        g_file_info_set_attribute_string (file_data->info, "gth::file::full-name", value);
        g_free (value);
 
-       value_s = get_static_string (g_file_info_get_content_type (file_data->info));
+       value_s = _g_str_get_static (g_file_info_get_content_type (file_data->info));
        if (value_s != NULL)
                g_file_info_set_attribute_string (file_data->info, "gth::file::content-type", value_s);
 
diff --git a/gthumb/gth-metadata-provider.c b/gthumb/gth-metadata-provider.c
index 9553b0a4..ddc3ee9d 100644
--- a/gthumb/gth-metadata-provider.c
+++ b/gthumb/gth-metadata-provider.c
@@ -183,14 +183,15 @@ _g_query_metadata_async_thread (GTask        *task,
                                                      G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
                                                      qmd->attributes_v))
                {
-                       char       *uri;
-                       const char *ext;
+                       char *uri;
+                       char *ext;
 
                        uri = g_file_get_uri (file_data->file);
-                       ext = _g_uri_get_file_extension (uri);
+                       ext = _g_uri_get_extension (uri);
                        if (g_strcmp0 (ext, ".webp") == 0)
                                gth_file_data_set_mime_type (file_data, "image/webp");
 
+                       g_free (ext);
                        g_free (uri);
                }
 #endif
@@ -435,10 +436,10 @@ _g_query_all_metadata_async (GList             *files, /* GFile * list */
        qam->ready_func = ready_func;
        qam->user_data = user_data;
 
-       _g_query_info_async (files,
-                            flags,
-                            qam->attributes,
-                            qam->cancellable,
-                            qam_info_ready_cb,
-                            qam);
+       _g_file_list_query_info_async (files,
+                                      flags,
+                                      qam->attributes,
+                                      qam->cancellable,
+                                      qam_info_ready_cb,
+                                      qam);
 }
diff --git a/gthumb/gth-metadata.c b/gthumb/gth-metadata.c
index 86a136e9..549513c3 100644
--- a/gthumb/gth-metadata.c
+++ b/gthumb/gth-metadata.c
@@ -98,13 +98,13 @@ gth_metadata_set_property (GObject      *object,
        self = GTH_METADATA (object);
        switch (property_id) {
        case GTH_METADATA_ID:
-               _g_strset (&self->priv->id, g_value_get_string (value));
+               _g_str_set (&self->priv->id, g_value_get_string (value));
                break;
        case GTH_METADATA_DESCRIPTION:
-               _g_strset (&self->priv->description, g_value_get_string (value));
+               _g_str_set (&self->priv->description, g_value_get_string (value));
                break;
        case GTH_METADATA_RAW:
-               _g_strset (&self->priv->raw, g_value_get_string (value));
+               _g_str_set (&self->priv->raw, g_value_get_string (value));
                break;
        case GTH_METADATA_STRING_LIST:
                _g_object_unref (self->priv->list);
@@ -112,10 +112,10 @@ gth_metadata_set_property (GObject      *object,
                self->priv->data_type = (self->priv->list != NULL) ? GTH_METADATA_TYPE_STRING_LIST : 
GTH_METADATA_TYPE_STRING;
                break;
        case GTH_METADATA_FORMATTED:
-               _g_strset (&self->priv->formatted, g_value_get_string (value));
+               _g_str_set (&self->priv->formatted, g_value_get_string (value));
                break;
        case GTH_METADATA_VALUE_TYPE:
-               _g_strset (&self->priv->value_type, g_value_get_string (value));
+               _g_str_set (&self->priv->value_type, g_value_get_string (value));
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
diff --git a/gthumb/gth-preferences.c b/gthumb/gth-preferences.c
index 9e5fc192..c590b5ba 100644
--- a/gthumb/gth-preferences.c
+++ b/gthumb/gth-preferences.c
@@ -71,7 +71,7 @@ gth_pref_initialize (void)
                        g_object_unref (file);
                }
                if (startup_location == NULL)
-                       startup_location = g_strdup (get_home_uri ());
+                       startup_location = g_strdup (_g_uri_get_home ());
                gth_pref_set_startup_location (startup_location);
 
                g_free (startup_location);
@@ -122,7 +122,7 @@ gth_pref_get_startup_location (void)
        if (Preferences->startup_location != NULL)
                return Preferences->startup_location;
        else
-               return get_home_uri ();
+               return _g_uri_get_home ();
 }
 
 
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 6fc60353..f04a63f4 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -513,7 +513,7 @@ is_a_cache_file (const char *uri)
 
        cache_dir_1 = g_build_filename (g_get_home_dir (), ".thumbnails", NULL);
        cache_dir_2 = g_build_filename (g_get_user_cache_dir (), "thumbnails", NULL);
-       result = _g_uri_parent_of_uri (cache_dir_1, filename) || _g_uri_parent_of_uri (cache_dir_2, filename);
+       result = _g_path_is_parent (cache_dir_1, filename) || _g_path_is_parent (cache_dir_2, filename);
 
        g_free (cache_dir_1);
        g_free (cache_dir_2);
diff --git a/gthumb/gth-time-selector.c b/gthumb/gth-time-selector.c
index 411d11b3..270c6946 100644
--- a/gthumb/gth-time-selector.c
+++ b/gthumb/gth-time-selector.c
@@ -292,7 +292,7 @@ update_view_from_data (GthTimeSelector *self)
                char      *text;
 
                g_date_to_struct_tm (self->priv->date_time->date, &tm);
-               text = struct_tm_strftime (&tm, "%x");
+               text = _g_struct_tm_strftime (&tm, "%x");
                gtk_entry_set_text (GTK_ENTRY (self->priv->date_entry), text);
 
                if (gth_datetime_valid (self->priv->date_time)) {
diff --git a/gthumb/gth-time.c b/gthumb/gth-time.c
index d76ee11f..73216488 100644
--- a/gthumb/gth-time.c
+++ b/gthumb/gth-time.c
@@ -348,7 +348,7 @@ gth_datetime_strftime (GthDateTime *dt,
        struct  tm tm;
 
        if (gth_datetime_to_struct_tm (dt, &tm))
-               return struct_tm_strftime (&tm, format);
+               return _g_struct_tm_strftime (&tm, format);
        else
                return g_strdup ("");
 }
diff --git a/gthumb/gth-trash-task.c b/gthumb/gth-trash-task.c
index 79421ee3..b68347a4 100644
--- a/gthumb/gth-trash-task.c
+++ b/gthumb/gth-trash-task.c
@@ -66,10 +66,10 @@ gth_trash_task_exec (GthTask *task)
 
        gth_task_progress (task, _("Moving files to trash"), NULL, TRUE, 0.0);
 
-       _g_trash_files_async (self->priv->file_list,
-                             gth_task_get_cancellable (task),
-                             trash_ready_cb,
-                             self);
+       _g_file_list_trash_async (self->priv->file_list,
+                                 gth_task_get_cancellable (task),
+                                 trash_ready_cb,
+                                 self);
 }
 
 
diff --git a/gthumb/gth-uri-list.c b/gthumb/gth-uri-list.c
index edd70f79..9b351ffd 100644
--- a/gthumb/gth-uri-list.c
+++ b/gthumb/gth-uri-list.c
@@ -196,7 +196,7 @@ _gth_uri_list_set_iter (GthUriList  *uri_list,
        GFile         *file;
        GthFileSource *file_source;
        GFileInfo     *info;
-       const char    *display_name;
+       char          *display_name;
        GIcon         *icon;
 
        file = g_file_new_for_uri (uri);
@@ -204,12 +204,12 @@ _gth_uri_list_set_iter (GthUriList  *uri_list,
        info = gth_file_source_get_file_info (file_source, file, GFILE_DISPLAY_ATTRIBUTES);
 
        if (info != NULL) {
-               display_name = (name != NULL) ? name : g_file_info_get_display_name (info);
+               display_name = g_strdup ((name != NULL) ? name : g_file_info_get_display_name (info));
                icon = _g_object_ref (g_file_info_get_symbolic_icon (info));
        }
        else {
-               display_name = (name != NULL) ? name : _g_file_get_display_name (file);
-               icon = _g_file_get_symbolic_icon (file);
+               display_name = (name != NULL) ? g_strdup (name) : _g_file_get_display_name (file);
+               icon = g_themed_icon_new ("text-x-generic-symbolic");
        }
 
        gtk_list_store_set (uri_list->priv->list_store, iter,
@@ -219,6 +219,7 @@ _gth_uri_list_set_iter (GthUriList  *uri_list,
                            -1);
 
        _g_object_unref (icon);
+       g_free (display_name);
        g_object_unref (file_source);
        g_object_unref (file);
 
@@ -288,8 +289,8 @@ gth_uri_list_set_bookmarks (GthUriList    *uri_list,
                }
                else {
                        if (display_name == NULL)
-                               display_name = g_strdup (_g_file_get_display_name (file));
-                       icon = _g_file_get_symbolic_icon (file);
+                               display_name = _g_file_get_display_name (file);
+                       icon = g_themed_icon_new ("text-x-generic-symbolic");
                }
 
                gtk_list_store_append (uri_list->priv->list_store, &iter);
@@ -299,6 +300,7 @@ gth_uri_list_set_bookmarks (GthUriList    *uri_list,
                                    URI_LIST_COLUMN_URI, uri,
                                    -1);
 
+               g_free (display_name);
                _g_object_unref (icon);
                g_object_unref (file_source);
                g_object_unref (file);
diff --git a/gthumb/main-migrate-catalogs.c b/gthumb/main-migrate-catalogs.c
index e823d6ed..75f5cb11 100644
--- a/gthumb/main-migrate-catalogs.c
+++ b/gthumb/main-migrate-catalogs.c
@@ -434,7 +434,7 @@ migration_for_each_file (GFile     *file,
        catalogs_path = g_file_get_path (catalogs_dir);
        relative_path = g_file_get_relative_path (data->collections_dir, file);
        tmp_path = g_strconcat (catalogs_path, G_DIR_SEPARATOR_S, relative_path, NULL);
-       full_path_no_ext = _g_uri_remove_extension (tmp_path);
+       full_path_no_ext = _g_path_remove_extension (tmp_path);
        full_path = g_strconcat (full_path_no_ext, extension, NULL);
        catalog_file = g_file_new_for_path (full_path);
        catalog_dir = g_file_get_parent (catalog_file);
@@ -500,7 +500,7 @@ migrate_catalogs_from_2_10 (void)
        home_dir = g_file_new_for_path (g_get_home_dir ());
        data->collections_dir = _g_file_get_child (home_dir, ".gnome2", "gthumb", "collections", NULL);
 
-       g_directory_foreach_child (data->collections_dir,
+       _g_directory_foreach_child (data->collections_dir,
                                   TRUE,
                                   TRUE,
                                   "standard::name,standard::type",
diff --git a/gthumb/meson.build b/gthumb/meson.build
index 10ab8bd9..e4222397 100644
--- a/gthumb/meson.build
+++ b/gthumb/meson.build
@@ -110,7 +110,9 @@ public_header_files = [
   'pixbuf-cache.h',
   'pixbuf-io.h',
   'pixbuf-utils.h',
+  'str-utils.h',
   'typedefs.h',
+  'uri-utils.h',
   'zlib-utils.h'
 ]
 
@@ -281,6 +283,8 @@ source_files = files(
   'pixbuf-cache.c',
   'pixbuf-io.c',
   'pixbuf-utils.c',
+  'str-utils.c',
+  'uri-utils.c',
   'zlib-utils.c'
 )
 
@@ -341,7 +345,7 @@ test('dom',
 
 test('glib-utils',
   executable('test-glib-utils',
-    sources : [ 'test-glib-utils.c', 'glib-utils.c' ],
+    sources : [ 'test-glib-utils.c', 'glib-utils.c', 'str-utils.c', 'uri-utils.c' ],
     dependencies : common_deps,
     include_directories : config_inc,
     c_args : c_args,
diff --git a/gthumb/str-utils.c b/gthumb/str-utils.c
new file mode 100644
index 00000000..b7c8200c
--- /dev/null
+++ b/gthumb/str-utils.c
@@ -0,0 +1,974 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2019 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include "str-utils.h"
+
+
+gboolean
+_g_str_equal (const char *str1,
+             const char *str2)
+{
+       return g_strcmp0 (str1, str2) == 0;
+}
+
+
+gboolean
+_g_str_n_equal (const char *str1,
+               const char *str2,
+               gsize       size)
+{
+       if ((str1 == NULL) && (str2 == NULL))
+               return TRUE;
+       if ((str1 == NULL) || (str2 == NULL))
+               return FALSE;
+       return strncmp (str1, str2, size);
+}
+
+
+void
+_g_str_set (char       **str,
+           const char  *value)
+{
+       if (*str == value)
+               return;
+
+       if (*str != NULL) {
+               g_free (*str);
+               *str = NULL;
+       }
+
+       if (value != NULL)
+               *str = g_strdup (value);
+}
+
+
+char **
+_g_strv_take_from_str_list (GList *str_list,
+                           int    size)
+{
+       char  **str_v;
+       GList  *scan;
+       int     i;
+
+       if (size < 0)
+               size = g_list_length (str_list);
+
+       str_v = g_new0 (char *, size + 1);
+       for (scan = g_list_last (str_list), i = 0; scan && (i < size); scan = scan->prev, i++)
+               str_v[i] = (char *) scan->data;
+       str_v[i] = NULL;
+
+       return str_v;
+}
+
+
+char *
+_g_str_random (int len)
+{
+       static char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+       static int   letters_only = 52;
+       static int   whole_alphabet = 62;
+
+       GRand       *generator;
+       char        *s;
+       int          i;
+
+       generator = g_rand_new ();
+
+       s = g_new (char, len + 1);
+       for (i = 0; i < len; i++)
+               s[i] = alphabet[g_rand_int_range (generator, 0, (i == 0) ? letters_only : whole_alphabet)];
+       s[len] = 0;
+
+       g_rand_free (generator);
+
+       return s;
+}
+
+
+char *
+_g_str_remove_suffix (const char *str,
+                     const char *suffix)
+{
+       int s_len;
+       int suffix_len;
+
+       if (str == NULL)
+               return NULL;
+
+       if (suffix == NULL)
+               return g_strdup (str);
+
+       s_len = strlen (str);
+       suffix_len = strlen (suffix);
+
+       if (suffix_len >= s_len)
+               return g_strdup ("");
+       else
+               return g_strndup (str, s_len - suffix_len);
+}
+
+
+GHashTable    *static_strings = NULL;
+static GMutex  static_strings_mutex;
+
+
+const char *
+_g_str_get_static (const char *str)
+{
+       const char *result;
+
+       if (str == NULL)
+               return NULL;
+
+       g_mutex_lock (&static_strings_mutex);
+
+       if (static_strings == NULL)
+               static_strings = g_hash_table_new_full (g_str_hash,
+                                                       g_str_equal,
+                                                       g_free,
+                                                       NULL);
+
+       if (! g_hash_table_lookup_extended (static_strings,
+                                           str,
+                                           (gpointer) &result,
+                                           NULL))
+       {
+               result = g_strdup (str);
+               g_hash_table_insert (static_strings,
+                                    (gpointer) result,
+                                    GINT_TO_POINTER (1));
+       }
+
+       g_mutex_unlock (&static_strings_mutex);
+
+       return result;
+}
+
+
+/* StrV utils */
+
+
+int
+_g_strv_find (char       **strv,
+             const char  *str)
+{
+       int i;
+
+       for (i = 0; strv[i] != NULL; i++) {
+               if (strcmp (strv[i], str) == 0)
+                       return i;
+       }
+
+       return -1;
+}
+
+
+gboolean
+_g_strv_contains (char       **strv,
+                 const char  *str)
+{
+       return (_g_strv_find (strv, str) >= 0);
+}
+
+
+char **
+_g_strv_prepend (char       **strv,
+                const char  *str)
+{
+       char **result;
+       int    i;
+       int    j;
+
+       result = g_new (char *, g_strv_length (strv) + 1);
+       i = 0;
+       result[i++] = g_strdup (str);
+       for (j = 0; strv[j] != NULL; j++)
+               result[i++] = g_strdup (strv[j]);
+       result[i] = NULL;
+
+       return result;
+}
+
+
+char **
+_g_strv_concat (char **strv1,
+               char **strv2)
+{
+       char **result;
+       int    i, j;
+
+       result = g_new (char *, g_strv_length (strv1) + g_strv_length (strv2) + 1);
+       i = 0;
+       for (j = 0; strv1[j] != NULL; j++)
+               result[i++] = g_strdup (strv1[j]);
+       for (j = 0; strv2[j] != NULL; j++)
+               result[i++] = g_strdup (strv2[j]);
+       result[i] = NULL;
+
+       return result;
+}
+
+
+gboolean
+_g_strv_remove (char       **strv,
+               const char  *str)
+{
+       int i;
+       int j;
+
+       if (str == NULL)
+               return FALSE;
+
+       for (i = 0; strv[i] != NULL; i++)
+               if (strcmp (strv[i], str) == 0)
+                       break;
+
+       if (strv[i] == NULL)
+               return FALSE;
+
+       for (j = i; strv[j] != NULL; j++)
+               strv[j] = strv[j + 1];
+
+       return TRUE;
+}
+
+
+/* UTF-8 utils */
+
+
+char *
+_g_utf8_strndup (const char *str,
+                gssize      size)
+{
+       char *new_str;
+
+       if ((str == NULL) || (size == 0))
+               return NULL;
+
+       if (size < 0)
+               size = g_utf8_strlen (str, -1);
+
+       new_str = g_new (char, size * 4 + 1);
+       g_utf8_strncpy (new_str, str, size);
+
+       return new_str;
+}
+
+
+const char *
+_g_utf8_find_str (const char *haystack,
+                 const char *needle)
+{
+       glong haystack_len;
+       glong needle_len;
+       glong needle_size;
+       glong i;
+
+       if ((haystack == NULL) || (needle == NULL))
+               return NULL;
+
+       haystack_len = g_utf8_strlen (haystack, -1);
+       needle_len = g_utf8_strlen (needle, -1);
+       needle_size = strlen (needle);
+
+       if (needle_len == 0)
+               return NULL;
+
+       for (i = 0; i <= haystack_len - needle_len; i++) {
+               if (strncmp (haystack, needle, needle_size) == 0)
+                       return haystack;
+               haystack = g_utf8_next_char (haystack);
+       }
+
+       return NULL;
+}
+
+
+/* -- _g_utf8_split -- */
+
+
+char **
+_g_utf8_split (const char *str,
+              const char *sep,
+              int         max_tokens)
+{
+       glong        sep_size;
+       GList       *chunk_list;
+       int          chunk_n;
+       const char  *p;
+       char       **chunk_v;
+
+       sep_size = (sep != NULL) ? strlen (sep) : 0;
+       chunk_list = NULL;
+       chunk_n = 0;
+       p = str;
+       while ((p != NULL) && (max_tokens != 0) && (max_tokens != 1)) {
+               const char *sep_p = _g_utf8_find_str (p, sep);
+               char       *chunk;
+
+               if (sep_p == NULL) {
+                       if ((p == str) && (*p == 0)) {
+                               /* Special case: when splitting an emtpy string
+                                * return an emtpy string. */
+
+                               chunk = g_strdup ("");
+                               chunk_list = g_list_prepend (chunk_list, chunk);
+                               chunk_n++;
+                               if (max_tokens > 0) max_tokens--;
+                               p = NULL;
+                       }
+                       else if ((sep != NULL) && (sep_size == 0)) {
+
+                               /* Special case: when the separator is an
+                                * empty string, split each character. */
+
+                               chunk = _g_utf8_strndup (p, 1);
+                               chunk_list = g_list_prepend (chunk_list, chunk);
+                               chunk_n++;
+                               if (max_tokens > 0) max_tokens--;
+                               p = g_utf8_next_char (p);
+                       }
+                       else {
+                               chunk = g_strdup (p);
+                               chunk_list = g_list_prepend (chunk_list, chunk);
+                               chunk_n++;
+                               if (max_tokens > 0) max_tokens--;
+                               p = NULL;
+                       }
+               }
+               else if (sep_p > p) {
+                       chunk = g_strndup (p, sep_p - p);
+                       chunk_list = g_list_prepend (chunk_list, chunk);
+                       chunk_n++;
+                       if (max_tokens > 0) max_tokens--;
+                       p = sep_p + sep_size;
+               }
+               else
+                       p = sep_p + sep_size;
+
+               if ((p != NULL) && (g_utf8_get_char (p) == 0))
+                       break;
+       }
+
+       if ((p != NULL) && (max_tokens == 1)) {
+               chunk_list = g_list_prepend (chunk_list, g_strdup (p));
+               chunk_n++;
+       }
+
+       chunk_v = _g_strv_take_from_str_list (chunk_list, chunk_n);
+       g_list_free (chunk_list);
+
+       return chunk_v;
+}
+
+
+/* -- _g_utf8_split_template -- */
+
+
+typedef enum {
+       SPLIT_TMPL_STATE_START,
+       SPLIT_TMPL_STATE_READING_SHARPS,
+       SPLIT_TMPL_STATE_READING_LITERAL
+} SplitTmplState;
+
+
+/**
+ * example 1 : "xxx##yy#" --> [0] = xxx
+ *                            [1] = ##
+ *                            [2] = yy
+ *                            [3] = #
+ *                            [4] = NULL
+ *
+ * example 2 : ""         --> [0] = NULL
+ **/
+char **
+_g_utf8_split_template (const char *tmpl)
+{
+       SplitTmplState   state;
+       GList           *chunk_list;
+       int              chunk_n;
+       const char      *p;
+       const char      *chunk_start;
+       const char      *chunk_end;
+       char           **chunk_v;
+
+       state = SPLIT_TMPL_STATE_START;
+       chunk_list = NULL;
+       chunk_n = 0;
+       p = tmpl;
+       while (p != NULL) {
+               gunichar ch = g_utf8_get_char (p);
+               gboolean save_chunk = FALSE;
+
+               switch (state) {
+               case SPLIT_TMPL_STATE_START:
+                       chunk_start = chunk_end = p;
+                       if (ch == '#')
+                               state = SPLIT_TMPL_STATE_READING_SHARPS;
+                       else
+                               state = SPLIT_TMPL_STATE_READING_LITERAL;
+                       break;
+
+               case SPLIT_TMPL_STATE_READING_SHARPS:
+                       if (ch != '#') {
+                               state = SPLIT_TMPL_STATE_READING_LITERAL;
+                               save_chunk = TRUE;
+                       }
+                       else
+                               chunk_end = p;
+                       break;
+
+               case SPLIT_TMPL_STATE_READING_LITERAL:
+                       if ((ch == '#') || (ch == 0)) {
+                               state = SPLIT_TMPL_STATE_READING_SHARPS;
+                               save_chunk = TRUE;
+                       }
+                       else
+                               chunk_end = p;
+                       break;
+               }
+
+               if (save_chunk) {
+                       glong  chunk_size;
+                       char  *chunk;
+
+                       chunk_size = chunk_end - chunk_start + 1;
+                       chunk = _g_utf8_strndup (chunk_start, chunk_size);
+                       chunk_list = g_list_prepend (chunk_list, chunk);
+                       chunk_n++;
+                       chunk_start = chunk_end = p;
+               }
+
+               if (ch == 0)
+                       break;
+
+               p = g_utf8_next_char (p);
+       }
+
+       chunk_v = _g_strv_take_from_str_list (chunk_list, chunk_n);
+       g_list_free (chunk_list);
+
+       return chunk_v;
+}
+
+
+char *
+_g_utf8_replace_str (const char *str,
+                    const char *old_str,
+                    const char *new_str)
+{
+       GString     *result;
+       size_t       old_str_size;
+       const char  *p;
+
+       if (str == NULL)
+               return NULL;
+
+       result = g_string_new ("");
+       old_str_size = (old_str != NULL) ? strlen (old_str) : 0;
+       p = str;
+       while ((p != NULL) && (g_utf8_get_char (p) != 0)) {
+               const char *sep = _g_utf8_find_str (p, old_str);
+
+               if (sep == NULL) {
+                       g_string_append (result, p);
+                       p = NULL;
+               }
+               else {
+                       g_string_append_len (result, p, sep - p);
+                       if (new_str != NULL)
+                               g_string_append (result, new_str);
+                       p = sep + old_str_size;
+               }
+       }
+
+       return g_string_free (result, FALSE);
+}
+
+
+char *
+_g_utf8_replace_pattern (const char *str,
+                        const char *pattern,
+                        const char *replacement)
+{
+       GRegex *regex;
+       char   *result;
+
+       if (str == NULL)
+               return NULL;
+
+       regex = g_regex_new (pattern, 0, 0, NULL);
+       if (regex == NULL)
+               return NULL;
+
+       result = g_regex_replace_literal (regex, str, -1, 0, replacement, 0, NULL);
+
+       g_regex_unref (regex);
+
+       return result;
+}
+
+
+char *
+_g_utf8_last_char (const char *str,
+                  glong      *p_size)
+{
+       glong len;
+
+       if (str == NULL) {
+               if (p_size) *p_size = 0;
+               return NULL;
+       }
+
+       len = strlen (str);
+       if (p_size) *p_size = len;
+
+       if (len == 0)
+               return NULL;
+
+       return g_utf8_find_prev_char (str, str + len);
+}
+
+
+gboolean
+_g_utf8_n_equal (const char  *str1,
+                const char  *str2,
+                glong        size)
+{
+       const char *p1;
+       const char *p2;
+
+       p1 = str1;
+       p2 = str2;
+       while ((size > 0) && (p1 != NULL) && (p2 != NULL)) {
+               gunichar c1 = g_utf8_get_char (p1);
+               gunichar c2 = g_utf8_get_char (p2);
+
+               if ((c1 == 0) || (c2 == 0) || (c1 != c2))
+                       break;
+
+               size--;
+               p1 = g_utf8_next_char (p1);
+               p2 = g_utf8_next_char (p2);
+       }
+
+       return size == 0;
+}
+
+
+const char *
+_g_utf8_after_ascii_space (const char *str)
+{
+       while (str != NULL) {
+               gunichar c = g_utf8_get_char (str);
+
+               if (c == 0)
+                       break;
+
+               if (c == ' ')
+                       return g_utf8_next_char (str);
+
+               str = g_utf8_next_char (str);
+       }
+
+       return NULL;
+}
+
+
+gboolean
+_g_utf8_has_prefix (const char *str,
+                   const char *prefix)
+{
+       if (str == NULL)
+               return FALSE;
+
+       if (prefix == NULL)
+               return FALSE;
+
+       while ((str != NULL) && (prefix != NULL)) {
+               gunichar str_ch = g_utf8_get_char (str);
+               gunichar prefix_ch = g_utf8_get_char (prefix);
+
+               if (prefix_ch == 0)
+                       return TRUE;
+
+               if (str_ch == 0)
+                       return FALSE;
+
+               if (str_ch != prefix_ch)
+                       return FALSE;
+
+               str = g_utf8_next_char (str);
+               prefix = g_utf8_next_char (prefix);
+       }
+
+       return FALSE;
+}
+
+
+gboolean
+_g_utf8_all_spaces (const char *str)
+{
+       while (str != NULL) {
+               gunichar ch = g_utf8_get_char (str);
+
+               if (ch == 0)
+                       break;
+
+               if (! g_unichar_isspace (ch))
+                       return FALSE;
+
+               str = g_utf8_next_char (str);
+       }
+
+       return TRUE;
+}
+
+
+char *
+_g_utf8_try_from_any (const char *str)
+{
+       char *utf8_str;
+
+       if (str == NULL)
+               return NULL;
+
+       if (! g_utf8_validate (str, -1, NULL))
+               utf8_str = g_locale_to_utf8 (str, -1, NULL, NULL, NULL);
+       else
+               utf8_str = g_strdup (str);
+
+       return utf8_str;
+}
+
+
+char *
+_g_utf8_from_any (const char *str)
+{
+       char *utf8_str;
+
+       if (str == NULL)
+               return NULL;
+
+       utf8_str = _g_utf8_try_from_any (str);
+       if (utf8_str == NULL)
+               utf8_str = g_strdup (_("(invalid value)"));
+
+       return utf8_str;
+}
+
+
+/* -- _g_utf8_strip_func -- */
+
+
+typedef enum {
+       STRIP_STATE_HEADING_SPACE,
+       STRIP_STATE_REST
+} StripState;
+
+
+char *
+_g_utf8_strip_func (const char *str,
+                   StripFunc   is_space_func)
+{
+       const char *first_non_space = NULL;
+       const char *last_non_space = NULL;
+       StripState  state = STRIP_STATE_HEADING_SPACE;
+
+       if (str == NULL)
+               return NULL;
+
+       if (is_space_func == NULL)
+               return g_strdup ("");
+
+       while (str != NULL) {
+               gunichar ch = g_utf8_get_char (str);
+               gboolean is_space = is_space_func (ch) || (ch == 0);
+
+               switch (state) {
+               case STRIP_STATE_HEADING_SPACE:
+                       if (! is_space) {
+                               state = STRIP_STATE_REST;
+                               first_non_space = last_non_space = str;
+                       }
+                       break;
+
+               case STRIP_STATE_REST:
+                       if (! is_space)
+                               last_non_space = str;
+                       break;
+               }
+
+               if (ch == 0)
+                       break;
+
+               str = g_utf8_next_char (str);
+       }
+
+       if (first_non_space == NULL)
+               return g_strdup ("");
+
+       g_assert (last_non_space != NULL);
+
+       return g_strndup (first_non_space, g_utf8_next_char (last_non_space) - first_non_space);
+}
+
+
+char *
+_g_utf8_strip (const char *str)
+{
+       return _g_utf8_strip_func (str, g_unichar_isspace);
+}
+
+
+/* -- _g_utf8_rstrip_func -- */
+
+
+typedef enum {
+       RSTRIP_STATE_ONLY_SPACES,       /* String contains only spaces. */
+       RSTRIP_STATE_NON_SPACE,         /* Reading non space characters. */
+       RSTRIP_STATE_TRAILING_SPACE     /* Reading possible trailing spaces. */
+} RStripState;
+
+
+char *
+_g_utf8_rstrip_func (const char         *str,
+                    StripFunc    is_space_func)
+{
+       const char  *first_trail_space;
+       RStripState  state;
+       const char  *p;
+
+       if (str == NULL)
+               return NULL;
+
+       if (is_space_func == NULL)
+               return g_strdup (str);
+
+       first_trail_space = NULL;
+       state = RSTRIP_STATE_ONLY_SPACES;
+       p = str;
+       while (p != NULL) {
+               gunichar ch = g_utf8_get_char (p);
+               gboolean is_space = is_space_func (ch);
+
+               switch (state) {
+               case RSTRIP_STATE_ONLY_SPACES:
+                       if (! is_space && (ch != 0))
+                               state = RSTRIP_STATE_NON_SPACE;
+                       break;
+
+               case RSTRIP_STATE_NON_SPACE:
+                       if (is_space) {
+                               state = RSTRIP_STATE_TRAILING_SPACE;
+                               first_trail_space = p;
+                       }
+                       break;
+
+               case RSTRIP_STATE_TRAILING_SPACE:
+                       if (! is_space && (ch != 0)) {
+                               state = RSTRIP_STATE_NON_SPACE;
+                               first_trail_space = NULL;
+                       }
+                       break;
+               }
+
+               if (ch == 0)
+                       break;
+
+               p = g_utf8_next_char (p);
+       }
+
+       if (state == RSTRIP_STATE_ONLY_SPACES)
+               return g_strdup ("");
+
+       if (state == RSTRIP_STATE_NON_SPACE)
+               return g_strdup (str);
+
+       g_assert (first_trail_space != NULL);
+
+       return g_strndup (str, first_trail_space - str);
+}
+
+
+char *
+_g_utf8_rstrip (const char *str)
+{
+       return _g_utf8_rstrip_func (str, g_unichar_isspace);
+}
+
+
+/* -- _g_utf8_translate -- */
+
+
+static gboolean
+_g_unichar_equal (gconstpointer v1,
+                 gconstpointer v2)
+{
+       return *((const gunichar*) v1) == *((const gunichar*) v2);
+}
+
+
+static guint
+_g_unichar_hash (gconstpointer v)
+{
+       return (guint) *(const gunichar*) v;
+}
+
+
+/* Substitute each occurrence of a character with a string. */
+char *
+_g_utf8_translate (const char *str,
+                  ...)
+{
+       va_list     args;
+       GHashTable *translation;
+       const char *arg;
+       GString    *regexp;
+
+       if (str == NULL)
+               return NULL;
+
+       translation = g_hash_table_new_full (_g_unichar_hash, _g_unichar_equal, NULL, g_free);
+       va_start (args, str);
+       while ((arg = va_arg (args, const char *)) != NULL) {
+               gunichar    from_ch;
+               const char *to_str;
+
+               from_ch = g_utf8_get_char (arg);
+               to_str = va_arg (args, const char *);
+               if (to_str == NULL)
+                       break;
+
+               g_hash_table_insert (translation, &from_ch, g_strdup (to_str));
+       }
+       va_end (args);
+
+       if (g_hash_table_size (translation) == 0) {
+               g_hash_table_unref (translation);
+               return g_strdup (str);
+       }
+
+       regexp = g_string_new ("");
+       while (str != NULL) {
+               gunichar  ch = g_utf8_get_char (str);
+               char     *replacement;
+
+               if (ch == 0)
+                       break;
+
+               replacement = g_hash_table_lookup (translation, &ch);
+               if (replacement != NULL)
+                       g_string_append (regexp, replacement);
+               else
+                       g_string_append_unichar (regexp, ch);
+
+               str = g_utf8_next_char (str);
+       }
+
+       g_hash_table_unref (translation);
+
+       return g_string_free (regexp, FALSE);
+}
+
+
+/* -- _g_utf8_text_escape_xml -- */
+
+
+typedef enum {
+       XML_ESCAPE_DEFAULT      = 1 << 0,
+       XML_ESCAPE_TEXT         = 1 << 1
+} XmlEscFlags;
+
+
+static char *
+_g_utf8_escape_xml_flags (const char  *text,
+                         XmlEscFlags  flags)
+{
+       GString  *str;
+       gboolean  for_text;
+
+       if (text == NULL)
+               return NULL;
+
+       str = g_string_sized_new (strlen (text));
+       for_text = (flags & XML_ESCAPE_TEXT) != 0;
+
+       while (text != NULL) {
+               gunichar ch = g_utf8_get_char (text);
+
+               if (ch == 0)
+                       break;
+
+               switch (ch) {
+               case '&':
+                       g_string_append (str, "&amp;");
+                       break;
+
+               case '<':
+                       g_string_append (str, "&lt;");
+                       break;
+
+               case '>':
+                       g_string_append (str, "&gt;");
+                       break;
+
+               case '\'':
+                       g_string_append (str, "&apos;");
+                       break;
+
+               case '"':
+                       g_string_append (str, "&quot;");
+                       break;
+
+               default:
+                       if (for_text && (ch == '\n'))
+                               g_string_append (str, "<br>");
+                       else if ((ch > 127) || ! g_ascii_isprint ((char) ch))
+                               g_string_append_printf (str, "&#%d;", ch);
+                       else
+                               g_string_append_unichar (str, ch);
+                       break;
+               }
+
+               text = g_utf8_next_char (text);
+       }
+
+       return g_string_free (str, FALSE);
+}
+
+
+char *
+_g_utf8_escape_xml (const char *str)
+{
+       return _g_utf8_escape_xml_flags (str, XML_ESCAPE_DEFAULT);
+}
+
+
+char *
+_g_utf8_text_escape_xml        (const char *str)
+{
+       return _g_utf8_escape_xml_flags (str, XML_ESCAPE_TEXT);
+}
diff --git a/gthumb/str-utils.h b/gthumb/str-utils.h
new file mode 100644
index 00000000..d5156152
--- /dev/null
+++ b/gthumb/str-utils.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2019 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STR_UTILS_H
+#define _STR_UTILS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef gboolean (*StripFunc) (gunichar ch);
+
+gboolean       _g_str_equal            (const char      *str1,
+                                        const char      *str2);
+gboolean       _g_str_n_equal          (const char      *str1,
+                                        const char      *str2,
+                                        gsize            size);
+void           _g_str_set              (char           **str,
+                                        const char      *value);
+char **                _g_strv_take_from_str_list
+                                       (GList           *str_list,
+                                        int              size);
+char *         _g_str_random           (int              len);
+char *         _g_str_remove_suffix    (const char      *str,
+                                        const char      *suffix);
+const char *   _g_str_get_static       (const char      *str);
+
+/* StrV utils */
+
+int            _g_strv_find            (char           **strv,
+                                        const char      *str);
+gboolean       _g_strv_contains        (char           **strv,
+                                        const char      *str);
+char **                _g_strv_prepend         (char           **strv,
+                                        const char      *str);
+char **                _g_strv_concat          (char           **strv1,
+                                        char           **strv2);
+gboolean       _g_strv_remove          (char           **strv,
+                                        const char      *str);
+
+/* UTF-8 utils */
+
+char *         _g_utf8_strndup         (const char      *str,
+                                        gssize           size);
+const char *   _g_utf8_find_str        (const char      *haystack,
+                                        const char      *needle);
+char **                _g_utf8_split           (const char      *str,
+                                        const char      *separator,
+                                        int              max_tokens);
+char **                _g_utf8_split_template  (const char      *tmpl);
+char *         _g_utf8_replace_str     (const char      *str,
+                                        const char      *old_str,
+                                        const char      *new_str);
+char *         _g_utf8_replace_pattern (const char      *str,
+                                        const char      *pattern,
+                                        const char      *replacement);
+char *         _g_utf8_last_char       (const char      *str,
+                                        glong           *p_size);
+gboolean       _g_utf8_n_equal         (const char      *str1,
+                                        const char      *str2,
+                                        glong            size);
+const char *   _g_utf8_after_ascii_space
+                                       (const char      *str);
+gboolean       _g_utf8_has_prefix      (const char      *str,
+                                        const char      *prefix);
+gboolean       _g_utf8_all_spaces      (const char      *str);
+char *         _g_utf8_try_from_any    (const char      *str);
+char *         _g_utf8_from_any        (const char      *str);
+char *         _g_utf8_strip_func      (const char      *str,
+                                        StripFunc        is_space_func);
+char *         _g_utf8_strip           (const char      *str);
+char *         _g_utf8_rstrip_func     (const char      *str,
+                                        StripFunc        func);
+char *         _g_utf8_rstrip          (const char      *str);
+char *         _g_utf8_translate       (const char      *str,
+                                        ...) G_GNUC_NULL_TERMINATED;
+char *         _g_utf8_escape_xml      (const char      *str);
+char *         _g_utf8_text_escape_xml (const char      *str);
+
+G_END_DECLS
+
+#endif /* _STR_UTILS_H */
diff --git a/gthumb/test-glib-utils.c b/gthumb/test-glib-utils.c
index aaa05bb8..4e368176 100644
--- a/gthumb/test-glib-utils.c
+++ b/gthumb/test-glib-utils.c
@@ -21,6 +21,7 @@
 
 #include <config.h>
 #include <string.h>
+#include <locale.h>
 #include "glib-utils.h"
 
 
@@ -29,11 +30,11 @@ test_g_rand_string (void)
 {
        char *id;
 
-       id = _g_rand_string (8);
+       id = _g_str_random (8);
        g_assert_cmpint (strlen (id), == , 8);
        g_free (id);
 
-       id = _g_rand_string (16);
+       id = _g_str_random (16);
        g_assert_cmpint (strlen (id), == , 16);
        g_free (id);
 }
@@ -72,18 +73,75 @@ test_regexp (void)
 static void
 test_g_utf8_has_prefix (void)
 {
+       g_assert_false (_g_utf8_has_prefix (NULL, NULL));
+       g_assert_false (_g_utf8_has_prefix (NULL, ""));
+       g_assert_false (_g_utf8_has_prefix ("", NULL));
+       g_assert_true (_g_utf8_has_prefix ("", ""));
+       g_assert_true (_g_utf8_has_prefix ("日", ""));
+       g_assert_false (_g_utf8_has_prefix ("", "日"));
+       g_assert_true (_g_utf8_has_prefix ("日本語", "日"));
+       g_assert_false (_g_utf8_has_prefix ("日", "日本"));
+       g_assert_false (_g_utf8_has_prefix ("日", "日本語"));
        g_assert_true (_g_utf8_has_prefix ("lang=正體字/繁體字 中华人民共和国", "lang="));
 }
 
 
 static void
-test_g_utf8_first_space (void)
+test_g_utf8_after_ascii_space (void)
 {
-       g_assert_cmpint (_g_utf8_first_ascii_space (NULL), ==, -1);
-       g_assert_cmpint (_g_utf8_first_ascii_space (""), ==, -1);
-       g_assert_cmpint (_g_utf8_first_ascii_space ("lang=FR langue d’oïl"), ==, 7);
-       g_assert_cmpint (_g_utf8_first_ascii_space ("正體字"), ==, -1);
-       g_assert_cmpint (_g_utf8_first_ascii_space ("lang=正體字/繁體字 中华人民共和国"), ==, 12);
+       g_assert_cmpstr (_g_utf8_after_ascii_space (NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_after_ascii_space (""), ==, NULL);
+       g_assert_cmpstr (_g_utf8_after_ascii_space ("正體字 "), ==, "");
+       g_assert_cmpstr (_g_utf8_after_ascii_space ("lang=FR langue d’oïl"), ==, "langue d’oïl");
+       g_assert_cmpstr (_g_utf8_after_ascii_space ("正體字"), ==, NULL);
+       g_assert_cmpstr (_g_utf8_after_ascii_space ("lang=正體字/繁體字 中华人民共和国"), ==, "中华人民共和国");
+}
+
+
+static void
+test_g_utf8_all_spaces_space (void)
+{
+       g_assert_true (_g_utf8_all_spaces (NULL));
+       g_assert_true (_g_utf8_all_spaces (""));
+       g_assert_true (_g_utf8_all_spaces (" "));
+       g_assert_false (_g_utf8_all_spaces ("."));
+       g_assert_false (_g_utf8_all_spaces ("正"));
+}
+
+
+static void
+test_g_utf8_escape_xml_space (void)
+{
+       g_assert_cmpstr (_g_utf8_escape_xml (NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_escape_xml (""), ==, "");
+       g_assert_cmpstr (_g_utf8_escape_xml ("ascii"), ==, "ascii");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正"), ==, "&#27491;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("體"), ==, "&#39636;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("字"), ==, "&#23383;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正體字"), ==, "&#27491;&#39636;&#23383;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正\\<體"), ==, "&#27491;\\&lt;&#39636;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正>體"), ==, "&#27491;&gt;&#39636;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正'體"), ==, "&#27491;&apos;&#39636;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正\"體"), ==, "&#27491;&quot;&#39636;");
+       g_assert_cmpstr (_g_utf8_escape_xml ("正&體"), ==, "&#27491;&amp;&#39636;");
+       g_assert_cmpstr (_g_utf8_text_escape_xml ("\n"), ==, "<br>");
+       g_assert_cmpstr (_g_utf8_text_escape_xml ("正\n體"), ==, "&#27491;<br>&#39636;");
+}
+
+
+static void
+test_g_utf8_find_str (void)
+{
+       g_assert_cmpstr (_g_utf8_find_str ("正體字", "正"), ==, "正體字");
+       g_assert_cmpstr (_g_utf8_find_str ("正體字", "體"), ==, "體字");
+       g_assert_cmpstr (_g_utf8_find_str ("正體字", "字"), ==, "字");
+       g_assert_cmpstr (_g_utf8_find_str ("正體", "字"), ==, NULL);
+       g_assert_cmpstr (_g_utf8_find_str ("正體", NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_find_str (NULL, NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_find_str (NULL, "字"), ==, NULL);
+       g_assert_cmpstr (_g_utf8_find_str ("正體", ""), ==, NULL);
+       g_assert_cmpstr (_g_utf8_find_str ("", ""), ==, NULL);
+       g_assert_cmpstr (_g_utf8_find_str ("", "字"), ==, NULL);
 }
 
 
@@ -93,14 +151,9 @@ test_remove_lang_from_utf8_string (const char *value,
 {
        char *result = NULL;
 
-       if (_g_utf8_has_prefix (value, "lang=")) {
-               int pos = _g_utf8_first_ascii_space (value);
-               if (pos > 0)
-                       result = _g_utf8_remove_prefix (value, pos + 1);
-       }
-
-       g_assert_true (result != NULL);
-       g_assert_true (g_utf8_collate (result, expected) == 0);
+       if (_g_utf8_has_prefix (value, "lang="))
+               result = g_strdup (_g_utf8_after_ascii_space (value));
+       g_assert_cmpstr (result, ==, expected);
 
        g_free (result);
 }
@@ -115,17 +168,788 @@ test_remove_lang_from_utf8_string_all (void)
 }
 
 
+static void
+test_g_path_get_parent_all (void)
+{
+       g_assert_cmpstr (_g_path_get_parent (NULL), ==, NULL);
+       g_assert_cmpstr (_g_path_get_parent (""), ==, NULL);
+       g_assert_cmpstr (_g_path_get_parent ("/"), ==, "/");
+       g_assert_cmpstr (_g_path_get_parent ("/日"), ==, "/");
+       g_assert_cmpstr (_g_path_get_parent ("/日/"), ==, "/日");
+       g_assert_cmpstr (_g_path_get_parent ("/日/本"), ==, "/日");
+       g_assert_cmpstr (_g_path_get_parent ("/日/本/"), ==, "/日/本");
+       g_assert_cmpstr (_g_path_get_parent ("/日/本/語.txt"), ==, "/日/本");
+       g_assert_cmpstr (_g_path_get_parent ("日"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_parent ("日/"), ==, "日");
+       g_assert_cmpstr (_g_path_get_parent ("日/本"), ==, "日");
+       g_assert_cmpstr (_g_path_get_parent ("日/本/"), ==, "日/本");
+       g_assert_cmpstr (_g_path_get_parent ("日/本/語.txt"), ==, "日/本");
+}
+
+
+static void
+test_g_path_get_basename_all (void)
+{
+       g_assert_cmpstr (_g_path_get_basename (NULL), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename (""), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("/"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("//"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("///"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("////"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("//a//"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("/日"), ==, "日");
+       g_assert_cmpstr (_g_path_get_basename ("/日/"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("/日/本"), ==, "本");
+       g_assert_cmpstr (_g_path_get_basename ("/日/本/語.txt"), ==, "語.txt");
+       g_assert_cmpstr (_g_path_get_basename ("日"), ==, "日");
+       g_assert_cmpstr (_g_path_get_basename ("日/"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("日/本"), ==, "本");
+       g_assert_cmpstr (_g_path_get_basename ("日/本/"), ==, NULL);
+       g_assert_cmpstr (_g_path_get_basename ("日/本/語.txt"), ==, "語.txt");
+}
+
+
+static void
+test_g_uri_append_path_all (void)
+{
+       g_assert_cmpstr (_g_uri_append_path (NULL, NULL), ==, NULL);
+       g_assert_cmpstr (_g_uri_append_path (NULL, ""), ==, NULL);
+       g_assert_cmpstr (_g_uri_append_path (NULL, "/"), ==, NULL);
+       g_assert_cmpstr (_g_uri_append_path (NULL, "/日"), ==, NULL);
+
+       g_assert_cmpstr (_g_uri_append_path ("", NULL), ==, NULL);
+       g_assert_cmpstr (_g_uri_append_path ("", ""), ==, NULL);
+       g_assert_cmpstr (_g_uri_append_path ("", "/"), ==, NULL);
+       g_assert_cmpstr (_g_uri_append_path ("", "/日"), ==, NULL);
+
+       g_assert_cmpstr (_g_uri_append_path ("file:", NULL), ==, "file:///");
+       g_assert_cmpstr (_g_uri_append_path ("file:", ""), ==, "file:///");
+       g_assert_cmpstr (_g_uri_append_path ("file:", "/"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_append_path ("file://", "/"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_append_path ("file:///", "/"), ==, "file:///");
+
+       g_assert_cmpstr (_g_uri_append_path ("file:", "日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_append_path ("file://", "日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_append_path ("file:///", "日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_append_path ("file:///", "日/本/語"), ==, "file:///日/本/語");
+       g_assert_cmpstr (_g_uri_append_path ("catalog:///", "Tags"), ==, "catalog:///Tags");
+
+       g_assert_cmpstr (_g_uri_append_path ("file:", "/日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_append_path ("file://", "/日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_append_path ("file:///", "/日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_append_path ("file:///", "/日/本/語"), ==, "file:///日/本/語");
+}
+
+
+static void
+test_g_uri_from_path_all (void)
+{
+       g_assert_cmpstr (_g_uri_from_path ("/"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_from_path ("/日"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_from_path ("/日/"), ==, "file:///日/");
+       g_assert_cmpstr (_g_uri_from_path ("/日/本/語"), ==, "file:///日/本/語");
+       g_assert_cmpstr (_g_uri_from_path ("/日 本"), ==, "file:///日%20本");
+}
+
+
+static void
+test_g_uri_get_basename_all (void)
+{
+       g_assert_cmpstr (_g_uri_get_basename ("file:///home/paolo/"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:///home/paolo/file.txt"), ==, "file.txt");
+       g_assert_cmpstr (_g_uri_get_basename ("file:///file.txt"), ==, "file.txt");
+       g_assert_cmpstr (_g_uri_get_basename ("file://file.txt"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:file.txt"), ==, "file.txt");
+       g_assert_cmpstr (_g_uri_get_basename ("file.txt"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("/file.txt"), ==, "file.txt");
+
+       g_assert_cmpstr (_g_uri_get_basename (NULL), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename (""), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:/"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file://"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:///"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:///%E6%97%A5"), ==, "日");
+       g_assert_cmpstr (_g_uri_get_basename ("file:///%E6%97%A5/"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_basename ("file:///%E6%97%A5/%E6%9C%AC/%E8%AA%9E"), ==, "語");
+}
+
+
+static void
+test_g_uri_get_parent_all (void)
+{
+       g_assert_cmpstr (_g_uri_get_parent ("file"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_parent ("file:"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_get_parent ("file://"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_get_parent ("file:///"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_get_parent ("file:///日"), ==, "file:///");
+       g_assert_cmpstr (_g_uri_get_parent ("file:///日/本"), ==, "file:///日");
+       g_assert_cmpstr (_g_uri_get_parent ("file:///日/本/語.txt"), ==, "file:///日/本");
+       g_assert_cmpstr (_g_uri_get_parent ("file:///%E6%97%A5/%E6%9C%AC/%E8%AA%9E"), ==, "file:///日/本");
+       g_assert_cmpstr (_g_uri_get_parent ("file://日/本/語.txt"), ==, "file://日/本");
+       g_assert_cmpstr (_g_uri_get_parent ("file://諸星@日:123/本/語.txt"), ==, "file://諸星@日:123/本");
+       g_assert_cmpstr (_g_uri_get_parent ("file://諸星@日:123/本"), ==, "file://諸星@日:123/");
+       g_assert_cmpstr (_g_uri_get_parent ("file://諸星@日:123/"), ==, "file://諸星@日:123/");
+}
+
+
+static void
+test_g_file_get_display_name (const char *uri,
+                             const char *expected)
+{
+       GFile *file;
+       char  *name;
+
+       file = g_file_new_for_uri (uri);
+       name = _g_file_get_display_name (file);
+       g_assert_cmpstr (name, ==, expected);
+
+       g_free (name);
+       g_object_unref (file);
+}
+
+
+static void
+test_g_file_get_display_name_all (void)
+{
+       test_g_file_get_display_name ("sftp:///";, "/");
+       test_g_file_get_display_name ("sftp://日本語";, "日本語");
+       test_g_file_get_display_name ("sftp://日本語/";, "日本語");
+       test_g_file_get_display_name ("sftp://日本語/諸星.txt";, "諸星.txt");
+       test_g_file_get_display_name ("file:///日/本/諸星.txt", "諸星.txt");
+       test_g_file_get_display_name ("file:///日本語/諸星", "諸星");
+       test_g_file_get_display_name ("file:///", "/");
+}
+
+
+static void
+test_g_utf8_n_equal_all (void)
+{
+       g_assert_true (_g_utf8_n_equal (NULL, NULL, 0));
+       g_assert_true (_g_utf8_n_equal ("", "", 0));
+       g_assert_true (_g_utf8_n_equal ("日本語", "日", 1));
+       g_assert_true (_g_utf8_n_equal ("日", "日本語", 1));
+       g_assert_true (_g_utf8_n_equal (".tar.日", ".tar.", 5));
+       g_assert_false (_g_utf8_n_equal ("日本", "日本語", 3));
+       g_assert_false (_g_utf8_n_equal ("日", "日本語", 3));
+       g_assert_false (_g_utf8_n_equal ("", "日本語", 3));
+       g_assert_false (_g_utf8_n_equal ("日", "日本語", 2));
+       g_assert_false (_g_utf8_n_equal ("日", "日本", 2));
+       g_assert_false (_g_utf8_n_equal ("日", "日", 2));
+       g_assert_true (_g_utf8_n_equal ("日", "日", 1));
+       g_assert_true (_g_utf8_n_equal ("本", "日", 0));
+       g_assert_false (_g_utf8_n_equal ("本", "日", 1));
+       g_assert_true (_g_utf8_n_equal ("日本", "日", 1));
+}
+
+
+static void
+test_g_utf8_last_char_all (void)
+{
+       g_assert_cmpstr (_g_utf8_last_char (NULL, NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_last_char ("", NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_last_char ("日", NULL), ==, "日");
+       g_assert_cmpstr (_g_utf8_last_char ("日本", NULL), ==, "本");
+       g_assert_cmpstr (_g_utf8_last_char ("日本語", NULL), ==, "語");
+}
+
+
+static void
+test_g_utf8_replace_str_all (void)
+{
+       g_assert_cmpstr (_g_utf8_replace_str (NULL, NULL, NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_replace_str (NULL, "の", "-"), ==, NULL);
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", NULL, NULL), ==, "正の體の字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "の", NULL), ==, "正體字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "の", ""), ==, "正體字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "", NULL), ==, "正の體の字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "", ""), ==, "正の體の字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "", "-"), ==, "正の體の字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "の", "-"), ==, "正-體-字");
+       g_assert_cmpstr (_g_utf8_replace_str ("正の體の字", "-", "の"), ==, "正の體の字");
+}
+
+
+static void
+_g_assert_strv_equal (char **strv, ...)
+{
+       va_list     args;
+       int         i;
+       const char *str;
+
+       va_start (args, strv);
+       i = 0;
+       while ((str = va_arg (args, const char *)) != NULL) {
+               g_assert_cmpstr (strv[i], ==, str);
+               i++;
+       }
+       va_end (args);
+
+       g_assert_cmpstr (strv[i], ==, NULL);
+}
+
+
+static void
+test_g_utf8_split_all (void)
+{
+       char **strv;
+
+       strv = _g_utf8_split (NULL, NULL, -1);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", NULL, -1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split (NULL, "の", -1);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", "の", -1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split (NULL, "", -1);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("", "", -1);
+       _g_assert_strv_equal (strv, "", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("", "の", -1);
+       _g_assert_strv_equal (strv, "", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の", "の", -1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體", "の", -1);
+       _g_assert_strv_equal (strv, "正", "體", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の", "の", -1);
+       _g_assert_strv_equal (strv, "正", "體", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の字", "の", -1);
+       _g_assert_strv_equal (strv, "正", "體", "字", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正體字", "", -1);
+       _g_assert_strv_equal (strv, "正", "體", "字", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split (NULL, NULL, 0);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("", "", 0);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", NULL, 0);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split (NULL, NULL, 1);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("", "", 1);
+       _g_assert_strv_equal (strv, "", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", NULL, 1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", "", 1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", "正", 1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", "の", 1);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の", "の", 1);
+       _g_assert_strv_equal (strv, "正の", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體", "の", 1);
+       _g_assert_strv_equal (strv, "正の體", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の", "の", 1);
+       _g_assert_strv_equal (strv, "正の體の", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正", "の", 2);
+       _g_assert_strv_equal (strv, "正", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體", "の", 2);
+       _g_assert_strv_equal (strv, "正", "體", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の", "の", 2);
+       _g_assert_strv_equal (strv, "正", "體の", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の字", "の", 2);
+       _g_assert_strv_equal (strv, "正", "體の字", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の字", "の", 3);
+       _g_assert_strv_equal (strv, "正", "體", "字", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split ("正の體の字", "の", 4);
+       _g_assert_strv_equal (strv, "正", "體", "字", NULL);
+       g_strfreev (strv);
+}
+
+
+static void
+test_g_utf8_split_template_all (void)
+{
+       char **strv;
+
+       strv = _g_utf8_split_template ("");
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("xxx##yy#");
+       _g_assert_strv_equal (strv, "xxx", "##", "yy", "#", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("日");
+       _g_assert_strv_equal (strv, "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("日本");
+       _g_assert_strv_equal (strv, "日本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("#");
+       _g_assert_strv_equal (strv, "#", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("##");
+       _g_assert_strv_equal (strv, "##", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("#日");
+       _g_assert_strv_equal (strv, "#", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("日#");
+       _g_assert_strv_equal (strv, "日", "#", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("日#本");
+       _g_assert_strv_equal (strv, "日", "#", "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("日#本#");
+       _g_assert_strv_equal (strv, "日", "#", "本", "#", NULL);
+       g_strfreev (strv);
+
+       strv = _g_utf8_split_template ("日#本#語");
+       _g_assert_strv_equal (strv, "日", "#", "本", "#", "語", NULL);
+       g_strfreev (strv);
+}
+
+
+static void
+test_g_utf8_rstrip_all (void)
+{
+       g_assert_cmpstr (_g_utf8_rstrip (NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_rstrip (""), ==, "");
+       g_assert_cmpstr (_g_utf8_rstrip (" "), ==, "");
+       g_assert_cmpstr (_g_utf8_rstrip ("  "), ==, "");
+       g_assert_cmpstr (_g_utf8_rstrip ("日"), ==, "日");
+       g_assert_cmpstr (_g_utf8_rstrip (" 日"), ==, " 日");
+       g_assert_cmpstr (_g_utf8_rstrip ("日 "), ==, "日");
+       g_assert_cmpstr (_g_utf8_rstrip ("日  "), ==, "日");
+       g_assert_cmpstr (_g_utf8_rstrip (" 日 "), ==, " 日");
+       g_assert_cmpstr (_g_utf8_rstrip (" 日  "), ==, " 日");
+       g_assert_cmpstr (_g_utf8_rstrip ("日 本"), ==, "日 本");
+       g_assert_cmpstr (_g_utf8_rstrip (" 日 本"), ==, " 日 本");
+       g_assert_cmpstr (_g_utf8_rstrip ("  日 本"), ==, "  日 本");
+       g_assert_cmpstr (_g_utf8_rstrip ("日 本 "), ==, "日 本");
+       g_assert_cmpstr (_g_utf8_rstrip ("日 本  "), ==, "日 本");
+       g_assert_cmpstr (_g_utf8_rstrip ("日  本"), ==, "日  本");
+       g_assert_cmpstr (_g_utf8_rstrip ("日  本 "), ==, "日  本");
+       g_assert_cmpstr (_g_utf8_rstrip ("日  本  "), ==, "日  本");
+}
+
+
+static void
+test_g_utf8_strip_all (void)
+{
+       g_assert_cmpstr (_g_utf8_strip (NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_strip (""), ==, "");
+       g_assert_cmpstr (_g_utf8_strip (" "), ==, "");
+       g_assert_cmpstr (_g_utf8_strip ("  "), ==, "");
+       g_assert_cmpstr (_g_utf8_strip ("日"), ==, "日");
+       g_assert_cmpstr (_g_utf8_strip (" 日"), ==, "日");
+       g_assert_cmpstr (_g_utf8_strip ("日 "), ==, "日");
+       g_assert_cmpstr (_g_utf8_strip (" 日 "), ==, "日");
+       g_assert_cmpstr (_g_utf8_strip ("日 本"), ==, "日 本");
+       g_assert_cmpstr (_g_utf8_strip (" 日 本"), ==, "日 本");
+       g_assert_cmpstr (_g_utf8_strip ("日 本 "), ==, "日 本");
+}
+
+
+static void
+test_g_utf8_translate_all (void)
+{
+       g_assert_cmpstr (_g_utf8_translate (NULL, NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_translate (NULL, "*", ".*", NULL), ==, NULL);
+       g_assert_cmpstr (_g_utf8_translate ("*", "*", "", NULL), ==, "");
+       g_assert_cmpstr (_g_utf8_translate ("**", "*", "", NULL), ==, "");
+       g_assert_cmpstr (_g_utf8_translate ("日", "*", "", NULL), ==, "日");
+       g_assert_cmpstr (_g_utf8_translate ("*日*", NULL), ==, "*日*");
+       g_assert_cmpstr (_g_utf8_translate ("*日*", "*", ".*", NULL), ==, ".*日.*");
+       g_assert_cmpstr (_g_utf8_translate ("*日*", "*", "", NULL), ==, "日");
+       g_assert_cmpstr (_g_utf8_translate ("*日*本.語", ".", "\\.", "*", ".*", NULL), ==, ".*日.*本\\.語");
+}
+
+
+static void
+test_g_path_get_extension_all (void)
+{
+       g_assert_cmpstr (_g_path_get_extension ("日本.tar"), ==, ".tar");
+       g_assert_cmpstr (_g_path_get_extension ("日本.tar.xz"), ==, ".tar.xz");
+       g_assert_cmpstr (_g_path_get_extension ("日本.xz"), ==, ".xz");
+       g_assert_null (_g_path_get_extension ("日本"));
+}
+
+
+static void
+test_g_path_remove_extension_all (void)
+{
+       g_assert_cmpstr (_g_path_remove_extension ("日本.tar"), ==, "日本");
+       g_assert_cmpstr (_g_path_remove_extension ("日本.tar.xz"), ==, "日本");
+       g_assert_cmpstr (_g_path_remove_extension ("日本"), ==, "日本");
+}
+
+
+static void
+test_g_path_is_parent_all (void)
+{
+       g_assert_true (_g_path_is_parent ("/日", "/日"));
+       g_assert_true (_g_path_is_parent ("/日", "/日/"));
+       g_assert_true (_g_path_is_parent ("/日/", "/日"));
+
+       g_assert_true (_g_path_is_parent ("/", "/日/本"));
+       g_assert_true (_g_path_is_parent ("/日", "/日/本"));
+       g_assert_true (_g_path_is_parent ("/日/", "/日/本"));
+
+       g_assert_false (_g_path_is_parent ("/日/本", "/日"));
+       g_assert_false (_g_path_is_parent ("/日/本", "/日/"));
+       g_assert_false (_g_path_is_parent ("/日/本/語", "/日/本"));
+       g_assert_false (_g_path_is_parent ("/日/本/語", "/日/本/"));
+
+       g_assert_false (_g_path_is_parent ("/日/", "/日本"));
+       g_assert_false (_g_path_is_parent ("/日", "/日本"));
+
+       g_assert_false (_g_path_is_parent ("/本", "/日本"));
+       g_assert_false (_g_path_is_parent ("/本", "/日"));
+       g_assert_false (_g_path_is_parent ("/本/", "/日"));
+       g_assert_false (_g_path_is_parent ("/本", "/日/"));
+       g_assert_false (_g_path_is_parent ("/本/", "/日/"));
+}
+
+
+static void
+test_g_path_join_components (const char *expected, ...)
+{
+       va_list      args;
+       const char  *str;
+       GList       *str_list;
+       char       **strv;
+       char        *result;
+
+       str_list = NULL;
+       va_start (args, expected);
+       while ((str = va_arg (args, const char *)) != NULL)
+               str_list = g_list_prepend (str_list, g_strdup (str));
+       va_end (args);
+       str_list = g_list_reverse (str_list);
+
+       strv = _g_string_list_to_strv (str_list);
+       result = _g_path_join_components (strv);
+       g_assert_cmpstr (result, ==, expected);
+
+       g_free (result);
+       g_strfreev (strv);
+       _g_string_list_free (str_list);
+}
+
+
+static void
+test_g_path_join_components_all (void)
+{
+       test_g_path_join_components ("", NULL);
+       test_g_path_join_components ("", "", NULL);
+       test_g_path_join_components ("/", "", "", NULL);
+       test_g_path_join_components ("/", "", "/", NULL);
+
+       test_g_path_join_components ("/", "/", NULL);
+       test_g_path_join_components ("/", "/", "", NULL);
+       test_g_path_join_components ("/", "/", "/", NULL);
+
+       test_g_path_join_components ("本", "本", NULL);
+       test_g_path_join_components ("/本", "/本", NULL);
+       test_g_path_join_components ("本/", "本/", NULL);
+       test_g_path_join_components ("/本/", "/本/", NULL);
+
+       test_g_path_join_components ("本/", "本", "", NULL);
+       test_g_path_join_components ("/本/", "/本", "", NULL);
+       test_g_path_join_components ("本/", "本/", "", NULL);
+       test_g_path_join_components ("/本/", "/本/", "", NULL);
+
+       test_g_path_join_components ("本/", "本", "/", NULL);
+       test_g_path_join_components ("/本/", "/本", "/", NULL);
+       test_g_path_join_components ("本/", "本/", "/", NULL);
+       test_g_path_join_components ("/本/", "/本/", "/", NULL);
+
+       test_g_path_join_components ("/本/", "/本", "", NULL);
+       test_g_path_join_components ("/本/", "/本", "", "", NULL);
+       test_g_path_join_components ("/本/", "/本", "/", NULL);
+       test_g_path_join_components ("/本/", "/本", "/", "/", NULL);
+
+       test_g_path_join_components ("/本", "/", "本", NULL);
+       test_g_path_join_components ("/本", "/", "/本", NULL);
+       test_g_path_join_components ("/本/", "/", "/本/", NULL);
+       test_g_path_join_components ("/本", "/", "/", "本", NULL);
+       test_g_path_join_components ("/本", "/", "/", "/本", NULL);
+       test_g_path_join_components ("/本/", "/", "/", "/本/", NULL);
+}
+
+
+static void
+test_g_path_split_components_all (void)
+{
+       char **strv;
+
+       strv = _g_path_split_components (NULL, NULL);
+       _g_assert_strv_equal (strv, NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("", NULL);
+       _g_assert_strv_equal (strv, "", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/", NULL);
+       _g_assert_strv_equal (strv, "/", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("//", NULL);
+       _g_assert_strv_equal (strv, "/", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("///", NULL);
+       _g_assert_strv_equal (strv, "/", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本", NULL);
+       _g_assert_strv_equal (strv, "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("//本", NULL);
+       _g_assert_strv_equal (strv, "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本/", NULL);
+       _g_assert_strv_equal (strv, "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本//", NULL);
+       _g_assert_strv_equal (strv, "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("//本//", NULL);
+       _g_assert_strv_equal (strv, "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本/日", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本/日/", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("//本/日/", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本//日/", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("/本/日//", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("本", NULL);
+       _g_assert_strv_equal (strv, "本", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("本日", NULL);
+       _g_assert_strv_equal (strv, "本日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("本/日", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("本//日", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("本//日/", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+
+       strv = _g_path_split_components ("本//日//", NULL);
+       _g_assert_strv_equal (strv, "本", "日", NULL);
+       g_strfreev (strv);
+}
+
+
+static void
+test_g_path_get_relative_all (void)
+{
+       g_assert_cmpstr (_g_path_get_relative ("/日/本/語", "/日/諸星"), ==, "../本/語");
+       g_assert_cmpstr (_g_path_get_relative ("/日/本/語", "/日"), ==, "本/語");
+       g_assert_cmpstr (_g_path_get_relative ("/日/本/語", "/日/"), ==, "本/語");
+       g_assert_cmpstr (_g_path_get_relative ("/日/本", "/日/本"), ==, "./");
+       g_assert_cmpstr (_g_path_get_relative ("/日", "/日"), ==, "./");
+       g_assert_cmpstr (_g_path_get_relative ("/", "/"), ==, "./");
+       g_assert_cmpstr (_g_path_get_relative ("/日/本語", "/日/本"), ==, "../本語");
+       g_assert_cmpstr (_g_path_get_relative ("/日/本", "/日/本語"), ==, "../本");
+}
+
+
+static void
+test_g_uri_get_relative_all (void)
+{
+       g_assert_cmpstr (_g_uri_get_relative_path ("file:///日/本/語", "file:///日/諸星"), ==, "../本/語");
+       g_assert_cmpstr (_g_uri_get_relative_path ("file:///日/本/語", "file:///日"), ==, "本/語");
+       g_assert_cmpstr (_g_uri_get_relative_path ("smb:///日/本/語", "file:///日/諸星"), ==, "smb:///日/本/語");
+       g_assert_cmpstr (_g_uri_get_relative_path ("file:///日/本", "file:///日/本"), ==, "./");
+}
+
+
+static void
+test_g_uri_get_scheme_all (void)
+{
+       g_assert_cmpstr (_g_uri_get_scheme (NULL), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_scheme (""), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_scheme ("/"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_scheme ("file:"), ==, "file");
+       g_assert_cmpstr (_g_uri_get_scheme ("file://"), ==, "file");
+       g_assert_cmpstr (_g_uri_get_scheme ("file:///"), ==, "file");
+       g_assert_cmpstr (_g_uri_get_scheme ("file:///日/本/語"), ==, "file");
+       g_assert_cmpstr (_g_uri_get_scheme ("sftp+file:///日/本/語"), ==, "sftp+file");
+}
+
+
+static void
+test_g_uri_get_path_all (void)
+{
+       g_assert_cmpstr (_g_uri_get_path (NULL), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_path (""), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_path ("file:"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_path ("file:/"), ==, "/");
+       g_assert_cmpstr (_g_uri_get_path ("file://"), ==, NULL);
+       g_assert_cmpstr (_g_uri_get_path ("file:///"), ==, "/");
+       g_assert_cmpstr (_g_uri_get_path ("file:///%E6%97%A5"), ==, "/日");
+       g_assert_cmpstr (_g_uri_get_path ("file:///%E6%97%A5/"), ==, "/日/");
+       g_assert_cmpstr (_g_uri_get_path ("file:///%E6%97%A5/%E6%9C%AC/%E8%AA%9E"), ==, "/日/本/語");
+}
+
+
+static void
+test_g_uri_is_parent_all (void)
+{
+       g_assert_false (_g_uri_is_parent (NULL, NULL));
+       g_assert_false (_g_uri_is_parent ("", ""));
+       g_assert_false (_g_uri_is_parent ("file:", "file:"));
+       g_assert_true (_g_uri_is_parent ("file:/日", "file:/日/本"));
+       g_assert_true (_g_uri_is_parent ("file:///日", "file:///日/本"));
+       g_assert_true (_g_uri_is_parent ("file:///日/本", "file:///日/本"));
+       g_assert_true (_g_uri_is_parent ("file:///日/本/", "file:///日/本"));
+       g_assert_true (_g_uri_is_parent ("file:///日/本", "file:///日/本/"));
+       g_assert_true (_g_uri_is_parent ("file:///日/本/", "file:///日/本/"));
+       g_assert_false (_g_uri_is_parent ("file:/日", "smb:/日/本"));
+}
+
+
+static void
+test_g_uri_remove_extension_all (void)
+{
+       g_assert_cmpstr (_g_uri_remove_extension ("file:///日本"), ==, "file:///日本");
+       g_assert_cmpstr (_g_uri_remove_extension ("file:///日本.tar"), ==, "file:///日本");
+       g_assert_cmpstr (_g_uri_remove_extension ("file:///日本.tar.xz"), ==, "file:///日本");
+       g_assert_cmpstr (_g_uri_remove_extension ("file://諸:星@日:123/日本.tar.xz"), ==, "file://諸:星@日:123/日本");
+}
+
+
 int
 main (int   argc,
       char *argv[])
 {
+       setlocale (LC_ALL, "");
        g_test_init (&argc, &argv, NULL);
 
-       g_test_add_func ("/glib-utils/_g_rand_string/1", test_g_rand_string);
+       g_test_add_func ("/glib-utils/_g_utf8_after_ascii_space", test_g_utf8_after_ascii_space);
+       g_test_add_func ("/glib-utils/_g_utf8_all_spaces", test_g_utf8_all_spaces_space);
+       g_test_add_func ("/glib-utils/_g_utf8_escape_xml", test_g_utf8_escape_xml_space);
+       g_test_add_func ("/glib-utils/_g_utf8_find_str", test_g_utf8_find_str);
+       g_test_add_func ("/glib-utils/_g_utf8_has_prefix", test_g_utf8_has_prefix);
+       g_test_add_func ("/glib-utils/_g_utf8_last_char", test_g_utf8_last_char_all);
+       g_test_add_func ("/glib-utils/_g_utf8_n_equal", test_g_utf8_n_equal_all);
+       g_test_add_func ("/glib-utils/_g_utf8_replace_str", test_g_utf8_replace_str_all);
+       g_test_add_func ("/glib-utils/_g_utf8_rstrip", test_g_utf8_rstrip_all);
+       g_test_add_func ("/glib-utils/_g_utf8_split", test_g_utf8_split_all);
+       g_test_add_func ("/glib-utils/_g_utf8_split_template", test_g_utf8_split_template_all);
+       g_test_add_func ("/glib-utils/_g_utf8_strip", test_g_utf8_strip_all);
+       g_test_add_func ("/glib-utils/_g_utf8_translate", test_g_utf8_translate_all);
+
+       g_test_add_func ("/glib-utils/_g_path_get_basename", test_g_path_get_basename_all);
+       g_test_add_func ("/glib-utils/_g_path_get_extension", test_g_path_get_extension_all);
+       g_test_add_func ("/glib-utils/_g_path_get_parent", test_g_path_get_parent_all);
+       g_test_add_func ("/glib-utils/_g_path_get_relative", test_g_path_get_relative_all);
+       g_test_add_func ("/glib-utils/_g_path_is_parent", test_g_path_is_parent_all);
+       g_test_add_func ("/glib-utils/_g_path_join_components", test_g_path_join_components_all);
+       g_test_add_func ("/glib-utils/_g_path_remove_extension", test_g_path_remove_extension_all);
+       g_test_add_func ("/glib-utils/_g_path_split_components", test_g_path_split_components_all);
+
+       g_test_add_func ("/glib-utils/_g_uri_append_path", test_g_uri_append_path_all);
+       g_test_add_func ("/glib-utils/_g_uri_from_path", test_g_uri_from_path_all);
+       g_test_add_func ("/glib-utils/_g_uri_get_basename", test_g_uri_get_basename_all);
+       g_test_add_func ("/glib-utils/_g_uri_get_parent", test_g_uri_get_parent_all);
+       g_test_add_func ("/glib-utils/_g_uri_get_relative_path", test_g_uri_get_relative_all);
+       g_test_add_func ("/glib-utils/_g_uri_get_scheme", test_g_uri_get_scheme_all);
+       g_test_add_func ("/glib-utils/_g_uri_get_path", test_g_uri_get_path_all);
+       g_test_add_func ("/glib-utils/_g_uri_is_parent", test_g_uri_is_parent_all);
+       g_test_add_func ("/glib-utils/_g_uri_remove_extension", test_g_uri_remove_extension_all);
+
+       g_test_add_func ("/glib-utils/_g_file_get_display_name", test_g_file_get_display_name_all);
+       g_test_add_func ("/glib-utils/_g_rand_string", test_g_rand_string);
        g_test_add_func ("/glib-utils/regex", test_regexp);
-       g_test_add_func ("/glib-utils/_g_utf8_has_prefix/1", test_g_utf8_has_prefix);
-       g_test_add_func ("/glib-utils/_g_utf8_first_space/1", test_g_utf8_first_space);
-       g_test_add_func ("/glib-utils/remove_lang_from_utf8_string/1", test_remove_lang_from_utf8_string_all);
+       g_test_add_func ("/glib-utils/remove_lang_from_utf8_string", test_remove_lang_from_utf8_string_all);
 
        return g_test_run ();
 }
diff --git a/gthumb/uri-utils.c b/gthumb/uri-utils.c
new file mode 100644
index 00000000..06bfcc7f
--- /dev/null
+++ b/gthumb/uri-utils.c
@@ -0,0 +1,1122 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2019 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include "glib-utils.h"
+#include "uri-utils.h"
+
+
+#define _G_URI_RESERVED_CHARS_IN_HOST "[]"
+
+
+/* -- _g_uri_parse --
+ *
+ * References:
+ *
+ * https://tools.ietf.org/html/rfc3986
+ * https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Generic_syntax
+ */
+
+
+typedef struct {
+       const char *scheme;
+       gsize       scheme_size;
+       const char *userinfo;
+       gsize       userinfo_size;
+       const char *host;
+       gsize       host_size;
+       const char *port;
+       gsize       port_size;
+       const char *path;
+       gsize       path_size;
+       const char *query;
+       gsize       query_size;
+       const char *fragment;
+       gsize       fragment_size;
+} UriInfo;
+
+
+typedef enum {
+       URI_STATE_ERROR,
+       URI_STATE_START,
+       URI_STATE_SCHEME,
+       URI_STATE_HIER,
+       URI_STATE_AUTHORITY,
+       URI_STATE_USERINFO_OR_HOST,
+       URI_STATE_IP_LITERAL,
+       URI_STATE_HOST,
+       URI_STATE_PORT,
+       URI_STATE_PATH,
+       URI_STATE_QUERY,
+       URI_STATE_FRAGMENT
+} UriState;
+
+
+static gboolean
+_g_uri_parse (const char *uri,
+             UriInfo    *info)
+{
+       UriState    state;
+       const char *p;
+       gunichar    c;
+       const char *part_begin;
+
+       if (uri == NULL)
+               return FALSE;
+
+       if (! g_utf8_validate (uri, -1, NULL))
+               return FALSE;
+
+#define CODE(x) do { x; } while (FALSE)
+#define PART_SET(dest, begin, size) CODE (info->dest = begin; info->dest##_size = size)
+#define PART_INIT(dest) PART_SET(dest, NULL, 0)
+#define PART_BEGIN(v) CODE (state = v; part_begin = p)
+#define PART_CONTINUE(v) CODE (/* void */)
+#define PART_END(dest) PART_SET(dest, part_begin, p - part_begin)
+#define NEXT_CHAR CODE (p = next_p; next_p = g_utf8_next_char (p))
+
+       PART_INIT (scheme);
+       PART_INIT (userinfo);
+       PART_INIT (host);
+       PART_INIT (port);
+       PART_INIT (path);
+       PART_INIT (query);
+       PART_INIT (fragment);
+
+       state = URI_STATE_START;
+       p = uri;
+       while ((state != URI_STATE_ERROR) && (c = g_utf8_get_char (p)) != 0) {
+               const char *next_p = g_utf8_next_char (p);
+               gunichar    next_c = g_utf8_get_char (next_p);
+
+               switch (state) {
+               case URI_STATE_START:
+                       if (c == '/')
+                               PART_BEGIN (URI_STATE_PATH);
+                       else if (g_unichar_isalpha (c))
+                               PART_BEGIN (URI_STATE_SCHEME);
+                       else
+                               state = URI_STATE_ERROR;
+                       break;
+
+               case URI_STATE_SCHEME:
+                       if (c == ':') {
+                               PART_END (scheme);
+                               state = URI_STATE_HIER;
+                       }
+                       else if (g_unichar_isalpha (c)
+                               || g_unichar_isdigit (c)
+                               || (c == '+')
+                               || (c == '-')
+                               || (c == '.'))
+                       {
+                               PART_CONTINUE (URI_STATE_SCHEME);
+                       }
+                       else
+                               state = URI_STATE_ERROR;
+                       break;
+
+               case URI_STATE_HIER:
+                       if ((c == '/') && (next_c == '/')) {
+                               state = URI_STATE_AUTHORITY;
+                               NEXT_CHAR;
+                       }
+                       else
+                               PART_BEGIN (URI_STATE_PATH);
+                       break;
+
+               case URI_STATE_AUTHORITY:
+                       if (c == '/')
+                               PART_BEGIN (URI_STATE_PATH);
+                       else if (c == '[')
+                               PART_BEGIN (URI_STATE_IP_LITERAL);
+                       else
+                               PART_BEGIN (URI_STATE_USERINFO_OR_HOST);
+                       break;
+
+               case URI_STATE_IP_LITERAL:
+                       PART_CONTINUE (URI_STATE_IP_LITERAL);
+                       if (c == ']') {
+                               PART_END (host);
+
+                               if (next_c == '?') {
+                                       NEXT_CHAR;
+                                       NEXT_CHAR;
+                                       PART_BEGIN (URI_STATE_QUERY);
+                               }
+                               else if (next_c == '#') {
+                                       NEXT_CHAR;
+                                       NEXT_CHAR;
+                                       PART_BEGIN (URI_STATE_FRAGMENT);
+                               }
+                               else if (next_c == ':') {
+                                       NEXT_CHAR;
+                                       NEXT_CHAR;
+                                       PART_BEGIN (URI_STATE_PORT);
+                               }
+                               else {
+                                       NEXT_CHAR;
+                                       PART_BEGIN (URI_STATE_PATH);
+                               }
+                       }
+                       break;
+
+               case URI_STATE_USERINFO_OR_HOST:
+               case URI_STATE_HOST:
+                       if (c == '@') {
+                               if (state == URI_STATE_HOST) {
+                                       state = URI_STATE_ERROR;
+                               }
+                               else {
+                                       PART_END (userinfo);
+
+                                       /* After the userinfo the host is mandatory. */
+
+                                       if ((next_c == '/')
+                                               || (next_c == '?')
+                                               || (next_c == '#')
+                                               || (next_c == ':'))
+                                       {
+                                               state = URI_STATE_ERROR;
+                                       }
+                                       else if (next_c == '[') {
+                                               NEXT_CHAR;
+                                               PART_BEGIN (URI_STATE_IP_LITERAL);
+                                       }
+                                       else {
+                                               NEXT_CHAR;
+                                               PART_BEGIN (URI_STATE_HOST);
+                                       }
+                               }
+                       }
+                       else if (c == '/') {
+                               PART_END (host);
+                               PART_BEGIN (URI_STATE_PATH);
+                       }
+                       else if (c == '?') {
+                               PART_END (host);
+                               NEXT_CHAR;
+                               PART_BEGIN (URI_STATE_QUERY);
+                       }
+                       else if (c == '#') {
+                               PART_END (host);
+                               NEXT_CHAR;
+                               PART_BEGIN (URI_STATE_FRAGMENT);
+                       }
+                       else if (c == ':') {
+
+                               /* Possible ambiguity: the colon can be part of
+                                * the userinfo as well as separate host and port. */
+
+                               if (state == URI_STATE_HOST) {
+                                       PART_END (host);
+                                       NEXT_CHAR;
+                                       PART_BEGIN (URI_STATE_PORT);
+                               }
+                               else {
+                                       gboolean    is_userinfo = TRUE;
+                                       const char *forward_p = next_p;
+
+                                       /* Search for @ until the end of the authority part. */
+
+                                       while (is_userinfo) {
+                                               gunichar forward_c = g_utf8_get_char (forward_p);
+
+                                               if ((forward_c == 0)
+                                                       || (forward_c == '/')
+                                                       || (forward_c == '?')
+                                                       || (forward_c == '#'))
+                                               {
+                                                       is_userinfo = FALSE;
+                                                       break;
+                                               }
+                                               else if (forward_c == '@') {
+                                                       is_userinfo = TRUE;
+                                                       break;
+                                               }
+
+                                               forward_p = g_utf8_next_char (forward_p);
+                                       }
+
+                                       if (is_userinfo) {
+                                               PART_CONTINUE (URI_STATE_USERINFO_OR_HOST);
+                                       }
+                                       else {
+                                               PART_END (host);
+                                               NEXT_CHAR;
+                                               PART_BEGIN (URI_STATE_PORT);
+                                       }
+                               }
+                       }
+                       else
+                               PART_CONTINUE (URI_STATE_USERINFO_OR_HOST);
+                       break;
+
+               case URI_STATE_PORT:
+                       if (g_unichar_isdigit (c)) {
+                               PART_CONTINUE (URI_STATE_PORT);
+                       }
+                       else if (c == '/') {
+                               PART_END (port);
+                               PART_BEGIN (URI_STATE_PATH);
+                       }
+                       else
+                               state = URI_STATE_ERROR;
+                       break;
+
+               case URI_STATE_PATH:
+                       if (c == '?') {
+                               PART_END (path);
+                               NEXT_CHAR;
+                               PART_BEGIN (URI_STATE_QUERY);
+                       }
+                       else if (c == '#') {
+                               PART_END (path);
+                               NEXT_CHAR;
+                               PART_BEGIN (URI_STATE_FRAGMENT);
+                       }
+                       else
+                               PART_CONTINUE (URI_STATE_PATH);
+                       break;
+
+               case URI_STATE_QUERY:
+                       if (c == '#') {
+                               PART_END (query);
+                               NEXT_CHAR;
+                               PART_BEGIN (URI_STATE_FRAGMENT);
+                       }
+                       else
+                               PART_CONTINUE (URI_STATE_QUERY);
+                       break;
+
+               case URI_STATE_FRAGMENT:
+                       PART_CONTINUE (URI_STATE_FRAGMENT);
+                       break;
+
+               case URI_STATE_ERROR:
+                       break;
+               }
+
+               p = next_p;
+       }
+
+       switch (state) {
+       case URI_STATE_HIER:
+       case URI_STATE_AUTHORITY:
+               break;
+
+       case URI_STATE_USERINFO_OR_HOST:
+       case URI_STATE_HOST:
+               PART_END (host);
+               break;
+
+       case URI_STATE_PORT:
+               PART_END (port);
+               break;
+
+       case URI_STATE_PATH:
+               PART_END (path);
+               break;
+
+       case URI_STATE_QUERY:
+               PART_END (query);
+               break;
+
+       case URI_STATE_FRAGMENT:
+               PART_END (fragment);
+               break;
+
+       default:
+               state = URI_STATE_ERROR;
+               break;
+       }
+
+#undef NEXT_CHAR
+#undef PART_END
+#undef PART_CONTINUE
+#undef PART_BEGIN
+#undef PART_INIT
+#undef PART_SET
+#undef CODE
+
+       return state != URI_STATE_ERROR;
+}
+
+
+static char *
+_g_uri_info_unescape_part (const char *part,
+                          gsize       part_size)
+{
+       if (part_size == 0)
+               return NULL;
+
+       return g_uri_unescape_segment (part,
+                                      part + part_size,
+                                      NULL);
+}
+
+
+gboolean
+_g_uri_split (const char *uri,
+             UriParts   *parts)
+{
+       UriInfo info;
+
+       if (! _g_uri_parse (uri, &info))
+               return FALSE;
+
+       parts->scheme = g_strndup (info.scheme, info.scheme_size);
+       parts->userinfo = _g_uri_info_unescape_part (info.userinfo, info.userinfo_size);
+       parts->host = _g_uri_info_unescape_part (info.host, info.host_size);
+       parts->port = g_strndup (info.port, info.port_size);
+       parts->path = _g_uri_info_unescape_part (info.path, info.path_size);
+       parts->query = g_strndup (info.query, info.query_size);
+       parts->fragment = g_strndup (info.fragment, info.fragment_size);
+
+       return TRUE;
+}
+
+
+/* Format:
+ *
+ * URI = scheme:[//authority]path[?query][#fragment]
+ * authority = [userinfo@]host[:port]
+ */
+
+
+static void
+_g_string_append_uri_escaped (GString    *str,
+                             const char *val,
+                             const char *reserved_chars_allowed)
+{
+       char *esc_val;
+
+       esc_val = g_uri_escape_string (val, reserved_chars_allowed, TRUE);
+       g_string_append (str, esc_val);
+
+       g_free (esc_val);
+}
+
+
+char *
+_g_uri_join (UriParts *parts)
+{
+       GString *uri;
+
+       if (parts == NULL)
+               return NULL;
+
+       uri = g_string_new ("");
+
+       if (parts->scheme != NULL) {
+               g_string_append (uri, parts->scheme);
+               g_string_append (uri, "://");
+
+               if (parts->host != NULL) {
+                       if (parts->userinfo != NULL) {
+                               _g_string_append_uri_escaped (uri,
+                                                             parts->userinfo,
+                                                             G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO);
+                               g_string_append_c (uri, '@');
+                       }
+
+                       _g_string_append_uri_escaped (uri, parts->host, _G_URI_RESERVED_CHARS_IN_HOST);
+
+                       if (parts->port != NULL) {
+                               g_string_append_c (uri, ':');
+                               g_string_append (uri, parts->port);
+                       }
+               }
+       }
+
+       if ((parts->path != NULL) && (*parts->path != 0))
+               _g_string_append_uri_escaped (uri,
+                                             parts->path,
+                                             G_URI_RESERVED_CHARS_ALLOWED_IN_PATH);
+       else
+               g_string_append (uri, "/");
+
+       if (parts->query != NULL) {
+               g_string_append_c (uri, '?');
+               g_string_append (uri, parts->query);
+       }
+
+       if (parts->fragment != NULL) {
+               g_string_append_c (uri, '#');
+               g_string_append (uri, parts->fragment);
+       }
+
+       return g_string_free (uri, FALSE);
+}
+
+
+void
+_g_uri_parts_init (UriParts *parts)
+{
+       parts->scheme = NULL;
+       parts->userinfo = NULL;
+       parts->host = NULL;
+       parts->port = NULL;
+       parts->path = NULL;
+       parts->query = NULL;
+       parts->fragment = NULL;
+}
+
+
+void
+_g_uri_parts_clear (UriParts *parts)
+{
+       g_free (parts->scheme);
+       g_free (parts->userinfo);
+       g_free (parts->host);
+       g_free (parts->port);
+       g_free (parts->path);
+       g_free (parts->query);
+       g_free (parts->fragment);
+}
+
+
+char *
+_g_uri_get_part (const char  *uri,
+                UriPart      part)
+{
+       UriInfo     info;
+       const char *begin;
+       gsize       size;
+
+       if (! _g_uri_parse (uri, &info))
+               return NULL;
+
+       switch (part) {
+       case URI_PART_SCHEME:
+               begin = info.scheme;
+               size = info.scheme_size;
+               break;
+
+       case URI_PART_USERINFO:
+               return _g_uri_info_unescape_part (info.userinfo, info.userinfo_size);
+
+       case URI_PART_HOST:
+               begin = info.host;
+               size = info.host_size;
+               break;
+
+       case URI_PART_PORT:
+               begin = info.port;
+               size = info.port_size;
+               break;
+
+       case URI_PART_PATH:
+               return _g_uri_info_unescape_part (info.path, info.path_size);
+
+       case URI_PART_QUERY:
+               begin = info.query;
+               size = info.query_size;
+               break;
+
+       case URI_PART_FRAGMENT:
+               begin = info.fragment;
+               size = info.fragment_size;
+               break;
+       }
+
+       return g_strndup (begin, size);
+}
+
+
+char *
+_g_uri_get_path (const char *uri)
+{
+       UriInfo info;
+
+       if (! _g_uri_parse (uri, &info))
+               return NULL;
+
+       return _g_uri_info_unescape_part (info.path, info.path_size);
+}
+
+
+char *
+_g_uri_get_basename (const char *uri)
+{
+       char *path;
+       char *result;
+
+       path = _g_uri_get_path (uri);
+       result = g_strdup (_g_path_get_basename (path));
+
+       g_free (path);
+
+       return result;
+}
+
+
+char *
+_g_uri_get_extension (const char *uri)
+{
+       char *path;
+       char *result;
+
+       path = _g_uri_get_path (uri);
+       result = g_strdup (_g_path_get_extension (path));
+
+       g_free (path);
+
+       return result;
+}
+
+
+char *
+_g_uri_get_scheme (const char *uri)
+{
+       UriInfo info;
+
+       if (_g_uri_parse (uri, &info))
+               return _g_utf8_strndup (info.scheme, info.scheme_size);
+       else
+               return NULL;
+}
+
+
+char *
+_g_uri_get_relative_path (const char *uri,
+                         const char *base)
+{
+       UriInfo  uri_info;
+       UriInfo  base_info;
+       char    *uri_path;
+       char    *base_path;
+       char    *rel_uri;
+
+       if (! _g_uri_parse (uri, &uri_info))
+               return NULL;
+
+       if (! _g_uri_parse (base, &base_info))
+               return g_strdup (uri);
+
+       if ((uri_info.scheme_size != base_info.scheme_size)
+               || ! _g_utf8_n_equal (uri_info.scheme,
+                                     base_info.scheme,
+                                     uri_info.scheme_size))
+       {
+               return g_strdup (uri);
+       }
+
+       uri_path = _g_utf8_strndup (uri_info.path, uri_info.path_size);
+       base_path = _g_utf8_strndup (base_info.path, base_info.path_size);
+       rel_uri = _g_path_get_relative (uri_path, base_path);
+
+       g_free (uri_path);
+       g_free (base_path);
+
+       return rel_uri;
+}
+
+
+gboolean
+_g_uri_is_parent (const char *uri,
+                 const char *file)
+{
+       UriInfo   uri_info;
+       UriInfo   file_info;
+       char     *path;
+       char     *file_path;
+       gboolean  result;
+
+       if (! _g_uri_parse (uri, &uri_info))
+               return FALSE;
+
+       if (! _g_uri_parse (file, &file_info))
+               return FALSE;
+
+       if ((uri_info.scheme_size != file_info.scheme_size)
+               || ! _g_utf8_n_equal (uri_info.scheme,
+                                     file_info.scheme,
+                                     uri_info.scheme_size))
+       {
+               return FALSE;
+       }
+
+       path = _g_utf8_strndup (uri_info.path, uri_info.path_size);
+       file_path = _g_utf8_strndup (file_info.path, file_info.path_size);
+       result = _g_path_is_parent (path, file_path);
+
+       g_free (file_path);
+       g_free (path);
+
+       return result;
+}
+
+
+char *
+_g_uri_get_parent (const char *uri)
+{
+       UriParts  parts;
+       char     *new_path;
+       char     *new_uri;
+
+       if (! _g_uri_split (uri, &parts))
+               return NULL;
+
+       new_path = _g_path_get_parent (parts.path);
+       _g_str_set (&parts.path, new_path);
+       _g_str_set (&parts.query, NULL);
+       _g_str_set (&parts.fragment, NULL);
+       new_uri = _g_uri_join (&parts);
+
+       _g_uri_parts_clear (&parts);
+       g_free (new_path);
+
+       return new_uri;
+}
+
+
+char *
+_g_uri_remove_extension (const char *uri)
+{
+       UriParts  parts;
+       char     *new_path;
+       char     *new_uri;
+
+       if (! _g_uri_split (uri, &parts))
+               return NULL;
+
+       new_path = _g_path_remove_extension (parts.path);
+       _g_str_set (&parts.path, new_path);
+       _g_str_set (&parts.query, NULL);
+       _g_str_set (&parts.fragment, NULL);
+       new_uri = _g_uri_join (&parts);
+
+       _g_uri_parts_clear (&parts);
+       g_free (new_path);
+
+       return new_uri;
+}
+
+
+char *
+_g_uri_from_path (const char *path)
+{
+       char *escaped;
+       char *uri;
+
+       escaped = g_uri_escape_string (path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
+       uri = g_strconcat ("file://", escaped, NULL);
+
+       g_free (escaped);
+
+       return uri;
+}
+
+
+const char *
+_g_uri_get_home (void)
+{
+       static char *home = NULL;
+
+       if (home == NULL)
+               home = _g_uri_from_path (g_get_home_dir ());
+
+       return home;
+}
+
+
+char *
+_g_uri_append_path (const char *uri,
+                   const char *path)
+{
+       UriParts  parts;
+       char     *new_path;
+       char     *new_uri;
+
+       if (! _g_uri_split (uri, &parts))
+               return NULL;
+
+       new_path = _g_path_join ((parts.path != NULL) ? parts.path : "/", path, NULL);
+
+       g_free (parts.path);
+       parts.path = new_path;
+       new_uri = _g_uri_join (&parts);
+
+       _g_uri_parts_clear (&parts);
+
+       return new_uri;
+}
+
+
+/* -- _g_path_split_components -- */
+
+
+typedef enum {
+       COMP_STATE_START,
+       COMP_STATE_NEXT_NON_SEP_STARTS_COMP,
+       COMP_STATE_NEXT_SEP_ENDS_COMP,
+} CompState;
+
+
+char **
+_g_path_split_components (const char *path,
+                         int        *size)
+{
+       GList       *comp_list;
+       int          comp_n;
+       const char  *comp_begin;
+       CompState    state;
+       char       **comp_v;
+
+       comp_list = NULL;
+       comp_n = 0;
+       comp_begin = NULL;
+       state = COMP_STATE_START;
+       while (path != NULL) {
+               gunichar ch = g_utf8_get_char (path);
+               gboolean is_sep = (ch == '/') || (ch == 0);
+
+               switch (state) {
+               case COMP_STATE_START:
+                       if (ch == 0) {
+                               break;
+                       }
+                       else if (is_sep) {
+                               state = COMP_STATE_NEXT_NON_SEP_STARTS_COMP;
+                       }
+                       else {
+                               comp_begin = path;
+                               state = COMP_STATE_NEXT_SEP_ENDS_COMP;
+                       }
+                       break;
+
+               case COMP_STATE_NEXT_NON_SEP_STARTS_COMP:
+                       if (! is_sep) {
+                               comp_begin = path;
+                               state = COMP_STATE_NEXT_SEP_ENDS_COMP;
+                       }
+                       break;
+
+               case COMP_STATE_NEXT_SEP_ENDS_COMP:
+                       if (is_sep) {
+                               comp_list = g_list_prepend (comp_list, g_strndup (comp_begin, path - 
comp_begin));
+                               comp_n++;
+                               state = COMP_STATE_START;
+                       }
+                       break;
+               }
+
+               if (ch == 0)
+                       break;
+               path = g_utf8_next_char (path);
+       }
+
+       if ((comp_n == 0) && (path != NULL)) {
+               const char *str = (state == COMP_STATE_START) ? "" : "/";
+               comp_list = g_list_prepend (comp_list, g_strdup (str));
+               comp_n++;
+       }
+
+       comp_v = _g_strv_take_from_str_list (comp_list, comp_n);
+       if (size != NULL)
+               *size = comp_n;
+
+       g_list_free (comp_list);
+
+       return comp_v;
+}
+
+
+/* -- _g_path_join_components -- */
+
+
+static gboolean
+_g_unichar_is_separator (gunichar ch)
+{
+       return ch == '/';
+}
+
+
+char *
+_g_path_join_components (char **comp_v)
+{
+       GString *path;
+       int      i;
+
+       if (comp_v == NULL)
+               return NULL;
+
+       path = g_string_new ("");
+       for (i = 0; comp_v[i] != NULL; i++) {
+               const char *next = comp_v[i + 1];
+               char       *comp;
+
+               /* If the next component starts with a separator
+                * trim the trailing separators from this component. */
+
+               if ((next != NULL) && (*next == '/'))
+                       comp = _g_utf8_rstrip_func (comp_v[i], _g_unichar_is_separator);
+               else
+                       comp = g_strdup (comp_v[i]);
+               g_string_append (path, comp);
+
+               if ((comp != NULL) && (next != NULL) && (*next != '/')) {
+                       const char *last_ch = _g_utf8_last_char (comp, NULL);
+                       if ((last_ch != NULL) && (g_utf8_get_char (last_ch) != '/'))
+                               g_string_append_c (path, '/');
+               }
+
+               g_free (comp);
+       }
+
+       if ((path->len == 0) && (i > 1))
+               g_string_append_c (path, '/');
+
+       return g_string_free (path, FALSE);
+}
+
+
+char *
+_g_path_join (char *first, ...)
+{
+       va_list      args;
+       const char  *arg;
+       GList       *arg_list;
+       int          n_comp;
+       char       **argv;
+       char        *result;
+
+       arg_list = g_list_prepend (NULL, g_strdup (first));
+       n_comp = 1;
+
+       va_start (args, first);
+       while ((arg = va_arg (args, const char *)) != NULL) {
+               arg_list = g_list_prepend (arg_list, g_strdup (arg));
+               n_comp++;
+       }
+       va_end (args);
+
+       argv = _g_strv_take_from_str_list (arg_list, n_comp);
+       result = _g_path_join_components (argv);
+
+       g_strfreev (argv);
+       g_list_free (arg_list);
+
+       return result;
+}
+
+
+const char *
+_g_path_get_basename (const char *path)
+{
+       const char *last_non_sep;
+       const char *p;
+
+       if (path == NULL)
+               return NULL;
+
+       last_non_sep = NULL;
+       p = _g_utf8_last_char (path, NULL);
+       while (p != NULL) {
+               if (g_utf8_get_char (p) == '/')
+                       break;
+               last_non_sep = p;
+               p = g_utf8_find_prev_char (path, p);
+       }
+
+       return last_non_sep;
+}
+
+
+char *
+_g_path_get_parent (const char *path)
+{
+       const char *p;
+
+       p = _g_utf8_last_char (path, NULL);
+       while (p != NULL) {
+               if (g_utf8_get_char (p) == '/')
+                       break;
+               p = g_utf8_find_prev_char (path, p);
+       }
+
+       if (p == NULL)
+               return NULL;
+
+       if (p == path)
+               return g_strdup ("/");
+
+       return g_strndup (path, p - path);
+}
+
+
+const char *
+_g_path_get_extension (const char *path)
+{
+       char *p;
+       char *p2;
+
+       if (path == NULL)
+               return NULL;
+
+       p = g_utf8_strrchr (path, -1, '.');
+       if (p == NULL)
+               return NULL;
+
+       p2 = g_utf8_find_prev_char (path, p);
+       while (p2 != NULL) {
+               if (g_utf8_get_char (p2) == '.')
+                       break;
+               p2 = g_utf8_find_prev_char (path, p2);
+       }
+
+       if (_g_utf8_n_equal (p2, ".tar.", 5))
+               p = p2;
+
+       return p;
+}
+
+
+char *
+_g_path_remove_extension (const char *path)
+{
+       char *new_path;
+       char *ext;
+
+       if (path == NULL)
+               return NULL;
+
+       new_path = g_strdup (path);
+       ext = (char *) _g_path_get_extension (new_path);
+       if (ext != NULL)
+               *ext = 0;
+
+       return new_path;
+}
+
+
+gboolean
+_g_path_is_parent (const char *dir,
+                  const char *file)
+{
+       const char *dir_p = NULL;
+       const char *file_p = NULL;
+       const char *p;
+       gunichar    dir_ch[3];
+       gunichar    file_ch[2];
+
+       if ((dir == NULL) || (file == NULL))
+               return FALSE;
+
+       while ((dir != NULL) && (file != NULL)) {
+               gunichar c1 = g_utf8_get_char (dir);
+               gunichar c2 = g_utf8_get_char (file);
+
+               if ((c1 == 0) || (c2 == 0))
+                       break;
+
+               if (c1 != c2)
+                       break;
+
+               dir_p = dir;
+               file_p = file;
+
+               dir = g_utf8_next_char (dir);
+               file = g_utf8_next_char (file);
+       }
+
+       /* dir and file have the same content until dir_p and file_p. */
+
+       /* dir_ch contains the last same char and the next two in dir. */
+
+       p = dir_p;
+       dir_ch[0] = (p != NULL) ? g_utf8_get_char (p) : 0;
+
+       p = g_utf8_next_char (p);
+       dir_ch[1] = ((dir_ch[0] != 0) && (p != NULL)) ? g_utf8_get_char (p) : 0;
+
+       p = g_utf8_next_char (p);
+       dir_ch[2] = ((dir_ch[1] != 0) && (p != NULL)) ? g_utf8_get_char (p) : 0;
+
+       /* file_ch contains the last same char and the next one in file. */
+
+       p = file_p;
+       file_ch[0] = (p != NULL) ? g_utf8_get_char (p) : 0;
+
+       p = g_utf8_next_char (p);
+       file_ch[1] = ((file_ch[0] != 0) && (p != NULL)) ? g_utf8_get_char (p) : 0;
+
+       g_assert (dir_ch[0] == file_ch[0]);
+
+       if ((dir_ch[1] == 0) && (file_ch[1] == 0))
+               return TRUE;
+
+       if ((dir_ch[1] == 0) && (file_ch[1] == '/'))
+               return TRUE;
+
+       if ((dir_ch[1] == '/') && (dir_ch[2] == 0) && (file_ch[1] == 0))
+               return TRUE;
+
+       if ((dir_ch[0] == '/') && (dir_ch[1] == 0))
+               return TRUE;
+
+       return FALSE;
+}
+
+
+char *
+_g_path_get_relative (const char *path,
+                     const char *base)
+{
+       GString  *rel_path;
+       char    **dir_v;
+       char    **base_v;
+       int       i;
+       int       j;
+
+       rel_path = g_string_new (NULL);
+       dir_v = _g_path_split_components (path, NULL);
+       base_v = _g_path_split_components (base, NULL);
+
+       i = 0;
+       while ((dir_v[i] != NULL)
+               && (base_v[i] != NULL)
+               && (strcmp (dir_v[i], base_v[i]) == 0))
+       {
+               i++;
+       }
+
+       j = i;
+
+       while (base_v[i++] != NULL)
+               g_string_append (rel_path, "../");
+
+       while (dir_v[j] != NULL) {
+               g_string_append (rel_path, dir_v[j]);
+               if (dir_v[j + 1] != NULL)
+                       g_string_append_c (rel_path, '/');
+               j++;
+       }
+
+       if (rel_path->len == 0)
+               g_string_append (rel_path, "./");
+
+       g_strfreev (base_v);
+       g_strfreev (dir_v);
+
+       return g_string_free (rel_path, FALSE);
+}
diff --git a/gthumb/uri-utils.h b/gthumb/uri-utils.h
new file mode 100644
index 00000000..ca725c7f
--- /dev/null
+++ b/gthumb/uri-utils.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2019 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _URI_UTILS_H
+#define _URI_UTILS_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+       char *scheme;
+       char *userinfo;
+       char *host;
+       char *port;
+       char *path;
+       char *query;
+       char *fragment;
+} UriParts;
+
+typedef enum {
+       URI_PART_SCHEME,
+       URI_PART_USERINFO,
+       URI_PART_HOST,
+       URI_PART_PORT,
+       URI_PART_PATH,
+       URI_PART_QUERY,
+       URI_PART_FRAGMENT
+} UriPart;
+
+gboolean       _g_uri_split                    (const char      *uri,
+                                                UriParts        *parts);
+char *         _g_uri_join                     (UriParts        *parts);
+void           _g_uri_parts_init               (UriParts        *parts);
+void           _g_uri_parts_clear              (UriParts        *parts);
+char *         _g_uri_get_part                 (const char      *uri,
+                                                UriPart          part);
+char *         _g_uri_get_path                 (const char      *uri);
+char *         _g_uri_get_basename             (const char      *uri);
+char *         _g_uri_get_extension            (const char      *uri);
+char *         _g_uri_get_scheme               (const char      *uri);
+char *         _g_uri_get_relative_path        (const char      *uri,
+                                                const char      *base);
+gboolean       _g_uri_is_parent                (const char      *uri,
+                                                const char      *file);
+char *         _g_uri_get_parent               (const char      *uri);
+char *         _g_uri_remove_extension         (const char      *uri);
+char *         _g_uri_from_path                (const char      *path);
+const char *   _g_uri_get_home                 (void);
+char *         _g_uri_append_path              (const char      *uri,
+                                                const char      *path);
+
+/* Path utils */
+
+char **                _g_path_split_components        (const char      *path,
+                                                int             *size);
+char *         _g_path_join_components         (char           **comp_v);
+char *         _g_path_join                    (char            *first,
+                                                ...) G_GNUC_NULL_TERMINATED;
+const char *   _g_path_get_basename            (const char      *path);
+char *         _g_path_get_parent              (const char      *path);
+const char *   _g_path_get_extension           (const char      *path);
+char *         _g_path_remove_extension        (const char      *path);
+gboolean       _g_path_is_parent               (const char      *dir,
+                                                const char      *file);
+char *         _g_path_get_relative            (const char      *path,
+                                                const char      *base);
+
+G_END_DECLS
+
+#endif /* _URI_UTILS_H */


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