[grilo-plugins] all: Merge GrlMediaSource and GrlMetadataSource into GrlSource



commit 29f02ba7eb1ac26a8a818d0bf2f5eea5a620139a
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Tue May 31 16:44:52 2011 +0000

    all: Merge GrlMediaSource and GrlMetadataSource into GrlSource

 src/media/apple-trailers/grl-apple-trailers.c      |   31 ++--
 src/media/apple-trailers/grl-apple-trailers.h      |    4 +-
 src/media/bliptv/grl-bliptv.c                      |   50 ++--
 src/media/bliptv/grl-bliptv.h                      |    4 +-
 src/media/bookmarks/grl-bookmarks.c                |  191 +++++++++-------
 src/media/bookmarks/grl-bookmarks.h                |    4 +-
 src/media/filesystem/grl-filesystem.c              |  147 ++++++------
 src/media/filesystem/grl-filesystem.h              |    4 +-
 src/media/flickr/grl-flickr.c                      |   81 ++++----
 src/media/flickr/grl-flickr.h                      |    4 +-
 src/media/jamendo/grl-jamendo.c                    |  178 ++++++---------
 src/media/jamendo/grl-jamendo.h                    |    4 +-
 src/media/optical-media/grl-optical-media.c        |   28 +--
 src/media/optical-media/grl-optical-media.h        |    4 +-
 src/media/podcasts/grl-podcasts.c                  |  239 +++++++++++---------
 src/media/podcasts/grl-podcasts.h                  |    4 +-
 src/media/shoutcast/grl-shoutcast.c                |   78 +++----
 src/media/shoutcast/grl-shoutcast.h                |    4 +-
 src/media/tracker/grl-tracker-media-api.c          |  226 +++++++++---------
 src/media/tracker/grl-tracker-media-api.h          |   24 +-
 src/media/tracker/grl-tracker-media-notif.c        |   21 +-
 src/media/tracker/grl-tracker-media.c              |   24 +-
 src/media/tracker/grl-tracker-media.h              |    4 +-
 src/media/tracker/grl-tracker-metadata.c           |   42 ++--
 src/media/tracker/grl-tracker-metadata.h           |    4 +-
 src/media/upnp/grl-upnp.c                          |  159 +++++++-------
 src/media/upnp/grl-upnp.h                          |    4 +-
 src/media/vimeo/grl-vimeo.c                        |   58 +++---
 src/media/vimeo/grl-vimeo.h                        |    4 +-
 src/media/youtube/grl-youtube.c                    |  177 +++++++--------
 src/media/youtube/grl-youtube.h                    |    4 +-
 src/metadata/fake-metadata/grl-fake-metadata.c     |   38 ++--
 src/metadata/fake-metadata/grl-fake-metadata.h     |    4 +-
 src/metadata/gravatar/grl-gravatar.c               |   24 +-
 src/metadata/gravatar/grl-gravatar.h               |    4 +-
 src/metadata/lastfm-albumart/grl-lastfm-albumart.c |   41 ++--
 src/metadata/lastfm-albumart/grl-lastfm-albumart.h |    4 +-
 src/metadata/local-metadata/grl-local-metadata.c   |   61 +++---
 src/metadata/local-metadata/grl-local-metadata.h   |    4 +-
 src/metadata/metadata-store/grl-metadata-store.c   |   71 +++---
 src/metadata/metadata-store/grl-metadata-store.h   |    4 +-
 test/main.c                                        |  216 +++++++++----------
 test/test_local_metadata.c                         |   14 +-
 43 files changed, 1132 insertions(+), 1163 deletions(-)
---
diff --git a/src/media/apple-trailers/grl-apple-trailers.c b/src/media/apple-trailers/grl-apple-trailers.c
index 801ba4f..facd0f6 100644
--- a/src/media/apple-trailers/grl-apple-trailers.c
+++ b/src/media/apple-trailers/grl-apple-trailers.c
@@ -55,7 +55,7 @@ GRL_LOG_DOMAIN_STATIC(apple_trailers_log_domain);
 #define SOURCE_DESC "A plugin for browsing Apple Movie Trailers"
 
 typedef struct {
-  GrlMediaSourceBrowseSpec *bs;
+  GrlSourceBrowseSpec *bs;
   xmlDocPtr xml_doc;
   xmlNodePtr xml_entries;
   gboolean cancelled;
@@ -88,8 +88,8 @@ gboolean grl_apple_trailers_plugin_init (GrlPluginRegistry *registry,
 
 static const GList *grl_apple_trailers_source_supported_keys (GrlSource *source);
 
-static void grl_apple_trailers_source_browse (GrlMediaSource *source,
-                                              GrlMediaSourceBrowseSpec *bs);
+static void grl_apple_trailers_source_browse (GrlSource *source,
+                                              GrlSourceBrowseSpec *bs);
 
 static void grl_apple_trailers_source_cancel (GrlSource *source,
                                               guint operation_id);
@@ -172,7 +172,7 @@ grl_apple_trailers_source_new (gboolean high_definition,
   return source;
 }
 
-G_DEFINE_TYPE (GrlAppleTrailersSource, grl_apple_trailers_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlAppleTrailersSource, grl_apple_trailers_source, GRL_TYPE_SOURCE);
 
 static void
 grl_apple_trailers_source_finalize (GObject *object)
@@ -215,20 +215,17 @@ grl_apple_trailers_source_set_property (GObject *object,
 static void
 grl_apple_trailers_source_class_init (GrlAppleTrailersSourceClass * klass)
 {
-  GObjectClass *g_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
+  GObjectClass *g_class = G_OBJECT_CLASS (klass);
 
   g_class->finalize = grl_apple_trailers_source_finalize;
   g_class->set_property = grl_apple_trailers_source_set_property;
 
   source_class->cancel = grl_apple_trailers_source_cancel;
   source_class->supported_keys = grl_apple_trailers_source_supported_keys;
+  source_class->browse = grl_apple_trailers_source_browse;
   source_class->get_caps = grl_apple_trailers_source_get_caps;
 
-  media_class->browse = grl_apple_trailers_source_browse;
-
-
   g_object_class_install_property (g_class,
                                    PROP_HD,
                                    g_param_spec_boolean ("high-definition",
@@ -403,7 +400,7 @@ send_movie_info (OperationData *op_data)
 
   if (op_data->cancelled) {
     op_data->bs->callback (op_data->bs->source,
-                           op_data->bs->browse_id,
+                           op_data->bs->operation_id,
                            NULL,
                            0,
                            op_data->bs->user_data,
@@ -420,7 +417,7 @@ send_movie_info (OperationData *op_data)
       !op_data->xml_entries->next || count == 1;
 
     op_data->bs->callback (op_data->bs->source,
-                           op_data->bs->browse_id,
+                           op_data->bs->operation_id,
                            media,
                            last? 0: -1,
                            op_data->bs->user_data,
@@ -487,7 +484,7 @@ xml_parse_result (const gchar *str, OperationData *op_data)
 
  finalize:
   op_data->bs->callback (op_data->bs->source,
-                         op_data->bs->browse_id,
+                         op_data->bs->operation_id,
                          NULL,
                          0,
                          op_data->bs->user_data,
@@ -524,7 +521,7 @@ read_done_cb (GObject *source_object,
                          "Failed to connect Apple Trailers: '%s'",
                          wc_error->message);
     op_data->bs->callback (op_data->bs->source,
-                           op_data->bs->browse_id,
+                           op_data->bs->operation_id,
                            NULL,
                            0,
                            op_data->bs->user_data,
@@ -582,17 +579,17 @@ grl_apple_trailers_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_apple_trailers_source_browse (GrlMediaSource *source,
-                                  GrlMediaSourceBrowseSpec *bs)
+grl_apple_trailers_source_browse (GrlSource *source,
+                                  GrlSourceBrowseSpec *bs)
 {
   GrlAppleTrailersSource *at_source = GRL_APPLE_TRAILERS_SOURCE (source);
   OperationData *op_data;
 
-  GRL_DEBUG ("grl_apple_trailers_source_browse");
+  GRL_DEBUG (__FUNCTION__);
 
   op_data = g_slice_new0 (OperationData);
   op_data->bs = bs;
-  grl_operation_set_data (bs->browse_id, op_data);
+  grl_operation_set_data (bs->operation_id, op_data);
 
   if (at_source->priv->hd) {
     read_url_async (at_source, APPLE_TRAILERS_CURRENT_HD, op_data);
diff --git a/src/media/apple-trailers/grl-apple-trailers.h b/src/media/apple-trailers/grl-apple-trailers.h
index 74f8f9a..874d648 100644
--- a/src/media/apple-trailers/grl-apple-trailers.h
+++ b/src/media/apple-trailers/grl-apple-trailers.h
@@ -58,7 +58,7 @@ typedef struct _GrlAppleTrailersSourcePriv GrlAppleTrailersSourcePriv;
 
 struct _GrlAppleTrailersSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlAppleTrailersSourcePriv *priv;
@@ -69,7 +69,7 @@ typedef struct _GrlAppleTrailersSourceClass GrlAppleTrailersSourceClass;
 
 struct _GrlAppleTrailersSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/bliptv/grl-bliptv.c b/src/media/bliptv/grl-bliptv.c
index 2068c19..fb59d09 100644
--- a/src/media/bliptv/grl-bliptv.c
+++ b/src/media/bliptv/grl-bliptv.c
@@ -48,7 +48,7 @@ GRL_LOG_DOMAIN_STATIC(bliptv_log_domain);
 #define SOURCE_DESC "A source for browsing and searching Blip.tv videos"
 
 
-G_DEFINE_TYPE (GrlBliptvSource, grl_bliptv_source, GRL_TYPE_MEDIA_SOURCE)
+G_DEFINE_TYPE (GrlBliptvSource, grl_bliptv_source, GRL_TYPE_SOURCE)
 
 #define BLIPTV_SOURCE_PRIVATE(o)                                        \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o),                                    \
@@ -62,12 +62,12 @@ struct _GrlBliptvSourcePrivate
 
 typedef struct
 {
-  GrlMediaSource *source;
-  guint           operation_id;
-  guint           count;
+  GrlSource *source;
+  guint      operation_id;
+  guint      count;
 
-  GrlMediaSourceResultCb callback;
-  gpointer               user_data;
+  GrlSourceResultCb callback;
+  gpointer          user_data;
 
   RestProxy     *proxy;
   RestProxyCall *call;
@@ -96,11 +96,11 @@ static const GList *grl_bliptv_source_supported_keys (GrlSource *source);
 static GrlCaps * grl_bliptv_source_get_caps (GrlSource *source,
                                              GrlSupportedOps operation);
 
-static void grl_bliptv_source_browse (GrlMediaSource *source,
-                                      GrlMediaSourceBrowseSpec *bs);
+static void grl_bliptv_source_browse (GrlSource *source,
+                                      GrlSourceBrowseSpec *bs);
 
-static void grl_bliptv_source_search (GrlMediaSource *source,
-                                      GrlMediaSourceSearchSpec *ss);
+static void grl_bliptv_source_search (GrlSource *source,
+                                      GrlSourceSearchSpec *ss);
 
 static void grl_bliptv_source_cancel (GrlSource *source,
                                       guint operation_id);
@@ -158,7 +158,6 @@ grl_bliptv_source_class_init (GrlBliptvSourceClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   g_type_class_add_private (klass, sizeof (GrlBliptvSourcePrivate));
 
@@ -168,9 +167,8 @@ grl_bliptv_source_class_init (GrlBliptvSourceClass *klass)
   source_class->supported_keys = grl_bliptv_source_supported_keys;
   source_class->get_caps = grl_bliptv_source_get_caps;
   source_class->cancel = grl_bliptv_source_cancel;
-
-  media_class->browse = grl_bliptv_source_browse;
-  media_class->search = grl_bliptv_source_search;
+  source_class->browse = grl_bliptv_source_browse;
+  source_class->search = grl_bliptv_source_search;
 }
 
 static void
@@ -387,8 +385,8 @@ grl_bliptv_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_bliptv_source_browse (GrlMediaSource *source,
-                          GrlMediaSourceBrowseSpec *bs)
+grl_bliptv_source_browse (GrlSource *source,
+                          GrlSourceBrowseSpec *bs)
 {
   BliptvOperation *op = g_slice_new0 (BliptvOperation);
   GError *error = NULL;
@@ -397,11 +395,11 @@ grl_bliptv_source_browse (GrlMediaSource *source,
 
   op->source       = g_object_ref (source);
   op->count        = count;
-  op->operation_id = bs->browse_id;
+  op->operation_id = bs->operation_id;
   op->callback     = bs->callback;
   op->user_data    = bs->user_data;
 
-  grl_operation_set_data (bs->browse_id, op);
+  grl_operation_set_data (bs->operation_id, op);
 
   op->proxy = rest_proxy_new ("http://blip.tv/posts/";, FALSE);
   op->call = rest_proxy_new_call (op->proxy);
@@ -410,7 +408,7 @@ grl_bliptv_source_browse (GrlMediaSource *source,
   rest_proxy_call_add_param (op->call, "pagelen", length);
   g_free (length);
 
-  GRL_DEBUG ("Starting browse request for id=%u", bs->browse_id);
+  GRL_DEBUG ("Starting browse request for id=%u", bs->operation_id);
 
   if (!rest_proxy_call_async (op->call,
                               proxy_call_raw_async_cb,
@@ -423,14 +421,14 @@ grl_bliptv_source_browse (GrlMediaSource *source,
           GRL_WARNING ("Could not start search request : %s", error->message);
           g_error_free (error);
         }
-      bs->callback (source, bs->browse_id, NULL, 0, bs->user_data, NULL);
+      bs->callback (source, bs->operation_id, NULL, 0, bs->user_data, NULL);
       bliptv_operation_free (op);
     }
 }
 
 static void
-grl_bliptv_source_search (GrlMediaSource *source,
-                          GrlMediaSourceSearchSpec *ss)
+grl_bliptv_source_search (GrlSource *source,
+                          GrlSourceSearchSpec *ss)
 {
   BliptvOperation *op = g_slice_new0 (BliptvOperation);
   GError *error = NULL;
@@ -440,11 +438,11 @@ grl_bliptv_source_search (GrlMediaSource *source,
 
   op->source       = g_object_ref (source);
   op->count        = count;
-  op->operation_id = ss->search_id;
+  op->operation_id = ss->operation_id;
   op->callback     = ss->callback;
   op->user_data    = ss->user_data;
 
-  grl_operation_set_data (ss->search_id, op);
+  grl_operation_set_data (ss->operation_id, op);
 
   op->proxy = rest_proxy_new ("http://blip.tv/posts/";, FALSE);
   op->call = rest_proxy_new_call (op->proxy);
@@ -455,7 +453,7 @@ grl_bliptv_source_search (GrlMediaSource *source,
   g_free (length);
 
   GRL_DEBUG ("Starting search request for id=%u : '%s'",
-             ss->search_id, ss->text);
+             ss->operation_id, ss->text);
 
   if (!rest_proxy_call_async (op->call,
                               proxy_call_raw_async_cb,
@@ -472,7 +470,7 @@ grl_bliptv_source_search (GrlMediaSource *source,
                                GRL_CORE_ERROR_SEARCH_FAILED,
                                "Unable to search '%s'",
                                ss->text? ss->text: "");
-      ss->callback (source, ss->search_id, NULL, 0, ss->user_data, grl_error);
+      ss->callback (source, ss->operation_id, NULL, 0, ss->user_data, grl_error);
       g_error_free (grl_error);
       bliptv_operation_free (op);
     }
diff --git a/src/media/bliptv/grl-bliptv.h b/src/media/bliptv/grl-bliptv.h
index 44b8c77..f98c844 100644
--- a/src/media/bliptv/grl-bliptv.h
+++ b/src/media/bliptv/grl-bliptv.h
@@ -61,7 +61,7 @@ typedef struct _GrlBliptvSourcePrivate GrlBliptvSourcePrivate;
 
 struct _GrlBliptvSource
 {
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlBliptvSourcePrivate *priv;
@@ -69,7 +69,7 @@ struct _GrlBliptvSource
 
 struct _GrlBliptvSourceClass
 {
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 };
 
 GType grl_bliptv_source_get_type (void) G_GNUC_CONST;
diff --git a/src/media/bookmarks/grl-bookmarks.c b/src/media/bookmarks/grl-bookmarks.c
index d2ee176..e1f954d 100644
--- a/src/media/bookmarks/grl-bookmarks.c
+++ b/src/media/bookmarks/grl-bookmarks.c
@@ -143,12 +143,12 @@ struct _GrlBookmarksPrivate {
 };
 
 typedef struct {
-  GrlMediaSource *source;
+  GrlSource *source;
   guint operation_id;
   const gchar *media_id;
   guint skip;
   guint count;
-  GrlMediaSourceResultCb callback;
+  GrlSourceResultCb callback;
   guint error_code;
   gboolean is_query;
   gpointer user_data;
@@ -159,25 +159,25 @@ static GrlBookmarksSource *grl_bookmarks_source_new (void);
 static void grl_bookmarks_source_finalize (GObject *plugin);
 
 static const GList *grl_bookmarks_source_supported_keys (GrlSource *source);
-static GrlSupportedOps grl_bookmarks_source_supported_operations (GrlSource *metadata_source);
-
-static void grl_bookmarks_source_search (GrlMediaSource *source,
-					 GrlMediaSourceSearchSpec *ss);
-static void grl_bookmarks_source_query (GrlMediaSource *source,
-					GrlMediaSourceQuerySpec *qs);
-static void grl_bookmarks_source_browse (GrlMediaSource *source,
-                                        GrlMediaSourceBrowseSpec *bs);
-static void grl_bookmarks_source_metadata (GrlMediaSource *source,
-					   GrlMediaSourceMetadataSpec *ms);
-static void grl_bookmarks_source_store (GrlMediaSource *source,
-                                       GrlMediaSourceStoreSpec *ss);
-static void grl_bookmarks_source_remove (GrlMediaSource *source,
-					 GrlMediaSourceRemoveSpec *rs);
-
-static gboolean grl_bookmarks_source_notify_change_start (GrlMediaSource *source,
+static GrlSupportedOps grl_bookmarks_source_supported_operations (GrlSource *source);
+
+static void grl_bookmarks_source_search (GrlSource *source,
+                                         GrlSourceSearchSpec *ss);
+static void grl_bookmarks_source_query (GrlSource *source,
+                                        GrlSourceQuerySpec *qs);
+static void grl_bookmarks_source_browse (GrlSource *source,
+                                         GrlSourceBrowseSpec *bs);
+static void grl_bookmarks_source_resolve (GrlSource *source,
+                                          GrlSourceResolveSpec *rs);
+static void grl_bookmarks_source_store (GrlSource *source,
+                                        GrlSourceStoreSpec *ss);
+static void grl_bookmarks_source_remove (GrlSource *source,
+                                         GrlSourceRemoveSpec *rs);
+
+static gboolean grl_bookmarks_source_notify_change_start (GrlSource *source,
                                                           GError **error);
 
-static gboolean grl_bookmarks_source_notify_change_stop (GrlMediaSource *source,
+static gboolean grl_bookmarks_source_notify_change_stop (GrlSource *source,
                                                          GError **error);
 
 static GrlCaps * grl_bookmarks_source_get_caps (GrlSource *source,
@@ -244,22 +244,20 @@ static GrlCaps * grl_bookmarks_source_get_caps (GrlSource *source,
  {
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
    GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-   GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
    gobject_class->finalize = grl_bookmarks_source_finalize;
 
    source_class->supported_operations = grl_bookmarks_source_supported_operations;
    source_class->supported_keys = grl_bookmarks_source_supported_keys;
    source_class->get_caps = grl_bookmarks_source_get_caps;
-
-   media_class->browse = grl_bookmarks_source_browse;
-   media_class->search = grl_bookmarks_source_search;
-   media_class->query = grl_bookmarks_source_query;
-   media_class->store = grl_bookmarks_source_store;
-   media_class->remove = grl_bookmarks_source_remove;
-   media_class->metadata = grl_bookmarks_source_metadata;
-   media_class->notify_change_start = grl_bookmarks_source_notify_change_start;
-   media_class->notify_change_stop = grl_bookmarks_source_notify_change_stop;
+   source_class->browse = grl_bookmarks_source_browse;
+   source_class->search = grl_bookmarks_source_search;
+   source_class->query = grl_bookmarks_source_query;
+   source_class->store = grl_bookmarks_source_store;
+   source_class->remove = grl_bookmarks_source_remove;
+   source_class->resolve = grl_bookmarks_source_resolve;
+   source_class->notify_change_start = grl_bookmarks_source_notify_change_start;
+   source_class->notify_change_stop = grl_bookmarks_source_notify_change_stop;
 
    g_type_class_add_private (klass, sizeof (GrlBookmarksPrivate));
 }
@@ -314,7 +312,7 @@ grl_bookmarks_source_init (GrlBookmarksSource *source)
   GRL_DEBUG ("  OK");
 }
 
-G_DEFINE_TYPE (GrlBookmarksSource, grl_bookmarks_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlBookmarksSource, grl_bookmarks_source, GRL_TYPE_SOURCE);
 
 static void
 grl_bookmarks_source_finalize (GObject *object)
@@ -409,7 +407,7 @@ build_media_from_stmt (GrlMedia *content, sqlite3_stmt *sql_stmt)
 }
 
 static void
-bookmark_metadata (GrlMediaSourceMetadataSpec *ms)
+bookmark_resolve (GrlSourceResolveSpec *rs)
 {
   gint r;
   sqlite3_stmt *sql_stmt = NULL;
@@ -417,16 +415,16 @@ bookmark_metadata (GrlMediaSourceMetadataSpec *ms)
   GError *error = NULL;
   gchar *sql;
   const gchar *id;
-  
-  GRL_DEBUG ("bookmark_metadata");
 
-  db = GRL_BOOKMARKS_SOURCE (ms->source)->priv->db;
+  GRL_DEBUG (__FUNCTION__);
+
+  db = GRL_BOOKMARKS_SOURCE (rs->source)->priv->db;
 
-  id = grl_media_get_id (ms->media);
+  id = grl_media_get_id (rs->media);
   if (!id) {
     /* Root category: special case */
-    grl_media_set_title (ms->media, GRL_ROOT_TITLE);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    grl_media_set_title (rs->media, GRL_ROOT_TITLE);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
     return;
   }
 
@@ -438,9 +436,9 @@ bookmark_metadata (GrlMediaSourceMetadataSpec *ms)
   if (r != SQLITE_OK) {
     GRL_WARNING ("Failed to get bookmark: %s", sqlite3_errmsg (db));
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "Failed to get bookmark metadata");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "Failed to get bookmark metadata");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -448,14 +446,14 @@ bookmark_metadata (GrlMediaSourceMetadataSpec *ms)
   while ((r = sqlite3_step (sql_stmt)) == SQLITE_BUSY);
 
   if (r == SQLITE_ROW) {
-    build_media_from_stmt (ms->media, sql_stmt);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    build_media_from_stmt (rs->media, sql_stmt);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
     GRL_WARNING ("Failed to get bookmark: %s", sqlite3_errmsg (db));
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "Failed to get bookmark metadata");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "Failed to get bookmark metadata");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 
@@ -601,18 +599,19 @@ remove_bookmark (GrlBookmarksSource *bookmarks_source,
   if (bookmarks_source->priv->notify_changes) {
     /* We can improve accuracy computing the parent container of removed
        element */
-    grl_media_source_notify_change (GRL_MEDIA_SOURCE (bookmarks_source),
-                                    NULL,
-                                    GRL_CONTENT_REMOVED,
-                                    TRUE);
+    grl_source_notify_change (GRL_SOURCE (bookmarks_source),
+                              NULL,
+                              GRL_CONTENT_REMOVED,
+                              TRUE);
   }
 }
 
 static void
 store_bookmark (GrlBookmarksSource *bookmarks_source,
-		GrlMediaBox *parent,
-		GrlMedia *bookmark,
-		GError **error)
+                GList **keylist,
+                GrlMediaBox *parent,
+                GrlMedia *bookmark,
+                GError **error)
 {
   gint r;
   sqlite3_stmt *sql_stmt = NULL;
@@ -670,10 +669,20 @@ store_bookmark (GrlBookmarksSource *bookmarks_source,
   sqlite3_bind_int (sql_stmt, BOOKMARK_TYPE, type);
   if (type == BOOKMARK_TYPE_STREAM) {
     sqlite3_bind_text (sql_stmt, BOOKMARK_URL, url, -1, SQLITE_STATIC);
+    *keylist = g_list_remove (*keylist,
+                              GRLKEYID_TO_POINTER (GRL_METADATA_KEY_URL));
   } else {
     sqlite3_bind_null (sql_stmt, BOOKMARK_URL);
   }
-  sqlite3_bind_text (sql_stmt, BOOKMARK_TITLE, title, -1, SQLITE_STATIC);
+  if (title) {
+    sqlite3_bind_text (sql_stmt, BOOKMARK_TITLE, title, -1, SQLITE_STATIC);
+    *keylist = g_list_remove (*keylist,
+                              GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE));
+  } else if (url) {
+    sqlite3_bind_text (sql_stmt, BOOKMARK_TITLE, url, -1, SQLITE_STATIC);
+  } else {
+    sqlite3_bind_text (sql_stmt, BOOKMARK_TITLE, "(unknown)", -1, SQLITE_STATIC);
+  }
   if (date) {
     sqlite3_bind_text (sql_stmt, BOOKMARK_DATE, date, -1, SQLITE_STATIC);
   } else {
@@ -681,11 +690,15 @@ store_bookmark (GrlBookmarksSource *bookmarks_source,
   }
   if (mime) {
     sqlite3_bind_text (sql_stmt, BOOKMARK_MIME, mime, -1, SQLITE_STATIC);
+    *keylist = g_list_remove (*keylist,
+                              GRLKEYID_TO_POINTER (GRL_METADATA_KEY_MIME));
   } else {
     sqlite3_bind_null (sql_stmt, BOOKMARK_MIME);
   }
   if (desc) {
     sqlite3_bind_text (sql_stmt, BOOKMARK_DESC, desc, -1, SQLITE_STATIC);
+    *keylist = g_list_remove (*keylist,
+                              GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DESCRIPTION));
   } else {
     sqlite3_bind_null (sql_stmt, BOOKMARK_DESC);
   }
@@ -710,10 +723,10 @@ store_bookmark (GrlBookmarksSource *bookmarks_source,
   g_free (id);
 
   if (bookmarks_source->priv->notify_changes) {
-    grl_media_source_notify_change (GRL_MEDIA_SOURCE (bookmarks_source),
-                                    GRL_MEDIA (parent),
-                                    GRL_CONTENT_ADDED,
-                                    FALSE);
+    grl_source_notify_change (GRL_SOURCE (bookmarks_source),
+                              GRL_MEDIA (parent),
+                              GRL_CONTENT_ADDED,
+                              FALSE);
   }
 }
 
@@ -736,8 +749,8 @@ grl_bookmarks_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_bookmarks_source_browse (GrlMediaSource *source,
-                            GrlMediaSourceBrowseSpec *bs)
+grl_bookmarks_source_browse (GrlSource *source,
+                             GrlSourceBrowseSpec *bs)
 {
   GRL_DEBUG ("grl_bookmarks_source_browse");
 
@@ -751,14 +764,14 @@ grl_bookmarks_source_browse (GrlMediaSource *source,
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_BROWSE_FAILED,
 			 "No database connection");
-    bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, error);
+    bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, error);
     g_error_free (error);
   }
 
   /* Configure browse operation */
   os = g_slice_new0 (OperationSpec);
   os->source = bs->source;
-  os->operation_id = bs->browse_id;
+  os->operation_id = bs->operation_id;
   os->media_id = grl_media_get_id (bs->container);
   os->count = grl_operation_options_get_count (bs->options);
   os->skip = grl_operation_options_get_skip (bs->options);
@@ -771,8 +784,8 @@ grl_bookmarks_source_browse (GrlMediaSource *source,
 }
 
 static void
-grl_bookmarks_source_search (GrlMediaSource *source,
-			     GrlMediaSourceSearchSpec *ss)
+grl_bookmarks_source_search (GrlSource *source,
+                             GrlSourceSearchSpec *ss)
 {
   GRL_DEBUG ("grl_bookmarks_source_search");
 
@@ -786,13 +799,13 @@ grl_bookmarks_source_search (GrlMediaSource *source,
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_QUERY_FAILED,
 			 "No database connection");
-    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, error);
+    ss->callback (ss->source, ss->operation_id, NULL, 0, ss->user_data, error);
     g_error_free (error);
   }
 
   os = g_slice_new0 (OperationSpec);
   os->source = ss->source;
-  os->operation_id = ss->search_id;
+  os->operation_id = ss->operation_id;
   os->count = grl_operation_options_get_count (ss->options);
   os->skip = grl_operation_options_get_skip (ss->options);
   os->callback = ss->callback;
@@ -803,8 +816,8 @@ grl_bookmarks_source_search (GrlMediaSource *source,
 }
 
 static void
-grl_bookmarks_source_query (GrlMediaSource *source,
-			    GrlMediaSourceQuerySpec *qs)
+grl_bookmarks_source_query (GrlSource *source,
+                            GrlSourceQuerySpec *qs)
 {
   GRL_DEBUG ("grl_bookmarks_source_query");
 
@@ -818,13 +831,13 @@ grl_bookmarks_source_query (GrlMediaSource *source,
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_QUERY_FAILED,
 			 "No database connection");
-    qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
+    qs->callback (qs->source, qs->operation_id, NULL, 0, qs->user_data, error);
     g_error_free (error);
   }
 
   os = g_slice_new0 (OperationSpec);
   os->source = qs->source;
-  os->operation_id = qs->query_id;
+  os->operation_id = qs->operation_id;
   os->count = grl_operation_options_get_count (qs->options);
   os->skip = grl_operation_options_get_skip (qs->options);
   os->callback = qs->callback;
@@ -835,23 +848,27 @@ grl_bookmarks_source_query (GrlMediaSource *source,
 }
 
 static void
-grl_bookmarks_source_store (GrlMediaSource *source, GrlMediaSourceStoreSpec *ss)
+grl_bookmarks_source_store (GrlSource *source, GrlSourceStoreSpec *ss)
 {
+  GError *error = NULL;
+  GList *keylist;
+
   GRL_DEBUG ("grl_bookmarks_source_store");
+
   /* FIXME: Try to guess bookmark mime somehow */
-  GError *error = NULL;
+  keylist = grl_data_get_keys (GRL_DATA (ss->media));
   store_bookmark (GRL_BOOKMARKS_SOURCE (ss->source),
-		  ss->parent, ss->media, &error);
-  ss->callback (ss->source, ss->parent, ss->media, ss->user_data, error);
+                  &keylist, ss->parent, ss->media, &error);
+  ss->callback (ss->source, ss->media, keylist, ss->user_data, error);
   if (error) {
     g_error_free (error);
   }
 }
 
-static void grl_bookmarks_source_remove (GrlMediaSource *source,
-					 GrlMediaSourceRemoveSpec *rs)
+static void grl_bookmarks_source_remove (GrlSource *source,
+                                         GrlSourceRemoveSpec *rs)
 {
-  GRL_DEBUG ("grl_bookmarks_source_remove");
+  GRL_DEBUG (__FUNCTION__);
   GError *error = NULL;
   remove_bookmark (GRL_BOOKMARKS_SOURCE (rs->source),
 		   rs->media_id, &error);
@@ -862,10 +879,10 @@ static void grl_bookmarks_source_remove (GrlMediaSource *source,
 }
 
 static void
-grl_bookmarks_source_metadata (GrlMediaSource *source,
-			       GrlMediaSourceMetadataSpec *ms)
+grl_bookmarks_source_resolve (GrlSource *source,
+                              GrlSourceResolveSpec *rs)
 {
-  GRL_DEBUG ("grl_bookmarks_source_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
   GrlBookmarksSource *bookmarks_source;
   GError *error = NULL;
@@ -874,28 +891,28 @@ grl_bookmarks_source_metadata (GrlMediaSource *source,
   if (!bookmarks_source->priv->db) {
     GRL_WARNING ("Can't execute operation: no database connection.");
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "No database connection");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "No database connection");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 
-  bookmark_metadata (ms);
+  bookmark_resolve (rs);
 }
 
 static GrlSupportedOps
-grl_bookmarks_source_supported_operations (GrlSource *metadata_source)
+grl_bookmarks_source_supported_operations (GrlSource *source)
 {
   GrlSupportedOps caps;
 
-  caps = GRL_OP_BROWSE | GRL_OP_METADATA | GRL_OP_SEARCH | GRL_OP_QUERY |
+  caps = GRL_OP_BROWSE | GRL_OP_RESOLVE | GRL_OP_SEARCH | GRL_OP_QUERY |
     GRL_OP_STORE | GRL_OP_STORE_PARENT | GRL_OP_REMOVE | GRL_OP_NOTIFY_CHANGE;
 
   return caps;
 }
 
 static gboolean
-grl_bookmarks_source_notify_change_start (GrlMediaSource *source,
+grl_bookmarks_source_notify_change_start (GrlSource *source,
                                           GError **error)
 {
   GrlBookmarksSource *bookmarks_source = GRL_BOOKMARKS_SOURCE (source);
@@ -906,7 +923,7 @@ grl_bookmarks_source_notify_change_start (GrlMediaSource *source,
 }
 
 static gboolean
-grl_bookmarks_source_notify_change_stop (GrlMediaSource *source,
+grl_bookmarks_source_notify_change_stop (GrlSource *source,
                                          GError **error)
 {
   GrlBookmarksSource *bookmarks_source = GRL_BOOKMARKS_SOURCE (source);
diff --git a/src/media/bookmarks/grl-bookmarks.h b/src/media/bookmarks/grl-bookmarks.h
index b5529b1..c743d77 100644
--- a/src/media/bookmarks/grl-bookmarks.h
+++ b/src/media/bookmarks/grl-bookmarks.h
@@ -56,7 +56,7 @@ typedef struct _GrlBookmarksSource  GrlBookmarksSource;
 
 struct _GrlBookmarksSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlBookmarksPrivate *priv;
@@ -66,7 +66,7 @@ typedef struct _GrlBookmarksSourceClass GrlBookmarksSourceClass;
 
 struct _GrlBookmarksSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/filesystem/grl-filesystem.c b/src/media/filesystem/grl-filesystem.c
index eaa4201..7c69ca1 100644
--- a/src/media/filesystem/grl-filesystem.c
+++ b/src/media/filesystem/grl-filesystem.c
@@ -88,7 +88,7 @@ typedef gboolean (*RecursiveOperationCb) (GFileInfo *file_info,
                                           RecursiveOperation *operation);
 
 typedef struct {
-  GrlMediaSourceBrowseSpec *spec;
+  GrlSourceBrowseSpec *spec;
   GList *entries;
   GList *current;
   const gchar *path;
@@ -127,30 +127,28 @@ static const GList *grl_filesystem_source_supported_keys (GrlSource *source);
 
 static GrlCaps *grl_filesystem_source_get_caps (GrlSource *source,
                                                 GrlSupportedOps operation);
+static void grl_filesystem_source_resolve (GrlSource *source,
+                                           GrlSourceResolveSpec *rs);
 
-static void grl_filesystem_source_metadata (GrlMediaSource *source,
-                                            GrlMediaSourceMetadataSpec *ms);
+static void grl_filesystem_source_browse (GrlSource *source,
+                                          GrlSourceBrowseSpec *bs);
 
-static void grl_filesystem_source_browse (GrlMediaSource *source,
-                                          GrlMediaSourceBrowseSpec *bs);
+static void grl_filesystem_source_search (GrlSource *source,
+                                          GrlSourceSearchSpec *ss);
 
-static void grl_filesystem_source_search (GrlMediaSource *source,
-                                          GrlMediaSourceSearchSpec *ss);
-
-
-static gboolean grl_filesystem_test_media_from_uri (GrlMediaSource *source,
+static gboolean grl_filesystem_test_media_from_uri (GrlSource *source,
                                                     const gchar *uri);
 
-static void grl_filesystem_get_media_from_uri (GrlMediaSource *source,
-                                               GrlMediaSourceMediaFromUriSpec *mfus);
+static void grl_filesystem_get_media_from_uri (GrlSource *source,
+                                               GrlSourceMediaFromUriSpec *mfus);
 
 static void grl_filesystem_source_cancel (GrlSource *source,
                                           guint operation_id);
 
-static gboolean grl_filesystem_source_notify_change_start (GrlMediaSource *source,
+static gboolean grl_filesystem_source_notify_change_start (GrlSource *source,
                                                            GError **error);
 
-static gboolean grl_filesystem_source_notify_change_stop (GrlMediaSource *source,
+static gboolean grl_filesystem_source_notify_change_stop (GrlSource *source,
                                                           GError **error);
 
 /* =================== Filesystem Plugin  =============== */
@@ -201,7 +199,7 @@ GRL_PLUGIN_REGISTER (grl_filesystem_plugin_init,
 
 G_DEFINE_TYPE (GrlFilesystemSource,
                grl_filesystem_source,
-               GRL_TYPE_MEDIA_SOURCE);
+               GRL_TYPE_SOURCE);
 
 static GrlFilesystemSource *
 grl_filesystem_source_new (void)
@@ -219,21 +217,19 @@ grl_filesystem_source_class_init (GrlFilesystemSourceClass * klass)
 {
   GObjectClass *g_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   g_class->finalize = grl_filesystem_source_finalize;
 
   source_class->supported_keys = grl_filesystem_source_supported_keys;
   source_class->cancel = grl_filesystem_source_cancel;
   source_class->get_caps = grl_filesystem_source_get_caps;
-
-  media_class->browse = grl_filesystem_source_browse;
-  media_class->search = grl_filesystem_source_search;
-  media_class->notify_change_start = grl_filesystem_source_notify_change_start;
-  media_class->notify_change_stop = grl_filesystem_source_notify_change_stop;
-  media_class->metadata = grl_filesystem_source_metadata;
-  media_class->test_media_from_uri = grl_filesystem_test_media_from_uri;
-  media_class->media_from_uri = grl_filesystem_get_media_from_uri;
+  source_class->browse = grl_filesystem_source_browse;
+  source_class->search = grl_filesystem_source_search;
+  source_class->notify_change_start = grl_filesystem_source_notify_change_start;
+  source_class->notify_change_stop = grl_filesystem_source_notify_change_stop;
+  source_class->resolve = grl_filesystem_source_resolve;
+  source_class->test_media_from_uri = grl_filesystem_test_media_from_uri;
+  source_class->media_from_uri = grl_filesystem_get_media_from_uri;
 
   g_type_class_add_private (klass, sizeof (GrlFilesystemSourcePrivate));
 }
@@ -450,7 +446,6 @@ set_container_childcount (const gchar *path,
   }
 
   /* Count valid entries */
-
   count = 0;
   while ((entry_name = g_dir_read_name (dir)) != NULL) {
     gchar *entry_path;
@@ -634,7 +629,7 @@ browse_emit_idle (gpointer user_data)
     g_free (idle_data->current->data);
 
     idle_data->spec->callback (idle_data->spec->source,
-			       idle_data->spec->browse_id,
+			       idle_data->spec->operation_id,
 			       content,
 			       idle_data->remaining--,
 			       idle_data->spec->user_data,
@@ -659,7 +654,7 @@ finish:
 }
 
 static void
-produce_from_path (GrlMediaSourceBrowseSpec *bs, const gchar *path, GrlOperationOptions *options)
+produce_from_path (GrlSourceBrowseSpec *bs, const gchar *path, GrlOperationOptions *options)
 {
   GDir *dir;
   GError *error = NULL;
@@ -673,7 +668,7 @@ produce_from_path (GrlMediaSourceBrowseSpec *bs, const gchar *path, GrlOperation
   dir = g_dir_open (path, 0, &error);
   if (error) {
     GRL_DEBUG ("Failed to open directory '%s': %s", path, error->message);
-    bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, error);
+    bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -728,16 +723,16 @@ produce_from_path (GrlMediaSourceBrowseSpec *bs, const gchar *path, GrlOperation
     idle_data->entries = entries;
     idle_data->current = entries;
     idle_data->cancellable = g_cancellable_new ();
-    idle_data->id = bs->browse_id;
+    idle_data->id = bs->operation_id;
     g_hash_table_insert (GRL_FILESYSTEM_SOURCE (bs->source)->priv->cancellables,
-                         GUINT_TO_POINTER (bs->browse_id),
+                         GUINT_TO_POINTER (bs->operation_id),
                          idle_data->cancellable);
 
     g_idle_add (browse_emit_idle, idle_data);
   } else {
     /* No results */
     bs->callback (bs->source,
-		  bs->browse_id,
+		  bs->operation_id,
 		  NULL,
 		  0,
 		  bs->user_data,
@@ -972,12 +967,12 @@ cancel_cb (GFileInfo *file_info, RecursiveOperation *operation)
   GrlFilesystemSource *fs_source;
 
   if (operation->on_file_data) {
-    GrlMediaSourceSearchSpec *ss =
-      (GrlMediaSourceSearchSpec *) operation->on_file_data;
+    GrlSourceSearchSpec *ss =
+      (GrlSourceSearchSpec *) operation->on_file_data;
     fs_source = GRL_FILESYSTEM_SOURCE (ss->source);
     g_hash_table_remove (fs_source->priv->cancellables,
-                         GUINT_TO_POINTER (ss->search_id));
-    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, NULL);
+                         GUINT_TO_POINTER (ss->operation_id));
+    ss->callback (ss->source, ss->operation_id, NULL, 0, ss->user_data, NULL);
   }
 
   if (operation->on_dir_data) {
@@ -992,11 +987,11 @@ static gboolean
 finish_cb (GFileInfo *file_info, RecursiveOperation *operation)
 {
   if (operation->on_file_data) {
-    GrlMediaSourceSearchSpec *ss =
-      (GrlMediaSourceSearchSpec *) operation->on_file_data;
+    GrlSourceSearchSpec *ss =
+      (GrlSourceSearchSpec *) operation->on_file_data;
     g_hash_table_remove (GRL_FILESYSTEM_SOURCE (ss->source)->priv->cancellables,
-                         GUINT_TO_POINTER (ss->search_id));
-    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, NULL);
+                         GUINT_TO_POINTER (ss->operation_id));
+    ss->callback (ss->source, ss->operation_id, NULL, 0, ss->user_data, NULL);
   }
 
   if (operation->on_dir_data) {
@@ -1014,7 +1009,7 @@ file_cb (GFileInfo *file_info, RecursiveOperation *operation)
   gchar *haystack = NULL;
   gchar *normalized_needle = NULL;
   gchar *normalized_haystack = NULL;
-  GrlMediaSourceSearchSpec *ss = operation->on_file_data;
+  GrlSourceSearchSpec *ss = operation->on_file_data;
   gint remaining = -1;
 
   GRL_DEBUG (__func__);
@@ -1064,7 +1059,7 @@ file_cb (GFileInfo *file_info, RecursiveOperation *operation)
       if (count == 0) {
         remaining = 0;
       }
-      ss->callback (ss->source, ss->search_id, media, remaining, ss->user_data, NULL);
+      ss->callback (ss->source, ss->operation_id, media, remaining, ss->user_data, NULL);
     }
   }
 
@@ -1076,7 +1071,7 @@ file_cb (GFileInfo *file_info, RecursiveOperation *operation)
 }
 
 static void
-notify_parent_change (GrlMediaSource *source, GFile *child, GrlMediaSourceChangeType change)
+notify_parent_change (GrlSource *source, GFile *child, GrlSourceChangeType change)
 {
   GFile *parent;
   GrlMedia *media;
@@ -1090,7 +1085,7 @@ notify_parent_change (GrlMediaSource *source, GFile *child, GrlMediaSourceChange
   }
 
   media = create_content (NULL, parent_path, GRL_RESOLVE_FAST_ONLY, parent == NULL, NULL);
-  grl_media_source_notify_change (source, media, change, FALSE);
+  grl_source_notify_change (source, media, change, FALSE);
   g_object_unref (media);
 
   if (parent) {
@@ -1106,7 +1101,7 @@ directory_changed (GFileMonitor *monitor,
                    GFileMonitorEvent event,
                    gpointer data)
 {
-  GrlMediaSource *source = GRL_MEDIA_SOURCE (data);
+  GrlSource *source = GRL_SOURCE (data);
   gchar *file_path, *other_file_path;
   gchar *file_parent_path = NULL;
   gchar *other_file_parent_path = NULL;
@@ -1232,13 +1227,13 @@ grl_filesystem_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_filesystem_source_browse (GrlMediaSource *source,
-                              GrlMediaSourceBrowseSpec *bs)
+grl_filesystem_source_browse (GrlSource *source,
+                              GrlSourceBrowseSpec *bs)
 {
   const gchar *id;
   GList *chosen_paths;
 
-  GRL_DEBUG ("grl_filesystem_source_browse");
+  GRL_DEBUG (__FUNCTION__);
 
   id = grl_media_get_id (bs->container);
   chosen_paths = GRL_FILESYSTEM_SOURCE(source)->priv->chosen_paths;
@@ -1258,7 +1253,7 @@ grl_filesystem_source_browse (GrlMediaSource *source,
         remaining--;
         if (content) {
           bs->callback (source,
-                        bs->browse_id,
+                        bs->operation_id,
                         content,
                         --remaining,
                         bs->user_data,
@@ -1271,13 +1266,13 @@ grl_filesystem_source_browse (GrlMediaSource *source,
   }
 }
 
-static void grl_filesystem_source_search (GrlMediaSource *source,
-                                          GrlMediaSourceSearchSpec *ss)
+static void grl_filesystem_source_search (GrlSource *source,
+                                          GrlSourceSearchSpec *ss)
 {
   RecursiveOperation *operation;
   GrlFilesystemSource *fs_source;
 
-  GRL_DEBUG ("grl_filesystem_source_search");
+  GRL_DEBUG (__FUNCTION__);
 
   fs_source = GRL_FILESYSTEM_SOURCE (source);
 
@@ -1288,7 +1283,7 @@ static void grl_filesystem_source_search (GrlMediaSource *source,
   operation->on_file_data = ss;
   operation->max_depth = fs_source->priv->max_search_depth;
   g_hash_table_insert (GRL_FILESYSTEM_SOURCE (source)->priv->cancellables,
-                       GUINT_TO_POINTER (ss->search_id),
+                       GUINT_TO_POINTER (ss->operation_id),
                        operation->cancellable);
 
   recursive_operation_initialize (operation, fs_source);
@@ -1296,43 +1291,43 @@ static void grl_filesystem_source_search (GrlMediaSource *source,
 }
 
 static void
-grl_filesystem_source_metadata (GrlMediaSource *source,
-                                GrlMediaSourceMetadataSpec *ms)
+grl_filesystem_source_resolve (GrlSource *source,
+                               GrlSourceResolveSpec *rs)
 {
   const gchar *path;
   const gchar *id;
 
-  GRL_DEBUG ("grl_filesystem_source_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
-  id = grl_media_get_id (ms->media);
+  id = grl_media_get_id (rs->media);
   path = id ? id : G_DIR_SEPARATOR_S;
 
   if (g_file_test (path, G_FILE_TEST_EXISTS)) {
-    create_content (ms->media, path,
-		    grl_operation_options_get_flags (ms->options)
-                      & GRL_RESOLVE_FAST_ONLY,
-		    !id,
-                    ms->options);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    create_content (rs->media, path,
+                    grl_operation_options_get_flags (rs->options)
+                    & GRL_RESOLVE_FAST_ONLY,
+                    !id,
+                    rs->options);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
     GError *error = g_error_new (GRL_CORE_ERROR,
-				 GRL_CORE_ERROR_METADATA_FAILED,
-				 "File '%s' does not exist",
-				 path);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                                 GRL_CORE_ERROR_RESOLVE_FAILED,
+                                 "File '%s' does not exist",
+                                 path);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 }
 
 static gboolean
-grl_filesystem_test_media_from_uri (GrlMediaSource *source,
+grl_filesystem_test_media_from_uri (GrlSource *source,
                                     const gchar *uri)
 {
   gchar *path, *scheme;
   GError *error = NULL;
   gboolean ret = FALSE;
 
-  GRL_DEBUG ("grl_filesystem_test_media_from_uri");
+  GRL_DEBUG (__FUNCTION__);
 
   scheme = g_uri_parse_scheme (uri);
   ret = (g_strcmp0(scheme, "file") == 0);
@@ -1352,15 +1347,15 @@ grl_filesystem_test_media_from_uri (GrlMediaSource *source,
   return ret;
 }
 
-static void grl_filesystem_get_media_from_uri (GrlMediaSource *source,
-                                               GrlMediaSourceMediaFromUriSpec *mfus)
+static void grl_filesystem_get_media_from_uri (GrlSource *source,
+                                               GrlSourceMediaFromUriSpec *mfus)
 {
   gchar *path, *scheme;
   GError *error = NULL;
   gboolean ret = FALSE;
   GrlMedia *media;
 
-  GRL_DEBUG ("grl_filesystem_get_media_from_uri");
+  GRL_DEBUG (__FUNCTION__);
 
   scheme = g_uri_parse_scheme (mfus->uri);
   ret = (g_strcmp0(scheme, "file") == 0);
@@ -1369,7 +1364,7 @@ static void grl_filesystem_get_media_from_uri (GrlMediaSource *source,
     error = g_error_new (GRL_CORE_ERROR,
                          GRL_CORE_ERROR_MEDIA_FROM_URI_FAILED,
                          "Cannot create media from '%s'", mfus->uri);
-    mfus->callback (source, mfus->media_from_uri_id, NULL, mfus->user_data, error);
+    mfus->callback (source, mfus->operation_id, NULL, mfus->user_data, error);
     g_clear_error (&error);
     return;
   }
@@ -1382,7 +1377,7 @@ static void grl_filesystem_get_media_from_uri (GrlMediaSource *source,
                          "Cannot create media from '%s', error message: %s",
                          mfus->uri, error->message);
     g_clear_error (&error);
-    mfus->callback (source, mfus->media_from_uri_id, NULL, mfus->user_data, new_error);
+    mfus->callback (source, mfus->operation_id, NULL, mfus->user_data, new_error);
     g_clear_error (&new_error);
     goto beach;
   }
@@ -1395,7 +1390,7 @@ static void grl_filesystem_get_media_from_uri (GrlMediaSource *source,
                        & GRL_RESOLVE_FAST_ONLY,
                       FALSE,
                       mfus->options);
-  mfus->callback (source, mfus->media_from_uri_id, media, mfus->user_data, NULL);
+  mfus->callback (source, mfus->operation_id, media, mfus->user_data, NULL);
 
 beach:
   g_free (path);
@@ -1417,7 +1412,7 @@ grl_filesystem_source_cancel (GrlSource *source, guint operation_id)
 }
 
 static gboolean
-grl_filesystem_source_notify_change_start (GrlMediaSource *source,
+grl_filesystem_source_notify_change_start (GrlSource *source,
                                            GError **error)
 {
   GrlFilesystemSource *fs_source;
@@ -1442,7 +1437,7 @@ grl_filesystem_source_notify_change_start (GrlMediaSource *source,
 }
 
 static gboolean
-grl_filesystem_source_notify_change_stop (GrlMediaSource *source,
+grl_filesystem_source_notify_change_stop (GrlSource *source,
                                           GError **error)
 {
   GrlFilesystemSource *fs_source = GRL_FILESYSTEM_SOURCE (source);
diff --git a/src/media/filesystem/grl-filesystem.h b/src/media/filesystem/grl-filesystem.h
index 428c61b..97729d4 100644
--- a/src/media/filesystem/grl-filesystem.h
+++ b/src/media/filesystem/grl-filesystem.h
@@ -62,7 +62,7 @@ typedef struct _GrlFilesystemSourcePrivate GrlFilesystemSourcePrivate;
 
 struct _GrlFilesystemSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlFilesystemSourcePrivate *priv;
@@ -72,7 +72,7 @@ typedef struct _GrlFilesystemSourceClass GrlFilesystemSourceClass;
 
 struct _GrlFilesystemSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/flickr/grl-flickr.c b/src/media/flickr/grl-flickr.c
index c7a200d..a95ec0e 100644
--- a/src/media/flickr/grl-flickr.c
+++ b/src/media/flickr/grl-flickr.c
@@ -61,8 +61,8 @@ GRL_LOG_DOMAIN(flickr_log_domain);
 #define PERSONAL_SOURCE_DESC "A source for browsing and searching %s' flickr photos"
 
 typedef struct {
-  GrlMediaSource *source;
-  GrlMediaSourceResultCb callback;
+  GrlSource *source;
+  GrlSourceResultCb callback;
   gchar *user_id;
   gchar *tags;
   gchar *text;
@@ -102,14 +102,14 @@ static const GList *grl_flickr_source_supported_keys (GrlSource *source);
 static GrlCaps * grl_flickr_source_get_caps (GrlSource *source,
                                              GrlSupportedOps operation);
 
-static void grl_flickr_source_browse (GrlMediaSource *source,
-                                      GrlMediaSourceBrowseSpec *bs);
+static void grl_flickr_source_browse (GrlSource *source,
+                                      GrlSourceBrowseSpec *bs);
 
-static void grl_flickr_source_metadata (GrlMediaSource *source,
-                                        GrlMediaSourceMetadataSpec *ss);
+static void grl_flickr_source_resolve (GrlSource *source,
+                                       GrlSourceResolveSpec *rs);
 
-static void grl_flickr_source_search (GrlMediaSource *source,
-                                      GrlMediaSourceSearchSpec *ss);
+static void grl_flickr_source_search (GrlSource *source,
+                                      GrlSourceSearchSpec *ss);
 
 /* =================== Flickr Plugin  =============== */
 
@@ -178,7 +178,7 @@ GRL_PLUGIN_REGISTER (grl_flickr_plugin_init,
 
 /* ================== Flickr GObject ================ */
 
-G_DEFINE_TYPE (GrlFlickrSource, grl_flickr_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlFlickrSource, grl_flickr_source, GRL_TYPE_SOURCE);
 
 static GrlFlickrSource *
 grl_flickr_source_public_new (const gchar *flickr_api_key,
@@ -215,16 +215,14 @@ grl_flickr_source_class_init (GrlFlickrSourceClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   gobject_class->finalize = grl_flickr_source_finalize;
 
   source_class->supported_keys = grl_flickr_source_supported_keys;
   source_class->get_caps = grl_flickr_source_get_caps;
-
-  media_class->browse = grl_flickr_source_browse;
-  media_class->metadata = grl_flickr_source_metadata;
-  media_class->search = grl_flickr_source_search;
+  source_class->browse = grl_flickr_source_browse;
+  source_class->resolve = grl_flickr_source_resolve;
+  source_class->search = grl_flickr_source_search;
 
   g_type_class_add_private (klass, sizeof (GrlFlickrSourcePrivate));
 }
@@ -234,8 +232,7 @@ grl_flickr_source_init (GrlFlickrSource *source)
 {
   source->priv = GRL_FLICKR_SOURCE_GET_PRIVATE (source);
 
-  grl_media_source_set_auto_split_threshold (GRL_MEDIA_SOURCE (source),
-                                             SEARCH_MAX);
+  grl_source_set_auto_split_threshold (GRL_SOURCE (source), SEARCH_MAX);
 }
 
 static void
@@ -383,13 +380,13 @@ update_media (GrlMedia *media, GHashTable *photo)
 static void
 getInfo_cb (GFlickr *f, GHashTable *photo, gpointer user_data)
 {
-  GrlMediaSourceMetadataSpec *ms = (GrlMediaSourceMetadataSpec *) user_data;
+  GrlSourceResolveSpec *rs = (GrlSourceResolveSpec *) user_data;
 
   if (photo) {
-    update_media (ms->media, photo);
+    update_media (rs->media, photo);
   }
 
-  ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+  rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
 }
 
 static void
@@ -452,7 +449,7 @@ static void
 photosetslist_cb (GFlickr *f, GList *photosets, gpointer user_data)
 {
   GrlMedia *media;
-  GrlMediaSourceBrowseSpec *bs = (GrlMediaSourceBrowseSpec *) user_data;
+  GrlSourceBrowseSpec *bs = (GrlSourceBrowseSpec *) user_data;
   gchar *value;
   gint count, desired_count;
 
@@ -463,7 +460,7 @@ photosetslist_cb (GFlickr *f, GList *photosets, gpointer user_data)
   /* No more elements can be sent */
   if (!photosets) {
     bs->callback (bs->source,
-                  bs->browse_id,
+                  bs->operation_id,
                   NULL,
                   0,
                   bs->user_data,
@@ -494,7 +491,7 @@ photosetslist_cb (GFlickr *f, GList *photosets, gpointer user_data)
     }
 
     bs->callback (bs->source,
-                  bs->browse_id,
+                  bs->operation_id,
                   media,
                   count,
                   bs->user_data,
@@ -557,7 +554,7 @@ static void
 gettags_cb (GFlickr *f, GList *taglist, gpointer user_data)
 {
   GrlMedia *media;
-  GrlMediaSourceBrowseSpec *bs = (GrlMediaSourceBrowseSpec *) user_data;
+  GrlSourceBrowseSpec *bs = (GrlSourceBrowseSpec *) user_data;
   gint count;
 
   /* Go to offset element */
@@ -566,7 +563,7 @@ gettags_cb (GFlickr *f, GList *taglist, gpointer user_data)
   /* No more elements can be sent */
   if (!taglist) {
     bs->callback (bs->source,
-                  bs->browse_id,
+                  bs->operation_id,
                   NULL,
                   0,
                   bs->user_data,
@@ -582,7 +579,7 @@ gettags_cb (GFlickr *f, GList *taglist, gpointer user_data)
     grl_media_set_id (media, taglist->data);
     grl_media_set_title (media, taglist->data);
     bs->callback (bs->source,
-                  bs->browse_id,
+                  bs->operation_id,
                   media,
                   count,
                   bs->user_data,
@@ -611,8 +608,8 @@ grl_flickr_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_flickr_source_public_browse (GrlMediaSource *source,
-                                 GrlMediaSourceBrowseSpec *bs)
+grl_flickr_source_public_browse (GrlSource *source,
+                                 GrlSourceBrowseSpec *bs)
 {
   GFlickr *f = GRL_FLICKR_SOURCE (source)->priv->flickr;
   const gchar *container_id;
@@ -626,7 +623,7 @@ grl_flickr_source_public_browse (GrlMediaSource *source,
   if (!container_id) {
     /* Get hot tags list. List is limited up to HOTLIST_MAX tags */
     if (skip >= HOTLIST_MAX) {
-      bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, NULL);
+      bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, NULL);
     } else {
       request_size = CLAMP (skip + count, 1, HOTLIST_MAX);
       g_flickr_tags_getHotList (f, request_size, gettags_cb, bs);
@@ -649,7 +646,7 @@ grl_flickr_source_public_browse (GrlMediaSource *source,
     od->text = NULL;
     od->user_data = bs->user_data;
     od->count = count;
-    od->operation_id = bs->browse_id;
+    od->operation_id = bs->operation_id;
     g_flickr_photos_search (f,
                             od->user_id,
                             NULL,
@@ -661,8 +658,8 @@ grl_flickr_source_public_browse (GrlMediaSource *source,
 }
 
 static void
-grl_flickr_source_personal_browse (GrlMediaSource *source,
-                                   GrlMediaSourceBrowseSpec *bs)
+grl_flickr_source_personal_browse (GrlSource *source,
+                                   GrlSourceBrowseSpec *bs)
 {
   GFlickr *f = GRL_FLICKR_SOURCE (source)->priv->flickr;
   OperationData *od;
@@ -693,15 +690,15 @@ grl_flickr_source_personal_browse (GrlMediaSource *source,
     od->text = (gchar *) container_id;
     od->user_data = bs->user_data;
     od->count = count;
-    od->operation_id = bs->browse_id;
+    od->operation_id = bs->operation_id;
 
     g_flickr_photosets_getPhotos (f, container_id, od->page, photosetsphotos_cb, od);
   }
 }
 
 static void
-grl_flickr_source_browse (GrlMediaSource *source,
-                          GrlMediaSourceBrowseSpec *bs)
+grl_flickr_source_browse (GrlSource *source,
+                          GrlSourceBrowseSpec *bs)
 {
   if (GRL_FLICKR_SOURCE (source)->priv->user_id) {
     grl_flickr_source_personal_browse (source, bs);
@@ -711,25 +708,25 @@ grl_flickr_source_browse (GrlMediaSource *source,
 }
 
 static void
-grl_flickr_source_metadata (GrlMediaSource *source,
-                            GrlMediaSourceMetadataSpec *ms)
+grl_flickr_source_resolve (GrlSource *source,
+                           GrlSourceResolveSpec *rs)
 {
   const gchar *id;
 
-  if (!ms->media || (id = grl_media_get_id (ms->media)) == NULL) {
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+  if (!rs->media || (id = grl_media_get_id (rs->media)) == NULL) {
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
     return;
   }
 
   g_flickr_photos_getInfo (GRL_FLICKR_SOURCE (source)->priv->flickr,
                            atol (id),
                            getInfo_cb,
-                           ms);
+                           rs);
 }
 
 static void
-grl_flickr_source_search (GrlMediaSource *source,
-                          GrlMediaSourceSearchSpec *ss)
+grl_flickr_source_search (GrlSource *source,
+                          GrlSourceSearchSpec *ss)
 {
   GFlickr *f = GRL_FLICKR_SOURCE (source)->priv->flickr;
   guint per_page;
@@ -753,7 +750,7 @@ grl_flickr_source_search (GrlMediaSource *source,
   od->text = ss->text;
   od->user_data = ss->user_data;
   od->count = count;
-  od->operation_id = ss->search_id;
+  od->operation_id = ss->operation_id;
 
   if (od->user_id || od->text) {
     g_flickr_photos_search (f,
diff --git a/src/media/flickr/grl-flickr.h b/src/media/flickr/grl-flickr.h
index af1a843..f2be728 100644
--- a/src/media/flickr/grl-flickr.h
+++ b/src/media/flickr/grl-flickr.h
@@ -61,7 +61,7 @@ typedef struct _GrlFlickrSourcePrivate GrlFlickrSourcePrivate;
 
 struct _GrlFlickrSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlFlickrSourcePrivate *priv;
@@ -71,7 +71,7 @@ typedef struct _GrlFlickrSourceClass GrlFlickrSourceClass;
 
 struct _GrlFlickrSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/jamendo/grl-jamendo.c b/src/media/jamendo/grl-jamendo.c
index 77b7f19..d7aab4f 100644
--- a/src/media/jamendo/grl-jamendo.c
+++ b/src/media/jamendo/grl-jamendo.c
@@ -92,7 +92,7 @@ GRL_LOG_DOMAIN_STATIC(jamendo_log_domain);
 #define SOURCE_DESC "A source for browsing and searching Jamendo music"
 
 enum {
-  METADATA,
+  RESOLVE,
   BROWSE,
   QUERY,
   SEARCH
@@ -127,10 +127,10 @@ typedef struct {
 typedef struct {
   gint type;
   union {
-    GrlMediaSourceBrowseSpec *bs;
-    GrlMediaSourceQuerySpec *qs;
-    GrlMediaSourceMetadataSpec *ms;
-    GrlMediaSourceSearchSpec *ss;
+    GrlSourceBrowseSpec *bs;
+    GrlSourceQuerySpec *qs;
+    GrlSourceResolveSpec *rs;
+    GrlSourceSearchSpec *ss;
   } spec;
   xmlNodePtr node;
   xmlDocPtr doc;
@@ -180,17 +180,17 @@ static const GList *grl_jamendo_source_supported_keys (GrlSource *source);
 static GrlCaps *grl_jamendo_source_get_caps (GrlSource *source,
                                              GrlSupportedOps operation);
 
-static void grl_jamendo_source_metadata (GrlMediaSource *source,
-                                         GrlMediaSourceMetadataSpec *ms);
+static void grl_jamendo_source_resolve (GrlSource *source,
+                                        GrlSourceResolveSpec *rs);
 
-static void grl_jamendo_source_browse (GrlMediaSource *source,
-                                       GrlMediaSourceBrowseSpec *bs);
+static void grl_jamendo_source_browse (GrlSource *source,
+                                       GrlSourceBrowseSpec *bs);
 
-static void grl_jamendo_source_query (GrlMediaSource *source,
-                                      GrlMediaSourceQuerySpec *qs);
+static void grl_jamendo_source_query (GrlSource *source,
+                                      GrlSourceQuerySpec *qs);
 
-static void grl_jamendo_source_search (GrlMediaSource *source,
-                                       GrlMediaSourceSearchSpec *ss);
+static void grl_jamendo_source_search (GrlSource *source,
+                                       GrlSourceSearchSpec *ss);
 
 static void grl_jamendo_source_cancel (GrlSource *source,
                                        guint operation_id);
@@ -231,7 +231,7 @@ grl_jamendo_source_new (void)
 		       NULL);
 }
 
-G_DEFINE_TYPE (GrlJamendoSource, grl_jamendo_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlJamendoSource, grl_jamendo_source, GRL_TYPE_SOURCE);
 
 static void
 grl_jamendo_source_finalize (GObject *object)
@@ -254,18 +254,16 @@ grl_jamendo_source_class_init (GrlJamendoSourceClass * klass)
 {
   GObjectClass *g_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   g_class->finalize = grl_jamendo_source_finalize;
 
   source_class->cancel = grl_jamendo_source_cancel;
   source_class->supported_keys = grl_jamendo_source_supported_keys;
   source_class->get_caps = grl_jamendo_source_get_caps;
-
-  media_class->metadata = grl_jamendo_source_metadata;
-  media_class->browse = grl_jamendo_source_browse;
-  media_class->query = grl_jamendo_source_query;
-  media_class->search = grl_jamendo_source_search;
+  source_class->resolve = grl_jamendo_source_resolve;
+  source_class->browse = grl_jamendo_source_browse;
+  source_class->query = grl_jamendo_source_query;
+  source_class->search = grl_jamendo_source_search;
 
   g_type_class_add_private (klass, sizeof (GrlJamendoSourcePriv));
 }
@@ -277,35 +275,11 @@ grl_jamendo_source_init (GrlJamendoSource *source)
 
   /* If we try to get too much elements in a single step, Jamendo might return
      nothing. So limit the maximum amount of elements in each query */
-  grl_media_source_set_auto_split_threshold (GRL_MEDIA_SOURCE (source),
-                                             MAX_ELEMENTS);
+  grl_source_set_auto_split_threshold (GRL_SOURCE (source), MAX_ELEMENTS);
 }
 
 /* ======================= Utilities ==================== */
 
-#if 0
-static void
-print_entry (Entry *entry)
-{
-  g_print ("Entry Information:\n");
-  g_print ("            ID: %s\n", entry->id);
-  g_print ("   Artist Name: %s\n", entry->artist_name);
-  g_print ("  Artist Genre: %s\n", entry->artist_genre);
-  g_print ("    Artist URL: %s\n", entry->artist_url);
-  g_print ("  Artist Image: %s\n", entry->artist_image);
-  g_print ("    Album Name: %s\n", entry->album_name);
-  g_print ("   Album Genre: %s\n", entry->album_genre);
-  g_print ("     Album URL: %s\n", entry->album_url);
-  g_print ("Album Duration: %s\n", entry->album_duration);
-  g_print ("   Album Image: %s\n", entry->album_image);
-  g_print ("    Track Name: %s\n", entry->track_name);
-  g_print ("     Track URL: %s\n", entry->track_url);
-  g_print ("  Track Stream: %s\n", entry->track_stream);
-  g_print ("Track Duration: %s\n", entry->track_duration);
-  g_print ("     Feed Name: %s\n", entry->feed_name);
-}
-#endif
-
 static void
 free_entry (Entry *entry)
 {
@@ -615,7 +589,7 @@ xml_parse_entries_idle (gpointer user_data)
     switch (xpe->type) {
     case BROWSE:
       xpe->spec.bs->callback (xpe->spec.bs->source,
-                              xpe->spec.bs->browse_id,
+                              xpe->spec.bs->operation_id,
                               media,
                               remaining,
                               xpe->spec.bs->user_data,
@@ -623,7 +597,7 @@ xml_parse_entries_idle (gpointer user_data)
       break;
     case QUERY:
       xpe->spec.qs->callback (xpe->spec.qs->source,
-                              xpe->spec.qs->query_id,
+                              xpe->spec.qs->operation_id,
                               media,
                               remaining,
                               xpe->spec.qs->user_data,
@@ -631,7 +605,7 @@ xml_parse_entries_idle (gpointer user_data)
       break;
     case SEARCH:
       xpe->spec.ss->callback (xpe->spec.ss->source,
-                              xpe->spec.ss->search_id,
+                              xpe->spec.ss->operation_id,
                               media,
                               remaining,
                               xpe->spec.ss->user_data,
@@ -671,8 +645,8 @@ read_done_cb (GObject *source_object,
                               NULL,
                               &wc_error)) {
     switch (xpe->type) {
-    case METADATA:
-      error_code = GRL_CORE_ERROR_METADATA_FAILED;
+    case RESOLVE:
+      error_code = GRL_CORE_ERROR_RESOLVE_FAILED;
       break;
     case BROWSE:
       error_code = GRL_CORE_ERROR_BROWSE_FAILED;
@@ -704,21 +678,21 @@ read_done_cb (GObject *source_object,
   }
 
   if (xpe->node) {
-    if (xpe->type == METADATA) {
+    if (xpe->type == RESOLVE) {
       entry = xml_parse_entry (xpe->doc, xpe->node);
       xmlFreeDoc (xpe->doc);
-      update_media_from_entry (xpe->spec.ms->media, entry);
+      update_media_from_entry (xpe->spec.rs->media, entry);
       free_entry (entry);
       goto invoke_cb;
     } else {
       g_idle_add (xml_parse_entries_idle, xpe);
     }
   } else {
-    if (xpe->type == METADATA) {
+    if (xpe->type == RESOLVE) {
       error = g_error_new (GRL_CORE_ERROR,
-                           GRL_CORE_ERROR_METADATA_FAILED,
+                           GRL_CORE_ERROR_RESOLVE_FAILED,
                            "Unable to get information: '%s'",
-                           grl_media_get_id (xpe->spec.ms->media));
+                           grl_media_get_id (xpe->spec.rs->media));
     }
     goto invoke_cb;
   }
@@ -727,16 +701,16 @@ read_done_cb (GObject *source_object,
 
  invoke_cb:
   switch (xpe->type) {
-  case METADATA:
-    xpe->spec.ms->callback (xpe->spec.ms->source,
-                            xpe->spec.ms->metadata_id,
-                            xpe->spec.ms->media,
-                            xpe->spec.ms->user_data,
+  case RESOLVE:
+    xpe->spec.rs->callback (xpe->spec.rs->source,
+                            xpe->spec.rs->operation_id,
+                            xpe->spec.rs->media,
+                            xpe->spec.rs->user_data,
                             error);
     break;
   case BROWSE:
     xpe->spec.bs->callback (xpe->spec.bs->source,
-                            xpe->spec.bs->browse_id,
+                            xpe->spec.bs->operation_id,
                             NULL,
                             0,
                             xpe->spec.bs->user_data,
@@ -744,7 +718,7 @@ read_done_cb (GObject *source_object,
     break;
   case QUERY:
     xpe->spec.qs->callback (xpe->spec.qs->source,
-                            xpe->spec.qs->query_id,
+                            xpe->spec.qs->operation_id,
                             NULL,
                             0,
                             xpe->spec.qs->user_data,
@@ -752,7 +726,7 @@ read_done_cb (GObject *source_object,
     break;
   case SEARCH:
     xpe->spec.ss->callback (xpe->spec.ss->source,
-                            xpe->spec.ss->search_id,
+                            xpe->spec.ss->operation_id,
                             NULL,
                             0,
                             xpe->spec.ss->user_data,
@@ -826,7 +800,7 @@ update_media_from_feeds (GrlMedia *media)
 }
 
 static void
-send_toplevel_categories (GrlMediaSourceBrowseSpec *bs)
+send_toplevel_categories (GrlSourceBrowseSpec *bs)
 {
   GrlMedia *media;
   gint remaining;
@@ -835,7 +809,7 @@ send_toplevel_categories (GrlMediaSourceBrowseSpec *bs)
 
   /* Check if all elements must be skipped */
   if (skip > 1 || count == 0) {
-    bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, NULL);
     return;
   }
 
@@ -845,20 +819,20 @@ send_toplevel_categories (GrlMediaSourceBrowseSpec *bs)
     media = grl_media_box_new ();
     update_media_from_artists (media);
     remaining--;
-    bs->callback (bs->source, bs->browse_id, media, remaining, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, media, remaining, bs->user_data, NULL);
   }
 
   if (remaining) {
     media = grl_media_box_new ();
     update_media_from_albums (media);
-    bs->callback (bs->source, bs->browse_id, media, remaining, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, media, remaining, bs->user_data, NULL);
     remaining--;
   }
 
   if (remaining) {
     media = grl_media_box_new ();
     update_media_from_feeds (media);
-    bs->callback (bs->source, bs->browse_id, media, 0, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, media, 0, bs->user_data, NULL);
   }
 }
 
@@ -876,7 +850,7 @@ update_media_from_feed (GrlMedia *media, int i)
 }
 
 static void
-send_feeds (GrlMediaSourceBrowseSpec *bs)
+send_feeds (GrlSourceBrowseSpec *bs)
 {
   int i;
   int remaining;
@@ -891,7 +865,7 @@ send_feeds (GrlMediaSourceBrowseSpec *bs)
     update_media_from_feed (media, i);
     remaining--;
     bs->callback (bs->source,
-                  bs->browse_id,
+                  bs->operation_id,
                   media,
                   remaining,
                   bs->user_data,
@@ -969,8 +943,8 @@ grl_jamendo_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_jamendo_source_metadata (GrlMediaSource *source,
-                             GrlMediaSourceMetadataSpec *ms)
+grl_jamendo_source_resolve (GrlSource *source,
+                            GrlSourceResolveSpec *rs)
 {
   gchar *url = NULL;
   gchar *jamendo_keys = NULL;
@@ -982,21 +956,21 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
 
   GRL_TRACE ();
 
-  if (!ms->media ||
-      !grl_data_has_key (GRL_DATA (ms->media),
+  if (!rs->media ||
+      !grl_data_has_key (GRL_DATA (rs->media),
                          GRL_METADATA_KEY_ID)) {
     /* Get info from root */
-    if (!ms->media) {
-      ms->media = grl_media_box_new ();
+    if (!rs->media) {
+      rs->media = grl_media_box_new ();
     }
-    update_media_from_root (ms->media);
+    update_media_from_root (rs->media);
   } else {
-    id = grl_media_get_id (ms->media);
+    id = grl_media_get_id (rs->media);
     id_split = g_strsplit (id, JAMENDO_ID_SEP, 0);
 
     if (g_strv_length (id_split) == 0) {
       error = g_error_new (GRL_CORE_ERROR,
-                           GRL_CORE_ERROR_METADATA_FAILED,
+                           GRL_CORE_ERROR_RESOLVE_FAILED,
                            "Invalid id: '%s'",
                            id);
       goto send_error;
@@ -1015,7 +989,7 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
         g_free (jamendo_keys);
       } else {
         /* Requesting information from artist category */
-        update_media_from_artists (ms->media);
+        update_media_from_artists (rs->media);
       }
     } else if (category == JAMENDO_ALBUM_CAT) {
       if (id_split[1]) {
@@ -1028,7 +1002,7 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
         g_free (jamendo_keys);
       } else {
         /* Requesting information from album category */
-        update_media_from_albums (ms->media);
+        update_media_from_albums (rs->media);
       }
     } else if (category == JAMENDO_TRACK_CAT) {
       if (id_split[1]) {
@@ -1041,7 +1015,7 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
         g_free (jamendo_keys);
       } else {
         error = g_error_new (GRL_CORE_ERROR,
-                             GRL_CORE_ERROR_METADATA_FAILED,
+                             GRL_CORE_ERROR_RESOLVE_FAILED,
                              "Invalid id: '%s'",
                              id);
         g_strfreev (id_split);
@@ -1055,19 +1029,19 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
         i = strtol (id_split[1], NULL, 0);
         if (errno != 0 || (i <= 0 && i > G_N_ELEMENTS (feeds))) {
           error = g_error_new (GRL_CORE_ERROR,
-                               GRL_CORE_ERROR_METADATA_FAILED,
+                               GRL_CORE_ERROR_RESOLVE_FAILED,
                                "Invalid cat id: '%s'", id_split[1]);
           g_strfreev (id_split);
           goto send_error;
         }
 
-        update_media_from_feed (ms->media, i);
+        update_media_from_feed (rs->media, i);
       } else {
-        update_media_from_feeds (ms->media);
+        update_media_from_feeds (rs->media);
       }
     } else {
       error = g_error_new (GRL_CORE_ERROR,
-                           GRL_CORE_ERROR_METADATA_FAILED,
+                           GRL_CORE_ERROR_RESOLVE_FAILED,
                            "Invalid id: '%s'",
                            id);
       g_strfreev (id_split);
@@ -1081,26 +1055,26 @@ grl_jamendo_source_metadata (GrlMediaSource *source,
 
   if (url) {
     xpe = g_slice_new0 (XmlParseEntries);
-    xpe->type = METADATA;
-    xpe->spec.ms = ms;
+    xpe->type = RESOLVE;
+    xpe->spec.rs = rs;
     read_url_async (GRL_JAMENDO_SOURCE (source), url, xpe);
     g_free (url);
   } else {
-    if (ms->media) {
-      ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    if (rs->media) {
+      rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
     }
   }
 
   return;
 
  send_error:
-  ms->callback (ms->source, ms->metadata_id, NULL, ms->user_data, error);
+  rs->callback (rs->source, rs->operation_id, NULL, rs->user_data, error);
   g_error_free (error);
 }
 
 static void
-grl_jamendo_source_browse (GrlMediaSource *source,
-                           GrlMediaSourceBrowseSpec *bs)
+grl_jamendo_source_browse (GrlSource *source,
+                           GrlSourceBrowseSpec *bs)
 {
   gchar *url = NULL;
   gchar *jamendo_keys;
@@ -1211,7 +1185,7 @@ grl_jamendo_source_browse (GrlMediaSource *source,
   }
 
   if (error) {
-    bs->callback (source, bs->browse_id, NULL, 0, bs->user_data, error);
+    bs->callback (source, bs->operation_id, NULL, 0, bs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -1221,7 +1195,7 @@ grl_jamendo_source_browse (GrlMediaSource *source,
   xpe->offset = page_offset;
   xpe->spec.bs = bs;
 
-  grl_operation_set_data (bs->browse_id, xpe);
+  grl_operation_set_data (bs->operation_id, xpe);
 
   read_url_async (GRL_JAMENDO_SOURCE (source), url, xpe);
   g_free (url);
@@ -1241,8 +1215,8 @@ grl_jamendo_source_browse (GrlMediaSource *source,
  *
  */
 static void
-grl_jamendo_source_query (GrlMediaSource *source,
-                          GrlMediaSourceQuerySpec *qs)
+grl_jamendo_source_query (GrlSource *source,
+                          GrlSourceQuerySpec *qs)
 {
   GError *error = NULL;
   JamendoCategory category;
@@ -1302,7 +1276,7 @@ grl_jamendo_source_query (GrlMediaSource *source,
   xpe->offset = page_offset;
   xpe->spec.qs = qs;
 
-  grl_operation_set_data (qs->query_id, xpe);
+  grl_operation_set_data (qs->operation_id, xpe);
 
   read_url_async (GRL_JAMENDO_SOURCE (source), url, xpe);
   g_free (url);
@@ -1310,14 +1284,14 @@ grl_jamendo_source_query (GrlMediaSource *source,
   return;
 
  send_error:
-  qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
+  qs->callback (qs->source, qs->operation_id, NULL, 0, qs->user_data, error);
   g_error_free (error);
 }
 
 
 static void
-grl_jamendo_source_search (GrlMediaSource *source,
-                           GrlMediaSourceSearchSpec *ss)
+grl_jamendo_source_search (GrlSource *source,
+                           GrlSourceSearchSpec *ss)
 {
   XmlParseEntries *xpe;
   gchar *jamendo_keys;
@@ -1357,7 +1331,7 @@ grl_jamendo_source_search (GrlMediaSource *source,
   xpe->offset = page_offset;
   xpe->spec.ss = ss;
 
-  grl_operation_set_data (ss->search_id, xpe);
+  grl_operation_set_data (ss->operation_id, xpe);
 
   read_url_async (GRL_JAMENDO_SOURCE (source), url, xpe);
   g_free (jamendo_keys);
diff --git a/src/media/jamendo/grl-jamendo.h b/src/media/jamendo/grl-jamendo.h
index 15a4b75..74f02e3 100644
--- a/src/media/jamendo/grl-jamendo.h
+++ b/src/media/jamendo/grl-jamendo.h
@@ -58,7 +58,7 @@ typedef struct _GrlJamendoSourcePriv GrlJamendoSourcePriv;
 
 struct _GrlJamendoSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlJamendoSourcePriv *priv;
@@ -69,7 +69,7 @@ typedef struct _GrlJamendoSourceClass GrlJamendoSourceClass;
 
 struct _GrlJamendoSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/optical-media/grl-optical-media.c b/src/media/optical-media/grl-optical-media.c
index 88d3c96..4e0e2af 100644
--- a/src/media/optical-media/grl-optical-media.c
+++ b/src/media/optical-media/grl-optical-media.c
@@ -74,8 +74,8 @@ static const GList *grl_optical_media_source_supported_keys (GrlSource *source);
 static GrlCaps *grl_optical_media_source_get_caps (GrlSource *source,
                                                    GrlSupportedOps operation);
 
-static void grl_optical_media_source_browse (GrlMediaSource *source,
-                                             GrlMediaSourceBrowseSpec *bs);
+static void grl_optical_media_source_browse (GrlSource *source,
+                                             GrlSourceBrowseSpec *bs);
 
 static void grl_optical_media_source_cancel (GrlSource *source,
                                              guint operation_id);
@@ -115,7 +115,7 @@ GRL_PLUGIN_REGISTER (grl_optical_media_plugin_init,
 
 G_DEFINE_TYPE (GrlOpticalMediaSource,
                grl_optical_media_source,
-               GRL_TYPE_MEDIA_SOURCE);
+               GRL_TYPE_SOURCE);
 
 static GrlOpticalMediaSource *
 grl_optical_media_source_new (void)
@@ -134,15 +134,13 @@ grl_optical_media_source_class_init (GrlOpticalMediaSourceClass * klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   object_class->finalize = grl_optical_media_source_finalize;
 
   source_class->supported_keys = grl_optical_media_source_supported_keys;
   source_class->cancel = grl_optical_media_source_cancel;
   source_class->get_caps = grl_optical_media_source_get_caps;
-
-  media_class->browse = grl_optical_media_source_browse;
+  source_class->browse = grl_optical_media_source_browse;
 
   g_type_class_add_private (klass, sizeof (GrlOpticalMediaSourcePrivate));
 }
@@ -193,7 +191,7 @@ on_g_volume_monitor_event (GVolumeMonitor *monitor,
                            gpointer device,
                            GrlOpticalMediaSource *source)
 {
-  grl_media_source_notify_change (GRL_MEDIA_SOURCE (source), NULL, GRL_CONTENT_CHANGED, TRUE);
+  grl_source_notify_change (GRL_SOURCE (source), NULL, GRL_CONTENT_CHANGED, TRUE);
 }
 
 /* ================== API Implementation ================ */
@@ -379,8 +377,8 @@ add_drive (GList *media_list,
 typedef struct {
   TotemPlParser *parser;
   GCancellable *cancellable;
-  GrlMediaSource *source;
-  GrlMediaSourceBrowseSpec *bs;
+  GrlSource *source;
+  GrlSourceBrowseSpec *bs;
   GList *media_list;
   GrlMedia *media;
 } BrowseData;
@@ -404,7 +402,7 @@ parsed_finished (TotemPlParser *pl, GAsyncResult *result, BrowseData *data)
   if (retval == TOTEM_PL_PARSER_RESULT_SUCCESS &&
       grl_media_get_url (data->media) != NULL) {
     data->bs->callback (data->bs->source,
-                        data->bs->browse_id,
+                        data->bs->operation_id,
                         data->media,
                         -1,
                         data->bs->user_data,
@@ -455,7 +453,7 @@ resolve_disc_urls (BrowseData *data)
     }
     /* No media left, we're done */
     data->bs->callback (data->bs->source,
-                        data->bs->browse_id,
+                        data->bs->operation_id,
                         NULL,
                         0,
                         data->bs->user_data,
@@ -478,8 +476,8 @@ resolve_disc_urls (BrowseData *data)
 }
 
 static void
-grl_optical_media_source_browse (GrlMediaSource *source,
-                                 GrlMediaSourceBrowseSpec *bs)
+grl_optical_media_source_browse (GrlSource *source,
+                                 GrlSourceBrowseSpec *bs)
 {
   GList *drives;
   GList *mounts;
@@ -516,7 +514,7 @@ grl_optical_media_source_browse (GrlMediaSource *source,
   if (media_list == NULL) {
     /* Tell the caller we're done */
     bs->callback (bs->source,
-                  bs->browse_id,
+                  bs->operation_id,
                   NULL,
                   0,
                   bs->user_data,
@@ -533,7 +531,7 @@ grl_optical_media_source_browse (GrlMediaSource *source,
   data->media_list = media_list;
   data->cancellable = g_cancellable_new ();
 
-  grl_operation_set_data (bs->browse_id, data->cancellable);
+  grl_operation_set_data (bs->operation_id, data->cancellable);
 
   data->parser = totem_pl_parser_new ();
   g_signal_connect (G_OBJECT (data->parser), "entry-parsed",
diff --git a/src/media/optical-media/grl-optical-media.h b/src/media/optical-media/grl-optical-media.h
index c91b7d0..e2e6aa5 100644
--- a/src/media/optical-media/grl-optical-media.h
+++ b/src/media/optical-media/grl-optical-media.h
@@ -57,7 +57,7 @@ typedef struct _GrlOpticalMediaSourcePrivate GrlOpticalMediaSourcePrivate;
 
 struct _GrlOpticalMediaSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlOpticalMediaSourcePrivate *priv;
@@ -67,7 +67,7 @@ typedef struct _GrlOpticalMediaSourceClass GrlOpticalMediaSourceClass;
 
 struct _GrlOpticalMediaSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/podcasts/grl-podcasts.c b/src/media/podcasts/grl-podcasts.c
index 62a3132..90c203a 100644
--- a/src/media/podcasts/grl-podcasts.c
+++ b/src/media/podcasts/grl-podcasts.c
@@ -207,13 +207,13 @@ struct _GrlPodcastsPrivate {
 };
 
 typedef struct {
-  GrlMediaSource *source;
+  GrlSource *source;
   guint operation_id;
   const gchar *media_id;
   guint skip;
   guint count;
   const gchar *text;
-  GrlMediaSourceResultCb callback;
+  GrlSourceResultCb callback;
   guint error_code;
   gboolean is_query;
   time_t last_refreshed;
@@ -240,21 +240,28 @@ static const GList *grl_podcasts_source_supported_keys (GrlSource *source);
 static GrlCaps * grl_podcasts_source_get_caps (GrlSource *source,
                                                GrlSupportedOps operation);
 
-static void grl_podcasts_source_browse (GrlMediaSource *source,
-                                        GrlMediaSourceBrowseSpec *bs);
-static void grl_podcasts_source_search (GrlMediaSource *source,
-                                        GrlMediaSourceSearchSpec *ss);
-static void grl_podcasts_source_query (GrlMediaSource *source,
-                                       GrlMediaSourceQuerySpec *qs);
-static void grl_podcasts_source_metadata (GrlMediaSource *source,
-                                          GrlMediaSourceMetadataSpec *ms);
-static void grl_podcasts_source_store (GrlMediaSource *source,
-                                       GrlMediaSourceStoreSpec *ss);
-static void grl_podcasts_source_remove (GrlMediaSource *source,
-                                        GrlMediaSourceRemoveSpec *rs);
-static gboolean grl_podcasts_source_notify_change_start (GrlMediaSource *source,
+static void grl_podcasts_source_browse (GrlSource *source,
+                                        GrlSourceBrowseSpec *bs);
+
+static void grl_podcasts_source_search (GrlSource *source,
+                                        GrlSourceSearchSpec *ss);
+
+static void grl_podcasts_source_query (GrlSource *source,
+                                       GrlSourceQuerySpec *qs);
+
+static void grl_podcasts_source_resolve (GrlSource *source,
+                                         GrlSourceResolveSpec *rs);
+
+static void grl_podcasts_source_store (GrlSource *source,
+                                       GrlSourceStoreSpec *ss);
+
+static void grl_podcasts_source_remove (GrlSource *source,
+                                        GrlSourceRemoveSpec *rs);
+
+static gboolean grl_podcasts_source_notify_change_start (GrlSource *source,
                                                          GError **error);
-static gboolean grl_podcasts_source_notify_change_stop (GrlMediaSource *source,
+
+static gboolean grl_podcasts_source_notify_change_stop (GrlSource *source,
                                                         GError **error);
 
 /* =================== Podcasts Plugin  =============== */
@@ -326,21 +333,19 @@ grl_podcasts_source_class_init (GrlPodcastsSourceClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   gobject_class->finalize = grl_podcasts_source_finalize;
 
   source_class->supported_keys = grl_podcasts_source_supported_keys;
   source_class->get_caps = grl_podcasts_source_get_caps;
-
-  media_class->browse = grl_podcasts_source_browse;
-  media_class->search = grl_podcasts_source_search;
-  media_class->query = grl_podcasts_source_query;
-  media_class->metadata = grl_podcasts_source_metadata;
-  media_class->store = grl_podcasts_source_store;
-  media_class->remove = grl_podcasts_source_remove;
-  media_class->notify_change_start = grl_podcasts_source_notify_change_start;
-  media_class->notify_change_stop = grl_podcasts_source_notify_change_stop;
+  source_class->browse = grl_podcasts_source_browse;
+  source_class->search = grl_podcasts_source_search;
+  source_class->query = grl_podcasts_source_query;
+  source_class->resolve = grl_podcasts_source_resolve;
+  source_class->store = grl_podcasts_source_store;
+  source_class->remove = grl_podcasts_source_remove;
+  source_class->notify_change_start = grl_podcasts_source_notify_change_start;
+  source_class->notify_change_stop = grl_podcasts_source_notify_change_stop;
 
   g_type_class_add_private (klass, sizeof (GrlPodcastsPrivate));
 }
@@ -400,7 +405,7 @@ grl_podcasts_source_init (GrlPodcastsSource *source)
   GRL_DEBUG ("  OK");
 }
 
-G_DEFINE_TYPE (GrlPodcastsSource, grl_podcasts_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlPodcastsSource, grl_podcasts_source, GRL_TYPE_SOURCE);
 
 static void
 grl_podcasts_source_finalize (GObject *object)
@@ -836,10 +841,10 @@ remove_podcast (GrlPodcastsSource *podcasts_source,
                          "Failed to remove podcast");
     sqlite3_free (sql_error);
   } else if (podcasts_source->priv->notify_changes) {
-    grl_media_source_notify_change (GRL_MEDIA_SOURCE (podcasts_source),
-                                    NULL,
-                                    GRL_CONTENT_REMOVED,
-                                    TRUE);
+    grl_source_notify_change (GRL_SOURCE (podcasts_source),
+                              NULL,
+                              GRL_CONTENT_REMOVED,
+                              TRUE);
   }
 }
 
@@ -867,15 +872,16 @@ remove_stream (GrlPodcastsSource *podcasts_source,
                          "Failed to remove podcast stream");
     sqlite3_free (sql_error);
   } else if (podcasts_source->priv->notify_changes) {
-    grl_media_source_notify_change (GRL_MEDIA_SOURCE (podcasts_source),
-                                    NULL,
-                                    GRL_CONTENT_REMOVED,
-                                    TRUE);
+    grl_source_notify_change (GRL_SOURCE (podcasts_source),
+                              NULL,
+                              GRL_CONTENT_REMOVED,
+                              TRUE);
   }
 }
 
 static void
 store_podcast (GrlPodcastsSource *podcasts_source,
+               GList **keylist,
                GrlMedia *podcast,
                GError **error)
 {
@@ -908,9 +914,21 @@ store_podcast (GrlPodcastsSource *podcasts_source,
   }
 
   sqlite3_bind_text (sql_stmt, 1, url, -1, SQLITE_STATIC);
-  sqlite3_bind_text (sql_stmt, 2, title, -1, SQLITE_STATIC);
+  *keylist = g_list_remove (*keylist,
+                            GRLKEYID_TO_POINTER (GRL_METADATA_KEY_URL));
+
+  if (title) {
+    sqlite3_bind_text (sql_stmt, 2, title, -1, SQLITE_STATIC);
+    *keylist = g_list_remove (*keylist,
+                              GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE));
+  } else {
+    sqlite3_bind_text (sql_stmt, 2, url, -1, SQLITE_STATIC);
+  }
+
   if (desc) {
     sqlite3_bind_text (sql_stmt, 3, desc, -1, SQLITE_STATIC);
+    *keylist = g_list_remove (*keylist,
+                              GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DESCRIPTION));
   } else {
     sqlite3_bind_text (sql_stmt, 3, "", -1, SQLITE_STATIC);
   }
@@ -936,10 +954,10 @@ store_podcast (GrlPodcastsSource *podcasts_source,
   g_free (id);
 
   if (podcasts_source->priv->notify_changes) {
-    grl_media_source_notify_change (GRL_MEDIA_SOURCE (podcasts_source),
-                                    NULL,
-                                    GRL_CONTENT_ADDED,
-                                    FALSE);
+    grl_source_notify_change (GRL_SOURCE (podcasts_source),
+                              NULL,
+                              GRL_CONTENT_ADDED,
+                              FALSE);
   }
 }
 
@@ -1171,10 +1189,10 @@ parse_entry_idle (gpointer user_data)
     if (GRL_PODCASTS_SOURCE (osp->os->source)->priv->notify_changes) {
       media = grl_media_box_new ();
       grl_media_set_id (media, osp->os->media_id);
-      grl_media_source_notify_change (osp->os->source,
-                                      media,
-                                      GRL_CONTENT_CHANGED,
-                                      FALSE);
+      grl_source_notify_change (GRL_SOURCE (osp->os->source),
+                                media,
+                                GRL_CONTENT_CHANGED,
+                                FALSE);
       g_object_unref (media);
     }
     g_slice_free (OperationSpec, osp->os);
@@ -1277,15 +1295,15 @@ parse_feed (OperationSpec *os, const gchar *str, GError **error)
   /* If the feed contains no streams, notify and bail out */
   stream_count = xpathObj->nodesetval ? xpathObj->nodesetval->nodeNr : 0;
   GRL_DEBUG ("Got %d streams", stream_count);
-  
+
   if (stream_count <= 0) {
     if (GRL_PODCASTS_SOURCE (os->source)->priv->notify_changes) {
       podcast = grl_media_box_new ();
       grl_media_set_id (podcast, os->media_id);
-      grl_media_source_notify_change (os->source,
-                                      podcast,
-                                      GRL_CONTENT_CHANGED,
-                                      FALSE);
+      grl_source_notify_change (GRL_SOURCE (os->source),
+                                podcast,
+                                GRL_CONTENT_CHANGED,
+                                FALSE);
       g_object_unref (podcast);
     }
     os->callback (os->source,
@@ -1505,7 +1523,7 @@ produce_podcasts (OperationSpec *os)
 }
 
 static void
-stream_metadata (GrlMediaSourceMetadataSpec *ms)
+stream_resolve (GrlSourceResolveSpec *rs)
 {
   gint r;
   sqlite3_stmt *sql_stmt = NULL;
@@ -1514,11 +1532,11 @@ stream_metadata (GrlMediaSourceMetadataSpec *ms)
   gchar *sql;
   const gchar *id;
 
-  GRL_DEBUG ("stream_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
-  db = GRL_PODCASTS_SOURCE (ms->source)->priv->db;
+  db = GRL_PODCASTS_SOURCE (rs->source)->priv->db;
 
-  id = grl_media_get_id (ms->media);
+  id = grl_media_get_id (rs->media);
   sql = g_strdup_printf (GRL_SQL_GET_PODCAST_STREAM, id);
   GRL_DEBUG ("%s", sql);
   r = sqlite3_prepare_v2 (db, sql, strlen (sql), &sql_stmt, NULL);
@@ -1527,9 +1545,9 @@ stream_metadata (GrlMediaSourceMetadataSpec *ms)
   if (r != SQLITE_OK) {
     GRL_WARNING ("Failed to get podcast stream: %s", sqlite3_errmsg (db));
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "Failed to get podcast stream metadata");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "Failed to get podcast stream metadata");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -1537,14 +1555,14 @@ stream_metadata (GrlMediaSourceMetadataSpec *ms)
   while ((r = sqlite3_step (sql_stmt)) == SQLITE_BUSY);
 
   if (r == SQLITE_ROW) {
-    build_media_from_stmt (ms->media, sql_stmt, FALSE);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    build_media_from_stmt (rs->media, sql_stmt, FALSE);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
     GRL_WARNING ("Failed to get podcast stream: %s", sqlite3_errmsg (db));
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "Failed to get podcast stream metadata");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "Failed to get podcast stream metadata");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 
@@ -1552,37 +1570,37 @@ stream_metadata (GrlMediaSourceMetadataSpec *ms)
 }
 
 static void
-podcast_metadata (GrlMediaSourceMetadataSpec *ms)
+podcast_resolve (GrlSourceResolveSpec *rs)
 {
   sqlite3_stmt *sql_stmt = NULL;
   sqlite3 *db;
   GError *error = NULL;
   const gchar *id;
 
-  GRL_DEBUG ("podcast_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
-  db = GRL_PODCASTS_SOURCE (ms->source)->priv->db;
+  db = GRL_PODCASTS_SOURCE (rs->source)->priv->db;
 
-  id = grl_media_get_id (ms->media);
+  id = grl_media_get_id (rs->media);
   if (!id) {
     /* Root category: special case */
-    grl_media_set_title (ms->media, GRL_ROOT_TITLE);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    grl_media_set_title (rs->media, GRL_ROOT_TITLE);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
     return;
   }
 
   sql_stmt = get_podcast_info (db, id);
 
   if (sql_stmt) {
-    build_media_from_stmt (ms->media, sql_stmt, TRUE);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    build_media_from_stmt (rs->media, sql_stmt, TRUE);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
     sqlite3_finalize (sql_stmt);
   } else {
     GRL_WARNING ("Failed to get podcast: %s", sqlite3_errmsg (db));
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "Failed to get podcast metadata");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "Failed to get podcast metadata");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 }
@@ -1611,8 +1629,8 @@ grl_podcasts_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_podcasts_source_browse (GrlMediaSource *source,
-                            GrlMediaSourceBrowseSpec *bs)
+grl_podcasts_source_browse (GrlSource *source,
+                            GrlSourceBrowseSpec *bs)
 {
   GRL_DEBUG ("grl_podcasts_source_browse");
 
@@ -1626,7 +1644,7 @@ grl_podcasts_source_browse (GrlMediaSource *source,
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_BROWSE_FAILED,
 			 "No database connection");
-    bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, error);
+    bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -1634,7 +1652,7 @@ grl_podcasts_source_browse (GrlMediaSource *source,
   /* Configure browse operation */
   os = g_slice_new0 (OperationSpec);
   os->source = bs->source;
-  os->operation_id = bs->browse_id;
+  os->operation_id = bs->operation_id;
   os->media_id = grl_media_get_id (bs->container);
   os->count = grl_operation_options_get_count (bs->options);
   os->skip = grl_operation_options_get_skip (bs->options);
@@ -1655,10 +1673,10 @@ grl_podcasts_source_browse (GrlMediaSource *source,
 }
 
 static void
-grl_podcasts_source_search (GrlMediaSource *source,
-                            GrlMediaSourceSearchSpec *ss)
+grl_podcasts_source_search (GrlSource *source,
+                            GrlSourceSearchSpec *ss)
 {
-  GRL_DEBUG ("grl_podcasts_source_search");
+  GRL_DEBUG (__FUNCTION__);
 
   GrlPodcastsSource *podcasts_source;
   OperationSpec *os;
@@ -1670,14 +1688,14 @@ grl_podcasts_source_search (GrlMediaSource *source,
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_QUERY_FAILED,
 			 "No database connection");
-    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, error);
+    ss->callback (ss->source, ss->operation_id, NULL, 0, ss->user_data, error);
     g_error_free (error);
     return;
   }
 
   os = g_slice_new0 (OperationSpec);
   os->source = ss->source;
-  os->operation_id = ss->search_id;
+  os->operation_id = ss->operation_id;
   os->text = ss->text;
   os->count = grl_operation_options_get_count (ss->options);
   os->skip = grl_operation_options_get_skip (ss->options);
@@ -1690,7 +1708,7 @@ grl_podcasts_source_search (GrlMediaSource *source,
 }
 
 static void
-grl_podcasts_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
+grl_podcasts_source_query (GrlSource *source, GrlSourceQuerySpec *qs)
 {
   GRL_DEBUG ("grl_podcasts_source_query");
 
@@ -1704,14 +1722,14 @@ grl_podcasts_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_QUERY_FAILED,
 			 "No database connection");
-    qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
+    qs->callback (qs->source, qs->operation_id, NULL, 0, qs->user_data, error);
     g_error_free (error);
     return;
   }
 
   os = g_slice_new0 (OperationSpec);
   os->source = qs->source;
-  os->operation_id = qs->query_id;
+  os->operation_id = qs->operation_id;
   os->text = qs->query;
   os->count = grl_operation_options_get_count (qs->options);
   os->skip = grl_operation_options_get_skip (qs->options);
@@ -1724,10 +1742,10 @@ grl_podcasts_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
 }
 
 static void
-grl_podcasts_source_metadata (GrlMediaSource *source,
-                              GrlMediaSourceMetadataSpec *ms)
+grl_podcasts_source_resolve (GrlSource *source,
+                             GrlSourceResolveSpec *rs)
 {
-  GRL_DEBUG ("grl_podcasts_source_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
   GrlPodcastsSource *podcasts_source;
   GError *error = NULL;
@@ -1737,46 +1755,57 @@ grl_podcasts_source_metadata (GrlMediaSource *source,
   if (!podcasts_source->priv->db) {
     GRL_WARNING ("Can't execute operation: no database connection.");
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "No database connection");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "No database connection");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
     return;
   }
 
-  media_id = grl_media_get_id (ms->media);
+  media_id = grl_media_get_id (rs->media);
   if (!media_id || media_id_is_podcast (media_id)) {
-    podcast_metadata (ms);
+    podcast_resolve (rs);
   } else {
-    stream_metadata (ms);
+    stream_resolve (rs);
   }
 }
 
 static void
-grl_podcasts_source_store (GrlMediaSource *source, GrlMediaSourceStoreSpec *ss)
+grl_podcasts_source_store (GrlSource *source, GrlSourceStoreSpec *ss)
 {
-  GRL_DEBUG ("grl_podcasts_source_store");
   GError *error = NULL;
+  GList *keylist;
+
+  GRL_DEBUG ("grl_podcasts_source_store");
+
+  keylist = grl_data_get_keys (GRL_DATA (ss->media));
+
   if (GRL_IS_MEDIA_BOX (ss->media)) {
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_STORE_FAILED,
-			 "Cannot create containers. Only feeds are accepted.");
+                         GRL_CORE_ERROR_STORE_FAILED,
+                         "Cannot create containers. Only feeds are accepted.");
+  } else if (!grl_data_has_key (GRL_DATA (ss->media), GRL_METADATA_KEY_URL)) {
+    error = g_error_new (GRL_CORE_ERROR,
+                         GRL_CORE_ERROR_STORE_FAILED,
+                         "Cannot store podcast. URL required");
   } else {
     store_podcast (GRL_PODCASTS_SOURCE (ss->source),
-		   ss->media,
-		   &error);
+                   &keylist,
+                   ss->media,
+                   &error);
   }
-  ss->callback (ss->source, ss->parent, ss->media, ss->user_data, error);
+
+  ss->callback (ss->source, ss->media, keylist, ss->user_data, error);
   if (error) {
     g_error_free (error);
   }
 }
 
 static void
-grl_podcasts_source_remove (GrlMediaSource *source,
-                            GrlMediaSourceRemoveSpec *rs)
+grl_podcasts_source_remove (GrlSource *source,
+                            GrlSourceRemoveSpec *rs)
 {
-  GRL_DEBUG ("grl_podcasts_source_remove");
+  GRL_DEBUG (__FUNCTION__);
   GError *error = NULL;
   if (media_id_is_podcast (rs->media_id)) {
     remove_podcast (GRL_PODCASTS_SOURCE (rs->source),
@@ -1792,7 +1821,7 @@ grl_podcasts_source_remove (GrlMediaSource *source,
 }
 
 static gboolean
-grl_podcasts_source_notify_change_start (GrlMediaSource *source,
+grl_podcasts_source_notify_change_start (GrlSource *source,
                                          GError **error)
 {
   GrlPodcastsSource *podcasts_source = GRL_PODCASTS_SOURCE (source);
@@ -1803,7 +1832,7 @@ grl_podcasts_source_notify_change_start (GrlMediaSource *source,
 }
 
 static gboolean
-grl_podcasts_source_notify_change_stop (GrlMediaSource *source,
+grl_podcasts_source_notify_change_stop (GrlSource *source,
                                         GError **error)
 {
   GrlPodcastsSource *podcasts_source = GRL_PODCASTS_SOURCE (source);
diff --git a/src/media/podcasts/grl-podcasts.h b/src/media/podcasts/grl-podcasts.h
index 039ba64..67c258e 100644
--- a/src/media/podcasts/grl-podcasts.h
+++ b/src/media/podcasts/grl-podcasts.h
@@ -56,7 +56,7 @@ typedef struct _GrlPodcastsSource  GrlPodcastsSource;
 
 struct _GrlPodcastsSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlPodcastsPrivate *priv;
@@ -66,7 +66,7 @@ typedef struct _GrlPodcastsSourceClass GrlPodcastsSourceClass;
 
 struct _GrlPodcastsSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/shoutcast/grl-shoutcast.c b/src/media/shoutcast/grl-shoutcast.c
index 719daf0..e502976 100644
--- a/src/media/shoutcast/grl-shoutcast.c
+++ b/src/media/shoutcast/grl-shoutcast.c
@@ -75,9 +75,9 @@ struct _GrlShoutcastSourcePriv {
 
 typedef struct {
   GrlMedia *media;
-  GrlMediaSource *source;
-  GrlMediaSourceMetadataCb metadata_cb;
-  GrlMediaSourceResultCb result_cb;
+  GrlSource *source;
+  GrlSourceResolveCb resolve_cb;
+  GrlSourceResultCb result_cb;
   gboolean cancelled;
   gboolean cache;
   gchar *filter_entry;
@@ -103,14 +103,14 @@ static const GList *grl_shoutcast_source_supported_keys (GrlSource *source);
 static GrlCaps * grl_shoutcast_source_get_caps (GrlSource *source,
                                                 GrlSupportedOps operation);
 
-static void grl_shoutcast_source_metadata (GrlMediaSource *source,
-                                           GrlMediaSourceMetadataSpec *ms);
+static void grl_shoutcast_source_resolve (GrlSource *source,
+                                          GrlSourceResolveSpec *rs);
 
-static void grl_shoutcast_source_browse (GrlMediaSource *source,
-                                         GrlMediaSourceBrowseSpec *bs);
+static void grl_shoutcast_source_browse (GrlSource *source,
+                                         GrlSourceBrowseSpec *bs);
 
-static void grl_shoutcast_source_search (GrlMediaSource *source,
-                                         GrlMediaSourceSearchSpec *ss);
+static void grl_shoutcast_source_search (GrlSource *source,
+                                         GrlSourceSearchSpec *ss);
 
 static void grl_shoutcast_source_cancel (GrlSource *source,
                                          guint operation_id);
@@ -176,7 +176,7 @@ grl_shoutcast_source_new (const gchar *dev_key)
 {
   GrlShoutcastSource *source;
 
-  GRL_DEBUG ("grl_shoutcast_source_new");
+  GRL_DEBUG (__FUNCTION__);
 
   source =  g_object_new (GRL_SHOUTCAST_SOURCE_TYPE,
                           "source-id", SOURCE_ID,
@@ -194,17 +194,15 @@ grl_shoutcast_source_class_init (GrlShoutcastSourceClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   gobject_class->finalize = grl_shoutcast_source_finalize;
 
   source_class->cancel = grl_shoutcast_source_cancel;
   source_class->supported_keys = grl_shoutcast_source_supported_keys;
   source_class->get_caps = grl_shoutcast_source_get_caps;
-
-  media_class->metadata = grl_shoutcast_source_metadata;
-  media_class->browse = grl_shoutcast_source_browse;
-  media_class->search = grl_shoutcast_source_search;
+  source_class->resolve = grl_shoutcast_source_resolve;
+  source_class->browse = grl_shoutcast_source_browse;
+  source_class->search = grl_shoutcast_source_search;
 
   g_type_class_add_private (klass, sizeof (GrlShoutcastSourcePriv));
 }
@@ -216,7 +214,7 @@ grl_shoutcast_source_init (GrlShoutcastSource *source)
   source->priv->cached_page_expired = TRUE;
 }
 
-G_DEFINE_TYPE (GrlShoutcastSource, grl_shoutcast_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlShoutcastSource, grl_shoutcast_source, GRL_TYPE_SOURCE);
 
 static void
 grl_shoutcast_source_finalize (GObject *object)
@@ -472,11 +470,11 @@ xml_parse_result (const gchar *str, OperationData *op_data)
                            "Can not build xpath context");
     }
 
-    op_data->metadata_cb (op_data->source,
-                          op_data->operation_id,
-                          op_data->media,
-                          op_data->user_data,
-                          error);
+    op_data->resolve_cb (op_data->source,
+                         op_data->operation_id,
+                         op_data->media,
+                         op_data->user_data,
+                         error);
     goto free_resources;
   }
 
@@ -634,8 +632,8 @@ grl_shoutcast_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_shoutcast_source_metadata (GrlMediaSource *source,
-                               GrlMediaSourceMetadataSpec *ms)
+grl_shoutcast_source_resolve (GrlSource *source,
+                              GrlSourceResolveSpec *rs)
 {
   const gchar *media_id;
   gchar **id_tokens;
@@ -650,20 +648,20 @@ grl_shoutcast_source_metadata (GrlMediaSource *source,
      repeat the Pop browsing and get the result with station id 1321. If it
      doesn't exist (think in results obtained from a search), we do nothing */
 
-  media_id = grl_media_get_id (ms->media);
+  media_id = grl_media_get_id (rs->media);
 
   /* Check if we need to report about root category */
   if (!media_id) {
-    grl_media_set_title (ms->media, "SHOUTcast");
+    grl_media_set_title (rs->media, "SHOUTcast");
   } else {
     data = g_slice_new0 (OperationData);
     data->source = source;
     data->count = 1;
-    data->metadata_cb = ms->callback;
-    data->user_data = ms->user_data;
-    data->error_code = GRL_CORE_ERROR_METADATA_FAILED;
-    data->media = ms->media;
-    data->operation_id = ms->metadata_id;
+    data->resolve_cb = rs->callback;
+    data->user_data = rs->user_data;
+    data->error_code = GRL_CORE_ERROR_RESOLVE_FAILED;
+    data->media = rs->media;
+    data->operation_id = rs->operation_id;
 
     id_tokens = g_strsplit (media_id, "/", -1);
 
@@ -697,13 +695,13 @@ grl_shoutcast_source_metadata (GrlMediaSource *source,
     read_url_async (shoutcast_source, url, data);
     g_free (url);
   } else {
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   }
 }
 
 static void
-grl_shoutcast_source_browse (GrlMediaSource *source,
-                             GrlMediaSourceBrowseSpec *bs)
+grl_shoutcast_source_browse (GrlSource *source,
+                             GrlSourceBrowseSpec *bs)
 {
   OperationData *data;
   const gchar *container_id;
@@ -714,7 +712,7 @@ grl_shoutcast_source_browse (GrlMediaSource *source,
 
   data = g_slice_new0 (OperationData);
   data->source = source;
-  data->operation_id = bs->browse_id;
+  data->operation_id = bs->operation_id;
   data->result_cb = bs->callback;
   data->skip = grl_operation_options_get_skip (bs->options);
   data->count = grl_operation_options_get_count (bs->options);
@@ -736,7 +734,7 @@ grl_shoutcast_source_browse (GrlMediaSource *source,
     data->genre = g_strdup (container_id);
   }
 
-  grl_operation_set_data (bs->browse_id, data);
+  grl_operation_set_data (bs->operation_id, data);
 
   read_url_async (shoutcast_source, url, data);
 
@@ -744,8 +742,8 @@ grl_shoutcast_source_browse (GrlMediaSource *source,
 }
 
 static void
-grl_shoutcast_source_search (GrlMediaSource *source,
-                             GrlMediaSourceSearchSpec *ss)
+grl_shoutcast_source_search (GrlSource *source,
+                             GrlSourceSearchSpec *ss)
 {
   GError *error;
   OperationData *data;
@@ -758,7 +756,7 @@ grl_shoutcast_source_search (GrlMediaSource *source,
                          GRL_CORE_ERROR_SEARCH_FAILED,
                          "Search text not specified");
     ss->callback (ss->source,
-                  ss->search_id,
+                  ss->operation_id,
                   NULL,
                   0,
                   ss->user_data,
@@ -770,14 +768,14 @@ grl_shoutcast_source_search (GrlMediaSource *source,
 
   data = g_slice_new0 (OperationData);
   data->source = source;
-  data->operation_id = ss->search_id;
+  data->operation_id = ss->operation_id;
   data->result_cb = ss->callback;
   data->skip = grl_operation_options_get_skip (ss->options);
   data->count = grl_operation_options_get_count (ss->options);
   data->user_data = ss->user_data;
   data->error_code = GRL_CORE_ERROR_SEARCH_FAILED;
 
-  grl_operation_set_data (ss->search_id, data);
+  grl_operation_set_data (ss->operation_id, data);
 
   url = g_strdup_printf (SHOUTCAST_SEARCH_RADIOS,
                          shoutcast_source->priv->dev_key,
diff --git a/src/media/shoutcast/grl-shoutcast.h b/src/media/shoutcast/grl-shoutcast.h
index 7e89c15..e28b635 100644
--- a/src/media/shoutcast/grl-shoutcast.h
+++ b/src/media/shoutcast/grl-shoutcast.h
@@ -58,7 +58,7 @@ typedef struct _GrlShoutcastSourcePriv GrlShoutcastSourcePriv;
 
 struct _GrlShoutcastSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
   GrlShoutcastSourcePriv *priv;
 };
 
@@ -66,7 +66,7 @@ typedef struct _GrlShoutcastSourceClass GrlShoutcastSourceClass;
 
 struct _GrlShoutcastSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/tracker/grl-tracker-media-api.c b/src/media/tracker/grl-tracker-media-api.c
index 494cf50..9082883 100644
--- a/src/media/tracker/grl-tracker-media-api.c
+++ b/src/media/tracker/grl-tracker-media-api.c
@@ -250,9 +250,9 @@ fill_grilo_media_from_sparql (GrlTrackerMedia    *source,
     GRL_ODEBUG ("%s", __FUNCTION__);                                    \
                                                                         \
     if (g_cancellable_is_cancelled (os->cancel)) {                      \
-      GRL_ODEBUG ("\tOperation %u cancelled", spec->name##_id);         \
-      spec->callback (spec->source,                                     \
-                      spec->name##_id,                                  \
+      GRL_ODEBUG ("\tOperation %u cancelled", spec->operation_id);      \
+      spec->callback (spec->source,                        \
+                      spec->operation_id,                               \
                       NULL, 0,                                          \
                       spec->user_data, NULL);                           \
       grl_tracker_queue_done (grl_tracker_queue, os);                   \
@@ -265,27 +265,27 @@ fill_grilo_media_from_sparql (GrlTrackerMedia    *source,
                                             &tracker_error)) {          \
       if (tracker_error != NULL) {                                      \
         GRL_WARNING ("\terror in parsing query id=%u : %s",             \
-                     spec->name##_id, tracker_error->message);          \
+                     spec->operation_id, tracker_error->message);       \
                                                                         \
         error = g_error_new (GRL_CORE_ERROR,                            \
                              GRL_CORE_ERROR_BROWSE_FAILED,              \
                              "Failed to start query action : %s",       \
                              tracker_error->message);                   \
                                                                         \
-        spec->callback (spec->source,                                   \
-                        spec->name##_id,                                \
+        spec->callback (spec->source,                      \
+                        spec->operation_id,                             \
                         NULL, 0,                                        \
                         spec->user_data, error);                        \
                                                                         \
         g_error_free (error);                                           \
         g_error_free (tracker_error);                                   \
       } else {                                                          \
-        GRL_ODEBUG ("\tend of parsing id=%u :)", spec->name##_id);      \
+        GRL_ODEBUG ("\tend of parsing id=%u :)", spec->operation_id);   \
                                                                         \
         /* Only emit this last one if more result than expected */      \
         if (os->count > 1)                                              \
-          spec->callback (spec->source,                                 \
-                          spec->name##_id,                              \
+          spec->callback (spec->source,                    \
+                          spec->operation_id,                           \
                           NULL, 0,                                      \
                           spec->user_data, NULL);                       \
       }                                                                 \
@@ -312,7 +312,7 @@ fill_grilo_media_from_sparql (GrlTrackerMedia    *source,
       }                                                                 \
                                                                         \
       spec->callback (spec->source,                                     \
-                      spec->name##_id,                                  \
+                      spec->operation_id,                               \
                       media,                                            \
                       --os->count,                                      \
                       spec->user_data,                                  \
@@ -347,14 +347,14 @@ fill_grilo_media_from_sparql (GrlTrackerMedia    *source,
                                                                         \
     if (tracker_error) {                                                \
       GRL_WARNING ("Could not execute sparql query id=%u: %s",          \
-                   spec->name##_id, tracker_error->message);            \
+                   spec->operation_id, tracker_error->message);         \
                                                                         \
       error = g_error_new (GRL_CORE_ERROR,                              \
                            GRL_CORE_ERROR_BROWSE_FAILED,                \
                            "Failed to start query action : %s",         \
                            tracker_error->message);                     \
                                                                         \
-      spec->callback (spec->source, spec->name##_id, NULL, 0,           \
+      spec->callback (spec->source, spec->operation_id, NULL, 0,           \
                       spec->user_data, error);                          \
                                                                         \
       g_error_free (tracker_error);                                     \
@@ -371,20 +371,20 @@ fill_grilo_media_from_sparql (GrlTrackerMedia    *source,
                                       (gpointer) os);                   \
   }
 
-TRACKER_QUERY_CB(GrlMediaSourceQuerySpec, query)
-TRACKER_QUERY_CB(GrlMediaSourceBrowseSpec, browse)
-TRACKER_QUERY_CB(GrlMediaSourceSearchSpec, search)
+TRACKER_QUERY_CB(GrlSourceQuerySpec, query)
+TRACKER_QUERY_CB(GrlSourceBrowseSpec, browse)
+TRACKER_QUERY_CB(GrlSourceSearchSpec, search)
 
 static void
 tracker_metadata_cb (GObject      *source_object,
                      GAsyncResult *result,
                      GrlTrackerOp *os)
 {
-  GrlMediaSourceMetadataSpec *ms            = (GrlMediaSourceMetadataSpec *) os->data;
-  GrlTrackerMediaPriv        *priv          = GRL_TRACKER_MEDIA_GET_PRIVATE (ms->source);
-  gint                        col;
-  GError                     *tracker_error = NULL, *error = NULL;
-  TrackerSparqlCursor        *cursor;
+  GrlSourceResolveSpec  *rs            = (GrlSourceResolveSpec *) os->data;
+  GrlTrackerMediaPriv   *priv          = GRL_TRACKER_MEDIA_GET_PRIVATE (rs->source);
+  gint                  col;
+  GError                *tracker_error = NULL, *error = NULL;
+  TrackerSparqlCursor   *cursor;
 
   GRL_ODEBUG ("%s", __FUNCTION__);
 
@@ -393,14 +393,14 @@ tracker_metadata_cb (GObject      *source_object,
 
   if (tracker_error) {
     GRL_WARNING ("Could not execute sparql query id=%u : %s",
-                 ms->metadata_id, tracker_error->message);
+                 rs->operation_id, tracker_error->message);
 
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_BROWSE_FAILED,
 			 "Failed to start metadata action : %s",
                          tracker_error->message);
 
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
 
     g_error_free (tracker_error);
     g_error_free (error);
@@ -412,11 +412,11 @@ tracker_metadata_cb (GObject      *source_object,
   if (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
     /* Translate Sparql result into Grilo result */
     for (col = 0 ; col < tracker_sparql_cursor_get_n_columns (cursor) ; col++) {
-      fill_grilo_media_from_sparql (GRL_TRACKER_MEDIA (ms->source),
-                                    ms->media, cursor, col);
+      fill_grilo_media_from_sparql (GRL_TRACKER_MEDIA (rs->source),
+                                    rs->media, cursor, col);
     }
 
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   }
 
  end_operation:
@@ -426,39 +426,39 @@ tracker_metadata_cb (GObject      *source_object,
   grl_tracker_queue_done (grl_tracker_queue, os);
 }
 
-/* static void */
-/* tracker_set_metadata_cb (GObject      *source_object, */
-/*                          GAsyncResult *result, */
-/*                          GrlTrackerOp *os) */
-/* { */
-/*   GrlMetadataSourceSetMetadataSpec *sms = */
-/*     (GrlMetadataSourceSetMetadataSpec *) os->data; */
-/*   GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (sms->source); */
-/*   GError *tracker_error = NULL, *error = NULL; */
+static void
+tracker_store_metadata_cb (GObject      *source_object,
+                           GAsyncResult *result,
+                           GrlTrackerOp *os)
+{
+  GrlSourceStoreMetadataSpec *sms =
+    (GrlSourceStoreMetadataSpec *) os->data;
+  GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (sms->source);
+  GError *tracker_error = NULL, *error = NULL;
 
-/*   tracker_sparql_connection_update_finish (priv->tracker_connection, */
-/*                                            result, */
-/*                                            &tracker_error); */
+  tracker_sparql_connection_update_finish (priv->tracker_connection,
+                                           result,
+                                           &tracker_error);
 
-/*   if (tracker_error) { */
-/*     GRL_WARNING ("Could not execute sparql update : %s", */
-/*                  tracker_error->message); */
+  if (tracker_error) {
+    GRL_WARNING ("Could not execute sparql update : %s",
+                 tracker_error->message);
 
-/*     error = g_error_new (GRL_CORE_ERROR, */
-/* 			 GRL_CORE_ERROR_SET_METADATA_FAILED, */
-/* 			 "Failed to set metadata : %s", */
-/*                          tracker_error->message); */
+    error = g_error_new (GRL_CORE_ERROR,
+                         GRL_CORE_ERROR_STORE_METADATA_FAILED,
+                         "Failed to set metadata : %s",
+                         tracker_error->message);
 
-/*     sms->callback (sms->source, sms->media, NULL, sms->user_data, error); */
+    sms->callback (sms->source, sms->media, NULL, sms->user_data, error);
 
-/*     g_error_free (tracker_error); */
-/*     g_error_free (error); */
-/*   } else { */
-/*     sms->callback (sms->source, sms->media, NULL, sms->user_data, error); */
-/*   } */
+    g_error_free (tracker_error);
+    g_error_free (error);
+  } else {
+    sms->callback (sms->source, sms->media, NULL, sms->user_data, error);
+  }
 
-/*   grl_tracker_queue_done (grl_tracker_queue, os); */
-/* } */
+  grl_tracker_queue_done (grl_tracker_queue, os);
+}
 
 /**/
 
@@ -546,8 +546,8 @@ grl_tracker_media_writable_keys (GrlSource *source)
  * the query spec.
  */
 void
-grl_tracker_media_query (GrlMediaSource *source,
-                         GrlMediaSourceQuerySpec *qs)
+grl_tracker_media_query (GrlSource *source,
+                         GrlSourceQuerySpec *qs)
 {
   GError               *error = NULL;
   GrlTrackerMediaPriv *priv  = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
@@ -558,7 +558,7 @@ grl_tracker_media_query (GrlMediaSource *source,
   gint count = grl_operation_options_get_count (qs->options);
   guint skip = grl_operation_options_get_skip (qs->options);
 
-  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, qs->query_id);
+  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, qs->operation_id);
 
   if (!qs->query || qs->query[0] == '\0') {
     error = g_error_new_literal (GRL_CORE_ERROR,
@@ -587,7 +587,7 @@ grl_tracker_media_query (GrlMediaSource *source,
 
   GRL_IDEBUG ("\tselect : '%s'", qs->query);
 
-  os = grl_tracker_op_initiate_query (qs->query_id,
+  os = grl_tracker_op_initiate_query (qs->operation_id,
                                       g_strdup (qs->query),
                                       (GAsyncReadyCallback) tracker_query_cb,
                                       qs);
@@ -604,44 +604,44 @@ grl_tracker_media_query (GrlMediaSource *source,
   return;
 
  send_error:
-  qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
+  qs->callback (qs->source, qs->operation_id, NULL, 0, qs->user_data, error);
   g_error_free (error);
 }
 
 void
-grl_tracker_media_metadata (GrlMediaSource *source,
-                            GrlMediaSourceMetadataSpec *ms)
+grl_tracker_media_resolve (GrlSource *source,
+                           GrlSourceResolveSpec *rs)
 {
   GrlTrackerMediaPriv *priv       = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
   gchar               *constraint = NULL, *sparql_select, *sparql_final;
   GrlTrackerOp        *os;
 
-  GRL_IDEBUG ("%s: id=%i", __FUNCTION__, ms->metadata_id);
+  GRL_IDEBUG ("%s: id=%i", __FUNCTION__, rs->operation_id);
 
-  if (grl_media_get_id (ms->media) == NULL) {
+  if (grl_media_get_id (rs->media) == NULL) {
     if (grl_tracker_per_device_source) {
       constraint = grl_tracker_media_get_device_constraint (priv);
-      sparql_select = grl_tracker_media_get_select_string (ms->keys);
+      sparql_select = grl_tracker_media_get_select_string (rs->keys);
       sparql_final = g_strdup_printf (TRACKER_BROWSE_FILESYSTEM_ROOT_REQUEST,
                                       sparql_select,
                                       grl_tracker_show_documents? TRACKER_BROWSE_SHOW_DOCUMENTS: "",
                                       constraint, 0, 1);
     } else {
-      ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+      rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
       return;
     }
   } else {
-    sparql_select = grl_tracker_media_get_select_string (ms->keys);
+    sparql_select = grl_tracker_media_get_select_string (rs->keys);
     sparql_final = g_strdup_printf (TRACKER_METADATA_REQUEST, sparql_select,
-                                    grl_media_get_id (ms->media));
+                                    grl_media_get_id (rs->media));
   }
 
   GRL_IDEBUG ("\tselect: '%s'", sparql_final);
 
   os = grl_tracker_op_initiate_metadata (sparql_final,
                                          (GAsyncReadyCallback) tracker_metadata_cb,
-                                         ms);
-  os->keys = ms->keys;
+                                         rs);
+  os->keys = rs->keys;
 
   grl_tracker_queue_push (grl_tracker_queue, os);
 
@@ -651,42 +651,42 @@ grl_tracker_media_metadata (GrlMediaSource *source,
     g_free (sparql_select);
 }
 
-/* void */
-/* grl_tracker_media_set_metadata (GrlMetadataSource *source, */
-/*                                 GrlMetadataSourceSetMetadataSpec *sms) */
-/* { */
-/*   /\* GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source); *\/ */
-/*   gchar *sparql_delete, *sparql_cdelete, *sparql_insert, *sparql_final; */
-/*   const gchar *urn = grl_data_get_string (GRL_DATA (sms->media), */
-/*                                           grl_metadata_key_tracker_urn); */
-/*   GrlTrackerOp *os; */
+void
+grl_tracker_media_store_metadata (GrlSource *source,
+                                  GrlSourceStoreMetadataSpec *sms)
+{
+  /* GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source); */
+  gchar *sparql_delete, *sparql_cdelete, *sparql_insert, *sparql_final;
+  const gchar *urn = grl_data_get_string (GRL_DATA (sms->media),
+                                          grl_metadata_key_tracker_urn);
+  GrlTrackerOp *os;
 
-/*   GRL_IDEBUG ("%s: urn=%s", G_STRFUNC, urn); */
+  GRL_IDEBUG ("%s: urn=%s", G_STRFUNC, urn);
 
-/*   sparql_delete = grl_tracker_get_delete_string (sms->keys); */
-/*   sparql_cdelete = grl_tracker_get_delete_conditional_string (urn, sms->keys); */
-/*   sparql_insert = grl_tracker_tracker_get_insert_string (sms->media, sms->keys); */
-/*   sparql_final = g_strdup_printf (TRACKER_SAVE_REQUEST, */
-/*                                   urn, sparql_delete, */
-/*                                   urn, sparql_cdelete, */
-/*                                   urn, sparql_insert); */
+  sparql_delete = grl_tracker_get_delete_string (sms->keys);
+  sparql_cdelete = grl_tracker_get_delete_conditional_string (urn, sms->keys);
+  sparql_insert = grl_tracker_tracker_get_insert_string (sms->media, sms->keys);
+  sparql_final = g_strdup_printf (TRACKER_SAVE_REQUEST,
+                                  urn, sparql_delete,
+                                  urn, sparql_cdelete,
+                                  urn, sparql_insert);
 
-/*   os = grl_tracker_op_initiate_set_metadata (sparql_final, */
-/*                                              (GAsyncReadyCallback) tracker_set_metadata_cb, */
-/*                                              sms); */
-/*   os->keys = sms->keys; */
+  os = grl_tracker_op_initiate_set_metadata (sparql_final,
+                                             (GAsyncReadyCallback) tracker_store_metadata_cb,
+                                             sms);
+  os->keys = sms->keys;
 
-/*   GRL_IDEBUG ("\trequest: '%s'", sparql_final); */
+  GRL_IDEBUG ("\trequest: '%s'", sparql_final);
 
-/*   grl_tracker_queue_push (grl_tracker_queue, os); */
+  grl_tracker_queue_push (grl_tracker_queue, os);
 
-/*   g_free (sparql_delete); */
-/*   g_free (sparql_cdelete); */
-/*   g_free (sparql_insert); */
-/* } */
+  g_free (sparql_delete);
+  g_free (sparql_cdelete);
+  g_free (sparql_insert);
+}
 
 void
-grl_tracker_media_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
+grl_tracker_media_search (GrlSource *source, GrlSourceSearchSpec *ss)
 {
   GrlTrackerMediaPriv *priv  = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
   gchar                *constraint;
@@ -696,7 +696,7 @@ grl_tracker_media_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
   gint count = grl_operation_options_get_count (ss->options);
   guint skip = grl_operation_options_get_skip (ss->options);
 
-  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, ss->search_id);
+  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, ss->operation_id);
 
   constraint = grl_tracker_media_get_device_constraint (priv);
   sparql_select = grl_tracker_media_get_select_string (ss->keys);
@@ -711,7 +711,7 @@ grl_tracker_media_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
 
   GRL_IDEBUG ("\tselect: '%s'", sparql_final);
 
-  os = grl_tracker_op_initiate_query (ss->search_id,
+  os = grl_tracker_op_initiate_query (ss->operation_id,
                                       sparql_final,
                                       (GAsyncReadyCallback) tracker_search_cb,
                                       ss);
@@ -726,8 +726,8 @@ grl_tracker_media_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
 }
 
 static void
-grl_tracker_media_browse_category (GrlMediaSource *source,
-                                   GrlMediaSourceBrowseSpec *bs)
+grl_tracker_media_browse_category (GrlSource *source,
+                                   GrlSourceBrowseSpec *bs)
 {
   GrlTrackerMediaPriv *priv  = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
   gchar                *constraint;
@@ -739,7 +739,7 @@ grl_tracker_media_browse_category (GrlMediaSource *source,
   gint count = grl_operation_options_get_count (bs->options);
   guint skip = grl_operation_options_get_skip (bs->options);
 
-  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->browse_id);
+  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->operation_id);
 
   if (bs->container == NULL ||
       !grl_data_has_key (GRL_DATA (bs->container),
@@ -751,7 +751,7 @@ grl_tracker_media_browse_category (GrlMediaSource *source,
       grl_data_set_string (GRL_DATA (media),
                            grl_metadata_key_tracker_category,
                            "nfo:Document");
-      bs->callback (bs->source, bs->browse_id, media, 3, bs->user_data, NULL);
+      bs->callback (bs->source, bs->operation_id, media, 3, bs->user_data, NULL);
     }
 
     media = grl_media_box_new ();
@@ -759,21 +759,21 @@ grl_tracker_media_browse_category (GrlMediaSource *source,
     grl_data_set_string (GRL_DATA (media),
                          grl_metadata_key_tracker_category,
                          "nmm:MusicPiece");
-    bs->callback (bs->source, bs->browse_id, media, 2, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, media, 2, bs->user_data, NULL);
 
     media = grl_media_box_new ();
     grl_media_set_title (media, "Photos");
     grl_data_set_string (GRL_DATA (media),
                          grl_metadata_key_tracker_category,
                          "nmm:Photo");
-    bs->callback (bs->source, bs->browse_id, media, 1, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, media, 1, bs->user_data, NULL);
 
     media = grl_media_box_new ();
     grl_media_set_title (media, "Videos");
     grl_data_set_string (GRL_DATA (media),
                          grl_metadata_key_tracker_category,
                          "nmm:Video");
-    bs->callback (bs->source, bs->browse_id, media, 0, bs->user_data, NULL);
+    bs->callback (bs->source, bs->operation_id, media, 0, bs->user_data, NULL);
     return;
   }
 
@@ -790,7 +790,7 @@ grl_tracker_media_browse_category (GrlMediaSource *source,
 
   GRL_IDEBUG ("\tselect: '%s'", sparql_final);
 
-  os = grl_tracker_op_initiate_query (bs->browse_id,
+  os = grl_tracker_op_initiate_query (bs->operation_id,
                                       sparql_final,
                                       (GAsyncReadyCallback) tracker_browse_cb,
                                       bs);
@@ -805,8 +805,8 @@ grl_tracker_media_browse_category (GrlMediaSource *source,
 }
 
 static void
-grl_tracker_media_browse_filesystem (GrlMediaSource *source,
-                                     GrlMediaSourceBrowseSpec *bs)
+grl_tracker_media_browse_filesystem (GrlSource *source,
+                                     GrlSourceBrowseSpec *bs)
 {
   GrlTrackerMediaPriv *priv  = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
   gchar                *constraint;
@@ -816,7 +816,7 @@ grl_tracker_media_browse_filesystem (GrlMediaSource *source,
   gint count = grl_operation_options_get_count (bs->options);
   guint skip = grl_operation_options_get_skip (bs->options);
 
-  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->browse_id);
+  GRL_IDEBUG ("%s: id=%u", __FUNCTION__, bs->operation_id);
 
   sparql_select = grl_tracker_media_get_select_string (bs->keys);
   constraint = grl_tracker_media_get_device_constraint (priv);
@@ -840,7 +840,7 @@ grl_tracker_media_browse_filesystem (GrlMediaSource *source,
 
   GRL_IDEBUG ("\tselect: '%s'", sparql_final);
 
-  os = grl_tracker_op_initiate_query (bs->browse_id,
+  os = grl_tracker_op_initiate_query (bs->operation_id,
                                       sparql_final,
                                       (GAsyncReadyCallback) tracker_browse_cb,
                                       bs);
@@ -855,8 +855,8 @@ grl_tracker_media_browse_filesystem (GrlMediaSource *source,
 }
 
 void
-grl_tracker_media_browse (GrlMediaSource *source,
-                          GrlMediaSourceBrowseSpec *bs)
+grl_tracker_media_browse (GrlSource *source,
+                          GrlSourceBrowseSpec *bs)
 {
   if (grl_tracker_browse_filesystem)
     grl_tracker_media_browse_filesystem (source, bs);
@@ -879,7 +879,7 @@ grl_tracker_media_cancel (GrlSource *source, guint operation_id)
 }
 
 gboolean
-grl_tracker_media_change_start (GrlMediaSource *source, GError **error)
+grl_tracker_media_change_start (GrlSource *source, GError **error)
 {
   GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
 
@@ -889,7 +889,7 @@ grl_tracker_media_change_start (GrlMediaSource *source, GError **error)
 }
 
 gboolean
-grl_tracker_media_change_stop (GrlMediaSource *source, GError **error)
+grl_tracker_media_change_stop (GrlSource *source, GError **error)
 {
   GrlTrackerMediaPriv *priv = GRL_TRACKER_MEDIA_GET_PRIVATE (source);
 
diff --git a/src/media/tracker/grl-tracker-media-api.h b/src/media/tracker/grl-tracker-media-api.h
index f745a67..1129066 100644
--- a/src/media/tracker/grl-tracker-media-api.h
+++ b/src/media/tracker/grl-tracker-media-api.h
@@ -34,27 +34,27 @@ void grl_tracker_media_init_requests (void);
 
 const GList *grl_tracker_media_writable_keys (GrlSource *source);
 
-void grl_tracker_media_query (GrlMediaSource *source,
-                              GrlMediaSourceQuerySpec *qs);
+void grl_tracker_media_query (GrlSource *source,
+                              GrlSourceQuerySpec *qs);
 
-void grl_tracker_media_metadata (GrlMediaSource *source,
-                                 GrlMediaSourceMetadataSpec *ms);
+void grl_tracker_media_resolve (GrlSource *source,
+                                GrlSourceResolveSpec *rs);
 
-/* void grl_tracker_media_set_metadata (GrlMetadataSource *source, */
-/*                                      GrlMetadataSourceSetMetadataSpec *sms); */
+void grl_tracker_media_store_metadata (GrlSource *source,
+                                       GrlSourceStoreMetadataSpec *sms);
 
 void grl_tracker_media_cancel (GrlSource *source, guint operation_id);
 
-void grl_tracker_media_search (GrlMediaSource *source,
-                               GrlMediaSourceSearchSpec *ss);
+void grl_tracker_media_search (GrlSource *source,
+                               GrlSourceSearchSpec *ss);
 
-void grl_tracker_media_browse (GrlMediaSource *source,
-                               GrlMediaSourceBrowseSpec *bs);
+void grl_tracker_media_browse (GrlSource *source,
+                               GrlSourceBrowseSpec *bs);
 
-gboolean grl_tracker_media_change_start (GrlMediaSource *source,
+gboolean grl_tracker_media_change_start (GrlSource *source,
                                          GError **error);
 
-gboolean grl_tracker_media_change_stop (GrlMediaSource *source,
+gboolean grl_tracker_media_change_stop (GrlSource *source,
                                         GError **error);
 
 #endif /* _GRL_TRACKER_MEDIA_API_H_ */
diff --git a/src/media/tracker/grl-tracker-media-notif.c b/src/media/tracker/grl-tracker-media-notif.c
index 935eb55..dc5e3aa 100644
--- a/src/media/tracker/grl-tracker-media-notif.c
+++ b/src/media/tracker/grl-tracker-media-notif.c
@@ -58,9 +58,9 @@ typedef struct {
   GList *old_sources;
 
   /* Convenient stuff (for tracker/own callbacks...) */
-  TrackerSparqlCursor      *cursor;
-  gboolean                  in_use;
-  GrlMediaSourceChangeType  change_type;
+  TrackerSparqlCursor  *cursor;
+  gboolean             in_use;
+  GrlSourceChangeType  change_type;
 } tracker_evt_update_t;
 
 /**/
@@ -236,8 +236,8 @@ tracker_evt_update_orphan_item_cb (GObject              *object,
         GRL_DEBUG ("\tNotify id=%u source=%s p=%p", id,
                    grl_source_get_name (GRL_SOURCE (source)),
                    source);
-        grl_media_source_notify_change (GRL_MEDIA_SOURCE (source),
-                                        media, change_type, FALSE);
+        grl_source_notify_change (GRL_SOURCE (source),
+                                  media, change_type, FALSE);
 
         g_object_unref (media);
       }
@@ -322,10 +322,10 @@ tracker_evt_update_orphans (tracker_evt_update_t *evt)
             grl_media_set_id (media, str_id);
             g_free (str_id);
 
-            grl_media_source_notify_change (GRL_MEDIA_SOURCE (source->data),
-                                            media,
-                                            GRL_CONTENT_REMOVED,
-                                            FALSE);
+            grl_source_notify_change (GRL_SOURCE (source->data),
+                                      media,
+                                      GRL_CONTENT_REMOVED,
+                                      FALSE);
             g_object_unref (media);
           }
         }
@@ -386,8 +386,7 @@ tracker_evt_update_items_cb (gpointer              key,
 
   GRL_DEBUG ("\tNotify id=%u source=%s", id,
              grl_source_get_name (GRL_SOURCE (source)));
-  grl_media_source_notify_change (GRL_MEDIA_SOURCE (source), media,
-                                  evt->change_type, FALSE);
+  grl_source_notify_change (GRL_SOURCE (source), media, evt->change_type, FALSE);
 
   g_object_unref (media);
 }
diff --git a/src/media/tracker/grl-tracker-media.c b/src/media/tracker/grl-tracker-media.c
index 236393a..ae5b391 100644
--- a/src/media/tracker/grl-tracker-media.c
+++ b/src/media/tracker/grl-tracker-media.c
@@ -74,7 +74,7 @@ GHashTable *grl_tracker_media_sources;
 
 /* ================== TrackerMedia GObject ================ */
 
-G_DEFINE_TYPE (GrlTrackerMedia, grl_tracker_media, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlTrackerMedia, grl_tracker_media, GRL_TYPE_SOURCE);
 
 static GrlTrackerMedia *
 grl_tracker_media_new (TrackerSparqlConnection *connection)
@@ -95,22 +95,20 @@ grl_tracker_media_class_init (GrlTrackerMediaClass * klass)
 {
   GObjectClass        *g_class      = G_OBJECT_CLASS (klass);
   GrlSourceClass      *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class  = GRL_MEDIA_SOURCE_CLASS (klass);
 
   g_class->finalize     = grl_tracker_media_finalize;
   g_class->set_property = grl_tracker_media_set_property;
 
-  source_class->cancel         = grl_tracker_media_cancel;
-  source_class->supported_keys = grl_tracker_supported_keys;
-  source_class->writable_keys  = grl_tracker_media_writable_keys;
-  /* source_class->set_metadata   = grl_tracker_media_set_metadata; */
-
-  media_class->query               = grl_tracker_media_query;
-  media_class->metadata            = grl_tracker_media_metadata;
-  media_class->search              = grl_tracker_media_search;
-  media_class->browse              = grl_tracker_media_browse;
-  media_class->notify_change_start = grl_tracker_media_change_start;
-  media_class->notify_change_stop  = grl_tracker_media_change_stop;
+  source_class->cancel              = grl_tracker_media_cancel;
+  source_class->supported_keys      = grl_tracker_supported_keys;
+  source_class->writable_keys       = grl_tracker_media_writable_keys;
+  source_class->store_metadata      = grl_tracker_media_store_metadata;
+  source_class->query               = grl_tracker_media_query;
+  source_class->resolve             = grl_tracker_media_resolve;
+  source_class->search              = grl_tracker_media_search;
+  source_class->browse              = grl_tracker_media_browse;
+  source_class->notify_change_start = grl_tracker_media_change_start;
+  source_class->notify_change_stop  = grl_tracker_media_change_stop;
 
 
   g_object_class_install_property (g_class,
diff --git a/src/media/tracker/grl-tracker-media.h b/src/media/tracker/grl-tracker-media.h
index 78e0fad..b6ded43 100644
--- a/src/media/tracker/grl-tracker-media.h
+++ b/src/media/tracker/grl-tracker-media.h
@@ -59,7 +59,7 @@ typedef struct _GrlTrackerMediaPriv GrlTrackerMediaPriv;
 
 struct _GrlTrackerMedia {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlTrackerMediaPriv *priv;
@@ -70,7 +70,7 @@ typedef struct _GrlTrackerMediaClass GrlTrackerMediaClass;
 
 struct _GrlTrackerMediaClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/tracker/grl-tracker-metadata.c b/src/media/tracker/grl-tracker-metadata.c
index e001be8..786908b 100644
--- a/src/media/tracker/grl-tracker-metadata.c
+++ b/src/media/tracker/grl-tracker-metadata.c
@@ -88,17 +88,17 @@ static void grl_tracker_metadata_set_property (GObject      *object,
 
 static void grl_tracker_metadata_finalize (GObject *object);
 
-static gboolean grl_tracker_metadata_may_resolve (GrlMetadataSource  *source,
-                                                  GrlMedia           *media,
-                                                  GrlKeyID            key_id,
-                                                  GList             **missing_keys);
+static gboolean grl_tracker_metadata_may_resolve (GrlSource *source,
+                                                  GrlMedia  *media,
+                                                  GrlKeyID  key_id,
+                                                  GList     **missing_keys);
 
-static void grl_tracker_metadata_resolve (GrlMetadataSource            *source,
-                                          GrlMetadataSourceResolveSpec *rs);
+static void grl_tracker_metadata_resolve (GrlSource            *source,
+                                          GrlSourceResolveSpec *rs);
 
 /* ================== TrackerMetadata GObject ================ */
 
-G_DEFINE_TYPE (GrlTrackerMetadata, grl_tracker_metadata, GRL_TYPE_METADATA_SOURCE);
+G_DEFINE_TYPE (GrlTrackerMetadata, grl_tracker_metadata, GRL_TYPE_SOURCE);
 
 static GrlTrackerMetadata *
 grl_tracker_metadata_new (TrackerSparqlConnection *connection)
@@ -118,17 +118,15 @@ grl_tracker_metadata_class_init (GrlTrackerMetadataClass * klass)
 {
   GObjectClass           *g_class        = G_OBJECT_CLASS (klass);
   GrlSourceClass         *source_class   = GRL_SOURCE_CLASS (klass);
-  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
 
   g_class->finalize     = grl_tracker_metadata_finalize;
   g_class->set_property = grl_tracker_metadata_set_property;
 
-  source_class->supported_keys = grl_tracker_supported_keys;
+  source_class->supported_keys   = grl_tracker_supported_keys;
+  source_class->may_resolve    = grl_tracker_metadata_may_resolve;
+  source_class->resolve        = grl_tracker_metadata_resolve;
   source_class->get_caps       = grl_tracker_get_caps;
 
-  metadata_class->may_resolve = grl_tracker_metadata_may_resolve;
-  metadata_class->resolve     = grl_tracker_metadata_resolve;
-
   g_object_class_install_property (g_class,
                                    PROP_TRACKER_CONNECTION,
                                    g_param_spec_object ("tracker-connection",
@@ -251,7 +249,7 @@ tracker_resolve_cb (GObject      *source_object,
                     GAsyncResult *result,
                     GrlTrackerOp *os)
 {
-  GrlMetadataSourceResolveSpec *rs = (GrlMetadataSourceResolveSpec *) os->data;
+  GrlSourceResolveSpec   *rs = (GrlSourceResolveSpec *) os->data;
   GrlTrackerMetadataPriv *priv = GRL_TRACKER_METADATA_GET_PRIVATE (rs->source);
   gint                  col;
   GError               *tracker_error = NULL, *error = NULL;
@@ -271,7 +269,7 @@ tracker_resolve_cb (GObject      *source_object,
 			 "Failed to start resolve action : %s",
                          tracker_error->message);
 
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
 
     g_error_free (tracker_error);
     g_error_free (error);
@@ -286,9 +284,9 @@ tracker_resolve_cb (GObject      *source_object,
       fill_grilo_media_from_sparql (rs->media, cursor, col);
     }
 
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   }
 
  end_operation:
@@ -302,10 +300,10 @@ tracker_resolve_cb (GObject      *source_object,
 /**/
 
 static gboolean
-grl_tracker_metadata_may_resolve (GrlMetadataSource  *source,
-                                  GrlMedia           *media,
-                                  GrlKeyID            key_id,
-                                  GList             **missing_keys)
+grl_tracker_metadata_may_resolve (GrlSource *source,
+                                  GrlMedia  *media,
+                                  GrlKeyID  key_id,
+                                  GList     **missing_keys)
 {
   GRL_IDEBUG ("%s: key=%s", __FUNCTION__, GRL_METADATA_KEY_GET_NAME (key_id));
 
@@ -327,8 +325,8 @@ grl_tracker_metadata_may_resolve (GrlMetadataSource  *source,
 
 
 static void
-grl_tracker_metadata_resolve (GrlMetadataSource            *source,
-                              GrlMetadataSourceResolveSpec *rs)
+grl_tracker_metadata_resolve (GrlSource            *source,
+                              GrlSourceResolveSpec *rs)
 {
   const gchar *url = grl_media_get_url (rs->media);
   gchar *sparql_select, *sparql_final;
diff --git a/src/media/tracker/grl-tracker-metadata.h b/src/media/tracker/grl-tracker-metadata.h
index 8720779..0b59476 100644
--- a/src/media/tracker/grl-tracker-metadata.h
+++ b/src/media/tracker/grl-tracker-metadata.h
@@ -72,7 +72,7 @@ typedef struct _GrlTrackerMetadataPriv GrlTrackerMetadataPriv;
 
 struct _GrlTrackerMetadata {
 
-  GrlMetadataSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlTrackerMetadataPriv *priv;
@@ -83,7 +83,7 @@ typedef struct _GrlTrackerMetadataClass GrlTrackerMetadataClass;
 
 struct _GrlTrackerMetadataClass {
 
-  GrlMetadataSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/upnp/grl-upnp.c b/src/media/upnp/grl-upnp.c
index aca89f4..c48bada 100644
--- a/src/media/upnp/grl-upnp.c
+++ b/src/media/upnp/grl-upnp.c
@@ -75,12 +75,12 @@ struct _GrlUpnpPrivate {
 };
 
 struct OperationSpec {
-  GrlMediaSource *source;
+  GrlSource *source;
   guint operation_id;
   GList *keys;
   guint skip;
   guint count;
-  GrlMediaSourceResultCb callback;
+  GrlSourceResultCb callback;
   gpointer user_data;
 };
 
@@ -106,27 +106,27 @@ static void grl_upnp_source_finalize (GObject *plugin);
 
 static const GList *grl_upnp_source_supported_keys (GrlSource *source);
 
+static GrlSupportedOps grl_upnp_source_supported_operations (GrlSource *source);
+
 static GrlCaps * grl_upnp_source_get_caps (GrlSource *source,
                                            GrlSupportedOps operation);
 
-static void grl_upnp_source_browse (GrlMediaSource *source,
-                                    GrlMediaSourceBrowseSpec *bs);
-
-static void grl_upnp_source_search (GrlMediaSource *source,
-                                    GrlMediaSourceSearchSpec *ss);
+static void grl_upnp_source_browse (GrlSource *source,
+                                    GrlSourceBrowseSpec *bs);
 
-static void grl_upnp_source_query (GrlMediaSource *source,
-                                   GrlMediaSourceQuerySpec *qs);
+static void grl_upnp_source_search (GrlSource *source,
+                                    GrlSourceSearchSpec *ss);
 
-static void grl_upnp_source_metadata (GrlMediaSource *source,
-                                      GrlMediaSourceMetadataSpec *ms);
+static void grl_upnp_source_query (GrlSource *source,
+                                   GrlSourceQuerySpec *qs);
 
-static GrlSupportedOps grl_upnp_source_supported_operations (GrlSource *source);
+static void grl_upnp_source_resolve (GrlSource *source,
+                                     GrlSourceResolveSpec *rs);
 
-static gboolean grl_upnp_source_notify_change_start (GrlMediaSource *source,
+static gboolean grl_upnp_source_notify_change_start (GrlSource *source,
                                                      GError **error);
 
-static gboolean grl_upnp_source_notify_change_stop (GrlMediaSource *source,
+static gboolean grl_upnp_source_notify_change_stop (GrlSource *source,
                                                     GError **error);
 
 static void context_available_cb (GUPnPContextManager *context_manager,
@@ -189,7 +189,7 @@ GRL_PLUGIN_REGISTER (grl_upnp_plugin_init,
 
 /* ================== UPnP GObject ================ */
 
-G_DEFINE_TYPE (GrlUpnpSource, grl_upnp_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlUpnpSource, grl_upnp_source, GRL_TYPE_SOURCE);
 
 static GrlUpnpSource *
 grl_upnp_source_new (const gchar *source_id, const gchar *name)
@@ -218,20 +218,18 @@ grl_upnp_source_class_init (GrlUpnpSourceClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   gobject_class->finalize = grl_upnp_source_finalize;
 
   source_class->supported_keys = grl_upnp_source_supported_keys;
   source_class->supported_operations = grl_upnp_source_supported_operations;
   source_class->get_caps = grl_upnp_source_get_caps;
-
-  media_class->browse = grl_upnp_source_browse;
-  media_class->search = grl_upnp_source_search;
-  media_class->query = grl_upnp_source_query;
-  media_class->metadata = grl_upnp_source_metadata;
-  media_class->notify_change_start = grl_upnp_source_notify_change_start;
-  media_class->notify_change_stop = grl_upnp_source_notify_change_stop;
+  source_class->browse = grl_upnp_source_browse;
+  source_class->search = grl_upnp_source_search;
+  source_class->query = grl_upnp_source_query;
+  source_class->resolve = grl_upnp_source_resolve;
+  source_class->notify_change_start = grl_upnp_source_notify_change_start;
+  source_class->notify_change_stop = grl_upnp_source_notify_change_stop;
 
   g_type_class_add_private (klass, sizeof (GrlUpnpPrivate));
 
@@ -287,7 +285,7 @@ container_changed_cb (GUPnPServiceProxy *proxy,
 {
   GPtrArray *changed_medias;
   GrlMedia *container;
-  GrlMediaSource *source = GRL_MEDIA_SOURCE (user_data);
+  GrlSource *source = GRL_SOURCE (user_data);
   gchar **tokens;
   gint i = 0;
 
@@ -303,10 +301,10 @@ container_changed_cb (GUPnPServiceProxy *proxy,
     i += 2;
   }
 
-  grl_media_source_notify_change_list (source,
-                                       changed_medias,
-                                       GRL_CONTENT_CHANGED,
-                                       FALSE);
+  grl_source_notify_change_list (source,
+                                 changed_medias,
+                                 GRL_CONTENT_CHANGED,
+                                 FALSE);
   g_strfreev (tokens);
 }
 
@@ -998,30 +996,31 @@ gupnp_browse_cb (GUPnPServiceProxy *service,
 }
 
 static void
-gupnp_metadata_result_cb (GUPnPDIDLLiteParser *parser,
-			  GUPnPDIDLLiteObject *didl,
-			  gpointer user_data)
+gupnp_resolve_result_cb (GUPnPDIDLLiteParser *parser,
+                         GUPnPDIDLLiteObject *didl,
+                         gpointer user_data)
 {
-  GrlMediaSourceMetadataSpec *ms = (GrlMediaSourceMetadataSpec *) user_data;
+  GrlSourceResolveSpec *rs = (GrlSourceResolveSpec *) user_data;
+
   if (gupnp_didl_lite_object_get_id (didl)) {
-    build_media_from_didl (ms->media, didl, ms->keys);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    build_media_from_didl (rs->media, didl, rs->keys);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   }
 }
 
 static void
-gupnp_metadata_cb (GUPnPServiceProxy *service,
-		   GUPnPServiceProxyAction *action,
-		   gpointer user_data)
+gupnp_resolve_cb (GUPnPServiceProxy *service,
+                  GUPnPServiceProxyAction *action,
+                  gpointer user_data)
 {
   GError *error = NULL;
   gchar *didl = NULL;
-  GrlMediaSourceMetadataSpec *ms;
+  GrlSourceResolveSpec *rs;
   GUPnPDIDLLiteParser *didl_parser;
 
-  GRL_DEBUG ("gupnp_metadata_cb");
+  GRL_DEBUG (__FUNCTION__);
 
-  ms = (GrlMediaSourceMetadataSpec *) user_data;
+  rs = (GrlSourceResolveSpec *) user_data;
   didl_parser = gupnp_didl_lite_parser_new ();
 
   gupnp_service_proxy_end_action (service, action, &error,
@@ -1029,9 +1028,8 @@ gupnp_metadata_cb (GUPnPServiceProxy *service,
                                   NULL);
 
   if (!didl) {
-    GRL_DEBUG ("Got no metadata");
-    ms->callback (ms->source, ms->metadata_id,
-                  ms->media, ms->user_data, error? error: NULL);
+    GRL_DEBUG ("Resolve operation failed");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     if (error) {
       g_error_free (error);
     }
@@ -1041,14 +1039,14 @@ gupnp_metadata_cb (GUPnPServiceProxy *service,
 
   g_signal_connect (G_OBJECT (didl_parser),
                     "object-available",
-                    G_CALLBACK (gupnp_metadata_result_cb),
-                    ms);
+                    G_CALLBACK (gupnp_resolve_result_cb),
+                    rs);
   gupnp_didl_lite_parser_parse_didl (didl_parser,
                                      didl,
                                      &error);
   if (error) {
     GRL_WARNING ("Failed to parse DIDL result: %s", error->message);
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
     goto free_resources;
   }
@@ -1084,7 +1082,8 @@ grl_upnp_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_upnp_source_browse (GrlMediaSource *source, GrlMediaSourceBrowseSpec *bs)
+grl_upnp_source_browse (GrlSource *source,
+                        GrlSourceBrowseSpec *bs)
 {
   GUPnPServiceProxyAction* action;
   gchar *upnp_filter;
@@ -1099,7 +1098,7 @@ grl_upnp_source_browse (GrlMediaSource *source, GrlMediaSourceBrowseSpec *bs)
 
   os = g_slice_new0 (struct OperationSpec);
   os->source = bs->source;
-  os->operation_id = bs->browse_id;
+  os->operation_id = bs->operation_id;
   os->keys = bs->keys;
   os->skip = grl_operation_options_get_skip (bs->options);
   os->count = grl_operation_options_get_count (bs->options);
@@ -1132,7 +1131,7 @@ grl_upnp_source_browse (GrlMediaSource *source, GrlMediaSourceBrowseSpec *bs)
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_BROWSE_FAILED,
 			 "Failed to start browse action");
-    bs->callback (bs->source, bs->browse_id, NULL, 0, bs->user_data, error);
+    bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, error);
     g_error_free (error);
     g_slice_free (struct OperationSpec, os);
   }
@@ -1141,7 +1140,7 @@ grl_upnp_source_browse (GrlMediaSource *source, GrlMediaSourceBrowseSpec *bs)
 }
 
 static void
-grl_upnp_source_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
+grl_upnp_source_search (GrlSource *source, GrlSourceSearchSpec *ss)
 {
   GUPnPServiceProxyAction* action;
   gchar *upnp_filter;
@@ -1159,7 +1158,7 @@ grl_upnp_source_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
 
   os = g_slice_new0 (struct OperationSpec);
   os->source = ss->source;
-  os->operation_id = ss->search_id;
+  os->operation_id = ss->operation_id;
   os->keys = ss->keys;
   os->skip = grl_operation_options_get_skip (ss->options);
   os->count = grl_operation_options_get_count (ss->options);
@@ -1187,7 +1186,7 @@ grl_upnp_source_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_SEARCH_FAILED,
 			 "Failed to start browse action");
-    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, error);
+    ss->callback (ss->source, ss->operation_id, NULL, 0, ss->user_data, error);
     g_error_free (error);
     g_slice_free (struct OperationSpec, os);
   }
@@ -1207,7 +1206,7 @@ grl_upnp_source_search (GrlMediaSource *source, GrlMediaSourceSearchSpec *ss)
  * be useful.
  */
 static void
-grl_upnp_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
+grl_upnp_source_query (GrlSource *source, GrlSourceQuerySpec *qs)
 {
   GUPnPServiceProxyAction* action;
   gchar *upnp_filter;
@@ -1223,7 +1222,7 @@ grl_upnp_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
 
   os = g_slice_new0 (struct OperationSpec);
   os->source = qs->source;
-  os->operation_id = qs->query_id;
+  os->operation_id = qs->operation_id;
   os->keys = qs->keys;
   os->skip = grl_operation_options_get_skip (qs->options);
   os->count = grl_operation_options_get_count (qs->options);
@@ -1250,7 +1249,7 @@ grl_upnp_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_QUERY_FAILED,
 			 "Failed to start query action");
-    qs->callback (qs->source, qs->query_id, NULL, 0, qs->user_data, error);
+    qs->callback (qs->source, qs->operation_id, NULL, 0, qs->user_data, error);
     g_error_free (error);
     g_slice_free (struct OperationSpec, os);
   }
@@ -1259,48 +1258,48 @@ grl_upnp_source_query (GrlMediaSource *source, GrlMediaSourceQuerySpec *qs)
 }
 
 static void
-grl_upnp_source_metadata (GrlMediaSource *source,
-                          GrlMediaSourceMetadataSpec *ms)
+grl_upnp_source_resolve (GrlSource *source,
+                         GrlSourceResolveSpec *rs)
 {
   GUPnPServiceProxyAction* action;
   gchar *upnp_filter;
   gchar *id;
   GError *error = NULL;
 
-  GRL_DEBUG ("grl_upnp_source_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
-  upnp_filter = get_upnp_filter (ms->keys);
+  upnp_filter = get_upnp_filter (rs->keys);
 
   GRL_DEBUG ("filter: '%s'", upnp_filter);
 
-  id = (gchar *) grl_media_get_id (ms->media);
+  id = (gchar *) grl_media_get_id (rs->media);
   if (!id) {
-    grl_media_set_title (ms->media, GRL_UPNP_SOURCE (source)->priv->upnp_name);
+    grl_media_set_title (rs->media, GRL_UPNP_SOURCE (source)->priv->upnp_name);
     id = "0";
   }
 
   action =
     gupnp_service_proxy_begin_action (GRL_UPNP_SOURCE (source)->priv->service,
-				      "Browse", gupnp_metadata_cb,
-                                      ms,
-				      "ObjectID", G_TYPE_STRING,
+                                      "Browse", gupnp_resolve_cb,
+                                      rs,
+                                      "ObjectID", G_TYPE_STRING,
                                       id,
-				      "BrowseFlag", G_TYPE_STRING,
+                                      "BrowseFlag", G_TYPE_STRING,
                                       "BrowseMetadata",
-				      "Filter", G_TYPE_STRING,
+                                      "Filter", G_TYPE_STRING,
                                       upnp_filter,
-				      "StartingIndex", G_TYPE_UINT,
+                                      "StartingIndex", G_TYPE_UINT,
                                       0,
-				      "RequestedCount", G_TYPE_UINT,
+                                      "RequestedCount", G_TYPE_UINT,
                                       0,
-				      "SortCriteria", G_TYPE_STRING,
+                                      "SortCriteria", G_TYPE_STRING,
                                       "",
-				      NULL);
+                                      NULL);
   if (!action) {
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_METADATA_FAILED,
-			 "Failed to start metadata action");
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+                         GRL_CORE_ERROR_RESOLVE_FAILED,
+                         "Failed to start resolve action");
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 
@@ -1308,25 +1307,25 @@ grl_upnp_source_metadata (GrlMediaSource *source,
 }
 
 static GrlSupportedOps
-grl_upnp_source_supported_operations (GrlSource *metadata_source)
+grl_upnp_source_supported_operations (GrlSource *source)
 {
   GrlSupportedOps caps;
-  GrlUpnpSource *source;
+  GrlUpnpSource *upnp_source;
 
   /* Some sources may support search() while other not, so we rewrite
      supported_operations() to take that into account.
      See also note in grl_upnp_source_query() */
 
-  source = GRL_UPNP_SOURCE (metadata_source);
-  caps = GRL_OP_BROWSE | GRL_OP_METADATA | GRL_OP_NOTIFY_CHANGE;
-  if (source->priv->search_enabled)
+  upnp_source = GRL_UPNP_SOURCE (source);
+  caps = GRL_OP_BROWSE | GRL_OP_RESOLVE | GRL_OP_NOTIFY_CHANGE;
+  if (upnp_source->priv->search_enabled)
     caps = caps | GRL_OP_SEARCH | GRL_OP_QUERY;
 
   return caps;
 }
 
 static gboolean
-grl_upnp_source_notify_change_start (GrlMediaSource *source,
+grl_upnp_source_notify_change_start (GrlSource *source,
                                      GError **error)
 {
   GrlUpnpSource *upnp_source = GRL_UPNP_SOURCE (source);
@@ -1350,7 +1349,7 @@ grl_upnp_source_notify_change_start (GrlMediaSource *source,
 
 
 static gboolean
-grl_upnp_source_notify_change_stop (GrlMediaSource *source,
+grl_upnp_source_notify_change_stop (GrlSource *source,
                                     GError **error)
 {
   GrlUpnpSource *upnp_source = GRL_UPNP_SOURCE (source);
diff --git a/src/media/upnp/grl-upnp.h b/src/media/upnp/grl-upnp.h
index e0bc748..4fd6c78 100644
--- a/src/media/upnp/grl-upnp.h
+++ b/src/media/upnp/grl-upnp.h
@@ -56,7 +56,7 @@ typedef struct _GrlUpnpSource  GrlUpnpSource;
 
 struct _GrlUpnpSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlUpnpPrivate *priv;
@@ -66,7 +66,7 @@ typedef struct _GrlUpnpSourceClass GrlUpnpSourceClass;
 
 struct _GrlUpnpSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/vimeo/grl-vimeo.c b/src/media/vimeo/grl-vimeo.c
index a2fc81c..97ead00 100644
--- a/src/media/vimeo/grl-vimeo.c
+++ b/src/media/vimeo/grl-vimeo.c
@@ -5,6 +5,7 @@
  * Contact: Iago Toral Quiroga <itoral igalia com>
  *
  * Authors: Joaquim Rocha <jrocha igalia com>
+            Juan A. Suarez Romero <jasuarez igalia com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -55,7 +56,7 @@ GRL_LOG_DOMAIN_STATIC(vimeo_log_domain);
 #define SOURCE_DESC "A source for browsing and searching Vimeo videos"
 
 typedef struct {
-  GrlMediaSourceSearchSpec *ss;
+  GrlSourceSearchSpec *ss;
   gint offset;
   gint page;
 } SearchData;
@@ -75,11 +76,11 @@ static const GList *grl_vimeo_source_supported_keys (GrlSource *source);
 static GrlCaps * grl_vimeo_source_get_caps (GrlSource *source,
                                             GrlSupportedOps operation);
 
-static void grl_vimeo_source_metadata (GrlMediaSource *source,
-				       GrlMediaSourceMetadataSpec *ss);
+static void grl_vimeo_source_resolve (GrlSource *source,
+                                      GrlSourceResolveSpec *rs);
 
-static void grl_vimeo_source_search (GrlMediaSource *source,
-				     GrlMediaSourceSearchSpec *ss);
+static void grl_vimeo_source_search (GrlSource *source,
+                                     GrlSourceSearchSpec *ss);
 
 /* =================== Vimeo Plugin  =============== */
 
@@ -167,13 +168,11 @@ static void
 grl_vimeo_source_class_init (GrlVimeoSourceClass * klass)
 {
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   source_class->supported_keys = grl_vimeo_source_supported_keys;
   source_class->get_caps = grl_vimeo_source_get_caps;
-
-  media_class->metadata = grl_vimeo_source_metadata;
-  media_class->search = grl_vimeo_source_search;
+  source_class->resolve = grl_vimeo_source_resolve;
+  source_class->search = grl_vimeo_source_search;
 
   g_type_class_add_private (klass, sizeof (GrlVimeoSourcePrivate));
 }
@@ -184,7 +183,7 @@ grl_vimeo_source_init (GrlVimeoSource *source)
   source->priv = GRL_VIMEO_SOURCE_GET_PRIVATE (source);
 }
 
-G_DEFINE_TYPE (GrlVimeoSource, grl_vimeo_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlVimeoSource, grl_vimeo_source, GRL_TYPE_SOURCE);
 
 /* ======================= Utilities ==================== */
 
@@ -295,7 +294,7 @@ search_cb (GVimeo *vimeo, GList *video_list, gpointer user_data)
   /* No more elements can be sent */
   if (!video_list) {
     sd->ss->callback (sd->ss->source,
-                      sd->ss->search_id,
+                      sd->ss->operation_id,
                       NULL,
                       0,
                       sd->ss->user_data,
@@ -315,7 +314,7 @@ search_cb (GVimeo *vimeo, GList *video_list, gpointer user_data)
     {
       update_media (media, video_list->data);
       sd->ss->callback (sd->ss->source,
-			sd->ss->search_id,
+			sd->ss->operation_id,
 			media,
 			count == 1? 0: -1,
 			sd->ss->user_data,
@@ -345,14 +344,13 @@ search_cb (GVimeo *vimeo, GList *video_list, gpointer user_data)
 static void
 video_get_play_url_cb (gchar *url, gpointer user_data)
 {
-  GrlMediaSourceMetadataSpec *ms = (GrlMediaSourceMetadataSpec *) user_data;
+  GrlSourceResolveSpec *rs = (GrlSourceResolveSpec *) user_data;
 
-  if (url)
-  {
-    grl_media_set_url (ms->media, url);
+  if (url) {
+    grl_media_set_url (rs->media, url);
   }
 
-  ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+  rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
 }
 
 /* ================== API Implementation ================ */
@@ -367,7 +365,7 @@ grl_vimeo_source_supported_keys (GrlSource *source)
 				      GRL_METADATA_KEY_DESCRIPTION,
 				      GRL_METADATA_KEY_URL,
 				      GRL_METADATA_KEY_AUTHOR,
-                                      GRL_METADATA_KEY_PUBLICATION_DATE,
+                      GRL_METADATA_KEY_PUBLICATION_DATE,
 				      GRL_METADATA_KEY_THUMBNAIL,
 				      GRL_METADATA_KEY_DURATION,
 				      GRL_METADATA_KEY_WIDTH,
@@ -378,34 +376,32 @@ grl_vimeo_source_supported_keys (GrlSource *source)
 }
 
 static void
-grl_vimeo_source_metadata (GrlMediaSource *source,
-			   GrlMediaSourceMetadataSpec *ms)
+grl_vimeo_source_resolve (GrlSource *source,
+                          GrlSourceResolveSpec *rs)
 {
   gint id;
   const gchar *id_str;
 
-  if (!ms->media || (id_str = grl_media_get_id (ms->media)) == NULL)
-  {
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+  if (!rs->media || (id_str = grl_media_get_id (rs->media)) == NULL) {
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
     return;
   }
 
   errno = 0;
   id = (gint) g_ascii_strtod (id_str, NULL);
-  if (errno != 0)
-  {
+  if (errno != 0) {
     return;
   }
 
   g_vimeo_video_get_play_url (GRL_VIMEO_SOURCE (source)->priv->vimeo,
-			      id,
-			      video_get_play_url_cb,
-			      ms);
+                              id,
+                              video_get_play_url_cb,
+                              rs);
 }
 
 static void
-grl_vimeo_source_search (GrlMediaSource *source,
-			 GrlMediaSourceSearchSpec *ss)
+grl_vimeo_source_search (GrlSource *source,
+                         GrlSourceSearchSpec *ss)
 {
   SearchData *sd;
   GError *error;
@@ -420,7 +416,7 @@ grl_vimeo_source_search (GrlMediaSource *source,
       g_error_new_literal (GRL_CORE_ERROR,
                            GRL_CORE_ERROR_SEARCH_NULL_UNSUPPORTED,
                            "Unable to execute search: non NULL search text is required");
-    ss->callback (ss->source, ss->search_id, NULL, 0, ss->user_data, error);
+    ss->callback (ss->source, ss->operation_id, NULL, 0, ss->user_data, error);
     g_error_free (error);
     return;
   }
diff --git a/src/media/vimeo/grl-vimeo.h b/src/media/vimeo/grl-vimeo.h
index fde4f36..b0c49bb 100644
--- a/src/media/vimeo/grl-vimeo.h
+++ b/src/media/vimeo/grl-vimeo.h
@@ -58,7 +58,7 @@ typedef struct _GrlVimeoSourcePrivate GrlVimeoSourcePrivate;
 
 struct _GrlVimeoSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlVimeoSourcePrivate *priv;
@@ -68,7 +68,7 @@ typedef struct _GrlVimeoSourceClass GrlVimeoSourceClass;
 
 struct _GrlVimeoSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/media/youtube/grl-youtube.c b/src/media/youtube/grl-youtube.c
index 51be00b..89849e8 100644
--- a/src/media/youtube/grl-youtube.c
+++ b/src/media/youtube/grl-youtube.c
@@ -128,15 +128,15 @@ typedef struct {
 } CategoryInfo;
 
 typedef struct {
-  GrlMediaSource *source;
+  GrlSource *source;
   GCancellable *cancellable;
   guint operation_id;
   const gchar *container_id;
   GList *keys;
-  GrlMetadataResolutionFlags flags;
+  GrlResolutionFlags flags;
   guint skip;
   guint count;
-  GrlMediaSourceResultCb callback;
+  GrlSourceResultCb callback;
   gpointer user_data;
   guint error_code;
   CategoryInfo *category_info;
@@ -196,20 +196,20 @@ static const GList *grl_youtube_source_slow_keys (GrlSource *source);
 static GrlCaps * grl_youtube_source_get_caps (GrlSource *source,
                                               GrlSupportedOps operation);
 
-static void grl_youtube_source_search (GrlMediaSource *source,
-                                       GrlMediaSourceSearchSpec *ss);
+static void grl_youtube_source_search (GrlSource *source,
+                                       GrlSourceSearchSpec *ss);
 
-static void grl_youtube_source_browse (GrlMediaSource *source,
-                                       GrlMediaSourceBrowseSpec *bs);
+static void grl_youtube_source_browse (GrlSource *source,
+                                       GrlSourceBrowseSpec *bs);
 
-static void grl_youtube_source_metadata (GrlMediaSource *source,
-                                         GrlMediaSourceMetadataSpec *ms);
+static void grl_youtube_source_resolve (GrlSource *source,
+                                        GrlSourceResolveSpec *rs);
 
-static gboolean grl_youtube_test_media_from_uri (GrlMediaSource *source,
+static gboolean grl_youtube_test_media_from_uri (GrlSource *source,
 						 const gchar *uri);
 
-static void grl_youtube_get_media_from_uri (GrlMediaSource *source,
-					    GrlMediaSourceMediaFromUriSpec *mfus);
+static void grl_youtube_get_media_from_uri (GrlSource *source,
+					    GrlSourceMediaFromUriSpec *mfus);
 
 static void grl_youtube_source_cancel (GrlSource *source,
                                        guint operation_id);
@@ -301,7 +301,7 @@ GRL_PLUGIN_REGISTER (grl_youtube_plugin_init,
 
 /* ================== YouTube GObject ================ */
 
-G_DEFINE_TYPE (GrlYoutubeSource, grl_youtube_source, GRL_TYPE_MEDIA_SOURCE);
+G_DEFINE_TYPE (GrlYoutubeSource, grl_youtube_source, GRL_TYPE_SOURCE);
 
 static GrlYoutubeSource *
 grl_youtube_source_new (const gchar *api_key, const gchar *client_id)
@@ -350,7 +350,6 @@ grl_youtube_source_class_init (GrlYoutubeSourceClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMediaSourceClass *media_class = GRL_MEDIA_SOURCE_CLASS (klass);
 
   gobject_class->set_property = grl_youtube_source_set_property;
   gobject_class->finalize = grl_youtube_source_finalize;
@@ -360,12 +359,11 @@ grl_youtube_source_class_init (GrlYoutubeSourceClass * klass)
   source_class->get_caps = grl_youtube_source_get_caps;
   source_class->cancel = grl_youtube_source_cancel;
 
-  media_class->search = grl_youtube_source_search;
-  media_class->browse = grl_youtube_source_browse;
-  media_class->metadata = grl_youtube_source_metadata;
-  media_class->test_media_from_uri = grl_youtube_test_media_from_uri;
-  media_class->media_from_uri = grl_youtube_get_media_from_uri;
-
+  source_class->search = grl_youtube_source_search;
+  source_class->browse = grl_youtube_source_browse;
+  source_class->resolve = grl_youtube_source_resolve;
+  source_class->test_media_from_uri = grl_youtube_test_media_from_uri;
+  source_class->media_from_uri = grl_youtube_get_media_from_uri;
 
   g_object_class_install_property (gobject_class,
                                    PROP_SERVICE,
@@ -427,8 +425,7 @@ grl_youtube_source_finalize (GObject *object)
 /* ======================= Utilities ==================== */
 
 static void
-release_operation_data (GrlMetadataSource *source,
-                        guint operation_id)
+release_operation_data (guint operation_id)
 {
   GCancellable *cancellable = grl_operation_get_data (operation_id);
 
@@ -757,11 +754,11 @@ get_category_index_from_id (const gchar *category_id)
 }
 
 static void
-build_media_from_entry_metadata_cb (GrlMedia *media, gpointer user_data)
+build_media_from_entry_resolve_cb (GrlMedia *media, gpointer user_data)
 {
-  GrlMediaSourceMetadataSpec *ms = (GrlMediaSourceMetadataSpec *) user_data;
-  release_operation_data (GRL_METADATA_SOURCE (ms->source), ms->metadata_id);
-  ms->callback (ms->source, ms->metadata_id, media, ms->user_data, NULL);
+  GrlSourceResolveSpec *rs = (GrlSourceResolveSpec *) user_data;
+  release_operation_data (rs->operation_id);
+  rs->callback (rs->source, rs->operation_id, media, rs->user_data, NULL);
 }
 
 static void
@@ -811,36 +808,36 @@ build_category_directory (OperationSpec *os)
 }
 
 static void
-metadata_cb (GObject *object,
-	     GAsyncResult *result,
-	     gpointer user_data)
+resolve_cb (GObject *object,
+            GAsyncResult *result,
+            gpointer user_data)
 {
+  GRL_DEBUG (__FUNCTION__);
+
   GError *error = NULL;
   GrlYoutubeSource *source;
   GDataEntry *video;
   GDataService *service;
-  GrlMediaSourceMetadataSpec *ms = (GrlMediaSourceMetadataSpec *) user_data;
+  GrlSourceResolveSpec *rs = (GrlSourceResolveSpec *) user_data;
 
-  GRL_DEBUG ("metadata_cb");
-
-  source = GRL_YOUTUBE_SOURCE (ms->source);
+  source = GRL_YOUTUBE_SOURCE (rs->source);
   service = GDATA_SERVICE (source->priv->service);
 
   video = gdata_service_query_single_entry_finish (service, result, &error);
 
   if (error) {
-    release_operation_data (GRL_METADATA_SOURCE (ms->source), ms->metadata_id);
-    error->code = GRL_CORE_ERROR_METADATA_FAILED;
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+    release_operation_data (rs->operation_id);
+    error->code = GRL_CORE_ERROR_RESOLVE_FAILED;
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   } else {
-    build_media_from_entry (GRL_YOUTUBE_SOURCE (ms->source),
-                            ms->media,
+    build_media_from_entry (GRL_YOUTUBE_SOURCE (rs->source),
+                            rs->media,
                             video,
-                            grl_operation_get_data (ms->metadata_id),
-                            ms->keys,
-			    build_media_from_entry_metadata_cb,
-                            ms);
+                            grl_operation_get_data (rs->operation_id),
+                            rs->keys,
+			    build_media_from_entry_resolve_cb,
+                            rs);
   }
 
   if (video) {
@@ -1252,11 +1249,11 @@ get_video_id_from_url (const gchar *url)
 static void
 build_media_from_entry_media_from_uri_cb (GrlMedia *media, gpointer user_data)
 {
-  GrlMediaSourceMediaFromUriSpec *mfus =
-    (GrlMediaSourceMediaFromUriSpec *) user_data;
+  GrlSourceMediaFromUriSpec *mfus = (GrlSourceMediaFromUriSpec *) user_data;
 
-  release_operation_data (GRL_METADATA_SOURCE (mfus->source), mfus->media_from_uri_id);
-  mfus->callback (mfus->source, mfus->media_from_uri_id, media, mfus->user_data, NULL);
+  release_operation_data (mfus->operation_id);
+  mfus->callback (mfus->source, mfus->operation_id,
+                  media, mfus->user_data, NULL);
 }
 
 static void
@@ -1266,8 +1263,7 @@ media_from_uri_cb (GObject *object, GAsyncResult *result, gpointer user_data)
   GrlYoutubeSource *source;
   GDataEntry *video;
   GDataService *service;
-  GrlMediaSourceMediaFromUriSpec *mfus =
-    (GrlMediaSourceMediaFromUriSpec *) user_data;
+  GrlSourceMediaFromUriSpec *mfus = (GrlSourceMediaFromUriSpec *) user_data;
 
   source = GRL_YOUTUBE_SOURCE (mfus->source);
   service = GDATA_SERVICE (source->priv->service);
@@ -1276,14 +1272,14 @@ media_from_uri_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
   if (error) {
     error->code = GRL_CORE_ERROR_MEDIA_FROM_URI_FAILED;
-    release_operation_data (GRL_METADATA_SOURCE (mfus->source), mfus->media_from_uri_id);
-    mfus->callback (mfus->source, mfus->media_from_uri_id, NULL, mfus->user_data, error);
+    release_operation_data (mfus->operation_id);
+    mfus->callback (mfus->source, mfus->operation_id, NULL, mfus->user_data, error);
     g_error_free (error);
   } else {
     build_media_from_entry (GRL_YOUTUBE_SOURCE (mfus->source),
                             NULL,
                             video,
-                            grl_operation_get_data (mfus->media_from_uri_id),
+                            grl_operation_get_data (mfus->operation_id),
                             mfus->keys,
 			    build_media_from_entry_media_from_uri_cb,
 			    mfus);
@@ -1304,7 +1300,7 @@ grl_youtube_source_supported_keys (GrlSource *source)
     keys = grl_metadata_key_list_new (GRL_METADATA_KEY_ID,
                                       GRL_METADATA_KEY_TITLE,
                                       GRL_METADATA_KEY_URL,
-				      GRL_METADATA_KEY_EXTERNAL_URL,
+                                      GRL_METADATA_KEY_EXTERNAL_URL,
                                       GRL_METADATA_KEY_DESCRIPTION,
                                       GRL_METADATA_KEY_DURATION,
                                       GRL_METADATA_KEY_PUBLICATION_DATE,
@@ -1313,7 +1309,7 @@ grl_youtube_source_supported_keys (GrlSource *source)
                                       GRL_METADATA_KEY_CHILDCOUNT,
                                       GRL_METADATA_KEY_SITE,
                                       GRL_METADATA_KEY_RATING,
-				      GRL_METADATA_KEY_EXTERNAL_PLAYER,
+                                      GRL_METADATA_KEY_EXTERNAL_PLAYER,
                                       NULL);
   }
   return keys;
@@ -1331,20 +1327,21 @@ grl_youtube_source_slow_keys (GrlSource *source)
 }
 
 static void
-grl_youtube_source_search (GrlMediaSource *source,
-                           GrlMediaSourceSearchSpec *ss)
+grl_youtube_source_search (GrlSource *source,
+                           GrlSourceSearchSpec *ss)
 {
   OperationSpec *os;
   GDataQuery *query;
 
-  GRL_DEBUG ("grl_youtube_source_search (%u, %d)",
+  GRL_DEBUG ("%s (%u, %d)",
+             __FUNCTION__,
              grl_operation_options_get_skip (ss->options),
              grl_operation_options_get_count (ss->options));
 
   os = operation_spec_new ();
   os->source = source;
   os->cancellable = g_cancellable_new ();
-  os->operation_id = ss->search_id;
+  os->operation_id = ss->operation_id;
   os->keys = ss->keys;
   os->skip = grl_operation_options_get_skip (ss->options) + 1;
   os->count = grl_operation_options_get_count (ss->options);
@@ -1355,7 +1352,7 @@ grl_youtube_source_search (GrlMediaSource *source,
   /* Look for OPERATION_SPEC_REF_RATIONALE for details */
   operation_spec_ref (os);
 
-  grl_operation_set_data (ss->search_id, os->cancellable);
+  grl_operation_set_data (ss->operation_id, os->cancellable);
 
   query = gdata_query_new_with_limits (ss->text, os->skip, os->count);
 
@@ -1382,19 +1379,19 @@ grl_youtube_source_search (GrlMediaSource *source,
 }
 
 static void
-grl_youtube_source_browse (GrlMediaSource *source,
-                           GrlMediaSourceBrowseSpec *bs)
+grl_youtube_source_browse (GrlSource *source,
+                           GrlSourceBrowseSpec *bs)
 {
   OperationSpec *os;
   const gchar *container_id;
 
-  GRL_DEBUG ("grl_youtube_source_browse: %s", grl_media_get_id (bs->container));
+  GRL_DEBUG ("%s: %s", __FUNCTION__, grl_media_get_id (bs->container));
 
   container_id = grl_media_get_id (bs->container);
 
   os = operation_spec_new ();
   os->source = bs->source;
-  os->operation_id = bs->browse_id;
+  os->operation_id = bs->operation_id;
   os->container_id = container_id;
   os->keys = bs->keys;
   os->flags = grl_operation_options_get_flags (bs->options);
@@ -1436,8 +1433,8 @@ grl_youtube_source_browse (GrlMediaSource *source,
 }
 
 static void
-grl_youtube_source_metadata (GrlMediaSource *source,
-                             GrlMediaSourceMetadataSpec *ms)
+grl_youtube_source_resolve (GrlSource *source,
+                            GrlSourceResolveSpec *rs)
 {
   YoutubeMediaType media_type;
   const gchar *id;
@@ -1446,32 +1443,32 @@ grl_youtube_source_metadata (GrlMediaSource *source,
   GError *error = NULL;
   GrlMedia *media = NULL;
 
-  GRL_DEBUG ("grl_youtube_source_metadata");
+  GRL_DEBUG (__FUNCTION__);
 
-  id = grl_media_get_id (ms->media);
+  id = grl_media_get_id (rs->media);
   media_type = classify_media_id (id);
   service = GRL_YOUTUBE_SOURCE (source)->priv->service;
 
   switch (media_type) {
   case YOUTUBE_MEDIA_TYPE_ROOT:
-    media = produce_container_from_directory (service, ms->media, NULL, 0);
+    media = produce_container_from_directory (service, rs->media, NULL, 0);
     break;
   case YOUTUBE_MEDIA_TYPE_FEEDS:
-    media = produce_container_from_directory (service, ms->media, root_dir, 0);
+    media = produce_container_from_directory (service, rs->media, root_dir, 0);
     break;
   case YOUTUBE_MEDIA_TYPE_CATEGORIES:
-    media = produce_container_from_directory (service, ms->media, root_dir, 1);
+    media = produce_container_from_directory (service, rs->media, root_dir, 1);
     break;
   case YOUTUBE_MEDIA_TYPE_FEED:
     {
       gint index = get_feed_type_from_id (id);
       if (index >= 0) {
-	media = produce_container_from_directory (service, ms->media, feeds_dir,
-						  index);
+        media = produce_container_from_directory (service, rs->media, feeds_dir,
+                                                  index);
       } else {
-	error = g_error_new (GRL_CORE_ERROR,
-			     GRL_CORE_ERROR_METADATA_FAILED,
-			     "Invalid feed id");
+        error = g_error_new (GRL_CORE_ERROR,
+                             GRL_CORE_ERROR_RESOLVE_FAILED,
+                             "Invalid feed id");
       }
     }
     break;
@@ -1479,19 +1476,19 @@ grl_youtube_source_metadata (GrlMediaSource *source,
     {
       gint index = get_category_index_from_id (id);
       if (index >= 0) {
-	media = produce_container_from_directory (service, ms->media,
-						  categories_dir, index);
+        media = produce_container_from_directory (service, rs->media,
+                                                  categories_dir, index);
       } else {
 	error = g_error_new (GRL_CORE_ERROR,
-			     GRL_CORE_ERROR_METADATA_FAILED,
-			     "Invalid category id");
+                        GRL_CORE_ERROR_RESOLVE_FAILED,
+                        "Invalid category id");
       }
     }
     break;
   case YOUTUBE_MEDIA_TYPE_VIDEO:
   default:
     cancellable = g_cancellable_new ();
-    grl_operation_set_data (ms->metadata_id, cancellable);
+    grl_operation_set_data (rs->operation_id, cancellable);
     gchar *entryid = g_strconcat ("tag:youtube.com,2008:video:", id, NULL);
 
 #ifdef HAVE_LIBGDATA_0_9
@@ -1501,8 +1498,8 @@ grl_youtube_source_metadata (GrlMediaSource *source,
                                               NULL,
                                               GDATA_TYPE_YOUTUBE_VIDEO,
                                               cancellable,
-                                              metadata_cb,
-                                              ms);
+                                              resolve_cb,
+                                              rs);
 #else /* HAVE_LIBGDATA_0_9 */
       gdata_service_query_single_entry_async (service,
                                               entryid,
@@ -1518,20 +1515,20 @@ grl_youtube_source_metadata (GrlMediaSource *source,
   }
 
   if (error) {
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   } else if (media) {
-    ms->callback (ms->source, ms->metadata_id, ms->media, ms->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   }
 }
 
 static gboolean
-grl_youtube_test_media_from_uri (GrlMediaSource *source, const gchar *uri)
+grl_youtube_test_media_from_uri (GrlSource *source, const gchar *uri)
 {
   gchar *video_id;
   gboolean ok;
 
-  GRL_DEBUG ("grl_youtube_test_media_from_uri");
+  GRL_DEBUG (__FUNCTION__);
 
   video_id = get_video_id_from_url (uri);
   ok = (video_id != NULL);
@@ -1540,8 +1537,8 @@ grl_youtube_test_media_from_uri (GrlMediaSource *source, const gchar *uri)
 }
 
 static void
-grl_youtube_get_media_from_uri (GrlMediaSource *source,
-				 GrlMediaSourceMediaFromUriSpec *mfus)
+grl_youtube_get_media_from_uri (GrlSource *source,
+                                GrlSourceMediaFromUriSpec *mfus)
 {
   gchar *video_id;
   GError *error;
@@ -1549,14 +1546,14 @@ grl_youtube_get_media_from_uri (GrlMediaSource *source,
   GDataService *service;
   gchar *entry_id;
 
-  GRL_DEBUG ("grl_youtube_get_media_from_uri");
+  GRL_DEBUG (__FUNCTION__);
 
   video_id = get_video_id_from_url (mfus->uri);
   if (video_id == NULL) {
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_MEDIA_FROM_URI_FAILED,
 			 "Cannot create media from '%s'", mfus->uri);
-    mfus->callback (source, mfus->media_from_uri_id, NULL, mfus->user_data, error);
+    mfus->callback (source, mfus->operation_id, NULL, mfus->user_data, error);
     g_error_free (error);
     return;
   }
@@ -1564,7 +1561,7 @@ grl_youtube_get_media_from_uri (GrlMediaSource *source,
   service = GRL_YOUTUBE_SOURCE (source)->priv->service;
 
   cancellable = g_cancellable_new ();
-  grl_operation_set_data (mfus->media_from_uri_id, cancellable);
+  grl_operation_set_data (mfus->operation_id, cancellable);
   entry_id = g_strconcat ("tag:youtube.com,2008:video:", video_id, NULL);
 
 #ifdef HAVE_LIBGDATA_0_9
diff --git a/src/media/youtube/grl-youtube.h b/src/media/youtube/grl-youtube.h
index dc88589..440d08c 100644
--- a/src/media/youtube/grl-youtube.h
+++ b/src/media/youtube/grl-youtube.h
@@ -56,7 +56,7 @@ typedef struct _GrlYoutubeSourcePriv GrlYoutubeSourcePriv;
 
 struct _GrlYoutubeSource {
 
-  GrlMediaSource parent;
+  GrlSource parent;
   GrlYoutubeSourcePriv *priv;
 
 };
@@ -65,7 +65,7 @@ typedef struct _GrlYoutubeSourceClass GrlYoutubeSourceClass;
 
 struct _GrlYoutubeSourceClass {
 
-  GrlMediaSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/metadata/fake-metadata/grl-fake-metadata.c b/src/metadata/fake-metadata/grl-fake-metadata.c
index e738444..78042fa 100644
--- a/src/metadata/fake-metadata/grl-fake-metadata.c
+++ b/src/metadata/fake-metadata/grl-fake-metadata.c
@@ -39,20 +39,20 @@ GRL_LOG_DOMAIN_STATIC(fake_metadata_log_domain);
 
 static GrlFakeMetadataSource *grl_fake_metadata_source_new (void);
 
-static void grl_fake_metadata_source_resolve (GrlMetadataSource *source,
-                                              GrlMetadataSourceResolveSpec *rs);
+static void grl_fake_metadata_source_resolve (GrlSource *source,
+                                              GrlSourceResolveSpec *rs);
 
-static void grl_fake_metadata_source_set_metadata (GrlMetadataSource *source,
-						   GrlMetadataSourceSetMetadataSpec *sms);
+static void grl_fake_metadata_source_store_metadata (GrlSource *source,
+                                                     GrlSourceStoreMetadataSpec *sms);
 
 static const GList *grl_fake_metadata_source_supported_keys (GrlSource *source);
 
-static gboolean grl_fake_metadata_source_may_resolve (GrlMetadataSource *source,
+static gboolean grl_fake_metadata_source_may_resolve (GrlSource *source,
                                                       GrlMedia *media,
                                                       GrlKeyID key_id,
                                                       GList **missing_keys);
 
-static const GList *grl_fake_metadata_source_writable_keys (GrlMetadataSource *source);
+static const GList *grl_fake_metadata_source_writable_keys (GrlSource *source);
 
 gboolean grl_fake_metadata_source_plugin_init (GrlPluginRegistry *registry,
                                                GrlPlugin *plugin,
@@ -99,14 +99,12 @@ static void
 grl_fake_metadata_source_class_init (GrlFakeMetadataSourceClass * klass)
 {
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
 
   source_class->supported_keys = grl_fake_metadata_source_supported_keys;
-
-  metadata_class->may_resolve = grl_fake_metadata_source_may_resolve;
-  metadata_class->resolve = grl_fake_metadata_source_resolve;
-  metadata_class->set_metadata = grl_fake_metadata_source_set_metadata;
-  metadata_class->writable_keys = grl_fake_metadata_source_writable_keys;
+  source_class->may_resolve = grl_fake_metadata_source_may_resolve;
+  source_class->resolve = grl_fake_metadata_source_resolve;
+  source_class->store_metadata = grl_fake_metadata_source_store_metadata;
+  source_class->writable_keys = grl_fake_metadata_source_writable_keys;
 }
 
 static void
@@ -116,7 +114,7 @@ grl_fake_metadata_source_init (GrlFakeMetadataSource *source)
 
 G_DEFINE_TYPE (GrlFakeMetadataSource,
                grl_fake_metadata_source,
-               GRL_TYPE_METADATA_SOURCE);
+               GRL_TYPE_SOURCE);
 
 /* ======================= Utilities ==================== */
 
@@ -171,7 +169,7 @@ grl_fake_metadata_source_supported_keys (GrlSource *source)
 }
 
 static gboolean
-grl_fake_metadata_source_may_resolve (GrlMetadataSource *source,
+grl_fake_metadata_source_may_resolve (GrlSource *source,
                                       GrlMedia *media,
                                       GrlKeyID key_id,
                                       GList **missing_keys)
@@ -187,7 +185,7 @@ grl_fake_metadata_source_may_resolve (GrlMetadataSource *source,
 }
 
 static const GList *
-grl_fake_metadata_source_writable_keys (GrlMetadataSource *source)
+grl_fake_metadata_source_writable_keys (GrlSource *source)
 {
   static GList *keys = NULL;
   if (!keys) {
@@ -200,8 +198,8 @@ grl_fake_metadata_source_writable_keys (GrlMetadataSource *source)
 }
 
 static void
-grl_fake_metadata_source_resolve (GrlMetadataSource *source,
-                                  GrlMetadataSourceResolveSpec *rs)
+grl_fake_metadata_source_resolve (GrlSource *source,
+                                  GrlSourceResolveSpec *rs)
 {
   GRL_DEBUG ("grl_fake_metadata_source_resolve");
 
@@ -213,12 +211,12 @@ grl_fake_metadata_source_resolve (GrlMetadataSource *source,
     iter = g_list_next (iter);
   }
 
-  rs->callback (source, rs->resolve_id, rs->media, rs->user_data, NULL);
+  rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
 }
 
 static void
-grl_fake_metadata_source_set_metadata (GrlMetadataSource *source,
-				       GrlMetadataSourceSetMetadataSpec *sms)
+grl_fake_metadata_source_store_metadata (GrlSource *source,
+                                         GrlSourceStoreMetadataSpec *sms)
 {
   GRL_DEBUG ("grl_fake_metadata_source_set_metadata");
   GRL_DEBUG ("  Faking set metadata for %d keys!", g_list_length (sms->keys));
diff --git a/src/metadata/fake-metadata/grl-fake-metadata.h b/src/metadata/fake-metadata/grl-fake-metadata.h
index 5d80453..232e91f 100644
--- a/src/metadata/fake-metadata/grl-fake-metadata.h
+++ b/src/metadata/fake-metadata/grl-fake-metadata.h
@@ -55,7 +55,7 @@ typedef struct _GrlFakeMetadataSource GrlFakeMetadataSource;
 
 struct _GrlFakeMetadataSource {
 
-  GrlMetadataSource parent;
+  GrlSource parent;
 
 };
 
@@ -63,7 +63,7 @@ typedef struct _GrlFakeMetadataSourceClass GrlFakeMetadataSourceClass;
 
 struct _GrlFakeMetadataSourceClass {
 
-  GrlMetadataSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/metadata/gravatar/grl-gravatar.c b/src/metadata/gravatar/grl-gravatar.c
index 89d849c..d08d293 100644
--- a/src/metadata/gravatar/grl-gravatar.c
+++ b/src/metadata/gravatar/grl-gravatar.c
@@ -47,12 +47,12 @@ GRL_LOG_DOMAIN_STATIC(gravatar_log_domain);
 
 static GrlGravatarSource *grl_gravatar_source_new (void);
 
-static void grl_gravatar_source_resolve (GrlMetadataSource *source,
-                                         GrlMetadataSourceResolveSpec *rs);
+static void grl_gravatar_source_resolve (GrlSource *source,
+                                         GrlSourceResolveSpec *rs);
 
 static const GList *grl_gravatar_source_supported_keys (GrlSource *source);
 
-static gboolean grl_gravatar_source_may_resolve (GrlMetadataSource *source,
+static gboolean grl_gravatar_source_may_resolve (GrlSource *source,
                                                  GrlMedia *media,
                                                  GrlKeyID key_id,
                                                  GList **missing_keys);
@@ -136,12 +136,10 @@ static void
 grl_gravatar_source_class_init (GrlGravatarSourceClass * klass)
 {
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
 
   source_class->supported_keys = grl_gravatar_source_supported_keys;
-
-  metadata_class->may_resolve = grl_gravatar_source_may_resolve;
-  metadata_class->resolve = grl_gravatar_source_resolve;
+  source_class->may_resolve = grl_gravatar_source_may_resolve;
+  source_class->resolve = grl_gravatar_source_resolve;
 }
 
 static void
@@ -151,7 +149,7 @@ grl_gravatar_source_init (GrlGravatarSource *source)
 
 G_DEFINE_TYPE (GrlGravatarSource,
                grl_gravatar_source,
-               GRL_TYPE_METADATA_SOURCE);
+               GRL_TYPE_SOURCE);
 
 /* ======================= Utilities ==================== */
 
@@ -277,7 +275,7 @@ grl_gravatar_source_supported_keys (GrlSource *source)
 }
 
 static gboolean
-grl_gravatar_source_may_resolve (GrlMetadataSource *source,
+grl_gravatar_source_may_resolve (GrlSource *source,
                                  GrlMedia *media,
                                  GrlKeyID key_id,
                                  GList **missing_keys)
@@ -294,13 +292,13 @@ grl_gravatar_source_may_resolve (GrlMetadataSource *source,
 }
 
 static void
-grl_gravatar_source_resolve (GrlMetadataSource *source,
-                             GrlMetadataSourceResolveSpec *rs)
+grl_gravatar_source_resolve (GrlSource *source,
+                             GrlSourceResolveSpec *rs)
 {
   gboolean artist_avatar_required = FALSE;
   gboolean author_avatar_required = FALSE;
 
-  GRL_DEBUG ("grl_gravatar_source_resolve");
+  GRL_DEBUG (__FUNCTION__);
 
   GList *iter;
 
@@ -324,5 +322,5 @@ grl_gravatar_source_resolve (GrlMetadataSource *source,
     set_avatar (GRL_DATA (rs->media), GRL_METADATA_KEY_AUTHOR);
   }
 
-  rs->callback (source, rs->resolve_id, rs->media, rs->user_data, NULL);
+  rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
 }
diff --git a/src/metadata/gravatar/grl-gravatar.h b/src/metadata/gravatar/grl-gravatar.h
index 644efdb..1af1f35 100644
--- a/src/metadata/gravatar/grl-gravatar.h
+++ b/src/metadata/gravatar/grl-gravatar.h
@@ -57,7 +57,7 @@ typedef struct _GrlGravatarSource GrlGravatarSource;
 
 struct _GrlGravatarSource {
 
-  GrlMetadataSource parent;
+  GrlSource parent;
 
 };
 
@@ -65,7 +65,7 @@ typedef struct _GrlGravatarSourceClass GrlGravatarSourceClass;
 
 struct _GrlGravatarSourceClass {
 
-  GrlMetadataSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/metadata/lastfm-albumart/grl-lastfm-albumart.c b/src/metadata/lastfm-albumart/grl-lastfm-albumart.c
index 4abad93..a779b8f 100644
--- a/src/metadata/lastfm-albumart/grl-lastfm-albumart.c
+++ b/src/metadata/lastfm-albumart/grl-lastfm-albumart.c
@@ -62,12 +62,12 @@ static GrlLastfmAlbumartSource *grl_lastfm_albumart_source_new (void);
 
 static void grl_lastfm_albumart_source_finalize (GObject *object);
 
-static void grl_lastfm_albumart_source_resolve (GrlMetadataSource *source,
-                                                GrlMetadataSourceResolveSpec *rs);
+static void grl_lastfm_albumart_source_resolve (GrlSource *source,
+                                                GrlSourceResolveSpec *rs);
 
 static const GList *grl_lastfm_albumart_source_supported_keys (GrlSource *source);
 
-static gboolean grl_lastfm_albumart_source_may_resolve (GrlMetadataSource *source,
+static gboolean grl_lastfm_albumart_source_may_resolve (GrlSource *source,
                                                         GrlMedia *media,
                                                         GrlKeyID key_id,
                                                         GList **missing_keys);
@@ -121,13 +121,11 @@ grl_lastfm_albumart_source_class_init (GrlLastfmAlbumartSourceClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
 
   source_class->supported_keys = grl_lastfm_albumart_source_supported_keys;
   source_class->cancel = grl_lastfm_albumart_source_cancel;
-
-  metadata_class->may_resolve = grl_lastfm_albumart_source_may_resolve;
-  metadata_class->resolve = grl_lastfm_albumart_source_resolve;
+  source_class->may_resolve = grl_lastfm_albumart_source_may_resolve;
+  source_class->resolve = grl_lastfm_albumart_source_resolve;
 
   gobject_class->finalize = grl_lastfm_albumart_source_finalize;
 }
@@ -139,7 +137,7 @@ grl_lastfm_albumart_source_init (GrlLastfmAlbumartSource *source)
 
 G_DEFINE_TYPE (GrlLastfmAlbumartSource,
                grl_lastfm_albumart_source,
-               GRL_TYPE_METADATA_SOURCE);
+               GRL_TYPE_SOURCE);
 
 static void
 grl_lastfm_albumart_source_finalize (GObject *object)
@@ -197,8 +195,7 @@ read_done_cb (GObject *source_object,
               GAsyncResult *res,
               gpointer user_data)
 {
-  GrlMetadataSourceResolveSpec *rs =
-    (GrlMetadataSourceResolveSpec *) user_data;
+  GrlSourceResolveSpec *rs = (GrlSourceResolveSpec *) user_data;
   GCancellable *cancellable;
   GError *error = NULL;
   GError *wc_error = NULL;
@@ -207,7 +204,7 @@ read_done_cb (GObject *source_object,
   gchar *image = NULL;
 
   /* Get rid of stored operation data */
-  cancellable = grl_operation_get_data (rs->resolve_id);
+  cancellable = grl_operation_get_data (rs->operation_id);
   if (cancellable) {
     g_object_unref (cancellable);
   }
@@ -226,7 +223,7 @@ read_done_cb (GObject *source_object,
                            wc_error->message);
       g_error_free (wc_error);
     }
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
 
     return;
@@ -272,13 +269,13 @@ read_done_cb (GObject *source_object,
     g_free (image);
   }
 
-  rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+  rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
 }
 
 static void
-read_url_async (GrlMetadataSource *source,
+read_url_async (GrlSource *source,
                 const gchar *url,
-                GrlMetadataSourceResolveSpec *rs)
+                GrlSourceResolveSpec *rs)
 {
   GCancellable *cancellable;
 
@@ -286,7 +283,7 @@ read_url_async (GrlMetadataSource *source,
     wc = grl_net_wc_new ();
 
   cancellable = g_cancellable_new ();
-  grl_operation_set_data (rs->resolve_id, cancellable);
+  grl_operation_set_data (rs->operation_id, cancellable);
 
   GRL_DEBUG ("Opening '%s'", url);
   grl_net_wc_request_async (wc, url, cancellable, read_done_cb, rs);
@@ -308,7 +305,7 @@ grl_lastfm_albumart_source_supported_keys (GrlSource *source)
 }
 
 static gboolean
-grl_lastfm_albumart_source_may_resolve (GrlMetadataSource *source,
+grl_lastfm_albumart_source_may_resolve (GrlSource *source,
                                         GrlMedia *media,
                                         GrlKeyID key_id,
                                         GList **missing_keys)
@@ -345,8 +342,8 @@ grl_lastfm_albumart_source_may_resolve (GrlMetadataSource *source,
 }
 
 static void
-grl_lastfm_albumart_source_resolve (GrlMetadataSource *source,
-                                    GrlMetadataSourceResolveSpec *rs)
+grl_lastfm_albumart_source_resolve (GrlSource *source,
+                                    GrlSourceResolveSpec *rs)
 {
   const gchar *artist = NULL;
   const gchar *album = NULL;
@@ -354,7 +351,7 @@ grl_lastfm_albumart_source_resolve (GrlMetadataSource *source,
   gchar *esc_album = NULL;
   gchar *url = NULL;
 
-  GRL_DEBUG ("grl_lastfm_albumart_source_resolve");
+  GRL_DEBUG (__FUNCTION__);
 
   GList *iter;
 
@@ -371,7 +368,7 @@ grl_lastfm_albumart_source_resolve (GrlMetadataSource *source,
 
   if (iter == NULL) {
     GRL_DEBUG ("No supported key was requested");
-    rs->callback (source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
     artist = grl_data_get_string (GRL_DATA (rs->media),
                                   GRL_METADATA_KEY_ARTIST);
@@ -381,7 +378,7 @@ grl_lastfm_albumart_source_resolve (GrlMetadataSource *source,
 
     if (!artist || !album) {
       GRL_DEBUG ("Missing dependencies");
-      rs->callback (source, rs->resolve_id, rs->media, rs->user_data, NULL);
+      rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
     } else {
       esc_artist = g_uri_escape_string (artist, NULL, TRUE);
       esc_album = g_uri_escape_string (album, NULL, TRUE);
diff --git a/src/metadata/lastfm-albumart/grl-lastfm-albumart.h b/src/metadata/lastfm-albumart/grl-lastfm-albumart.h
index 43a5ab5..7d9e4b4 100644
--- a/src/metadata/lastfm-albumart/grl-lastfm-albumart.h
+++ b/src/metadata/lastfm-albumart/grl-lastfm-albumart.h
@@ -57,7 +57,7 @@ typedef struct _GrlLastfmAlbumartSource GrlLastfmAlbumartSource;
 
 struct _GrlLastfmAlbumartSource {
 
-  GrlMetadataSource parent;
+  GrlSource parent;
 
 };
 
@@ -65,7 +65,7 @@ typedef struct _GrlLastfmAlbumartSourceClass GrlLastfmAlbumartSourceClass;
 
 struct _GrlLastfmAlbumartSourceClass {
 
-  GrlMetadataSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/metadata/local-metadata/grl-local-metadata.c b/src/metadata/local-metadata/grl-local-metadata.c
index 514c011..c3a5726 100644
--- a/src/metadata/local-metadata/grl-local-metadata.c
+++ b/src/metadata/local-metadata/grl-local-metadata.c
@@ -101,19 +101,19 @@ static void grl_local_metadata_source_set_property (GObject      *object,
 
 static GrlLocalMetadataSource *grl_local_metadata_source_new (gboolean guess_video);
 
-static void grl_local_metadata_source_resolve (GrlMetadataSource *source,
-                                              GrlMetadataSourceResolveSpec *rs);
+static void grl_local_metadata_source_resolve (GrlSource *source,
+                                               GrlSourceResolveSpec *rs);
 
 static const GList *grl_local_metadata_source_supported_keys (GrlSource *source);
 
-static gboolean grl_local_metadata_source_may_resolve (GrlMetadataSource *source,
+static void grl_local_metadata_source_cancel (GrlSource *source,
+                                              guint operation_id);
+
+static gboolean grl_local_metadata_source_may_resolve (GrlSource *source,
                                                        GrlMedia *media,
                                                        GrlKeyID key_id,
                                                        GList **missing_keys);
 
-static void grl_local_metadata_source_cancel (GrlSource *source,
-                                              guint operation_id);
-
 gboolean grl_local_metadata_source_plugin_init (GrlPluginRegistry *registry,
                                                 GrlPlugin *plugin,
                                                 GList *configs);
@@ -179,15 +179,13 @@ grl_local_metadata_source_class_init (GrlLocalMetadataSourceClass * klass)
 {
   GObjectClass           *g_class        = G_OBJECT_CLASS (klass);
   GrlSourceClass         *source_class   = GRL_SOURCE_CLASS (klass);
-  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
 
   g_class->set_property = grl_local_metadata_source_set_property;
 
   source_class->supported_keys = grl_local_metadata_source_supported_keys;
   source_class->cancel = grl_local_metadata_source_cancel;
-
-  metadata_class->may_resolve = grl_local_metadata_source_may_resolve;
-  metadata_class->resolve = grl_local_metadata_source_resolve;
+  source_class->may_resolve = grl_local_metadata_source_may_resolve;
+  source_class->resolve = grl_local_metadata_source_resolve;
 
   g_object_class_install_property (g_class,
                                    PROP_GUESS_VIDEO,
@@ -209,7 +207,7 @@ grl_local_metadata_source_init (GrlLocalMetadataSource *source)
 
 G_DEFINE_TYPE (GrlLocalMetadataSource,
                grl_local_metadata_source,
-               GRL_TYPE_METADATA_SOURCE);
+               GRL_TYPE_SOURCE);
 
 static void
 grl_local_metadata_source_set_property (GObject      *object,
@@ -417,8 +415,9 @@ video_guess_values_from_uri (const gchar *uri,
 }
 
 static void
-got_file_info (GFile *file, GAsyncResult *result,
-               GrlMetadataSourceResolveSpec *rs)
+got_file_info (GFile *file,
+               GAsyncResult *result,
+               GrlSourceResolveSpec *rs)
 {
   GCancellable *cancellable;
   GFileInfo *info;
@@ -428,7 +427,7 @@ got_file_info (GFile *file, GAsyncResult *result,
   GRL_DEBUG ("got_file_info");
 
   /* Free stored operation data */
-  cancellable = grl_operation_get_data (rs->resolve_id);
+  cancellable = grl_operation_get_data (rs->operation_id);
 
   if (cancellable) {
     g_object_unref (cancellable);
@@ -452,11 +451,11 @@ got_file_info (GFile *file, GAsyncResult *result,
     grl_media_set_thumbnail (rs->media, thumbnail_uri);
     g_free (thumbnail_uri);
 
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
     GRL_INFO ("Could not find thumbnail for media: %s",
               grl_media_get_url (rs->media));
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   }
 
   goto exit;
@@ -465,7 +464,7 @@ error:
     {
       GError *new_error = g_error_new (GRL_CORE_ERROR, GRL_CORE_ERROR_RESOLVE_FAILED,
                                        "Got error: %s", error->message);
-      rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, new_error);
+      rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, new_error);
 
       g_error_free (error);
       g_error_free (new_error);
@@ -477,8 +476,8 @@ exit:
 }
 
 static void
-resolve_video (GrlMetadataSource *source,
-               GrlMetadataSourceResolveSpec *rs,
+resolve_video (GrlSource *source,
+               GrlSourceResolveSpec *rs,
                GrlKeyID key,
                resolution_flags_t flags)
 {
@@ -554,8 +553,8 @@ resolve_video (GrlMetadataSource *source,
 }
 
 static gboolean
-resolve_image (GrlMetadataSource *source,
-               GrlMetadataSourceResolveSpec *rs,
+resolve_image (GrlSource *source,
+               GrlSourceResolveSpec *rs,
                resolution_flags_t flags)
 {
   GFile *file;
@@ -567,7 +566,7 @@ resolve_image (GrlMetadataSource *source,
     file = g_file_new_for_uri (grl_media_get_url (rs->media));
 
     cancellable = g_cancellable_new ();
-    grl_operation_set_data (rs->resolve_id, cancellable);
+    grl_operation_set_data (rs->operation_id, cancellable);
     g_file_query_info_async (file, G_FILE_ATTRIBUTE_THUMBNAIL_PATH,
                              G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, cancellable,
                              (GAsyncReadyCallback)got_file_info, rs);
@@ -713,8 +712,8 @@ albumart_strip_invalid_entities (const gchar *original)
 }
 
 static gboolean
-resolve_album_art (GrlMetadataSource *source,
-                   GrlMetadataSourceResolveSpec *rs,
+resolve_album_art (GrlSource *source,
+                   GrlSourceResolveSpec *rs,
                    resolution_flags_t flags)
 {
   const gchar *artist_value, *album_value;
@@ -772,7 +771,7 @@ resolve_album_art (GrlMetadataSource *source,
     g_free (thumbnail_uri);
     g_free (file_path);
   }
-  rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+  rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
 
   return FALSE;
 }
@@ -871,7 +870,7 @@ grl_local_metadata_source_supported_keys (GrlSource *source)
 }
 
 static gboolean
-grl_local_metadata_source_may_resolve (GrlMetadataSource *source,
+grl_local_metadata_source_may_resolve (GrlSource *source,
                                        GrlMedia *media,
                                        GrlKeyID key_id,
                                        GList **missing_keys)
@@ -959,8 +958,8 @@ missing_url:
 }
 
 static void
-grl_local_metadata_source_resolve (GrlMetadataSource *source,
-                                  GrlMetadataSourceResolveSpec *rs)
+grl_local_metadata_source_resolve (GrlSource *source,
+                                   GrlSourceResolveSpec *rs)
 {
   GError *error = NULL;
   resolution_flags_t flags;
@@ -969,7 +968,7 @@ grl_local_metadata_source_resolve (GrlMetadataSource *source,
   gboolean can_access;
   gboolean done;
 
-  GRL_DEBUG ("grl_local_metadata_source_resolve");
+  GRL_DEBUG (__FUNCTION__);
 
   /* Can we access the media through gvfs? */
   can_access = has_compatible_media_url (rs->media);
@@ -985,7 +984,7 @@ grl_local_metadata_source_resolve (GrlMetadataSource *source,
 
   if (error) {
     /* No can do! */
-    rs->callback (source, rs->resolve_id, rs->media, rs->user_data, error);
+    rs->callback (source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -1009,7 +1008,7 @@ grl_local_metadata_source_resolve (GrlMetadataSource *source,
   /* Only call the callback if there are no async jobs left-over,
    * such as resolve_image() checking for thumbnails */
   if (done)
-    rs->callback (source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
 }
 
 static void
diff --git a/src/metadata/local-metadata/grl-local-metadata.h b/src/metadata/local-metadata/grl-local-metadata.h
index f680061..7d6bfd9 100644
--- a/src/metadata/local-metadata/grl-local-metadata.h
+++ b/src/metadata/local-metadata/grl-local-metadata.h
@@ -56,7 +56,7 @@ typedef struct _GrlLocalMetadataSourcePriv GrlLocalMetadataSourcePriv;
 
 struct _GrlLocalMetadataSource {
 
-  GrlMetadataSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlLocalMetadataSourcePriv *priv;
@@ -67,7 +67,7 @@ typedef struct _GrlLocalMetadataSourceClass GrlLocalMetadataSourceClass;
 
 struct _GrlLocalMetadataSourceClass {
 
-  GrlMetadataSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/src/metadata/metadata-store/grl-metadata-store.c b/src/metadata/metadata-store/grl-metadata-store.c
index 3b14c33..64c0d4c 100644
--- a/src/metadata/metadata-store/grl-metadata-store.c
+++ b/src/metadata/metadata-store/grl-metadata-store.c
@@ -86,19 +86,19 @@ enum {
 
 static GrlMetadataStoreSource *grl_metadata_store_source_new (void);
 
-static void grl_metadata_store_source_resolve (GrlMetadataSource *source,
-					       GrlMetadataSourceResolveSpec *rs);
+static void grl_metadata_store_source_resolve (GrlSource *source,
+                                               GrlSourceResolveSpec *rs);
 
-static void grl_metadata_store_source_set_metadata (GrlMetadataSource *source,
-						    GrlMetadataSourceSetMetadataSpec *sms);
+static void grl_metadata_store_source_store_metadata (GrlSource *source,
+                                                      GrlSourceStoreMetadataSpec *sms);
 
-static const GList *grl_metadata_store_source_supported_keys (GrlSource *source);
-
-static gboolean grl_metadata_store_source_may_resolve (GrlMetadataSource *source,
+static gboolean grl_metadata_store_source_may_resolve (GrlSource *source,
                                                        GrlMedia *media,
                                                        GrlKeyID key_id,
                                                        GList **missing_keys);
 
+static const GList *grl_metadata_store_source_supported_keys (GrlSource *source);
+
 static const GList *grl_metadata_store_source_writable_keys (GrlSource *source);
 
 gboolean grl_metadata_store_source_plugin_init (GrlPluginRegistry *registry,
@@ -110,8 +110,8 @@ gboolean grl_metadata_store_source_plugin_init (GrlPluginRegistry *registry,
 
 gboolean
 grl_metadata_store_source_plugin_init (GrlPluginRegistry *registry,
-                                      GrlPlugin *plugin,
-                                      GList *configs)
+                                       GrlPlugin *plugin,
+                                       GList *configs)
 {
   GRL_LOG_DOMAIN_INIT (metadata_store_log_domain, "metadata-store");
 
@@ -146,14 +146,12 @@ static void
 grl_metadata_store_source_class_init (GrlMetadataStoreSourceClass * klass)
 {
   GrlSourceClass *source_class = GRL_SOURCE_CLASS (klass);
-  GrlMetadataSourceClass *metadata_class = GRL_METADATA_SOURCE_CLASS (klass);
 
   source_class->supported_keys = grl_metadata_store_source_supported_keys;
   source_class->writable_keys = grl_metadata_store_source_writable_keys;
-
-  metadata_class->may_resolve = grl_metadata_store_source_may_resolve;
-  metadata_class->resolve = grl_metadata_store_source_resolve;
-  metadata_class->set_metadata = grl_metadata_store_source_set_metadata;
+  source_class->may_resolve = grl_metadata_store_source_may_resolve;
+  source_class->resolve = grl_metadata_store_source_resolve;
+  source_class->store_metadata = grl_metadata_store_source_store_metadata;
 
   g_type_class_add_private (klass, sizeof (GrlMetadataStorePrivate));
 }
@@ -208,8 +206,9 @@ grl_metadata_store_source_init (GrlMetadataStoreSource *source)
   GRL_DEBUG ("  OK");
 }
 
-G_DEFINE_TYPE (GrlMetadataStoreSource, grl_metadata_store_source,
-               GRL_TYPE_METADATA_SOURCE);
+G_DEFINE_TYPE (GrlMetadataStoreSource,
+               grl_metadata_store_source,
+               GRL_TYPE_SOURCE);
 
 /* ======================= Utilities ==================== */
 
@@ -447,7 +446,7 @@ static GList *
 write_keys (sqlite3 *db,
 	    const gchar *source_id,
 	    const gchar *media_id,
-	    GrlMetadataSourceSetMetadataSpec *sms,
+	    GrlSourceStoreMetadataSpec *sms,
 	    GError **error)
 {
   GList *col_names = NULL;
@@ -478,9 +477,9 @@ write_keys (sqlite3 *db,
     GRL_WARNING ("Failed to update metadata, none of the specified "
                      "keys is writable");
     *error = g_error_new (GRL_CORE_ERROR,
-			  GRL_CORE_ERROR_SET_METADATA_FAILED,
-			  "Failed to update metadata, "
-			  "specified keys are not writable");
+                          GRL_CORE_ERROR_STORE_METADATA_FAILED,
+                          "Failed to update metadata, "
+                          "specified keys are not writable");
     goto done;
   }
 
@@ -497,8 +496,8 @@ write_keys (sqlite3 *db,
     g_list_free (failed_keys);
     failed_keys = g_list_copy (sms->keys);
     *error = g_error_new (GRL_CORE_ERROR,
-			  GRL_CORE_ERROR_SET_METADATA_FAILED,
-			  "Failed to update metadata");
+                          GRL_CORE_ERROR_STORE_METADATA_FAILED,
+                          "Failed to update metadata");
     goto done;
   } 
   
@@ -518,8 +517,8 @@ write_keys (sqlite3 *db,
     g_list_free (failed_keys);
     failed_keys = g_list_copy (sms->keys);
     *error = g_error_new (GRL_CORE_ERROR,
-			  GRL_CORE_ERROR_SET_METADATA_FAILED,
-			  "Failed to update metadata");
+                          GRL_CORE_ERROR_STORE_METADATA_FAILED,
+                          "Failed to update metadata");
     goto done;
   } 
 
@@ -559,7 +558,7 @@ grl_metadata_store_source_writable_keys (GrlSource *source)
 }
 
 static gboolean
-grl_metadata_store_source_may_resolve (GrlMetadataSource *source,
+grl_metadata_store_source_may_resolve (GrlSource *source,
                                        GrlMedia *media,
                                        GrlKeyID key_id,
                                        GList **missing_keys)
@@ -587,15 +586,15 @@ grl_metadata_store_source_may_resolve (GrlMetadataSource *source,
 }
 
 static void
-grl_metadata_store_source_resolve (GrlMetadataSource *source,
-				   GrlMetadataSourceResolveSpec *rs)
+grl_metadata_store_source_resolve (GrlSource *source,
+                                   GrlSourceResolveSpec *rs)
 {
-  GRL_DEBUG ("grl_metadata_store_source_resolve");
-
   const gchar *source_id, *media_id;
   sqlite3_stmt *stmt;
   GError *error = NULL;
 
+  GRL_DEBUG (__FUNCTION__);
+
   source_id = grl_media_get_source (rs->media);
   media_id = grl_media_get_id (rs->media);
 
@@ -605,7 +604,7 @@ grl_metadata_store_source_resolve (GrlMetadataSource *source,
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_RESOLVE_FAILED,
 			 "source-id not available, cannot resolve metadata.");
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
     return;
   }
@@ -619,20 +618,20 @@ grl_metadata_store_source_resolve (GrlMetadataSource *source,
 			       source_id, media_id);
   if (stmt) {
     fill_metadata (rs->media, rs->keys, stmt);
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, NULL);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, NULL);
   } else {
     GRL_WARNING ("Failed to resolve metadata");
     error = g_error_new (GRL_CORE_ERROR,
 			 GRL_CORE_ERROR_RESOLVE_FAILED,
 			 "Failed to resolve metadata.");
-    rs->callback (rs->source, rs->resolve_id, rs->media, rs->user_data, error);
+    rs->callback (rs->source, rs->operation_id, rs->media, rs->user_data, error);
     g_error_free (error);
   }
 }
 
 static void
-grl_metadata_store_source_set_metadata (GrlMetadataSource *source,
-					GrlMetadataSourceSetMetadataSpec *sms)
+grl_metadata_store_source_store_metadata (GrlSource *source,
+                                          GrlSourceStoreMetadataSpec *sms)
 {
   GRL_DEBUG ("grl_metadata_store_source_set_metadata");
 
@@ -647,8 +646,8 @@ grl_metadata_store_source_set_metadata (GrlMetadataSource *source,
   if (!source_id) {
     GRL_WARNING ("Failed to update metadata: source-id not available");
     error = g_error_new (GRL_CORE_ERROR,
-			 GRL_CORE_ERROR_SET_METADATA_FAILED,
-			 "source-id not available, cannot update metadata.");
+                         GRL_CORE_ERROR_STORE_METADATA_FAILED,
+                         "source-id not available, cannot update metadata.");
     failed_keys = g_list_copy (sms->keys);
   } else {
     /* Special case for root categories */
diff --git a/src/metadata/metadata-store/grl-metadata-store.h b/src/metadata/metadata-store/grl-metadata-store.h
index 47df494..051a5db 100644
--- a/src/metadata/metadata-store/grl-metadata-store.h
+++ b/src/metadata/metadata-store/grl-metadata-store.h
@@ -56,7 +56,7 @@ typedef struct _GrlMetadataStoreSource GrlMetadataStoreSource;
 
 struct _GrlMetadataStoreSource {
 
-  GrlMetadataSource parent;
+  GrlSource parent;
 
   /*< private >*/
   GrlMetadataStorePrivate *priv;
@@ -66,7 +66,7 @@ typedef struct _GrlMetadataStoreSourceClass GrlMetadataStoreSourceClass;
 
 struct _GrlMetadataStoreSourceClass {
 
-  GrlMetadataSourceClass parent_class;
+  GrlSourceClass parent_class;
 
 };
 
diff --git a/test/main.c b/test/main.c
index 160f9d7..6b569e5 100644
--- a/test/main.c
+++ b/test/main.c
@@ -38,9 +38,6 @@ print_supported_ops (GrlSource *source)
 
   GrlSupportedOps caps = grl_source_supported_operations (source);
 
-  if (caps & GRL_OP_METADATA) {
-    GRL_DEBUG ("    + Metadata");
-  }
   if (caps & GRL_OP_RESOLVE) {
     GRL_DEBUG ("    + Resolution");
   }
@@ -61,8 +58,8 @@ print_supported_ops (GrlSource *source)
   if (caps & GRL_OP_REMOVE) {
     GRL_DEBUG ("    + Remove");
   }
-  if (caps & GRL_OP_SET_METADATA) {
-    GRL_DEBUG ("    + Set Metadata");
+  if (caps & GRL_OP_STORE_METADATA) {
+    GRL_DEBUG ("    + Store Metadata");
   }
 }
 
@@ -104,12 +101,12 @@ box_from_id (const gchar *id)
 }
 
 static void
-browse_cb (GrlMediaSource *source,
-	   guint browse_id,
+browse_cb (GrlSource *source,
+           guint browse_id,
            GrlMedia *media,
-	   guint remaining,
-	   gpointer user_data,
-	   const GError *error)
+           guint remaining,
+           gpointer user_data,
+           const GError *error)
 {
   GList *keys;
   static guint index = 0;
@@ -138,15 +135,15 @@ browse_cb (GrlMediaSource *source,
 }
 
 static void
-metadata_cb (GrlMediaSource *source,
+resolve_cb (GrlSource *source,
              guint operation_id,
-	     GrlMedia *media,
-	     gpointer user_data,
-	     const GError *error)
+             GrlMedia *media,
+             gpointer user_data,
+             const GError *error)
 {
   GList *keys;
 
-  GRL_DEBUG ("  metadata_cb");
+  GRL_DEBUG ("  resolve_cb");
 
   if (error) {
     GRL_DEBUG ("Error: %s", error->message);
@@ -167,21 +164,11 @@ metadata_cb (GrlMediaSource *source,
 }
 
 static void
-resolve_cb (GrlMetadataSource *source,
-            guint resolve_id,
-            GrlMedia *media,
-            gpointer user_data,
-            const GError *error)
-{
-  metadata_cb (NULL, 0, media, user_data, error);
-}
-
-static void
-set_cb (GrlMetadataSource *source,
-	GrlMedia *media,
-	GList *failed_keys,
-	gpointer user_data,
-	const GError *error)
+set_cb (GrlSource *source,
+        GrlMedia *media,
+        GList *failed_keys,
+        gpointer user_data,
+        const GError *error)
 {
   if (error) {
     g_critical ("%s: %d keys not written",
@@ -274,49 +261,49 @@ main (void)
 
   GRL_DEBUG ("Obtaining sources");
 
-  GrlMediaSource *youtube =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-youtube");
+  GrlSource *youtube =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-youtube");
 
-  GrlMediaSource *fs =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-filesystem");
+  GrlSource *fs =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-filesystem");
 
-  GrlMediaSource *flickr =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-flickr");
+  GrlSource *flickr =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-flickr");
 
-  GrlMediaSource *jamendo =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-jamendo");
+  GrlSource *jamendo =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-jamendo");
 
-  GrlMediaSource *shoutcast =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-shoutcast");
+  GrlSource *shoutcast =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-shoutcast");
 
-  GrlMediaSource *apple_trailers =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-apple-trailers");
+  GrlSource *apple_trailers =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-apple-trailers");
 
-  GrlMetadataSource *fake =
-    (GrlMetadataSource *) grl_plugin_registry_lookup_source (registry,
-                                                             "grl-fake-metadata");
+  GrlSource *fake =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-fake-metadata");
 
-  GrlMetadataSource *lastfm =
-    (GrlMetadataSource *) grl_plugin_registry_lookup_source (registry,
-                                                             "grl-lastfm-albumart");
+  GrlSource *lastfm =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-lastfm-albumart");
 
-  GrlMetadataSource *metadata_store =
-    (GrlMetadataSource *) grl_plugin_registry_lookup_source (registry,
-                                                             "grl-metadata-store");
+  GrlSource *metadata_store =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-metadata-store");
 
-  GrlMediaSource *bookmarks =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-bookmarks");
+  GrlSource *bookmarks =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-bookmarks");
 
-  GrlMediaSource *podcasts =
-    (GrlMediaSource *) grl_plugin_registry_lookup_source (registry,
-                                                          "grl-podcasts");
+  GrlSource *podcasts =
+    grl_plugin_registry_lookup_source (registry,
+                                       "grl-podcasts");
 
   g_assert (youtube);
   g_assert (fs);
@@ -329,58 +316,58 @@ main (void)
   g_assert (podcasts);
   GRL_DEBUG ("Supported operations");
 
-  print_supported_ops (GRL_SOURCE (youtube));
-  print_supported_ops (GRL_SOURCE (fs));
-  if (flickr) print_supported_ops (GRL_SOURCE (flickr));
-  print_supported_ops (GRL_SOURCE (jamendo));
-  print_supported_ops (GRL_SOURCE (apple_trailers));
-  print_supported_ops (GRL_SOURCE (shoutcast));
+  if (youtube) print_supported_ops (youtube);
+  if (fs) print_supported_ops (fs);
+  if (flickr) print_supported_ops (flickr);
+  if (jamendo) print_supported_ops (jamendo);
+  if (apple_trailers) print_supported_ops (apple_trailers);
+  if (shoutcast) print_supported_ops (shoutcast);
   if (fake) print_supported_ops (fake);
-  print_supported_ops (GRL_SOURCE (podcasts));
-  print_supported_ops (GRL_SOURCE (bookmarks));
-  print_supported_ops (lastfm);
-  print_supported_ops (metadata_store);
+  if (podcasts) print_supported_ops (podcasts);
+  if (bookmarks) print_supported_ops (bookmarks);
+  if (lastfm) print_supported_ops (lastfm);
+  if (metadata_store) print_supported_ops (metadata_store);
 
   GRL_DEBUG ("testing");
 
-  if (0) grl_media_source_browse (youtube, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (youtube, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (youtube, media_from_id ("standard-feeds/most-viewed"), keys, 0, 10, GRL_RESOLVE_FAST_ONLY , browse_cb, NULL);
-  if (0) grl_media_source_browse (youtube, media_from_id ("categories/Sports"), keys,  0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_search (youtube, "igalia", keys, 0, 5, GRL_RESOLVE_NORMAL, browse_cb, NULL);
-  if (0) grl_media_source_search (youtube, "igalia", keys, 1, 10, GRL_RESOLVE_FULL | GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_metadata (youtube, NULL, keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (youtube, NULL, keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY | GRL_RESOLVE_FULL, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (youtube, NULL, keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY , metadata_cb, NULL);
-  if (0) grl_media_source_metadata (youtube, NULL, keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_browse (fs, media_from_id ("/home"), keys, 0, 100, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FULL, browse_cb, NULL);
-  if (0) grl_media_source_metadata (fs, media_from_id ("/home"), keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FULL, metadata_cb, NULL);
-  if (0) grl_media_source_search (flickr, "igalia", keys, 1, 10, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_metadata (flickr, media_from_id ("4201406347"), keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FULL, metadata_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, media_from_id("1"), keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, media_from_id("1/9"), keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, media_from_id("2"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, media_from_id("2/25"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, media_from_id("2/1225"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (jamendo, media_from_id("3/174"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_metadata (jamendo, NULL, keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (jamendo, media_from_id("1"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (jamendo, media_from_id("1/9"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (jamendo, media_from_id("2/1225"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (jamendo, media_from_id("3/174"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_query (jamendo, "artist=shake da", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_query (jamendo, "album=Nick", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_query (jamendo, "track=asylum mind", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_search (jamendo, "next", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_browse (shoutcast, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_browse (shoutcast, media_from_id("American"), keys, 2, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
-  if (0) grl_media_source_search (shoutcast, "Roxette", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
-  if (0) grl_media_source_metadata (shoutcast, box_from_id("24hs"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (shoutcast, box_from_id("2424hs"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (shoutcast, media_from_id("American/556687"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_metadata (shoutcast, media_from_id("American/556682"), keys, 0, metadata_cb, NULL);
-  if (0) grl_media_source_browse (apple_trailers, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (youtube, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (youtube, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (youtube, media_from_id ("standard-feeds/most-viewed"), keys, 0, 10, GRL_RESOLVE_FAST_ONLY , browse_cb, NULL);
+  if (0) grl_source_browse (youtube, media_from_id ("categories/Sports"), keys,  0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_search (youtube, "igalia", keys, 0, 5, GRL_RESOLVE_NORMAL, browse_cb, NULL);
+  if (0) grl_source_search (youtube, "igalia", keys, 1, 10, GRL_RESOLVE_FULL | GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_resolve (youtube, NULL, keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (youtube, NULL, keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY | GRL_RESOLVE_FULL, resolve_cb, NULL);
+  if (0) grl_source_resolve (youtube, NULL, keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FAST_ONLY , resolve_cb, NULL);
+  if (0) grl_source_resolve (youtube, NULL, keys, 0, resolve_cb, NULL);
+  if (0) grl_source_browse (fs, media_from_id ("/home"), keys, 0, 100, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FULL, browse_cb, NULL);
+  if (0) grl_source_resolve (fs, media_from_id ("/home"), keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FULL, resolve_cb, NULL);
+  if (0) grl_source_search (flickr, "igalia", keys, 1, 10, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_resolve (flickr, media_from_id ("4201406347"), keys, GRL_RESOLVE_IDLE_RELAY | GRL_RESOLVE_FULL, resolve_cb, NULL);
+  if (0) grl_source_browse (jamendo, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (jamendo, media_from_id("1"), keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (jamendo, media_from_id("1/9"), keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (jamendo, media_from_id("2"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (jamendo, media_from_id("2/25"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (jamendo, media_from_id("2/1225"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (jamendo, media_from_id("3/174"), keys, -1, 2, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_resolve (jamendo, NULL, keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (jamendo, media_from_id("1"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (jamendo, media_from_id("1/9"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (jamendo, media_from_id("2/1225"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (jamendo, media_from_id("3/174"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_query (jamendo, "artist=shake da", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_query (jamendo, "album=Nick", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_query (jamendo, "track=asylum mind", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_search (jamendo, "next", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_browse (shoutcast, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_browse (shoutcast, media_from_id("American"), keys, 2, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
+  if (0) grl_source_search (shoutcast, "Roxette", keys, 0, 5, GRL_RESOLVE_FAST_ONLY, browse_cb, NULL);
+  if (0) grl_source_resolve (shoutcast, box_from_id("24hs"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (shoutcast, box_from_id("2424hs"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (shoutcast, media_from_id("American/556687"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_resolve (shoutcast, media_from_id("American/556682"), keys, 0, resolve_cb, NULL);
+  if (0) grl_source_browse (apple_trailers, NULL, keys, 0, 5, GRL_RESOLVE_IDLE_RELAY , browse_cb, NULL);
   if (0) {
     GrlMedia *media = media_from_id ("test");
     grl_data_set_string (GRL_DATA (media),
@@ -389,7 +376,7 @@ main (void)
     grl_data_set_string (GRL_DATA (media),
                          GRL_METADATA_KEY_ALBUM,
                          "pop hits");
-    grl_metadata_source_resolve (lastfm, keys, media, GRL_RESOLVE_IDLE_RELAY, resolve_cb, NULL);
+    grl_source_resolve (lastfm, media, keys, GRL_RESOLVE_IDLE_RELAY, resolve_cb, NULL);
   }
   if (0) {
     GrlMedia *media = media_from_id ("test-id");
@@ -406,8 +393,9 @@ main (void)
 						      GRL_METADATA_KEY_TITLE,
                                                       GRL_METADATA_KEY_GENRE,
 						      NULL);
-    grl_metadata_source_set_metadata (metadata_store, media, keys_to_write,
-				      GRL_WRITE_FULL, set_cb, NULL);
+    grl_source_store_metadata (metadata_store,
+                               media, keys_to_write,
+                               GRL_WRITE_FULL, set_cb, NULL);
   }
 
   GRL_DEBUG ("Running main loop");
diff --git a/test/test_local_metadata.c b/test/test_local_metadata.c
index fb6c147..734124f 100644
--- a/test/test_local_metadata.c
+++ b/test/test_local_metadata.c
@@ -45,7 +45,7 @@
  * It's a test program, global variables are allowed!
  */
 
-GrlMetadataSource *local_source = NULL;
+GrlSource *local_source = NULL;
 GMainLoop *loop = NULL;
 
 static gchar *
@@ -151,8 +151,8 @@ setup (void)
   registry = grl_plugin_registry_get_default ();
   grl_plugin_registry_load_all (registry, NULL);
   local_source =
-      GRL_METADATA_SOURCE (grl_plugin_registry_lookup_source (registry,
-                                                              LOCAL_SOURCE_ID));
+    GRL_SOURCE (grl_plugin_registry_lookup_source (registry,
+                                                   LOCAL_SOURCE_ID));
 
 finish:
   return ret;
@@ -194,8 +194,8 @@ test_image_thumbnail (void)
 
   keys = grl_metadata_key_list_new (GRL_METADATA_KEY_THUMBNAIL, NULL);
 
-  media = grl_metadata_source_resolve_sync (local_source, keys, media,
-                                            GRL_RESOLVE_NORMAL, &error);
+  media = grl_source_resolve_sync (GRL_SOURCE (local_source), media, keys,
+                                   GRL_RESOLVE_NORMAL, &error);
   if (error) {
     g_clear_error (&error);
     ret = FALSE;
@@ -238,8 +238,8 @@ test_image_no_thumbnail (void)
 
   keys = grl_metadata_key_list_new (GRL_METADATA_KEY_THUMBNAIL, NULL);
 
-  media = grl_metadata_source_resolve_sync (local_source, keys, media,
-                                            GRL_RESOLVE_NORMAL, &error);
+  media = grl_source_resolve_sync (GRL_SOURCE (local_source), media, keys,
+                                   GRL_RESOLVE_NORMAL, &error);
   if (error) {
     g_clear_error (&error);
     ret = FALSE;



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