diff --git a/src/trackerd/Makefile.am b/src/trackerd/Makefile.am
index dee675f..94c449c 100644
--- a/src/trackerd/Makefile.am
+++ b/src/trackerd/Makefile.am
@@ -58,6 +58,8 @@ trackerd_SOURCES =			\
 	$(db_sources)			\
 	tracker-apps.c			\
 	tracker-apps.h			\
+	tracker-config.c		\
+	tracker-config.h		\
 	tracker-db.c			\
 	tracker-db.h			\
 	tracker-dbus.c			\
@@ -82,12 +84,12 @@ trackerd_SOURCES =			\
 	tracker-email-thunderbird.h	\
 	tracker-email-kmail.c		\
 	tracker-email-kmail.h		\
+	tracker-language.c		\
+	tracker-language.h		\
 	tracker-metadata.c		\
 	tracker-metadata.h		\
 	tracker-rdf-query.c		\
 	tracker-rdf-query.h		\
-	tracker-stemmer.c		\
-	tracker-stemmer.h		\
 	tracker-utils.c			\
 	tracker-utils.h			\
 	tracker-ioprio.c		\
diff --git a/src/trackerd/tracker-cache.c b/src/trackerd/tracker-cache.c
index e5305a3..be1151e 100644
--- a/src/trackerd/tracker-cache.c
+++ b/src/trackerd/tracker-cache.c
@@ -24,7 +24,7 @@
 #include "tracker-utils.h"
 #include "tracker-dbus.h"
 #include "tracker-cache.h"
-
+#include "tracker-config.h"
 
 #define USE_SLICE
 
@@ -247,7 +247,7 @@ update_word_table (GHashTable *table, const char *word, WordDetails *word_detail
 
 	if (!array) {
 
-		if (tracker->use_extra_memory) {
+                if (!tracker_config_get_low_memory_mode (tracker->config)) {
 			array = g_byte_array_sized_new (sz * 2);
 		} else {
 			array = g_byte_array_sized_new (sz);
@@ -307,7 +307,8 @@ tracker_cache_process_events (DBConnection *db_con, gboolean check_flush)
 
 		gboolean sleep = FALSE;
 
-		if (!tracker->is_running || !tracker->enable_indexing) {
+		if (!tracker->is_running || 
+                    !tracker_config_get_enable_indexing (tracker->config)) {
 			if (check_flush) tracker_cache_flush_all ();
 			sleep = TRUE;
 		}
@@ -329,7 +330,10 @@ tracker_cache_process_events (DBConnection *db_con, gboolean check_flush)
 			/* set mutex to indicate we are in "check" state to prevent race conditions from other threads resetting gloabl vars */
 			g_mutex_lock (tracker->files_check_mutex);		
 
-			if ((tracker_pause () || !tracker->is_running || !tracker->enable_indexing) && (!tracker->shutdown))  {
+			if ((tracker_pause () || 
+                             !tracker->is_running || 
+                             !tracker_config_get_enable_indexing (tracker->config)) && 
+                            (!tracker->shutdown))  {
 				g_cond_wait (tracker->file_thread_signal, tracker->files_signal_mutex);
 			}
 
diff --git a/src/trackerd/tracker-config.c b/src/trackerd/tracker-config.c
new file mode 100644
index 0000000..af95e3a
--- /dev/null
+++ b/src/trackerd/tracker-config.c
@@ -0,0 +1,2353 @@
+/* -*- 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)
+ *
+ * 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 <glib.h>
+
+#include "tracker-utils.h"
+#include "tracker-language.h"
+#include "tracker-config.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_CONFIG, TrackerConfigPriv))
+
+/* GKeyFile defines */
+#define GROUP_GENERAL				 "General"
+#define KEY_VERBOSITY				 "Verbosity"
+#define KEY_INITIAL_SLEEP			 "InitialSleep"
+#define KEY_LOW_MEMORY_MODE			 "LowMemoryMode"
+
+#define GROUP_WATCHES				 "Watches"
+#define KEY_WATCH_DIRECTORY_ROOTS		 "WatchDirectoryRoots"
+#define KEY_CRAWL_DIRECTORY_ROOTS		 "CrawlDirectory"
+#define KEY_NO_WATCH_DIRECTORY_ROOTS		 "NoWatchDirectory"
+#define KEY_ENABLE_WATCHES			 "EnableWatching"
+
+#define GROUP_INDEXING				 "Indexing"
+#define KEY_THROTTLE				 "Throttle"
+#define KEY_ENABLE_INDEXING			 "EnableIndexing"
+#define KEY_ENABLE_CONTENT_INDEXING		 "EnableFileContentIndexing"
+#define KEY_ENABLE_THUMBNAILS			 "EnableThumbnails"
+#define KEY_FAST_MERGES				 "FastMerges"
+#define KEY_NO_INDEX_FILE_TYPES			 "NoIndexFileTypes"
+#define KEY_MIN_WORD_LENGTH			 "MinWorldLength"
+#define KEY_MAX_WORD_LENGTH			 "MaxWorldLength"
+#define KEY_LANGUAGE				 "Language"
+#define KEY_ENABLE_STEMMER			 "EnableStemmer"
+#define KEY_SKIP_MOUNT_POINTS			 "SkipMountPoints"
+#define KEY_DISABLE_INDEXING_ON_BATTERY		 "BatteryIndex"
+#define KEY_DISABLE_INDEXING_ON_BATTERY_INIT	 "BatteryIndexInitial"
+#define KEY_LOW_DISK_SPACE_LIMIT		 "LowDiskSpaceLimit"
+
+#define GROUP_EMAILS				 "Emails"
+#define KEY_INDEX_EVOLUTION_EMAILS		 "IndexEvolutionEmails"
+#define KEY_INDEX_KMAIL_EMAILS			 "IndexKMailEmails"
+#define KEY_INDEX_THUNDERBIRD_EMAILS		 "IndexThunderbirdEmails"
+
+#define GROUP_PERFORMANCE			 "Performance"
+#define KEY_MAX_TEXT_TO_INDEX			 "MaxTextToIndex"
+#define KEY_MAX_WORDS_TO_INDEX			 "MaxWordsToIndex"
+#define KEY_OPTIMIZATION_SWEEP_COUNT		 "OptimizationSweepCount"
+#define KEY_MAX_BUCKET_COUNT			 "MaxBucketCount"
+#define KEY_MIN_BUCKET_COUNT			 "MinBucketCount"
+#define KEY_DIVISIONS				 "Divisions"
+#define KEY_BUCKET_RATIO			 "BucketRatio"
+#define KEY_PADDING				 "Padding"
+#define KEY_THREAD_STACK_SIZE			 "ThreadStackSize"
+
+/* Default values */
+#define DEFAULT_VERBOSITY			 0
+#define DEFAULT_INITIAL_SLEEP			 45	  /* 0->1000 */
+#define DEFAULT_LOW_MEMORY_MODE			 TRUE
+#define DEFAULT_ENABLE_WATCHES			 TRUE
+#define DEFAULT_THROTTLE			 0	  /* 0->20 */
+#define DEFAULT_ENABLE_INDEXING			 TRUE
+#define DEFAULT_ENABLE_CONTENT_INDEXING		 TRUE
+#define DEFAULT_ENABLE_THUMBNAILS		 TRUE
+#define DEFAULT_FAST_MERGES			 FALSE
+#define DEFAULT_MIN_WORD_LENGTH			 3	  /* 0->30 */
+#define DEFAULT_MAX_WORD_LENGTH			 30	  /* 0->200 */
+#define DEFAULT_ENABLE_STEMMER			 TRUE
+#define DEFAULT_SKIP_MOUNT_POINTS		 FALSE
+#define DEFAULT_DISABLE_INDEXING_ON_BATTERY	 TRUE
+#define DEFAULT_DISABLE_INDEXING_ON_BATTERY_INIT FALSE
+#define DEFAULT_INDEX_EVOLUTION_EMAILS		 TRUE
+#define DEFAULT_INDEX_KMAIL_EMAILS		 TRUE
+#define DEFAULT_INDEX_THUNDERBIRD_EMAILS	 TRUE
+#define DEFAULT_LOW_DISK_SPACE_LIMIT		 1	  /* 0->100 / -1 */
+#define DEFAULT_MAX_TEXT_TO_INDEX		 1048576  /* Bytes */
+#define DEFAULT_MAX_WORDS_TO_INDEX		 10000
+#define DEFAULT_OPTIMIZATION_SWEEP_COUNT	 10000
+#define DEFAULT_MAX_BUCKET_COUNT		 524288
+#define DEFAULT_MIN_BUCKET_COUNT		 65536
+#define DEFAULT_DIVISIONS			 4	  /* 1->64 */
+#define DEFAULT_BUCKET_RATIO			 1	  /* 0=50%, 1=100%, 2=200%, 3=300%, 4=400% */
+#define DEFAULT_PADDING				 2	  /* 1->8 */
+#define DEFAULT_THREAD_STACK_SIZE		 0	  /* 0 is the default for the platform */
+
+typedef struct _ConfigLanguages	  ConfigLanguages;
+typedef struct _TrackerConfigPriv TrackerConfigPriv;
+
+struct _TrackerConfigPriv {
+	/* General */
+	gint	  verbosity;
+	gint	  initial_sleep;
+	gboolean  low_memory_mode;
+
+	/* Watches */
+	GSList	 *watch_directory_roots;
+	GSList	 *crawl_directory_roots;
+	GSList	 *no_watch_directory_roots;
+	gboolean  enable_watches;
+
+	/* Indexing */
+	gint	  throttle;
+	gboolean  enable_indexing;
+	gboolean  enable_content_indexing;
+	gboolean  enable_thumbnails;
+	gboolean  fast_merges;
+	GSList	 *no_index_file_types;
+	gint	  min_word_length;
+	gint	  max_word_length;
+	gchar	 *language;
+	gboolean  enable_stemmer;
+	gboolean  skip_mount_points;
+	gboolean  disable_indexing_on_battery;
+	gboolean  disable_indexing_on_battery_init;
+	gint	  low_disk_space_limit;
+
+	/* Emails */
+	gboolean  index_evolution_emails;
+	gboolean  index_kmail_emails;
+	gboolean  index_thunderbird_emails;
+
+	/* Performance */
+	gint	  max_text_to_index;
+	gint	  max_words_to_index;
+	gint	  optimization_sweep_count;
+	gint	  max_bucket_count;
+	gint	  min_bucket_count;
+	gint	  divisions;
+	gint	  bucket_ratio;
+	gint	  padding;
+	gint	  thread_stack_size;
+};
+
+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);
+
+/* GObject properties */
+enum {
+	PROP_0,
+
+	/* General */
+	PROP_VERBOSITY,
+	PROP_INITIAL_SLEEP,
+	PROP_LOW_MEMORY_MODE,
+
+	/* Watches */
+	PROP_WATCH_DIRECTORY_ROOTS,
+	PROP_CRAWL_DIRECTORY_ROOTS,
+	PROP_NO_WATCH_DIRECTORY_ROOTS,
+	PROP_ENABLE_WATCHES,
+
+	/* Indexing */
+	PROP_THROTTLE,
+	PROP_ENABLE_INDEXING,
+	PROP_ENABLE_CONTENT_INDEXING,
+	PROP_ENABLE_THUMBNAILS,
+	PROP_FAST_MERGES,
+	PROP_NO_INDEX_FILE_TYPES,
+	PROP_MIN_WORD_LENGTH,
+	PROP_MAX_WORD_LENGTH,
+	PROP_LANGUAGE,
+	PROP_ENABLE_STEMMER,
+	PROP_SKIP_MOUNT_POINTS,
+	PROP_DISABLE_INDEXING_ON_BATTERY,
+	PROP_DISABLE_INDEXING_ON_BATTERY_INIT,
+	PROP_LOW_DISK_SPACE_LIMIT,
+
+	/* Emails */
+	PROP_INDEX_EVOLUTION_EMAILS,
+	PROP_INDEX_KMAIL_EMAILS,
+	PROP_INDEX_THUNDERBIRD_EMAILS,
+
+	/* Performance */
+	PROP_MAX_TEXT_TO_INDEX,
+	PROP_MAX_WORDS_TO_INDEX,
+	PROP_OPTIMIZATION_SWEEP_COUNT,
+	PROP_MAX_BUCKET_COUNT,
+	PROP_MIN_BUCKET_COUNT,
+	PROP_DIVISIONS,
+	PROP_BUCKET_RATIO,
+	PROP_PADDING,
+	PROP_THREAD_STACK_SIZE
+};
+
+G_DEFINE_TYPE (TrackerConfig, tracker_config, G_TYPE_OBJECT);
+
+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;
+
+	/* 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)",
+							   0,
+							   3,
+							   DEFAULT_VERBOSITY,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_INITIAL_SLEEP,
+					 g_param_spec_int ("initial-sleep",
+							   "Initial sleep",
+							   "Initial sleep time in seconds "
+							   "(0->1000)",
+							   0,
+							   1000,
+							   DEFAULT_INITIAL_SLEEP,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_LOW_MEMORY_MODE,
+					 g_param_spec_boolean ("low-memory-mode",
+							       "Use extra memory",
+							       "Use extra memory at the "
+							       "expense of indexing speed",
+							       DEFAULT_LOW_MEMORY_MODE,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	/* Watches */
+	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));
+	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));
+	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,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	/* Indexing */
+	g_object_class_install_property (object_class,
+					 PROP_THROTTLE,
+					 g_param_spec_int ("throttle",
+							   "Throttle",
+							   "Throttle indexing, higher value "
+							   "is slower (0->20)",
+							   0,
+							   20,
+							   DEFAULT_THROTTLE,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_ENABLE_INDEXING,
+					 g_param_spec_boolean ("enable-indexing",
+							       "Enable indexing",
+							       "All indexing",
+							       DEFAULT_ENABLE_INDEXING,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_ENABLE_CONTENT_INDEXING,
+					 g_param_spec_boolean ("enable-content-indexing",
+							       "Enable content indexing",
+							       "Content specific indexing "
+							       "(i.e. file content)",
+							       DEFAULT_ENABLE_CONTENT_INDEXING,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_ENABLE_THUMBNAILS,
+					 g_param_spec_boolean ("enable-thumbnails",
+							       "Enable thumbnails",
+							       "Create thumbnails from image based files",
+							       DEFAULT_ENABLE_THUMBNAILS,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_FAST_MERGES,
+					 g_param_spec_boolean ("fast-merges",
+							       "Fast merges",
+							       "Spends more disk usage if TRUE",
+							       DEFAULT_FAST_MERGES,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_NO_INDEX_FILE_TYPES,
+					 g_param_spec_pointer ("no-index-file-types",
+							       "File types to not index",
+							       "This is a GSList of file types "
+							       "to NOT index",
+							       G_PARAM_READABLE));
+	g_object_class_install_property (object_class,
+					 PROP_MIN_WORD_LENGTH,
+					 g_param_spec_int ("min-word-length",
+							   "Minimum word length",
+							   "Minimum word length used to index "
+							   "(0->30)",
+							   0,
+							   30,
+							   DEFAULT_MIN_WORD_LENGTH,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_MAX_WORD_LENGTH,
+					 g_param_spec_int ("max-word-length",
+							   "Maximum word length",
+							   "Maximum word length used to index",
+							   0,
+							   200, /* Is this a reasonable limit? */
+							   DEFAULT_MAX_WORD_LENGTH,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_LANGUAGE,
+					 g_param_spec_string ("language",
+							      "Language",
+							      "Language to use with stemming "
+							      "('en', 'fr', 'sv', etc)",
+							      "en",
+							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_ENABLE_STEMMER,
+					 g_param_spec_boolean ("enable-stemmer",
+							       "Enable stemmer",
+							       "Language specific stemmer",
+							       DEFAULT_ENABLE_STEMMER,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_SKIP_MOUNT_POINTS,
+					 g_param_spec_boolean ("skip-mount-points",
+							       "Skip mount points",
+							       "Don't traverse mount points "
+							       "when indexing",
+							       DEFAULT_SKIP_MOUNT_POINTS,
+							       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",
+							       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",
+							       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)",
+							   -1,
+							   100,
+							   DEFAULT_LOW_DISK_SPACE_LIMIT,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	/* Emails */
+	g_object_class_install_property (object_class,
+					 PROP_INDEX_EVOLUTION_EMAILS,
+					 g_param_spec_boolean ("index-evolution-emails",
+							       "Index evolution emails",
+							       "Index evolution emails",
+							       DEFAULT_INDEX_EVOLUTION_EMAILS,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_INDEX_KMAIL_EMAILS,
+					 g_param_spec_boolean ("index-kmail-emails",
+							       "Index kmail emails",
+							       "Index kmail emails",
+							       DEFAULT_INDEX_KMAIL_EMAILS,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_INDEX_THUNDERBIRD_EMAILS,
+					 g_param_spec_boolean ("index-thunderbird-emails",
+							       "Index thunderbird emails",
+							       "Index thunderbird emails",
+							       DEFAULT_INDEX_THUNDERBIRD_EMAILS,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	/* Performance */
+	g_object_class_install_property (object_class,
+					 PROP_MAX_TEXT_TO_INDEX,
+					 g_param_spec_int ("max-text-to-index",
+							   "Maximum text to index",
+							   "Maximum text in bytes to index "
+							   "from file's content",
+							   0,
+							   G_MAXINT,
+							   DEFAULT_MAX_TEXT_TO_INDEX,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_MAX_TEXT_TO_INDEX,
+					 g_param_spec_int ("max-words-to-index",
+							   "Maximum words to index",
+							   "Maximum unique words to index "
+							   "from file's content",
+							   0,
+							   G_MAXINT,
+							   DEFAULT_MAX_WORDS_TO_INDEX,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_OPTIMIZATION_SWEEP_COUNT,
+					 g_param_spec_int ("optimization-sweep-count",
+							   "Optimization Sweep Count",
+							   "Number of entities to index "
+							   "before deciding to try to optimize "
+							   "(1000->10000)",
+							   1000,
+							   G_MAXINT,
+							   DEFAULT_OPTIMIZATION_SWEEP_COUNT,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_MAX_BUCKET_COUNT,
+					 g_param_spec_int ("max-bucket-count",
+							   "Maximum bucket count",
+							   "Maximum bucket count (1000->524288)",
+							   1000,
+							   G_MAXINT, /* FIXME: Is this reasonable? */
+							   DEFAULT_MAX_BUCKET_COUNT,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_MIN_BUCKET_COUNT,
+					 g_param_spec_int ("min-bucket-count",
+							   "Minimum bucket count",
+							   "Minimum bucket count (1000->65536)",
+							   1000,
+							   G_MAXINT,
+							   DEFAULT_MIN_BUCKET_COUNT,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_DIVISIONS,
+					 g_param_spec_int ("divisions",
+							   "Divisions",
+							   "Number of divisions of the index file (1->64)",
+							   1,
+							   64,
+							   DEFAULT_DIVISIONS,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_BUCKET_RATIO,
+					 g_param_spec_int ("bucket-ratio",
+							   "Bucket Ratio",
+							   "Number of used records to buckets ratio "
+							   "when optimizing the index "
+							   "(0=50%, 1=100%, 2=200%, 3=300%, 4=400%)",
+							   0,
+							   4,
+							   DEFAULT_BUCKET_RATIO,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_PADDING,
+					 g_param_spec_int ("padding",
+							   "Padding",
+							   "How much space is used to prevent "
+							   "index relocations, higher values use "
+							   "more disk space (1->8)",
+							   1,
+							   8,
+							   DEFAULT_PADDING,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+	g_object_class_install_property (object_class,
+					 PROP_THREAD_STACK_SIZE,
+					 g_param_spec_int ("thread-stack-size",
+							   "Thread stack size",
+							   "Thread stack size to use inside tracker. "
+							   "Use this carefully, as it may lead to misterious crashes. "
+							   "The default is 0, which uses the default for the platform.",
+							   0, G_MAXINT,
+							   DEFAULT_THREAD_STACK_SIZE,
+							   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_type_class_add_private (object_class, sizeof (TrackerConfigPriv));
+}
+
+static void
+tracker_config_init (TrackerConfig *config)
+{
+}
+
+static void
+config_finalize (GObject *object)
+{
+	TrackerConfigPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	(G_OBJECT_CLASS (tracker_config_parent_class)->finalize) (object);
+}
+
+static void
+config_get_property (GObject	*object,
+		     guint	 param_id,
+		     GValue	*value,
+		     GParamSpec *pspec)
+{
+	TrackerConfigPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	switch (param_id) {
+		/* General */
+	case PROP_VERBOSITY:
+		g_value_set_int (value, priv->verbosity);
+		break;
+	case PROP_INITIAL_SLEEP:
+		g_value_set_int (value, priv->initial_sleep);
+		break;
+	case PROP_LOW_MEMORY_MODE:
+		g_value_set_boolean (value, priv->low_memory_mode);
+		break;
+
+		/* Watches */
+	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:
+		g_value_set_boolean (value, priv->enable_watches);
+		break;
+
+		/* Indexing */
+	case PROP_THROTTLE:
+		g_value_set_int (value, priv->throttle);
+		break;
+	case PROP_ENABLE_INDEXING:
+		g_value_set_boolean (value, priv->enable_indexing);
+		break;
+	case PROP_ENABLE_CONTENT_INDEXING:
+		g_value_set_boolean (value, priv->enable_content_indexing);
+		break;
+	case PROP_ENABLE_THUMBNAILS:
+		g_value_set_boolean (value, priv->enable_thumbnails);
+		break;
+	case PROP_FAST_MERGES:
+		g_value_set_boolean (value, priv->fast_merges);
+		break;
+	case PROP_NO_INDEX_FILE_TYPES:
+		g_value_set_pointer (value, priv->no_index_file_types);
+		break;
+	case PROP_MIN_WORD_LENGTH:
+		g_value_set_int (value, priv->min_word_length);
+		break;
+	case PROP_MAX_WORD_LENGTH:
+		g_value_set_int (value, priv->max_word_length);
+		break;
+	case PROP_LANGUAGE:
+		g_value_set_string (value, priv->language);
+		break;
+	case PROP_ENABLE_STEMMER:
+		g_value_set_boolean (value, priv->enable_stemmer);
+		break;
+	case PROP_SKIP_MOUNT_POINTS:
+		g_value_set_boolean (value, priv->skip_mount_points);
+		break;
+	case PROP_DISABLE_INDEXING_ON_BATTERY:
+		g_value_set_boolean (value, priv->disable_indexing_on_battery);
+		break;
+	case PROP_DISABLE_INDEXING_ON_BATTERY_INIT:
+		g_value_set_boolean (value, priv->disable_indexing_on_battery_init);
+		break;
+	case PROP_LOW_DISK_SPACE_LIMIT:
+		g_value_set_int (value, priv->low_disk_space_limit);
+		break;
+
+		/* Emails */
+	case PROP_INDEX_EVOLUTION_EMAILS:
+		g_value_set_boolean (value, priv->index_evolution_emails);
+		break;
+	case PROP_INDEX_KMAIL_EMAILS:
+		g_value_set_boolean (value, priv->index_kmail_emails);
+		break;
+	case PROP_INDEX_THUNDERBIRD_EMAILS:
+		g_value_set_boolean (value, priv->index_thunderbird_emails);
+		break;
+
+		/* Performance */
+	case PROP_MAX_TEXT_TO_INDEX:
+		g_value_set_int (value, priv->max_text_to_index);
+		break;
+	case PROP_MAX_WORDS_TO_INDEX:
+		g_value_set_int (value, priv->max_words_to_index);
+		break;
+	case PROP_OPTIMIZATION_SWEEP_COUNT:
+		g_value_set_int (value, priv->optimization_sweep_count);
+		break;
+	case PROP_MAX_BUCKET_COUNT:
+		g_value_set_int (value, priv->max_bucket_count);
+		break;
+	case PROP_MIN_BUCKET_COUNT:
+		g_value_set_int (value, priv->min_bucket_count);
+		break;
+	case PROP_DIVISIONS:
+		g_value_set_int (value, priv->divisions);
+		break;
+	case PROP_BUCKET_RATIO:
+		g_value_set_int (value, priv->bucket_ratio);
+		break;
+	case PROP_PADDING:
+		g_value_set_int (value, priv->padding);
+		break;
+	case PROP_THREAD_STACK_SIZE:
+		g_value_set_int (value, priv->thread_stack_size);
+		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)
+{
+	TrackerConfigPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	switch (param_id) {
+		/* General */
+	case PROP_VERBOSITY:
+		tracker_config_set_verbosity (TRACKER_CONFIG (object),
+					      g_value_get_int (value));
+		break;
+	case PROP_INITIAL_SLEEP:
+		tracker_config_set_initial_sleep (TRACKER_CONFIG (object),
+						  g_value_get_int (value));
+		break;
+	case PROP_LOW_MEMORY_MODE:
+		tracker_config_set_low_memory_mode (TRACKER_CONFIG (object),
+						    g_value_get_boolean (value));
+		break;
+
+		/* Watches */
+	case PROP_WATCH_DIRECTORY_ROOTS:    /* Not writable */
+	case PROP_CRAWL_DIRECTORY_ROOTS:    /* Not writable */
+	case PROP_NO_WATCH_DIRECTORY_ROOTS: /* Not writable */
+		break;
+	case PROP_ENABLE_WATCHES:
+		tracker_config_set_enable_watches (TRACKER_CONFIG (object),
+						   g_value_get_boolean (value));
+		break;
+
+		/* Indexing */
+	case PROP_THROTTLE:
+		tracker_config_set_throttle (TRACKER_CONFIG (object),
+					     g_value_get_int (value));
+		break;
+	case PROP_ENABLE_INDEXING:
+		tracker_config_set_enable_indexing (TRACKER_CONFIG (object),
+						    g_value_get_boolean (value));
+		break;
+	case PROP_ENABLE_CONTENT_INDEXING:
+		tracker_config_set_enable_content_indexing (TRACKER_CONFIG (object),
+							    g_value_get_boolean (value));
+		break;
+	case PROP_ENABLE_THUMBNAILS:
+		tracker_config_set_enable_thumbnails (TRACKER_CONFIG (object),
+						      g_value_get_boolean (value));
+		break;
+	case PROP_FAST_MERGES:
+		tracker_config_set_fast_merges (TRACKER_CONFIG (object),
+						g_value_get_boolean (value));
+		break;
+	case PROP_NO_INDEX_FILE_TYPES:	    /* Not writable */
+		break;
+	case PROP_MIN_WORD_LENGTH:
+		tracker_config_set_min_word_length (TRACKER_CONFIG (object),
+						    g_value_get_int (value));
+		break;
+	case PROP_MAX_WORD_LENGTH:
+		tracker_config_set_max_word_length (TRACKER_CONFIG (object),
+						    g_value_get_int (value));
+		break;
+	case PROP_LANGUAGE:
+		tracker_config_set_language (TRACKER_CONFIG (object),
+					     g_value_get_string (value));
+		break;
+	case PROP_ENABLE_STEMMER:
+		tracker_config_set_enable_stemmer (TRACKER_CONFIG (object),
+						   g_value_get_boolean (value));
+		break;
+	case PROP_SKIP_MOUNT_POINTS:
+		tracker_config_set_skip_mount_points (TRACKER_CONFIG (object),
+						      g_value_get_boolean (value));
+		break;
+	case PROP_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:
+		tracker_config_set_disable_indexing_on_battery_init (TRACKER_CONFIG (object),
+								     g_value_get_boolean (value));
+		break;
+	case PROP_LOW_DISK_SPACE_LIMIT:
+		tracker_config_set_low_disk_space_limit (TRACKER_CONFIG (object),
+							 g_value_get_int (value));
+		break;
+
+		/* Emails */
+	case PROP_INDEX_EVOLUTION_EMAILS:
+		tracker_config_set_index_evolution_emails (TRACKER_CONFIG (object),
+							   g_value_get_boolean (value));
+		break;
+	case PROP_INDEX_KMAIL_EMAILS:
+		tracker_config_set_index_kmail_emails (TRACKER_CONFIG (object),
+						       g_value_get_boolean (value));
+		break;
+	case PROP_INDEX_THUNDERBIRD_EMAILS:
+		tracker_config_set_index_thunderbird_emails (TRACKER_CONFIG (object),
+							     g_value_get_boolean (value));
+		break;
+
+		/* Performance */
+	case PROP_MAX_TEXT_TO_INDEX:
+		tracker_config_set_max_text_to_index (TRACKER_CONFIG (object),
+						      g_value_get_int (value));
+		break;
+	case PROP_MAX_WORDS_TO_INDEX:
+		tracker_config_set_max_words_to_index (TRACKER_CONFIG (object),
+						       g_value_get_int (value));
+		break;
+	case PROP_OPTIMIZATION_SWEEP_COUNT:
+		tracker_config_set_optimization_sweep_count (TRACKER_CONFIG (object),
+							     g_value_get_int (value));
+		break;
+	case PROP_MAX_BUCKET_COUNT:
+		tracker_config_set_max_bucket_count (TRACKER_CONFIG (object),
+						     g_value_get_int (value));
+		break;
+	case PROP_MIN_BUCKET_COUNT:
+		tracker_config_set_min_bucket_count (TRACKER_CONFIG (object),
+						     g_value_get_int (value));
+		break;
+	case PROP_DIVISIONS:
+		tracker_config_set_divisions (TRACKER_CONFIG (object),
+					      g_value_get_int (value));
+		break;
+	case PROP_BUCKET_RATIO:
+		tracker_config_set_bucket_ratio (TRACKER_CONFIG (object),
+						 g_value_get_int (value));
+		break;
+	case PROP_PADDING:
+		tracker_config_set_padding (TRACKER_CONFIG (object),
+					    g_value_get_int (value));
+		break;
+	case PROP_THREAD_STACK_SIZE:
+		tracker_config_set_thread_stack_size (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 gchar *
+config_dir_validate_name (const gchar *original_path)
+{
+	gchar resolved_path[PATH_MAX + 2];
+
+	if (!original_path || original_path[0] == '\0') {
+		return NULL;
+	}
+
+	if (original_path[0] == '~') {
+		const char *home = g_get_home_dir ();
+
+		if (!home || home[0] == '\0') {
+			return NULL;
+		}
+
+		return g_build_path (G_DIR_SEPARATOR_S,
+				     home,
+				     original_path + 1,
+				     NULL);
+	}
+
+	return g_strdup (realpath (original_path, resolved_path));
+}
+
+static gboolean
+config_dir_is_child_of (const char *dir,
+			const char *dir_to_test)
+{
+	gchar	 *path;
+	gboolean  result;
+
+	if (!dir_to_test) {
+		return FALSE;
+	}
+
+	if (dir[strlen (dir)-1] != '/') {
+		path = g_strconcat (dir, "/", NULL);
+	} else {
+		path = g_strdup (dir);
+	}
+
+	result = g_str_has_prefix (dir_to_test, path);
+	g_free (path);
+
+	return result;
+}
+
+static void
+config_dir_check_roots_for_conflicts (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+	GSList		  *final_list = NULL;
+	GSList		  *l1, *l2;
+
+	priv = GET_PRIV (config);
+
+	for (l1 = priv->watch_directory_roots; l1; l1 = l1->next) {
+		gboolean add = TRUE;
+
+		if (!final_list) {
+			final_list = g_slist_prepend (NULL, l1->data);
+			continue;
+		}
+
+		for (l2 = final_list; l2 && add; l2 = l2->next) {
+			if (!l2->data) {
+				continue;
+			}
+
+			/* Is new directory a child of another in
+			 * current list already?
+			 */
+			if (config_dir_is_child_of (l2->data, l1->data)) {
+				add = FALSE;
+				continue;
+			}
+
+			/* Is current directory a child of the new
+			 * directory we are adding?
+			 */
+			if (config_dir_is_child_of (l1->data, l2->data)) {
+				l2->data = NULL;
+			}
+		}
+
+		if (add) {
+			final_list = g_slist_prepend (final_list, l1->data);
+		}
+	}
+
+	g_slist_free (priv->watch_directory_roots);
+	priv->watch_directory_roots = NULL;
+
+	for (l1 = final_list; l1; l1 = l1->next) {
+		gchar *root;
+
+		root = l1->data;
+
+		if (!root || root[0] != G_DIR_SEPARATOR) {
+			continue;
+		}
+
+		priv->watch_directory_roots =
+			g_slist_prepend (priv->watch_directory_roots, root);
+	}
+
+	priv->watch_directory_roots = g_slist_reverse (priv->watch_directory_roots);
+	g_slist_free (final_list);
+}
+
+static gboolean
+config_create_with_defaults (const gchar *filename)
+{
+	GKeyFile     *key_file;
+	GError	     *error = NULL;
+	gchar	     *content = NULL;
+	gchar	     *language;
+	const gchar  *watch_directory_roots[2] = { NULL, NULL };
+	const gchar  *empty_string_list[] = { NULL };
+
+	key_file = g_key_file_new ();
+
+	/* Get default values */
+	language = tracker_language_get_default_code ();
+
+	watch_directory_roots[0] = g_get_home_dir ();
+
+	/* General */
+	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);
+	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);
+	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);
+
+	/* Watches */
+	g_key_file_set_string_list (key_file, GROUP_WATCHES, KEY_WATCH_DIRECTORY_ROOTS,
+				    watch_directory_roots, 1);
+	g_key_file_set_comment (key_file, GROUP_WATCHES, KEY_WATCH_DIRECTORY_ROOTS,
+				" List of directory roots to index and watch (separator=;)",
+				NULL);
+	g_key_file_set_string_list (key_file, GROUP_WATCHES, KEY_CRAWL_DIRECTORY_ROOTS,
+				    empty_string_list, 0);
+	g_key_file_set_comment (key_file, GROUP_WATCHES, KEY_CRAWL_DIRECTORY_ROOTS,
+				" List of directory roots to index but NOT watch (separator=;)",
+				NULL);
+	g_key_file_set_string_list (key_file, GROUP_WATCHES, KEY_NO_WATCH_DIRECTORY_ROOTS,
+				    empty_string_list, 0);
+	g_key_file_set_comment (key_file, GROUP_WATCHES, KEY_NO_WATCH_DIRECTORY_ROOTS,
+				" List of directory roots NOT to index and NOT to watch (separator=;)",
+				NULL);
+	g_key_file_set_boolean (key_file, GROUP_WATCHES, KEY_ENABLE_WATCHES, DEFAULT_ENABLE_WATCHES);
+	g_key_file_set_comment (key_file, GROUP_WATCHES, KEY_ENABLE_WATCHES,
+				" Set to false to completely disable any watching",
+				NULL);
+
+	/* Indexing */
+	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);
+
+	g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_ENABLE_INDEXING, DEFAULT_ENABLE_INDEXING);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_ENABLE_INDEXING,
+				" Set to false to completely disable any indexing",
+				NULL);
+	g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_ENABLE_CONTENT_INDEXING, DEFAULT_ENABLE_CONTENT_INDEXING);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_ENABLE_CONTENT_INDEXING,
+				" Set to false to completely disable file content indexing",
+				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);
+	g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_FAST_MERGES, DEFAULT_FAST_MERGES);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_FAST_MERGES,
+				" Set to false to NOT hog the disk for extended periods",
+				NULL);
+	g_key_file_set_string_list (key_file, GROUP_INDEXING, KEY_NO_INDEX_FILE_TYPES,
+				    empty_string_list, 0);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_NO_INDEX_FILE_TYPES,
+				" List of partial file pattern globs (separator=;)\n"
+				" This is for files to NOT index\n"
+				" (basic stat info is only extended for files that match the patterns)",
+				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);
+	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);
+	g_key_file_set_string (key_file, GROUP_INDEXING, KEY_LANGUAGE, language);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_LANGUAGE,
+				" Set the language specific stemmer and stopword list to use\n"
+				" Values include:\n"
+				" - en (English)\n"
+				" - da (Danish)\n"
+				" - nl (Dutch)\n"
+				" - fi (Finish)\n"
+				" - fr (French)\n"
+				" - de (German)\n"
+				" - it (Italian)\n"
+				" - nb (Norwegian)\n"
+				" - pt (Portugese)\n"
+				" - ru (Russian)\n"
+				" - es (Spanish)\n"
+				" - sv (Swedish)",
+				NULL);
+	g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_ENABLE_STEMMER, DEFAULT_ENABLE_STEMMER);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_ENABLE_STEMMER,
+				" Set to false to disable language specific stemmer",
+				NULL);
+	g_key_file_set_boolean (key_file, GROUP_INDEXING, KEY_SKIP_MOUNT_POINTS, DEFAULT_SKIP_MOUNT_POINTS);
+	g_key_file_set_comment (key_file, GROUP_INDEXING, KEY_SKIP_MOUNT_POINTS,
+				" Set to true to disable traversing directories on mount points",
+				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_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_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);
+
+	/* Emails */
+	g_key_file_set_boolean (key_file, GROUP_EMAILS, KEY_INDEX_EVOLUTION_EMAILS, DEFAULT_INDEX_EVOLUTION_EMAILS);
+	g_key_file_set_boolean (key_file, GROUP_EMAILS, KEY_INDEX_KMAIL_EMAILS, DEFAULT_INDEX_KMAIL_EMAILS);
+	g_key_file_set_boolean (key_file, GROUP_EMAILS, KEY_INDEX_THUNDERBIRD_EMAILS, DEFAULT_INDEX_THUNDERBIRD_EMAILS);
+
+	/* Performance */
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_MAX_TEXT_TO_INDEX, DEFAULT_MAX_TEXT_TO_INDEX);
+	g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_MAX_TEXT_TO_INDEX,
+				" Maximum text size in bytes to index from a file's content",
+				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);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_OPTIMIZATION_SWEEP_COUNT, DEFAULT_OPTIMIZATION_SWEEP_COUNT);
+	g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_OPTIMIZATION_SWEEP_COUNT,
+				" Number of entities to index before deciding to trying to optimize"
+				" (1000->10000)",
+				NULL);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_MAX_BUCKET_COUNT, DEFAULT_MAX_BUCKET_COUNT);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_MIN_BUCKET_COUNT, DEFAULT_MIN_BUCKET_COUNT);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_DIVISIONS, DEFAULT_DIVISIONS);
+	g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_DIVISIONS,
+				" Number of divisions of the index file (1->64, default=4)",
+				NULL);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_BUCKET_RATIO, DEFAULT_BUCKET_RATIO);
+	g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_BUCKET_RATIO,
+				" Number of used records to buckets ratio when optimising the index.\n"
+				" (0=50%, 1=100%, 2=200%, 3=300%, 4=400%)",
+				NULL);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_PADDING, DEFAULT_PADDING);
+	g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_PADDING,
+				" How much space is used to prevent index relocations.\n"
+				" Higher values improve indexing speed but waste more disk space.\n"
+				" Values should be between 1 and 8.",
+				NULL);
+	g_key_file_set_integer (key_file, GROUP_PERFORMANCE, KEY_THREAD_STACK_SIZE, DEFAULT_THREAD_STACK_SIZE);
+	g_key_file_set_comment (key_file, GROUP_PERFORMANCE, KEY_THREAD_STACK_SIZE,
+				" Stack size to use in threads inside Tracker.\n"
+				" Use this carefully, or expect misterious crashes.\n"
+				" 0 uses the default stack size for this platform",
+				NULL);
+
+	content = g_key_file_to_data (key_file, NULL, &error);
+	g_free (language);
+	g_key_file_free (key_file);
+
+	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 ("Writting default configuration to file:'%s'\n", filename);
+	g_free (content);
+
+	return TRUE;
+}
+
+static GSList *
+config_string_list_to_gslist (const gchar **value,
+			      gboolean	    is_directory_list)
+{
+	GSList *list = NULL;
+	gint	i;
+
+	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 = config_dir_validate_name (str);
+		if (validated) {
+			list = g_slist_prepend (list, validated);
+		}
+	}
+
+	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_clear_error (&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_clear_error (&error);
+	}
+}
+
+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_clear_error (&error);
+	}
+
+	g_free (value);
+}
+
+static void
+config_load_string_list (TrackerConfig *config,
+			 const gchar   *property,
+			 GKeyFile      *key_file,
+			 const gchar   *group,
+			 const gchar   *key)
+{
+	TrackerConfigPriv  *priv;
+	gchar		  **value;
+
+	priv = GET_PRIV (config);
+
+	value = g_key_file_get_string_list (key_file, group, key, NULL, NULL);
+
+	if (strcmp (property, "watch-directory-roots") == 0) {
+		if (!value) {
+			priv->watch_directory_roots =
+				g_slist_prepend (NULL, g_strdup (g_get_home_dir ()));
+		} else {
+			priv->watch_directory_roots =
+				config_string_list_to_gslist ((const gchar **) value, TRUE);
+		}
+
+		/* We only do this for watch directory roots right now, not
+		 * sure why.
+		 */
+		config_dir_check_roots_for_conflicts (config);
+	}
+	else if (strcmp (property, "crawl-directory-roots") == 0) {
+		if (value) {
+			priv->crawl_directory_roots =
+				config_string_list_to_gslist ((const gchar **) value, TRUE);
+		}
+	}
+	else if (strcmp (property, "no-watch-directory-roots") == 0) {
+		if (value) {
+			priv->no_watch_directory_roots =
+				config_string_list_to_gslist ((const gchar **) value, TRUE);
+		}
+	}
+	else if (strcmp (property, "no-index-file-types") == 0) {
+		if (value) {
+			priv->no_index_file_types =
+				config_string_list_to_gslist ((const gchar **) value, FALSE);
+		}
+	}
+	else {
+		g_warning ("Property '%s' not recognized to set string list from key '%s'",
+			   property, key);
+	}
+
+	g_strfreev (value);
+}
+
+static void
+config_load (TrackerConfig *config)
+{
+	GKeyFile *key_file;
+	GError	 *error = NULL;
+	gchar	 *filename;
+	gchar	 *directory;
+
+	key_file = g_key_file_new ();
+
+	/* 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;
+	}
+
+	filename = g_build_filename (directory, "tracker.cfg", NULL);
+	g_free (directory);
+
+	/* Load options */
+	g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, &error);
+	if (error) {
+		config_create_with_defaults (filename);
+		g_clear_error (&error);
+	}
+
+	g_free (filename);
+
+	/* General */
+	config_load_int (config, "verbosity", key_file, GROUP_GENERAL, KEY_VERBOSITY);
+	config_load_int (config, "initial-sleep", key_file, GROUP_GENERAL, KEY_INITIAL_SLEEP);
+	config_load_boolean (config, "low-memory-mode", key_file, GROUP_GENERAL, KEY_LOW_MEMORY_MODE);
+
+	/* Watches */
+	config_load_string_list (config, "watch-directory-roots", key_file, GROUP_WATCHES, KEY_WATCH_DIRECTORY_ROOTS);
+	config_load_string_list (config, "crawl-directory-roots", key_file, GROUP_WATCHES, KEY_CRAWL_DIRECTORY_ROOTS);
+	config_load_string_list (config, "no-watch-directory-roots", key_file, GROUP_WATCHES, KEY_NO_WATCH_DIRECTORY_ROOTS);
+	config_load_boolean (config, "enable-watches", key_file, GROUP_WATCHES, KEY_ENABLE_WATCHES);
+
+	/* Indexing */
+	config_load_int (config, "throttle", key_file, GROUP_INDEXING, KEY_THROTTLE);
+	config_load_boolean (config, "enable-indexing", key_file, GROUP_INDEXING, KEY_ENABLE_INDEXING);
+	config_load_boolean (config, "enable-content-indexing", key_file, GROUP_INDEXING, KEY_ENABLE_CONTENT_INDEXING);
+	config_load_boolean (config, "enable-thumbnails", key_file, GROUP_INDEXING, KEY_ENABLE_THUMBNAILS);
+	config_load_boolean (config, "fast-merges", key_file, GROUP_INDEXING, KEY_FAST_MERGES);
+	config_load_string_list (config, "no-index-file-types", key_file, GROUP_INDEXING, KEY_NO_INDEX_FILE_TYPES);
+	config_load_int (config, "min-word-length", key_file, GROUP_INDEXING, KEY_MIN_WORD_LENGTH);
+	config_load_int (config, "max-word-length", key_file, GROUP_INDEXING, KEY_MAX_WORD_LENGTH);
+	config_load_string (config, "language", key_file, GROUP_INDEXING, KEY_LANGUAGE);
+	config_load_boolean (config, "enable-stemmer", key_file, GROUP_INDEXING, KEY_ENABLE_STEMMER);
+	config_load_boolean (config, "skip-mount-points", key_file, GROUP_INDEXING, KEY_SKIP_MOUNT_POINTS);
+	config_load_boolean (config, "disable-indexing-on-battery", key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY);
+	config_load_boolean (config, "disable-indexing-on-battery-init", key_file, GROUP_INDEXING, KEY_DISABLE_INDEXING_ON_BATTERY_INIT);
+	config_load_int (config, "low-disk-space-limit", key_file, GROUP_INDEXING, KEY_LOW_DISK_SPACE_LIMIT);
+
+	/* Emails */
+	config_load_boolean (config, "index-evolution-emails", key_file, GROUP_EMAILS, KEY_INDEX_EVOLUTION_EMAILS);
+	config_load_boolean (config, "index-kmail-emails", key_file, GROUP_EMAILS, KEY_INDEX_KMAIL_EMAILS);
+	config_load_boolean (config, "index-thunderbird-emails", key_file, GROUP_EMAILS, KEY_INDEX_THUNDERBIRD_EMAILS);
+
+	/* Performance */
+	config_load_int (config, "max-text-to-index", key_file, GROUP_PERFORMANCE, KEY_MAX_TEXT_TO_INDEX);
+	config_load_int (config, "max-words-to-index", key_file, GROUP_PERFORMANCE, KEY_MAX_WORDS_TO_INDEX);
+	config_load_int (config, "optimization-sweep-count", key_file, GROUP_PERFORMANCE, KEY_OPTIMIZATION_SWEEP_COUNT);
+	config_load_int (config, "max-bucket-count", key_file, GROUP_PERFORMANCE, KEY_MAX_BUCKET_COUNT);
+	config_load_int (config, "min-bucket-count", key_file, GROUP_PERFORMANCE, KEY_MIN_BUCKET_COUNT);
+	config_load_int (config, "divisions", key_file, GROUP_PERFORMANCE, KEY_DIVISIONS);
+	config_load_int (config, "bucket-ratio", key_file, GROUP_PERFORMANCE, KEY_BUCKET_RATIO);
+	config_load_int (config, "padding", key_file, GROUP_PERFORMANCE, KEY_PADDING);
+	config_load_int (config, "thread-stack-size", key_file, GROUP_PERFORMANCE, KEY_THREAD_STACK_SIZE);
+
+	g_key_file_free (key_file);
+}
+
+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;
+}
+
+TrackerConfig *
+tracker_config_new (void)
+{
+	TrackerConfig *config;
+
+	config = g_object_new (TRACKER_TYPE_CONFIG, NULL);
+	config_load (config);
+
+	return config;
+}
+
+gint
+tracker_config_get_verbosity (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_VERBOSITY);
+
+	priv = GET_PRIV (config);
+
+	return priv->verbosity;
+}
+
+gint
+tracker_config_get_initial_sleep (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_INITIAL_SLEEP);
+
+	priv = GET_PRIV (config);
+
+	return priv->initial_sleep;
+}
+
+gboolean
+tracker_config_get_low_memory_mode (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_LOW_MEMORY_MODE);
+
+	priv = GET_PRIV (config);
+
+	return priv->low_memory_mode;
+}
+
+GSList *
+tracker_config_get_watch_directory_roots (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
+
+	priv = GET_PRIV (config);
+
+	return priv->watch_directory_roots;
+}
+
+GSList *
+tracker_config_get_crawl_directory_roots (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
+
+	priv = GET_PRIV (config);
+
+	return priv->crawl_directory_roots;
+}
+
+GSList *
+tracker_config_get_no_watch_directory_roots (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
+
+	priv = GET_PRIV (config);
+
+	return priv->no_watch_directory_roots;
+}
+
+gboolean
+tracker_config_get_enable_watches (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_ENABLE_WATCHES);
+
+	priv = GET_PRIV (config);
+
+	return priv->enable_watches;
+}
+
+gint
+tracker_config_get_throttle (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_THROTTLE);
+
+	priv = GET_PRIV (config);
+
+	return priv->throttle;
+}
+
+gboolean
+tracker_config_get_enable_indexing (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_ENABLE_INDEXING);
+
+	priv = GET_PRIV (config);
+
+	return priv->enable_indexing;
+}
+
+gboolean
+tracker_config_get_enable_content_indexing (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_ENABLE_CONTENT_INDEXING);
+
+	priv = GET_PRIV (config);
+
+	return priv->enable_content_indexing;
+}
+
+gboolean
+tracker_config_get_enable_thumbnails (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_ENABLE_THUMBNAILS);
+
+	priv = GET_PRIV (config);
+
+	return priv->enable_thumbnails;
+}
+
+gboolean
+tracker_config_get_fast_merges (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_FAST_MERGES);
+
+	priv = GET_PRIV (config);
+
+	return priv->fast_merges;
+}
+
+GSList *
+tracker_config_get_no_index_file_types (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
+
+	priv = GET_PRIV (config);
+
+	return priv->no_index_file_types;
+}
+
+gint
+tracker_config_get_min_word_length (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_MIN_WORD_LENGTH);
+
+	priv = GET_PRIV (config);
+
+	return priv->min_word_length;
+}
+
+gint
+tracker_config_get_max_word_length (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_MAX_WORD_LENGTH);
+
+	priv = GET_PRIV (config);
+
+	return priv->max_word_length;
+}
+
+const gchar *
+tracker_config_get_language (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), "en");
+
+	priv = GET_PRIV (config);
+
+	return priv->language;
+}
+
+gboolean
+tracker_config_get_enable_stemmer (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_ENABLE_STEMMER);
+
+	priv = GET_PRIV (config);
+
+	return priv->enable_stemmer;
+}
+
+gboolean
+tracker_config_get_skip_mount_points (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_SKIP_MOUNT_POINTS);
+
+	priv = GET_PRIV (config);
+
+	return priv->skip_mount_points;
+}
+
+gboolean
+tracker_config_get_disable_indexing_on_battery (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_DISABLE_INDEXING_ON_BATTERY);
+
+	priv = GET_PRIV (config);
+
+	return priv->disable_indexing_on_battery;
+}
+
+gboolean
+tracker_config_get_disable_indexing_on_battery_init (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_DISABLE_INDEXING_ON_BATTERY_INIT);
+
+	priv = GET_PRIV (config);
+
+	return priv->disable_indexing_on_battery_init;
+}
+
+gint
+tracker_config_get_low_disk_space_limit (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_LOW_DISK_SPACE_LIMIT);
+
+	priv = GET_PRIV (config);
+
+	return priv->low_disk_space_limit;
+}
+
+gboolean
+tracker_config_get_index_evolution_emails (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_INDEX_EVOLUTION_EMAILS);
+
+	priv = GET_PRIV (config);
+
+	return priv->index_evolution_emails;
+}
+
+gboolean
+tracker_config_get_index_kmail_emails (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_INDEX_KMAIL_EMAILS);
+
+	priv = GET_PRIV (config);
+
+	return priv->index_kmail_emails;
+}
+
+gboolean
+tracker_config_get_index_thunderbird_emails (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_INDEX_THUNDERBIRD_EMAILS);
+
+	priv = GET_PRIV (config);
+
+	return priv->index_thunderbird_emails;
+}
+
+gint
+tracker_config_get_max_text_to_index (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_MAX_TEXT_TO_INDEX);
+
+	priv = GET_PRIV (config);
+
+	return priv->max_text_to_index;
+}
+
+gint
+tracker_config_get_max_words_to_index (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_MAX_WORDS_TO_INDEX);
+
+	priv = GET_PRIV (config);
+
+	return priv->max_words_to_index;
+}
+
+gint
+tracker_config_get_optimization_sweep_count (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_OPTIMIZATION_SWEEP_COUNT);
+
+	priv = GET_PRIV (config);
+
+	return priv->optimization_sweep_count;
+}
+
+gint
+tracker_config_get_max_bucket_count (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_MAX_BUCKET_COUNT);
+
+	priv = GET_PRIV (config);
+
+	return priv->max_bucket_count;
+}
+
+gint
+tracker_config_get_min_bucket_count (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_MIN_BUCKET_COUNT);
+
+	priv = GET_PRIV (config);
+
+	return priv->min_bucket_count;
+}
+
+gint
+tracker_config_get_divisions (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_DIVISIONS);
+
+	priv = GET_PRIV (config);
+
+	return priv->divisions;
+}
+
+gint
+tracker_config_get_bucket_ratio (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_BUCKET_RATIO);
+
+	priv = GET_PRIV (config);
+
+	return priv->bucket_ratio;
+}
+
+gint
+tracker_config_get_padding (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_PADDING);
+
+	priv = GET_PRIV (config);
+
+	return priv->padding;
+}
+
+gint
+tracker_config_get_thread_stack_size (TrackerConfig *config)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), DEFAULT_THREAD_STACK_SIZE);
+
+	priv = GET_PRIV (config);
+
+	return priv->thread_stack_size;
+}
+
+void
+tracker_config_set_verbosity (TrackerConfig *config,
+			      gint	     value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "verbosity", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->verbosity = value;
+	g_object_notify (G_OBJECT (config), "verbosity");
+}
+
+void
+tracker_config_set_initial_sleep (TrackerConfig *config,
+				  gint		 value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "initial-sleep", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->initial_sleep = value;
+	g_object_notify (G_OBJECT (config), "initial-sleep");
+}
+
+void
+tracker_config_set_low_memory_mode (TrackerConfig *config,
+				    gboolean	   value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->low_memory_mode = value;
+	g_object_notify (G_OBJECT (config), "low-memory-mode");
+}
+
+void
+tracker_config_set_enable_watches (TrackerConfig *config,
+				   gboolean	  value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->enable_watches = value;
+	g_object_notify (G_OBJECT (config), "enable-watches");
+}
+
+void
+tracker_config_set_throttle (TrackerConfig *config,
+			     gint	    value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "throttle", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->throttle = value;
+	g_object_notify (G_OBJECT (config), "throttle");
+}
+
+void
+tracker_config_set_enable_indexing (TrackerConfig *config,
+				    gboolean	   value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->enable_indexing = value;
+	g_object_notify (G_OBJECT (config), "enable-indexing");
+}
+
+void
+tracker_config_set_enable_content_indexing (TrackerConfig *config,
+					    gboolean	   value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->enable_content_indexing = value;
+	g_object_notify (G_OBJECT (config), "enable-content-indexing");
+}
+
+void
+tracker_config_set_enable_thumbnails (TrackerConfig *config,
+				      gboolean	     value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->enable_thumbnails = value;
+	g_object_notify (G_OBJECT (config), "enable-thumbnails");
+}
+
+void
+tracker_config_set_fast_merges (TrackerConfig *config,
+				gboolean       value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->fast_merges = value;
+	g_object_notify (G_OBJECT (config), "fast-merges");
+}
+
+void
+tracker_config_set_min_word_length (TrackerConfig *config,
+				    gint	   value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "min-word-length", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->min_word_length = value;
+	g_object_notify (G_OBJECT (config), "min-word-length");
+}
+
+void
+tracker_config_set_max_word_length (TrackerConfig *config,
+				    gint	   value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "max-word-length", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->max_word_length = value;
+	g_object_notify (G_OBJECT (config), "max-word-length");
+}
+
+void
+tracker_config_set_language (TrackerConfig *config,
+			     const gchar   *value)
+{
+	TrackerConfigPriv *priv;
+	gboolean	   use_default = FALSE;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	g_free (priv->language);
+
+	/* Validate language */
+	use_default |= !value;
+	use_default |= strlen (value) < 2;
+	use_default |= !tracker_language_check_exists (value);
+
+	if (use_default) {
+		priv->language = tracker_language_get_default_code ();
+	} else {
+		priv->language = g_strdup (value);
+	}
+
+	g_object_notify (G_OBJECT (config), "language");
+}
+
+void
+tracker_config_set_enable_stemmer (TrackerConfig *config,
+				   gboolean	  value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->enable_stemmer = value;
+	g_object_notify (G_OBJECT (config), "enable-stemmer");
+}
+
+void
+tracker_config_set_skip_mount_points (TrackerConfig *config,
+				      gboolean	     value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->skip_mount_points = value;
+	g_object_notify (G_OBJECT (config), "skip-mount-points");
+}
+
+void
+tracker_config_set_disable_indexing_on_battery (TrackerConfig *config,
+						gboolean       value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->disable_indexing_on_battery = value;
+	g_object_notify (G_OBJECT (config), "disable-indexing-on-battery");
+}
+
+void
+tracker_config_set_disable_indexing_on_battery_init (TrackerConfig *config,
+						     gboolean	    value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->disable_indexing_on_battery_init = value;
+	g_object_notify (G_OBJECT (config), "disable-indexing-on-battery-init");
+}
+
+void
+tracker_config_set_low_disk_space_limit (TrackerConfig *config,
+					 gint		value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "low-disk-space-limit", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->low_disk_space_limit = value;
+	g_object_notify (G_OBJECT (config), "low-disk-space-limit");
+}
+
+void
+tracker_config_set_index_evolution_emails (TrackerConfig *config,
+					   gboolean	  value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->index_evolution_emails = value;
+	g_object_notify (G_OBJECT (config), "index-evolution-emails");
+}
+
+void
+tracker_config_set_index_kmail_emails (TrackerConfig *config,
+				       gboolean	      value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->index_kmail_emails = value;
+	g_object_notify (G_OBJECT (config), "index-kmail-emails");
+}
+
+void
+tracker_config_set_index_thunderbird_emails (TrackerConfig *config,
+					     gboolean	    value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	priv = GET_PRIV (config);
+
+	priv->index_thunderbird_emails = value;
+	g_object_notify (G_OBJECT (config), "index-thunderbird-emails");
+}
+
+void
+tracker_config_set_max_text_to_index (TrackerConfig *config,
+				      gint	     value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "max-text-to-index", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->max_text_to_index = value;
+	g_object_notify (G_OBJECT (config), "max_text_to_index");
+}
+
+void
+tracker_config_set_max_words_to_index (TrackerConfig *config,
+				       gint	      value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "max-words-to-index", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->max_words_to_index = value;
+	g_object_notify (G_OBJECT (config), "max_words_to_index");
+}
+
+void
+tracker_config_set_optimization_sweep_count (TrackerConfig *config,
+					     gint	    value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "optimization-sweep-count", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->optimization_sweep_count = value;
+	g_object_notify (G_OBJECT (config), "optimization-sweep-count");
+}
+
+void
+tracker_config_set_max_bucket_count (TrackerConfig *config,
+				     gint	    value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "max-bucket-count", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->max_bucket_count = value;
+	g_object_notify (G_OBJECT (config), "max-bucket-count");
+}
+
+void
+tracker_config_set_min_bucket_count (TrackerConfig *config,
+				     gint	    value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "min-bucket-count", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->min_bucket_count = value;
+	g_object_notify (G_OBJECT (config), "min-bucket-count");
+}
+
+void
+tracker_config_set_divisions (TrackerConfig *config,
+			      gint	     value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "divisions", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->divisions = value;
+	g_object_notify (G_OBJECT (config), "divisions");
+}
+
+void
+tracker_config_set_bucket_ratio (TrackerConfig *config,
+				 gint		value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "bucket-ratio", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->bucket_ratio = value;
+	g_object_notify (G_OBJECT (config), "bucket-ratio");
+}
+
+void
+tracker_config_set_padding (TrackerConfig *config,
+			    gint	   value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "padding", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->padding = value;
+	g_object_notify (G_OBJECT (config), "padding");
+}
+
+void
+tracker_config_set_thread_stack_size (TrackerConfig *config,
+				      gint	     value)
+{
+	TrackerConfigPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+
+	if (!config_int_validate (config, "thread-stack-size", value)) {
+		return;
+	}
+
+	priv = GET_PRIV (config);
+
+	priv->padding = value;
+	g_object_notify (G_OBJECT (config), "thread-stack-size");
+}
+
+void
+tracker_config_add_watch_directory_roots (TrackerConfig	 *config,
+					  gchar * const	 *roots)
+{
+	TrackerConfigPriv  *priv;
+	gchar		   *validated_root;
+	gchar * const	   *p;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+	g_return_if_fail (roots != NULL);
+
+	priv = GET_PRIV (config);
+
+	for (p = roots; *p; p++) {
+		validated_root = config_dir_validate_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);
+	}
+
+	/* We only do this for watch directory roots right now, not
+	 * sure why.
+	 */
+	config_dir_check_roots_for_conflicts (config);
+
+	g_object_notify (G_OBJECT (config), "watch-directory-roots");
+}
+
+void
+tracker_config_add_crawl_directory_roots (TrackerConfig	 *config,
+					  gchar * const	 *roots)
+{
+	TrackerConfigPriv  *priv;
+	gchar		   *validated_root;
+	gchar * const	   *p;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+	g_return_if_fail (roots != NULL);
+
+	priv = GET_PRIV (config);
+
+	for (p = roots; *p; p++) {
+		validated_root = config_dir_validate_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);
+	}
+
+	g_object_notify (G_OBJECT (config), "crawl-directory-roots");
+}
+
+void
+tracker_config_add_no_watch_directory_roots (TrackerConfig  *config,
+					     gchar * const  *roots)
+{
+	TrackerConfigPriv  *priv;
+	gchar		   *validated_root;
+	gchar * const	   *p;
+
+	g_return_if_fail (TRACKER_IS_CONFIG (config));
+	g_return_if_fail (roots != NULL);
+
+	priv = GET_PRIV (config);
+
+	for (p = roots; *p; p++) {
+		validated_root = config_dir_validate_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);
+	}
+
+	g_object_notify (G_OBJECT (config), "no-watch-directory-roots");
+}
diff --git a/src/trackerd/tracker-config.h b/src/trackerd/tracker-config.h
new file mode 100644
index 0000000..5c9945e
--- /dev/null
+++ b/src/trackerd/tracker-config.h
@@ -0,0 +1,156 @@
+/* -*- 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)
+ *
+ * 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_H__
+#define __TRACKER_CONFIG_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TRACKER_TYPE_CONFIG         (tracker_config_get_type ())
+#define TRACKER_CONFIG(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_CONFIG, TrackerConfig))
+#define TRACKER_CONFIG_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_CONFIG, TrackerConfigClass))
+#define TRACKER_IS_CONFIG(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_CONFIG))
+#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;
+
+struct _TrackerConfig {
+	GObject      parent;
+};
+
+struct _TrackerConfigClass {
+	GObjectClass parent_class;
+};
+
+GType          tracker_config_get_type                             (void) G_GNUC_CONST;
+
+void           tracker_config_load_file                            (void);
+
+TrackerConfig *tracker_config_new                                  (void);
+
+gint           tracker_config_get_verbosity                        (TrackerConfig *config);
+gint           tracker_config_get_initial_sleep                    (TrackerConfig *config);
+gboolean       tracker_config_get_low_memory_mode                  (TrackerConfig *config);
+GSList *       tracker_config_get_watch_directory_roots            (TrackerConfig *config);
+GSList *       tracker_config_get_crawl_directory_roots            (TrackerConfig *config);
+GSList *       tracker_config_get_no_watch_directory_roots         (TrackerConfig *config);
+gboolean       tracker_config_get_enable_watches                   (TrackerConfig *config);
+gint           tracker_config_get_throttle                         (TrackerConfig *config);
+gboolean       tracker_config_get_enable_indexing                  (TrackerConfig *config);
+gboolean       tracker_config_get_enable_content_indexing          (TrackerConfig *config);
+gboolean       tracker_config_get_enable_thumbnails                (TrackerConfig *config);
+gboolean       tracker_config_get_fast_merges                      (TrackerConfig *config);
+GSList *       tracker_config_get_no_index_file_types              (TrackerConfig *config);
+gint           tracker_config_get_min_word_length                  (TrackerConfig *config);
+gint           tracker_config_get_max_word_length                  (TrackerConfig *config);
+const gchar *  tracker_config_get_language                         (TrackerConfig *config);
+gboolean       tracker_config_get_enable_stemmer                   (TrackerConfig *config);
+gboolean       tracker_config_get_skip_mount_points                (TrackerConfig *config);
+gboolean       tracker_config_get_disable_indexing_on_battery      (TrackerConfig *config);
+gboolean       tracker_config_get_disable_indexing_on_battery_init (TrackerConfig *config);
+gint           tracker_config_get_low_disk_space_limit             (TrackerConfig *config);
+gboolean       tracker_config_get_index_evolution_emails           (TrackerConfig *config);
+gboolean       tracker_config_get_index_kmail_emails               (TrackerConfig *config);
+gboolean       tracker_config_get_index_thunderbird_emails         (TrackerConfig *config);
+gint           tracker_config_get_max_text_to_index                (TrackerConfig *config);
+gint           tracker_config_get_max_words_to_index               (TrackerConfig *config);
+gint           tracker_config_get_optimization_sweep_count         (TrackerConfig *config);
+gint           tracker_config_get_max_bucket_count                 (TrackerConfig *config);
+gint           tracker_config_get_min_bucket_count                 (TrackerConfig *config);
+gint           tracker_config_get_divisions                        (TrackerConfig *config);
+gint           tracker_config_get_bucket_ratio                     (TrackerConfig *config);
+gint           tracker_config_get_padding                          (TrackerConfig *config);
+gint           tracker_config_get_thread_stack_size                (TrackerConfig *config);
+void           tracker_config_set_verbosity                        (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_initial_sleep                    (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_low_memory_mode                  (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_enable_watches                   (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_throttle                         (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_enable_indexing                  (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_enable_content_indexing          (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_enable_thumbnails                (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_fast_merges                      (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_min_word_length                  (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_max_word_length                  (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_language                         (TrackerConfig *config,
+								    const gchar   *value);
+void           tracker_config_set_enable_stemmer                   (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_skip_mount_points                (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_disable_indexing_on_battery      (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_disable_indexing_on_battery_init (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_low_disk_space_limit             (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_index_evolution_emails           (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_index_kmail_emails               (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_index_thunderbird_emails         (TrackerConfig *config,
+								    gboolean       value);
+void           tracker_config_set_max_text_to_index                (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_max_words_to_index               (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_optimization_sweep_count         (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_max_bucket_count                 (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_min_bucket_count                 (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_divisions                        (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_bucket_ratio                     (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_padding                          (TrackerConfig *config,
+								    gint           value);
+void           tracker_config_set_thread_stack_size                (TrackerConfig *config,
+								    gint           value);
+/* Directory root APIs*/
+void           tracker_config_add_watch_directory_roots            (TrackerConfig *config,
+								    gchar * const *roots);
+void           tracker_config_add_crawl_directory_roots            (TrackerConfig *config,
+								    gchar * const *roots);
+void           tracker_config_add_no_watch_directory_roots         (TrackerConfig *config,
+								    gchar * const *roots);
+
+G_END_DECLS
+
+#endif /* __TRACKER_CONFIG_H__ */
+
diff --git a/src/trackerd/tracker-db-sqlite.c b/src/trackerd/tracker-db-sqlite.c
index ce01f33..37d3fae 100644
--- a/src/trackerd/tracker-db-sqlite.c
+++ b/src/trackerd/tracker-db-sqlite.c
@@ -42,6 +42,7 @@
 #include "tracker-metadata.h"
 #include "tracker-utils.h"
 #include "tracker-watch.h"
+#include "tracker-config.h"
 
 #include "config.h"
 
@@ -715,7 +716,7 @@ set_params (DBConnection *db_con, int cache_size, gboolean add_functions)
 
 	char *prag;
 
-	if (tracker->use_extra_memory) {
+	if (!tracker_config_get_low_memory_mode (tracker->config)) {
 		prag = g_strdup_printf ("PRAGMA cache_size = %d", cache_size);
 	} else {
 		prag = g_strdup_printf ("PRAGMA cache_size = %d", cache_size/2);
@@ -1037,7 +1038,7 @@ tracker_db_connect (void)
 
 	tracker_db_set_default_pragmas (db_con);
 	
-	if (tracker->use_extra_memory) {
+	if (!tracker_config_get_low_memory_mode (tracker->config)) {
 		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 32");
 	} else {
 		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 16");
@@ -1348,7 +1349,7 @@ tracker_db_connect_cache (void)
 
 	tracker_db_set_default_pragmas (db_con);
 
-	if (tracker->use_extra_memory) {
+	if (!tracker_config_get_low_memory_mode (tracker->config)) {
 		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 128");
 	} else {
 		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 32");
@@ -1407,7 +1408,7 @@ tracker_db_connect_emails (void)
 
 	tracker_db_set_default_pragmas (db_con);
 
-	if (tracker->use_extra_memory) {
+	if (!tracker_config_get_low_memory_mode (tracker->config)) {
 		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 8");
 	} else {
 		tracker_db_exec_no_reply (db_con, "PRAGMA cache_size = 8");
@@ -2955,8 +2956,11 @@ tracker_db_save_file_contents (DBConnection *db_con, GHashTable *index_table, GH
 
 		if (!use_buffer) g_free (value);
 
-		if (tracker->throttle > 9) {
-			tracker_throttle (tracker->throttle * 100);
+                gint throttle;
+
+                throttle = tracker_config_get_throttle (tracker->config);
+		if (throttle > 9) {
+			tracker_throttle (throttle * 100);
 		}
 
 	}        	
diff --git a/src/trackerd/tracker-db.c b/src/trackerd/tracker-db.c
index 16f784c..e1dad8b 100644
--- a/src/trackerd/tracker-db.c
+++ b/src/trackerd/tracker-db.c
@@ -28,7 +28,7 @@
 #include "tracker-email.h"
 #include "tracker-metadata.h"
 #include "tracker-os-dependant.h"
-
+#include "tracker-config.h"
 
 extern Tracker *tracker;
 
@@ -256,7 +256,7 @@ save_meta_table_data (gpointer mtype,
 		}
 		
 	} else {
-		char **array = tracker_list_to_array (value);
+		gchar **array = tracker_gslist_to_string_list (value);
 
 		tracker_db_insert_embedded_metadata (db_action->db_con, db_action->service, db_action->file_id, mtype, array, g_slist_length (value), db_action->table);
 
@@ -631,6 +631,7 @@ restore_backup_data (gpointer mtype,
 			 gpointer user_data)
 {
 	DatabaseAction	*db_action;
+	gchar          **string_list;
 
 	if (mtype == NULL || value == NULL) {
 		return;
@@ -638,15 +639,12 @@ restore_backup_data (gpointer mtype,
 
 	db_action = user_data;
 
-	char **array = tracker_list_to_array (value);
-
+        string_list = tracker_gslist_to_string_list (value);
 	tracker_log ("restoring keyword list with %d items", g_slist_length (value));
 
-	tracker_db_set_metadata (db_action->db_con->index, db_action->service, db_action->file_id, mtype, array, g_slist_length (value), FALSE);
-
-	g_strfreev (array);
-	
+	tracker_db_set_metadata (db_action->db_con->index, db_action->service, db_action->file_id, mtype, string_list, g_slist_length (value), FALSE);
 
+	g_strfreev (string_list);
 }
 
 
@@ -737,7 +735,7 @@ tracker_db_index_service (DBConnection *db_con, FileInfo *info, const char *serv
 
 	str_file_id = tracker_uint_to_str (info->file_id);
 
-	if (get_thumbs && tracker->enable_thumbnails) {
+	if (get_thumbs && tracker_config_get_enable_thumbnails (tracker->config)) {
 		char *small_thumb_file = NULL;
 
 		small_thumb_file = tracker_metadata_get_thumbnail (info->uri, info->mime, "normal");
@@ -753,7 +751,7 @@ tracker_db_index_service (DBConnection *db_con, FileInfo *info, const char *serv
 	}
 
 
-	if (get_full_text && tracker->enable_content_indexing) {
+	if (get_full_text && tracker_config_get_enable_content_indexing (tracker->config)) {
 		char *file_as_text;
 
 		file_as_text = tracker_metadata_get_text_file (info->uri, info->mime);
diff --git a/src/trackerd/tracker-dbus-methods.c b/src/trackerd/tracker-dbus-methods.c
index f21e053..da40602 100644
--- a/src/trackerd/tracker-dbus-methods.c
+++ b/src/trackerd/tracker-dbus-methods.c
@@ -23,6 +23,7 @@
 #include "tracker-dbus-methods.h"
 #include "tracker-metadata.h"
 #include "tracker-rdf-query.h"
+#include "tracker-config.h"
 
 #include "config.h"
 
@@ -473,37 +474,34 @@ tracker_dbus_method_set_bool_option (DBusRec *rec)
 	if (strcasecmp (option, "Pause") == 0) {
 		tracker->pause_manual = value;
 	} else if (strcasecmp (option, "FastMerges") == 0) {
-		tracker->fast_merges = value;
-		tracker_log ("fast merges set to %d", value);
+		tracker_config_set_fast_merges (tracker->config, value);
+		tracker_log ("Fast merges set to %d", value);
 	} else if (strcasecmp (option, "EnableIndexing") == 0) {
-		tracker->enable_indexing = value;
+		tracker_config_set_enable_indexing (tracker->config, value);
 		tracker_log ("Enable indexing set to %d", value);
 	} else if (strcasecmp (option, "EnableWatching") == 0) {
-		tracker->enable_watching = value;
+		tracker_config_set_enable_watches (tracker->config, value);
 		tracker_log ("Enable Watching set to %d", value);
 	} else if (strcasecmp (option, "LowMemoryMode") == 0) {
-		tracker->use_extra_memory = !value;
+		tracker_config_set_low_memory_mode (tracker->config, value);
 		tracker_log ("Extra memory usage set to %d", !value);
 	} else if (strcasecmp (option, "IndexFileContents") == 0) {
-		tracker->enable_content_indexing = value;
+		tracker_config_set_enable_content_indexing (tracker->config, value);
 		tracker_log ("Index file contents set to %d", value);	
 	} else if (strcasecmp (option, "GenerateThumbs") == 0) {
-		tracker->enable_thumbnails = value;
+		tracker_config_set_enable_thumbnails (tracker->config, value);
 		tracker_log ("Generate thumbnails set to %d", value);	
 	} else if (strcasecmp (option, "SkipMountPoints") == 0) {
-		tracker->skip_mount_points = value;
+		tracker_config_set_skip_mount_points (tracker->config, value);
 		tracker_log ("Skip mounted directories set to %d", value);
 	} else if (strcasecmp (option, "EnableEvolution") == 0) {
-		tracker->index_evolution_emails = value;
+		tracker_config_set_index_evolution_emails (tracker->config, value);
 		tracker_log ("evolution support set to %d", value);
-	} else if (strcasecmp (option, "FastMerges") == 0) {
-		tracker->fast_merges = value;
-		tracker_log ("Fast merges set to %d", value);
 	} else if (strcasecmp (option, "BatteryIndex") == 0) {
-		tracker->index_on_battery = value;
+		tracker_config_set_disable_indexing_on_battery (tracker->config, !value);
 		tracker_log ("Disable index on battery set to %d", !value);
 	} else if (strcasecmp (option, "BatteryIndexInitial") == 0) {
-		tracker->index_on_battery = value;
+		tracker_config_set_disable_indexing_on_battery_init (tracker->config, !value);
 		tracker_log ("Disable initial index sweep on battery set to %d", !value);
 	}
 
@@ -544,13 +542,13 @@ tracker_dbus_method_set_int_option (DBusRec *rec)
 	}
 
 	if (strcasecmp (option, "Throttle") == 0) {
-		tracker->throttle = value;
+                tracker_config_set_throttle (tracker->config, value);
 		tracker_log ("throttle set to %d", value);
 	} else if (strcasecmp (option, "MaxText") == 0) {
-		tracker->max_index_text_length = value;
+                tracker_config_set_max_text_to_index (tracker->config, value);
 		tracker_log ("Maxinum amount of text set to %d", value);
 	} else if (strcasecmp (option, "MaxWords") == 0) {
-		tracker->max_words_to_index = value;
+                tracker_config_set_max_words_to_index (tracker->config, value);
 		tracker_log ("Maxinum number of unique words set to %d", value);
 	} 
 
diff --git a/src/trackerd/tracker-dbus-search.c b/src/trackerd/tracker-dbus-search.c
index c9d9298..ab06610 100644
--- a/src/trackerd/tracker-dbus-search.c
+++ b/src/trackerd/tracker-dbus-search.c
@@ -22,6 +22,7 @@
 #include "tracker-dbus-methods.h"
 #include "tracker-rdf-query.h"
 #include "tracker-indexer.h"
+#include "tracker-config.h"
 
 extern Tracker *tracker;
 
@@ -383,7 +384,7 @@ tracker_dbus_method_search_text_detailed (DBusRec *rec)
 
 	res = tracker_db_search_text (db_con, service, str, offset, limit, FALSE, TRUE);
 
-	if (tracker->verbosity > 0) {
+	if (tracker_config_get_verbosity (tracker->config) > 0) {
 		tracker_db_log_result (res);
 	}
 
diff --git a/src/trackerd/tracker-email-evolution.c b/src/trackerd/tracker-email-evolution.c
index 20199f2..28f05e5 100644
--- a/src/trackerd/tracker-email-evolution.c
+++ b/src/trackerd/tracker-email-evolution.c
@@ -36,7 +36,7 @@
 #include "tracker-cache.h"
 #include "tracker-dbus.h"
 #include "tracker-watch.h"
-
+#include "tracker-config.h"
 
 #define EVOLUTION_MAIL_DIR_S ".evolution/mail"
 
@@ -1243,7 +1243,13 @@ index_mail_messages_by_summary_file (DBConnection                 *db_con,
 {
 	SummaryFile *summary = NULL;
 
-	if (!tracker->is_running || !tracker->enable_indexing) return; 
+	if (!tracker->is_running) { 
+                return; 
+        }
+
+        if (!tracker_config_get_enable_indexing (tracker->config)) {
+                return;
+        }
 
 	if (open_summary_file (summary_file_path, &summary)) {
 		SummaryFileHeader *header;
@@ -1399,7 +1405,7 @@ index_mail_messages_by_summary_file (DBConnection                 *db_con,
 				}
 
 				if (tracker_db_regulate_transactions (db_con->data, 100)) {
-					if (tracker->verbosity == 1) {
+					if (tracker_config_get_verbosity (tracker->config) == 1) {
 						tracker_log ("indexing #%d - Emails in %s", tracker->index_count, dir);
 					}
 
diff --git a/src/trackerd/tracker-email-thunderbird.c b/src/trackerd/tracker-email-thunderbird.c
index 1fc4155..bdee83d 100644
--- a/src/trackerd/tracker-email-thunderbird.c
+++ b/src/trackerd/tracker-email-thunderbird.c
@@ -26,6 +26,7 @@
 #include "tracker-email-thunderbird.h"
 #include "tracker-db-email.h"
 #include "tracker-watch.h"
+#include "tracker-config.h"
 
 
 typedef enum
diff --git a/src/trackerd/tracker-email-utils.c b/src/trackerd/tracker-email-utils.c
index f40daaa..38fedd9 100644
--- a/src/trackerd/tracker-email-utils.c
+++ b/src/trackerd/tracker-email-utils.c
@@ -37,6 +37,7 @@
 #include "tracker-email-thunderbird.h"
 #include "tracker-email-kmail.h"
 #include "tracker-watch.h"
+#include "tracker-config.h"
 
 
 extern Tracker *tracker;
@@ -165,7 +166,7 @@ email_parse_mail_file_and_save_new_emails (DBConnection *db_con, MailApplication
 
 		if (tracker_db_regulate_transactions (db_con->data, 300)) {
 
-			if (tracker->verbosity == 1) {
+			if (tracker_config_get_verbosity (tracker->config) == 1) {
 				tracker_log ("indexing #%d - Emails in %s", tracker->index_count, path);
 			}
 
diff --git a/src/trackerd/tracker-email.c b/src/trackerd/tracker-email.c
index 545834f..c886ff9 100644
--- a/src/trackerd/tracker-email.c
+++ b/src/trackerd/tracker-email.c
@@ -26,7 +26,7 @@
 #include "tracker-email-evolution.h"
 #include "tracker-email-thunderbird.h"
 #include "tracker-email-kmail.h"
-
+#include "tracker-config.h"
 
 extern Tracker *tracker;
 
@@ -38,19 +38,19 @@ tracker_email_add_service_directories (DBConnection *db_con)
 
 	g_mime_init (0);
 
-	if (tracker->index_evolution_emails) {
+	if (tracker_config_get_index_evolution_emails (tracker->config)) {
 		if (evolution_init_module ()) {
 			evolution_watch_emails (db_con);
 		}
 	}
 
-	if (tracker->index_kmail_emails) {
+	if (tracker_config_get_index_kmail_emails (tracker->config)) {
 		if (kmail_init_module ()) {
 			kmail_watch_emails (db_con);
 		}
 	}
 
-	if (tracker->index_thunderbird_emails) {
+	if (tracker_config_get_index_thunderbird_emails (tracker->config)) {
 		if (thunderbird_init_module ()) {
 			thunderbird_watch_emails (db_con);
 		}
diff --git a/src/trackerd/tracker-indexer.c b/src/trackerd/tracker-indexer.c
index d5fe847..dc5366b 100644
--- a/src/trackerd/tracker-indexer.c
+++ b/src/trackerd/tracker-indexer.c
@@ -36,6 +36,7 @@
 #include "tracker-indexer.h"
 #include "tracker-cache.h"
 #include "tracker-dbus.h"
+#include "tracker-config.h"
 
 extern Tracker *tracker;
 
@@ -166,18 +167,21 @@ static int
 get_preferred_bucket_count (Indexer *indexer)
 {
 	int result;
+        gint bucket_ratio;
 
-	if (tracker->index_bucket_ratio < 1) {
+        bucket_ratio = tracker_config_get_bucket_ratio (tracker->config);
+
+	if (bucket_ratio < 1) {
 
 		result = (dprnum (indexer->word_index)/2);
 
-	} else if (tracker->index_bucket_ratio > 3) {
+	} else if (bucket_ratio > 3) {
 
 		result = (dprnum (indexer->word_index) * 4);
 
 	} else {
 
-		result = (tracker->index_bucket_ratio * dprnum (indexer->word_index));
+		result = (bucket_ratio * dprnum (indexer->word_index));
 	}
 
 	tracker_log ("Preferred bucket count is %d", result);
@@ -209,15 +213,18 @@ open_index (const gchar *name)
 	tracker_log ("Opening index %s", name);
 
 	if (strstr (name, "tmp")) {
-		word_index = dpopen (name, DP_OWRITER | DP_OCREAT | DP_ONOLCK, tracker->min_index_bucket_count);
+		word_index = dpopen (name, DP_OWRITER | DP_OCREAT | DP_ONOLCK, 
+                                     tracker_config_get_min_bucket_count (tracker->config));
 	} else {
-		word_index = dpopen (name, DP_OWRITER | DP_OCREAT | DP_ONOLCK, tracker->max_index_bucket_count);
+		word_index = dpopen (name, DP_OWRITER | DP_OCREAT | DP_ONOLCK, 
+                                     tracker_config_get_max_bucket_count (tracker->config));
 	}
 
 	if (!word_index) {
 		tracker_error ("%s index was not closed properly and caused error %s- attempting repair", name, dperrmsg (dpecode));
 		if (dprepair (name)) {
-			word_index = dpopen (name, DP_OWRITER | DP_OCREAT | DP_ONOLCK, tracker->min_index_bucket_count);
+			word_index = dpopen (name, DP_OWRITER | DP_OCREAT | DP_ONOLCK, 
+                                             tracker_config_get_min_bucket_count (tracker->config));
 		} else {
 			g_assert ("FATAL: index file is dead (suggest delete index file and restart trackerd)");
 		}
@@ -274,7 +281,9 @@ tracker_indexer_open (const gchar *name)
 	bucket_count = dpbnum (result->word_index);
 	rec_count = dprnum (result->word_index);
 
-	tracker_log ("Bucket count (max is %d) is %d and Record Count is %d", tracker->max_index_bucket_count, bucket_count, rec_count);
+	tracker_log ("Bucket count (max is %d) is %d and Record Count is %d", 
+                     tracker_config_get_max_bucket_count (tracker->config),
+                     bucket_count, rec_count);
 
 	return result;
 }
@@ -359,17 +368,11 @@ tracker_indexer_optimize (Indexer *indexer)
         }
 
 	/* set bucket count to bucket_ratio times no. of recs divided by no. of divisions */
-	num = (get_preferred_bucket_count (indexer));
-
-	if (num > tracker->max_index_bucket_count) {
-		num = tracker->max_index_bucket_count;
-	}
-
-	if (num < tracker->min_index_bucket_count) {
-		num = tracker->min_index_bucket_count;
-	}
+        num = CLAMP (get_preferred_bucket_count (indexer), 
+                     tracker_config_get_min_bucket_count (tracker->config),
+                     tracker_config_get_max_bucket_count (tracker->config));
 
-	b_count = (num / tracker->index_divisions);
+	b_count = num / tracker_config_get_divisions (tracker->config);
 	tracker_log ("No. of buckets per division is %d", b_count);
 
 	tracker_log ("Please wait while optimization of indexes takes place...");
@@ -447,7 +450,9 @@ tracker_indexer_apply_changes (Indexer *dest, Indexer *src,  gboolean update)
 		}
 
 		if (i > 1 && (i % interval == 0)) {
-			if (!tracker->fast_merges) dpsync (dest->word_index);
+			if (!tracker_config_get_fast_merges (tracker->config)) {
+                                dpsync (dest->word_index);
+                        }
 		}
 			
 		bytes = dpgetwb (src->word_index, str, -1, 0, buff_size, buffer);
@@ -691,7 +696,7 @@ tracker_indexer_merge_indexes (IndexType type)
 
 				if (i > interval && (i % interval == 0)) {
 
-					if (!tracker->fast_merges) {
+                                        if (!tracker_config_get_fast_merges (tracker->config)) {
 
 						dpsync (final_index->word_index);
 
diff --git a/src/trackerd/tracker-language.c b/src/trackerd/tracker-language.c
new file mode 100644
index 0000000..b118af9
--- /dev/null
+++ b/src/trackerd/tracker-language.c
@@ -0,0 +1,313 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008, 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 <glib.h>
+
+#include "../libstemmer/include/libstemmer.h"
+
+#include "tracker-utils.h"
+#include "tracker-language.h"
+
+typedef struct _Languages Languages;
+
+struct _TrackerLanguage {
+	GHashTable    *stop_words;
+
+	GMutex        *stemmer_mutex;
+	gpointer       stemmer;
+
+	TrackerConfig *config;
+};
+
+struct _Languages {
+        gchar *code;
+        gchar *name;
+};
+
+static Languages all_langs[] = {
+        { "da", "danish" },
+        { "nl", "dutch" },
+        { "en", "english" },
+        { "fi", "finnish" },
+        { "fr", "french" },
+        { "de", "german" },
+        { "it", "italian" },
+        { "nb", "norwegian" },
+        { "pt", "portuguese" },
+        { "ru", "russian" },
+        { "es", "spanish" },
+        { "sv", "swedish" },
+        { NULL, NULL },
+};
+
+static gchar *
+language_get_stopword_filename (const gchar *language_code)
+{
+	gchar *str;
+	gchar *filename;
+
+	str = g_strconcat (".", language_code, NULL);
+	filename = g_build_filename (TRACKER_DATADIR,
+				     "tracker",
+				     "languages",
+				     "stopwords",
+				     str,
+				     NULL);
+	g_free (str);
+
+	return filename;
+}
+
+static const gchar *
+language_get_name_for_code (const gchar *language_code)
+{
+	gint i;
+
+	if (!language_code || language_code[0] == '\0') {
+		return "english";
+	}
+
+	for (i = 0; all_langs[i].code; i++) {
+		if (g_str_has_prefix (language_code, all_langs[i].code)) {
+			return all_langs[i].name;
+		}
+	}
+
+	return "";
+}
+
+static void
+language_add_stopwords (TrackerLanguage *language,
+			const gchar     *filename)
+{
+	GMappedFile  *mapped_file;
+	GError       *error = NULL;
+	gchar        *content;
+	gchar       **words, **p;
+
+	mapped_file = g_mapped_file_new (filename, FALSE, &error);
+	if (error) {
+		tracker_log ("Tracker couldn't read stopword file:'%s', %s",
+			     filename, error->message);
+		g_clear_error (&error);
+		return;
+	}
+
+	content = g_mapped_file_get_contents (mapped_file);
+	words = g_strsplit_set (content, "\n" , -1);
+	g_free (content);
+	g_mapped_file_free (mapped_file);
+
+	/* FIXME: Shouldn't clear the hash table first? */
+	for (p = words; *p; p++) {
+		g_hash_table_insert (language->stop_words,
+				     g_strdup (g_strstrip (*p)),
+				     GINT_TO_POINTER (1));
+	}
+
+	g_strfreev (words);
+}
+
+static void
+language_set_stopword_list (TrackerLanguage *language,
+			    const gchar     *language_code)
+{
+	gchar       *stopword_filename;
+	const gchar *stem_language;
+
+	g_return_if_fail (language != NULL);
+
+	/* Set up stopwords list */
+	tracker_log ("Setting up stopword list for language code:'%s'", language_code);
+
+	stopword_filename = language_get_stopword_filename (language_code);
+	language_add_stopwords (language, stopword_filename);
+	g_free (stopword_filename);
+
+	if (!language_code || strcmp (language_code, "en") != 0) {
+		stopword_filename = language_get_stopword_filename ("en");
+		language_add_stopwords (language, stopword_filename);
+		g_free (stopword_filename);
+	}
+
+	tracker_log ("Setting up stemmer for language code:'%s'", language_code);
+
+	stem_language = language_get_name_for_code (language_code);
+
+	g_mutex_lock (language->stemmer_mutex);
+
+	if (language->stemmer) {
+		sb_stemmer_delete (language->stemmer);
+	}
+
+	language->stemmer = sb_stemmer_new (stem_language, NULL);
+	if (!language->stemmer) {
+		tracker_log ("No stemmer could be found for language:'%s'",
+			     stem_language);
+	}
+
+	g_mutex_unlock (language->stemmer_mutex);
+}
+
+static void
+language_notify_cb (TrackerConfig *config,
+		    GParamSpec    *param,
+		    gpointer       user_data)
+{
+	TrackerLanguage *language;
+
+	language = (TrackerLanguage*) user_data;
+
+	language_set_stopword_list (language,
+				    tracker_config_get_language (config));
+}
+
+TrackerLanguage *
+tracker_language_new (TrackerConfig *config)
+{
+	TrackerLanguage *language;
+	const gchar     *stem_language;
+
+	g_return_val_if_fail (TRACKER_IS_CONFIG (config), NULL);
+
+	language = g_new0 (TrackerLanguage, 1);
+
+	language->stop_words = g_hash_table_new_full (g_str_hash,
+						      g_str_equal,
+						      g_free,
+						      NULL);
+
+	language->stemmer_mutex = g_mutex_new ();
+
+	stem_language = language_get_name_for_code (NULL);
+	language->stemmer = sb_stemmer_new (stem_language, NULL);
+
+	language->config = g_object_ref (config);
+
+	g_signal_connect (language->config, "notify::language",
+			  G_CALLBACK (language_notify_cb),
+			  language);
+
+	return language;
+}
+
+void
+tracker_language_free (TrackerLanguage *language)
+{
+	if (!language) {
+		return;
+	}
+
+	g_signal_handlers_disconnect_by_func (language->config,
+					      language_notify_cb,
+					      language);
+	g_object_unref (language->config);
+
+	if (language->stemmer) {
+		g_mutex_lock (language->stemmer_mutex);
+		sb_stemmer_delete (language->stemmer);
+		g_mutex_unlock (language->stemmer_mutex);
+	}
+
+	g_mutex_free (language->stemmer_mutex);
+
+	g_hash_table_destroy (language->stop_words);
+
+	g_free (language);
+}
+
+gboolean
+tracker_language_check_exists (const gchar *language_code)
+{
+	gint i;
+
+	if (!language_code || language_code[0] == '\0') {
+		return FALSE;
+	}
+
+	for (i = 0; all_langs[i].code; i++) {
+		if (g_str_has_prefix (language_code, all_langs[i].code)) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+gchar *
+tracker_language_get_default_code (void)
+{
+	const gchar **local_languages;
+        const gchar **p;
+
+	/* Get langauges for user's locale */
+	local_languages = (const gchar**) g_get_language_names ();
+
+	for (p = local_languages; *p; p++) {
+                const gchar *code;
+                gint         i = 0;
+
+                if (!*p || *p[0] == '\0') {
+                        continue;
+                }
+
+                code = all_langs[i].code;
+
+                while (code) {
+                        if (g_str_has_prefix (*p, code)) {
+                                return g_strndup (*p, strlen (code));
+                        }
+
+                        code = all_langs[i++].code;
+                }
+	}
+
+	return g_strdup ("en");
+}
+
+gchar *
+tracker_language_stem_word (TrackerLanguage *language,
+			    const gchar     *word,
+			    gint             word_length)
+{
+	const gchar *stem_word;
+
+	g_return_val_if_fail (language != NULL, NULL);
+
+	if (!tracker_config_get_enable_stemmer (language->config)) {
+		return NULL;
+	}
+
+	g_mutex_lock (language->stemmer_mutex);
+	if (!language->stemmer) {
+
+	}
+
+	stem_word = (const gchar *) sb_stemmer_stem (language->stemmer,
+						     (guchar*) word,
+						     word_length);
+	g_mutex_unlock (language->stemmer_mutex);
+
+	return g_strdup (stem_word);
+}
diff --git a/src/trackerd/tracker-language.h b/src/trackerd/tracker-language.h
new file mode 100644
index 0000000..f189b96
--- /dev/null
+++ b/src/trackerd/tracker-language.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008, 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.
+ */
+
+#ifndef __TRACKER_LANGUAGE_H__
+#define __TRACKER_LANGUAGE_H__
+
+#include "tracker-config.h"
+
+G_BEGIN_DECLS
+
+typedef struct _TrackerLanguage TrackerLanguage;
+
+TrackerLanguage *tracker_language_new              (TrackerConfig   *config);
+void             tracker_language_free             (TrackerLanguage *language);
+
+gboolean         tracker_language_check_exists     (const gchar     *language_code);
+gchar *          tracker_language_get_default_code (void);
+gchar *          tracker_language_stem_word        (TrackerLanguage *language,
+						    const gchar     *word,
+						    gint             word_length);
+
+G_END_DECLS
+
+#endif /* __TRACKER_LANGUAGE_H__ */
diff --git a/src/trackerd/tracker-parser.c b/src/trackerd/tracker-parser.c
index 07e37ce..c0542ae 100644
--- a/src/trackerd/tracker-parser.c
+++ b/src/trackerd/tracker-parser.c
@@ -22,7 +22,8 @@
 
 #include "tracker-parser.h"
 #include "tracker-utils.h"
-#include "tracker-stemmer.h"
+#include "tracker-config.h"
+#include "tracker-language.h"
 
 #include "config.h"
 
@@ -175,7 +176,7 @@ analyze_text (const char *text, char **index_word, gboolean filter_words, gboole
 
 	if (text) {
 		gunichar	word[64];
-		gboolean 	do_stem = TRUE, do_strip = FALSE, is_valid = TRUE;
+		gboolean 	do_strip = FALSE, is_valid = TRUE;
 		int		length = 0;
 		glong		bytes = 0;
 		WordType	word_type = WORD_IGNORE;
@@ -220,7 +221,7 @@ analyze_text (const char *text, char **index_word, gboolean filter_words, gboole
 				
 			}
 
-			if (length >= tracker->max_word_length) {
+			if (length >= tracker_config_get_max_word_length (tracker->config)) {
 				continue;
 			}
 
@@ -290,7 +291,7 @@ analyze_text (const char *text, char **index_word, gboolean filter_words, gboole
 
 			} else {
 			
-				if (length >= tracker->min_word_length) {
+				if (length >= tracker_config_get_min_word_length (tracker->config)) {
 			
 					char 	*str = NULL, *tmp;
 					guint32 len;
@@ -323,10 +324,10 @@ analyze_text (const char *text, char **index_word, gboolean filter_words, gboole
 						}
 					}
 
-		
-					if (do_stem && (tracker->stemmer && tracker->use_stemmer)) {
-
-						*index_word = tracker_stem (tmp, strlen (tmp));
+                                        *index_word = tracker_language_stem_word (tracker->language, 
+                                                                                  tmp, 
+                                                                                  strlen (tmp));
+                                        if (*index_word) {
 						g_free (tmp);
 					} else {
 						*index_word = tmp;			
@@ -568,7 +569,7 @@ tracker_parse_text (GHashTable *word_table, const char *txt, int weight, gboolea
 					
 					total_words++;
 
-					if (total_words < tracker->max_words_to_index) { 
+					if (total_words < tracker_config_get_max_words_to_index (tracker->config)) { 
 
 						int count = GPOINTER_TO_INT (g_hash_table_lookup (word_table, index_word));
 						g_hash_table_insert (word_table, index_word, GINT_TO_POINTER (count + weight));
@@ -603,7 +604,7 @@ tracker_parse_text (GHashTable *word_table, const char *txt, int weight, gboolea
 
 				total_words++;
 
-				if (total_words < tracker->max_words_to_index) { 
+				if (total_words < tracker_config_get_max_words_to_index (tracker->config)) { 
 			
 					int count = GPOINTER_TO_INT (g_hash_table_lookup (word_table, word));
 					g_hash_table_insert (word_table, word, GINT_TO_POINTER (count + weight));
diff --git a/src/trackerd/tracker-stemmer.c b/src/trackerd/tracker-stemmer.c
index 9a19d52..e69de29 100644
--- a/src/trackerd/tracker-stemmer.c
+++ b/src/trackerd/tracker-stemmer.c
@@ -1,39 +0,0 @@
-/* Tracker - indexer and metadata database engine
- * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc@gnome.org)
- *
- * 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 <stdlib.h> 
-#include <string.h> 
-#include <glib.h> 
-#include "tracker-stemmer.h"
-#include "tracker-utils.h"
-
-extern Tracker *tracker;
-
-
-gchar *
-tracker_stem (const gchar *word, gint word_length)
-{
-	gchar *stem_word;
-	
-	g_mutex_lock (tracker->stemmer_mutex);
-	stem_word = (gchar *) sb_stemmer_stem (tracker->stemmer, (guchar *) word, word_length);
-	g_mutex_unlock (tracker->stemmer_mutex);
-
-	return g_strdup (stem_word);
-}
diff --git a/src/trackerd/tracker-stemmer.h b/src/trackerd/tracker-stemmer.h
index b7cee6e..e69de29 100644
--- a/src/trackerd/tracker-stemmer.h
+++ b/src/trackerd/tracker-stemmer.h
@@ -1,25 +0,0 @@
-/* Tracker - indexer and metadata database engine
- * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc@gnome.org)
- *
- * 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_STEMMER_H_
-#define _TRACKER_STEMMER_H_
-
-gchar * tracker_stem (const gchar *word, gint word_length);
-
-#endif
diff --git a/src/trackerd/tracker-utils.c b/src/trackerd/tracker-utils.c
index 3cc5c68..afebd9e 100644
--- a/src/trackerd/tracker-utils.c
+++ b/src/trackerd/tracker-utils.c
@@ -43,7 +43,7 @@
 #include "tracker-dbus.h"
 #include "tracker-utils.h"
 #include "tracker-indexer.h"
-#include "tracker-stemmer.h"
+#include "tracker-config.h"
 #include "../xdgmime/xdgmime.h"
 
 #include "tracker-os-dependant.h"
@@ -89,23 +89,6 @@ static const char imonths[] = {
 };
 
 
-static Matches tmap[] = {
-		{"da", "danish"},
-		{"nl", "dutch"},
-		{"en", "english"},
- 		{"fi", "finnish"},
-		{"fr", "french"},
-		{"de", "german"},
-		{"it", "italian"},
-		{"nb", "norwegian"},
-		{"pt", "portuguese"},
-		{"ru", "russian"},
-		{"es", "spanish"},
-		{"sv", "swedish"},
-		{NULL, NULL},
-};
-
-
 char *
 tracker_get_service_by_id (int service_type_id)
 {
@@ -1097,7 +1080,8 @@ is_in_path (const char *uri, const char *path)
 gboolean
 tracker_file_is_no_watched (const char* uri)
 {
-	GSList *lst;
+        GSList *no_watch_directory_roots;
+	GSList *l;
 
 	if (!tracker_check_uri (uri)) {
 		return TRUE;
@@ -1119,22 +1103,21 @@ tracker_file_is_no_watched (const char* uri)
 		return TRUE;
 	}
 
-	if (!tracker->no_watch_directory_list) {
-		return FALSE;
-	}
+        no_watch_directory_roots = tracker_config_get_no_watch_directory_roots (tracker->config);
 
-	for (lst = tracker->no_watch_directory_list; lst; lst = lst->next) {
-
-                char *compare_uri = lst->data;
+	for (l = no_watch_directory_roots; l; l = l->next) {
+                if (!l->data) {
+                        continue;
+                }
 
-		/* check if equal or a prefix with an appended '/' */
-		if (strcmp (uri, compare_uri) == 0) {
-			tracker_debug ("blocking watch of %s", uri);
+		/* Check if equal or a prefix with an appended '/' */
+		if (strcmp (uri, l->data) == 0) {
+			tracker_log ("Blocking watch of %s", uri);
 			return TRUE;
 		}
 
-		if (is_in_path (uri, compare_uri)) {
-			tracker_debug ("blocking watch of %s", uri);
+		if (is_in_path (uri, l->data)) {
+			tracker_log ("Blocking watch of %s", uri);
 			return TRUE;
 		}
 	}
@@ -1142,32 +1125,26 @@ tracker_file_is_no_watched (const char* uri)
 	return FALSE;
 }
 
-
 gboolean
-tracker_file_is_crawled (const char* uri)
+tracker_file_is_crawled (const char *uri)
 {
-	GSList *lst;
-
-	if (!tracker->crawl_directory_list) {
-		return FALSE;
-	}
+        GSList *crawl_directory_roots;
+	GSList *l;
 
-	if (!uri || uri[0] != '/') {
-		return FALSE;
-	}
+        g_return_val_if_fail (uri != NULL, FALSE);
+        g_return_val_if_fail (uri[0] == G_DIR_SEPARATOR, FALSE);
 
-	for (lst = tracker->crawl_directory_list; lst; lst = lst->next) {
+        crawl_directory_roots = tracker_config_get_crawl_directory_roots (tracker->config);
 
-		char *compare_uri = lst->data;
-
-		/* check if equal or a prefix with an appended '/' */
-		if (strcmp (uri, compare_uri) == 0) {
-			tracker_debug ("blocking watch of %s", uri);
+	for (l = crawl_directory_roots; l; l = l->next) {
+		/* Check if equal or a prefix with an appended '/' */
+		if (strcmp (uri, l->data) == 0) {
+			tracker_log ("Blocking watch of %s", uri);
 			return TRUE;
 		}
 
-		if (is_in_path (uri, compare_uri)) {
-			tracker_debug ("blocking watch of %s", uri);
+		if (is_in_path (uri, l->data)) {
+			tracker_log ("Blocking watch of %s", uri);
 			return TRUE;
 		}
 	}
@@ -1181,7 +1158,7 @@ tracker_add_root_dir (const char *uri)
 {
 	struct stat st;
 
-	if (! tracker->skip_mount_points) {
+	if (!tracker_config_get_skip_mount_points (tracker->config)) {
 		return;
 	}
 
@@ -1218,7 +1195,7 @@ tracker_add_root_directories (GSList * uri_list)
 {
 	GSList * cur = NULL;
 
-	if (! tracker->skip_mount_points) {
+	if (!tracker_config_get_skip_mount_points (tracker->config)) {
 		return;
 	}
 
@@ -1235,7 +1212,7 @@ tracker_file_is_in_root_dir (const char *uri)
 	GSList *     cur = NULL;
 	dev_t        uri_dev = 0;
 
-	if (! tracker->skip_mount_points) {
+	if (!tracker_config_get_skip_mount_points (tracker->config)) {
 		return TRUE;
 	}
 
@@ -2083,146 +2060,43 @@ tracker_get_all_dirs (const char *dir, GSList **file_list)
 	get_dirs (dir, file_list, FALSE);
 }
 
-
-static GSList *
-check_dir_name (GSList* list, char *input_name)
-{
-	tracker_debug ("checking dir names : %s", input_name);
-
-	int is_converted = FALSE;
-
-	if (input_name[0] == '~') {
-
-		const char* home_dir = g_get_home_dir ();
-
-		if ((home_dir != NULL) && (home_dir[0] != '\0')) {
-
-			int is_separator = FALSE;
-			char *new_name;
-
-			if (input_name[1] == G_DIR_SEPARATOR) {
-				is_separator = TRUE;
-			} else {
-				if (home_dir[strlen (home_dir)-1] == G_DIR_SEPARATOR) {
-					is_separator = TRUE;
-				}
-			}
-
-			new_name = g_strdup_printf ("%s%s%s", home_dir, (is_separator? "" : G_DIR_SEPARATOR_S), &input_name[1]);
-
-			if ((new_name != NULL) && (strlen (new_name) <= PATH_MAX)) {
-
-				char resolved_name[PATH_MAX+2];
-
-				if (realpath (new_name, resolved_name) != NULL) {
-					list = g_slist_prepend (list, g_strdup (resolved_name));
-				} else {
-					list = g_slist_prepend (list, g_strdup (new_name));
-				}
-
-				is_converted = TRUE;
-			}
-
-			if (new_name != NULL) {
-				g_free (new_name);
-			}
-		}
-	}
-
-	if (!is_converted) {
-
-		char resolved_name[PATH_MAX+2];
-
-		if( realpath (input_name, resolved_name) != NULL ) {
-			list = g_slist_prepend (list, g_strdup (resolved_name));
-		} else {
-			list = g_slist_prepend (list, g_strdup (input_name));
-		}
-	}
-
-	tracker_debug ("resolved to %s\n", list->data);
-
-	return list;
-}
-
-
 GSList *
-tracker_filename_array_to_list (char **array)
+tracker_string_list_to_gslist (const gchar **array)
 {
-	GSList *list;
-	int    i;
+	GSList *list = NULL;
+ 	gint	i;
 
-	list = NULL;
-
-	for (i = 0; array[i] != NULL; i++) {
-                if (!tracker_is_empty_string (array[i])) {
-			list = check_dir_name (list, array[i]);
+ 	for (i = 0; array[i]; i++) {
+		if (tracker_is_empty_string (array[i])) {
+			continue;
 		}
-	}
-
-	g_strfreev (array);
-
-	return list;
-}
-
-
-static GSList *
-array_to_list (char **array)
-{
-	GSList  *list = NULL;
-	int	i;
 
-	for (i = 0; array[i] != NULL; i++) {
-                if (!tracker_is_empty_string (array[i])) {
-			list = g_slist_prepend (list, array[i]);
-		}
+		list = g_slist_prepend (list, g_strdup (array[i]));
 	}
 
-	g_free (array);
-
-	return list;
-}
-
-
-GSList *
-tracker_array_to_list (char **array)
-{
-	return array_to_list (array);
+	return g_slist_reverse (list);
 }
 
-
-char **
-tracker_list_to_array (GSList *list)
+gchar **
+tracker_gslist_to_string_list (GSList *list)
 {
-	GSList *tmp;
-	char **array;
-	int i;
+	GSList  *l;
+	gchar  **string_list;
+	gint     i;
 
-	array = g_new0 (char *, g_slist_length (list) + 1);
+	string_list = g_new0 (gchar *, g_slist_length (list) + 1);
 
-	i = 0;
+	for (l = list, i = 0; l; l = l->next) {
+ 		if (!l->data) {
+			continue;
+  		}
 
-	for (tmp = list; tmp; tmp = tmp->next) {
-		if (tmp->data) {
-			array[i] = g_strdup (tmp->data);
-			i++;
-		}
+		string_list[i++] = g_strdup (l->data);
 	}
 
-	array[i] = NULL;
+	string_list[i] = NULL;
 
-	return array;
-}
-
-
-void
-tracker_free_strs_in_array (char **array)
-{
-	char **a;
-
-	for (a = array; *a; a++) {
-		g_free (*a);
-	}
+	return string_list;
 }
 
 
@@ -2321,496 +2195,22 @@ tracker_array_to_str (char **array, int length, char sep)
 
 }
 
-char *
-tracker_get_english_lang_code (void)
-{
-        return g_strdup (tmap[2].lang);
-}
-
-
-gboolean
-tracker_is_supported_lang (const char *lang)
-{
-	int i;
-
-	for (i = 0; tmap[i].lang; i++) {
-		if (g_str_has_prefix (lang, tmap[i].lang)) {
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-
-static char *
-get_default_language_code (void)
-{
-	char **langs, **plangs;
-
-	/* get langauges for user's locale */
-	langs = (char**) g_get_language_names ();
-
-	for (plangs = langs; *plangs; plangs++) {
-		if (strlen (*plangs) > 1) {
-                        int i;
-			for (i = 0; tmap[i].lang; i++) {
-				if (g_str_has_prefix (*plangs, tmap[i].lang)) {
-					return g_strndup (*plangs, 2);
-				}
-			}
-		}
-	}
-
-	return g_strdup ("en");
-}
-
 
 void
-tracker_set_language (const char *language, gboolean create_stemmer)
-{
-	if (!language || strlen (language) < 2) {
-                if (tracker->language) {
-                        g_free (tracker->language);
-                }
-		tracker->language = get_default_language_code ();
-		tracker_log ("Setting default language code to %s based on user's locale", language);
-
-	} else {
-		int i;
-		for (i = 0; tmap[i].lang; i++) {
-			if (g_str_has_prefix (language, tmap[i].lang)) {
-                                if (tracker->language) {
-                                        g_free (tracker->language);
-                                }
-                                tracker->language = g_strdup (tmap[i].lang);
-				break;
-			}
-		}
-	}
-
-	/* set stopwords list and create stemmer for language */
-	tracker_log ("setting stopword list for language code %s", language);
-
-	char *stopword_path, *stopword_file, *stopword_en_file = NULL;
-	char *stopwords = NULL;
-
-	stopword_path = g_build_filename (TRACKER_DATADIR, "tracker", "languages", "stopwords", NULL);
-	stopword_file = g_strconcat (stopword_path, ".", language, NULL);
-
-	if (strcmp (language, "en") != 0) {
-		stopword_en_file = g_strconcat (stopword_path, ".en", NULL);
-	}
-
-
-	if (!g_file_get_contents (stopword_file, &stopwords, NULL, NULL)) {
-		tracker_log ("Warning : Tracker cannot read stopword file %s", stopword_file);
-	} else {
-
-		tracker->stop_words = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-		char **words = g_strsplit_set (stopwords, "\n" , -1);
-		char **pwords;
-
-		for (pwords = words; *pwords; pwords++) {
-			g_hash_table_insert (tracker->stop_words, g_strdup (g_strstrip (*pwords)), GINT_TO_POINTER (1));
-		}
-
-		g_strfreev (words);
-	}
-
-
-	if (stopword_en_file) {
-		g_free (stopwords);
-		if (!g_file_get_contents (stopword_en_file, &stopwords, NULL, NULL)) {
-			tracker_log ("Warning : Tracker cannot read stopword file %s", stopword_file);
-		} else {
-
-			tracker->stop_words = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-			char **words = g_strsplit_set (stopwords, "\n" , -1);
-			char **pwords;
-
-			for (pwords = words; *pwords; pwords++) {
-				g_hash_table_insert (tracker->stop_words, g_strdup (g_strstrip (*pwords)), GINT_TO_POINTER (1));
-			}
-
-			g_strfreev (words);
-		}
-		g_free (stopword_en_file);
-	}
-
-	g_free (stopword_path);
-	g_free (stopwords);
-	g_free (stopword_file);
-
-	if (!tracker->use_stemmer || !create_stemmer) {
-		return;
-	}
-
-	char *stem_language;
-
-	/* set default language */
-	stem_language = "english";
-
-	if (language) {
-		int i;
-
-		for (i = 0; tmap[i].lang; i++) {
-			if ((strcasecmp (tmap[i].lang, language) == 0)) {
-				stem_language = tmap[i].name;
-				break;
-			}
-		}
-	}
-
-	tracker->stemmer = sb_stemmer_new (stem_language, NULL);
-
-	if (!tracker->stemmer) {
-		tracker_log ("Warning : No stemmer could be found for language %s", stem_language);
-	} else {
-		tracker_log ("Using stemmer for language %s\n", stem_language);
-	}
-}
-
-
-void
-tracker_load_config_file (void)
+tracker_throttle (int multiplier)
 {
-	GKeyFile *key_file;
-	char	 *filename;
-	char	 **values;
-
-	key_file = g_key_file_new ();
-
-	filename = g_build_filename (tracker->config_dir, "/tracker/tracker.cfg", NULL);
-
-	if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
-                char *tracker_dir = g_build_filename (tracker->config_dir,"/tracker",NULL);
-
-                if (!g_file_test (tracker_dir,G_FILE_TEST_EXISTS)) {
-                    g_mkdir_with_parents (tracker_dir,0700);
-                }
-
-		g_free (tracker_dir);
+	gint throttle;
 
-		char *contents, *language;
-
-		language = get_default_language_code ();
-
-		char *default_throttle;
-
-		if (tracker->battery_udi) {
-			default_throttle = "5";
-		} else {
-			default_throttle = "0";
-		}
-
-		contents  = g_strconcat (
-					 "[General]\n",
-					 "# Log Verbosity - Valid values are 0 (displays/logs only errors), 1 (minimal), 2 (detailed), and 3 (debug)\n",
-					 "Verbosity=0\n",
-					 "# Set the initial sleeping time, in seconds\n",
-					 "InitialSleep=45\n",
-					 "# Minimizes the use of memory but may slow indexing down\n", 
-					 "LowMemoryMode=false\n\n",
-					 "[Watches]\n",
-					 "# List of directory roots to index and watch seperated by semicolons\n",
-					 "WatchDirectoryRoots=", g_get_home_dir (), ";\n",
-					 "# List of directory roots to index but not watch (no live updates but are refreshed when trackerd is next restarted) seperated by semicolons\n",
-					 "CrawlDirectory=\n",
-					 "# List of directory roots to not index and not watch seperated by semicolons\n",
-					 "NoWatchDirectory=\n",
-					 "# Set to false to prevent watching of any kind\n",
-					 "EnableWatching=true\n\n",
-					 "[Indexing]\n",
-					 "# Throttles the indexing process. Allowable values are 0-20. higher values decrease indexing speed\n",
-					 "Throttle=", default_throttle, "\n",
-					 "# Disables the indexing process\n",
-					 "EnableIndexing=true\n",
-					 "# Enables indexing of a file's text contents\n",
-					 "EnableFileContentIndexing=true\n",
-					 "# Enables generation of thumbnails\n",
-					 "EnableThumbnails=false\n",
-					 "# Enables fast index merges but may hog the disk for extended periods\n",
-					 "EnableFastMerges=false\n",
-					 "# List of partial file patterns (glob) seperated by semicolons that specify files to not index (basic stat info is only indexed for files that match these patterns)\n",
-					 "NoIndexFileTypes=;\n",
-					 "# Sets minimum length of words to index\n",
-					 "MinWordLength=3\n",
-					 "# Sets maximum length of words to index (words are cropped if bigger than this)\n",
-					 "MaxWordLength=30\n",
-					 "# Sets the language specific stemmer and stopword list to use \n",
-					 "# Valid values are 'en' (english), 'da' (danish), 'nl' (dutch), 'fi' (finnish), 'fr' (french), 'de' (german), 'it' (italien), 'nb' (norwegian), 'pt' (portugese), 'ru' (russian), 'es' (spanish), 'sv' (swedish)\n",
-					 "Language=", language, "\n",
-					 "# Enables use of language-specific stemmer\n",
-					 "EnableStemmer=true\n",
-					 "# Set to true prevents tracker from descending into mounted directory trees\n",
-					 "SkipMountPoints=false\n",
-                                         "# Disable all indexing when on battery\n",
-                                         "BatteryIndex=true\n",
-                                         "# Disable initial index sweep when on battery\n",
-                                         "BatteryIndexInitial=false\n",
-					 "# Pause indexer when disk space gets below equal/below this value, in %% of the $HOME filesystem. Set it to a value smaller then zero to disable pausing at all.\n",
-					 "LowDiskSpaceLimit=1\n\n",
-					 "[Emails]\n",
-					 "IndexEvolutionEmails=true\n",
-                                         "IndexThunderbirdEmails=true\n\n",
-					 "[Performance]\n",
-					 "# Maximum size of text in bytes to index from a file's text contents\n",
-					 "MaxTextToIndex=1048576\n",
-					 "# Maximum number of unique words to index from a file's text contents\n",
-					 "MaxWordsToIndex=10000\n",
-					 "# Specifies the no of entities to index before determining whether to perform index optimization\n",
-					 "OptimizationSweepCount=10000\n",
-					 "# Sets the maximum bucket count for the indexer\n",
-					 "MaxBucketCount=524288\n",
-					 "# Sets the minimum bucket count\n",
-					 "MinBucketCount=65536\n",
-					 "# Sets no. of divisions of the index file\n",
-					 "Divisions=4\n",
-					 "# Selects the desired ratio of used records to buckets to be used when optimizing index (should be a value between 0 and 4) \n",
-					 "BucketRatio=1\n",
-					 "# Alters how much padding is used to prevent index relocations. Higher values improve indexing speed but waste more disk space. Value should be in range (1..8)\n",
-					 "Padding=2\n",
-					 "# Sets stack size of trackerd threads in bytes. The default on Linux is 8Mb (0 will use the system default).\n",
-					 "ThreadStackSize=0\n",
-					 NULL);
-
-		g_file_set_contents (filename, contents, strlen (contents), NULL);
-		g_free (contents);
-	}
-
-	/* load all options into tracker struct */
-	g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
-
-	/* general options */
-
-	if (g_key_file_has_key (key_file, "General", "Verbosity", NULL)) {
-		tracker->verbosity = g_key_file_get_integer (key_file, "General", "Verbosity", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "General", "LowMemoryMode", NULL)) {
-		tracker->use_extra_memory = !g_key_file_get_boolean (key_file, "General", "LowMemoryMode", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "General", "InitialSleep", NULL)) {
-		tracker->initial_sleep = g_key_file_get_integer (key_file, "General", "InitialSleep", NULL);
-	}
-
-	/* Watch options */
-
-	values =  g_key_file_get_string_list (key_file,
-					      "Watches",
-					      "WatchDirectoryRoots",
-					      NULL,
-					      NULL);
-
-	if (values) {
-		tracker->watch_directory_roots_list = tracker_filename_array_to_list (values);
-	} else {
-		tracker->watch_directory_roots_list = g_slist_prepend (tracker->watch_directory_roots_list, g_strdup (g_get_home_dir ()));
-	}
-
-
-	values =  g_key_file_get_string_list (key_file,
-			       	     	      "Watches",
-				              "CrawlDirectory",
-				              NULL,
-				              NULL);
-
-	if (values) {
-		tracker->crawl_directory_list = tracker_filename_array_to_list (values);
-
-	} else {
-		tracker->crawl_directory_list = NULL;
-	}
-
-
-	values =  g_key_file_get_string_list (key_file,
-			       	     	      "Watches",
-				              "NoWatchDirectory",
-				              NULL,
-				              NULL);
-
-	if (values) {
-		tracker->no_watch_directory_list = tracker_filename_array_to_list (values);
-
-	} else {
-		tracker->no_watch_directory_list = NULL;
-	}
-
-
-	if (g_key_file_has_key (key_file, "Watches", "EnableWatching", NULL)) {
-		tracker->enable_watching = g_key_file_get_boolean (key_file, "Watches", "EnableWatching", NULL);
-	}
-
-
-	/* Indexing options */
-
-	if (g_key_file_has_key (key_file, "Indexing", "Throttle", NULL)) {
-		tracker->throttle = g_key_file_get_integer (key_file, "Indexing", "Throttle", NULL);
-	} else {
-		tracker->throttle = 0;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "EnableIndexing", NULL)) {
-		tracker->enable_indexing = g_key_file_get_boolean (key_file, "Indexing", "EnableIndexing", NULL);
-	} else {
-		tracker->enable_indexing = TRUE;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "EnableFileContentIndexing", NULL)) {
-		tracker->enable_content_indexing = g_key_file_get_boolean (key_file, "Indexing", "EnableFileContentIndexing", NULL);
-	} else {
-		tracker->enable_content_indexing = TRUE;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "EnableThumbnails", NULL)) {
-		tracker->enable_thumbnails = g_key_file_get_boolean (key_file, "Indexing", "EnableThumbnails", NULL);
-	} else {
-		tracker->enable_thumbnails = FALSE;
-	}
+	throttle = tracker_config_get_throttle (tracker->config);
 
-	if (g_key_file_has_key (key_file, "Indexing", "EnableFastMerges", NULL)) {
-		tracker->fast_merges = g_key_file_get_boolean (key_file, "Indexing", "EnableFastMerges", NULL);
-	} else {
-		tracker->fast_merges = FALSE;
-	}
-
-	values =  g_key_file_get_string_list (key_file,
-                                              "Indexing",
-                                              "NoIndexFileTypes",
-                                              NULL,
-                                              NULL);
-
-	if (values) {
-		tracker->no_index_file_types_list = array_to_list (values);
-	} else {
-		tracker->no_index_file_types_list = NULL;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "MinWordLength", NULL)) {
-		tracker->min_word_length = g_key_file_get_integer (key_file, "Indexing", "MinWordLength", NULL);
-	} else {
-		tracker->min_word_length = 3;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "MaxWordLength", NULL)) {
-		tracker->max_word_length = g_key_file_get_integer (key_file, "Indexing", "MaxWordLength", NULL);
-	} else {
-		tracker->max_word_length = 40;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "Language", NULL)) {
-		tracker->language = g_key_file_get_string (key_file, "Indexing", "Language", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "EnableStemmer", NULL)) {
-		tracker->use_stemmer = g_key_file_get_boolean (key_file, "Indexing", "EnableStemmer", NULL);
-	} else {
-		tracker->use_stemmer = TRUE;
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "SkipMountPoints", NULL)) {
-		tracker->skip_mount_points = g_key_file_get_boolean (key_file, "Indexing", "SkipMountPoints", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "BatteryIndex", NULL)) {
-		tracker->index_on_battery = g_key_file_get_boolean (key_file, "Indexing", "BatteryIndex", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Indexing", "BatteryIndexInitial", NULL)) {
-		tracker->initial_index_on_battery = g_key_file_get_boolean (key_file, "Indexing", "BatteryIndexInitial", NULL);
-	}
-
-	if (g_key_file_get_integer (key_file, "Indexing", "LowDiskSpaceLimit", NULL) >= 0) {
-		tracker->low_diskspace_limit = g_key_file_get_integer (key_file, "Indexing", "LowDiskSpaceLimit", NULL);
-	}
-
-
-	/* Emails config */
-
-	tracker->additional_mboxes_to_index = NULL;
-
-	if (g_key_file_has_key (key_file, "Emails", "IndexEvolutionEmails", NULL)) {
-		tracker->index_evolution_emails = g_key_file_get_boolean (key_file, "Emails", "IndexEvolutionEmails", NULL);
-	} else {
-		tracker->index_evolution_emails = TRUE;
-	}
-
-	if (g_key_file_has_key (key_file, "Emails", "IndexKMailEmails", NULL)) {
-		tracker->index_kmail_emails = g_key_file_get_boolean (key_file, "Emails", "IndexKMailEmails", NULL);
-	} else {
-		tracker->index_kmail_emails = FALSE;
-	}
-
-	if (g_key_file_has_key (key_file, "Emails", "IndexThunderbirdEmails", NULL)) {
-		tracker->index_thunderbird_emails = g_key_file_get_boolean (key_file, "Emails", "IndexThunderbirdEmails", NULL);
-	} else {
-		tracker->index_thunderbird_emails = FALSE;
-	}
-
-
-	/* Performance options */
-
-	if (g_key_file_has_key (key_file, "Performance", "MaxTextToIndex", NULL)) {
-		tracker->max_index_text_length = g_key_file_get_integer (key_file, "Performance", "MaxTextToIndex", NULL);
-
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "MaxWordsToIndex", NULL)) {
-		tracker->max_words_to_index = g_key_file_get_integer (key_file, "Performance", "MaxWordsToIndex", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "OptimizationSweepCount", NULL)) {
-		tracker->optimization_count = g_key_file_get_integer (key_file, "Performance", "OptimizationSweepCount", NULL);
-
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "MaxBucketCount", NULL)) {
-		tracker->max_index_bucket_count = g_key_file_get_integer (key_file, "Performance", "MaxBucketCount", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "MinBucketCount", NULL)) {
-		tracker->min_index_bucket_count = g_key_file_get_integer (key_file, "Performance", "MinBucketCount", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "Divisions", NULL)) {
-		tracker->index_divisions = g_key_file_get_integer (key_file, "Performance", "Divisions", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "BucketRatio", NULL)) {
-		tracker->index_bucket_ratio = g_key_file_get_integer (key_file, "Performance", "BucketRatio", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "Padding", NULL)) {
-		tracker->padding = g_key_file_get_integer (key_file, "Performance", "Padding", NULL);
-	}
-
-	if (g_key_file_has_key (key_file, "Performance", "ThreadStackSize", NULL)) {
-		tracker->thread_stack_size = g_key_file_get_integer (key_file, "Performance", "ThreadStackSize", NULL);
-	}
-
-	g_free (filename);
-
-	g_key_file_free (key_file);
-}
-
-
-void
-tracker_throttle (int multiplier)
-{
-	if (tracker->throttle == 0) {
+	if (throttle < 1) {
 		return;
 	}
 
-	int throttle;
-
-	throttle = tracker->throttle * multiplier;
+ 	throttle *= multiplier;
 
 	if (throttle > 0) {
-		g_usleep (throttle);
+  		g_usleep (throttle);
 	}
 }
 
@@ -3567,7 +2967,7 @@ tracker_log 	(const char *message, ...)
 	va_list		args;
 	char 		*msg;
 
-	if (tracker->verbosity < 1) {
+	if (tracker_config_get_verbosity (tracker->config) < 1) {
 		return;
 	}
 
@@ -3586,7 +2986,7 @@ tracker_info	(const char *message, ...)
 	va_list		args;
 	char 		*msg;
 
-	if (tracker->verbosity < 2) {
+	if (tracker_config_get_verbosity (tracker->config) < 2) {
 		return;
 	}
 
@@ -3605,7 +3005,7 @@ tracker_debug 	(const char *message, ...)
 	va_list		args;
 	char 		*msg;
 
-	if (tracker->verbosity < 3) {
+	if (tracker_config_get_verbosity (tracker->config) < 3) {
 		return;
 	}
 
@@ -3849,10 +3249,10 @@ tracker_pause_on_battery (void)
         }
 
 	if (tracker->first_time_index) {
-		return !tracker->initial_index_on_battery;
+		return tracker_config_get_disable_indexing_on_battery_init (tracker->config);
 	}
 
-	return !tracker->index_on_battery;	
+        return tracker_config_get_disable_indexing_on_battery (tracker->config);
 }
 
 
@@ -3860,8 +3260,11 @@ gboolean
 tracker_low_diskspace (void)
 {
 	struct statvfs st;
+        gint           low_disk_space_limit;
+
+        low_disk_space_limit = tracker_config_get_low_disk_space_limit (tracker->config);
 
-	if (tracker->low_diskspace_limit < 1)
+	if (low_disk_space_limit < 1)
 		return FALSE;
 
 	if (statvfs (tracker->data_dir, &st) == -1) {
@@ -3873,7 +3276,7 @@ tracker_low_diskspace (void)
 		return FALSE;
 	}
 
-	if ((st.f_bavail * 100 / st.f_blocks) <= tracker->low_diskspace_limit) {
+	if ((st.f_bavail * 100 / st.f_blocks) <= low_disk_space_limit) {
 		tracker_error ("Disk space is low!");
 		return TRUE;
 	}
diff --git a/src/trackerd/tracker-utils.h b/src/trackerd/tracker-utils.h
index b105469..5341ac6 100644
--- a/src/trackerd/tracker-utils.h
+++ b/src/trackerd/tracker-utils.h
@@ -35,7 +35,6 @@ extern char *tracker_actions[];
 
 #include "config.h"
 #include "tracker-parser.h"
-#include "../libstemmer/include/libstemmer.h"
 
 #define MAX_HITS_FOR_WORD 30000
 
@@ -209,25 +208,14 @@ typedef struct {
 
 	gboolean	reindex;
 
+        gpointer        config;
+        gpointer        language;
+
 	/* config options */
-	GSList 		*watch_directory_roots_list;
-	GSList 		*crawl_directory_list;
-	GSList 		*no_watch_directory_list;
-	GSList		*no_index_file_types_list;
 	GSList		*ignore_pattern_list;
 
-	gboolean	enable_indexing;
-	gboolean	enable_watching; /* can disable all forms of directory watching */
-	gboolean	enable_content_indexing; /* enables indexing of a file's text contents */
-	gboolean	enable_thumbnails;
-
 	guint32		watch_limit;
 
-
-
-	/* controls how much to output to screen/log file */
-	int		verbosity;
-
 	gboolean	fatal_errors;
 
 	gpointer	index_db;
@@ -245,35 +233,19 @@ typedef struct {
 	int		max_index_text_length; /* max size of file's text contents to index */
 	int		max_process_queue_size;
 	int		max_extract_queue_size;
-	int		optimization_count;   /* no of updates or inserts to be performed before optimizing hashtable */
-	int		throttle;
-	int		default_throttle;
-	gboolean	use_extra_memory;
-	int		initial_sleep;
-	int		max_words_to_index;
 	int 		memory_limit;
 	int 		thread_stack_size;
-	gboolean	fast_merges;
 
 	/* HAL battery */
 	char		*battery_udi;
-	gboolean	index_on_battery;
-	gboolean	initial_index_on_battery;
 
 	/* pause/shutdown vars */
 	gboolean	shutdown;
 	gboolean	pause_manual;
 	gboolean	pause_battery;
 	gboolean	pause_io;
-	gint		low_diskspace_limit;
 
 	/* indexing options */
-	gint            max_index_bucket_count;
-	gint            min_index_bucket_count;
-	gint            index_bucket_ratio; /* 0 = 50%, 1 = 100%, 2 = 200%, 3 = 300%, 4+ = 400% */
-	gint            index_divisions;
-	gint            padding; /* values 1-8 */
-
 	gpointer	file_index;
 	gpointer	file_update_index;
 	gpointer	email_index;
@@ -282,13 +254,6 @@ typedef struct {
 	gboolean	active_file_merge;
 	gboolean	active_email_merge;
 
-	int		min_word_length;  	/* words shorter than this are not parsed */
-	int		max_word_length;  	/* words longer than this are cropped */
-	gboolean	use_stemmer;	 	/* enables stemming support */
-	char		*language;		/* the language specific stemmer and stopwords to use */	
-	gpointer	stemmer;		/* pointer to stemmer */	
-	GMutex		*stemmer_mutex;
-
 	GHashTable	*stop_words;	  	/* table of stop words that are to be ignored by the parser */
 
 	gboolean	index_numbers;
@@ -308,7 +273,6 @@ typedef struct {
 
 	const char	*current_uri;
 	
-	gboolean	skip_mount_points;	/* should tracker descend into mounted directories? see Tracker.root_directory_devices */
 	GSList *	root_directory_devices;
 
 	IndexStatus	index_status;
@@ -328,9 +292,6 @@ typedef struct {
 	GHashTable	*metadata_table;
 
 	/* email config options */
-	gboolean	index_evolution_emails;
-	gboolean	index_thunderbird_emails;
-	gboolean	index_kmail_emails;
 	GSList		*additional_mboxes_to_index;
 
 	int		email_service_min;
@@ -464,12 +425,6 @@ typedef enum {
 
 
 typedef struct {
-	char *lang;
-	char *name;
-} Matches;
-
-
-typedef struct {
 
 	/* file name/path related info */
 	char 			*uri;
@@ -529,10 +484,10 @@ DBTypes		tracker_get_db_for_service 		(const char *service);
 gboolean 	tracker_is_service_embedded 		(const char *service);
 
 
-GSList *	tracker_filename_array_to_list		(char **array);
-GSList *	tracker_array_to_list 			(char **array);
-char **		tracker_make_array_null_terminated 	(char **array, int length);
-void		tracker_free_strs_in_array 		(char **array);
+GSList *	tracker_filename_array_to_list		(gchar **array);
+GSList *	tracker_string_list_to_gslist   	(const gchar **array);
+gchar **	tracker_gslist_to_string_list 		(GSList *list);
+gchar **	tracker_make_array_null_terminated 	(gchar **array, gint length);
 
 void		tracker_free_array 		(char **array, int row_count);
 gboolean        tracker_is_empty_string         (const char *s);
@@ -555,10 +510,6 @@ char *		tracker_unescape_metadata 	(const char *in);
 void		tracker_remove_dirs 		(const char *root_dir);
 char *		tracker_format_search_terms 	(const char *str, gboolean *do_bool_search);
 
-char *    	tracker_get_english_lang_code   (void);
-gboolean	tracker_is_supported_lang 	(const char *lang);
-void		tracker_set_language		(const char *language, gboolean create_stemmer);
-
 gint32		tracker_get_file_mtime 		(const char *uri);
 
 char *		tracker_array_to_str 		(char **array, int length, char sep);
@@ -631,8 +582,6 @@ char*	 	tracker_string_replace 		(const char *haystack, char *needle, char *repl
 
 void		tracker_add_metadata_to_table 	(GHashTable *meta_table, const char *key, const char *value);
 
-char **		tracker_list_to_array 		(GSList *list);
-
 void		tracker_free_metadata_field 	(FieldData *field_data);
 
 gboolean	tracker_unlink 			(const char *uri);
diff --git a/src/trackerd/trackerd.c b/src/trackerd/trackerd.c
index 9514ceb..cdf27c9 100644
--- a/src/trackerd/trackerd.c
+++ b/src/trackerd/trackerd.c
@@ -64,6 +64,8 @@
 #include "tracker-cache.h"
 #include "tracker-indexer.h"
 #include "tracker-watch.h"
+#include "tracker-config.h"
+#include "tracker-language.h"
 
 #include "tracker-os-dependant.h"
   
@@ -436,6 +438,14 @@ tracker_do_cleanup (const gchar *sig_msg)
 		tracker_remove_dirs (tracker->sys_tmp_root_dir);
 	}
 
+        if (tracker->language) {
+                tracker_language_free (tracker->language);
+        }
+
+        if (tracker->config) {
+                g_object_unref (tracker->config);
+        }
+
 	g_main_loop_quit (tracker->loop);
 
 	exit (EXIT_SUCCESS);
@@ -542,7 +552,8 @@ add_dirs_to_watch_list (GSList *dir_list, gboolean check_dirs, DBConnection *db_
 
 				tracker->dir_list = g_slist_prepend (tracker->dir_list, g_strdup (str));
 
-				if (tracker_file_is_crawled (str) || !tracker->enable_watching) {
+				if (!tracker_config_get_enable_watches (tracker->config) || 
+                                    tracker_file_is_crawled (str)) {
                                         continue;
                                 }
 
@@ -1080,18 +1091,24 @@ process_files_thread (void)
 							break;
 
 						case INDEX_FILES: {
+                                                                GSList *watch_directory_roots;
+                                                                GSList *no_watch_directory_roots;
+                                                                gint    initial_sleep;
 
+                                                                initial_sleep = tracker_config_get_initial_sleep (tracker->config);
 
 								/* sleep for N secs before watching/indexing any of the major services */
-								tracker_log ("Sleeping for %d secs...", tracker->initial_sleep);
+								tracker_log ("Sleeping for %d secs...", 
+                                                                             initial_sleep);
 								tracker->pause_io = TRUE;
 								tracker_dbus_send_index_status_change_signal ();
 								tracker_db_end_index_transaction (db_con);
 								
-								while (tracker->initial_sleep > 0) {
+
+								while (initial_sleep > 0) {
 									g_usleep (1000 * 1000);
 
-									tracker->initial_sleep --;
+									initial_sleep --;
 
 									if (!tracker->is_running || tracker->shutdown) {
 										break;
@@ -1108,47 +1125,59 @@ process_files_thread (void)
 								
 								/* delete all stuff in the no watch dirs */
 
-								if (tracker->no_watch_directory_list) {
-									GSList *lst;
+                                                                watch_directory_roots = 
+                                                                        tracker_config_get_watch_directory_roots (tracker->config);
 
-									tracker_log ("Deleting entities in no watch directories...");
+                                                                no_watch_directory_roots = 
+                                                                        tracker_config_get_no_watch_directory_roots (tracker->config);
+
+								if (no_watch_directory_roots) {
+									GSList *l;
 
-									for (lst = tracker->no_watch_directory_list; lst; lst = lst->next) {
-                                                                                gchar *no_watch_uri = lst->data;
+									tracker_log ("Deleting entities in no watch directories...");
 
-										if (no_watch_uri) {
-											guint32 f_id = tracker_db_get_file_id (db_con, no_watch_uri);
+									for (l = no_watch_directory_roots; l; l = l->next) {
+                                                                                guint32 f_id = tracker_db_get_file_id (db_con, l->data);
 
 											if (f_id > 0) {
-												tracker_db_delete_directory (db_con, f_id, no_watch_uri);
-											}
+                                                                                        tracker_db_delete_directory (db_con, f_id, l->data);
 										}
 									}
 								}
 
-								if (!tracker->watch_directory_roots_list) {
+								if (!watch_directory_roots) {
 									break;
 								}
 
 								tracker_db_start_transaction (db_con->cache);
 
-								tracker_add_root_directories (tracker->watch_directory_roots_list);
+								tracker_add_root_directories (watch_directory_roots);
 
 								/* index watched dirs first */
-								g_slist_foreach (tracker->watch_directory_roots_list, (GFunc) watch_dir, db_con);
+								g_slist_foreach (watch_directory_roots, 
+                                                                                 (GFunc) watch_dir, 
+                                                                                 db_con);
 
-								g_slist_foreach (tracker->dir_list, (GFunc) schedule_dir_check, db_con);
+								g_slist_foreach (tracker->dir_list, 
+                                                                                 (GFunc) schedule_dir_check, 
+                                                                                 db_con);
 
 								if (tracker->dir_list) {
-									g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
+									g_slist_foreach (tracker->dir_list, 
+                                                                                         (GFunc) g_free, 
+                                                                                         NULL);
 									g_slist_free (tracker->dir_list);
 									tracker->dir_list = NULL;
 								}
 
-								g_slist_foreach (tracker->watch_directory_roots_list, (GFunc) schedule_dir_check, db_con);
+								g_slist_foreach (watch_directory_roots, 
+                                                                                 (GFunc) schedule_dir_check, 
+                                                                                 db_con);
 
 								if (tracker->dir_list) {
-									g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
+									g_slist_foreach (tracker->dir_list, 
+                                                                                         (GFunc) g_free, 
+                                                                                         NULL);
 									g_slist_free (tracker->dir_list);
 									tracker->dir_list = NULL;
 								}
@@ -1161,18 +1190,23 @@ process_files_thread (void)
 							break;
 
 						case INDEX_CRAWL_FILES: {
+                                                        GSList *crawl_directory_roots;
+                                                        
 								tracker_log ("Indexing directories to be crawled...");
 								tracker->dir_list = NULL;
 
-								if (!tracker->crawl_directory_list) {
+                                                                crawl_directory_roots = 
+                                                                        tracker_config_get_crawl_directory_roots (tracker->config);
+
+								if (!crawl_directory_roots) {
 									break;
 								}
 
 								tracker_db_start_transaction (db_con->cache);
 
-								tracker_add_root_directories (tracker->crawl_directory_list);
+								tracker_add_root_directories (crawl_directory_roots);
 
-								add_dirs_to_list (tracker->crawl_directory_list, db_con);
+								add_dirs_to_list (crawl_directory_roots, db_con);
 
 								g_slist_foreach (tracker->dir_list, (GFunc) schedule_dir_check, db_con);
 
@@ -1182,7 +1216,9 @@ process_files_thread (void)
 									tracker->dir_list = NULL;
 								}
 
-								g_slist_foreach (tracker->crawl_directory_list, (GFunc) schedule_dir_check, db_con);
+								g_slist_foreach (crawl_directory_roots, 
+                                                                                 (GFunc) schedule_dir_check, 
+                                                                                 db_con);
 
 								if (tracker->dir_list) {
 									g_slist_foreach (tracker->dir_list, (GFunc) g_free, NULL);
@@ -1258,15 +1294,23 @@ process_files_thread (void)
 
 								tracker_db_start_index_transaction (db_con);
 
-								if (tracker->index_evolution_emails || tracker->index_kmail_emails
-                                                                        || tracker->index_thunderbird_emails) {
-
+                                                                gboolean index_evolution_emails;
+                                                                gboolean index_kmail_emails;
+                                                                gboolean index_thunderbird_emails;
+
+                                                                index_evolution_emails = tracker_config_get_index_evolution_emails (tracker->config);
+                                                                index_kmail_emails = tracker_config_get_index_kmail_emails (tracker->config);
+                                                                index_thunderbird_emails = tracker_config_get_index_thunderbird_emails (tracker->config);
+                                                                
+								if (index_evolution_emails ||
+                                                                    index_kmail_emails ||
+                                                                    index_thunderbird_emails) {
 									tracker_email_add_service_directories (db_con->emails);
 									tracker_log ("Starting email indexing...");
 
 									tracker_db_start_transaction (db_con->cache);
 
-									if (tracker->index_evolution_emails) {
+									if (index_evolution_emails) {
 										GSList *list = tracker_get_service_dirs ("EvolutionEmails");
 										tracker_add_root_directories (list);
 										process_directory_list (db_con, list, TRUE);
@@ -1285,14 +1329,14 @@ process_files_thread (void)
 
 									}
 
-									if (tracker->index_kmail_emails) {
+									if (index_kmail_emails) {
 										GSList *list = tracker_get_service_dirs ("KMailEmails");
 										tracker_add_root_directories (list);
 										process_directory_list (db_con, list, TRUE);
 										g_slist_free (list);
 									}
                                                                         
-                                                                        if (tracker->index_thunderbird_emails) {
+                                                                        if (index_thunderbird_emails) {
 										GSList *list = tracker_get_service_dirs ("ThunderbirdEmails");
 										tracker_add_root_directories (list);
 										process_directory_list (db_con, list, TRUE);
@@ -1596,7 +1640,7 @@ process_files_thread (void)
 					
 
 			if (tracker_db_regulate_transactions (db_con, 100)) {
-				if (tracker->verbosity == 1) {
+				if (tracker_config_get_verbosity (tracker->config) == 1) {
 					tracker_log ("indexing #%d - %s", tracker->index_count, info->uri);
 				}
 
@@ -2074,8 +2118,6 @@ set_defaults (void)
 {
 	tracker->grace_period = 0;
 
-	tracker->fast_merges = FALSE;
-
 	tracker->reindex = FALSE;
 	tracker->in_merge = FALSE;
 
@@ -2087,16 +2129,8 @@ set_defaults (void)
 	tracker->pause_battery = FALSE;
 	tracker->pause_io = FALSE;
 
-	tracker->watch_directory_roots_list = NULL;
-	tracker->no_watch_directory_list = NULL;
-	tracker->crawl_directory_list = NULL;
 	tracker->use_nfs_safe_locking = FALSE;
 
-	tracker->enable_indexing = TRUE;
-	tracker->enable_watching = TRUE;
-	tracker->enable_content_indexing = TRUE;
-	tracker->enable_thumbnails = FALSE;
-
 	tracker->watch_limit = 0;
 	tracker->index_counter = 0;
 	tracker->index_count = 0;
@@ -2105,34 +2139,9 @@ set_defaults (void)
 	tracker->max_index_text_length = MAX_INDEX_TEXT_LENGTH;
 	tracker->max_process_queue_size = MAX_PROCESS_QUEUE_SIZE;
 	tracker->max_extract_queue_size = MAX_EXTRACT_QUEUE_SIZE;
-	tracker->optimization_count = OPTIMIZATION_COUNT;
-	tracker->max_words_to_index = MAX_WORDS_TO_INDEX;
-
-	tracker->max_index_bucket_count = MAX_INDEX_BUCKET_COUNT;
-	tracker->min_index_bucket_count = MIN_INDEX_BUCKET_COUNT;
-	tracker->index_bucket_ratio = INDEX_BUCKET_RATIO;
-	tracker->index_divisions = INDEX_DIVISIONS;
-	tracker->padding = INDEX_PADDING;
 
 	tracker->flush_count = 0;
 
-	tracker->index_evolution_emails = TRUE;
-	tracker->index_thunderbird_emails = TRUE;
-	tracker->index_kmail_emails = TRUE;
-
-	tracker->use_extra_memory = TRUE;
-
-	tracker->thread_stack_size = 0;
-
-	tracker->throttle = 0;
-	tracker->initial_sleep = 45;
-
-	tracker->min_word_length = 3;
-	tracker->max_word_length = 30;
-	tracker->use_stemmer = TRUE;
-	tracker->language = tracker_get_english_lang_code ();
-	tracker->stop_words = NULL;
-
 	tracker->index_numbers = FALSE;
 	tracker->index_number_min_length = 6;
 	tracker->strip_accents = TRUE;
@@ -2141,98 +2150,75 @@ set_defaults (void)
 
 	tracker->services_dir = g_build_filename (TRACKER_DATADIR, "tracker", "services", NULL);
 
-	tracker->skip_mount_points = FALSE;
 	tracker->root_directory_devices = NULL;
 
 	tracker->folders_count = 0;
 	tracker->folders_processed = 0;
 	tracker->mbox_count = 0;
 	tracker->folders_processed = 0;
-
-	tracker->index_on_battery = TRUE;
-	tracker->initial_index_on_battery = FALSE;
-
-	tracker->low_diskspace_limit = 1;
 }
 
-static gboolean
-is_child_of (const char *dir, const char *file)
+static void
+log_option_list (GSList      *list,
+		 const gchar *str)
 {
-	if (!file) return FALSE;
+	GSList *l;
 
-	char *uri;
-	gboolean result;
-				
-	if (dir[strlen (dir)-1] != '/') {
-		uri = g_strconcat (dir, "/", NULL);
-	} else {
-		uri = g_strdup (dir);
+	if (!list) {
+		tracker_log ("%s: NONE!", str);
+		return;
 	}
 
-	result = g_str_has_prefix (file, uri);
-		
-	g_free (uri);
+	tracker_log ("%s:", str);
 
-	return result;
+	for (l = list; l; l = l->next) {
+		tracker_log ("  %s", l->data);
+	}
 }
 
-
 static void
 sanity_check_option_values (void)
 {
+        GSList *watch_directory_roots;
+        GSList *crawl_directory_roots;
+        GSList *no_watch_directory_roots;
+        GSList *no_index_file_types;
 
-	if (tracker->max_index_text_length < 0) tracker->max_index_text_length = 0;
-	if (tracker->max_words_to_index < 0) tracker->max_words_to_index = 0;
-	if (tracker->optimization_count < 1000) tracker->optimization_count = 1000;
-	if (tracker->max_index_bucket_count < 1000) tracker->max_index_bucket_count= 1000;
-	if (tracker->min_index_bucket_count < 1000) tracker->min_index_bucket_count= 1000;
-	if (tracker->index_divisions < 1) tracker->index_divisions = 1;
-	if (tracker->index_divisions > 64) tracker->index_divisions = 64;
-	if (tracker->index_bucket_ratio < 1) tracker->index_bucket_ratio = 0;
- 	if (tracker->index_bucket_ratio > 4) tracker->index_bucket_ratio = 4;
-	if (tracker->padding < 0) tracker->padding = 0;
-	if (tracker->padding > 8) tracker->padding = 8;
-
-
-	if (tracker->min_word_length < 1) tracker->min_word_length = 3;
-
-	if (!tracker_is_supported_lang (tracker->language)) {
-		tracker_set_language ("en", TRUE);
-	} else {
-		tracker_set_language (tracker->language, TRUE);
-	}
-
-	/* dont need this as the default is to watch home dir in the cfg file */
-	//if (!tracker->watch_directory_roots_list) {
-	//	tracker->watch_directory_roots_list = g_slist_prepend (tracker->watch_directory_roots_list, g_strdup (g_get_home_dir()));
-	//}
+        watch_directory_roots = tracker_config_get_watch_directory_roots (tracker->config);
+        crawl_directory_roots = tracker_config_get_crawl_directory_roots (tracker->config);
+        no_watch_directory_roots = tracker_config_get_no_watch_directory_roots (tracker->config);
 
-	if (tracker->throttle > 99) {
-		tracker->throttle = 99;
-	} else 	if (tracker->throttle < 0) {
-		tracker->throttle = 0;
-	}
-
-	if (tracker->initial_sleep > 1000) tracker->initial_sleep = 1000; /* g_usleep (X * 1000 * 1000) */
-
-	gchar *bools[] = {"no", "yes"};
+        no_index_file_types = tracker_config_get_no_index_file_types (tracker->config);
 
 	tracker_log ("Tracker configuration options :");
-	tracker_log ("Verbosity : ........................  %d", tracker->verbosity);
- 	tracker_log ("Low memory mode : ..................  %s", bools[!tracker->use_extra_memory]);
- 	tracker_log ("Indexing enabled : .................  %s", bools[tracker->enable_indexing]);
- 	tracker_log ("Watching enabled : .................  %s", bools[tracker->enable_watching]);
- 	tracker_log ("File content indexing enabled : ....  %s", bools[tracker->enable_content_indexing]);
-	tracker_log ("Thumbnailing enabled : .............  %s", bools[tracker->enable_thumbnails]);
- 	tracker_log ("Evolution email indexing enabled : .  %s", bools[tracker->index_evolution_emails]);
- 	tracker_log ("Thunderbird email indexing enabled :  %s", bools[tracker->index_thunderbird_emails]);
- 	tracker_log ("KMail indexing enabled : ...........  %s\n", bools[tracker->index_kmail_emails]);
+	tracker_log ("Verbosity : ........................  %d", 
+                     tracker_config_get_verbosity (tracker->config));
+ 	tracker_log ("Low memory mode : ..................  %s", 
+                     tracker_config_get_low_memory_mode (tracker->config) ? "yes" : "no");
+ 	tracker_log ("Indexing enabled : .................  %s", 
+                     tracker_config_get_enable_indexing (tracker->config) ? "yes" : "no");
+ 	tracker_log ("Watching enabled : .................  %s", 
+                     tracker_config_get_enable_watches (tracker->config) ? "yes" : "no");
+ 	tracker_log ("File content indexing enabled : ....  %s", 
+                     tracker_config_get_enable_content_indexing (tracker->config) ? "yes" : "no");
+	tracker_log ("Thumbnailing enabled : .............  %s", 
+                     tracker_config_get_enable_thumbnails (tracker->config) ? "yes" : "no");
+ 	tracker_log ("Evolution email indexing enabled : .  %s", 
+                     tracker_config_get_index_evolution_emails (tracker->config) ? "yes" : "no");
+ 	tracker_log ("KMail email indexing enabled :  %s", 
+                     tracker_config_get_index_kmail_emails (tracker->config) ? "yes" : "no");
+ 	tracker_log ("Thunderbird email indexing enabled :  %s", 
+                     tracker_config_get_index_thunderbird_emails (tracker->config) ? "yes" : "no");
 
 	tracker_log ("Tracker indexer parameters :");
-	tracker_log ("Indexer language code : ............  %s", tracker->language);
-	tracker_log ("Minimum index word length : ........  %d", tracker->min_word_length);
-	tracker_log ("Maximum index word length : ........  %d", tracker->max_word_length);
-	tracker_log ("Stemmer enabled : ..................  %s", bools[tracker->use_stemmer]);
+	tracker_log ("Indexer language code : ............  %s", 
+                     tracker_config_get_language (tracker->config));
+	tracker_log ("Minimum index word length : ........  %d", 
+                     tracker_config_get_min_word_length (tracker->config));
+	tracker_log ("Maximum index word length : ........  %d", 
+                     tracker_config_get_max_word_length (tracker->config));
+	tracker_log ("Stemmer enabled : ..................  %s", 
+                     tracker_config_get_enable_stemmer (tracker->config) ? "yes" : "no");
 
 	tracker->word_count = 0;
 	tracker->word_detail_count = 0;
@@ -2242,7 +2228,7 @@ sanity_check_option_values (void)
 	tracker->file_update_word_table = g_hash_table_new (g_str_hash, g_str_equal);
 	tracker->email_word_table = g_hash_table_new (g_str_hash, g_str_equal);
 
-	if (tracker->use_extra_memory) {
+	if (!tracker_config_get_low_memory_mode (tracker->config)) {
 		tracker->memory_limit = 16000 *1024;
 	
 		tracker->max_process_queue_size = 5000;
@@ -2264,100 +2250,17 @@ sanity_check_option_values (void)
 		tracker->word_count_min = 500;
 	}
 
-
-	GSList *lst, *final_list = NULL;
-	tracker_log ("Setting watch directory roots to:");
-	for (lst = tracker->watch_directory_roots_list; lst; lst = lst->next) {
-                if (lst->data) {
-			char *uri = lst->data;
-
-			
-					
-			if (final_list) {
-				gboolean add = TRUE;
-
-
-				GSList *l;
-				for (l = final_list; l; l = l->next) {
-			                if (l->data) {
-						char *uri2 =  l->data;
-
-						if (is_child_of (uri2, uri)) {
-							add = FALSE;
-							break;			
-						}
-
-						if (is_child_of (uri, uri2)) {
-							l->data = NULL;	
-						}
-		
-					}
-	
-				}
-
-				if (add) {
-					final_list = g_slist_prepend (final_list, uri);
-				}
-
-
-			} else {
-				final_list = g_slist_prepend (final_list, uri);
-			}
-		
-		}
-	}
-
-	g_slist_free (tracker->watch_directory_roots_list);
-	tracker->watch_directory_roots_list = NULL;
-
-	for (lst = final_list; lst; lst=lst->next) {
-		char *uri = lst->data;
-		if (uri && uri[0] == '/') tracker->watch_directory_roots_list = g_slist_prepend (tracker->watch_directory_roots_list, uri);
-	}
-
-	for (lst = tracker->watch_directory_roots_list; lst; lst = lst->next) {
-                if (lst->data) {	
-                        tracker_log (lst->data);
-                }
-	}
-
-	if (tracker->no_watch_directory_list) {
-
-		tracker_log ("Setting no watch directory roots to:");
-		for (lst = tracker->no_watch_directory_list; lst; lst = lst->next) {
-                        if (lst->data) {
-                                tracker_log (lst->data);
-                        }
-		}
-	}
-
-	if (tracker->crawl_directory_list) {
-
-		tracker_log ("Setting crawl directory roots to:");
-		for (lst = tracker->crawl_directory_list; lst; lst = lst->next) {
-                        if (lst->data) {
-                                tracker_log (lst->data);
-                        }
-		}
+        if (tracker->battery_udi) {
+                /* Default is 0 */
+                tracker_config_set_throttle (tracker->config, 5);
 	}
 
-	if (tracker->no_index_file_types_list) {
+	log_option_list (watch_directory_roots, "Watching directory roots");
+	log_option_list (crawl_directory_roots, "Crawling directory roots");
+	log_option_list (no_watch_directory_roots, "NOT watching directory roots");
+	log_option_list (no_index_file_types, "NOT indexing file types");
 
-               tracker_log ("Setting no watch file types:");
-               for (lst = tracker->no_index_file_types_list; lst; lst = lst->next) {
-                       if (lst->data) {
-                               tracker_log (lst->data);
-                       }
-               }
-       }
-
-	if (tracker->verbosity < 0) {
-		tracker->verbosity = 0;
-	} else if (tracker->verbosity > 3) {
-		tracker->verbosity = 3;
-	}
-
-	g_print ("Throttle level is %d\n", tracker->throttle);
+        tracker_log ("Throttle level is %d\n", tracker_config_get_throttle (tracker->config));
 
 	tracker->metadata_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
 	tracker->service_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
@@ -2416,17 +2319,13 @@ main (gint argc, gchar *argv[])
 	char **st;
 	GPatternSpec* spec;
 
+        g_type_init ();
+        
 	if (!g_thread_supported ())
 		g_thread_init (NULL);
 
 	dbus_g_thread_init ();
 
-	tracker = g_new0 (Tracker, 1);
-
-	tracker->dbus_con = tracker_dbus_init ();
-	
-	add_local_dbus_connection_monitoring (tracker->dbus_con);
-
 	setlocale (LC_ALL, "");
 
 	bindtextdomain (GETTEXT_PACKAGE, TRACKER_LOCALEDIR);
@@ -2483,9 +2382,13 @@ main (gint argc, gchar *argv[])
 	sigaction (SIGINT,  &act, NULL);
 #endif
 
+	tracker = g_new0 (Tracker, 1);
 	
+        tracker->config = tracker_config_new ();
+        tracker->language = tracker_language_new (tracker->config);
+	tracker->dbus_con = tracker_dbus_init ();
 
-	
+	add_local_dbus_connection_monitoring (tracker->dbus_con);
 
 	tracker->status = STATUS_INIT;
 
@@ -2506,6 +2409,31 @@ main (gint argc, gchar *argv[])
 
 	tracker->log_file = g_build_filename (tracker->root_dir, "tracker.log", NULL);
 
+	tracker->shutdown = FALSE;
+
+	tracker->files_check_mutex = g_mutex_new ();
+	tracker->metadata_check_mutex = g_mutex_new ();
+	tracker->request_check_mutex = g_mutex_new ();
+
+	tracker->files_stopped_mutex = g_mutex_new ();
+	tracker->metadata_stopped_mutex = g_mutex_new ();
+	tracker->request_stopped_mutex = g_mutex_new ();
+
+	tracker->file_metadata_thread = NULL;
+	tracker->file_process_thread = NULL;
+	tracker->user_request_thread = NULL;;
+
+	tracker->file_thread_signal = g_cond_new ();
+	tracker->metadata_thread_signal = g_cond_new ();
+	tracker->request_thread_signal = g_cond_new ();
+
+	tracker->metadata_signal_mutex = g_mutex_new ();
+	tracker->files_signal_mutex = g_mutex_new ();
+	tracker->request_signal_mutex = g_mutex_new ();
+
+	tracker->log_access_mutex = g_mutex_new ();
+	tracker->scheduler_mutex = g_mutex_new ();
+
 	/* reset log file */
 	tracker_unlink (tracker->log_file);
 
@@ -2545,33 +2473,6 @@ main (gint argc, gchar *argv[])
 	need_index = FALSE;
 	need_data = FALSE;
 
-	tracker->shutdown = FALSE;
-
-	tracker->files_check_mutex = g_mutex_new ();
-	tracker->metadata_check_mutex = g_mutex_new ();
-	tracker->request_check_mutex = g_mutex_new ();
-
-	tracker->files_stopped_mutex = g_mutex_new ();
-	tracker->metadata_stopped_mutex = g_mutex_new ();
-	tracker->request_stopped_mutex = g_mutex_new ();
-
-	tracker->file_metadata_thread = NULL;
-	tracker->file_process_thread = NULL;
-	tracker->user_request_thread = NULL;;
-
-	tracker->file_thread_signal = g_cond_new ();
-	tracker->metadata_thread_signal = g_cond_new ();
-	tracker->request_thread_signal = g_cond_new ();
-
-	tracker->metadata_signal_mutex = g_mutex_new ();
-	tracker->files_signal_mutex = g_mutex_new ();
-	tracker->request_signal_mutex = g_mutex_new ();
-
-	tracker->log_access_mutex = g_mutex_new ();
-	tracker->scheduler_mutex = g_mutex_new ();
-
-	tracker->stemmer_mutex = g_mutex_new ();
-
 	//tracker->cached_word_table_mutex = g_mutex_new ();
 
 	tracker->dir_queue = g_async_queue_new ();
@@ -2655,55 +2556,57 @@ main (gint argc, gchar *argv[])
 	tracker->hal_con = tracker_hal_init ();
 #endif
 
-	tracker_load_config_file ();
-
 	if (error) {
 		g_printerr ("invalid arguments: %s\n", error->message);
 		return 1;
 	}
 
-	if (no_watch_dirs) {
-		tracker->no_watch_directory_list = tracker_filename_array_to_list (no_watch_dirs);
-	}
-
 	if (watch_dirs) {
-	 	tracker->watch_directory_roots_list = tracker_filename_array_to_list (watch_dirs);
+                tracker_config_add_watch_directory_roots (tracker->config, watch_dirs);
 	}
 
 	if (crawl_dirs) {
-	 	tracker->crawl_directory_list = tracker_filename_array_to_list (crawl_dirs);
+                tracker_config_add_crawl_directory_roots (tracker->config, crawl_dirs);
+	}
+
+	if (no_watch_dirs) {
+                tracker_config_add_no_watch_directory_roots (tracker->config, no_watch_dirs);
 	}
 
 	if (disable_indexing) {
-		tracker->enable_indexing = FALSE;
+		tracker_config_set_enable_indexing (tracker->config, FALSE);
 	}
 
 	if (language) {
-		tracker->language = language;
+		tracker_config_set_language (tracker->config, language);
 	}
 
 	if (enable_evolution) {
-		tracker->index_evolution_emails = TRUE;
+		tracker_config_set_index_evolution_emails (tracker->config, TRUE);
 	}
 	
 	if (enable_kmail) {
-		tracker->index_kmail_emails = TRUE;
+		tracker_config_set_index_kmail_emails (tracker->config, TRUE);
+	}
+
+	if (enable_thunderbird) {
+		tracker_config_set_index_thunderbird_emails (tracker->config, TRUE);
 	}
 
 	if (throttle != -1) {
-		tracker->throttle = throttle;
+		tracker_config_set_throttle (tracker->config, throttle);
 	}
 
 	if (low_memory) {
-		tracker->use_extra_memory = FALSE;
+		tracker_config_set_low_memory_mode (tracker->config, TRUE);
 	}
 
 	if (verbosity != 0) {
-		tracker->verbosity = verbosity;
+		tracker_config_set_verbosity (tracker->config, verbosity);
 	}
 
 	if (initial_sleep >= 0) {
-		tracker->initial_sleep = initial_sleep;
+		tracker_config_set_initial_sleep (tracker->config, initial_sleep);
 	}
 
 	tracker->fatal_errors = fatal_errors;
@@ -2768,14 +2671,19 @@ main (gint argc, gchar *argv[])
 		tracker_db_set_option_int (db_con, "InitialIndex", 1);
 	}
 
-	if (tracker->no_index_file_types_list) {
-               ignore_pattern = tracker_list_to_array (tracker->no_index_file_types_list);
+        GSList *no_index_file_types;
+
+        no_index_file_types = tracker_config_get_no_index_file_types (tracker->config);
+
+	if (no_index_file_types) {
+               ignore_pattern = tracker_gslist_to_string_list (no_index_file_types);
  
                for (st = ignore_pattern; *st; st++) {
                        spec = g_pattern_spec_new (*st);
                        tracker->ignore_pattern_list = g_slist_prepend (tracker->ignore_pattern_list, spec);
                }
 
+	       tracker->ignore_pattern_list = g_slist_reverse (tracker->ignore_pattern_list);
 	}
 
 	db_con->cache = tracker_db_connect_cache ();
@@ -2815,8 +2723,9 @@ main (gint argc, gchar *argv[])
 	/* this var is used to tell the threads when to quit */
 	tracker->is_running = TRUE;
 
-	tracker->user_request_thread = g_thread_create_full ((GThreadFunc) process_user_request_queue_thread, NULL, 
-								tracker->thread_stack_size, FALSE, FALSE, G_THREAD_PRIORITY_NORMAL,  NULL);
+	tracker->user_request_thread = g_thread_create_full ((GThreadFunc) process_user_request_queue_thread, NULL,
+							     (gulong) tracker_config_get_thread_stack_size (tracker->config),
+							     FALSE, FALSE, G_THREAD_PRIORITY_NORMAL,  NULL);
 
 	
 
@@ -2828,8 +2737,9 @@ main (gint argc, gchar *argv[])
 			exit (1);
 		}
 
-		tracker->file_process_thread =  g_thread_create_full ((GThreadFunc) process_files_thread, NULL, tracker->thread_stack_size, 
-									FALSE, FALSE, G_THREAD_PRIORITY_NORMAL, NULL);
+		tracker->file_process_thread = g_thread_create_full ((GThreadFunc) process_files_thread, NULL,
+								     (gulong) tracker_config_get_thread_stack_size (tracker->config),
+								     FALSE, FALSE, G_THREAD_PRIORITY_NORMAL, NULL);
 	}
 	
 	g_main_loop_run (tracker->loop);
