[tracker/external-crawler: 42/45] libtracker-miner: Split TrackerEnumerator into 2 classes, now with TrackerDataProvider



commit 2be3f349c813447599d6c6ef23e1ad01de0f4b87
Author: Martyn Russell <martyn lanedo com>
Date:   Tue Aug 12 19:12:42 2014 +0100

    libtracker-miner: Split TrackerEnumerator into 2 classes, now with TrackerDataProvider
    
    So now we have:
    - TrackerEnumerator (GInterface)
    - TrackerFileEnumerator (using GIO API)
    - TrackerDataProvider (GInterface) which provides a TrackerEnumerator
    - TrackerFileDataProvider (using GIO API) implemented as internal default

 .../libtracker-miner/libtracker-miner-docs.sgml    |   12 +-
 .../libtracker-miner/libtracker-miner-sections.txt |  311 +++++++++-------
 src/libtracker-miner/Makefile.am                   |   13 +-
 src/libtracker-miner/tracker-crawler.c             |  311 ++++++++++------
 src/libtracker-miner/tracker-crawler.h             |    4 +-
 src/libtracker-miner/tracker-data-provider.c       |  403 ++++++++++++++++++++
 src/libtracker-miner/tracker-data-provider.h       |  165 ++++++++
 src/libtracker-miner/tracker-enumerator.c          |  173 +++------
 src/libtracker-miner/tracker-enumerator.h          |   82 ++---
 src/libtracker-miner/tracker-file-data-provider.c  |  255 +++++++++++++
 src/libtracker-miner/tracker-file-data-provider.h  |   62 +++
 src/libtracker-miner/tracker-file-enumerator.c     |  240 ++++---------
 src/libtracker-miner/tracker-file-enumerator.h     |    2 +-
 src/libtracker-miner/tracker-file-notifier.c       |   32 +-
 src/libtracker-miner/tracker-file-notifier.h       |    2 +-
 src/libtracker-miner/tracker-miner-fs.c            |   56 ++--
 src/libtracker-miner/tracker-miner-fs.h            |    6 +-
 src/libtracker-miner/tracker-miner.h               |    3 +-
 .../tracker-file-enumerator-test.c                 |   75 +++--
 19 files changed, 1529 insertions(+), 678 deletions(-)
---
diff --git a/docs/reference/libtracker-miner/libtracker-miner-docs.sgml 
b/docs/reference/libtracker-miner/libtracker-miner-docs.sgml
index 582c152..6d19210 100644
--- a/docs/reference/libtracker-miner/libtracker-miner-docs.sgml
+++ b/docs/reference/libtracker-miner/libtracker-miner-docs.sgml
@@ -29,25 +29,33 @@
     </partintro>
 
     <chapter>
+      <title>Basics and foundations</title>
+      <xi:include href="xml/tracker-miner-enums.xml"/>
+      <xi:include href="xml/tracker-miner-common.xml"/>
+    </chapter>
+
+    <chapter>
       <title>Base abstract miner classes</title>
       <xi:include href="xml/tracker-miner-object.xml"/>
       <xi:include href="xml/tracker-miner-online.xml"/>
+      <xi:include href="xml/tracker-data-provider.xml"/>
       <xi:include href="xml/tracker-enumerator.xml"/>
       <xi:include href="xml/tracker-decorator.xml"/>
+      <xi:include href="xml/tracker-indexing-tree.xml"/>
     </chapter>
 
     <chapter>
       <title>Miner classes for file system</title>
       <xi:include href="xml/tracker-miner-fs.xml"/>
+      <xi:include href="xml/tracker-file-data-provider.xml"/>
       <xi:include href="xml/tracker-file-enumerator.xml"/>
-      <xi:include href="xml/tracker-indexing-tree.xml"/>
       <xi:include href="xml/tracker-decorator-fs.xml"/>
     </chapter>
 
     <chapter>
       <title>Utilities</title>
       <xi:include href="xml/tracker-thumbnailer.xml"/>
-      <xi:include href="xml/tracker-miner-enums.xml"/>
+      <xi:include href="xml/tracker-media-art.xml"/>
     </chapter>
   </part>
 
diff --git a/docs/reference/libtracker-miner/libtracker-miner-sections.txt 
b/docs/reference/libtracker-miner/libtracker-miner-sections.txt
index 965d8df..241681f 100644
--- a/docs/reference/libtracker-miner/libtracker-miner-sections.txt
+++ b/docs/reference/libtracker-miner/libtracker-miner-sections.txt
@@ -1,24 +1,143 @@
 <SECTION>
+<FILE>tracker-data-provider</FILE>
+<TITLE>TrackerDataProvider</TITLE>
+TrackerDataProviderIface
+tracker_data_provider_get_crawl_flags
+tracker_data_provider_set_crawl_flags
+tracker_data_provider_begin
+tracker_data_provider_begin_async
+tracker_data_provider_begin_finish
+tracker_data_provider_end
+tracker_data_provider_end_async
+tracker_data_provider_end_finish
+TrackerDataProvider
+<SUBSECTION Standard>
+TRACKER_DATA_PROVIDER
+TRACKER_DATA_PROVIDER_GET_IFACE
+TRACKER_IS_DATA_PROVIDER
+TRACKER_TYPE_DATA_PROVIDER
+tracker_data_provider_get_type
+</SECTION>
+
+<SECTION>
+<FILE>tracker-decorator</FILE>
+<TITLE>TrackerDecorator</TITLE>
+TrackerDecorator
+TrackerDecoratorClass
+TrackerDecoratorError
+tracker_decorator_error_quark
+tracker_decorator_get_data_source
+tracker_decorator_get_class_names
+tracker_decorator_get_n_items
+tracker_decorator_prepend_id
+tracker_decorator_delete_id
+tracker_decorator_next
+tracker_decorator_next_finish
+tracker_decorator_set_priority_rdf_types
+tracker_decorator_info_ref
+tracker_decorator_info_unref
+tracker_decorator_info_get_urn
+tracker_decorator_info_get_url
+tracker_decorator_info_get_mimetype
+tracker_decorator_info_get_task
+tracker_decorator_info_get_sparql
+<SUBSECTION Standard>
+TRACKER_DECORATOR
+TRACKER_DECORATOR_CLASS
+TRACKER_DECORATOR_GET_CLASS
+TRACKER_IS_DECORATOR
+TRACKER_IS_DECORATOR_CLASS
+TRACKER_TYPE_DECORATOR
+TrackerDecoratorInfo
+tracker_decorator_get_type
+tracker_decorator_info_get_type
+</SECTION>
+
+<SECTION>
+<FILE>tracker-decorator-fs</FILE>
+<TITLE>TrackerDecoratorFS</TITLE>
+TrackerDecoratorFS
+TrackerDecoratorFSClass
+<SUBSECTION Standard>
+TRACKER_DECORATOR_FS
+TRACKER_DECORATOR_FS_CLASS
+TRACKER_DECORATOR_FS_GET_CLASS
+TRACKER_IS_DECORATOR_FS
+TRACKER_IS_DECORATOR_FS_CLASS
+TRACKER_TYPE_DECORATOR_FS
+tracker_decorator_fs_get_type
+</SECTION>
+
+<SECTION>
+<FILE>tracker-enumerator</FILE>
+<TITLE>TrackerEnumerator</TITLE>
+TrackerEnumeratorIface
+tracker_enumerator_next
+tracker_enumerator_next_async
+tracker_enumerator_next_finish
+TrackerEnumerator
+<SUBSECTION Standard>
+TRACKER_ENUMERATOR
+TRACKER_ENUMERATOR_GET_IFACE
+TRACKER_IS_ENUMERATOR
+TRACKER_TYPE_ENUMERATOR
+tracker_enumerator_get_type
+</SECTION>
+
+<SECTION>
+<FILE>tracker-file-data-provider</FILE>
+<TITLE>TrackerFileDataProvider</TITLE>
+TrackerFileDataProviderClass
+tracker_file_data_provider_new
+TrackerFileDataProvider
+<SUBSECTION Standard>
+TRACKER_FILE_DATA_PROVIDER
+TRACKER_FILE_DATA_PROVIDER_CLASS
+TRACKER_FILE_DATA_PROVIDER_GET_CLASS
+TRACKER_IS_FILE_DATA_PROVIDER
+TRACKER_IS_FILE_DATA_PROVIDER_CLASS
+TRACKER_TYPE_FILE_DATA_PROVIDER
+TrackerFileDataProviderPrivate
+tracker_file_data_provider_get_type
+</SECTION>
+
+<SECTION>
+<FILE>tracker-file-enumerator</FILE>
+<TITLE>TrackerFileEnumerator</TITLE>
+TrackerFileEnumeratorClass
+tracker_file_enumerator_new
+TrackerFileEnumerator
+<SUBSECTION Standard>
+TRACKER_FILE_ENUMERATOR
+TRACKER_FILE_ENUMERATOR_CLASS
+TRACKER_FILE_ENUMERATOR_GET_CLASS
+TRACKER_IS_FILE_ENUMERATOR
+TRACKER_IS_FILE_ENUMERATOR_CLASS
+TRACKER_TYPE_FILE_ENUMERATOR
+tracker_file_enumerator_get_type
+</SECTION>
+
+<SECTION>
 <FILE>tracker-indexing-tree</FILE>
 <TITLE>TrackerIndexingTree</TITLE>
 TrackerIndexingTree
 TrackerIndexingTreeClass
+tracker_indexing_tree_new
 tracker_indexing_tree_add
+tracker_indexing_tree_remove
 tracker_indexing_tree_add_filter
 tracker_indexing_tree_clear_filters
-tracker_indexing_tree_file_is_indexable
-tracker_indexing_tree_file_is_root
 tracker_indexing_tree_file_matches_filter
-tracker_indexing_tree_get_default_policy
+tracker_indexing_tree_file_is_indexable
+tracker_indexing_tree_parent_is_indexable
 tracker_indexing_tree_get_filter_hidden
-tracker_indexing_tree_get_master_root
+tracker_indexing_tree_set_filter_hidden
+tracker_indexing_tree_get_default_policy
+tracker_indexing_tree_set_default_policy
 tracker_indexing_tree_get_root
+tracker_indexing_tree_get_master_root
+tracker_indexing_tree_file_is_root
 tracker_indexing_tree_list_roots
-tracker_indexing_tree_new
-tracker_indexing_tree_parent_is_indexable
-tracker_indexing_tree_remove
-tracker_indexing_tree_set_default_policy
-tracker_indexing_tree_set_filter_hidden
 <SUBSECTION Standard>
 TRACKER_INDEXING_TREE
 TRACKER_INDEXING_TREE_CLASS
@@ -30,8 +149,9 @@ tracker_indexing_tree_get_type
 </SECTION>
 
 <SECTION>
-<FILE>tracker-miner</FILE>
-TrackerMinerError
+<FILE>tracker-media-art</FILE>
+tracker_media_art_queue_remove
+tracker_media_art_queue_empty
 </SECTION>
 
 <SECTION>
@@ -42,19 +162,25 @@ TRACKER_MINER_FS_GRAPH_URN
 <SECTION>
 <FILE>tracker-miner-enum-types</FILE>
 <SUBSECTION Standard>
+TRACKER_TYPE_CRAWL_FLAGS
 TRACKER_TYPE_DIRECTORY_FLAGS
 TRACKER_TYPE_FILTER_POLICY
 TRACKER_TYPE_FILTER_TYPE
+TRACKER_TYPE_NETWORK_TYPE
+tracker_crawl_flags_get_type
 tracker_directory_flags_get_type
 tracker_filter_policy_get_type
 tracker_filter_type_get_type
+tracker_network_type_get_type
 </SECTION>
 
 <SECTION>
 <FILE>tracker-miner-enums</FILE>
 TrackerDirectoryFlags
-TrackerFilterPolicy
 TrackerFilterType
+TrackerFilterPolicy
+TrackerNetworkType
+TrackerCrawlFlags
 </SECTION>
 
 <SECTION>
@@ -63,31 +189,32 @@ TrackerFilterType
 TrackerMinerFS
 TrackerMinerFSClass
 TrackerMinerFSError
+tracker_miner_fs_error_quark
+tracker_miner_fs_get_indexing_tree
+tracker_miner_fs_get_data_provider
+tracker_miner_fs_get_throttle
+tracker_miner_fs_get_mtime_checking
+tracker_miner_fs_get_initial_crawling
+tracker_miner_fs_set_throttle
+tracker_miner_fs_set_mtime_checking
+tracker_miner_fs_set_initial_crawling
 tracker_miner_fs_add_directory_without_parent
-tracker_miner_fs_check_directory
-tracker_miner_fs_check_directory_with_priority
-tracker_miner_fs_check_file
-tracker_miner_fs_check_file_with_priority
 tracker_miner_fs_directory_add
 tracker_miner_fs_directory_remove
 tracker_miner_fs_directory_remove_full
-tracker_miner_fs_file_notify
 tracker_miner_fs_force_mtime_checking
+tracker_miner_fs_check_file
+tracker_miner_fs_check_file_with_priority
+tracker_miner_fs_check_directory
+tracker_miner_fs_check_directory_with_priority
 tracker_miner_fs_force_recheck
-tracker_miner_fs_get_indexing_tree
-tracker_miner_fs_get_enumerator
-tracker_miner_fs_get_initial_crawling
-tracker_miner_fs_get_mtime_checking
-tracker_miner_fs_get_parent_urn
-tracker_miner_fs_get_throttle
-tracker_miner_fs_get_urn
-tracker_miner_fs_has_items_to_process
-tracker_miner_fs_query_urn
-tracker_miner_fs_set_initial_crawling
-tracker_miner_fs_set_mtime_checking
-tracker_miner_fs_set_throttle
 tracker_miner_fs_writeback_file
 tracker_miner_fs_writeback_notify
+tracker_miner_fs_file_notify
+tracker_miner_fs_get_urn
+tracker_miner_fs_get_parent_urn
+tracker_miner_fs_query_urn
+tracker_miner_fs_has_items_to_process
 <SUBSECTION Standard>
 TRACKER_IS_MINER_FS
 TRACKER_IS_MINER_FS_CLASS
@@ -97,32 +224,32 @@ TRACKER_MINER_FS_GET_CLASS
 TRACKER_TYPE_MINER_FS
 TrackerMinerFSPrivate
 tracker_miner_fs_get_type
-tracker_miner_fs_error_quark
 </SECTION>
 
 <SECTION>
 <FILE>tracker-miner-object</FILE>
 <TITLE>TrackerMiner</TITLE>
-TRACKER_MINER_ERROR
-TRACKER_MINER_ERROR_DOMAIN
 TRACKER_MINER_DBUS_INTERFACE
 TRACKER_MINER_DBUS_NAME_PREFIX
 TRACKER_MINER_DBUS_PATH_PREFIX
+TRACKER_MINER_ERROR_DOMAIN
+TRACKER_MINER_ERROR
 TrackerMiner
 TrackerMinerClass
+TrackerMinerError
 tracker_miner_error_quark
-tracker_miner_get_connection
-tracker_miner_get_dbus_connection
-tracker_miner_get_dbus_full_name
-tracker_miner_get_dbus_full_path
-tracker_miner_get_n_pause_reasons
+tracker_miner_start
+tracker_miner_stop
 tracker_miner_ignore_next_update
-tracker_miner_is_paused
 tracker_miner_is_started
+tracker_miner_is_paused
+tracker_miner_get_n_pause_reasons
 tracker_miner_pause
 tracker_miner_resume
-tracker_miner_start
-tracker_miner_stop
+tracker_miner_get_connection
+tracker_miner_get_dbus_connection
+tracker_miner_get_dbus_full_name
+tracker_miner_get_dbus_full_path
 <SUBSECTION Standard>
 TRACKER_IS_MINER
 TRACKER_IS_MINER_CLASS
@@ -137,19 +264,17 @@ tracker_miner_get_type
 <SECTION>
 <FILE>tracker-miner-online</FILE>
 <TITLE>TrackerMinerOnline</TITLE>
-TrackerMinerOnline
 TrackerMinerOnlineClass
-tracker_miner_online_get_type
 tracker_miner_online_get_network_type
-TrackerNetworkType
-tracker_network_type_get_type
 <SUBSECTION Standard>
+TRACKER_IS_MINER_ONLINE
+TRACKER_IS_MINER_ONLINE_CLASS
 TRACKER_MINER_ONLINE
 TRACKER_MINER_ONLINE_CLASS
 TRACKER_MINER_ONLINE_GET_CLASS
-TRACKER_IS_MINER_ONLINE
-TRACKER_IS_MINER_ONLINE_CLASS
 TRACKER_TYPE_MINER_ONLINE
+TrackerMinerOnline
+tracker_miner_online_get_type
 </SECTION>
 
 <SECTION>
@@ -157,99 +282,17 @@ TRACKER_TYPE_MINER_ONLINE
 <TITLE>TrackerThumbnailer</TITLE>
 TrackerThumbnailer
 TrackerThumbnailerClass
-tracker_thumbnailer_cleanup
-tracker_thumbnailer_get_type
-tracker_thumbnailer_move_add
 tracker_thumbnailer_new
-tracker_thumbnailer_remove_add
 tracker_thumbnailer_send
+tracker_thumbnailer_move_add
+tracker_thumbnailer_remove_add
+tracker_thumbnailer_cleanup
 <SUBSECTION Standard>
+TRACKER_IS_THUMBNAILER
+TRACKER_IS_THUMBNAILER_CLASS
 TRACKER_THUMBNAILER
 TRACKER_THUMBNAILER_CLASS
 TRACKER_THUMBNAILER_GET_CLASS
-TRACKER_IS_THUMBNAILER
-TRACKER_IS_THUMBNAILER_CLASS
-TRACKER_TYPE_NETWORK_TYPE
 TRACKER_TYPE_THUMBNAILER
-</SECTION>
-
-<SECTION>
-<FILE>tracker-decorator</FILE>
-<TITLE>TrackerDecorator</TITLE>
-TrackerDecorator
-TrackerDecoratorClass
-TrackerDecoratorError
-TrackerDecoratorInfo
-tracker_decorator_get_type
-tracker_decorator_error_quark
-tracker_decorator_get_class_names
-tracker_decorator_get_data_source
-tracker_decorator_get_n_items
-tracker_decorator_set_priority_rdf_types
-tracker_decorator_prepend_id
-tracker_decorator_delete_id
-tracker_decorator_next
-tracker_decorator_next_finish
-tracker_decorator_info_get_type
-tracker_decorator_info_ref
-tracker_decorator_info_unref
-tracker_decorator_info_get_mimetype
-tracker_decorator_info_get_sparql
-tracker_decorator_info_get_task
-tracker_decorator_info_get_url
-tracker_decorator_info_get_urn
-<SUBSECTION Standard>
-TRACKER_DECORATOR
-TRACKER_DECORATOR_CLASS
-TRACKER_DECORATOR_GET_CLASS
-TRACKER_IS_DECORATOR
-TRACKER_IS_DECORATOR_CLASS
-TRACKER_TYPE_DECORATOR
-</SECTION>
-
-<SECTION>
-<FILE>tracker-decorator-fs</FILE>
-<TITLE>TrackerDecoratorFS</TITLE>
-TrackerDecoratorFS
-TrackerDecoratorFSClass
-tracker_decorator_fs_get_type
-<SUBSECTION Standard>
-TRACKER_DECORATOR_FS
-TRACKER_DECORATOR_FS_CLASS
-TRACKER_DECORATOR_FS_GET_CLASS
-TRACKER_IS_DECORATOR_FS
-TRACKER_IS_DECORATOR_FS_CLASS
-TRACKER_TYPE_DECORATOR_FS
-</SECTION>
-
-<SECTION>
-<FILE>tracker-enumerator</FILE>
-<TITLE>TrackerEnumerator</TITLE>
-TrackerEnumeratorIface
-tracker_enumerator_get_children
-tracker_enumerator_get_children_async
-tracker_enumerator_get_children_finish
-TrackerEnumerator
-<SUBSECTION Standard>
-TRACKER_ENUMERATOR
-TRACKER_ENUMERATOR_GET_IFACE
-TRACKER_IS_ENUMERATOR
-TRACKER_TYPE_ENUMERATOR
-tracker_enumerator_get_type
-</SECTION>
-
-<SECTION>
-<FILE>tracker-file-enumerator</FILE>
-<TITLE>TrackerFileEnumerator</TITLE>
-tracker_file_enumerator_new
-<SUBSECTION Standard>
-TRACKER_FILE_ENUMERATOR
-TRACKER_FILE_ENUMERATOR_CLASS
-TRACKER_FILE_ENUMERATOR_GET_CLASS
-TRACKER_IS_FILE_ENUMERATOR
-TRACKER_IS_FILE_ENUMERATOR_CLASS
-TRACKER_TYPE_FILE_ENUMERATOR
-TrackerFileEnumerator
-TrackerFileEnumeratorClass
-tracker_file_enumerator_get_type
+tracker_thumbnailer_get_type
 </SECTION>
diff --git a/src/libtracker-miner/Makefile.am b/src/libtracker-miner/Makefile.am
index 8556350..52aef42 100644
--- a/src/libtracker-miner/Makefile.am
+++ b/src/libtracker-miner/Makefile.am
@@ -33,6 +33,8 @@ libtracker_minerincludedir=$(includedir)/tracker-$(TRACKER_API_VERSION)/libtrack
 private_sources =                                     \
        tracker-crawler.c                              \
        tracker-crawler.h                              \
+       tracker-file-data-provider.c                   \
+       tracker-file-data-provider.h                   \
        tracker-file-enumerator.c                      \
        tracker-file-enumerator.h                      \
        tracker-file-notifier.h                        \
@@ -59,13 +61,15 @@ endif
 miner_sources =                                       \
        $(libtracker_miner_monitor_sources)            \
        $(libtracker_miner_monitor_headers)            \
-       tracker-enumerator.c                           \
-       tracker-enumerator.h                           \
+       tracker-data-provider.c                        \
+       tracker-data-provider.h                        \
        tracker-decorator.c                            \
        tracker-decorator.h                            \
        tracker-decorator-internal.h                   \
        tracker-decorator-fs.c                         \
        tracker-decorator-fs.h                         \
+       tracker-enumerator.c                           \
+       tracker-enumerator.h                           \
        tracker-indexing-tree.c                        \
        tracker-indexing-tree.h                        \
        tracker-miner-enum-types.c                     \
@@ -84,9 +88,10 @@ libtracker_miner_ TRACKER_API_VERSION@_la_SOURCES =    \
        $(miner_sources)
 
 libtracker_minerinclude_HEADERS =                      \
-       tracker-enumerator.h                           \
+       tracker-data-provider.h                        \
        tracker-decorator.h                            \
        tracker-decorator-fs.h                         \
+       tracker-enumerator.h                           \
        tracker-indexing-tree.h                        \
        tracker-miner.h                                \
        tracker-miner-common.h                         \
@@ -102,7 +107,7 @@ if !ENABLE_GCOV
 # Using enable_gcov instead of have_unit_test because when doing a release
 #  we disable gcov but NOT the unit tests
 libtracker_miner_ TRACKER_API_VERSION@_la_LDFLAGS +=    \
-       -export-symbols-regex 
'^tracker_(enumerator|crawl|miner|indexing_tree|directory_flags|filter_type|filter_policy|network_type|decorator)_.*'
+       -export-symbols-regex 
'^tracker_(data_provider|enumerator|crawl|miner|indexing_tree|directory_flags|filter_type|filter_policy|network_type|decorator)_.*'
 endif
 
 libtracker_miner_ TRACKER_API_VERSION@_la_LIBADD =     \
diff --git a/src/libtracker-miner/tracker-crawler.c b/src/libtracker-miner/tracker-crawler.c
index 11b98f6..029f8f7 100644
--- a/src/libtracker-miner/tracker-crawler.c
+++ b/src/libtracker-miner/tracker-crawler.c
@@ -20,7 +20,7 @@
 #include "config.h"
 
 #include "tracker-crawler.h"
-#include "tracker-file-enumerator.h"
+#include "tracker-file-data-provider.h"
 #include "tracker-miner-enums.h"
 #include "tracker-miner-enum-types.h"
 #include "tracker-utils.h"
@@ -70,7 +70,7 @@ struct DirectoryRootInfo {
 };
 
 struct TrackerCrawlerPrivate {
-       TrackerEnumerator *enumerator;
+       TrackerDataProvider *data_provider;
 
        /* Directories to crawl */
        GQueue         *directories;
@@ -96,11 +96,13 @@ struct TrackerCrawlerPrivate {
 
 typedef struct {
        TrackerCrawler *crawler;
+       TrackerEnumerator *enumerator;
        DirectoryRootInfo  *root_info;
        DirectoryProcessingData *dir_info;
        GFile *dir_file;
        GCancellable *cancellable;
-} EnumeratorData;
+       GSList *files;
+} DataProviderData;
 
 enum {
        CHECK_DIRECTORY,
@@ -113,7 +115,7 @@ enum {
 
 enum {
        PROP_0,
-       PROP_ENUMERATOR,
+       PROP_DATA_PROVIDER,
 };
 
 static void     crawler_get_property     (GObject         *object,
@@ -130,7 +132,7 @@ static gboolean check_defaults           (TrackerCrawler  *crawler,
 static gboolean check_contents_defaults  (TrackerCrawler  *crawler,
                                           GFile           *file,
                                           GList           *contents);
-static void     file_enumerate_children  (TrackerCrawler          *crawler,
+static void     data_provider_begin      (TrackerCrawler          *crawler,
                                          DirectoryRootInfo       *info,
                                          DirectoryProcessingData *dir_data);
 
@@ -214,11 +216,11 @@ tracker_crawler_class_init (TrackerCrawlerClass *klass)
                              1, G_TYPE_BOOLEAN);
 
        g_object_class_install_property (object_class,
-                                        PROP_ENUMERATOR,
-                                        g_param_spec_object ("enumerator",
-                                                             "Enumerator",
-                                                             "Enumerator to use to crawl structures 
populating data, e.g. like GFileEnumerator",
-                                                             TRACKER_TYPE_ENUMERATOR,
+                                        PROP_DATA_PROVIDER,
+                                        g_param_spec_object ("data-provider",
+                                                             "Data provider",
+                                                             "Data provider to use to crawl structures 
populating data, e.g. like GFileEnumerator",
+                                                             TRACKER_TYPE_DATA_PROVIDER,
                                                              G_PARAM_READWRITE |
                                                              G_PARAM_CONSTRUCT_ONLY));
 
@@ -250,8 +252,8 @@ crawler_set_property (GObject      *object,
        priv = TRACKER_CRAWLER (object)->priv;
 
        switch (prop_id) {
-       case PROP_ENUMERATOR:
-               priv->enumerator = g_value_dup_object (value);
+       case PROP_DATA_PROVIDER:
+               priv->data_provider = g_value_dup_object (value);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -270,8 +272,8 @@ crawler_get_property (GObject    *object,
        priv = TRACKER_CRAWLER (object)->priv;
 
        switch (prop_id) {
-       case PROP_ENUMERATOR:
-               g_value_set_object (value, priv->enumerator);
+       case PROP_DATA_PROVIDER:
+               g_value_set_object (value, priv->data_provider);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -320,15 +322,15 @@ check_contents_defaults (TrackerCrawler  *crawler,
 }
 
 TrackerCrawler *
-tracker_crawler_new (TrackerEnumerator *enumerator)
+tracker_crawler_new (TrackerDataProvider *data_provider)
 {
-       if (!enumerator) {
-               /* Default to the file enumerator if none is passed */
-               enumerator = tracker_file_enumerator_new ();
+       if (!data_provider) {
+               /* Default to the file data_provider if none is passed */
+               data_provider = tracker_file_data_provider_new ();
        }
 
        return g_object_new (TRACKER_TYPE_CRAWLER,
-                            "enumerator", enumerator,
+                            "data-provider", data_provider,
                             NULL);
 }
 
@@ -549,7 +551,7 @@ process_func (gpointer data)
                                /* Directory contents haven't been inspected yet,
                                 * stop this idle function while it's being iterated
                                 */
-                               file_enumerate_children (crawler, info, dir_data);
+                               data_provider_begin (crawler, info, dir_data);
                                stop_idle = TRUE;
                        }
                } else if (dir_data->was_inspected &&
@@ -649,113 +651,66 @@ process_func_stop (TrackerCrawler *crawler)
        }
 }
 
-static EnumeratorData *
-enumerator_data_new (TrackerCrawler          *crawler,
-                    DirectoryRootInfo       *root_info,
-                    DirectoryProcessingData *dir_info)
+static DataProviderData *
+data_provider_data_new (TrackerCrawler          *crawler,
+                        DirectoryRootInfo       *root_info,
+                        DirectoryProcessingData *dir_info)
 {
-       EnumeratorData *ed;
+       DataProviderData *dpd;
 
-       ed = g_slice_new (EnumeratorData);
+       dpd = g_slice_new0 (DataProviderData);
 
-       ed->crawler = g_object_ref (crawler);
-       ed->root_info = root_info;
-       ed->dir_info = dir_info;
+       dpd->crawler = g_object_ref (crawler);
+       dpd->root_info = root_info;
+       dpd->dir_info = dir_info;
        /* Make sure there's always a ref of the GFile while we're
         * iterating it */
-       ed->dir_file = g_object_ref (G_FILE (dir_info->node->data));
-       ed->cancellable = g_cancellable_new ();
+       dpd->dir_file = g_object_ref (G_FILE (dir_info->node->data));
+       dpd->cancellable = g_cancellable_new ();
 
        crawler->priv->cancellables = g_list_prepend (crawler->priv->cancellables,
-                                                     ed->cancellable);
-       return ed;
+                                                     dpd->cancellable);
+       return dpd;
 }
 
 static void
-enumerator_data_process (EnumeratorData *ed)
+data_provider_data_process (DataProviderData *dpd)
 {
        TrackerCrawler *crawler;
        GSList *l;
        GList *children = NULL;
        gboolean use;
 
-       crawler = ed->crawler;
+       crawler = dpd->crawler;
 
-       for (l = ed->dir_info->children; l; l = l->next) {
+       for (l = dpd->dir_info->children; l; l = l->next) {
                DirectoryChildData *child_data;
 
                child_data = l->data;
                children = g_list_prepend (children, child_data->child);
        }
 
-       g_signal_emit (crawler, signals[CHECK_DIRECTORY_CONTENTS], 0, ed->dir_info->node->data, children, 
&use);
+       g_signal_emit (crawler, signals[CHECK_DIRECTORY_CONTENTS], 0, dpd->dir_info->node->data, children, 
&use);
        g_list_free (children);
 
        if (!use) {
-               ed->dir_info->ignored_by_content = TRUE;
+               dpd->dir_info->ignored_by_content = TRUE;
                /* FIXME: Update stats */
                return;
        }
 }
 
 static void
-enumerator_data_free (EnumeratorData *ed)
-{
-       ed->crawler->priv->cancellables =
-               g_list_remove (ed->crawler->priv->cancellables,
-                              ed->cancellable);
-
-       g_object_unref (ed->dir_file);
-       g_object_unref (ed->crawler);
-       g_object_unref (ed->cancellable);
-       g_slice_free (EnumeratorData, ed);
-}
-
-static void
-file_enumerate_children_cb (GObject      *object,
-                            GAsyncResult *result,
-                            gpointer      user_data)
+data_provider_data_add (DataProviderData *dpd)
 {
        TrackerCrawler *crawler;
-       TrackerEnumerator *enumerator;
-       GSList *l;
-       EnumeratorData *ed;
        GFile *parent;
-       GError *error = NULL;
-       GSList *files = NULL;
-       gboolean cancelled;
-
-       ed = (EnumeratorData*) user_data;
-       crawler = ed->crawler;
-       cancelled = g_cancellable_is_cancelled (ed->cancellable);
-       parent = ed->dir_info->node->data;
-       enumerator = TRACKER_ENUMERATOR (object);
-
-       files = tracker_enumerator_get_children_finish (enumerator, result, &error);
-
-       if (!files) {
-               if (error && !cancelled) {
-                       gchar *uri;
-
-                       uri = g_file_get_uri (parent);
-
-                       g_warning ("Could not enumerate container / directory '%s', %s",
-                                  uri, error->message);
-
-                       g_error_free (error);
-                       g_free (uri);
-               }
-
-               enumerator_data_free (ed);
-               process_func_start (crawler);
-               return;
-       }
+       GSList *l;
 
-       if (!cancelled) {
-               enumerator_data_process (ed);
-       }
+       crawler = dpd->crawler;
+       parent = dpd->dir_info->node->data;
 
-       for (l = files; l; l = l->next) {
+       for (l = dpd->files; l; l = l->next) {
                GFileInfo *info;
                GFile *child;
                const gchar *child_name;
@@ -775,26 +730,165 @@ file_enumerate_children_cb (GObject      *object,
                                                 (GDestroyNotify) g_object_unref);
                }
 
-               directory_processing_data_add_child (ed->dir_info, child, is_dir);
+               directory_processing_data_add_child (dpd->dir_info, child, is_dir);
 
                g_object_unref (child);
                g_object_unref (info);
        }
 
-       g_slist_free (files);
-       enumerator_data_free (ed);
-       process_func_start (crawler);
+       g_slist_free (dpd->files);
+       dpd->files = NULL;
+}
+
+static void
+data_provider_data_free (DataProviderData *dpd)
+{
+       dpd->crawler->priv->cancellables =
+               g_list_remove (dpd->crawler->priv->cancellables,
+                              dpd->cancellable);
+
+       g_object_unref (dpd->dir_file);
+       g_object_unref (dpd->crawler);
+       g_object_unref (dpd->cancellable);
+
+       if (dpd->files) {
+               g_slist_free_full (dpd->files, g_object_unref);
+       }
+
+       if (dpd->enumerator) {
+               g_object_unref (dpd->enumerator);
+       }
+
+       g_slice_free (DataProviderData, dpd);
+}
+
+static void
+enumerate_next_cb (GObject      *object,
+                   GAsyncResult *result,
+                   gpointer      user_data)
+{
+       DataProviderData *dpd;
+       GFileInfo *info;
+       GError *error = NULL;
+       gboolean cancelled;
+
+       dpd = user_data;
+       cancelled = g_cancellable_is_cancelled (dpd->cancellable);
+       info = tracker_enumerator_next_finish (TRACKER_ENUMERATOR (object), result, &error);
+
+       /* If cancelled, process what we have so far only... */
+       if (cancelled) {
+               data_provider_data_process (dpd);
+               data_provider_data_add (dpd);
+
+               process_func_start (dpd->crawler);
+               data_provider_data_free (dpd);
+               return;
+       }
+
+       if (!info) {
+               /* Could be due to:
+                * a) error,
+                * b) cancellation,
+                * c) no more items
+                */
+
+               /* We don't consider cancellation an error, so we only
+                * log errors which are not cancellations.
+                */
+               if (error) {
+                       /* condition a) */
+
+                       if (!cancelled) {
+                               GFile *parent;
+                               gchar *uri;
+
+                               /* condition b) */
+                               parent = dpd->dir_info->node->data;
+                               uri = g_file_get_uri (parent);
+                               g_warning ("Could not enumerate next item in container / directory '%s', %s",
+                                          uri, error ? error->message : "no error given");
+                               g_free (uri);
+                       }
+
+                       g_clear_error (&error);
+               } else {
+                       /* condition c) */
+                       /* Done enumerating, start processing what we got ... */
+                       data_provider_data_process (dpd);
+                       data_provider_data_add (dpd);
+               }
+
+               process_func_start (dpd->crawler);
+               data_provider_data_free (dpd);
+       } else {
+               /* More work to do */
+               dpd->files = g_slist_prepend (dpd->files, g_object_ref (info));
+
+               tracker_enumerator_next_async (TRACKER_ENUMERATOR (object),
+                                              G_PRIORITY_LOW,
+                                              dpd->cancellable,
+                                              enumerate_next_cb,
+                                              dpd);
+       }
+}
+
+static void
+data_provider_begin_cb (GObject      *object,
+                        GAsyncResult *result,
+                        gpointer      user_data)
+{
+       DataProviderData *dpd;
+       GError *error = NULL;
+       gboolean cancelled;
+
+       dpd = user_data;
+       cancelled = g_cancellable_is_cancelled (dpd->cancellable);
+
+       dpd->enumerator = tracker_data_provider_begin_finish (TRACKER_DATA_PROVIDER (object), result, &error);
+
+       if (!dpd->enumerator) {
+               if (error && !cancelled) {
+                       GFile *parent;
+                       gchar *uri;
+
+                       parent = dpd->dir_info->node->data;
+                       uri = g_file_get_uri (parent);
+
+                       g_warning ("Could not enumerate container / directory '%s', %s",
+                                  uri, error ? error->message : "no error given");
+
+                       g_free (uri);
+                       g_clear_error (&error);
+               }
+
+               process_func_start (dpd->crawler);
+               data_provider_data_free (dpd);
+               return;
+       }
+
+       if (cancelled) {
+               process_func_start (dpd->crawler);
+               data_provider_data_free (dpd);
+               return;
+       }
+
+       tracker_enumerator_next_async (dpd->enumerator,
+                                      G_PRIORITY_LOW,
+                                      dpd->cancellable,
+                                      enumerate_next_cb,
+                                      dpd);
 }
 
 static void
-file_enumerate_children (TrackerCrawler          *crawler,
-                        DirectoryRootInfo       *info,
-                        DirectoryProcessingData *dir_data)
+data_provider_begin (TrackerCrawler          *crawler,
+                     DirectoryRootInfo       *info,
+                     DirectoryProcessingData *dir_data)
 {
-       EnumeratorData *ed;
+       DataProviderData *dpd;
        gchar *attrs;
 
-       ed = enumerator_data_new (crawler, info, dir_data);
+       dpd = data_provider_data_new (crawler, info, dir_data);
 
        if (crawler->priv->file_attributes) {
                attrs = g_strconcat (FILE_ATTRIBUTES ",",
@@ -804,14 +898,15 @@ file_enumerate_children (TrackerCrawler          *crawler,
                attrs = g_strdup (FILE_ATTRIBUTES);
        }
 
-       tracker_enumerator_get_children_async (crawler->priv->enumerator,
-                                              ed->dir_file,
-                                              attrs,
-                                              G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                              G_PRIORITY_LOW,
-                                              ed->cancellable,
-                                              file_enumerate_children_cb,
-                                              ed);
+
+       tracker_data_provider_begin_async (crawler->priv->data_provider,
+                                          dpd->dir_file,
+                                          attrs,
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                          G_PRIORITY_LOW,
+                                          dpd->cancellable,
+                                          data_provider_begin_cb,
+                                          dpd);
        g_free (attrs);
 }
 
@@ -830,7 +925,7 @@ tracker_crawler_start (TrackerCrawler *crawler,
 
        priv = crawler->priv;
 
-       flags = tracker_enumerator_get_crawl_flags (priv->enumerator);
+       flags = tracker_data_provider_get_crawl_flags (priv->data_provider);
        enable_stat = (flags & TRACKER_CRAWL_FLAG_NO_STAT) == 0;
 
        if (enable_stat && !g_file_query_exists (file, NULL)) {
diff --git a/src/libtracker-miner/tracker-crawler.h b/src/libtracker-miner/tracker-crawler.h
index 5282e54..74123df 100644
--- a/src/libtracker-miner/tracker-crawler.h
+++ b/src/libtracker-miner/tracker-crawler.h
@@ -27,7 +27,7 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
-#include "tracker-enumerator.h"
+#include "tracker-data-provider.h"
 
 G_BEGIN_DECLS
 
@@ -72,7 +72,7 @@ struct TrackerCrawlerClass {
 };
 
 GType           tracker_crawler_get_type     (void);
-TrackerCrawler *tracker_crawler_new          (TrackerEnumerator *enumerator);
+TrackerCrawler *tracker_crawler_new          (TrackerDataProvider *data_provider);
 gboolean        tracker_crawler_start        (TrackerCrawler *crawler,
                                               GFile          *file,
                                              gint            max_depth);
diff --git a/src/libtracker-miner/tracker-data-provider.c b/src/libtracker-miner/tracker-data-provider.c
new file mode 100644
index 0000000..f0c83d9
--- /dev/null
+++ b/src/libtracker-miner/tracker-data-provider.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2014, Softathome <contact softathome com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ * Author: Martyn Russell <martyn lanedo com>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "tracker-data-provider.h"
+
+/**
+ * SECTION:tracker-data-provider
+ * @short_description: Provide data to be indexed
+ * @include: libtracker-miner/miner.h
+ *
+ * #TrackerDataProvider allows you to operate on a set of #GFiles,
+ * returning a #GFileInfo structure for each file enumerated (e.g.
+ * tracker_data_provider_begin() will return a #TrackerEnumerator
+ * which can be used to enumerate resources provided by the
+ * #TrackerDataProvider.
+ *
+ * There is also a #TrackerFileDataProvider which is an implementation
+ * of this #TrackerDataProvider interface.
+ *
+ * The #TrackerMinerFS class which is a subclass to #TrackerMiner
+ * takes a #TrackerDataProvider property which is passed down to the
+ * TrackerCrawler created upon instantiation. This property is
+ * #TrackerMinerFS:data-provider.
+ *
+ * See the #TrackerEnumerator documentation for more details.
+ *
+ * Since: 1.2
+ **/
+
+typedef TrackerDataProviderIface TrackerDataProviderInterface;
+G_DEFINE_INTERFACE (TrackerDataProvider, tracker_data_provider, G_TYPE_OBJECT)
+
+static void
+tracker_data_provider_default_init (TrackerDataProviderInterface *iface)
+{
+}
+
+/**
+ * tracker_data_provider_get_crawl_flags:
+ * @data_provider: a #TrackerDataProvider
+ *
+ * Get the conditions used to provide data, for example, following symlinks.
+ *
+ * Returns: the #TrackerCrawlFlags used with this @data_provider.
+ *
+ * Since: 1.2
+ **/
+TrackerCrawlFlags
+tracker_data_provider_get_crawl_flags (TrackerDataProvider *data_provider)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), TRACKER_CRAWL_FLAG_NONE);
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       g_return_val_if_fail (iface->get_crawl_flags != NULL, TRACKER_CRAWL_FLAG_NONE);
+
+       return (* iface->get_crawl_flags) (data_provider);
+}
+
+/**
+ * tracker_data_provider_set_crawl_flags:
+ * @data_provider: a #TrackerDataProvider
+ * @flags: the #TrackerCrawlFlags to use
+ *
+ * Sets the #TrackerCrawlFlags used with this @data_provider. Each time
+ * tracker_data_provider_begin() is called, these flags are used.
+ *
+ * Since: 1.2
+ **/
+void
+tracker_data_provider_set_crawl_flags (TrackerDataProvider *data_provider,
+                                       TrackerCrawlFlags    flags)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider));
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       g_return_if_fail (iface->set_crawl_flags != NULL);
+
+       (* iface->set_crawl_flags) (data_provider, flags);
+}
+
+/**
+ * tracker_data_provider_begin:
+ * @data_provider: a #TrackerDataProvider
+ * @url: a #GFile to enumerate
+ * @attributes: an attribute query string
+ * @flags: a set of GFileQueryInfoFlags
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
+ * @error: location to store the error occurring, or %NULL to ignore
+ *
+ * Creates a #TrackerEnumerator to enumerate children at the URI
+ * provided by @url.
+ *
+ * The attributes value is a string that specifies the file attributes
+ * that should be gathered. It is not an error if it's not possible to
+ * read a particular requested attribute from a file - it just won't
+ * be set. attributes should be a comma-separated list of attributes
+ * or attribute wildcards. The wildcard "*" means all attributes, and
+ * a wildcard like "standard::*" means all attributes in the standard
+ * namespace. An example attribute query be "standard::*,owner::user".
+ * The standard attributes are available as defines, like
+ * G_FILE_ATTRIBUTE_STANDARD_NAME. See g_file_enumerate_children() for
+ * more details.
+ *
+ * Returns: (transfer full): a #TrackerEnumerator or %NULL on failure.
+ * This must be freed with g_object_unref().
+ *
+ * Since: 1.2
+ **/
+TrackerEnumerator *
+tracker_data_provider_begin (TrackerDataProvider  *data_provider,
+                             GFile                *url,
+                             const gchar          *attributes,
+                             GFileQueryInfoFlags   flags,
+                             GCancellable         *cancellable,
+                             GError              **error)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), NULL);
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+               return NULL;
+       }
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       if (iface->begin == NULL) {
+               g_set_error_literal (error,
+                                    G_IO_ERROR,
+                                    G_IO_ERROR_NOT_SUPPORTED,
+                                    _("Operation not supported"));
+               return NULL;
+       }
+
+       return (* iface->begin) (data_provider, url, attributes, flags, cancellable, error);
+}
+
+/**
+ * tracker_data_provider_begin_async:
+ * @data_provider: a #TrackerDataProvider.
+ * @url: a #GFile to enumerate
+ * @attributes: an attribute query string
+ * @flags: a set of GFileQueryInfoFlags
+ * @io_priority: the [I/O priority][io-priority] of the request
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to
+ * ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the
+ * request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Precisely the same operation as tracker_data_provider_begin()
+ * is performing, but asynchronously.
+ *
+ * When all i/o for the operation is finished the @callback will be
+ * called with the requested information.
+
+ * See the documentation of #TrackerDataProvider for information about the
+ * order of returned files.
+ *
+ * In case of a partial error the callback will be called with any
+ * succeeding items and no error, and on the next request the error
+ * will be reported. If a request is cancelled the callback will be
+ * called with %G_IO_ERROR_CANCELLED.
+ *
+ * During an async request no other sync and async calls are allowed,
+ * and will result in %G_IO_ERROR_PENDING errors.
+ *
+ * Any outstanding i/o request with higher priority (lower numerical
+ * value) will be executed before an outstanding request with lower
+ * priority. Default priority is %G_PRIORITY_DEFAULT.
+ *
+ * Since: 1.2
+ **/
+void
+tracker_data_provider_begin_async (TrackerDataProvider  *data_provider,
+                                   GFile                *url,
+                                   const gchar          *attributes,
+                                   GFileQueryInfoFlags   flags,
+                                   int                   io_priority,
+                                   GCancellable         *cancellable,
+                                   GAsyncReadyCallback   callback,
+                                   gpointer              user_data)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider));
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       if (iface->begin_async == NULL) {
+               g_critical (_("Operation not supported"));
+               return;
+       }
+
+       (* iface->begin_async) (data_provider, url, attributes, flags, io_priority, cancellable, callback, 
user_data);
+}
+
+/**
+ * tracker_data_provider_begin_finish:
+ * @data_provider: a #TrackerDataProvider.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occurring, or %NULL
+ * to ignore.
+ *
+ * Finishes the asynchronous operation started with
+ * tracker_data_provider_begin_async().
+ *
+ * Returns: (transfer full): a #TrackerEnumerator or %NULL on failure.
+ * This must be freed with g_object_unref().
+ *
+ * Since: 1.2
+ **/
+TrackerEnumerator *
+tracker_data_provider_begin_finish (TrackerDataProvider  *data_provider,
+                                    GAsyncResult         *result,
+                                    GError              **error)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), NULL);
+       g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       if (g_async_result_legacy_propagate_error (result, error)) {
+               return NULL;
+       }
+
+       return (* iface->begin_finish) (data_provider, result, error);
+}
+
+/**
+ * tracker_data_provider_end:
+ * @data_provider: a #TrackerDataProvider
+ * @enumerator: a #TrackerEnumerator originally created by
+ * tracker_data_provider_begin().
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
+ * @error: location to store the error occurring, or %NULL to ignore
+ *
+ * Closes any caches or operations related to creating the
+ * #TrackerEnumerator to enumerate data at @url.
+ *
+ * The attributes value is a string that specifies the file attributes
+ * that should be gathered. It is not an error if it's not possible to
+ * read a particular requested attribute from a file - it just won't
+ * be set. attributes should be a comma-separated list of attributes
+ * or attribute wildcards. The wildcard "*" means all attributes, and
+ * a wildcard like "standard::*" means all attributes in the standard
+ * namespace. An example attribute query be "standard::*,owner::user".
+ * The standard attributes are available as defines, like
+ * G_FILE_ATTRIBUTE_STANDARD_NAME. See g_file_enumerate_children() for
+ * more details.
+ *
+ * Returns: %TRUE on success, otherwise %FALSE and @error is set.
+ *
+ * Since: 1.2
+ **/
+gboolean
+tracker_data_provider_end (TrackerDataProvider  *data_provider,
+                           TrackerEnumerator    *enumerator,
+                           GCancellable         *cancellable,
+                           GError              **error)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), FALSE);
+       g_return_val_if_fail (TRACKER_IS_ENUMERATOR (enumerator), FALSE);
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+               return FALSE;
+       }
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       if (iface->end == NULL) {
+               g_set_error_literal (error,
+                                    G_IO_ERROR,
+                                    G_IO_ERROR_NOT_SUPPORTED,
+                                    _("Operation not supported"));
+               return FALSE;
+       }
+
+       return (* iface->end) (data_provider, enumerator, cancellable, error);
+}
+
+/**
+ * tracker_data_provider_end_async:
+ * @data_provider: a #TrackerDataProvider.
+ * @enumerator: a #TrackerEnumerator originally created by
+ * tracker_data_provider_begin().
+ * @io_priority: the [I/O priority][io-priority] of the request
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to
+ * ignore
+ * @callback: (scope async): a #GAsyncReadyCallback to call when the
+ * request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Precisely the same operation as tracker_data_provider_end()
+ * is performing, but asynchronously.
+ *
+ * When all i/o for the operation is finished the @callback will be
+ * called with the requested information.
+
+ * See the documentation of #TrackerDataProvider for information about the
+ * order of returned files.
+ *
+ * In case of a partial error the callback will be called with any
+ * succeeding items and no error, and on the next request the error
+ * will be reported. If a request is cancelled the callback will be
+ * called with %G_IO_ERROR_CANCELLED.
+ *
+ * During an async request no other sync and async calls are allowed,
+ * and will result in %G_IO_ERROR_PENDING errors.
+ *
+ * Any outstanding i/o request with higher priority (lower numerical
+ * value) will be executed before an outstanding request with lower
+ * priority. Default priority is %G_PRIORITY_DEFAULT.
+ *
+ * Since: 1.2
+ **/
+void
+tracker_data_provider_end_async (TrackerDataProvider  *data_provider,
+                                 TrackerEnumerator    *enumerator,
+                                 int                   io_priority,
+                                 GCancellable         *cancellable,
+                                 GAsyncReadyCallback   callback,
+                                 gpointer              user_data)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider));
+       g_return_if_fail (TRACKER_IS_ENUMERATOR (enumerator));
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       if (iface->end_async == NULL) {
+               g_critical (_("Operation not supported"));
+               return;
+       }
+
+       (* iface->end_async) (data_provider, enumerator, io_priority, cancellable, callback, user_data);
+}
+
+/**
+ * tracker_data_provider_end_finish:
+ * @data_provider: a #TrackerDataProvider.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occurring, or %NULL
+ * to ignore.
+ *
+ * Finishes the asynchronous operation started with
+ * tracker_data_provider_end_async().
+ *
+ * Returns: %TRUE on success, otherwise %FALSE and @error is set.
+ *
+ * Since: 1.2
+ **/
+gboolean
+tracker_data_provider_end_finish (TrackerDataProvider  *data_provider,
+                                  GAsyncResult         *result,
+                                  GError              **error)
+{
+       TrackerDataProviderIface *iface;
+
+       g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), FALSE);
+       g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+       iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider);
+
+       if (g_async_result_legacy_propagate_error (result, error)) {
+               return FALSE;
+       }
+
+       return (* iface->end_finish) (data_provider, result, error);
+}
diff --git a/src/libtracker-miner/tracker-data-provider.h b/src/libtracker-miner/tracker-data-provider.h
new file mode 100644
index 0000000..b9da4dc
--- /dev/null
+++ b/src/libtracker-miner/tracker-data-provider.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014, Softathome <contact softathome com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ * Author: Martyn Russell <martyn lanedo com>
+ */
+
+#ifndef __LIBTRACKER_MINER_DATA_PROVIDER_H__
+#define __LIBTRACKER_MINER_DATA_PROVIDER_H__
+
+#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "Only <libtracker-miner/tracker-miner.h> can be included directly."
+#endif
+
+#include <gio/gio.h>
+
+#include "tracker-enumerator.h"
+#include "tracker-miner-enums.h"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_DATA_PROVIDER           (tracker_data_provider_get_type ())
+#define TRACKER_DATA_PROVIDER(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRACKER_TYPE_DATA_PROVIDER, 
TrackerDataProvider))
+#define TRACKER_IS_DATA_PROVIDER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_DATA_PROVIDER))
+#define TRACKER_DATA_PROVIDER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), 
TRACKER_TYPE_DATA_PROVIDER, TrackerDataProviderIface))
+
+/**
+ * TrackerDataProvider:
+ *
+ * An interface to enumerate URIs and feed the data to Tracker.
+ **/
+typedef struct _TrackerDataProvider TrackerDataProvider;
+typedef struct _TrackerDataProviderIface TrackerDataProviderIface;
+
+/**
+ * TrackerDataProviderIface:
+ * @g_iface: Parent interface type.
+ * @get_crawl_flags: Called when before data_provider starts to know how
+ * to enumerate.
+ * @set_crawl_flags: Called when setting the flags an data_provider
+ * should use.
+ * @begin: Called when the data_provider is synchronously
+ * opening and starting the iteration of a given location.
+ * @begin_async: Called when the data_provider is synchronously
+ * opening and starting the iteration of a given location. Completed
+ * using @begin_finish.
+ * @begin_finish: Called when the data_provider is completing the
+ * asynchronous operation provided by @begin_async.
+ * @end: Called when the data_provider is synchronously
+ * closing and cleaning up the iteration of a given location.
+ * @end_async: Called when the data_provider is asynchronously
+ * closing and cleaning up the iteration of a given location.
+ * Completed using @end_finish.
+ * @end_finish: Called when the data_provider is completing the
+ * asynchronous operation provided by @end_async.
+ *
+ * Virtual methods left to implement.
+ **/
+struct _TrackerDataProviderIface {
+       GTypeInterface g_iface;
+
+       /* Virtual Table */
+       TrackerCrawlFlags   (* get_crawl_flags)    (TrackerDataProvider  *data_provider);
+       void                (* set_crawl_flags)    (TrackerDataProvider  *data_provider,
+                                                   TrackerCrawlFlags     flags);
+
+       /* Start the data_provider for a given location, attributes and flags */
+       TrackerEnumerator * (* begin)              (TrackerDataProvider  *data_provider,
+                                                   GFile                *url,
+                                                   const gchar          *attributes,
+                                                   GFileQueryInfoFlags   flags,
+                                                   GCancellable         *cancellable,
+                                                   GError              **error);
+       void                (* begin_async)        (TrackerDataProvider  *data_provider,
+                                                   GFile                *url,
+                                                   const gchar          *attributes,
+                                                   GFileQueryInfoFlags   flags,
+                                                   gint                  io_priority,
+                                                   GCancellable         *cancellable,
+                                                   GAsyncReadyCallback   callback,
+                                                   gpointer              user_data);
+       TrackerEnumerator * (* begin_finish)       (TrackerDataProvider  *data_provider,
+                                                   GAsyncResult         *result,
+                                                   GError              **error);
+
+       /* Close the given location */
+       gboolean            (* end)                (TrackerDataProvider  *data_provider,
+                                                   TrackerEnumerator    *enumerator,
+                                                   GCancellable         *cancellable,
+                                                   GError              **error);
+       void                (* end_async)          (TrackerDataProvider  *data_provider,
+                                                   TrackerEnumerator    *enumerator,
+                                                   gint                  io_priority,
+                                                   GCancellable         *cancellable,
+                                                   GAsyncReadyCallback   callback,
+                                                   gpointer              user_data);
+       gboolean            (* end_finish)         (TrackerDataProvider  *data_provider,
+                                                   GAsyncResult         *result,
+                                                   GError              **error);
+
+       /*< private >*/
+       /* Padding for future expansion */
+       void (*_tracker_reserved1) (void);
+       void (*_tracker_reserved2) (void);
+       void (*_tracker_reserved3) (void);
+       void (*_tracker_reserved4) (void);
+       void (*_tracker_reserved5) (void);
+       void (*_tracker_reserved6) (void);
+       void (*_tracker_reserved7) (void);
+       void (*_tracker_reserved8) (void);
+};
+
+GType              tracker_data_provider_get_type        (void) G_GNUC_CONST;
+
+TrackerCrawlFlags  tracker_data_provider_get_crawl_flags (TrackerDataProvider  *data_provider);
+void               tracker_data_provider_set_crawl_flags (TrackerDataProvider  *data_provider,
+                                                          TrackerCrawlFlags     flags);
+TrackerEnumerator *tracker_data_provider_begin           (TrackerDataProvider  *data_provider,
+                                                          GFile                *url,
+                                                          const gchar          *attributes,
+                                                          GFileQueryInfoFlags   flags,
+                                                          GCancellable         *cancellable,
+                                                          GError              **error);
+void               tracker_data_provider_begin_async     (TrackerDataProvider  *data_provider,
+                                                          GFile                *url,
+                                                          const gchar          *attributes,
+                                                          GFileQueryInfoFlags   flags,
+                                                          gint                  io_priority,
+                                                          GCancellable         *cancellable,
+                                                          GAsyncReadyCallback   callback,
+                                                          gpointer              user_data);
+TrackerEnumerator *tracker_data_provider_begin_finish    (TrackerDataProvider  *data_provider,
+                                                          GAsyncResult         *result,
+                                                          GError              **error);
+gboolean           tracker_data_provider_end             (TrackerDataProvider  *data_provider,
+                                                          TrackerEnumerator    *enumerator,
+                                                          GCancellable         *cancellable,
+                                                          GError              **error);
+void               tracker_data_provider_end_async       (TrackerDataProvider  *data_provider,
+                                                          TrackerEnumerator    *enumerator,
+                                                          gint                  io_priority,
+                                                          GCancellable         *cancellable,
+                                                          GAsyncReadyCallback   callback,
+                                                          gpointer              user_data);
+gboolean           tracker_data_provider_end_finish      (TrackerDataProvider  *data_provider,
+                                                          GAsyncResult         *result,
+                                                          GError              **error);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKER_MINER_DATA_PROVIDER_H__ */
diff --git a/src/libtracker-miner/tracker-enumerator.c b/src/libtracker-miner/tracker-enumerator.c
index 233ca7f..1eddd8e 100644
--- a/src/libtracker-miner/tracker-enumerator.c
+++ b/src/libtracker-miner/tracker-enumerator.c
@@ -27,48 +27,43 @@
 
 /**
  * SECTION:tracker-enumerator
- * @short_description: Enumerate URI locations
+ * @short_description: Enumerate resources
  * @include: libtracker-miner/miner.h
  *
- * #TrackerEnumerator allows you to operate on a set of #GFiles,
- * returning a #GFileInfo structure for each file enumerated (e.g.
- * tracker_enumerator_get_children() will return a #GSList with the
- * children within a parent directory or structure for the URI.
+ * #TrackerEnumerator allows you to iterate content or resources.
  *
- * This function is similar to g_file_enumerator_next_files_async(),
- * unlike the g_file_enumerator_next() which will return one #GFile at
- * a time, this will return all children at once.
+ * The common example use case for #TrackerEnumerator would be to
+ * operate on a set of #GFiles, returning a #GFileInfo structure for
+ * each file enumerated (e.g. tracker_enumerator_next() would return a
+ * #GFileInfo for each resource found in a parent folder or container).
  *
- * The ordering of returned files is unspecified and dependent on
+ * The ordering of returned content is unspecified and dependent on
  * implementation.
  *
  * If your application needs a specific ordering, such as by name or
  * modification time, you will have to implement that in your
  * application code.
  *
- * There is also a #TrackerFileEnumerator which is an implementation
- * of this #TrackerEnumerator interface. This makes use of the
+ * There is a #TrackerFileEnumerator which is an implementation
+ * of the #TrackerEnumerator interface. This makes use of the
  * #GFileEnumerator API as an example of how to implement your own
  * enumerator class. Typically, an implementation class (like
  * #TrackerFileEnumerator) would be used with TrackerCrawler (an
  * internal class) which feeds URI data for Tracker to insert into the
  * database.
  *
- * The #TrackerMinerFS class which is a subclass to #TrackerMiner
- * takes a #TrackerEnumerator property which is passed down to the
- * TrackerCrawler created upon instantiation. This property is
- * #TrackerMinerFS:enumerator.
- *
  * What is important to note about implementations is what is expected
  * to be returned by an enumerator. There are some simple rules:
  *
- * 1. Tracker expects children on a per directory basis only, i.e. not
- * recursively given for a top level URI. This allows Tracker to
- * properly construct the database and carry out white/black listing
- * correctly, amongst other things.
+ * 1. Tracker expects resources on a per container (or directory)
+ * basis only, i.e. not recursively given for a top level URI. This
+ * allows Tracker to properly construct the database and carry out
+ * white/black listing correctly, amongst other things.
  * 2. Tracker does not expect the top level URL to be reported in the
  * children returned. This is considered an error.
  *
+ * See the #TrackerDataProvider documentation for more details.
+ *
  * Since: 1.2
  **/
 
@@ -81,86 +76,26 @@ tracker_enumerator_default_init (TrackerEnumeratorInterface *iface)
 }
 
 /**
- * tracker_enumerator_get_crawl_flags:
+ * tracker_enumerator_next:
  * @enumerator: a #TrackerEnumerator
- *
- * Returns the #TrackerCrawlFlags used with this @enumerator.
- *
- * Since: 1.2
- **/
-TrackerCrawlFlags
-tracker_enumerator_get_crawl_flags (TrackerEnumerator *enumerator)
-{
-       TrackerEnumeratorIface *iface;
-
-       g_return_val_if_fail (TRACKER_IS_ENUMERATOR (enumerator), TRACKER_CRAWL_FLAG_NONE);
-
-       iface = TRACKER_ENUMERATOR_GET_IFACE (enumerator);
-
-       g_return_val_if_fail (iface->get_crawl_flags != NULL, TRACKER_CRAWL_FLAG_NONE);
-
-       return (* iface->get_crawl_flags) (enumerator);
-}
-
-/**
- * tracker_enumerator_set_crawl_flags:
- * @enumerator: a #TrackerEnumerator
- *
- * Sets the #TrackerCrawlFlags used with this @enumerator. Each time
- * tracker_enumerator_get_children() is called, these flags are used.
- *
- * Since: 1.2
- **/
-void
-tracker_enumerator_set_crawl_flags (TrackerEnumerator *enumerator,
-                                    TrackerCrawlFlags  flags)
-{
-       TrackerEnumeratorIface *iface;
-
-       g_return_if_fail (TRACKER_IS_ENUMERATOR (enumerator));
-
-       iface = TRACKER_ENUMERATOR_GET_IFACE (enumerator);
-
-       g_return_if_fail (iface->set_crawl_flags != NULL);
-
-       (* iface->set_crawl_flags) (enumerator, flags);
-}
-
-/**
- * tracker_enumerator_get_children:
- * @enumerator: a #TrackerEnumerator
- * @dir: a #GFile to enumerate
- * @attributes: an attribute query string
- * @flags: a set of GFileQueryInfoFlags
  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
  * @error: location to store the error occurring, or %NULL to ignore
  *
- * Enumerates children at the URI provided by @dir.
- *
- * The attributes value is a string that specifies the file attributes
- * that should be gathered. It is not an error if it's not possible to
- * read a particular requested attribute from a file - it just won't
- * be set. attributes should be a comma-separated list of attributes
- * or attribute wildcards. The wildcard "*" means all attributes, and
- * a wildcard like "standard::*" means all attributes in the standard
- * namespace. An example attribute query be "standard::*,owner::user".
- * The standard attributes are available as defines, like
- * G_FILE_ATTRIBUTE_STANDARD_NAME. See g_file_enumerate_children() for
- * more details.
+ * Enumerates to the next piece of data according to the @enumerator
+ * implementation.
  *
- * Returns: (transfer full) (element-type Gio.FileInfo): a #GSList of
- * #GFileInfo pointers. Both must be freed with g_slist_free() and
- * g_object_unref() when finished with.
+ * Returns: (transfer full): Returns a #gpointer with the next item
+ * from the @enumerator, or %NULL when @error is set or the operation
+ * was cancelled in @cancellable. The data must be freed. The function
+ * to free depends on the data returned by the enumerator and the
+ * #TrackerDataProvider that created the @enumerator.
  *
  * Since: 1.2
  **/
-GSList *
-tracker_enumerator_get_children (TrackerEnumerator    *enumerator,
-                                 GFile                *dir,
-                                 const gchar          *attributes,
-                                 GFileQueryInfoFlags   flags,
-                                 GCancellable         *cancellable,
-                                 GError              **error)
+gpointer
+tracker_enumerator_next (TrackerEnumerator  *enumerator,
+                         GCancellable       *cancellable,
+                         GError            **error)
 {
        TrackerEnumeratorIface *iface;
 
@@ -172,7 +107,7 @@ tracker_enumerator_get_children (TrackerEnumerator    *enumerator,
 
        iface = TRACKER_ENUMERATOR_GET_IFACE (enumerator);
 
-       if (iface->get_children == NULL) {
+       if (iface->next == NULL) {
                g_set_error_literal (error,
                                     G_IO_ERROR,
                                     G_IO_ERROR_NOT_SUPPORTED,
@@ -180,15 +115,12 @@ tracker_enumerator_get_children (TrackerEnumerator    *enumerator,
                return NULL;
        }
 
-       return (* iface->get_children) (enumerator, dir, attributes, flags, cancellable, error);
+       return (* iface->next) (enumerator, cancellable, error);
 }
 
 /**
- * tracker_enumerator_get_children_async:
+ * tracker_enumerator_next_async:
  * @enumerator: a #TrackerEnumerator.
- * @dir: a #GFile to enumerate
- * @attributes: an attribute query string
- * @flags: a set of GFileQueryInfoFlags
  * @io_priority: the [I/O priority][io-priority] of the request
  * @cancellable: (allow-none): optional #GCancellable object, %NULL to
  * ignore
@@ -196,14 +128,11 @@ tracker_enumerator_get_children (TrackerEnumerator    *enumerator,
  * request is satisfied
  * @user_data: (closure): the data to pass to callback function
  *
- * Precisely the same operation as tracker_enumerator_get_children()
+ * Precisely the same operation as tracker_enumerator_next()
  * is performing, but asynchronously.
  *
  * When all i/o for the operation is finished the @callback will be
  * called with the requested information.
-
- * See the documentation of #TrackerEnumerator for information about the
- * order of returned files.
  *
  * In case of a partial error the callback will be called with any
  * succeeding items and no error, and on the next request the error
@@ -220,14 +149,11 @@ tracker_enumerator_get_children (TrackerEnumerator    *enumerator,
  * Since: 1.2
  **/
 void
-tracker_enumerator_get_children_async (TrackerEnumerator    *enumerator,
-                                       GFile                *dir,
-                                       const gchar          *attributes,
-                                       GFileQueryInfoFlags   flags,
-                                       int                   io_priority,
-                                       GCancellable         *cancellable,
-                                       GAsyncReadyCallback   callback,
-                                       gpointer              user_data)
+tracker_enumerator_next_async (TrackerEnumerator    *enumerator,
+                               gint                  io_priority,
+                               GCancellable         *cancellable,
+                               GAsyncReadyCallback   callback,
+                               gpointer              user_data)
 {
        TrackerEnumeratorIface *iface;
 
@@ -235,35 +161,36 @@ tracker_enumerator_get_children_async (TrackerEnumerator    *enumerator,
 
        iface = TRACKER_ENUMERATOR_GET_IFACE (enumerator);
 
-       if (iface->get_children_async == NULL) {
+       if (iface->next_async == NULL) {
                g_critical (_("Operation not supported"));
                return;
        }
 
-       (* iface->get_children_async) (enumerator, dir, attributes, flags, io_priority, cancellable, 
callback, user_data);
+       (* iface->next_async) (enumerator, io_priority, cancellable, callback, user_data);
 }
 
 /**
- * tracker_enumerator_get_children_finish:
+ * tracker_enumerator_next_finish:
  * @enumerator: a #TrackerEnumerator.
  * @result: a #GAsyncResult.
  * @error: a #GError location to store the error occurring, or %NULL
  * to ignore.
  *
  * Finishes the asynchronous operation started with
- * tracker_enumerator_get_children_async().
+ * tracker_enumerator_next_async().
  *
- * Returns: (transfer full) (element-type Gio.FileInfo): a #GSList of
- * #GFileInfos. You must free the list with g_slist_free() and
- * unref the infos with g_object_unref() when you're done with
- * them.
+ * Returns: (transfer full): Returns a #gpointer with the next item
+ * from the @enumerator, or %NULL when @error is set or the operation
+ * was cancelled in @cancellable. The data must be freed. The function
+ * to free depends on the data returned by the enumerator and the
+ * #TrackerDataProvider that created the @enumerator.
  *
  * Since: 1.2
  **/
-GSList *
-tracker_enumerator_get_children_finish (TrackerEnumerator  *enumerator,
-                                        GAsyncResult       *result,
-                                        GError            **error)
+gpointer
+tracker_enumerator_next_finish (TrackerEnumerator  *enumerator,
+                                GAsyncResult       *result,
+                                GError            **error)
 {
        TrackerEnumeratorIface *iface;
 
@@ -276,5 +203,5 @@ tracker_enumerator_get_children_finish (TrackerEnumerator  *enumerator,
                return NULL;
        }
 
-       return (* iface->get_children_finish) (enumerator, result, error);
+       return (* iface->next_finish) (enumerator, result, error);
 }
diff --git a/src/libtracker-miner/tracker-enumerator.h b/src/libtracker-miner/tracker-enumerator.h
index 3fc6eb5..fce1db4 100644
--- a/src/libtracker-miner/tracker-enumerator.h
+++ b/src/libtracker-miner/tracker-enumerator.h
@@ -48,16 +48,13 @@ typedef struct _TrackerEnumeratorIface TrackerEnumeratorIface;
 /**
  * TrackerEnumeratorIface:
  * @g_iface: Parent interface type.
- * @get_crawl_flags: Called when before enumerator starts to know how
- * to enumerate.
- * @set_crawl_flags: Called when setting the flags an enumerator
- * should use.
- * @get_children: Called when the enumerator is synchronously
- * retrieving children.
- * @get_children_async: Called when the enumerator is asynchronously
- * retrieving children.
- * @get_children_finish: Called when the enumerator is completing the
- * asynchronous operation provided by @get_children_async.
+ * @next: Called when the enumerator is synchronously
+ * retrieving the next resource to be iterated.
+ * @next_async: Called when the enumerator is asynchronously
+ * retrieving the next resource to be iterated. Completed using
+ * @next_finish.
+ * @next_finish: Called when the enumerator is completing the
+ * asynchronous operation provided by @next_async.
  *
  * Virtual methods left to implement.
  **/
@@ -65,26 +62,17 @@ struct _TrackerEnumeratorIface {
        GTypeInterface g_iface;
 
        /* Virtual Table */
-       TrackerCrawlFlags (* get_crawl_flags)     (TrackerEnumerator    *enumerator);
-       void              (* set_crawl_flags)     (TrackerEnumerator    *enumerator,
-                                                  TrackerCrawlFlags     flags);
-       GSList *          (* get_children)        (TrackerEnumerator    *enumerator,
-                                                  GFile                *dir,
-                                                  const gchar          *attributes,
-                                                  GFileQueryInfoFlags   flags,
-                                                  GCancellable         *cancellable,
-                                                  GError              **error);
-       void              (* get_children_async)  (TrackerEnumerator    *enumerator,
-                                                  GFile                *dir,
-                                                  const gchar          *attributes,
-                                                  GFileQueryInfoFlags   flags,
-                                                  int                   io_priority,
-                                                  GCancellable         *cancellable,
-                                                  GAsyncReadyCallback   callback,
-                                                  gpointer              user_data);
-       GSList *          (* get_children_finish) (TrackerEnumerator    *enumerator,
-                                                  GAsyncResult         *result,
-                                                  GError              **error);
+       gpointer          (* next)        (TrackerEnumerator    *enumerator,
+                                          GCancellable         *cancellable,
+                                          GError              **error);
+       void              (* next_async)  (TrackerEnumerator    *enumerator,
+                                          gint                  io_priority,
+                                          GCancellable         *cancellable,
+                                          GAsyncReadyCallback   callback,
+                                          gpointer              user_data);
+       gpointer          (* next_finish) (TrackerEnumerator    *enumerator,
+                                          GAsyncResult         *result,
+                                          GError              **error);
 
        /*< private >*/
        /* Padding for future expansion */
@@ -98,28 +86,18 @@ struct _TrackerEnumeratorIface {
        void (*_tracker_reserved8) (void);
 };
 
-GType             tracker_enumerator_get_type            (void) G_GNUC_CONST;
-TrackerCrawlFlags tracker_enumerator_get_crawl_flags     (TrackerEnumerator    *enumerator);
-void              tracker_enumerator_set_crawl_flags     (TrackerEnumerator    *enumerator,
-                                                          TrackerCrawlFlags     flags);
-GSList *          tracker_enumerator_get_children        (TrackerEnumerator    *enumerator,
-                                                          GFile                *dir,
-                                                          const gchar          *attributes,
-                                                          GFileQueryInfoFlags   flags,
-                                                          GCancellable         *cancellable,
-                                                          GError              **error);
-void              tracker_enumerator_get_children_async  (TrackerEnumerator    *enumerator,
-                                                          GFile                *dir,
-                                                          const gchar          *attributes,
-                                                          GFileQueryInfoFlags   flags,
-                                                          int                   io_priority,
-                                                          GCancellable         *cancellable,
-                                                          GAsyncReadyCallback   callback,
-                                                          gpointer              user_data);
-GSList *          tracker_enumerator_get_children_finish (TrackerEnumerator    *enumerator,
-                                                          GAsyncResult         *result,
-                                                          GError              **error);
-
+GType             tracker_enumerator_get_type        (void) G_GNUC_CONST;
+gpointer          tracker_enumerator_next            (TrackerEnumerator    *enumerator,
+                                                      GCancellable         *cancellable,
+                                                      GError              **error);
+void              tracker_enumerator_next_async      (TrackerEnumerator    *enumerator,
+                                                      gint                  io_priority,
+                                                      GCancellable         *cancellable,
+                                                      GAsyncReadyCallback   callback,
+                                                      gpointer              user_data);
+gpointer          tracker_enumerator_next_finish     (TrackerEnumerator    *enumerator,
+                                                      GAsyncResult         *result,
+                                                      GError              **error);
 
 G_END_DECLS
 
diff --git a/src/libtracker-miner/tracker-file-data-provider.c 
b/src/libtracker-miner/tracker-file-data-provider.c
new file mode 100644
index 0000000..4bd6bb0
--- /dev/null
+++ b/src/libtracker-miner/tracker-file-data-provider.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2014, Softathome <contact softathome com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ * Author: Martyn Russell <martyn lanedo com>
+ */
+
+#include "config.h"
+
+#include "tracker-file-enumerator.h"
+#include "tracker-file-data-provider.h"
+
+static void tracker_file_data_provider_file_iface_init (TrackerDataProviderIface *iface);
+
+struct _TrackerFileDataProvider {
+       GObject parent_instance;
+       TrackerCrawlFlags crawl_flags;
+};
+
+typedef struct {
+       GFile *url;
+       gchar *attributes;
+       GFileQueryInfoFlags flags;
+} BeginData;
+
+/**
+ * SECTION:tracker-file-data-provider
+ * @short_description: File based data provider for file:// descendant URIs
+ * @include: libtracker-miner/miner.h
+ *
+ * #TrackerFileDataProvider is a local file implementation of the
+ * #TrackerDataProvider interface, charged with handling all file:// type URIs.
+ *
+ * Underneath it all, this implementation makes use of the
+ * #GFileEnumerator APIs.
+ *
+ * Since: 1.2
+ **/
+
+G_DEFINE_TYPE_WITH_CODE (TrackerFileDataProvider, tracker_file_data_provider, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (TRACKER_TYPE_DATA_PROVIDER,
+                                                tracker_file_data_provider_file_iface_init))
+
+static void
+tracker_file_data_provider_finalize (GObject *object)
+{
+       G_OBJECT_CLASS (tracker_file_data_provider_parent_class)->finalize (object);
+}
+
+static void
+tracker_file_data_provider_class_init (TrackerFileDataProviderClass *klass)
+{
+       GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+       gobject_class->finalize = tracker_file_data_provider_finalize;
+}
+
+static void
+tracker_file_data_provider_init (TrackerFileDataProvider *fe)
+{
+       fe->crawl_flags = TRACKER_CRAWL_FLAG_NONE;
+}
+
+static TrackerCrawlFlags
+file_data_provider_get_crawl_flags (TrackerDataProvider *data_provider)
+{
+       TrackerFileDataProvider *fe;
+
+       fe = TRACKER_FILE_DATA_PROVIDER (data_provider);
+
+       return fe->crawl_flags;
+}
+
+static void
+file_data_provider_set_crawl_flags (TrackerDataProvider *data_provider,
+                                 TrackerCrawlFlags  flags)
+{
+       TrackerFileDataProvider *fe;
+
+       fe = TRACKER_FILE_DATA_PROVIDER (data_provider);
+
+       fe->crawl_flags = flags;
+}
+
+static BeginData *
+begin_data_new (GFile               *url,
+                const gchar         *attributes,
+                GFileQueryInfoFlags  flags)
+{
+       BeginData *data;
+
+       data = g_slice_new0 (BeginData);
+       data->url = g_object_ref (url);
+       /* FIXME: inefficient */
+       data->attributes = g_strdup (attributes);
+       data->flags = flags;
+
+       return data;
+}
+
+static void
+begin_data_free (BeginData *data)
+{
+       if (!data) {
+               return;
+       }
+
+       g_object_unref (data->url);
+       g_free (data->attributes);
+       g_slice_free (BeginData, data);
+}
+
+static TrackerEnumerator *
+file_data_provider_begin (TrackerDataProvider  *data_provider,
+                          GFile                *url,
+                          const gchar          *attributes,
+                          GFileQueryInfoFlags   flags,
+                          GCancellable         *cancellable,
+                          GError              **error)
+{
+       TrackerEnumerator *enumerator;
+       GFileEnumerator *fe;
+       GError *local_error = NULL;
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+               return NULL;
+       }
+
+       fe = g_file_enumerate_children (url,
+                                       attributes,
+                                       flags,
+                                       cancellable,
+                                       &local_error);
+
+
+       if (local_error) {
+               gchar *uri;
+
+               uri = g_file_get_uri (url);
+
+               g_warning ("Could not open directory '%s': %s",
+                          uri, local_error->message);
+
+               g_propagate_error (error, local_error);
+               g_free (uri);
+       }
+
+       enumerator = tracker_file_enumerator_new (fe);
+
+       return TRACKER_ENUMERATOR (enumerator);
+}
+
+static void
+file_data_provider_begin_thread (GTask        *task,
+                                 gpointer      source_object,
+                                 gpointer      task_data,
+                                 GCancellable *cancellable)
+{
+       TrackerDataProvider *data_provider = source_object;
+       TrackerEnumerator *enumerator = NULL;
+       BeginData *data = task_data;
+       GError *error = NULL;
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+               enumerator = NULL;
+       } else {
+               enumerator = file_data_provider_begin (data_provider,
+                                                      data->url,
+                                                      data->attributes,
+                                                      data->flags,
+                                                      cancellable,
+                                                      &error);
+       }
+
+       if (error) {
+               g_task_return_error (task, error);
+       } else {
+               g_task_return_pointer (task, enumerator, (GDestroyNotify) g_object_unref);
+       }
+}
+
+static void
+file_data_provider_begin_async (TrackerDataProvider  *data_provider,
+                                GFile                *dir,
+                                const gchar          *attributes,
+                                GFileQueryInfoFlags   flags,
+                                int                   io_priority,
+                                GCancellable         *cancellable,
+                                GAsyncReadyCallback   callback,
+                                gpointer              user_data)
+{
+       GTask *task;
+
+       task = g_task_new (data_provider, cancellable, callback, user_data);
+       g_task_set_task_data (task, begin_data_new (dir, attributes, flags), (GDestroyNotify) 
begin_data_free);
+       g_task_set_priority (task, io_priority);
+       g_task_run_in_thread (task, file_data_provider_begin_thread);
+       g_object_unref (task);
+}
+
+static TrackerEnumerator *
+file_data_provider_begin_finish (TrackerDataProvider  *data_provider,
+                                 GAsyncResult         *result,
+                                 GError              **error)
+{
+       g_return_val_if_fail (g_task_is_valid (result, data_provider), NULL);
+
+       return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+static void
+tracker_file_data_provider_file_iface_init (TrackerDataProviderIface *iface)
+{
+       iface->get_crawl_flags = file_data_provider_get_crawl_flags;
+       iface->set_crawl_flags = file_data_provider_set_crawl_flags;
+       iface->begin = file_data_provider_begin;
+       iface->begin_async = file_data_provider_begin_async;
+       iface->begin_finish = file_data_provider_begin_finish;
+}
+
+/**
+ * tracker_file_data_provider_new:
+ *
+ * Creates a new TrackerDataProvider which can be used to create new
+ * #TrackerMinerFS classes. See #TrackerMinerFS for an example of how
+ * to use your #TrackerDataProvider.
+ *
+ * Returns: (transfer full): a #TrackerDataProvider which must be
+ * unreferenced with g_object_unref().
+ *
+ * Since: 1.2:
+ **/
+TrackerDataProvider *
+tracker_file_data_provider_new (void)
+{
+       TrackerFileDataProvider *tfdp;
+
+       tfdp = g_object_new (TRACKER_TYPE_FILE_DATA_PROVIDER, NULL);
+
+       return TRACKER_DATA_PROVIDER (tfdp);
+}
diff --git a/src/libtracker-miner/tracker-file-data-provider.h 
b/src/libtracker-miner/tracker-file-data-provider.h
new file mode 100644
index 0000000..945eaa0
--- /dev/null
+++ b/src/libtracker-miner/tracker-file-data-provider.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014, Softathome <contact softathome com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ * Author: Martyn Russell <martyn lanedo com>
+ */
+
+#ifndef __LIBTRACKER_MINER_FILE_DATA_PROVIDER_H__
+#define __LIBTRACKER_MINER_FILE_DATA_PROVIDER_H__
+
+#include <gio/gio.h>
+
+#include "tracker-data-provider.h"
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_FILE_DATA_PROVIDER         (tracker_file_data_provider_get_type ())
+#define TRACKER_FILE_DATA_PROVIDER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), 
TRACKER_TYPE_FILE_DATA_PROVIDER, TrackerFileDataProvider))
+#define TRACKER_FILE_DATA_PROVIDER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), 
TRACKER_TYPE_FILE_DATA_PROVIDER, TrackerFileDataProviderClass))
+#define TRACKER_IS_FILE_DATA_PROVIDER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), 
TRACKER_TYPE_FILE_DATA_PROVIDER))
+#define TRACKER_IS_FILE_DATA_PROVIDER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), 
TRACKER_TYPE_FILE_DATA_PROVIDER))
+#define TRACKER_FILE_DATA_PROVIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), 
TRACKER_TYPE_FILE_DATA_PROVIDER, TrackerFileDataProviderClass))
+
+/**
+ * TrackerFileDataProvider:
+ *
+ * An implementation of the #TrackerDataProvider interface.
+ **/
+typedef struct _TrackerFileDataProvider        TrackerFileDataProvider;
+typedef struct _TrackerFileDataProviderClass   TrackerFileDataProviderClass;
+typedef struct _TrackerFileDataProviderPrivate TrackerFileDataProviderPrivate;
+
+/**
+ * TrackerFileDataProviderClass:
+ * @parent_class: Parent object class.
+ *
+ * Prototype for the class implementation.
+ **/
+struct _TrackerFileDataProviderClass {
+       GObjectClass parent_class;
+};
+
+GType                 tracker_file_data_provider_get_type (void) G_GNUC_CONST;
+TrackerDataProvider * tracker_file_data_provider_new      (void);
+
+G_END_DECLS
+
+#endif /* __LIBTRACKERMINER_FILE_DATA_PROVIDER_H__ */
diff --git a/src/libtracker-miner/tracker-file-enumerator.c b/src/libtracker-miner/tracker-file-enumerator.c
index 4a4f421..31a5c66 100644
--- a/src/libtracker-miner/tracker-file-enumerator.c
+++ b/src/libtracker-miner/tracker-file-enumerator.c
@@ -28,14 +28,9 @@ static void tracker_file_enumerator_file_iface_init (TrackerEnumeratorIface *ifa
 struct _TrackerFileEnumerator {
        GObject parent_instance;
        TrackerCrawlFlags crawl_flags;
+       GFileEnumerator *file_enumerator;
 };
 
-typedef struct {
-       GFile *dir;
-       gchar *attributes;
-       GFileQueryInfoFlags flags;
-} GetChildrenData;
-
 /**
  * SECTION:tracker-file-enumerator
  * @short_description: File based enumerator for file:// descendant URIs
@@ -57,6 +52,12 @@ G_DEFINE_TYPE_WITH_CODE (TrackerFileEnumerator, tracker_file_enumerator, G_TYPE_
 static void
 tracker_file_enumerator_finalize (GObject *object)
 {
+       TrackerFileEnumerator *tfe = TRACKER_FILE_ENUMERATOR (object);
+
+       if (tfe->file_enumerator) {
+               g_object_unref (tfe->file_enumerator);
+       }
+
        G_OBJECT_CLASS (tracker_file_enumerator_parent_class)->finalize (object);
 }
 
@@ -74,221 +75,105 @@ tracker_file_enumerator_init (TrackerFileEnumerator *fe)
        fe->crawl_flags = TRACKER_CRAWL_FLAG_NONE;
 }
 
-static TrackerCrawlFlags
-file_enumerator_get_crawl_flags (TrackerEnumerator *enumerator)
-{
-       TrackerFileEnumerator *fe;
-
-       fe = TRACKER_FILE_ENUMERATOR (enumerator);
-
-       return fe->crawl_flags;
-}
-
-static void
-file_enumerator_set_crawl_flags (TrackerEnumerator *enumerator,
-                                 TrackerCrawlFlags  flags)
-{
-       TrackerFileEnumerator *fe;
-
-       fe = TRACKER_FILE_ENUMERATOR (enumerator);
-
-       fe->crawl_flags = flags;
-}
-
-static GetChildrenData *
-get_children_data_new (GFile               *dir,
-                       const gchar         *attributes,
-                       GFileQueryInfoFlags  flags)
+static gpointer
+file_enumerator_next (TrackerEnumerator  *enumerator,
+                      GCancellable       *cancellable,
+                      GError            **error)
 {
-       GetChildrenData *data;
-
-       data = g_slice_new0 (GetChildrenData);
-       data->dir = g_object_ref (dir);
-       /* FIXME: inefficient */
-       data->attributes = g_strdup (attributes);
-       data->flags = flags;
-
-       return data;
-}
-
-static void
-get_children_data_free (GetChildrenData *data)
-{
-       if (!data) {
-               return;
-       }
-
-       g_object_unref (data->dir);
-       g_free (data->attributes);
-       g_slice_free (GetChildrenData, data);
-}
-
-static GSList *
-file_enumerator_get_children (TrackerEnumerator    *enumerator,
-                              GFile                *dir,
-                              const gchar          *attributes,
-                              GFileQueryInfoFlags   flags,
-                              GCancellable         *cancellable,
-                              GError              **error)
-{
-       GFileEnumerator *fe;
-       GSList *files;
+       TrackerFileEnumerator *tfe;
+       GFileInfo *info = NULL;
        GError *local_error = NULL;
-       gboolean cancelled;
-
-       fe = g_file_enumerate_children (dir,
-                                       attributes,
-                                       flags,
-                                       cancellable,
-                                       &local_error);
-
-
-       cancelled = g_cancellable_is_cancelled (cancellable);
-
-       if (!fe) {
-               if (local_error && !cancelled) {
-                       gchar *uri;
-
-                       uri = g_file_get_uri (dir);
-
-                       g_warning ("Could not open directory '%s': %s",
-                                  uri, local_error->message);
-
-                       g_propagate_error (error, local_error);
-                       g_free (uri);
-               }
 
+       if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                return NULL;
        }
 
-       files = NULL;
-
-       /* May as well be while TRUE ... */
-       while (!cancelled) {
-               GFileInfo *info;
-
-               info = g_file_enumerator_next_file (fe, cancellable, &local_error);
+       tfe = TRACKER_FILE_ENUMERATOR (enumerator);
+       info = g_file_enumerator_next_file (tfe->file_enumerator, cancellable, &local_error);
 
-               /* FIXME: Do we need a ->is_running check here like before? */
-               if (local_error || !info) {
-                       if (local_error && !cancelled) {
-                               g_critical ("Could not crawl through directory: %s", local_error->message);
-                               g_propagate_error (error, local_error);
-                       }
-
-                       /* No more files or we are stopping anyway, so clean
-                        * up and close all file enumerators.
-                        */
-                       if (info) {
-                               g_object_unref (info);
-                       }
-
-                       /* FIXME: We need some check here to call
-                        * enumerator_data_process which signals
-                        * CHECK_DIRECTORY_CONTENTS
-                        */
-                       g_file_enumerator_close (fe, NULL, &local_error);
-
-                       if (local_error) {
-                               g_warning ("Couldn't close GFileEnumerator (%p): %s", fe,
-                                          local_error ? local_error->message : "No reason");
-                               g_propagate_error (error, local_error);
-                       }
-
-                       g_object_unref (fe);
-
-                       break;
+       /* FIXME: Do we need a ->is_running check here like before? */
+       if (local_error || !info) {
+               if (local_error) {
+                       g_critical ("Could not crawl through directory: %s", local_error->message);
+                       g_propagate_error (error, local_error);
                }
 
-               g_message ("--> Found:'%s' (%s)",
-                          g_file_info_get_name (info),
-                          g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY ? "Dir" : "File");
-
+               /* No more files or we are stopping anyway, so clean
+                * up and close all file enumerators.
+                */
+               if (info) {
+                       g_object_unref (info);
+               }
 
-               files = g_slist_prepend (files, info);
+               return NULL;
        }
 
-       return g_slist_reverse (files);
-}
+       /* FIXME: We need some check here to call
+        * enumerator_data_process which signals
+        * CHECK_DIRECTORY_CONTENTS
+        */
+       g_debug ("--> Found:'%s' (%s)",
+                g_file_info_get_name (info),
+                g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY ? "Dir" : "File");
 
-static void
-get_children_async_thread_op_free (GSList *files)
-{
-       g_slist_free_full (files, g_object_unref);
+       return info;
 }
 
 static void
-get_children_async_thread (GTask        *task,
-                           gpointer      source_object,
-                           gpointer      task_data,
-                           GCancellable *cancellable)
+file_enumerator_next_thread (GTask        *task,
+                             gpointer      source_object,
+                             gpointer      task_data,
+                             GCancellable *cancellable)
 {
        TrackerEnumerator *enumerator = source_object;
-       GetChildrenData *data = task_data;
-       GSList *files = NULL;
+       GFileInfo *info;
        GError *error = NULL;
 
-       if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
-               files = NULL;
-       } else {
-               files = file_enumerator_get_children (enumerator,
-                                                     data->dir,
-                                                     data->attributes,
-                                                     data->flags,
-                                                     cancellable,
-                                                     &error);
-       }
+       info = file_enumerator_next (enumerator, cancellable, &error);
 
        if (error) {
                g_task_return_error (task, error);
        } else {
-               g_task_return_pointer (task, files, (GDestroyNotify) get_children_async_thread_op_free);
+               g_task_return_pointer (task, info, (GDestroyNotify) g_object_unref);
        }
 }
 
 static void
-file_enumerator_get_children_async (TrackerEnumerator    *enumerator,
-                                    GFile                *dir,
-                                    const gchar          *attributes,
-                                    GFileQueryInfoFlags   flags,
-                                    int                   io_priority,
-                                    GCancellable         *cancellable,
-                                    GAsyncReadyCallback   callback,
-                                    gpointer              user_data)
+file_enumerator_next_async (TrackerEnumerator    *enumerator,
+                            gint                  io_priority,
+                            GCancellable         *cancellable,
+                            GAsyncReadyCallback   callback,
+                            gpointer              user_data)
 {
        GTask *task;
 
        task = g_task_new (enumerator, cancellable, callback, user_data);
-       g_task_set_task_data (task, get_children_data_new (dir, attributes, flags), (GDestroyNotify) 
get_children_data_free);
        g_task_set_priority (task, io_priority);
-
-       g_task_run_in_thread (task, get_children_async_thread);
+       g_task_run_in_thread (task, file_enumerator_next_thread);
        g_object_unref (task);
 }
 
-static GSList *
-file_enumerator_get_children_finish (TrackerEnumerator  *enumerator,
-                                     GAsyncResult       *result,
-                                     GError            **error)
+static gpointer
+file_enumerator_next_finish (TrackerEnumerator  *enumerator,
+                             GAsyncResult       *result,
+                             GError            **error)
 {
        g_return_val_if_fail (g_task_is_valid (result, enumerator), NULL);
 
        return g_task_propagate_pointer (G_TASK (result), error);
 }
 
-
 static void
 tracker_file_enumerator_file_iface_init (TrackerEnumeratorIface *iface)
 {
-       iface->get_crawl_flags = file_enumerator_get_crawl_flags;
-       iface->set_crawl_flags = file_enumerator_set_crawl_flags;
-       iface->get_children = file_enumerator_get_children;
-       iface->get_children_async = file_enumerator_get_children_async;
-       iface->get_children_finish = file_enumerator_get_children_finish;
+       iface->next = file_enumerator_next;
+       iface->next_async = file_enumerator_next_async;
+       iface->next_finish = file_enumerator_next_finish;
 }
 
 /**
  * tracker_file_enumerator_new:
+ * @file_enumerator: the #GFileEnumerator used to enumerate with
  *
  * Creates a new TrackerEnumerator which can be used to create new
  * #TrackerMinerFS classes. See #TrackerMinerFS for an example of how
@@ -297,14 +182,21 @@ tracker_file_enumerator_file_iface_init (TrackerEnumeratorIface *iface)
  * Returns: (transfer full): a #TrackerEnumerator which must be
  * unreferenced with g_object_unref().
  *
- * Since: 1.2:
+ * Since: 1.2
  **/
 TrackerEnumerator *
-tracker_file_enumerator_new (void)
+tracker_file_enumerator_new (GFileEnumerator *file_enumerator)
 {
        TrackerFileEnumerator *tfe;
 
+       g_return_val_if_fail (G_IS_FILE_ENUMERATOR (file_enumerator), NULL);
+
        tfe = g_object_new (TRACKER_TYPE_FILE_ENUMERATOR, NULL);
+       if (!tfe) {
+               return NULL;
+       }
+
+       tfe->file_enumerator = g_object_ref (file_enumerator);
 
        return TRACKER_ENUMERATOR (tfe);
 }
diff --git a/src/libtracker-miner/tracker-file-enumerator.h b/src/libtracker-miner/tracker-file-enumerator.h
index 750a0a6..c33a291 100644
--- a/src/libtracker-miner/tracker-file-enumerator.h
+++ b/src/libtracker-miner/tracker-file-enumerator.h
@@ -53,7 +53,7 @@ struct _TrackerFileEnumeratorClass {
 };
 
 GType               tracker_file_enumerator_get_type (void) G_GNUC_CONST;
-TrackerEnumerator * tracker_file_enumerator_new      (void);
+TrackerEnumerator * tracker_file_enumerator_new      (GFileEnumerator *file_enumerator);
 
 G_END_DECLS
 
diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c
index 156374b..b332385 100644
--- a/src/libtracker-miner/tracker-file-notifier.c
+++ b/src/libtracker-miner/tracker-file-notifier.c
@@ -38,7 +38,7 @@ static GQuark quark_property_filesystem_mtime = 0;
 enum {
        PROP_0,
        PROP_INDEXING_TREE,
-       PROP_ENUMERATOR
+       PROP_DATA_PROVIDER
 };
 
 enum {
@@ -75,7 +75,7 @@ typedef struct {
 
        TrackerCrawler *crawler;
        TrackerMonitor *monitor;
-       TrackerEnumerator *enumerator;
+       TrackerDataProvider *data_provider;
 
        GTimer *timer;
 
@@ -116,8 +116,8 @@ tracker_file_notifier_set_property (GObject      *object,
                tracker_monitor_set_indexing_tree (priv->monitor,
                                                   priv->indexing_tree);
                break;
-       case PROP_ENUMERATOR:
-               priv->enumerator = g_value_dup_object (value);
+       case PROP_DATA_PROVIDER:
+               priv->data_provider = g_value_dup_object (value);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -139,8 +139,8 @@ tracker_file_notifier_get_property (GObject    *object,
        case PROP_INDEXING_TREE:
                g_value_set_object (value, priv->indexing_tree);
                break;
-       case PROP_ENUMERATOR:
-               g_value_set_object (value, priv->enumerator);
+       case PROP_DATA_PROVIDER:
+               g_value_set_object (value, priv->data_provider);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1309,7 +1309,7 @@ indexing_tree_directory_removed (TrackerIndexingTree *indexing_tree,
        }
 
        /* Remove monitors if any */
-       /* FIXME: How do we handle this with 3rd party enumerators? */
+       /* FIXME: How do we handle this with 3rd party data_providers? */
        tracker_monitor_remove_recursively (priv->monitor, directory);
 
        /* Remove all files from cache */
@@ -1367,7 +1367,7 @@ tracker_file_notifier_constructed (GObject *object)
                          G_CALLBACK (indexing_tree_directory_removed), object);
 
        /* Set up crawler */
-       priv->crawler = tracker_crawler_new (priv->enumerator);
+       priv->crawler = tracker_crawler_new (priv->data_provider);
        tracker_crawler_set_file_attributes (priv->crawler,
                                             G_FILE_ATTRIBUTE_TIME_MODIFIED ","
                                             G_FILE_ATTRIBUTE_STANDARD_TYPE);
@@ -1479,11 +1479,11 @@ tracker_file_notifier_class_init (TrackerFileNotifierClass *klass)
                                                              G_PARAM_READWRITE |
                                                              G_PARAM_CONSTRUCT_ONLY));
        g_object_class_install_property (object_class,
-                                        PROP_ENUMERATOR,
-                                        g_param_spec_object ("enumerator",
-                                                             "Enumerator",
-                                                             "Enumerator to use to crawl structures 
populating data, e.g. like GFileEnumerator",
-                                                             TRACKER_TYPE_ENUMERATOR,
+                                        PROP_DATA_PROVIDER,
+                                        g_param_spec_object ("data-provider",
+                                                             "Data provider",
+                                                             "Data provider to use to crawl structures 
populating data, e.g. like GFileEnumerator",
+                                                             TRACKER_TYPE_DATA_PROVIDER,
                                                              G_PARAM_READWRITE |
                                                              G_PARAM_CONSTRUCT_ONLY));
 
@@ -1549,14 +1549,14 @@ tracker_file_notifier_init (TrackerFileNotifier *notifier)
 }
 
 TrackerFileNotifier *
-tracker_file_notifier_new (TrackerIndexingTree *indexing_tree,
-                           TrackerEnumerator   *enumerator)
+tracker_file_notifier_new (TrackerIndexingTree  *indexing_tree,
+                           TrackerDataProvider  *data_provider)
 {
        g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (indexing_tree), NULL);
 
        return g_object_new (TRACKER_TYPE_FILE_NOTIFIER,
                             "indexing-tree", indexing_tree,
-                            "enumerator", enumerator,
+                            "data-provider", data_provider,
                             NULL);
 }
 
diff --git a/src/libtracker-miner/tracker-file-notifier.h b/src/libtracker-miner/tracker-file-notifier.h
index 5af8760..f1c86a5 100644
--- a/src/libtracker-miner/tracker-file-notifier.h
+++ b/src/libtracker-miner/tracker-file-notifier.h
@@ -80,7 +80,7 @@ GType         tracker_file_notifier_get_type     (void) G_GNUC_CONST;
 
 TrackerFileNotifier *
               tracker_file_notifier_new          (TrackerIndexingTree     *indexing_tree,
-                                                  TrackerEnumerator       *enumerator);
+                                                  TrackerDataProvider     *data_provider);
 
 gboolean      tracker_file_notifier_start        (TrackerFileNotifier     *notifier);
 void          tracker_file_notifier_stop         (TrackerFileNotifier     *notifier);
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index 01ec0af..115be5b 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -117,7 +117,7 @@ static gboolean miner_fs_queues_status_trace_timeout_cb (gpointer data);
  * should it process, and the actual data extraction.
  *
  * Example creating a TrackerMinerFS with our own file system root and
- * enumerator.
+ * data provider.
  *
  * First create our class and base it on TrackerMinerFS:
  * |[
@@ -128,10 +128,10 @@ static gboolean miner_fs_queues_status_trace_timeout_cb (gpointer data);
  *
  * Later in our class creation function, we are supplying the
  * arguments we want. In this case, the 'root' is a #GFile pointing to
- * a root URI location (for example 'file:///') and 'enumerator' is a
- * #TrackerEnumerator used to enumerate 'root' and return children it
- * finds. If 'enumerator' is %NULL (the default), then a
- * #TrackerFileEnumerator is created automatically.
+ * a root URI location (for example 'file:///') and 'data_provider' is a
+ * #TrackerDataProvider used to enumerate 'root' and return children it
+ * finds. If 'data_provider' is %NULL (the default), then a
+ * #TrackerFileDataProvider is created automatically.
  * |[
  * // Note that only 'name' is mandatory
  * miner = g_initable_new (MY_TYPE_MINER_FILES,
@@ -139,7 +139,7 @@ static gboolean miner_fs_queues_status_trace_timeout_cb (gpointer data);
  *                         error,
  *                         "name", "MyMinerFiles",
  *                         "root", root,
- *                         "enumerator", enumerator,
+ *                         "data-provider", data_provider,
  *                         "processing-pool-wait-limit", 10,
  *                         "processing-pool-ready-limit", 100,
  *                         NULL);
@@ -199,7 +199,7 @@ struct _TrackerMinerFSPrivate {
        GFile *root;
        TrackerIndexingTree *indexing_tree;
        TrackerFileNotifier *file_notifier;
-       TrackerEnumerator *enumerator;
+       TrackerDataProvider *data_provider;
 
        /* Sparql insertion tasks */
        TrackerTaskPool *task_pool;
@@ -285,7 +285,7 @@ enum {
        PROP_ROOT,
        PROP_WAIT_POOL_LIMIT,
        PROP_READY_POOL_LIMIT,
-       PROP_ENUMERATOR,
+       PROP_DATA_PROVIDER,
        PROP_MTIME_CHECKING,
        PROP_INITIAL_CRAWLING
 };
@@ -414,11 +414,11 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                                                            1, G_MAXUINT, DEFAULT_READY_POOL_LIMIT,
                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
        g_object_class_install_property (object_class,
-                                        PROP_ENUMERATOR,
-                                        g_param_spec_object ("enumerator",
-                                                             "Enumerator",
-                                                             "Enumerator to use to crawl structures 
populating data, e.g. like GFileEnumerator",
-                                                             TRACKER_TYPE_ENUMERATOR,
+                                        PROP_DATA_PROVIDER,
+                                        g_param_spec_object ("data-provider",
+                                                             "Data provider",
+                                                             "Data provider populating data, e.g. like 
GFileEnumerator",
+                                                             TRACKER_TYPE_DATA_PROVIDER,
                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
        g_object_class_install_property (object_class,
                                         PROP_MTIME_CHECKING,
@@ -726,7 +726,7 @@ miner_fs_initable_init (GInitable     *initable,
 
        /* Create the file notifier */
        priv->file_notifier = tracker_file_notifier_new (priv->indexing_tree,
-                                                        priv->enumerator);
+                                                        priv->data_provider);
 
        if (!priv->file_notifier) {
                g_set_error (error,
@@ -914,8 +914,8 @@ fs_set_property (GObject      *object,
                                                     fs->priv->sparql_buffer_limit);
                }
                break;
-       case PROP_ENUMERATOR:
-               fs->priv->enumerator = g_value_dup_object (value);
+       case PROP_DATA_PROVIDER:
+               fs->priv->data_provider = g_value_dup_object (value);
                break;
        case PROP_MTIME_CHECKING:
                fs->priv->mtime_checking = g_value_get_boolean (value);
@@ -955,8 +955,8 @@ fs_get_property (GObject    *object,
        case PROP_MTIME_CHECKING:
                g_value_set_boolean (value, fs->priv->mtime_checking);
                break;
-       case PROP_ENUMERATOR:
-               g_value_set_object (value, fs->priv->enumerator);
+       case PROP_DATA_PROVIDER:
+               g_value_set_object (value, fs->priv->data_provider);
                break;
        case PROP_INITIAL_CRAWLING:
                g_value_set_boolean (value, fs->priv->initial_crawling);
@@ -3204,7 +3204,7 @@ tracker_miner_fs_directory_add (TrackerMinerFS *fs,
                flags |= TRACKER_DIRECTORY_FLAG_RECURSE;
        }
 
-       if (!fs->priv->enumerator) {
+       if (!fs->priv->data_provider) {
                flags |= TRACKER_DIRECTORY_FLAG_MONITOR;
        }
 
@@ -3645,7 +3645,7 @@ tracker_miner_fs_check_directory_with_priority (TrackerMinerFS *fs,
                flags = TRACKER_DIRECTORY_FLAG_RECURSE |
                        TRACKER_DIRECTORY_FLAG_CHECK_MTIME;
 
-               if (!fs->priv->enumerator) {
+               if (!fs->priv->data_provider) {
                        flags |= TRACKER_DIRECTORY_FLAG_MONITOR;
                }
 
@@ -4028,7 +4028,7 @@ tracker_miner_fs_force_mtime_checking (TrackerMinerFS *fs,
        flags = TRACKER_DIRECTORY_FLAG_RECURSE |
                TRACKER_DIRECTORY_FLAG_CHECK_MTIME;
 
-       if (!fs->priv->enumerator) {
+       if (!fs->priv->data_provider) {
                flags |= TRACKER_DIRECTORY_FLAG_MONITOR;
        }
 
@@ -4106,7 +4106,7 @@ tracker_miner_fs_add_directory_without_parent (TrackerMinerFS *fs,
                TRACKER_DIRECTORY_FLAG_PRESERVE |
                TRACKER_DIRECTORY_FLAG_CHECK_MTIME;
 
-       if (!fs->priv->enumerator) {
+       if (!fs->priv->data_provider) {
                flags |= TRACKER_DIRECTORY_FLAG_MONITOR;
        }
 
@@ -4134,22 +4134,22 @@ tracker_miner_fs_get_indexing_tree (TrackerMinerFS *fs)
 }
 
 /**
- * tracker_miner_fs_get_enumerator:
+ * tracker_miner_fs_get_data_provider:
  * @fs: a #TrackerMinerFS
  *
- * Returns the #TrackerEnumerator implementation, which is being used
+ * Returns the #TrackerDataProvider implementation, which is being used
  * to supply #GFile and #GFileInfo content to Tracker.
  *
- * Returns: (transfer none): The #TrackerEnumerator supplying content
+ * Returns: (transfer none): The #TrackerDataProvider supplying content
  *
  * Since: 1.2
  **/
-TrackerEnumerator *
-tracker_miner_fs_get_enumerator (TrackerMinerFS *fs)
+TrackerDataProvider *
+tracker_miner_fs_get_data_provider (TrackerMinerFS *fs)
 {
        g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL);
 
-       return fs->priv->enumerator;
+       return fs->priv->data_provider;
 }
 
 #ifdef EVENT_QUEUE_ENABLE_TRACE
diff --git a/src/libtracker-miner/tracker-miner-fs.h b/src/libtracker-miner/tracker-miner-fs.h
index 342acc0..f46d022 100644
--- a/src/libtracker-miner/tracker-miner-fs.h
+++ b/src/libtracker-miner/tracker-miner-fs.h
@@ -30,9 +30,9 @@
 #include <libtracker-sparql/tracker-sparql.h>
 
 #include "tracker-miner-object.h"
-#include "tracker-indexing-tree.h"
-
 #include "tracker-miner-common.h"
+#include "tracker-data-provider.h"
+#include "tracker-indexing-tree.h"
 
 G_BEGIN_DECLS
 
@@ -130,7 +130,7 @@ GQuark                tracker_miner_fs_error_quark           (void);
 
 /* Properties */
 TrackerIndexingTree * tracker_miner_fs_get_indexing_tree     (TrackerMinerFS  *fs);
-TrackerEnumerator *   tracker_miner_fs_get_enumerator        (TrackerMinerFS  *fs);
+TrackerDataProvider * tracker_miner_fs_get_data_provider     (TrackerMinerFS  *fs);
 gdouble               tracker_miner_fs_get_throttle          (TrackerMinerFS  *fs);
 gboolean              tracker_miner_fs_get_mtime_checking    (TrackerMinerFS  *fs);
 gboolean              tracker_miner_fs_get_initial_crawling  (TrackerMinerFS  *fs);
diff --git a/src/libtracker-miner/tracker-miner.h b/src/libtracker-miner/tracker-miner.h
index d437385..be46174 100644
--- a/src/libtracker-miner/tracker-miner.h
+++ b/src/libtracker-miner/tracker-miner.h
@@ -22,9 +22,10 @@
 
 #define __LIBTRACKER_MINER_H_INSIDE__
 
-#include <libtracker-miner/tracker-enumerator.h>
+#include <libtracker-miner/tracker-data-provider.h>
 #include <libtracker-miner/tracker-decorator.h>
 #include <libtracker-miner/tracker-decorator-fs.h>
+#include <libtracker-miner/tracker-enumerator.h>
 #include <libtracker-miner/tracker-miner-object.h>
 #include <libtracker-miner/tracker-miner-online.h>
 #include <libtracker-miner/tracker-miner-fs.h>
diff --git a/tests/libtracker-miner/tracker-file-enumerator-test.c 
b/tests/libtracker-miner/tracker-file-enumerator-test.c
index 99e68de..a0a35ef 100644
--- a/tests/libtracker-miner/tracker-file-enumerator-test.c
+++ b/tests/libtracker-miner/tracker-file-enumerator-test.c
@@ -21,57 +21,74 @@
 
 #include <locale.h>
 
-#include <libtracker-miner/tracker-file-enumerator.h>
+#include <libtracker-miner/tracker-miner.h>
+/* Normally private */
+#include <libtracker-miner/tracker-file-data-provider.h>
 
 static void
-test_enumerator_crawl (void)
+test_enumerator_and_provider (void)
 {
+       GFileEnumerator *fe;
+       TrackerDataProvider *data_provider;
        TrackerEnumerator *enumerator;
-       GFile *dir;
+       GFileInfo *info;
+       GFile *url;
        GSList *files, *l;
        GError *error = NULL;
+       gint count = 0;
        const gchar *path;
 
-       setlocale (LC_ALL, "");
-
-       enumerator = tracker_file_enumerator_new ();
-       g_assert (enumerator != NULL);
+       data_provider = tracker_file_data_provider_new ();
+       g_assert_nonnull (data_provider);
 
        /* FIXME: Use better tmp data structure */
-       path = "/tmp";
-       dir = g_file_new_for_path (path);
-       g_print ("'%s'\n", path);
-
-       files = tracker_enumerator_get_children (enumerator,
-                                                dir,
-                                                G_FILE_ATTRIBUTE_STANDARD_NAME "," \
-                                                G_FILE_ATTRIBUTE_STANDARD_TYPE,
-                                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                                NULL,
-                                                &error);
-       g_assert_no_error (error);
-       g_assert (files != NULL);
-       g_assert (g_slist_length (files) > 0);
+       url = g_file_new_for_path (g_get_tmp_dir ());
+       g_assert_nonnull (url);
 
-       for (l = files; l; l = l->next) {
-               GFileInfo *info = l->data;
+       /* fe = g_file_enumerate_children ( */
+       /*                                 0, */
+       /*                                 NULL, */
+       /*                                 &error); */
 
-               g_print ("-> '%s'\n", g_file_info_get_name (info));
+       /* g_assert_no_error (error); */
+       /* g_assert_nonnull (fe); */
+
+       /* enumerator = tracker_file_enumerator_new (fe); */
+       /* g_assert_nonnull (enumerator); */
+
+       enumerator = tracker_data_provider_begin (data_provider,
+                                                 url,
+                                                 G_FILE_ATTRIBUTE_STANDARD_NAME "," \
+                                                 G_FILE_ATTRIBUTE_STANDARD_TYPE,
+                                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                                 NULL,
+                                                 &error);
+       g_assert_no_error (error);
+       g_assert_nonnull (enumerator);
+
+       while ((info = tracker_enumerator_next (enumerator, NULL, &error)) != NULL) {
+               g_assert_no_error (error);
+               count++;
        }
 
-       g_object_unref (dir);
+       g_assert_no_error (error);
+       g_assert (count > 0);
+
+       g_object_unref (enumerator);
+       g_object_unref (data_provider);
 }
 
 int
-main (int    argc,
-      char **argv)
+main (int argc, char **argv)
 {
+       setlocale (LC_ALL, "");
+
        g_test_init (&argc, &argv, NULL);
 
        g_test_message ("Testing file enumerator");
 
-       g_test_add_func ("/libtracker-miner/tracker-enumerator/crawl",
-                        test_enumerator_crawl);
+       g_test_add_func ("/libtracker-miner/tracker-enumerator-and-provider",
+                        test_enumerator_and_provider);
 
        return g_test_run ();
 }


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