[tracker] Moved config functions and modules around



commit 407212934384cc8c87439096bb643d833eb6589c
Author: Martyn Russell <martyn imendio com>
Date:   Mon Jul 20 11:37:03 2009 +0100

    Moved config functions and modules around
    
    Now we have tracker-config-manager which is used to do all file based
    operations for the config file. We also have tracker-config-utils
    which does all the GKeyFile<-->GObject work for us.
    
    Perhaps these should be renamed at some point to:
    
      tracker-config-file
      tracker-object-keyfile
    
    To be more aligned to what they actually do.

 configure.ac                                   |    2 +-
 src/libtracker-common/Makefile.am              |    4 +
 src/libtracker-common/tracker-config-manager.c |  371 +++++++
 src/libtracker-common/tracker-config-manager.h |  118 ++
 src/libtracker-common/tracker-config-utils.c   |  351 ++++++
 src/libtracker-common/tracker-config-utils.h   |   81 ++
 src/tracker-extract/tracker-config.c           |  490 +++------
 src/tracker-extract/tracker-config.h           |   31 +-
 src/tracker-miner-fs/tracker-config.c          | 1398 ++++++------------------
 src/tracker-miner-fs/tracker-config.h          |   18 +-
 src/tracker-store/tracker-config.c             |  732 ++++---------
 src/tracker-store/tracker-config.h             |   16 +-
 12 files changed, 1618 insertions(+), 1994 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index b3b31a5..013f889 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1504,7 +1504,7 @@ Plugins:
 	Evolution plugin    (data-push):	$have_evolution_plugin
 	KMail plugin        (data-push):	$enable_kmail_push_module
 
-Warning:
+Warning:2
 
         You must make sure SQLite is compiled with --enable-threadsafe
 
diff --git a/src/libtracker-common/Makefile.am b/src/libtracker-common/Makefile.am
index 048c60a..fb35aa5 100644
--- a/src/libtracker-common/Makefile.am
+++ b/src/libtracker-common/Makefile.am
@@ -57,6 +57,8 @@ libtracker_common_la_SOURCES =	 			\
 	$(os_sources)					\
 	$(power_sources)				\
 	$(storage_sources)				\
+	tracker-config-manager.c			\
+	tracker-config-utils.c				\
 	tracker-class.c					\
 	tracker-dbus.c	 				\
 	tracker-file-utils.c				\
@@ -88,6 +90,8 @@ noinst_HEADERS =					\
 	tracker-albumart.h
 
 libtracker_commoninclude_HEADERS =			\
+	tracker-config-manager.h			\
+	tracker-config-utils.h				\
 	tracker-class.h					\
 	tracker-common.h				\
 	tracker-file-utils.h				\
diff --git a/src/libtracker-common/tracker-config-manager.c b/src/libtracker-common/tracker-config-manager.c
new file mode 100644
index 0000000..dd865af
--- /dev/null
+++ b/src/libtracker-common/tracker-config-manager.c
@@ -0,0 +1,371 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "tracker-config-manager.h"
+
+#define TRACKER_CONFIG_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_CONFIG_MANAGER, TrackerConfigManagerPrivate))
+
+typedef struct _TrackerConfigManagerPrivate TrackerConfigManagerPrivate;
+
+struct _TrackerConfigManagerPrivate {
+	gchar *domain;
+};
+
+static void     config_finalize     (GObject              *object);
+static void     config_load         (TrackerConfigManager *config);
+static gboolean config_save         (TrackerConfigManager *config);
+static void     config_get_property (GObject              *object,
+				     guint                 param_id,
+				     GValue               *value,
+				     GParamSpec           *pspec);
+static void     config_set_property (GObject              *object,
+				     guint                 param_id,
+				     const GValue         *value,
+				     GParamSpec           *pspec);
+static void     config_constructed  (GObject              *object);
+
+enum {
+	PROP_0,
+	PROP_DOMAIN
+};
+
+G_DEFINE_TYPE (TrackerConfigManager, tracker_config_manager, G_TYPE_OBJECT);
+
+static void
+tracker_config_manager_class_init (TrackerConfigManagerClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->get_property = config_get_property;
+	object_class->set_property = config_set_property;
+	object_class->finalize	   = config_finalize;
+	object_class->constructed  = config_constructed;
+
+	g_object_class_install_property (object_class,
+					 PROP_DOMAIN,
+					 g_param_spec_string ("domain",
+							      "Config domain",
+							      "The prefix before .cfg for the filename",
+							      g_get_application_name (),
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_type_class_add_private (object_class, sizeof (TrackerConfigManagerPrivate));
+}
+
+static void
+tracker_config_manager_init (TrackerConfigManager *manager)
+{
+	manager->key_file = g_key_file_new ();
+}
+
+static void     
+config_get_property (GObject       *object,
+		     guint          param_id,
+		     GValue        *value,
+		     GParamSpec    *pspec)
+{
+	TrackerConfigManagerPrivate *priv;
+
+	priv = TRACKER_CONFIG_MANAGER_GET_PRIVATE (object);
+
+	switch (param_id) {
+	case PROP_DOMAIN:
+		g_value_set_string (value, priv->domain);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+config_set_property (GObject	  *object,
+		     guint	   param_id,
+		     const GValue *value,
+		     GParamSpec	  *pspec)
+{
+	TrackerConfigManagerPrivate *priv;
+
+	priv = TRACKER_CONFIG_MANAGER_GET_PRIVATE (object);
+
+	switch (param_id) {
+	case PROP_DOMAIN:
+		g_free (priv->domain);
+		priv->domain = g_strdup (g_value_get_string (value));
+		g_object_notify (object, "domain");
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+config_finalize (GObject *object)
+{
+	TrackerConfigManager *manager;
+	TrackerConfigManagerPrivate *priv;
+
+	manager = TRACKER_CONFIG_MANAGER (object);
+	priv = TRACKER_CONFIG_MANAGER_GET_PRIVATE (manager);
+
+	if (manager->key_file) {
+		g_key_file_free (manager->key_file);
+	}
+
+	if (manager->monitor) {
+		g_object_unref (manager->monitor);
+	}
+
+	if (manager->file) {
+		g_object_unref (manager->file);
+	}
+
+	g_free (priv->domain);
+
+	(G_OBJECT_CLASS (tracker_config_manager_parent_class)->finalize) (object);
+}
+
+static void
+config_constructed (GObject *object)
+{
+	config_load (TRACKER_CONFIG_MANAGER (object));
+}
+
+static gchar *
+config_dir_ensure_exists_and_return (void)
+{
+	gchar *directory;
+
+	directory = g_build_filename (g_get_user_config_dir (),
+				      "tracker",
+				      NULL);
+
+	if (!g_file_test (directory, G_FILE_TEST_EXISTS)) {
+		g_print ("Creating config directory:'%s'\n", directory);
+
+		if (g_mkdir_with_parents (directory, 0700) == -1) {
+			g_critical ("Could not create configuration directory");
+			g_free (directory);
+			return NULL;
+		}
+	}
+
+	return directory;
+}
+
+static void
+config_changed_cb (GFileMonitor     *monitor,
+		   GFile	    *file,
+		   GFile	    *other_file,
+		   GFileMonitorEvent event_type,
+		   gpointer	     user_data)
+{
+	TrackerConfigManager *manager;
+	gchar	             *filename;
+
+	manager = TRACKER_CONFIG_MANAGER (user_data);
+
+	/* Do we recreate if the file is deleted? */
+
+	switch (event_type) {
+	case G_FILE_MONITOR_EVENT_CHANGED:
+	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+		manager->file_exists = TRUE;
+
+		filename = g_file_get_path (file);
+		g_message ("Config file changed:'%s', reloading settings...",
+			   filename);
+		g_free (filename);
+
+		config_load (manager);
+		break;
+
+	case G_FILE_MONITOR_EVENT_DELETED:
+		manager->file_exists = FALSE;
+		break;
+
+	case G_FILE_MONITOR_EVENT_CREATED:
+	case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
+	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
+	case G_FILE_MONITOR_EVENT_UNMOUNTED:
+		manager->file_exists = TRUE;
+
+	default:
+		break;
+	}
+}
+
+static void
+config_load (TrackerConfigManager *manager)
+{
+	TrackerConfigManagerPrivate *priv;
+	GError *error = NULL;
+	gchar *basename;
+	gchar *filename;
+	gchar *directory;
+
+	/* Check we have a config file and if not, create it based on
+	 * the default settings.
+	 */
+	directory = config_dir_ensure_exists_and_return ();
+	if (!directory) {
+		return;
+	}
+
+	priv = TRACKER_CONFIG_MANAGER_GET_PRIVATE (manager);
+
+	basename = g_strdup_printf ("%s.cfg", priv->domain);
+	filename = g_build_filename (directory, basename, NULL);
+	g_free (basename);
+	g_free (directory);
+
+	/* Add file monitoring for changes */
+	if (!manager->file) {
+		manager->file = g_file_new_for_path (filename);
+	}
+
+	if (!manager->monitor) {
+		g_message ("Setting up monitor for changes to config file:'%s'",
+			   filename);
+
+		manager->monitor = g_file_monitor_file (manager->file,
+						       G_FILE_MONITOR_NONE,
+						       NULL,
+						       NULL);
+
+		g_signal_connect (manager->monitor, "changed",
+				  G_CALLBACK (config_changed_cb),
+				  manager);
+	}
+
+	/* Load options */
+	g_key_file_load_from_file (manager->key_file, 
+				   filename, 
+				   G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+				   &error);
+
+	/* We force an overwrite in cases of error */
+	manager->file_exists = error ? FALSE : TRUE;
+
+	if (error) {
+		g_error_free (error);
+	}
+
+	g_free (filename);
+}
+
+static gboolean
+config_save (TrackerConfigManager *manager)
+{
+	GError *error = NULL;
+	gchar *filename;
+	gchar *data;
+	gsize size;
+
+	if (!manager->key_file) {
+		g_critical ("Could not save config, GKeyFile was NULL, has the config been loaded?");
+
+		return FALSE;
+	}
+
+	g_message ("Setting details to GKeyFile object...");
+
+	/* FIXME: Get to GKeyFile from object properties */
+
+	g_message ("Saving config to disk...");
+
+	/* Do the actual saving to disk now */
+	data = g_key_file_to_data (manager->key_file, &size, &error);
+	if (error) {
+		g_warning ("Could not get config data to write to file, %s",
+			   error->message);
+		g_error_free (error);
+
+		return FALSE;
+	}
+
+	filename = g_file_get_path (manager->file);
+
+	g_file_set_contents (filename, data, size, &error);
+	g_free (data);
+
+	if (error) {
+		g_warning ("Could not write %" G_GSIZE_FORMAT " bytes to file '%s', %s",
+			   size,
+			   filename,
+			   error->message);
+		g_free (filename);
+		g_error_free (error);
+
+		return FALSE;
+	}
+
+	g_message ("Wrote config to '%s' (%" G_GSIZE_FORMAT " bytes)",
+		   filename, 
+		   size);
+
+	g_free (filename);
+
+	return TRUE;
+}
+
+/**
+ * tracker_config_manager_new:
+ *
+ * Creates a new GObject for handling Tracker's config file.
+ *
+ * Return value: A new TrackerConfigManager object. Must be unreferenced when
+ * finished with.
+ */
+TrackerConfigManager *
+tracker_config_manager_new (const gchar *domain)
+{
+	TrackerConfigManager *config;
+
+	config = g_object_new (TRACKER_TYPE_CONFIG_MANAGER, 
+			       "domain", domain,
+			       NULL);
+
+	return config;
+}
+
+/**
+ * tracker_config_manager_save:
+ * @config: a #TrackerConfigManager
+ *
+ * Writes the configuration stored in TrackerConfigManager to disk.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise.
+ */
+gboolean
+tracker_config_manager_save (TrackerConfigManager *config)
+{
+	g_return_val_if_fail (TRACKER_IS_CONFIG_MANAGER (config), FALSE);
+
+	return config_save (config);
+}
diff --git a/src/libtracker-common/tracker-config-manager.h b/src/libtracker-common/tracker-config-manager.h
new file mode 100644
index 0000000..e95057c
--- /dev/null
+++ b/src/libtracker-common/tracker-config-manager.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#ifndef __TRACKER_CONFIG_MANAGER_H__
+#define __TRACKER_CONFIG_MANAGER_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_CONFIG_MANAGER	    (tracker_config_manager_get_type ())
+#define TRACKER_CONFIG_MANAGER(o)	    (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_CONFIG_MANAGER, TrackerConfigManager))
+#define TRACKER_CONFIG_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_CONFIG_MANAGER, TrackerConfigManagerClass))
+#define TRACKER_IS_CONFIG_MANAGER(o)	    (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_CONFIG_MANAGER))
+#define TRACKER_IS_CONFIG_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_CONFIG_MANAGER))
+#define TRACKER_CONFIG_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_CONFIG_MANAGER, TrackerConfigManagerClass))
+
+typedef struct _TrackerConfigManager	  TrackerConfigManager;
+typedef struct _TrackerConfigManagerClass TrackerConfigManagerClass;
+
+struct _TrackerConfigManager {
+	GObject       parent;
+
+	GFile	     *file;
+	GFileMonitor *monitor;
+
+	gboolean      file_exists;
+
+	GKeyFile     *key_file;
+};
+
+struct _TrackerConfigManagerClass {
+	GObjectClass parent_class;
+};
+
+GType	              tracker_config_manager_get_type              (void) G_GNUC_CONST;
+
+TrackerConfigManager *tracker_config_manager_new                   (const gchar           *domain);
+gboolean              tracker_config_manager_save                  (TrackerConfigManager  *config);
+
+const gchar *         tracker_config_manager_get_property_blurb    (TrackerConfigManager  *config,
+								    const gchar           *property);
+gboolean              tracker_config_manager_boolean_default       (TrackerConfigManager  *config,
+								    const gchar           *property);
+
+gint                  tracker_config_manager_int_default           (TrackerConfigManager  *config,
+								    const gchar           *property);
+
+gboolean              tracker_config_manager_int_validate          (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    gint                   value);
+
+GSList *              tracker_config_manager_string_list_to_gslist (const gchar          **value,
+								    gboolean               is_directory_list);
+
+void                  tracker_config_manager_load_int              (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+void                  tracker_config_manager_load_boolean          (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+void                  tracker_config_manager_load_string           (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+void                  tracker_config_manager_load_string_list      (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+
+void                  tracker_config_manager_save_int              (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+void                  tracker_config_manager_save_boolean          (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+void                  tracker_config_manager_save_string           (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+void                  tracker_config_manager_save_string_list      (TrackerConfigManager  *config,
+								    const gchar           *property,
+								    GKeyFile              *key_file,
+								    const gchar           *group,
+								    const gchar           *key);
+	
+G_END_DECLS
+
+#endif /* __TRACKER_CONFIG_MANAGER_H__ */
diff --git a/src/libtracker-common/tracker-config-utils.c b/src/libtracker-common/tracker-config-utils.c
new file mode 100644
index 0000000..c69b111
--- /dev/null
+++ b/src/libtracker-common/tracker-config-utils.c
@@ -0,0 +1,351 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#include "config.h"
+
+#include <libtracker-common/tracker-file-utils.h>
+#include <libtracker-common/tracker-type-utils.h>
+
+#include "tracker-config-utils.h"
+
+static GSList *
+config_string_list_to_gslist (const gchar **value,
+			      gboolean	    is_directory_list)
+{
+	GSList *list = NULL;
+	gint	i;
+
+	if (!value) {
+		return NULL;
+	}
+
+	for (i = 0; value[i]; i++) {
+		const gchar *str;
+		gchar	    *validated;
+
+		str = value[i];
+		if (!str || str[0] == '\0') {
+			continue;
+		}
+
+		if (!is_directory_list) {
+			list = g_slist_prepend (list, g_strdup (str));
+			continue;
+		}
+
+		/* For directories we validate any special characters,
+		 * for example '~' and '../../'
+		 */
+		validated = tracker_path_evaluate_name (str);
+		if (validated) {
+			list = g_slist_prepend (list, validated);
+		}
+	}
+
+	return g_slist_reverse (list);
+}
+
+const gchar *
+tracker_config_blurb (gpointer     config,
+		      const gchar *property)
+{
+	GObjectClass *klass;
+	GParamSpec *spec;
+
+	g_return_val_if_fail (G_IS_OBJECT (config), NULL);
+	g_return_val_if_fail (property != NULL, NULL);
+	
+	klass = G_OBJECT_GET_CLASS (config);
+	spec = g_object_class_find_property (G_OBJECT_CLASS (klass), property);
+	g_return_val_if_fail (spec != NULL, NULL);
+
+	return g_param_spec_get_blurb (spec);
+}
+
+gboolean
+tracker_config_default_boolean (gpointer     config,
+				const gchar *property)
+{
+	GObjectClass *klass;
+	GParamSpec *spec;
+	GParamSpecBoolean *bspec; 
+
+	g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
+	g_return_val_if_fail (property != NULL, FALSE);
+
+	klass = G_OBJECT_GET_CLASS (config);
+	spec = g_object_class_find_property (G_OBJECT_CLASS (klass), property);
+	g_return_val_if_fail (spec != NULL, FALSE);
+
+	bspec = G_PARAM_SPEC_BOOLEAN (spec);
+	g_return_val_if_fail (bspec != NULL, FALSE);
+	
+	return bspec->default_value;
+}
+
+gint
+tracker_config_default_int (gpointer     config,
+			    const gchar *property)
+{
+	GObjectClass *klass;
+	GParamSpec *spec;
+	GParamSpecInt *ispec; 
+
+	g_return_val_if_fail (G_IS_OBJECT (config), 0);
+	g_return_val_if_fail (property != NULL, 0);
+
+	klass = G_OBJECT_GET_CLASS (config);
+	spec = g_object_class_find_property (G_OBJECT_CLASS (klass), property);
+	g_return_val_if_fail (spec != NULL, 0);
+
+	ispec = G_PARAM_SPEC_INT (spec);
+	g_return_val_if_fail (ispec != NULL, 0);
+
+	return ispec->default_value;
+}
+
+gboolean
+tracker_config_validate_int (gpointer     config,
+			     const gchar *property,
+			     gint	  value)
+{
+	g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
+	g_return_val_if_fail (property != NULL, FALSE);
+
+#ifdef G_DISABLE_CHECKS
+	GParamSpec *spec;
+	GValue	    value = { 0 };
+	gboolean    valid;
+
+	spec = g_object_class_find_property (G_OBJECT_CLASS (config), property);
+	g_return_val_if_fail (spec != NULL, FALSE);
+
+	g_value_init (&value, spec->value_type);
+	g_value_set_int (&value, verbosity);
+	valid = g_param_value_validate (spec, &value);
+	g_value_unset (&value);
+
+	g_return_val_if_fail (valid != TRUE, FALSE);
+#endif
+
+	return TRUE;
+}
+
+void
+tracker_config_load_int (gpointer     config,
+			 const gchar *property,
+			 GKeyFile    *key_file,
+			 const gchar *group,
+			 const gchar *key)
+{
+	GError *error = NULL;
+	gint	value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	value = g_key_file_get_integer (key_file, group, key, &error);
+	if (!error) {
+		g_object_set (G_OBJECT (config), property, value, NULL);
+	} else {
+		g_message ("Couldn't load config option '%s' (int) in group '%s', %s",
+			   property, group, error->message);
+		g_error_free (error);
+	}
+}
+
+void
+tracker_config_load_boolean (gpointer     config,
+			     const gchar *property,
+			     GKeyFile	 *key_file,
+			     const gchar *group,
+			     const gchar *key)
+{
+	GError	 *error = NULL;
+	gboolean  value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	value = g_key_file_get_boolean (key_file, group, key, &error);
+	if (!error) {
+		g_object_set (G_OBJECT (config), property, value, NULL);
+	} else {
+		g_message ("Couldn't load config option '%s' (bool) in group '%s', %s",
+			   property, group, error->message);
+		g_error_free (error);
+	}
+}
+
+void
+tracker_config_load_string (gpointer     config,
+			    const gchar	*property,
+			    GKeyFile    *key_file,
+			    const gchar	*group,
+			    const gchar	*key)
+{
+	GError *error = NULL;
+	gchar  *value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	value = g_key_file_get_string (key_file, group, key, &error);
+	if (!error) {
+		g_object_set (G_OBJECT (config), property, value, NULL);
+	} else {
+		g_message ("Couldn't load config option '%s' (string) in group '%s', %s",
+			   property, group, error->message);
+		g_error_free (error);
+	}
+
+	g_free (value);
+}
+
+void
+tracker_config_load_string_list (gpointer     config,
+				 const gchar *property,
+				 GKeyFile    *key_file,
+				 const gchar *group,
+				 const gchar *key,
+				 gboolean     is_directory_list)
+{
+	GSList *l;
+	gchar **value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	value = g_key_file_get_string_list (key_file, group, key, NULL, NULL);
+	l = config_string_list_to_gslist ((const gchar **) value, is_directory_list);
+	g_strfreev (value);
+
+	if (l) {
+		GSList *filtered;
+
+		/* Should we make the basename (2nd argument) here
+		 * part of this function's API? 
+		 */
+		filtered = tracker_path_list_filter_duplicates (l, ".");
+		
+		g_slist_foreach (l, (GFunc) g_free, NULL);
+		g_slist_free (l);
+
+		l = filtered;
+	}
+
+	g_object_set (G_OBJECT (config), property, l, NULL);
+}
+
+void
+tracker_config_save_int (gpointer     config,
+			 const gchar *property,
+			 GKeyFile    *key_file,
+			 const gchar *group,
+			 const gchar *key)
+{
+	gint value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	g_object_get (G_OBJECT (config), property, &value, NULL);
+	g_key_file_set_integer (key_file, group, key, value);
+}
+
+void
+tracker_config_save_boolean (gpointer     config,
+			     const gchar *property,
+			     GKeyFile    *key_file,
+			     const gchar *group,
+			     const gchar *key)
+{
+	gboolean value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	g_object_get (G_OBJECT (config), property, &value, NULL);
+	g_key_file_set_boolean (key_file, group, key, value);
+}
+
+void
+tracker_config_save_string (gpointer     config,
+			    const gchar *property,
+			    GKeyFile	*key_file,
+			    const gchar *group,
+			    const gchar	*key)
+{
+	gchar *value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	g_object_get (G_OBJECT (config), property, &value, NULL);
+	g_key_file_set_string (key_file, group, key, value);
+	g_free (value);
+}
+
+void
+tracker_config_save_string_list (gpointer     config,
+				 const gchar *property,
+				 GKeyFile    *key_file,
+				 const gchar *group,
+				 const gchar *key)
+{
+	GSList *list;
+	gchar **value;
+
+	g_return_if_fail (G_IS_OBJECT (config));
+	g_return_if_fail (property != NULL);
+	g_return_if_fail (key_file != NULL);
+	g_return_if_fail (group != NULL);
+	g_return_if_fail (key != NULL);
+
+	value = tracker_gslist_to_string_list (list);
+	g_key_file_set_string_list (key_file, 
+				    group, 
+				    key, 
+				    (const gchar * const *) value, 
+				    (gsize) g_slist_length (list));
+	g_strfreev (value);
+}
+
diff --git a/src/libtracker-common/tracker-config-utils.h b/src/libtracker-common/tracker-config-utils.h
new file mode 100644
index 0000000..857b55f
--- /dev/null
+++ b/src/libtracker-common/tracker-config-utils.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Nokia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ */
+
+#ifndef __TRACKER_CONFIG_UTILS_H__
+#define __TRACKER_CONFIG_UTILS_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+const gchar *tracker_config_blurb                 (gpointer      config,
+						   const gchar  *property);
+gboolean     tracker_config_default_boolean       (gpointer      config,
+						   const gchar  *property);
+gint         tracker_config_default_int           (gpointer      config,
+						   const gchar  *property);
+gboolean     tracker_config_validate_int          (gpointer      config,
+						   const gchar  *property,
+						   gint          value);
+void         tracker_config_load_int              (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+void         tracker_config_load_boolean          (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+void         tracker_config_load_string           (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+void         tracker_config_load_string_list      (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key,
+						   gboolean      is_directory_list);
+void         tracker_config_save_int              (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+void         tracker_config_save_boolean          (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+void         tracker_config_save_string           (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+void         tracker_config_save_string_list      (gpointer      config,
+						   const gchar  *property,
+						   GKeyFile     *key_file,
+						   const gchar  *group,
+						   const gchar  *key);
+
+G_END_DECLS
+
+#endif /* __TRACKER_CONFIG_UTILS_H__ */
diff --git a/src/tracker-extract/tracker-config.c b/src/tracker-extract/tracker-config.c
index 384dad4..4bc6246 100644
--- a/src/tracker-extract/tracker-config.c
+++ b/src/tracker-extract/tracker-config.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2008, Nokia (urho konttori nokia com)
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -20,77 +20,75 @@
 
 #include "config.h"
 
-#include <string.h>
-#include <stdlib.h>
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include <libtracker-common/tracker-file-utils.h>
-#include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-config-utils.h>
 
 #include "tracker-config.h"
 
 #define TRACKER_CONFIG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_CONFIG, TrackerConfigPrivate))
 
 /* GKeyFile defines */
-#define GROUP_GENERAL				 "General"
-#define KEY_VERBOSITY				 "Verbosity"
+#define GROUP_GENERAL	  "General"
 
 /* Default values */
-#define DEFAULT_VERBOSITY			 0
-
-typedef struct _TrackerConfigPrivate TrackerConfigPrivate;
-
-struct _TrackerConfigPrivate {
-	GFile	     *file;
-	GFileMonitor *monitor;
-
-	GKeyFile     *key_file;
+#define DEFAULT_VERBOSITY 0
 
+typedef struct {
 	/* General */
-	gint	      verbosity;
-};
+	gint verbosity;
+} TrackerConfigPrivate;
+
+typedef struct {
+	GType  type;
+	gchar *property;
+	gchar *group;
+	gchar *key;
+} ObjectToKeyFile;
 
-static void     config_finalize             (GObject       *object);
-static void     config_get_property         (GObject       *object,
-					     guint          param_id,
-					     GValue        *value,
-					     GParamSpec    *pspec);
 static void     config_set_property         (GObject       *object,
 					     guint          param_id,
 					     const GValue  *value,
 					     GParamSpec    *pspec);
+static void     config_get_property         (GObject       *object,
+					     guint          param_id,
+					     GValue        *value,
+					     GParamSpec    *pspec);
+static void     config_finalize             (GObject       *object);
+static void     config_constructed          (GObject       *object);
 static void     config_load                 (TrackerConfig *config);
 static gboolean config_save                 (TrackerConfig *config);
-static void     config_create_with_defaults (GKeyFile      *key_file,
+static void     config_create_with_defaults (TrackerConfig *config,
+					     GKeyFile      *key_file,
 					     gboolean       overwrite);
 
 enum {
 	PROP_0,
 
 	/* General */
-	PROP_VERBOSITY,
+	PROP_VERBOSITY
+};
+
+static ObjectToKeyFile conversions[] = {
+	{ G_TYPE_INT,     "verbosity",          GROUP_GENERAL,  "Verbosity"       },
 };
 
-G_DEFINE_TYPE (TrackerConfig, tracker_config, G_TYPE_OBJECT);
+G_DEFINE_TYPE (TrackerConfig, tracker_config, TRACKER_TYPE_CONFIG_MANAGER);
 
 static void
 tracker_config_class_init (TrackerConfigClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-	object_class->finalize	   = config_finalize;
-	object_class->get_property = config_get_property;
 	object_class->set_property = config_set_property;
+	object_class->get_property = config_get_property;
+	object_class->finalize	   = config_finalize;
+	object_class->constructed  = config_constructed;
 
 	/* General */
 	g_object_class_install_property (object_class,
 					 PROP_VERBOSITY,
 					 g_param_spec_int ("verbosity",
 							   "Log verbosity",
-							   "How much logging we have "
-							   "(0=errors, 1=minimal, 2=detailed, 3=debug)",
+							   " Log verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
 							   0,
 							   3,
 							   DEFAULT_VERBOSITY,
@@ -102,33 +100,25 @@ tracker_config_class_init (TrackerConfigClass *klass)
 static void
 tracker_config_init (TrackerConfig *object)
 {
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
-	priv->key_file = g_key_file_new ();
 }
 
 static void
-config_finalize (GObject *object)
+config_set_property (GObject	  *object,
+		     guint	   param_id,
+		     const GValue *value,
+		     GParamSpec	  *pspec)
 {
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
-	if (priv->key_file) {
-		g_key_file_free (priv->key_file);
-	}
-
-	if (priv->monitor) {
-		g_object_unref (priv->monitor);
-	}
-
-	if (priv->file) {
-		g_object_unref (priv->file);
-	}
+	switch (param_id) {
+		/* General */
+	case PROP_VERBOSITY:
+		tracker_config_set_verbosity (TRACKER_CONFIG (object),
+					      g_value_get_int (value));
+		break;
 
-	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
 }
 
 static void
@@ -154,233 +144,111 @@ config_get_property (GObject	*object,
 }
 
 static void
-config_set_property (GObject	  *object,
-		     guint	   param_id,
-		     const GValue *value,
-		     GParamSpec	  *pspec)
-{
-	switch (param_id) {
-		/* General */
-	case PROP_VERBOSITY:
-		tracker_config_set_verbosity (TRACKER_CONFIG (object),
-					      g_value_get_int (value));
-		break;
-
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-		break;
-	};
-}
-
-static gchar *
-config_dir_ensure_exists_and_return (void)
-{
-	gchar *directory;
-
-	directory = g_build_filename (g_get_user_config_dir (),
-				      "tracker",
-				      NULL);
-
-	if (!g_file_test (directory, G_FILE_TEST_EXISTS)) {
-		g_print ("Creating config directory:'%s'\n", directory);
-
-		if (g_mkdir_with_parents (directory, 0700) == -1) {
-			g_warning ("Could not create configuration directory");
-			g_free (directory);
-			return NULL;
-		}
-	}
-
-	return directory;
-}
-
-static void
-config_create_with_defaults (GKeyFile *key_file, 
-			     gboolean  overwrite)
-{
-	g_message ("Loading defaults into GKeyFile...");
-
-	/* General */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_GENERAL, KEY_VERBOSITY, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_GENERAL, KEY_VERBOSITY, 
-					DEFAULT_VERBOSITY);
-		g_key_file_set_comment (key_file, GROUP_GENERAL, KEY_VERBOSITY,
-					" Log Verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
-					NULL);
-	}
-}
-
-static gboolean
-config_save_with_defaults (const gchar *filename,
-			   GKeyFile    *key_file)
+config_finalize (GObject *object)
 {
-	GError *error = NULL;
-	gchar  *content = NULL;
-
-	/* Save to file */
-	content = g_key_file_to_data (key_file, NULL, &error);
-
-	if (error) {
-		g_warning ("Couldn't produce default configuration, %s", error->message);
-		g_clear_error (&error);
-		return FALSE;
-	}
-
-	if (!g_file_set_contents (filename, content, -1, &error)) {
-		g_warning ("Couldn't write default configuration, %s", error->message);
-		g_clear_error (&error);
-		g_free (content);
-		return FALSE;
-	}
-
-	g_print ("Writing default configuration to file:'%s'\n", filename);
-	g_free (content);
-
-	return TRUE;
-}
+	/* For now we do nothing here, we left this override in for
+	 * future expansion.
+	 */
 
-static void
-config_load_int (TrackerConfig *config,
-		 const gchar   *property,
-		 GKeyFile      *key_file,
-		 const gchar   *group,
-		 const gchar   *key)
-{
-	GError *error = NULL;
-	gint	value;
-
-	value = g_key_file_get_integer (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (int) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
+	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
 }
 
 static void
-config_save_int (TrackerConfig *config,
-		 const gchar   *property,
-		 GKeyFile      *key_file,
-		 const gchar   *group,
-		 const gchar   *key)
+config_constructed (GObject *object)
 {
-	gint value;
+	(G_OBJECT_CLASS (tracker_config_parent_class)->constructed) (object);
 
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_integer (key_file, group, key, value);
+	config_load (TRACKER_CONFIG (object));
 }
 
 static void
-config_changed_cb (GFileMonitor     *monitor,
-		   GFile	    *file,
-		   GFile	    *other_file,
-		   GFileMonitorEvent event_type,
-		   gpointer	     user_data)
+config_create_with_defaults (TrackerConfig *config,
+			     GKeyFile      *key_file, 
+			     gboolean       overwrite)
 {
-	TrackerConfig *config;
-	gchar	      *filename;
+	gint i;
 
-	config = TRACKER_CONFIG (user_data);
-
-	/* Do we recreate if the file is deleted? */
-
-	switch (event_type) {
-	case G_FILE_MONITOR_EVENT_CHANGED:
-	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
-		filename = g_file_get_path (file);
-		g_message ("Config file changed:'%s', reloading settings...",
-			   filename);
-		g_free (filename);
-
-		config_load (config);
-		break;
+	g_message ("Loading defaults into GKeyFile...");
+	
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+		
+		has_key = g_key_file_has_key (key_file, 
+					      conversions[i].group, 
+					      conversions[i].key, 
+					      NULL);
+		if (!overwrite && has_key) {
+			continue;
+		}
+		
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			g_key_file_set_integer (key_file, 
+						conversions[i].group, 
+						conversions[i].key, 
+						tracker_config_default_int (config, 
+									    conversions[i].property));
+			break;
+
+		default:
+			g_assert_not_reached ();
+		}
 
-	case G_FILE_MONITOR_EVENT_DELETED:
-	case G_FILE_MONITOR_EVENT_CREATED:
-	case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
-	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
-	case G_FILE_MONITOR_EVENT_UNMOUNTED:
-	default:
-		break;
+		g_key_file_set_comment (key_file, 
+					conversions[i].group, 
+					conversions[i].key, 
+					tracker_config_blurb (config,
+							      conversions[i].property), 
+					NULL);
 	}
 }
 
 static void
 config_load (TrackerConfig *config)
 {
-	TrackerConfigPrivate *priv;
-	GError		     *error = NULL;
-	gchar                *basename;
-	gchar		     *filename;
-	gchar		     *directory;
-
-	/* Check we have a config file and if not, create it based on
-	 * the default settings.
-	 */
-	directory = config_dir_ensure_exists_and_return ();
-	if (!directory) {
-		return;
-	}
-
-	basename = g_strdup_printf ("%s.cfg", g_get_application_name ());
-	filename = g_build_filename (directory, basename, NULL);
-	g_free (basename);
-	g_free (directory);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	/* Add file monitoring for changes */
-	if (!priv->file) {
-		priv->file = g_file_new_for_path (filename);
-	}
-
-	if (!priv->monitor) {
-		g_message ("Setting up monitor for changes to config file:'%s'",
-			   filename);
+	TrackerConfigManager *manager;
+	gint i;
 
-		priv->monitor = g_file_monitor_file (priv->file,
-						     G_FILE_MONITOR_NONE,
-						     NULL,
-						     NULL);
+	manager = TRACKER_CONFIG_MANAGER (config);
+	config_create_with_defaults (config, manager->key_file, FALSE);
 
-		g_signal_connect (priv->monitor, "changed",
-				  G_CALLBACK (config_changed_cb),
-				  config);
+	if (!manager->file_exists) {
+		tracker_config_manager_save (manager);
 	}
 
-	/* Load options */
-	g_key_file_load_from_file (priv->key_file, 
-				   filename, 
-				   G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
-				   &error);
-
-	config_create_with_defaults (priv->key_file, FALSE);
-
-	if (error) {
-		config_save_with_defaults (filename, priv->key_file);
-		g_clear_error (&error);
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+		
+		has_key = g_key_file_has_key (manager->key_file, 
+					      conversions[i].group, 
+					      conversions[i].key, 
+					      NULL);
+	
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_config_load_int (G_OBJECT (manager), 
+						 conversions[i].property,
+						 manager->key_file,
+						 conversions[i].group, 
+						 conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
 	}
-
-	g_free (filename);
-
-	/* General */
-	config_load_int (config, "verbosity", priv->key_file, GROUP_GENERAL, KEY_VERBOSITY);
 }
 
 static gboolean
 config_save (TrackerConfig *config)
 {
-	TrackerConfigPrivate *priv;
-	GError		     *error = NULL;
-	gchar		     *filename;
-	gchar		     *data;
-	gsize                 size;
+	TrackerConfigManager *manager;
+	gint i;
 
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
+	manager = TRACKER_CONFIG_MANAGER (config);
 
-	if (!priv->key_file) {
+	if (!manager->key_file) {
 		g_critical ("Could not save config, GKeyFile was NULL, has the config been loaded?");
 
 		return FALSE;
@@ -388,97 +256,31 @@ config_save (TrackerConfig *config)
 
 	g_message ("Setting details to GKeyFile object...");
 
-	/* Set properties to GKeyFile */
-	config_save_int (config, "verbosity", priv->key_file, GROUP_GENERAL, KEY_VERBOSITY);
-
-	g_message ("Saving config to disk...");
-
-	/* Do the actual saving to disk now */
-	data = g_key_file_to_data (priv->key_file, &size, &error);
-	if (error) {
-		g_warning ("Could not get config data to write to file, %s",
-			   error->message);
-		g_error_free (error);
-
-		return FALSE;
-	}
-
-	filename = g_file_get_path (priv->file);
-
-	g_file_set_contents (filename, data, size, &error);
-	g_free (data);
-
-	if (error) {
-		g_warning ("Could not write %" G_GSIZE_FORMAT " bytes to file '%s', %s",
-			   size,
-			   filename,
-			   error->message);
-		g_free (filename);
-		g_error_free (error);
-
-		return FALSE;
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_config_save_int (manager,
+						 conversions[i].property, 
+						 manager->key_file,
+						 conversions[i].group, 
+						 conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
 	}
 
-	g_message ("Wrote config to '%s' (%" G_GSIZE_FORMAT " bytes)",
-		   filename, 
-		   size);
-
-	g_free (filename);
-
-	return TRUE;
+	return tracker_config_manager_save (manager);
 }
 
-static gboolean
-config_int_validate (TrackerConfig *config,
-		     const gchar   *property,
-		     gint	    value)
-{
-#ifdef G_DISABLE_CHECKS
-	GParamSpec *spec;
-	GValue	    value = { 0 };
-	gboolean    valid;
-
-	spec = g_object_class_find_property (G_OBJECT_CLASS (config), property);
-	g_return_val_if_fail (spec != NULL, FALSE);
-
-	g_value_init (&value, spec->value_type);
-	g_value_set_int (&value, verbosity);
-	valid = g_param_value_validate (spec, &value);
-	g_value_unset (&value);
-
-	g_return_val_if_fail (valid != TRUE, FALSE);
-#endif
-
-	return TRUE;
-}
-
-/**
- * tracker_config_new:
- *
- * Creates a new GObject for handling Tracker's config file.
- *
- * Return value: A new TrackerConfig object. Must be unreferenced when
- * finished with.
- */
 TrackerConfig *
 tracker_config_new (void)
 {
-	TrackerConfig *config;
-
-	config = g_object_new (TRACKER_TYPE_CONFIG, NULL);
-	config_load (config);
-
-	return config;
+	return g_object_new (TRACKER_TYPE_CONFIG, NULL);
 }
 
-/**
- * tracker_config_save:
- * @config: a #TrackerConfig
- *
- * Writes the configuration stored in TrackerConfig to disk.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
 gboolean
 tracker_config_save (TrackerConfig *config)
 {
@@ -487,24 +289,6 @@ tracker_config_save (TrackerConfig *config)
 	return config_save (config);
 }
 
-/**
- * tracker_config_get_verbosity:
- * @config: a #TrackerConfig
- *
- * Gets the verbosity of the logging in the indexer and the daemon.
- *
- * If the verbosity is 0, there is no logging except for warnings and
- * errors.
- * If the verbosity is 1, information is displayed.
- * If the verbosity is 2, general messages are displayed.
- * If the verbosity is 3, debug messages are displayed.
- *
- * Note, you receive logging for anything less priority than the
- * verbosity level as well as the level you set. So if the verbosity
- * is 3 you receive debug, messages, info and warnings.
- *
- * Return value: An integer value from 0 to 3.
- */
 gint
 tracker_config_get_verbosity (TrackerConfig *config)
 {
@@ -525,7 +309,7 @@ tracker_config_set_verbosity (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "verbosity", value)) {
+	if (!tracker_config_validate_int (config, "verbosity", value)) {
 		return;
 	}
 
diff --git a/src/tracker-extract/tracker-config.h b/src/tracker-extract/tracker-config.h
index 157428b..0cfd20d 100644
--- a/src/tracker-extract/tracker-config.h
+++ b/src/tracker-extract/tracker-config.h
@@ -1,8 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
- * Copyright (C) 2007, Michal Pryc (Michal Pryc Sun Com)
- * Copyright (C) 2008, Nokia (urho konttori nokia com)
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -25,6 +23,8 @@
 
 #include <glib-object.h>
 
+#include <libtracker-common/tracker-config-manager.h>
+
 G_BEGIN_DECLS
 
 #define TRACKER_TYPE_CONFIG	    (tracker_config_get_type ())
@@ -34,24 +34,25 @@ G_BEGIN_DECLS
 #define TRACKER_IS_CONFIG_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_CONFIG))
 #define TRACKER_CONFIG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_CONFIG, TrackerConfigClass))
 
-typedef struct _TrackerConfig	   TrackerConfig;
-typedef struct _TrackerConfigClass TrackerConfigClass;
+typedef struct TrackerConfig	  TrackerConfig;
+typedef struct TrackerConfigClass TrackerConfigClass;
 
-struct _TrackerConfig {
-	GObject      parent;
+struct TrackerConfig {
+	TrackerConfigManager parent;
 };
 
-struct _TrackerConfigClass {
-	GObjectClass parent_class;
+struct TrackerConfigClass {
+	TrackerConfigManagerClass parent_class;
 };
 
-GType	       tracker_config_get_type            (void) G_GNUC_CONST;
+GType	       tracker_config_get_type      (void) G_GNUC_CONST;
+
+TrackerConfig *tracker_config_new           (void);
+gboolean       tracker_config_save          (TrackerConfig *config);
 
-TrackerConfig *tracker_config_new                 (void);
-gboolean       tracker_config_save                (TrackerConfig *config);
-gint           tracker_config_get_verbosity       (TrackerConfig *config);
-void           tracker_config_set_verbosity       (TrackerConfig *config,
-						   gint           value);
+gint           tracker_config_get_verbosity (TrackerConfig *config);
+void           tracker_config_set_verbosity (TrackerConfig *config,
+					     gint           value);
 
 G_END_DECLS
 
diff --git a/src/tracker-miner-fs/tracker-config.c b/src/tracker-miner-fs/tracker-config.c
index a9a3dc3..21cef9e 100644
--- a/src/tracker-miner-fs/tracker-config.c
+++ b/src/tracker-miner-fs/tracker-config.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2008, Nokia (urho konttori nokia com)
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -26,6 +26,7 @@
 #include <glib.h>
 #include <gio/gio.h>
 
+#include <libtracker-common/tracker-config-utils.h>
 #include <libtracker-common/tracker-file-utils.h>
 #include <libtracker-common/tracker-type-utils.h>
 
@@ -35,28 +36,12 @@
 
 /* GKeyFile defines */
 #define GROUP_GENERAL				 "General"
-#define KEY_VERBOSITY				 "Verbosity"
-#define KEY_INITIAL_SLEEP			 "InitialSleep"
-
 #define GROUP_MONITORS				 "Monitors"
-#define KEY_ENABLE_WATCHES		         "EnableWatches"
-#define KEY_WATCH_DIRECTORY_ROOTS		 "WatchDirectoryRoots"
-#define KEY_CRAWL_DIRECTORY_ROOTS		 "CrawlDirectory"
-#define KEY_NO_WATCH_DIRECTORY_ROOTS		 "NoWatchDirectory"
-
 #define GROUP_INDEXING				 "Indexing"
-#define KEY_THROTTLE				 "Throttle"
-#define KEY_ENABLE_THUMBNAILS			 "EnableThumbnails"
-#define KEY_DISABLED_MODULES			 "DisabledModules"
-#define KEY_DISABLE_INDEXING_ON_BATTERY		 "BatteryIndex"
-#define KEY_DISABLE_INDEXING_ON_BATTERY_INIT	 "BatteryIndexInitial"
-#define KEY_LOW_DISK_SPACE_LIMIT		 "LowDiskSpaceLimit"
-#define KEY_INDEX_MOUNTED_DIRECTORIES		 "IndexMountedDirectories"
-#define KEY_INDEX_REMOVABLE_DEVICES		 "IndexRemovableMedia"
 
 /* Default values */
 #define DEFAULT_VERBOSITY			 0
-#define DEFAULT_INITIAL_SLEEP			 45	  /* 0->1000 */
+#define DEFAULT_INITIAL_SLEEP			 15	  /* 0->1000 */
 #define DEFAULT_ENABLE_WATCHES			 TRUE
 #define DEFAULT_THROTTLE			 0	  /* 0->20 */
 #define DEFAULT_ENABLE_THUMBNAILS		 TRUE
@@ -66,48 +51,50 @@
 #define DEFAULT_INDEX_REMOVABLE_DEVICES		 TRUE
 #define DEFAULT_LOW_DISK_SPACE_LIMIT		 1	  /* 0->100 / -1 */
 
-typedef struct _TrackerConfigPrivate TrackerConfigPrivate;
-
-struct _TrackerConfigPrivate {
-	GFile	     *file;
-	GFileMonitor *monitor;
-
-	GKeyFile     *key_file;
-
+typedef struct {
 	/* General */
-	gint	      verbosity;
-	gint	      initial_sleep;
+	gint	  verbosity;
+	gint	  initial_sleep;
 
 	/* Watches */
-	GSList	     *watch_directory_roots;
-	GSList	     *crawl_directory_roots;
-	GSList	     *no_watch_directory_roots;
-	gboolean      enable_watches;
+	GSList	 *watch_directory_roots;
+	GSList	 *crawl_directory_roots;
+	GSList	 *no_watch_directory_roots;
+	gboolean  enable_watches;
 
 	/* Indexing */
-	gint	      throttle;
-	gboolean      enable_thumbnails;
-	GSList	     *disabled_modules;
-
-	gboolean      disable_indexing_on_battery;
-	gboolean      disable_indexing_on_battery_init;
-	gint	      low_disk_space_limit;
-	gboolean      index_mounted_directories;
-	gboolean      index_removable_devices;
-};
+	gint	  throttle;
+	gboolean  enable_thumbnails;
+	GSList   *disabled_modules;
+
+	gboolean  disable_indexing_on_battery;
+	gboolean  disable_indexing_on_battery_init;
+	gint	  low_disk_space_limit;
+	gboolean  index_mounted_directories;
+	gboolean  index_removable_devices;
+} TrackerConfigPrivate;
+
+typedef struct {
+	GType  type;
+	gchar *property;
+	gchar *group;
+	gchar *key;
+} ObjectToKeyFile;
 
-static void     config_finalize             (GObject       *object);
-static void     config_get_property         (GObject       *object,
-					     guint          param_id,
-					     GValue        *value,
-					     GParamSpec    *pspec);
 static void     config_set_property         (GObject       *object,
 					     guint          param_id,
 					     const GValue  *value,
 					     GParamSpec    *pspec);
+static void     config_get_property         (GObject       *object,
+					     guint          param_id,
+					     GValue        *value,
+					     GParamSpec    *pspec);
+static void     config_finalize             (GObject       *object);
+static void     config_constructed          (GObject       *object);
 static void     config_load                 (TrackerConfig *config);
 static gboolean config_save                 (TrackerConfig *config);
-static void     config_create_with_defaults (GKeyFile      *key_file,
+static void     config_create_with_defaults (TrackerConfig *config,
+					     GKeyFile      *key_file,
 					     gboolean       overwrite);
 
 enum {
@@ -118,10 +105,10 @@ enum {
 	PROP_INITIAL_SLEEP,
 
 	/* Watches */
+	PROP_ENABLE_WATCHES,
 	PROP_WATCH_DIRECTORY_ROOTS,
 	PROP_CRAWL_DIRECTORY_ROOTS,
 	PROP_NO_WATCH_DIRECTORY_ROOTS,
-	PROP_ENABLE_WATCHES,
 
 	/* Indexing */
 	PROP_THROTTLE,
@@ -134,24 +121,42 @@ enum {
 	PROP_INDEX_REMOVABLE_DEVICES,
 };
 
-G_DEFINE_TYPE (TrackerConfig, tracker_config, G_TYPE_OBJECT);
+
+static ObjectToKeyFile conversions[] = {
+	{ G_TYPE_INT,     "verbosity",                        GROUP_GENERAL,  "Verbosity"               },
+	{ G_TYPE_INT,     "initial-sleep",                    GROUP_GENERAL,  "InitialSleep"            },
+	{ G_TYPE_BOOLEAN, "enable-watches",                   GROUP_MONITORS, "EnableWatches"           },
+	{ G_TYPE_POINTER, "watch-directory-roots",            GROUP_MONITORS, "WatchDirectoryRoots"     },
+	{ G_TYPE_POINTER, "crawl-directory-roots",            GROUP_MONITORS, "CrawlDirectoryRoots"     },
+	{ G_TYPE_POINTER, "no-watch-directory-roots",         GROUP_MONITORS, "NoWatchDirectory"        },
+	{ G_TYPE_INT,     "throttle",                         GROUP_INDEXING, "Throttle"                },
+	{ G_TYPE_BOOLEAN, "enable-thumbnails",                GROUP_INDEXING, "EnableThumbnails"        },
+	{ G_TYPE_POINTER, "disabled-modules",                 GROUP_INDEXING, "DisabledModules"         },
+	{ G_TYPE_BOOLEAN, "disable-indexing-on-battery",      GROUP_INDEXING, "BatteryIndex"            },
+	{ G_TYPE_BOOLEAN, "disable-indexing-on-battery-init", GROUP_INDEXING, "BatteryIndexInitial"     },
+	{ G_TYPE_INT,     "low-disk-space-limit",             GROUP_INDEXING, "LowDiskSpaceLimit"       },
+	{ G_TYPE_BOOLEAN, "index-mounted-directories",        GROUP_INDEXING, "IndexMountedDirectories" },
+	{ G_TYPE_BOOLEAN, "index-removable-devices",          GROUP_INDEXING, "IndexRemovableMedia"     },
+};
+
+G_DEFINE_TYPE (TrackerConfig, tracker_config, TRACKER_TYPE_CONFIG_MANAGER);
 
 static void
 tracker_config_class_init (TrackerConfigClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-	object_class->finalize	   = config_finalize;
-	object_class->get_property = config_get_property;
 	object_class->set_property = config_set_property;
+	object_class->get_property = config_get_property;
+	object_class->finalize	   = config_finalize;
+	object_class->constructed  = config_constructed;
 
 	/* General */
 	g_object_class_install_property (object_class,
 					 PROP_VERBOSITY,
 					 g_param_spec_int ("verbosity",
 							   "Log verbosity",
-							   "How much logging we have "
-							   "(0=errors, 1=minimal, 2=detailed, 3=debug)",
+							   " Log verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
 							   0,
 							   3,
 							   DEFAULT_VERBOSITY,
@@ -160,42 +165,37 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_INITIAL_SLEEP,
 					 g_param_spec_int ("initial-sleep",
 							   "Initial sleep",
-							   "Initial sleep time in seconds "
-							   "(0->1000)",
+							   " Time in seconds before crawling filesystem (0->1000)",
 							   0,
 							   1000,
 							   DEFAULT_INITIAL_SLEEP,
 							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
-	/* Watches */
+	/* Monitors */
+	g_object_class_install_property (object_class,
+					 PROP_ENABLE_WATCHES,
+					 g_param_spec_boolean ("enable-watches",
+							       "Enable watches",
+							       " Set to false to completely disable any watching",
+							       DEFAULT_ENABLE_WATCHES,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_WATCH_DIRECTORY_ROOTS,
 					 g_param_spec_pointer ("watch-directory-roots",
 							       "Watched directory roots",
-							       "This is a GSList of directory roots "
-							       "to index and watch",
-							       G_PARAM_READABLE));
+							       " List of directory roots to index and watch (separator=;)",
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_CRAWL_DIRECTORY_ROOTS,
 					 g_param_spec_pointer ("crawl-directory-roots",
 							       "Crawl directory roots",
-							       "This is a GSList of directory roots "
-							       "to index but NOT watch",
-							       G_PARAM_READABLE));
+							       " List of directory roots to index but NOT watch (separator=;)",
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_NO_WATCH_DIRECTORY_ROOTS,
 					 g_param_spec_pointer ("no-watch-directory-roots",
 							       "Not watched directory roots",
-							       "This is a GSList of directory roots "
-							       "to NOT index and NOT watch",
-							       G_PARAM_READABLE));
-	g_object_class_install_property (object_class,
-					 PROP_ENABLE_WATCHES,
-					 g_param_spec_boolean ("enable-watches",
-							       "Enable watches",
-							       "You can disable all watches "
-							       "by setting this FALSE",
-							       DEFAULT_ENABLE_WATCHES,
+							       " List of directory roots NOT to index and NOT to watch (separator=;)",
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 	/* Indexing */
@@ -203,8 +203,7 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_THROTTLE,
 					 g_param_spec_int ("throttle",
 							   "Throttle",
-							   "Throttle indexing, higher value "
-							   "is slower (0->20)",
+							   " Sets the indexing speed (0->20, where 20=slowest speed)",
 							   0,
 							   20,
 							   DEFAULT_THROTTLE,
@@ -213,38 +212,37 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_ENABLE_THUMBNAILS,
 					 g_param_spec_boolean ("enable-thumbnails",
 							       "Enable thumbnails",
-							       "Create thumbnails from image based files",
+							       " Set to false to completely disable thumbnail generation",
 							       DEFAULT_ENABLE_THUMBNAILS,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_DISABLED_MODULES,
 					 g_param_spec_pointer ("disabled-modules",
 							       "Disabled modules",
-							       "Modules to disable, like 'files', etc.",
-							       G_PARAM_READABLE));
+							       " List of disabled modules (separator=;)\n"
+							       " The modules that are indexed are kept in $prefix/lib/tracker/indexer-modules",
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 ;
 	g_object_class_install_property (object_class,
 					 PROP_DISABLE_INDEXING_ON_BATTERY,
 					 g_param_spec_boolean ("disable-indexing-on-battery",
 							       "Disable indexing on battery",
-							       "Don't index when using AC battery",
+							       " Set to true to disable indexing when running on battery",
 							       DEFAULT_DISABLE_INDEXING_ON_BATTERY,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_DISABLE_INDEXING_ON_BATTERY_INIT,
 					 g_param_spec_boolean ("disable-indexing-on-battery-init",
 							       "Disable indexing on battery",
-							       "Don't index when using AC "
-							       "battery initially",
+							       " Set to true to disable initial indexing when running on battery",
 							       DEFAULT_DISABLE_INDEXING_ON_BATTERY_INIT,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_LOW_DISK_SPACE_LIMIT,
 					 g_param_spec_int ("low-disk-space-limit",
 							   "Low disk space limit",
-							   "Pause the indexer when the "
-							   "disk space is below this percentage "
-							   "(-1=off, 0->100)",
+							   " Pause indexer when disk space is <= this value\n"
+							   " (0->100, value is in % of $HOME file system, -1=disable pausing)",
 							   -1,
 							   100,
 							   DEFAULT_LOW_DISK_SPACE_LIMIT,
@@ -253,16 +251,15 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_INDEX_MOUNTED_DIRECTORIES,
 					 g_param_spec_boolean ("index-mounted-directories",
 							       "Index mounted directories",
-							       "Don't traverse mounted directories "
-							       "which are not on the same file system",
+							       " Set to true to enable traversing mounted directories on other file systems\n"
+							       " (this excludes removable devices)",
 							       DEFAULT_INDEX_MOUNTED_DIRECTORIES,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	g_object_class_install_property (object_class,
 					 PROP_INDEX_REMOVABLE_DEVICES,
 					 g_param_spec_boolean ("index-removable-devices",
 							       "index removable devices",
-							       "Don't traverse mounted directories "
-							       "which are for removable devices",
+							       " Set to true to enable traversing mounted directories for removable devices",
 							       DEFAULT_INDEX_REMOVABLE_DEVICES,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
@@ -272,104 +269,76 @@ tracker_config_class_init (TrackerConfigClass *klass)
 static void
 tracker_config_init (TrackerConfig *object)
 {
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
-	priv->key_file = g_key_file_new ();
 }
 
 static void
-config_finalize (GObject *object)
-{
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
-	g_slist_foreach (priv->watch_directory_roots, (GFunc) g_free, NULL);
-	g_slist_free (priv->watch_directory_roots);
-
-	g_slist_foreach (priv->crawl_directory_roots, (GFunc) g_free, NULL);
-	g_slist_free (priv->crawl_directory_roots);
-
-	g_slist_foreach (priv->no_watch_directory_roots, (GFunc) g_free, NULL);
-	g_slist_free (priv->no_watch_directory_roots);
-
-	g_slist_foreach (priv->disabled_modules, (GFunc) g_free, NULL);
-	g_slist_free (priv->disabled_modules);
-
-	if (priv->key_file) {
-		g_key_file_free (priv->key_file);
-	}
-
-	if (priv->monitor) {
-		g_object_unref (priv->monitor);
-	}
-
-	if (priv->file) {
-		g_object_unref (priv->file);
-	}
-
-	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
-}
-
-static void
-config_get_property (GObject	*object,
-		     guint	 param_id,
-		     GValue	*value,
-		     GParamSpec *pspec)
+config_set_property (GObject	  *object,
+		     guint	   param_id,
+		     const GValue *value,
+		     GParamSpec	  *pspec)
 {
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
 	switch (param_id) {
 		/* General */
 	case PROP_VERBOSITY:
-		g_value_set_int (value, priv->verbosity);
+		tracker_config_set_verbosity (TRACKER_CONFIG (object),
+					      g_value_get_int (value));
 		break;
 	case PROP_INITIAL_SLEEP:
-		g_value_set_int (value, priv->initial_sleep);
+		tracker_config_set_initial_sleep (TRACKER_CONFIG (object),
+						  g_value_get_int (value));
 		break;
 
 		/* Watches */
-	case PROP_WATCH_DIRECTORY_ROOTS:
-		g_value_set_pointer (value, priv->watch_directory_roots);
+	case PROP_WATCH_DIRECTORY_ROOTS:    
+		tracker_config_set_watch_directory_roots (TRACKER_CONFIG (object),
+							  g_value_get_pointer (value));
 		break;
-	case PROP_CRAWL_DIRECTORY_ROOTS:
-		g_value_set_pointer (value, priv->crawl_directory_roots);
+
+	case PROP_CRAWL_DIRECTORY_ROOTS:    
+		tracker_config_set_crawl_directory_roots (TRACKER_CONFIG (object),
+							  g_value_get_pointer (value));
 		break;
-	case PROP_NO_WATCH_DIRECTORY_ROOTS:
-		g_value_set_pointer (value, priv->no_watch_directory_roots);
+	case PROP_NO_WATCH_DIRECTORY_ROOTS: 
+		tracker_config_set_no_watch_directory_roots (TRACKER_CONFIG (object),
+							     g_value_get_pointer (value));
 		break;
 	case PROP_ENABLE_WATCHES:
-		g_value_set_boolean (value, priv->enable_watches);
+		tracker_config_set_enable_watches (TRACKER_CONFIG (object),
+						   g_value_get_boolean (value));
 		break;
 
 		/* Indexing */
 	case PROP_THROTTLE:
-		g_value_set_int (value, priv->throttle);
+		tracker_config_set_throttle (TRACKER_CONFIG (object),
+					     g_value_get_int (value));
 		break;
 	case PROP_ENABLE_THUMBNAILS:
-		g_value_set_boolean (value, priv->enable_thumbnails);
+		tracker_config_set_enable_thumbnails (TRACKER_CONFIG (object),
+						      g_value_get_boolean (value));
 		break;
 	case PROP_DISABLED_MODULES:
-		g_value_set_pointer (value, priv->disabled_modules);
+		tracker_config_set_disabled_modules (TRACKER_CONFIG (object),
+						     g_value_get_pointer (value));
 		break;
 	case PROP_DISABLE_INDEXING_ON_BATTERY:
-		g_value_set_boolean (value, priv->disable_indexing_on_battery);
+		tracker_config_set_disable_indexing_on_battery (TRACKER_CONFIG (object),
+								g_value_get_boolean (value));
 		break;
 	case PROP_DISABLE_INDEXING_ON_BATTERY_INIT:
-		g_value_set_boolean (value, priv->disable_indexing_on_battery_init);
+		tracker_config_set_disable_indexing_on_battery_init (TRACKER_CONFIG (object),
+								     g_value_get_boolean (value));
 		break;
 	case PROP_LOW_DISK_SPACE_LIMIT:
-		g_value_set_int (value, priv->low_disk_space_limit);
+		tracker_config_set_low_disk_space_limit (TRACKER_CONFIG (object),
+							 g_value_get_int (value));
 		break;
 	case PROP_INDEX_MOUNTED_DIRECTORIES:
-		g_value_set_boolean (value, priv->index_mounted_directories);
+		tracker_config_set_index_mounted_directories (TRACKER_CONFIG (object),
+							      g_value_get_boolean (value));
 		break;
 	case PROP_INDEX_REMOVABLE_DEVICES:
-		g_value_set_boolean (value, priv->index_removable_devices);
+		tracker_config_set_index_removable_devices (TRACKER_CONFIG (object),
+								g_value_get_boolean (value));
 		break;
 
 	default:
@@ -379,63 +348,62 @@ config_get_property (GObject	*object,
 }
 
 static void
-config_set_property (GObject	  *object,
-		     guint	   param_id,
-		     const GValue *value,
-		     GParamSpec	  *pspec)
+config_get_property (GObject	*object,
+		     guint	 param_id,
+		     GValue	*value,
+		     GParamSpec *pspec)
 {
+	TrackerConfigPrivate *priv;
+
+	priv = TRACKER_CONFIG_GET_PRIVATE (object);
+
 	switch (param_id) {
 		/* General */
 	case PROP_VERBOSITY:
-		tracker_config_set_verbosity (TRACKER_CONFIG (object),
-					      g_value_get_int (value));
+		g_value_set_int (value, priv->verbosity);
 		break;
 	case PROP_INITIAL_SLEEP:
-		tracker_config_set_initial_sleep (TRACKER_CONFIG (object),
-						  g_value_get_int (value));
+		g_value_set_int (value, priv->initial_sleep);
 		break;
 
 		/* Watches */
-	case PROP_WATCH_DIRECTORY_ROOTS:    /* Not writable */
-	case PROP_CRAWL_DIRECTORY_ROOTS:    /* Not writable */
-	case PROP_NO_WATCH_DIRECTORY_ROOTS: /* Not writable */
+	case PROP_WATCH_DIRECTORY_ROOTS:
+		g_value_set_pointer (value, priv->watch_directory_roots);
+		break;
+	case PROP_CRAWL_DIRECTORY_ROOTS:
+		g_value_set_pointer (value, priv->crawl_directory_roots);
+		break;
+	case PROP_NO_WATCH_DIRECTORY_ROOTS:
+		g_value_set_pointer (value, priv->no_watch_directory_roots);
 		break;
 	case PROP_ENABLE_WATCHES:
-		tracker_config_set_enable_watches (TRACKER_CONFIG (object),
-						   g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->enable_watches);
 		break;
 
 		/* Indexing */
 	case PROP_THROTTLE:
-		tracker_config_set_throttle (TRACKER_CONFIG (object),
-					     g_value_get_int (value));
+		g_value_set_int (value, priv->throttle);
 		break;
 	case PROP_ENABLE_THUMBNAILS:
-		tracker_config_set_enable_thumbnails (TRACKER_CONFIG (object),
-						      g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->enable_thumbnails);
 		break;
 	case PROP_DISABLED_MODULES:
-		/* Not writable */
+		g_value_set_pointer (value, priv->disabled_modules);
 		break;
 	case PROP_DISABLE_INDEXING_ON_BATTERY:
-		tracker_config_set_disable_indexing_on_battery (TRACKER_CONFIG (object),
-								g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->disable_indexing_on_battery);
 		break;
 	case PROP_DISABLE_INDEXING_ON_BATTERY_INIT:
-		tracker_config_set_disable_indexing_on_battery_init (TRACKER_CONFIG (object),
-								     g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->disable_indexing_on_battery_init);
 		break;
 	case PROP_LOW_DISK_SPACE_LIMIT:
-		tracker_config_set_low_disk_space_limit (TRACKER_CONFIG (object),
-							 g_value_get_int (value));
+		g_value_set_int (value, priv->low_disk_space_limit);
 		break;
 	case PROP_INDEX_MOUNTED_DIRECTORIES:
-		tracker_config_set_index_mounted_directories (TRACKER_CONFIG (object),
-							      g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->index_mounted_directories);
 		break;
 	case PROP_INDEX_REMOVABLE_DEVICES:
-		tracker_config_set_index_removable_devices (TRACKER_CONFIG (object),
-								g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->index_removable_devices);
 		break;
 
 	default:
@@ -444,588 +412,176 @@ config_set_property (GObject	  *object,
 	};
 }
 
-static gchar *
-config_dir_ensure_exists_and_return (void)
-{
-	gchar *directory;
-
-	directory = g_build_filename (g_get_user_config_dir (),
-				      "tracker",
-				      NULL);
-
-	if (!g_file_test (directory, G_FILE_TEST_EXISTS)) {
-		g_print ("Creating config directory:'%s'\n", directory);
-
-		if (g_mkdir_with_parents (directory, 0700) == -1) {
-			g_warning ("Could not create configuration directory");
-			g_free (directory);
-			return NULL;
-		}
-	}
-
-	return directory;
-}
-
 static void
-config_create_with_defaults (GKeyFile *key_file, 
-			     gboolean  overwrite)
+config_finalize (GObject *object)
 {
-	const gchar  *watch_directory_roots[2] = { NULL, NULL };
-	const gchar  *empty_string_list[] = { NULL };
-
-	/* Get default values */
-	watch_directory_roots[0] = g_get_home_dir ();
-
-	g_message ("Loading defaults into GKeyFile...");
-
-	/* General */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_GENERAL, KEY_VERBOSITY, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_GENERAL, KEY_VERBOSITY, 
-					DEFAULT_VERBOSITY);
-		g_key_file_set_comment (key_file, GROUP_GENERAL, KEY_VERBOSITY,
-					" Log Verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_GENERAL, KEY_INITIAL_SLEEP, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_GENERAL, KEY_INITIAL_SLEEP, 
-					DEFAULT_INITIAL_SLEEP);
-		g_key_file_set_comment (key_file, GROUP_GENERAL, KEY_INITIAL_SLEEP,
-					" Initial sleep time in seconds (0->1000)",
-					NULL);
-	}
-
-	/* Watches */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_MONITORS, KEY_WATCH_DIRECTORY_ROOTS, NULL)) {
-		g_key_file_set_string_list (key_file, GROUP_MONITORS, KEY_WATCH_DIRECTORY_ROOTS,
-					    watch_directory_roots, 
-					    g_strv_length ((gchar**) watch_directory_roots));
-		g_key_file_set_comment (key_file, GROUP_MONITORS, KEY_WATCH_DIRECTORY_ROOTS,
-					" List of directory roots to index and watch (separator=;)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_MONITORS, KEY_CRAWL_DIRECTORY_ROOTS, NULL)) {
-		g_key_file_set_string_list (key_file, GROUP_MONITORS, KEY_CRAWL_DIRECTORY_ROOTS,
-					    empty_string_list, 0);
-		g_key_file_set_comment (key_file, GROUP_MONITORS, KEY_CRAWL_DIRECTORY_ROOTS,
-					" List of directory roots to index but NOT watch (separator=;)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_MONITORS, KEY_NO_WATCH_DIRECTORY_ROOTS, NULL)) {
-		g_key_file_set_string_list (key_file, GROUP_MONITORS, KEY_NO_WATCH_DIRECTORY_ROOTS,
-					    empty_string_list, 0);
-		g_key_file_set_comment (key_file, GROUP_MONITORS, KEY_NO_WATCH_DIRECTORY_ROOTS,
-					" List of directory roots NOT to index and NOT to watch (separator=;)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_MONITORS, KEY_ENABLE_WATCHES, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_MONITORS, KEY_ENABLE_WATCHES, 
-					DEFAULT_ENABLE_WATCHES);
-		g_key_file_set_comment (key_file, GROUP_MONITORS, KEY_ENABLE_WATCHES,
-					" Set to false to completely disable any watching",
-					NULL);
-	}
-
-	/* Indexing */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_THROTTLE, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_INDEXING, KEY_THROTTLE, 
-					DEFAULT_THROTTLE);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_THROTTLE,
-					" Sets the indexing speed (0->20, where 20=slowest speed)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_ENABLE_THUMBNAILS, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_ENABLE_THUMBNAILS, 
-					DEFAULT_ENABLE_THUMBNAILS);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_ENABLE_THUMBNAILS,
-					" Set to false to completely disable thumbnail generation",
-					NULL);
-	}
+	TrackerConfigPrivate *priv;
 
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_DISABLED_MODULES, NULL)) {
-		g_key_file_set_string_list (key_file, GROUP_INDEXING, KEY_DISABLED_MODULES,
-					    empty_string_list, 0);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_DISABLED_MODULES,
-					" List of disabled modules (separator=;)\n"
-					" The modules that are indexed are kept in $prefix/lib/tracker/indexer-modules",
-					NULL);
-	}
+	priv = TRACKER_CONFIG_GET_PRIVATE (object);
 
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY,
-					DEFAULT_DISABLE_INDEXING_ON_BATTERY);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY,
-					" Set to true to disable indexing when running on battery",
-					NULL);
-	}
+	g_slist_foreach (priv->watch_directory_roots, (GFunc) g_free, NULL);
+	g_slist_free (priv->watch_directory_roots);
 
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY_INIT, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY_INIT,
-					DEFAULT_DISABLE_INDEXING_ON_BATTERY_INIT);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY_INIT,
-					" Set to true to disable initial indexing when running on battery",
-					NULL);
-	}
+	g_slist_foreach (priv->crawl_directory_roots, (GFunc) g_free, NULL);
+	g_slist_free (priv->crawl_directory_roots);
 
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_LOW_DISK_SPACE_LIMIT, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_INDEXING, KEY_LOW_DISK_SPACE_LIMIT, 
-					DEFAULT_LOW_DISK_SPACE_LIMIT);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_LOW_DISK_SPACE_LIMIT,
-					" Pause indexer when disk space is <= this value\n"
-					" (0->100, value is in % of $HOME file system, -1=disable pausing)",
-					NULL);
-	}
+	g_slist_foreach (priv->no_watch_directory_roots, (GFunc) g_free, NULL);
+	g_slist_free (priv->no_watch_directory_roots);
 
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_INDEX_MOUNTED_DIRECTORIES, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_INDEX_MOUNTED_DIRECTORIES,
-					DEFAULT_INDEX_MOUNTED_DIRECTORIES);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_INDEX_MOUNTED_DIRECTORIES,
-					" Set to true to enable traversing mounted directories on other file systems\n"
-					" (this excludes removable devices)",
-					NULL);
-	}
+	g_slist_foreach (priv->disabled_modules, (GFunc) g_free, NULL);
+	g_slist_free (priv->disabled_modules);
 
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_INDEX_REMOVABLE_DEVICES, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_INDEX_REMOVABLE_DEVICES, 
-					DEFAULT_INDEX_REMOVABLE_DEVICES);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_INDEX_REMOVABLE_DEVICES,
-					" Set to true to enable traversing mounted directories for removable devices",
-					NULL);
-	}
+	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
 }
 
-static gboolean
-config_save_with_defaults (const gchar *filename,
-			   GKeyFile    *key_file)
+static void
+config_constructed (GObject *object)
 {
-	GError *error = NULL;
-	gchar  *content = NULL;
-
-	/* Save to file */
-	content = g_key_file_to_data (key_file, NULL, &error);
-
-	if (error) {
-		g_warning ("Couldn't produce default configuration, %s", error->message);
-		g_clear_error (&error);
-		return FALSE;
-	}
-
-	if (!g_file_set_contents (filename, content, -1, &error)) {
-		g_warning ("Couldn't write default configuration, %s", error->message);
-		g_clear_error (&error);
-		g_free (content);
-		return FALSE;
-	}
+	(G_OBJECT_CLASS (tracker_config_parent_class)->constructed) (object);
 
-	g_print ("Writing default configuration to file:'%s'\n", filename);
-	g_free (content);
-
-	return TRUE;
+	config_load (TRACKER_CONFIG (object));
 }
 
-static GSList *
-config_string_list_to_gslist (const gchar **value,
-			      gboolean	    is_directory_list)
+static void
+config_create_with_defaults (TrackerConfig *config,
+			     GKeyFile      *key_file, 
+			     gboolean       overwrite)
 {
-	GSList *list = NULL;
-	gint	i;
-
-	if (!value) {
-		return NULL;
-	}
-
-	for (i = 0; value[i]; i++) {
-		const gchar *str;
-		gchar	    *validated;
-
-		str = value[i];
-		if (!str || str[0] == '\0') {
-			continue;
-		}
+	gint i;
 
-		if (!is_directory_list) {
-			list = g_slist_prepend (list, g_strdup (str));
+	g_message ("Loading defaults into GKeyFile...");
+	
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+		
+		has_key = g_key_file_has_key (key_file, 
+					      conversions[i].group, 
+					      conversions[i].key, 
+					      NULL);
+		if (!overwrite && has_key) {
 			continue;
 		}
-
-		/* For directories we validate any special characters,
-		 * for example '~' and '../../'
-		 */
-		validated = tracker_path_evaluate_name (str);
-		if (validated) {
-			list = g_slist_prepend (list, validated);
+		
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			g_key_file_set_integer (key_file, 
+						conversions[i].group, 
+						conversions[i].key, 
+						tracker_config_default_int (config, 
+									    conversions[i].property));
+			break;
+
+		case G_TYPE_BOOLEAN:
+			g_key_file_set_boolean (key_file, 
+						conversions[i].group, 
+						conversions[i].key, 
+						tracker_config_default_boolean (config, 
+										conversions[i].property));
+			break;
+
+		case G_TYPE_POINTER:
+			/* Special case string lists */
+			if (g_strcmp0 (conversions[i].property, "watch-directory-roots") == 0) {
+				const gchar *string_list[] = { NULL, NULL };
+
+				string_list[0] = g_get_home_dir ();
+
+				g_key_file_set_string_list (key_file, 
+							    conversions[i].group, 
+							    conversions[i].key, 
+							    string_list, 
+							    G_N_ELEMENTS (string_list));
+			} else {
+				const gchar *string_list[] = { NULL };
+
+				g_key_file_set_string_list (key_file, 
+							    conversions[i].group, 
+							    conversions[i].key, 
+							    string_list, 
+							    G_N_ELEMENTS (string_list));
+			}
+
+			break;
+
+		default:
+			g_assert_not_reached ();
 		}
-	}
-
-	return g_slist_reverse (list);
-}
-
-static void
-config_load_int (TrackerConfig *config,
-		 const gchar   *property,
-		 GKeyFile      *key_file,
-		 const gchar   *group,
-		 const gchar   *key)
-{
-	GError *error = NULL;
-	gint	value;
-
-	value = g_key_file_get_integer (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (int) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
-}
-
-static void
-config_load_boolean (TrackerConfig *config,
-		     const gchar   *property,
-		     GKeyFile	   *key_file,
-		     const gchar   *group,
-		     const gchar   *key)
-{
-	GError	 *error = NULL;
-	gboolean  value;
 
-	value = g_key_file_get_boolean (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (bool) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
-}
-
-#if 0
-
-static void
-config_load_string (TrackerConfig *config,
-		    const gchar	  *property,
-		    GKeyFile	  *key_file,
-		    const gchar	  *group,
-		    const gchar	  *key)
-{
-	GError *error = NULL;
-	gchar  *value;
-
-	value = g_key_file_get_string (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (string) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
-
-	g_free (value);
-}
-
-#endif
-
-static void
-config_load_string_list (TrackerConfig *config,
-			 const gchar   *property,
-			 GKeyFile      *key_file,
-			 const gchar   *group,
-			 const gchar   *key)
-{
-	TrackerConfigPrivate  *priv;
-	GSList		      *l;
-	gchar		     **value;
-	gboolean               is_directory_list = TRUE;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	if (strcmp (property, "disabled-modules") == 0) {
-		is_directory_list = FALSE;
-	}
-
-	value = g_key_file_get_string_list (key_file, group, key, NULL, NULL);
-	l = config_string_list_to_gslist ((const gchar **) value, is_directory_list);
-
-	if (strcmp (property, "watch-directory-roots") == 0) {
-		priv->watch_directory_roots = tracker_path_list_filter_duplicates (l, "."); 
-	}
-	else if (strcmp (property, "crawl-directory-roots") == 0) {
-		priv->crawl_directory_roots = tracker_path_list_filter_duplicates (l, ".");
-	}
-	else if (strcmp (property, "no-watch-directory-roots") == 0) {
-		priv->no_watch_directory_roots = tracker_path_list_filter_duplicates (l, ".");
-	}
-	else if (strcmp (property, "disabled-modules") == 0) {
-		priv->disabled_modules = l;
-	}
-	else {
-		g_warning ("Property '%s' not recognized to set string list from key '%s'",
-			   property, key);
-		return;
-	}
-
-	if (is_directory_list) {
-		g_slist_foreach (l, (GFunc) g_free, NULL);
-		g_slist_free (l);
-	}
-
-	g_strfreev (value);
-}
-
-static void
-config_save_int (TrackerConfig *config,
-		 const gchar   *property,
-		 GKeyFile      *key_file,
-		 const gchar   *group,
-		 const gchar   *key)
-{
-	gint value;
-
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_integer (key_file, group, key, value);
-}
-
-static void
-config_save_boolean (TrackerConfig *config,
-		     const gchar   *property,
-		     GKeyFile	   *key_file,
-		     const gchar   *group,
-		     const gchar   *key)
-{
-	gboolean value;
-
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_boolean (key_file, group, key, value);
-}
-
-#if 0
-
-static void
-config_save_string (TrackerConfig *config,
-		    const gchar	  *property,
-		    GKeyFile	  *key_file,
-		    const gchar	  *group,
-		    const gchar	  *key)
-{
-	gchar *value;
-
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_string (key_file, group, key, value);
-	g_free (value);
-}
-
-#endif 
-
-static void
-config_save_string_list (TrackerConfig *config,
-			 const gchar   *property,
-			 GKeyFile      *key_file,
-			 const gchar   *group,
-			 const gchar   *key)
-{
-	TrackerConfigPrivate  *priv;
-	GSList		      *list;
-	gchar		     **value;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	if (strcmp (property, "watch-directory-roots") == 0) {
-		list = priv->watch_directory_roots;
-	}
-	else if (strcmp (property, "crawl-directory-roots") == 0) {
-		list = priv->crawl_directory_roots;
-	}
-	else if (strcmp (property, "no-watch-directory-roots") == 0) {
-		list = priv->no_watch_directory_roots;
-	}
-	else if (strcmp (property, "disabled-modules") == 0) {
-		list = priv->disabled_modules;
-	}
-	else {
-		g_warning ("Property '%s' not recognized to set string list from key '%s'",
-			   property, key);
-		return;
-	}
-
-	value = tracker_gslist_to_string_list (list);
-	g_key_file_set_string_list (key_file, 
-				    group, 
-				    key, 
-				    (const gchar * const *) value, 
-				    (gsize) g_slist_length (list));
-	g_strfreev (value);
-}
-
-static void
-config_changed_cb (GFileMonitor     *monitor,
-		   GFile	    *file,
-		   GFile	    *other_file,
-		   GFileMonitorEvent event_type,
-		   gpointer	     user_data)
-{
-	TrackerConfig *config;
-	gchar	      *filename;
-
-	config = TRACKER_CONFIG (user_data);
-
-	/* Do we recreate if the file is deleted? */
-
-	switch (event_type) {
-	case G_FILE_MONITOR_EVENT_CHANGED:
-	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
-		filename = g_file_get_path (file);
-		g_message ("Config file changed:'%s', reloading settings...",
-			   filename);
-		g_free (filename);
-
-		config_load (config);
-		break;
-
-	case G_FILE_MONITOR_EVENT_DELETED:
-	case G_FILE_MONITOR_EVENT_CREATED:
-	case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
-	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
-	case G_FILE_MONITOR_EVENT_UNMOUNTED:
-	default:
-		break;
+		g_key_file_set_comment (key_file, 
+					conversions[i].group, 
+					conversions[i].key, 
+					tracker_config_blurb (config,
+							      conversions[i].property), 
+					NULL);
 	}
 }
 
 static void
 config_load (TrackerConfig *config)
 {
-	TrackerConfigPrivate *priv;
-	GError		     *error = NULL;
-	gchar                *basename;
-	gchar		     *filename;
-	gchar		     *directory;
-	gboolean	      value;
-
-	/* Check we have a config file and if not, create it based on
-	 * the default settings.
-	 */
-	directory = config_dir_ensure_exists_and_return ();
-	if (!directory) {
-		return;
-	}
-
-	basename = g_strdup_printf ("%s.cfg", g_get_application_name ());
-	filename = g_build_filename (directory, basename, NULL);
-	g_free (basename);
-	g_free (directory);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	/* Add file monitoring for changes */
-	if (!priv->file) {
-		priv->file = g_file_new_for_path (filename);
-	}
-
-	if (!priv->monitor) {
-		g_message ("Setting up monitor for changes to config file:'%s'",
-			   filename);
-
-		priv->monitor = g_file_monitor_file (priv->file,
-						     G_FILE_MONITOR_NONE,
-						     NULL,
-						     NULL);
+	TrackerConfigManager *manager;
+	gint i;
 
-		g_signal_connect (priv->monitor, "changed",
-				  G_CALLBACK (config_changed_cb),
-				  config);
-	}
-
-	/* Load options */
-	g_key_file_load_from_file (priv->key_file, 
-				   filename, 
-				   G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
-				   &error);
-
-	config_create_with_defaults (priv->key_file, FALSE);
+	manager = TRACKER_CONFIG_MANAGER (config);
+	config_create_with_defaults (config, manager->key_file, FALSE);
 
-	if (error) {
-		config_save_with_defaults (filename, priv->key_file);
-		g_clear_error (&error);
+	if (!manager->file_exists) {
+		tracker_config_manager_save (manager);
 	}
 
-	g_free (filename);
-
-	/* General */
-	config_load_int (config, "verbosity", priv->key_file, GROUP_GENERAL, KEY_VERBOSITY);
-	config_load_int (config, "initial-sleep", priv->key_file, GROUP_GENERAL, KEY_INITIAL_SLEEP);
-
-	/* Watches */
-	config_load_string_list (config, "watch-directory-roots", priv->key_file, GROUP_MONITORS, KEY_WATCH_DIRECTORY_ROOTS);
-	config_load_string_list (config, "crawl-directory-roots", priv->key_file, GROUP_MONITORS, KEY_CRAWL_DIRECTORY_ROOTS);
-	config_load_string_list (config, "no-watch-directory-roots", priv->key_file, GROUP_MONITORS, KEY_NO_WATCH_DIRECTORY_ROOTS);
-	config_load_boolean (config, "enable-watches", priv->key_file, GROUP_MONITORS, KEY_ENABLE_WATCHES);
-
-	/* Indexing */
-	config_load_int (config, "throttle", priv->key_file, GROUP_INDEXING, KEY_THROTTLE);
-	config_load_boolean (config, "enable-thumbnails", priv->key_file, GROUP_INDEXING, KEY_ENABLE_THUMBNAILS);
-	config_load_string_list (config, "disabled-modules", priv->key_file, GROUP_INDEXING, KEY_DISABLED_MODULES);
-	config_load_boolean (config, "disable-indexing-on-battery", priv->key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY);
-	config_load_boolean (config, "disable-indexing-on-battery-init", priv->key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY_INIT);
-	config_load_int (config, "low-disk-space-limit", priv->key_file, GROUP_INDEXING, KEY_LOW_DISK_SPACE_LIMIT);
-	config_load_boolean (config, "index-mounted-directories", priv->key_file, GROUP_INDEXING, KEY_INDEX_MOUNTED_DIRECTORIES);
-	config_load_boolean (config, "index-removable-devices", priv->key_file, GROUP_INDEXING, KEY_INDEX_REMOVABLE_DEVICES);
-
-	/*
-	 * Legacy options no longer supported:
-	 */
-	value = g_key_file_get_boolean (priv->key_file, "Emails", "IndexEvolutionEmails", &error);
-	if (!error) {
-		const gchar * const modules[2] = { "evolution", NULL };
-
-		g_message ("Legacy config option 'IndexEvolutionEmails' found");
-		g_message ("  This option has been replaced by 'DisabledModules'");
-
-		if (!value) {
-			tracker_config_add_disabled_modules (config, modules);
-			g_message ("  Option 'DisabledModules' added '%s'", modules[0]);
-		} else {
-			tracker_config_remove_disabled_modules (config, modules[0]);
-			g_message ("  Option 'DisabledModules' removed '%s'", modules[0]);
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+		gboolean is_directory_list;
+		
+		has_key = g_key_file_has_key (manager->key_file, 
+					      conversions[i].group, 
+					      conversions[i].key, 
+					      NULL);
+	
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_config_load_int (G_OBJECT (manager), 
+						 conversions[i].property,
+						 manager->key_file,
+						 conversions[i].group, 
+						 conversions[i].key);
+			break;
+
+		case G_TYPE_BOOLEAN:
+			tracker_config_load_boolean (G_OBJECT (manager), 
+						     conversions[i].property,
+						     manager->key_file,
+						     conversions[i].group, 
+						     conversions[i].key);
+			break;
+
+		case G_TYPE_POINTER:
+			if (g_strcmp0 (conversions[i].property, "disabled-modules") == 0) {
+				is_directory_list = FALSE;
+			} else {
+				is_directory_list = TRUE;
+			}
+
+			tracker_config_load_string_list (G_OBJECT (manager), 
+							 conversions[i].property,
+							 manager->key_file, 
+							 conversions[i].group, 
+							 conversions[i].key,
+							 is_directory_list);
+			break;
 		}
-	} else {
-		g_clear_error (&error);
-	}
-
-	value = g_key_file_get_boolean (priv->key_file, "Emails", "IndexThunderbirdEmails", &error);
-	if (!error) {
-		g_message ("Legacy config option 'IndexThunderbirdEmails' found");
-		g_message ("  This option is no longer supported and has no effect");
-	} else {
-		g_clear_error (&error);
-	}
-
-	value = g_key_file_get_boolean (priv->key_file, "Indexing", "SkipMountPoints", &error);
-	if (!error) {
-		g_message ("Legacy config option 'SkipMountPoints' found");
-		tracker_config_set_index_mounted_directories (config, !value);
-		g_message ("  Option 'IndexMountedDirectories' set to %s", !value ? "true" : "false");
-	} else {
-		g_clear_error (&error);
 	}
 }
 
 static gboolean
 config_save (TrackerConfig *config)
 {
-	TrackerConfigPrivate *priv;
-	GError		     *error = NULL;
-	gchar		     *filename;
-	gchar		     *data;
-	gsize                 size;
+	TrackerConfigManager *manager;
+	gint i;
 
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
+	manager = TRACKER_CONFIG_MANAGER (config);
 
-	if (!priv->key_file) {
+	if (!manager->key_file) {
 		g_critical ("Could not save config, GKeyFile was NULL, has the config been loaded?");
 
 		return FALSE;
@@ -1033,114 +589,47 @@ config_save (TrackerConfig *config)
 
 	g_message ("Setting details to GKeyFile object...");
 
-	/* Set properties to GKeyFile */
-	config_save_int (config, "verbosity", priv->key_file, GROUP_GENERAL, KEY_VERBOSITY);
-	config_save_int (config, "initial-sleep", priv->key_file, GROUP_GENERAL, KEY_INITIAL_SLEEP);
-
-	/* Watches */
-	config_save_string_list (config, "watch-directory-roots", priv->key_file, GROUP_MONITORS, KEY_WATCH_DIRECTORY_ROOTS);
-	config_save_string_list (config, "crawl-directory-roots", priv->key_file, GROUP_MONITORS, KEY_CRAWL_DIRECTORY_ROOTS);
-	config_save_string_list (config, "no-watch-directory-roots", priv->key_file, GROUP_MONITORS, KEY_NO_WATCH_DIRECTORY_ROOTS);
-	config_save_boolean (config, "enable-watches", priv->key_file, GROUP_MONITORS, KEY_ENABLE_WATCHES);
-
-	/* Indexing */
-	config_save_int (config, "throttle", priv->key_file, GROUP_INDEXING, KEY_THROTTLE);
-	config_save_boolean (config, "enable-thumbnails", priv->key_file, GROUP_INDEXING, KEY_ENABLE_THUMBNAILS);
-	config_save_string_list (config, "disabled-modules", priv->key_file, GROUP_INDEXING, KEY_DISABLED_MODULES);
-	config_save_boolean (config, "disable-indexing-on-battery", priv->key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY);
-	config_save_boolean (config, "disable-indexing-on-battery-init", priv->key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY_INIT);
-	config_save_int (config, "low-disk-space-limit", priv->key_file, GROUP_INDEXING, KEY_LOW_DISK_SPACE_LIMIT);
-	config_save_boolean (config, "index-mounted-directories", priv->key_file, GROUP_INDEXING, KEY_INDEX_MOUNTED_DIRECTORIES);
-	config_save_boolean (config, "index-removable-devices", priv->key_file, GROUP_INDEXING, KEY_INDEX_REMOVABLE_DEVICES);
-
-	g_message ("Saving config to disk...");
-
-	/* Do the actual saving to disk now */
-	data = g_key_file_to_data (priv->key_file, &size, &error);
-	if (error) {
-		g_warning ("Could not get config data to write to file, %s",
-			   error->message);
-		g_error_free (error);
-
-		return FALSE;
-	}
-
-	filename = g_file_get_path (priv->file);
-
-	g_file_set_contents (filename, data, size, &error);
-	g_free (data);
-
-	if (error) {
-		g_warning ("Could not write %" G_GSIZE_FORMAT " bytes to file '%s', %s",
-			   size,
-			   filename,
-			   error->message);
-		g_free (filename);
-		g_error_free (error);
-
-		return FALSE;
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_config_save_int (manager,
+						 conversions[i].property, 
+						 manager->key_file,
+						 conversions[i].group, 
+						 conversions[i].key);
+			break;
+
+		case G_TYPE_BOOLEAN:
+			tracker_config_save_boolean (manager,
+						     conversions[i].property, 
+						     manager->key_file,
+						     conversions[i].group, 
+						     conversions[i].key);
+			break;
+
+		case G_TYPE_POINTER:
+			tracker_config_save_string_list (manager,
+							 conversions[i].property, 
+							 manager->key_file,
+							 conversions[i].group, 
+							 conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
 	}
 
-	g_message ("Wrote config to '%s' (%" G_GSIZE_FORMAT " bytes)",
-		   filename, 
-		   size);
-
-	g_free (filename);
-
-	return TRUE;
+	return tracker_config_manager_save (manager);
 }
 
-static gboolean
-config_int_validate (TrackerConfig *config,
-		     const gchar   *property,
-		     gint	    value)
-{
-#ifdef G_DISABLE_CHECKS
-	GParamSpec *spec;
-	GValue	    value = { 0 };
-	gboolean    valid;
-
-	spec = g_object_class_find_property (G_OBJECT_CLASS (config), property);
-	g_return_val_if_fail (spec != NULL, FALSE);
-
-	g_value_init (&value, spec->value_type);
-	g_value_set_int (&value, verbosity);
-	valid = g_param_value_validate (spec, &value);
-	g_value_unset (&value);
-
-	g_return_val_if_fail (valid != TRUE, FALSE);
-#endif
-
-	return TRUE;
-}
-
-/**
- * tracker_config_new:
- *
- * Creates a new GObject for handling Tracker's config file.
- *
- * Return value: A new TrackerConfig object. Must be unreferenced when
- * finished with.
- */
 TrackerConfig *
 tracker_config_new (void)
 {
-	TrackerConfig *config;
-
-	config = g_object_new (TRACKER_TYPE_CONFIG, NULL);
-	config_load (config);
-
-	return config;
+	return g_object_new (TRACKER_TYPE_CONFIG, NULL);
 }
 
-/**
- * tracker_config_save:
- * @config: a #TrackerConfig
- *
- * Writes the configuration stored in TrackerConfig to disk.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
 gboolean
 tracker_config_save (TrackerConfig *config)
 {
@@ -1149,24 +638,6 @@ tracker_config_save (TrackerConfig *config)
 	return config_save (config);
 }
 
-/**
- * tracker_config_get_verbosity:
- * @config: a #TrackerConfig
- *
- * Gets the verbosity of the logging in the indexer and the daemon.
- *
- * If the verbosity is 0, there is no logging except for warnings and
- * errors.
- * If the verbosity is 1, information is displayed.
- * If the verbosity is 2, general messages are displayed.
- * If the verbosity is 3, debug messages are displayed.
- *
- * Note, you receive logging for anything less priority than the
- * verbosity level as well as the level you set. So if the verbosity
- * is 3 you receive debug, messages, info and warnings.
- *
- * Return value: An integer value from 0 to 3.
- */
 gint
 tracker_config_get_verbosity (TrackerConfig *config)
 {
@@ -1343,7 +814,7 @@ tracker_config_set_verbosity (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "verbosity", value)) {
+	if (!tracker_config_validate_int (config, "verbosity", value)) {
 		return;
 	}
 
@@ -1361,7 +832,7 @@ tracker_config_set_initial_sleep (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "initial-sleep", value)) {
+	if (!tracker_config_validate_int (config, "initial-sleep", value)) {
 		return;
 	}
 
@@ -1393,7 +864,7 @@ tracker_config_set_throttle (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "throttle", value)) {
+	if (!tracker_config_validate_int (config, "throttle", value)) {
 		return;
 	}
 
@@ -1453,7 +924,7 @@ tracker_config_set_low_disk_space_limit (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "low-disk-space-limit", value)) {
+	if (!tracker_config_validate_int (config, "low-disk-space-limit", value)) {
 		return;
 	}
 
@@ -1491,237 +962,6 @@ tracker_config_set_index_removable_devices (TrackerConfig *config,
 	g_object_notify (G_OBJECT (config), "index-removable-devices");
 }
 
-void
-tracker_config_add_watch_directory_roots (TrackerConfig *config,
-					  gchar * const *roots)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-	gchar		     *validated_root;
-	gchar * const	     *p;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (roots != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	for (p = roots; *p; p++) {
-		validated_root = tracker_path_evaluate_name (*p);
-		if (!validated_root) {
-			g_print ("Root '%s' is not valid to add to watch directory list\n",
-				 validated_root);
-			continue;
-		}
-
-		priv->watch_directory_roots = g_slist_append (priv->watch_directory_roots,
-							      validated_root);
-	}
-
-	l = priv->watch_directory_roots;
-	priv->watch_directory_roots =
-		tracker_path_list_filter_duplicates (priv->watch_directory_roots, ".");
-
-	g_slist_foreach (l, (GFunc) g_free, NULL);
-	g_slist_free (l);
-
-	g_object_notify (G_OBJECT (config), "watch-directory-roots");
-}
-
-void
-tracker_config_add_crawl_directory_roots (TrackerConfig *config,
-					  gchar * const *roots)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-	gchar		     *validated_root;
-	gchar * const	     *p;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (roots != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	for (p = roots; *p; p++) {
-		validated_root = tracker_path_evaluate_name (*p);
-		if (!validated_root) {
-			g_print ("Root '%s' is not valid to add to crawl directory list\n",
-				 validated_root);
-			continue;
-		}
-
-		priv->crawl_directory_roots = g_slist_append (priv->crawl_directory_roots,
-							      validated_root);
-	}
-
-	l = priv->crawl_directory_roots;
-	priv->crawl_directory_roots =
-		tracker_path_list_filter_duplicates (priv->crawl_directory_roots, ".");
-
-	g_slist_foreach (l, (GFunc) g_free, NULL);
-	g_slist_free (l);
-
-	g_object_notify (G_OBJECT (config), "crawl-directory-roots");
-}
-
-void
-tracker_config_add_no_watch_directory_roots (TrackerConfig *config,
-					     gchar * const *roots)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-	gchar		     *validated_root;
-	gchar * const	     *p;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (roots != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	for (p = roots; *p; p++) {
-		validated_root = tracker_path_evaluate_name (*p);
-		if (!validated_root) {
-			g_print ("Root '%s' is not valid to add to no_watch directory list\n",
-				 validated_root);
-			continue;
-		}
-
-		priv->no_watch_directory_roots = g_slist_append (priv->no_watch_directory_roots,
-								 validated_root);
-	}
-
-	l = priv->no_watch_directory_roots;
-	priv->no_watch_directory_roots =
-		tracker_path_list_filter_duplicates (priv->no_watch_directory_roots, ".");
-
-	g_slist_foreach (l, (GFunc) g_free, NULL);
-	g_slist_free (l);
-
-	g_object_notify (G_OBJECT (config), "no-watch-directory-roots");
-}
-
-void
-tracker_config_add_disabled_modules (TrackerConfig *config,
-				     const gchar * const *modules)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *new_modules;
-	const gchar * const  *p;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (modules != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	new_modules = NULL;
-
-	for (p = modules; *p; p++) {
-		if (g_slist_find_custom (priv->disabled_modules,
-					 *p,
-					 (GCompareFunc) strcmp)) {
-			continue;
-		}
-
-		new_modules = g_slist_append (new_modules, g_strdup (*p));
-	}
-
-	priv->disabled_modules = g_slist_concat (priv->disabled_modules,
-						 new_modules);
-
-	g_object_notify (G_OBJECT (config), "disabled-modules");
-}
-
-void
-tracker_config_remove_watch_directory_roots (TrackerConfig *config,
-					     const gchar   *root)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (root != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	l = g_slist_find_custom (priv->watch_directory_roots,
-				 root,
-				 (GCompareFunc) strcmp);
-
-	if (l) {
-		g_free (l->data);
-		priv->watch_directory_roots = g_slist_delete_link (priv->watch_directory_roots, l);
-		g_object_notify (G_OBJECT (config), "watch-directory-roots");
-	}
-}
-
-void
-tracker_config_remove_crawl_directory_roots (TrackerConfig *config,
-					     const gchar   *root)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (root != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	l = g_slist_find_custom (priv->crawl_directory_roots,
-				 root,
-				 (GCompareFunc) strcmp);
-
-	if (l) {
-		g_free (l->data);
-		priv->crawl_directory_roots = g_slist_delete_link (priv->crawl_directory_roots, l);
-		g_object_notify (G_OBJECT (config), "crawl-directory-roots");
-	}
-}
-
-void
-tracker_config_remove_no_watch_directory_roots (TrackerConfig *config,
-						const gchar   *root)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (root != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	l = g_slist_find_custom (priv->no_watch_directory_roots,
-				 root,
-				 (GCompareFunc) strcmp);
-
-	if (l) {
-		g_free (l->data);
-		priv->no_watch_directory_roots = g_slist_delete_link (priv->no_watch_directory_roots, l);
-		g_object_notify (G_OBJECT (config), "no-watch-directory-roots");
-	}
-}
-
-void
-tracker_config_remove_disabled_modules (TrackerConfig *config,
-					const gchar   *module)
-{
-	TrackerConfigPrivate *priv;
-	GSList		     *l;
-
-	g_return_if_fail (TRACKER_IS_CONFIG (config));
-	g_return_if_fail (module != NULL);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
-
-	l = g_slist_find_custom (priv->disabled_modules,
-				 module,
-				 (GCompareFunc) strcmp);
-
-	if (l) {
-		g_free (l->data);
-		priv->disabled_modules = g_slist_delete_link (priv->disabled_modules, l);
-		g_object_notify (G_OBJECT (config), "disabled-modules");
-	}
-}
-
 void	       
 tracker_config_set_watch_directory_roots (TrackerConfig *config,
 					  GSList        *roots)
diff --git a/src/tracker-miner-fs/tracker-config.h b/src/tracker-miner-fs/tracker-config.h
index d040635..0390ac4 100644
--- a/src/tracker-miner-fs/tracker-config.h
+++ b/src/tracker-miner-fs/tracker-config.h
@@ -1,8 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
- * Copyright (C) 2007, Michal Pryc (Michal Pryc Sun Com)
- * Copyright (C) 2008, Nokia (urho konttori nokia com)
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -25,6 +23,8 @@
 
 #include <glib-object.h>
 
+#include <libtracker-common/tracker-config-manager.h>
+
 G_BEGIN_DECLS
 
 #define TRACKER_TYPE_CONFIG	    (tracker_config_get_type ())
@@ -34,15 +34,15 @@ G_BEGIN_DECLS
 #define TRACKER_IS_CONFIG_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_CONFIG))
 #define TRACKER_CONFIG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_CONFIG, TrackerConfigClass))
 
-typedef struct _TrackerConfig	   TrackerConfig;
-typedef struct _TrackerConfigClass TrackerConfigClass;
+typedef struct TrackerConfig	  TrackerConfig;
+typedef struct TrackerConfigClass TrackerConfigClass;
 
-struct _TrackerConfig {
-	GObject      parent;
+struct TrackerConfig {
+	TrackerConfigManager parent;
 };
 
-struct _TrackerConfigClass {
-	GObjectClass parent_class;
+struct TrackerConfigClass {
+	TrackerConfigManagerClass parent_class;
 };
 
 GType	       tracker_config_get_type				   (void) G_GNUC_CONST;
diff --git a/src/tracker-store/tracker-config.c b/src/tracker-store/tracker-config.c
index fc96f4f..ee77c12 100644
--- a/src/tracker-store/tracker-config.c
+++ b/src/tracker-store/tracker-config.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2008, Nokia (urho konttori nokia com)
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -26,65 +26,57 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-#include <libtracker-common/tracker-file-utils.h>
-#include <libtracker-common/tracker-type-utils.h>
+#include <libtracker-common/tracker-config-utils.h>
 
 #include "tracker-config.h"
 
 #define TRACKER_CONFIG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_CONFIG, TrackerConfigPrivate))
 
 /* GKeyFile defines */
-#define GROUP_GENERAL				 "General"
-#define KEY_VERBOSITY				 "Verbosity"
-#define KEY_LOW_MEMORY_MODE			 "LowMemoryMode"
-
-#define GROUP_INDEXING				 "Indexing"
-#define KEY_MIN_WORD_LENGTH			 "MinWordLength"
-#define KEY_MAX_WORD_LENGTH			 "MaxWordLength"
-
-#define GROUP_PERFORMANCE			 "Performance"
-#define KEY_MAX_WORDS_TO_INDEX			 "MaxWordsToIndex"
+#define GROUP_GENERAL		    "General"
+#define GROUP_INDEXING		    "Indexing"
 
 /* Default values */
-#define DEFAULT_VERBOSITY			 0
-#define DEFAULT_LOW_MEMORY_MODE			 FALSE
-#define DEFAULT_MIN_WORD_LENGTH			 3	  /* 0->30 */
-#define DEFAULT_MAX_WORD_LENGTH			 30	  /* 0->200 */
-#define DEFAULT_MAX_WORDS_TO_INDEX		 10000
-
-typedef struct _TrackerConfigPrivate TrackerConfigPrivate;
-
-struct _TrackerConfigPrivate {
-	GFile	     *file;
-	GFileMonitor *monitor;
+#define DEFAULT_VERBOSITY	    2
+#define DEFAULT_LOW_MEMORY_MODE	    FALSE
+#define DEFAULT_MIN_WORD_LENGTH	    3	  /* 0->30 */
+#define DEFAULT_MAX_WORD_LENGTH	    30	  /* 0->200 */
+#define DEFAULT_MAX_WORDS_TO_INDEX  10000
 
-	GKeyFile     *key_file;
+/* typedef struct TrackerConfigPrivate TrackerConfigPrivate; */
 
+typedef struct {
 	/* General */
-	gint	      verbosity;
-	gboolean      low_memory_mode;
+	gint     verbosity;
+	gboolean low_memory_mode;
 
 	/* Indexing */
-	gint	      min_word_length;
-	gint	      max_word_length;
-
-	/* Performance */
-	gint	      max_words_to_index;
-};
-
-static void     config_finalize             (GObject       *object);
-static void     config_get_property         (GObject       *object,
-					     guint          param_id,
-					     GValue        *value,
-					     GParamSpec    *pspec);
-static void     config_set_property         (GObject       *object,
-					     guint          param_id,
-					     const GValue  *value,
-					     GParamSpec    *pspec);
-static void     config_load                 (TrackerConfig *config);
-static gboolean config_save                 (TrackerConfig *config);
-static void     config_create_with_defaults (GKeyFile      *key_file,
-					     gboolean       overwrite);
+	gint     min_word_length;
+	gint     max_word_length;
+	gint     max_words_to_index;
+}  TrackerConfigPrivate;
+
+typedef struct {
+	GType  type;
+	gchar *property;
+	gchar *group;
+	gchar *key;
+} ObjectToKeyFile;
+
+static void config_set_property         (GObject       *object,
+					 guint          param_id,
+					 const GValue  *value,
+					 GParamSpec    *pspec);
+static void config_get_property         (GObject       *object,
+					 guint          param_id,
+					 GValue        *value,
+					 GParamSpec    *pspec);
+static void config_finalize             (GObject       *object);
+static void config_constructed          (GObject       *object);
+static void config_create_with_defaults (TrackerConfig *config,
+					 GKeyFile      *key_file, 
+					 gboolean       overwrite);
+static void config_load                 (TrackerConfig *config);
 
 enum {
 	PROP_0,
@@ -101,24 +93,32 @@ enum {
 	PROP_MAX_WORDS_TO_INDEX,
 };
 
-G_DEFINE_TYPE (TrackerConfig, tracker_config, G_TYPE_OBJECT);
+static ObjectToKeyFile conversions[] = {
+	{ G_TYPE_INT,     "verbosity",          GROUP_GENERAL,  "Verbosity"       },
+	{ G_TYPE_BOOLEAN, "low-memory-mode",    GROUP_GENERAL,  "LowMemoryMode"   },
+	{ G_TYPE_INT,     "min-word-length",    GROUP_INDEXING, "MinWordLength"   },
+	{ G_TYPE_INT,     "max-word-length",    GROUP_INDEXING, "MaxWordLength"   },
+	{ G_TYPE_INT,     "max-words-to-index", GROUP_INDEXING, "MaxWordsToIndex" },
+};
+
+G_DEFINE_TYPE (TrackerConfig, tracker_config, TRACKER_TYPE_CONFIG_MANAGER);
 
 static void
 tracker_config_class_init (TrackerConfigClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-	object_class->finalize	   = config_finalize;
-	object_class->get_property = config_get_property;
 	object_class->set_property = config_set_property;
+	object_class->get_property = config_get_property;
+	object_class->finalize	   = config_finalize;
+	object_class->constructed  = config_constructed;
 
 	/* General */
 	g_object_class_install_property (object_class,
 					 PROP_VERBOSITY,
 					 g_param_spec_int ("verbosity",
 							   "Log verbosity",
-							   "How much logging we have "
-							   "(0=errors, 1=minimal, 2=detailed, 3=debug)",
+							   " Log verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
 							   0,
 							   3,
 							   DEFAULT_VERBOSITY,
@@ -127,8 +127,7 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_LOW_MEMORY_MODE,
 					 g_param_spec_boolean ("low-memory-mode",
 							       "Use extra memory",
-							       "Use extra memory at the "
-							       "expense of indexing speed",
+							       " Minimizes memory use at the expense of indexing speed",
 							       DEFAULT_LOW_MEMORY_MODE,
 							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
@@ -137,8 +136,7 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_MIN_WORD_LENGTH,
 					 g_param_spec_int ("min-word-length",
 							   "Minimum word length",
-							   "Minimum word length used to index "
-							   "(0->30)",
+							   " Set the minimum length of words to index (0->30, default=3)",
 							   0,
 							   30,
 							   DEFAULT_MIN_WORD_LENGTH,
@@ -147,20 +145,16 @@ tracker_config_class_init (TrackerConfigClass *klass)
 					 PROP_MAX_WORD_LENGTH,
 					 g_param_spec_int ("max-word-length",
 							   "Maximum word length",
-							   "Maximum word length used to index",
+							   " Set the maximum length of words to index (0->200, default=30)",
 							   0,
 							   200, /* Is this a reasonable limit? */
 							   DEFAULT_MAX_WORD_LENGTH,
 							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-
-	/* Performance */
 	g_object_class_install_property (object_class,
 					 PROP_MAX_WORDS_TO_INDEX,
 					 g_param_spec_int ("max-words-to-index",
 							   "Maximum words to index",
-							   "Maximum unique words to index "
-							   "from file's content",
+							   " Maximum unique words to index from a file's content (default=10000)",
 							   0,
 							   G_MAXINT,
 							   DEFAULT_MAX_WORDS_TO_INDEX,
@@ -172,65 +166,37 @@ tracker_config_class_init (TrackerConfigClass *klass)
 static void
 tracker_config_init (TrackerConfig *object)
 {
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
-	priv->key_file = g_key_file_new ();
-}
-
-static void
-config_finalize (GObject *object)
-{
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
-	if (priv->key_file) {
-		g_key_file_free (priv->key_file);
-	}
-
-	if (priv->monitor) {
-		g_object_unref (priv->monitor);
-	}
-
-	if (priv->file) {
-		g_object_unref (priv->file);
-	}
-
-	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
 }
 
 static void
-config_get_property (GObject	*object,
-		     guint	 param_id,
-		     GValue	*value,
-		     GParamSpec *pspec)
+config_set_property (GObject	  *object,
+		     guint	   param_id,
+		     const GValue *value,
+		     GParamSpec	  *pspec)
 {
-	TrackerConfigPrivate *priv;
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (object);
-
 	switch (param_id) {
 		/* General */
 	case PROP_VERBOSITY:
-		g_value_set_int (value, priv->verbosity);
+		tracker_config_set_verbosity (TRACKER_CONFIG (object),
+					      g_value_get_int (value));
 		break;
 	case PROP_LOW_MEMORY_MODE:
-		g_value_set_boolean (value, priv->low_memory_mode);
+		tracker_config_set_low_memory_mode (TRACKER_CONFIG (object),
+						    g_value_get_boolean (value));
 		break;
 
 		/* Indexing */
 	case PROP_MIN_WORD_LENGTH:
-		g_value_set_int (value, priv->min_word_length);
+		tracker_config_set_min_word_length (TRACKER_CONFIG (object),
+						    g_value_get_int (value));
 		break;
 	case PROP_MAX_WORD_LENGTH:
-		g_value_set_int (value, priv->max_word_length);
+		tracker_config_set_max_word_length (TRACKER_CONFIG (object),
+						    g_value_get_int (value));
 		break;
-
-		/* Performance */
 	case PROP_MAX_WORDS_TO_INDEX:
-		g_value_set_int (value, priv->max_words_to_index);
+		tracker_config_set_max_words_to_index (TRACKER_CONFIG (object),
+						       g_value_get_int (value));
 		break;
 
 	default:
@@ -240,36 +206,33 @@ config_get_property (GObject	*object,
 }
 
 static void
-config_set_property (GObject	  *object,
-		     guint	   param_id,
-		     const GValue *value,
-		     GParamSpec	  *pspec)
+config_get_property (GObject	*object,
+		     guint	 param_id,
+		     GValue	*value,
+		     GParamSpec *pspec)
 {
+	TrackerConfigPrivate *priv;
+
+	priv = TRACKER_CONFIG_GET_PRIVATE (object);
+
 	switch (param_id) {
 		/* General */
 	case PROP_VERBOSITY:
-		tracker_config_set_verbosity (TRACKER_CONFIG (object),
-					      g_value_get_int (value));
+		g_value_set_int (value, priv->verbosity);
 		break;
 	case PROP_LOW_MEMORY_MODE:
-		tracker_config_set_low_memory_mode (TRACKER_CONFIG (object),
-						    g_value_get_boolean (value));
+		g_value_set_boolean (value, priv->low_memory_mode);
 		break;
 
 		/* Indexing */
 	case PROP_MIN_WORD_LENGTH:
-		tracker_config_set_min_word_length (TRACKER_CONFIG (object),
-						    g_value_get_int (value));
+		g_value_set_int (value, priv->min_word_length);
 		break;
 	case PROP_MAX_WORD_LENGTH:
-		tracker_config_set_max_word_length (TRACKER_CONFIG (object),
-						    g_value_get_int (value));
+		g_value_set_int (value, priv->max_word_length);
 		break;
-
-		/* Performance */
 	case PROP_MAX_WORDS_TO_INDEX:
-		tracker_config_set_max_words_to_index (TRACKER_CONFIG (object),
-						       g_value_get_int (value));
+		g_value_set_int (value, priv->max_words_to_index);
 		break;
 
 	default:
@@ -278,336 +241,129 @@ config_set_property (GObject	  *object,
 	};
 }
 
-static gchar *
-config_dir_ensure_exists_and_return (void)
-{
-	gchar *directory;
-
-	directory = g_build_filename (g_get_user_config_dir (),
-				      "tracker",
-				      NULL);
-
-	if (!g_file_test (directory, G_FILE_TEST_EXISTS)) {
-		g_print ("Creating config directory:'%s'\n", directory);
-
-		if (g_mkdir_with_parents (directory, 0700) == -1) {
-			g_warning ("Could not create configuration directory");
-			g_free (directory);
-			return NULL;
-		}
-	}
-
-	return directory;
-}
-
 static void
-config_create_with_defaults (GKeyFile *key_file, 
-			     gboolean  overwrite)
-{
-	g_message ("Loading defaults into GKeyFile...");
-
-	/* General */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_GENERAL, KEY_VERBOSITY, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_GENERAL, KEY_VERBOSITY, 
-					DEFAULT_VERBOSITY);
-		g_key_file_set_comment (key_file, GROUP_GENERAL, KEY_VERBOSITY,
-					" Log Verbosity (0=errors, 1=minimal, 2=detailed, 3=debug)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_GENERAL, KEY_LOW_MEMORY_MODE, NULL)) {
-		g_key_file_set_boolean (key_file, GROUP_GENERAL, KEY_LOW_MEMORY_MODE, 
-					DEFAULT_LOW_MEMORY_MODE);
-		g_key_file_set_comment (key_file, GROUP_GENERAL, KEY_LOW_MEMORY_MODE,
-					" Minimizes memory use at the expense of indexing speed",
-					NULL);
-	}
-
-	/* Indexing */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_MIN_WORD_LENGTH, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_INDEXING, KEY_MIN_WORD_LENGTH,
-					DEFAULT_MIN_WORD_LENGTH);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_MIN_WORD_LENGTH,
-					" Set the minimum length of words to index (0->30, default=3)",
-					NULL);
-	}
-
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_INDEXING, KEY_MAX_WORD_LENGTH, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_INDEXING, KEY_MAX_WORD_LENGTH,
-					DEFAULT_MAX_WORD_LENGTH);
-		g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_MAX_WORD_LENGTH,
-					" Set the maximum length of words to index (0->200, default=30)",
-					NULL);
-	}
-
-	/* Performance */
-	if (overwrite || !g_key_file_has_key (key_file, GROUP_PERFORMANCE, KEY_MAX_WORDS_TO_INDEX, NULL)) {
-		g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_MAX_WORDS_TO_INDEX,
-					DEFAULT_MAX_WORDS_TO_INDEX);
-		g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_MAX_WORDS_TO_INDEX,
-					" Maximum unique words to index from a file's content",
-					NULL);
-	}
-}
-
-static gboolean
-config_save_with_defaults (const gchar *filename,
-			   GKeyFile    *key_file)
-{
-	GError *error = NULL;
-	gchar  *content = NULL;
-
-	/* Save to file */
-	content = g_key_file_to_data (key_file, NULL, &error);
-
-	if (error) {
-		g_warning ("Couldn't produce default configuration, %s", error->message);
-		g_clear_error (&error);
-		return FALSE;
-	}
-
-	if (!g_file_set_contents (filename, content, -1, &error)) {
-		g_warning ("Couldn't write default configuration, %s", error->message);
-		g_clear_error (&error);
-		g_free (content);
-		return FALSE;
-	}
-
-	g_print ("Writing default configuration to file:'%s'\n", filename);
-	g_free (content);
-
-	return TRUE;
-}
-
-static void
-config_load_int (TrackerConfig *config,
-		 const gchar   *property,
-		 GKeyFile      *key_file,
-		 const gchar   *group,
-		 const gchar   *key)
-{
-	GError *error = NULL;
-	gint	value;
-
-	value = g_key_file_get_integer (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (int) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
-}
-
-static void
-config_load_boolean (TrackerConfig *config,
-		     const gchar   *property,
-		     GKeyFile	   *key_file,
-		     const gchar   *group,
-		     const gchar   *key)
-{
-	GError	 *error = NULL;
-	gboolean  value;
-
-	value = g_key_file_get_boolean (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (bool) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
-}
-
-#if 0
-
-static void
-config_load_string (TrackerConfig *config,
-		    const gchar	  *property,
-		    GKeyFile	  *key_file,
-		    const gchar	  *group,
-		    const gchar	  *key)
-{
-	GError *error = NULL;
-	gchar  *value;
-
-	value = g_key_file_get_string (key_file, group, key, &error);
-	if (!error) {
-		g_object_set (G_OBJECT (config), property, value, NULL);
-	} else {
-		g_message ("Couldn't load config option '%s' (string) in group '%s', %s",
-			   property, group, error->message);
-		g_error_free (error);
-	}
-
-	g_free (value);
-}
-
-#endif
-
-
-static void
-config_save_int (TrackerConfig *config,
-		 const gchar   *property,
-		 GKeyFile      *key_file,
-		 const gchar   *group,
-		 const gchar   *key)
-{
-	gint value;
-
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_integer (key_file, group, key, value);
-}
-
-static void
-config_save_boolean (TrackerConfig *config,
-		     const gchar   *property,
-		     GKeyFile	   *key_file,
-		     const gchar   *group,
-		     const gchar   *key)
+config_finalize (GObject *object)
 {
-	gboolean value;
+	/* For now we do nothing here, we left this override in for
+	 * future expansion.
+	 */
 
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_boolean (key_file, group, key, value);
+	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
 }
 
-#if 0
-
 static void
-config_save_string (TrackerConfig *config,
-		    const gchar	  *property,
-		    GKeyFile	  *key_file,
-		    const gchar	  *group,
-		    const gchar	  *key)
+config_constructed (GObject *object)
 {
-	gchar *value;
+	(G_OBJECT_CLASS (tracker_config_parent_class)->constructed) (object);
 
-	g_object_get (G_OBJECT (config), property, &value, NULL);
-	g_key_file_set_string (key_file, group, key, value);
-	g_free (value);
+	config_load (TRACKER_CONFIG (object));
 }
 
-#endif 
-
-
 static void
-config_changed_cb (GFileMonitor     *monitor,
-		   GFile	    *file,
-		   GFile	    *other_file,
-		   GFileMonitorEvent event_type,
-		   gpointer	     user_data)
+config_create_with_defaults (TrackerConfig *config,
+			     GKeyFile      *key_file, 
+			     gboolean       overwrite)
 {
-	TrackerConfig *config;
-	gchar	      *filename;
-
-	config = TRACKER_CONFIG (user_data);
+	gint i;
 
-	/* Do we recreate if the file is deleted? */
-
-	switch (event_type) {
-	case G_FILE_MONITOR_EVENT_CHANGED:
-	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
-		filename = g_file_get_path (file);
-		g_message ("Config file changed:'%s', reloading settings...",
-			   filename);
-		g_free (filename);
-
-		config_load (config);
-		break;
+	g_message ("Loading defaults into GKeyFile...");
+	
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+		
+		has_key = g_key_file_has_key (key_file, 
+					      conversions[i].group, 
+					      conversions[i].key, 
+					      NULL);
+		if (!overwrite && has_key) {
+			continue;
+		}
+		
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			g_key_file_set_integer (key_file, 
+						conversions[i].group, 
+						conversions[i].key, 
+						tracker_config_default_int (config, 
+									    conversions[i].property));
+			break;
+
+		case G_TYPE_BOOLEAN:
+			g_key_file_set_boolean (key_file, 
+						conversions[i].group, 
+						conversions[i].key, 
+						tracker_config_default_boolean (config, 
+										conversions[i].property));
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
 
-	case G_FILE_MONITOR_EVENT_DELETED:
-	case G_FILE_MONITOR_EVENT_CREATED:
-	case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
-	case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
-	case G_FILE_MONITOR_EVENT_UNMOUNTED:
-	default:
-		break;
+		g_key_file_set_comment (key_file, 
+					conversions[i].group, 
+					conversions[i].key, 
+					tracker_config_blurb (config,
+							      conversions[i].property), 
+					NULL);
 	}
 }
 
 static void
 config_load (TrackerConfig *config)
 {
-	TrackerConfigPrivate *priv;
-	GError		     *error = NULL;
-	gchar                *basename;
-	gchar		     *filename;
-	gchar		     *directory;
+	TrackerConfigManager *manager;
+	gint i;
 
-	/* Check we have a config file and if not, create it based on
-	 * the default settings.
-	 */
-	directory = config_dir_ensure_exists_and_return ();
-	if (!directory) {
-		return;
-	}
-
-	basename = g_strdup_printf ("%s.cfg", g_get_application_name ());
-	filename = g_build_filename (directory, basename, NULL);
-	g_free (basename);
-	g_free (directory);
-
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
+	manager = TRACKER_CONFIG_MANAGER (config);
+	config_create_with_defaults (config, manager->key_file, FALSE);
 
-	/* Add file monitoring for changes */
-	if (!priv->file) {
-		priv->file = g_file_new_for_path (filename);
+	if (!manager->file_exists) {
+		tracker_config_manager_save (manager);
 	}
 
-	if (!priv->monitor) {
-		g_message ("Setting up monitor for changes to config file:'%s'",
-			   filename);
-
-		priv->monitor = g_file_monitor_file (priv->file,
-						     G_FILE_MONITOR_NONE,
-						     NULL,
-						     NULL);
-
-		g_signal_connect (priv->monitor, "changed",
-				  G_CALLBACK (config_changed_cb),
-				  config);
-	}
-
-	/* Load options */
-	g_key_file_load_from_file (priv->key_file, 
-				   filename, 
-				   G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
-				   &error);
-
-	config_create_with_defaults (priv->key_file, FALSE);
-
-	if (error) {
-		config_save_with_defaults (filename, priv->key_file);
-		g_clear_error (&error);
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		gboolean has_key;
+		
+		has_key = g_key_file_has_key (manager->key_file, 
+					      conversions[i].group, 
+					      conversions[i].key, 
+					      NULL);
+	
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_config_load_int (G_OBJECT (manager), 
+						 conversions[i].property,
+						 manager->key_file,
+						 conversions[i].group, 
+						 conversions[i].key);
+			break;
+
+		case G_TYPE_BOOLEAN:
+			tracker_config_load_boolean (G_OBJECT (manager), 
+						     conversions[i].property,
+						     manager->key_file,
+						     conversions[i].group, 
+						     conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
 	}
-
-	g_free (filename);
-
-	/* General */
-	config_load_int (config, "verbosity", priv->key_file, GROUP_GENERAL, KEY_VERBOSITY);
-	config_load_boolean (config, "low-memory-mode", priv->key_file, GROUP_GENERAL, KEY_LOW_MEMORY_MODE);
-
-	/* Indexing */
-	config_load_int (config, "min-word-length", priv->key_file, GROUP_INDEXING, KEY_MIN_WORD_LENGTH);
-	config_load_int (config, "max-word-length", priv->key_file, GROUP_INDEXING, KEY_MAX_WORD_LENGTH);
-
-	/* Performance */
-	config_load_int (config, "max-words-to-index", priv->key_file, GROUP_PERFORMANCE, KEY_MAX_WORDS_TO_INDEX);
 }
 
 static gboolean
 config_save (TrackerConfig *config)
 {
-	TrackerConfigPrivate *priv;
-	GError		     *error = NULL;
-	gchar		     *filename;
-	gchar		     *data;
-	gsize                 size;
+	TrackerConfigManager *manager;
+	gint i;
 
-	priv = TRACKER_CONFIG_GET_PRIVATE (config);
+	manager = TRACKER_CONFIG_MANAGER (config);
 
-	if (!priv->key_file) {
+	if (!manager->key_file) {
 		g_critical ("Could not save config, GKeyFile was NULL, has the config been loaded?");
 
 		return FALSE;
@@ -615,105 +371,39 @@ config_save (TrackerConfig *config)
 
 	g_message ("Setting details to GKeyFile object...");
 
-	/* Set properties to GKeyFile */
-	config_save_int (config, "verbosity", priv->key_file, GROUP_GENERAL, KEY_VERBOSITY);
-	config_save_boolean (config, "low-memory-mode", priv->key_file, GROUP_GENERAL, KEY_LOW_MEMORY_MODE);
-
-	/* Indexing */
-	config_save_int (config, "min-word-length", priv->key_file, GROUP_INDEXING, KEY_MIN_WORD_LENGTH);
-	config_save_int (config, "max-word-length", priv->key_file, GROUP_INDEXING, KEY_MAX_WORD_LENGTH);
-
-	/* Performance */
-	config_save_int (config, "max-words-to-index", priv->key_file, GROUP_PERFORMANCE, KEY_MAX_WORDS_TO_INDEX);
-
-	g_message ("Saving config to disk...");
-
-	/* Do the actual saving to disk now */
-	data = g_key_file_to_data (priv->key_file, &size, &error);
-	if (error) {
-		g_warning ("Could not get config data to write to file, %s",
-			   error->message);
-		g_error_free (error);
-
-		return FALSE;
-	}
-
-	filename = g_file_get_path (priv->file);
-
-	g_file_set_contents (filename, data, size, &error);
-	g_free (data);
-
-	if (error) {
-		g_warning ("Could not write %" G_GSIZE_FORMAT " bytes to file '%s', %s",
-			   size,
-			   filename,
-			   error->message);
-		g_free (filename);
-		g_error_free (error);
-
-		return FALSE;
+	for (i = 0; i < G_N_ELEMENTS (conversions); i++) {
+		switch (conversions[i].type) {
+		case G_TYPE_INT:
+			tracker_config_save_int (manager,
+						 conversions[i].property, 
+						 manager->key_file,
+						 conversions[i].group, 
+						 conversions[i].key);
+			break;
+
+		case G_TYPE_BOOLEAN:
+			tracker_config_save_boolean (manager,
+						     conversions[i].property, 
+						     manager->key_file,
+						     conversions[i].group, 
+						     conversions[i].key);
+			break;
+
+		default:
+			g_assert_not_reached ();
+			break;
+		}
 	}
 
-	g_message ("Wrote config to '%s' (%" G_GSIZE_FORMAT " bytes)",
-		   filename, 
-		   size);
-
-	g_free (filename);
-
-	return TRUE;
+	return tracker_config_manager_save (TRACKER_CONFIG_MANAGER (config));
 }
 
-static gboolean
-config_int_validate (TrackerConfig *config,
-		     const gchar   *property,
-		     gint	    value)
-{
-#ifdef G_DISABLE_CHECKS
-	GParamSpec *spec;
-	GValue	    value = { 0 };
-	gboolean    valid;
-
-	spec = g_object_class_find_property (G_OBJECT_CLASS (config), property);
-	g_return_val_if_fail (spec != NULL, FALSE);
-
-	g_value_init (&value, spec->value_type);
-	g_value_set_int (&value, verbosity);
-	valid = g_param_value_validate (spec, &value);
-	g_value_unset (&value);
-
-	g_return_val_if_fail (valid != TRUE, FALSE);
-#endif
-
-	return TRUE;
-}
-
-/**
- * tracker_config_new:
- *
- * Creates a new GObject for handling Tracker's config file.
- *
- * Return value: A new TrackerConfig object. Must be unreferenced when
- * finished with.
- */
 TrackerConfig *
 tracker_config_new (void)
 {
-	TrackerConfig *config;
-
-	config = g_object_new (TRACKER_TYPE_CONFIG, NULL);
-	config_load (config);
-
-	return config;
+	return g_object_new (TRACKER_TYPE_CONFIG, NULL);
 }
 
-/**
- * tracker_config_save:
- * @config: a #TrackerConfig
- *
- * Writes the configuration stored in TrackerConfig to disk.
- *
- * Return value: %TRUE on success, %FALSE otherwise.
- */
 gboolean
 tracker_config_save (TrackerConfig *config)
 {
@@ -722,24 +412,6 @@ tracker_config_save (TrackerConfig *config)
 	return config_save (config);
 }
 
-/**
- * tracker_config_get_verbosity:
- * @config: a #TrackerConfig
- *
- * Gets the verbosity of the logging in the indexer and the daemon.
- *
- * If the verbosity is 0, there is no logging except for warnings and
- * errors.
- * If the verbosity is 1, information is displayed.
- * If the verbosity is 2, general messages are displayed.
- * If the verbosity is 3, debug messages are displayed.
- *
- * Note, you receive logging for anything less priority than the
- * verbosity level as well as the level you set. So if the verbosity
- * is 3 you receive debug, messages, info and warnings.
- *
- * Return value: An integer value from 0 to 3.
- */
 gint
 tracker_config_get_verbosity (TrackerConfig *config)
 {
@@ -809,7 +481,7 @@ tracker_config_set_verbosity (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "verbosity", value)) {
+	if (!tracker_config_validate_int (config, "verbosity", value)) {
 		return;
 	}
 
@@ -841,7 +513,7 @@ tracker_config_set_min_word_length (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "min-word-length", value)) {
+	if (!tracker_config_validate_int (config, "min-word-length", value)) {
 		return;
 	}
 
@@ -859,7 +531,7 @@ tracker_config_set_max_word_length (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "max-word-length", value)) {
+	if (!tracker_config_validate_int (config, "max-word-length", value)) {
 		return;
 	}
 
@@ -877,7 +549,7 @@ tracker_config_set_max_words_to_index (TrackerConfig *config,
 
 	g_return_if_fail (TRACKER_IS_CONFIG (config));
 
-	if (!config_int_validate (config, "max-words-to-index", value)) {
+	if (!tracker_config_validate_int (config, "max-words-to-index", value)) {
 		return;
 	}
 
diff --git a/src/tracker-store/tracker-config.h b/src/tracker-store/tracker-config.h
index 7ce6e90..f6b8521 100644
--- a/src/tracker-store/tracker-config.h
+++ b/src/tracker-store/tracker-config.h
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * Copyright (C) 2008, Nokia (urho konttori nokia com)
+ * Copyright (C) 2009, Nokia (urho konttori nokia com)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -23,6 +23,8 @@
 
 #include <glib-object.h>
 
+#include <libtracker-common/tracker-config-manager.h>
+
 G_BEGIN_DECLS
 
 #define TRACKER_TYPE_CONFIG	    (tracker_config_get_type ())
@@ -32,15 +34,15 @@ G_BEGIN_DECLS
 #define TRACKER_IS_CONFIG_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_CONFIG))
 #define TRACKER_CONFIG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_CONFIG, TrackerConfigClass))
 
-typedef struct _TrackerConfig	   TrackerConfig;
-typedef struct _TrackerConfigClass TrackerConfigClass;
+typedef struct TrackerConfig	  TrackerConfig;
+typedef struct TrackerConfigClass TrackerConfigClass;
 
-struct _TrackerConfig {
-	GObject      parent;
+struct TrackerConfig {
+	TrackerConfigManager parent;
 };
 
-struct _TrackerConfigClass {
-	GObjectClass parent_class;
+struct TrackerConfigClass {
+	TrackerConfigManagerClass parent_class;
 };
 
 GType	       tracker_config_get_type               (void) G_GNUC_CONST;



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