PropertyContext *mkdg_properties_find_by_key(MkdgProperties * properties,
                                             const gchar * key)
{
    gsize i;

    for (i = 0; i < mkdg_properties_size(properties); i++) {
        PropertyContext *ctx = mkdg_properties_index(properties, i);

        if (STRING_EQUALS(ctx->spec->key, key)) {
            return ctx;
        }
    }
    return NULL;
}
gboolean mkdg_g_value_is_equal(GValue * value1, GValue * value2)
{
    switch (G_VALUE_TYPE(value1)) {
    case G_TYPE_BOOLEAN:
	return (g_value_get_boolean(value1) ==
		g_value_get_boolean(value2));
    case G_TYPE_INT:
	return (g_value_get_int(value1) == g_value_get_int(value2));
    case G_TYPE_UINT:
	return (g_value_get_uint(value1) == g_value_get_uint(value2));
    case G_TYPE_STRING:
	return (STRING_EQUALS
		(g_value_get_string(value1), g_value_get_string(value2)));
    default:
	break;
    }
    return FALSE;
}
/* FIXME: Throw error */
static GdkPixbuf*
download_image(GtResourceDownloader* self,
    const gchar* uri, const gchar* name,
    SoupMessage* msg, GInputStream* istream,
    gboolean* from_file, GError** error)
{
    RETURN_VAL_IF_FAIL(GT_IS_RESOURCE_DOWNLOADER(self), NULL);
    RETURN_VAL_IF_FAIL(!utils_str_empty(uri), NULL);
    RETURN_VAL_IF_FAIL(SOUP_IS_MESSAGE(msg), NULL);
    RETURN_VAL_IF_FAIL(G_IS_INPUT_STREAM(istream), NULL);

    GtResourceDownloaderPrivate* priv = gt_resource_downloader_get_instance_private(self);
    g_autofree gchar* filename = NULL;
    gint64 file_timestamp = 0;
    gboolean file_exists = FALSE;
    g_autoptr(GdkPixbuf) ret = NULL;
    g_autoptr(GError) err = NULL;

        /* NOTE: If we aren't supplied a filename, we'll just create one by hashing the uri */
    if (utils_str_empty(name))
    {
        gchar hash_str[15];
        guint hash = 0;

        hash = g_str_hash(uri); /* TODO: Replace this with murmur3 hash */

        g_sprintf(hash_str, "%ud", hash);

        filename = g_build_filename(priv->filepath, hash_str, NULL);
    }
    else
        filename = g_build_filename(priv->filepath, name, NULL);

    if (priv->filepath && (file_exists = g_file_test(filename, G_FILE_TEST_EXISTS)))
    {
        file_timestamp = utils_timestamp_file(filename, NULL);
    }

    if (SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
    {
        const gchar* last_modified_str = NULL;

        DEBUG("Successful return code from uri '%s'", uri);

        last_modified_str = soup_message_headers_get_one(msg->response_headers, "Last-Modified");

        if (utils_str_empty(last_modified_str))
        {
            DEBUG("No 'Last-Modified' header in response from uri '%s'", uri);

            goto download;
        }
        else if (utils_http_full_date_to_timestamp(last_modified_str) < file_timestamp)
        {
            DEBUG("No new image at uri '%s'", uri);

            if (file_exists)
            {
                DEBUG("Loading image from file '%s'", filename);

                ret = gdk_pixbuf_new_from_file(filename, NULL);

                if (from_file) *from_file = TRUE;
            }
            else
            {
                DEBUG("Image doesn't exist locally");

                goto download;
            }
        }
        else
        {
        download:
            DEBUG("New image at uri '%s'", uri);

            ret = gdk_pixbuf_new_from_stream(istream, NULL, &err);

            if (err)
            {
                WARNING("Unable to download image from uri '%s' because: %s",
                    uri, err->message);

                g_propagate_prefixed_error(error, g_steal_pointer(&err),
                    "Unable to download image from uri '%s' because: ", uri);

                return NULL;
            }

            if (priv->filepath && STRING_EQUALS(priv->image_filetype, GT_IMAGE_FILETYPE_JPEG))
            {
                gdk_pixbuf_save(ret, filename, priv->image_filetype,
                    NULL, "quality", "100", NULL);
            }
            else if (priv->filepath)
            {
                gdk_pixbuf_save(ret, filename, priv->image_filetype,
                    NULL, NULL);
            }

            if (from_file) *from_file = FALSE;
        }
    }

    return g_steal_pointer(&ret);
}